Conversation
c8d8b87 to
5a16feb
Compare
|
I narrowed this down to the following example: val params: continents.type *: Int *: EmptyTuple = continents *: 10_000_000 *: EmptyTupleOr equivalently, after dealiasing val params: continents.type :: Int :: HNil = continents :: 10_000_000 :: HNilThis fails with the following error: We can work around this by manually specifying the type to cons: val params: continents.type :: Int :: HNil =
new ::[continents.type, Int :: HNil](continents, 10_000_000 :: HNil)Or even letting those types be inferred while manually instantiating the cons constructor: val params: continents.type :: Int :: HNil = new ::(continents, 10_000_000 :: HNil)So this appears to be a bug in the Scala 2 compiler when handling right associative operators. Appears to be a manifestation of scala/bug#11117. |
|
I don't think this is a compiler bug. The desugaring for right associated calls involves an assignment to an intermediate val ( miles@tarski:~% scala-cli --java-home /usr/lib/jvm/java-20-jdk
Welcome to Scala 3.3.0 (20, Java Java HotSpot(TM) 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> val foo = new Object
val foo: Object = java.lang.Object@5cc1bf20
scala> val bar = foo
val bar: Object = java.lang.Object@5cc1bf20
scala> val baz: bar.type = foo
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val baz: bar.type = foo
| ^^^
| Found: (foo : Object)
| Required: (bar : Object)
|
| longer explanation available when compiling with `-explain`
1 error found
scala> val quux: foo.type = foo
val quux: foo.type = java.lang.Object@5cc1bf20So, unfortunately the name (ie. the precise Symbol) that the value is presented as matters and has to match between the value and the singleton type. |
|
For completeness, here's the working test: // Uses import skunk._ for *: and EmptyTuple polyfills; can replace with :: and HNil if preferred
sessionTest("parameterized w/ list") { s =>
val continents = List("Europe", "Asia")
val query = sql"""
SELECT name, region FROM country
WHERE continent IN (${varchar.list(continents)})
AND population > $int4
""".query(varchar *: varchar)
val countryStream = for {
preparedQuery <- Stream.eval(s.prepare(query))
country <- preparedQuery.stream(new *:(continents, 10_000_000 *: EmptyTuple), chunkSize = 5)
} yield country
countryStream.compile.toList.map(_ => "ok")
} |
5a16feb to
cbc1515
Compare
|
Thanks for looking into this @mpilquist! I've updated the test to use the explicit twiddle constructor. LMK if we want this merged, or rather add some examples to the docs, or both. |
|
P.S.: If the list codec is not the first, |
|
@mpilquist do we eventually want to merge this suite for regression purposes, or should I close the PR since it's achieved its purpose? |
|
Yeah, I think we should include. |
Codecov Report
@@ Coverage Diff @@
## main #898 +/- ##
==========================================
+ Coverage 83.89% 83.94% +0.05%
==========================================
Files 125 125
Lines 1757 1757
Branches 211 211
==========================================
+ Hits 1474 1475 +1
+ Misses 283 282 -1 |
|
My bad, should have ran the tests locally for both 2.13 and 3. Compilations fails on Scala 3 with: Trying to find a workaround. |
|
I couldn't find a way to please both Scala 2.13 and Scala 3 compilers. ^ This isn't accepted by the Scala 3 compiler :( I don't feel like I have sufficient knowledge of the scala type system internals to understand what's happening here. |
Test
parameterized w/ listfails.It's equivalent to the second test which uses the legacy twiddle syntax.
The first test passes so the issue seems to appear when list (maybe other?) codec is involved.