-
-
Notifications
You must be signed in to change notification settings - Fork 619
Bring back MappedTo class for both Scala 2 and 3
#3233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Includes scala-2 and scala-3 versions of the macros. For scala-2, the old one was brought back, but for scala-3, the api had to be adjusted to comply with the new type projection rules. This difference in API should not matter that much, as this is an implicit method. The -source 3.0-migration option had to be removed as it caused the added macro to not compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Restore and unify support for MappedTo-based column mapping across Scala 2 and Scala 3, adjust related implicits and APIs, and re-enable corresponding tests
- Reintroduce Scala-2 and Scala-3
MappedToandIsomorphismmacros - Add
isomorphicTypeimplicit inRelationalImplicitColumnTypesand newMappedTo[String]extension methods - Suppress newly surfaced pattern-match warnings with
: @uncheckedacross several compiler/driver components and restore lifted-mapping tests
Reviewed Changes
Copilot reviewed 18 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| slick/src/main/scala/slick/relational/RelationalProfile.scala | Added isomorphicType implicit for automatic column mapping |
| slick/src/main/scala/slick/lifted/ExtensionMethods.scala | Added MappedTo[String] and Option[MappedTo[String]] string methods |
| slick/src/main/scala/slick/lifted/Aliases.scala | Introduced MappedTo and Isomorphism type aliases |
| slick/src/main/scala-3/slick/lifted/MappedTo.scala | New Scala 3 macro implementation for MappedTo isomorphism |
| slick/src/main/scala-2/slick/lifted/MappedTo.scala | Restored Scala 2 macro implementation for MappedTo isomorphism |
| slick/src/main/scala/slick/memory/DistributedProfile.scala | Wrapped pattern matches in : @unchecked to suppress warnings |
| slick/src/main/scala/slick/jdbc/JdbcStatementBuilderComponent.scala | Added : @unchecked on result of forceInsertCompiler.run(...) |
| slick/src/main/scala/slick/jdbc/JdbcInvokerComponent.scala | Added : @unchecked in findCompiledStatement destructuring |
| slick/src/main/scala/slick/jdbc/JdbcActionComponent.scala | Added : @unchecked on CompiledMapping destructuring |
| slick/src/main/scala/slick/compiler/*.scala | Added : @unchecked on various pattern-match destructurings |
| slick-testkit/src/test/scala/slick/test/lifted/MappedToStringExtensionMethodSupportTest.scala | Added tests covering string methods on MappedTo[String] |
| slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/RelationalMapperTest.scala | Extended mapping tests with auto-mapped IDs and projection shapes |
Comments suppressed due to low confidence (1)
slick-testkit/src/main/scala/com/typesafe/slick/testkit/tests/RelationalMapperTest.scala:130
- This test method is missing an
@Testannotation, so it will not be executed by the test runner. Add@Testto ensure it runs and validates the intended behavior.
def mappedToMacroCompilerBug = {
Incompatible changesslick12 changes since 3.7.0-pre.103.e7dfce09 Code changes
slick-testkit5 changes since 3.7.0-pre.103.e7dfce09 Code changes
|
|
What was the error with -source 3.0-migration? |
Incompatible changesslick12 changes since 3.7.0-pre.103.e7dfce09 Code changes
slick-testkit5 changes since 3.7.0-pre.103.e7dfce09 Code changes
|
| import scala.util.control.NonFatal | ||
|
|
||
| /** An isomorphism between two types that can be used for mapped column types. */ | ||
| class Isomorphism[A, B](val map: A => B, val comap: B => A) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the common parts could be moved to a shared source directory. Although MappedToBase would need to be in the same file as its version-dependent companion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Isomorphism supposed to be instantiated by users ever or is it just an implementation detail of the macro?
If the former, perhaps it would be more ergonomic to either change the constructor, or provide an apply method, that uses two argument lists to support type inference.
| def mappedToIsomorphismMacroImpl[T: Type, E <: MappedTo[T]: Type](using Quotes): Expr[Isomorphism[E, T]] = { | ||
| import quotes.reflect._ | ||
| def makeApply(v: Expr[T])(using Quotes): Expr[E] = { | ||
| import quotes.reflect._ | ||
| val sym = TypeRepr.of[E].typeSymbol | ||
| Apply(Select(New(TypeTree.of[E]), sym.primaryConstructor), List(v.asTerm)).asExprOf[E] | ||
| } | ||
| val cons = '{(v: T) => ${ makeApply('v)}} | ||
|
|
||
| val res = '{ new Isomorphism[E, T](_.value, $cons) } | ||
| res | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Claude Code I came up with a version that works without changing the compiler flags:
def mappedToIsomorphismMacroImpl[T: Type, E <: MappedTo[T]: Type](using Quotes): Expr[Isomorphism[E, T]] = {
import quotes.reflect._
val cons =
Lambda(
owner = Symbol.spliceOwner,
tpe = MethodType(List("v"))(_ => List(TypeRepr.of[T]), _ => TypeRepr.of[E]),
rhsFn =
(owner, args) => {
val sym = TypeRepr.of[E].typeSymbol
val v = args.head.asExprOf[T]
Apply(Select(New(TypeTree.of[E]), sym.primaryConstructor), List(v.asTerm))
}
).asExprOf[T => E]
val res = '{ new Isomorphism[E, T](_.value, $cons) }
res
}I don't know macros too well but the test passes...
Do you think it's safe enough to go with and avoid needing all the other changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although, maybe the other changes are net positive? What do you think?
|
Hi, sorry for losing sight of this for so long. Thanks for taking my comments into account. However I would appreciate if you could reply to all of them so we can figure out the best approach. Thanks |
Includes scala-2 and scala-3 versions of the macros. For scala-2, the old one was brought back, but for scala-3, the api had to be adjusted to comply with the new type projection rules. This difference in API should not matter that much, as this is an implicit method. The test were brought back from #2698
The -source 3.0-migration option had to be removed as it caused the added macro to not compile. This in turn caused more warnings to be thrown, most of them being a variation of
pattern's type (...) is more specialized than the right hand side expression's type (...)(which were suppressed in the second commit).