type Test1[A] = String
val test1 = Test1[Nothing]
type Test2 = [A] =>> String
val test2 = Test2[Nothing]
type Test3 = String
val test3 = Test3
scala> type Test1[A] = String
// defined alias type Test1[A] = String
scala> val test1 = Test1[Nothing]
val test1: String = ""
scala> type Test2 = [A] =>> String
// defined alias type Test2[A] = String
scala> val test2 = Test2[Nothing]
val test2: String = ""
scala> type Test3 = String
// defined alias type Test3 = String
scala> val test3 = Test3
1 |val test3 = Test3
| ^^^^^
| Not found: Test3
I would expect all three of them to behave the same way
This is a bug in typer, all of the value definitions should be rejected, as it is in Scala 2.
Hi @liufengyun! I'd like to try to fix this issue myself if you could provide some guidance :) I've never contributed to Dotty before
Thanks @agluszak 馃憤
To investigate this issue, first make sure you can clone and successfully compile the project:
http://dotty.epfl.ch/docs/contributing/getting-started.html
The debugging tips can be also very helpful:
http://dotty.epfl.ch/docs/contributing/debugging.html#tracing
For this issue, the code that might be relevant is findRef in Typer.scala. The compiler should not be able to find the name Test1 in type checking val test1 = Test1[Nothing], as no term name of Test1 exists in scope.
Update: so it looks like the compiler indeed fails to find the name Test1, but somehow swallows this error (>>>> StoredError:) and then continues to conduct various adaptations, and finally reaches method typedFunPart in Applications.scala, which does this:
/** Typecheck the function part of an application.
* Fallback if this fails: try to convert `E` to `new E`.
*/
Here's the relevant part of the log (I changed the name Test1 to TestBad)
[log typer] ==> typing type TestBad[A] = String, pt = <?>?
ADAPT in module class Playground$package$
creating symbol for A in Mode(ImplicitsEnabled)
entered: type A in type TestBad
[log typer] ==> typing A, pt = <?>?
ADAPT in type TestBad
[log typer] ==> typing , pt = <?>?
ADAPT in type A
[log typer] ==> typing <empty>, pt = <?>?
ADAPT in type A
[log typer] ==> adapting <empty> to <?>
?
[log typer] <== adapting <empty> to <?>
= <empty>
[log typer] <== typing <empty>, pt = <?> = <empty>
[log typer] ==> typing <empty>, pt = <?>?
ADAPT in type A
[log typer] ==> adapting <empty> to <?>
?
[log typer] <== adapting <empty> to <?>
= <empty>
[log typer] <== typing <empty>, pt = <?> = <empty>
[log typer] ==> typing <empty>, pt = <?>?
ADAPT in type A
[log typer] ==> adapting <empty> to <?>
?
[log typer] <== adapting <empty> to <?>
= <empty>
[log typer] <== typing <empty>, pt = <?> = <empty>
[log typer] ==> typing Nothing, pt = <?>?
ADAPT in type A
[log typer] ==> adapting Nothing to <?>
?
[log typer] <== adapting Nothing to <?>
= Nothing
[log typer] <== typing Nothing, pt = <?> = Nothing
[log typer] ==> typing Any, pt = <?>?
ADAPT in type A
[log typer] ==> adapting Any to <?>
?
[log typer] <== adapting Any to <?>
= Any
[log typer] <== typing Any, pt = <?> = Any
[log typer] ==> adapting >: Nothing <: Any to <?>
?
[log typer] <== adapting >: Nothing <: Any to <?>
= >: Nothing <: Any
[log typer] <== typing , pt = <?> = >: Nothing <: Any
[log typer] ==> typing , pt = <?>?
ADAPT in type A
[log typer] ==> adapting >: Nothing <: Any to <?>
?
[log typer] <== adapting >: Nothing <: Any to <?>
= >: Nothing <: Any
[log typer] <== typing , pt = <?> = >: Nothing <: Any
[log typer] ==> adapting A >: Nothing <: Any to <?>
?
[log typer] <== adapting A >: Nothing <: Any to <?>
= A >: Nothing <: Any
[log typer] <== typing A, pt = <?> = A >: Nothing <: Any
[log typer] ==> typing String, pt = <?>?
ADAPT in type TestBad
typed ident type String in type TestBad
FIND REF String <?>
ENSURE ACCESSIBLE type String in type TestBad
[log typer] ==> adapting String to <?>
?
[log typer] <== adapting String to <?>
= String
[log typer] <== typing String, pt = <?> = String
[log typer] ==> typing A, pt = <?>?
ADAPT in type TestBad
[log typer] ==> adapting A >: Nothing <: Any to <?>
?
[log typer] <== adapting A >: Nothing <: Any to <?>
= A >: Nothing <: Any
[log typer] <== typing A, pt = <?> = A >: Nothing <: Any
[log typer] ==> typing String, pt = <?>?
ADAPT in type TestBad
[log typer] ==> adapting String to <?>
?
[log typer] <== adapting String to <?>
= String
[log typer] <== typing String, pt = <?> = String
[log typer] ==> adapting type TestBad[A >: Nothing <: Any] = String to <?>
?
[log typer] <== adapting type TestBad[A >: Nothing <: Any] = String to <?>
= type TestBad[A >: Nothing <: Any] = String
[log typer] <== typing type TestBad[A] = String, pt = <?> = type TestBad[A >: Nothing <: Any] = String
[log typer] ==> typing val testBad = TestBad[Nothing], pt = <?>?
ADAPT in module class Playground$package$
[log typer] ==> glb(<notype>, <notype>)?
[log typer] <== glb(<notype>, <notype>) = <notype>
[log typer] ==> glb(<notype>, <notype>)?
[log typer] <== glb(<notype>, <notype>) = <notype>
[log typer] ==> typing TestBad[Nothing], pt = <?>?
ADAPT in val testBad
[log typer] ==> typing Nothing, pt = <?>?
ADAPT in val testBad
typed ident type Nothing in val testBad
FIND REF Nothing <?>
ENSURE ACCESSIBLE type Nothing in val testBad
[log typer] ==> adapting Nothing to <?>
?
[log typer] <== adapting Nothing to <?>
= Nothing
[log typer] <== typing Nothing, pt = <?> = Nothing
TYPED TYPE APPLY <?> in val testBad
>>>> StoredError: [log typer] ==> typing TestBad, pt = [applied to [Nothing] returning <?>?
ADAPT in val testBad
typed ident TestBad in val testBad
FIND REF TestBad [applied to [Nothing] returning <?>
MISSING IDENT TestBad in val testBad
>>>> StoredError: Not found: TestBad
java.lang.Exception: Stack trace
at java.base/java.lang.Thread.dumpStack(Thread.java:1388)
at dotty.tools.dotc.report$.error(report.scala:72)
at dotty.tools.dotc.typer.ErrorReporting$.errorType(ErrorReporting.scala:33)
at dotty.tools.dotc.typer.ErrorReporting$.errorTree(ErrorReporting.scala:24)
at dotty.tools.dotc.typer.ErrorReporting$.errorTree(ErrorReporting.scala:27)
at dotty.tools.dotc.typer.Typer.typedIdent(Typer.scala:514)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2454)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2546)
at dotty.tools.dotc.typer.Typer.typed$$anonfun$3(Typer.scala:2619)
at dotty.tools.dotc.reporting.trace$.doTrace(trace.scala:72)
at dotty.tools.dotc.reporting.trace$.inline$doTrace(trace.scala:49)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2621)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2624)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2740)
at dotty.tools.dotc.typer.Applications.typedFunPart$$anonfun$1(Applications.scala:852)
at dotty.tools.dotc.typer.Typer.tryEither(Typer.scala:2748)
at dotty.tools.dotc.typer.Applications.typedFunPart(Applications.scala:864)
at dotty.tools.dotc.typer.Applications.typedFunPart$(Applications.scala:236)
at dotty.tools.dotc.typer.Typer.typedFunPart(Typer.scala:92)
at dotty.tools.dotc.typer.Applications.typedTypeApply(Applications.scala:1082)
at dotty.tools.dotc.typer.Applications.typedTypeApply$(Applications.scala:236)
at dotty.tools.dotc.typer.Typer.typedTypeApply(Typer.scala:92)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2504)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2547)
at dotty.tools.dotc.typer.Typer.typed$$anonfun$3(Typer.scala:2619)
at dotty.tools.dotc.reporting.trace$.doTrace(trace.scala:72)
at dotty.tools.dotc.reporting.trace$.inline$doTrace(trace.scala:49)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2621)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2624)
at dotty.tools.dotc.typer.Namer.typedAheadExpr$$anonfun$1(Namer.scala:1232)
at dotty.tools.dotc.typer.Namer.typedAhead(Namer.scala:1219)
at dotty.tools.dotc.typer.Namer.typedAheadExpr(Namer.scala:1232)
at dotty.tools.dotc.typer.Namer.rhsType$1$$anonfun$1(Namer.scala:1367)
at dotty.tools.dotc.typer.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:216)
at dotty.tools.dotc.typer.Namer.rhsType$2(Namer.scala:1367)
at dotty.tools.dotc.typer.Namer.cookedRhsType$1(Namer.scala:1378)
at dotty.tools.dotc.typer.Namer.lhsType$1(Namer.scala:1379)
at dotty.tools.dotc.typer.Namer.inferredType$1(Namer.scala:1390)
at dotty.tools.dotc.typer.Namer.valOrDefDefSig(Namer.scala:1398)
at dotty.tools.dotc.typer.Namer$Completer.typeSig(Namer.scala:680)
at dotty.tools.dotc.typer.Namer$Completer.completeInCreationContext(Namer.scala:801)
at dotty.tools.dotc.typer.Namer$Completer.complete(Namer.scala:712)
at dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:166)
at dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:188)
at dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:190)
at dotty.tools.dotc.core.SymDenotations$SymDenotation.ensureCompleted(SymDenotations.scala:370)
at dotty.tools.dotc.typer.Typer.retrieveSym(Typer.scala:2427)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2452)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2546)
at dotty.tools.dotc.typer.Typer.typed$$anonfun$3(Typer.scala:2619)
at dotty.tools.dotc.reporting.trace$.doTrace(trace.scala:72)
at dotty.tools.dotc.reporting.trace$.inline$doTrace(trace.scala:49)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2621)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2624)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2646)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2696)
at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2135)
at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$2(Typer.scala:2473)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2477)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2546)
at dotty.tools.dotc.typer.Typer.typed$$anonfun$3(Typer.scala:2619)
at dotty.tools.dotc.reporting.trace$.doTrace(trace.scala:72)
at dotty.tools.dotc.reporting.trace$.inline$doTrace(trace.scala:49)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2621)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2624)
at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2646)
at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2696)
at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2270)
at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2518)
at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2547)
at dotty.tools.dotc.typer.Typer.typed$$anonfun$3(Typer.scala:2619)
at dotty.tools.dotc.reporting.trace$.doTrace(trace.scala:72)
at dotty.tools.dotc.reporting.trace$.inline$doTrace(trace.scala:49)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2621)
at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2624)
at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2740)
at dotty.tools.dotc.typer.FrontEnd.liftedTree1$2(FrontEnd.scala:79)
at dotty.tools.dotc.typer.FrontEnd.typeCheck$$anonfun$1(FrontEnd.scala:84)
at dotty.tools.dotc.typer.FrontEnd.monitor(FrontEnd.scala:43)
at dotty.tools.dotc.typer.FrontEnd.typeCheck(FrontEnd.scala:85)
at dotty.tools.dotc.typer.FrontEnd.runOn$$anonfun$3(FrontEnd.scala:120)
at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.immutable.List.foreach(List.scala:333)
at dotty.tools.dotc.typer.FrontEnd.runOn(FrontEnd.scala:120)
at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:185)
at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
at dotty.tools.dotc.Run.runPhases$5(Run.scala:195)
at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:203)
at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
at dotty.tools.dotc.Run.compileUnits(Run.scala:210)
at dotty.tools.dotc.Run.compileSources(Run.scala:147)
at dotty.tools.dotc.Run.compile(Run.scala:129)
at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
at dotty.tools.dotc.Driver.process(Driver.scala:193)
at dotty.tools.dotc.Driver.process(Driver.scala:162)
at dotty.tools.dotc.Driver.process(Driver.scala:174)
at dotty.tools.dotc.Driver.main(Driver.scala:201)
at dotty.tools.dotc.Main.main(Main.scala)
>>>> StoredError: [log typer] ==> adapting TestBad to [applied to [Nothing] returning <?>
?
>>>> StoredError: [log typer] <== adapting TestBad to [applied to [Nothing] returning <?>
= TestBad
>>>> StoredError: [log typer] <== typing TestBad, pt = [applied to [Nothing] returning <?> = TestBad
APPLICATIONS [applied to [Nothing] returning <?> in val testBad
TRY NEW IDENT in val testBad
>>>> StoredError: [log typer] ==> typing TestBad, pt = <?>?
ADAPT in val testBad
typed ident type TestBad in val testBad
FIND REF TestBad <?>
ENSURE ACCESSIBLE type TestBad in val testBad
>>>> StoredError: [log typer] ==> adapting TestBad to <?>
?
>>>> StoredError: [log typer] <== adapting TestBad to <?>
= TestBad
>>>> StoredError: [log typer] <== typing TestBad, pt = <?> = TestBad
>>>> StoredError: [log typer] ==> typing new TestBad[Nothing], pt = <?>?
ADAPT in val testBad
>>>> StoredError: [log typer] ==> typing new TestBad[Nothing], pt = <?>?
ADAPT in val testBad
>>>> StoredError: [log typer] ==> typing TestBad[Nothing], pt = <?>?
ADAPT in val testBad
>>>> StoredError: [log typer] ==> adapting TestBad[Nothing] to <?>
?
>>>> StoredError: [log typer] <== adapting TestBad[Nothing] to <?>
= TestBad[Nothing]
>>>> StoredError: [log typer] <== typing TestBad[Nothing], pt = <?> = TestBad[Nothing]
>>>> StoredError: [log typer] ==> adapting new TestBad[Nothing] to <?>
?
>>>> StoredError: [log typer] <== adapting new TestBad[Nothing] to <?>
= new TestBad[Nothing]
>>>> StoredError: [log typer] <== typing new TestBad[Nothing], pt = <?> = new TestBad[Nothing]
>>>> StoredError: [log typer] ==> adapting new TestBad[Nothing] to <?>
?
adapt overloaded <overloaded TestBad[Nothing]#<init>> with alternatives (x$0: StringBuilder): String
(x$0: StringBuffer): String
(x$0: Array[Byte]): String
(x$0: Array[Byte], x$1: Int, x$2: Int): String
(x$0: Array[Byte], x$1: java.nio.charset.Charset): String
(x$0: Array[Byte], x$1: String): String
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: java.nio.charset.Charset): String
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: String): String
(x$0: Array[Byte], x$1: Int): String
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: Int): String
(x$0: Array[Int], x$1: Int, x$2: Int): String
(x$0: Array[Char], x$1: Int, x$2: Int): String
(x$0: Array[Char]): String
(x$0: String): String
(): String
>>>> StoredError: [log typer] ==> resolve over (TestBad[Nothing]#<init> : (x$0: StringBuilder): String), (TestBad[Nothing]#<init> : (x$0: StringBuffer): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte]): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: String): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: String): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: Int): String
), (TestBad[Nothing]#<init> : (x$0: Array[Int], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char]): String), (TestBad[Nothing]#<init> : (x$0: String): String), (TestBad[Nothing]#<init> : (): String), pt = <?>?
>>>> StoredError: [log typer] ==> isSubType StringBuilder <:< StringBuffer ?
>>>> StoredError: [log typer] <== isSubType StringBuilder <:< StringBuffer = false
>>>> StoredError: [log typer] ==> isSubType StringBuffer <:< StringBuilder ?
>>>> StoredError: [log typer] <== isSubType StringBuffer <:< StringBuilder = false
>>>> StoredError: [log typer] ==> isSubType StringBuffer <:< Array[Byte] ?
>>>> StoredError: [log typer] <== isSubType StringBuffer <:< Array[Byte] = false
>>>> StoredError: [log typer] ==> isSubType Array[Byte] <:< StringBuffer ?
>>>> StoredError: [log typer] <== isSubType Array[Byte] <:< StringBuffer = false
>>>> StoredError: [log typer] ==> isSubType Int <:< java.nio.charset.Charset ?
>>>> StoredError: [log typer] <== isSubType Int <:< java.nio.charset.Charset = false
>>>> StoredError: [log typer] ==> isSubType java.nio.charset.Charset <:< Int ?
>>>> StoredError: [log typer] <== isSubType java.nio.charset.Charset <:< Int = false
>>>> StoredError: [log typer] ==> isSubType java.nio.charset.Charset <:< String ?
>>>> StoredError: [log typer] <== isSubType java.nio.charset.Charset <:< String = false
>>>> StoredError: [log typer] ==> isSubType String <:< java.nio.charset.Charset ?
>>>> StoredError: [log typer] <== isSubType String <:< java.nio.charset.Charset = false
>>>> StoredError: [log typer] ==> isSubType String <:< Int ?
>>>> StoredError: [log typer] <== isSubType String <:< Int = false
>>>> StoredError: [log typer] ==> isSubType Int <:< String ?
>>>> StoredError: [log typer] <== isSubType Int <:< String = false
>>>> StoredError: [log typer] ==> isSubType java.nio.charset.Charset <:< String ?
>>>> StoredError: [log typer] <== isSubType java.nio.charset.Charset <:< String = false
>>>> StoredError: [log typer] ==> isSubType String <:< java.nio.charset.Charset ?
>>>> StoredError: [log typer] <== isSubType String <:< java.nio.charset.Charset = false
>>>> StoredError: [log typer] ==> isSubType Array[Byte] <:< Array[Int] ?
assume equal prefixes (scala : scala.type) (scala : scala.type)
>>>> StoredError: [log typer] ==> isSubType Int <:< Byte ?
>>>> StoredError: [log typer] <== isSubType Int <:< Byte = false
>>>> StoredError: [log typer] <== isSubType Array[Byte] <:< Array[Int] = false
>>>> StoredError: [log typer] ==> isSubType Array[Int] <:< Array[Byte] ?
assume equal prefixes (scala : scala.type) (scala : scala.type)
>>>> StoredError: [log typer] ==> isSubType Byte <:< Int ?
>>>> StoredError: [log typer] <== isSubType Byte <:< Int = false
>>>> StoredError: [log typer] <== isSubType Array[Int] <:< Array[Byte] = false
>>>> StoredError: [log typer] ==> isSubType Array[Int] <:< Array[Char] ?
assume equal prefixes (scala : scala.type) (scala : scala.type)
>>>> StoredError: [log typer] ==> isSubType Char <:< Int ?
>>>> StoredError: [log typer] <== isSubType Char <:< Int = false
>>>> StoredError: [log typer] <== isSubType Array[Int] <:< Array[Char] = false
>>>> StoredError: [log typer] ==> isSubType Array[Char] <:< Array[Int] ?
assume equal prefixes (scala : scala.type) (scala : scala.type)
>>>> StoredError: [log typer] ==> isSubType Int <:< Char ?
>>>> StoredError: [log typer] <== isSubType Int <:< Char = false
>>>> StoredError: [log typer] <== isSubType Array[Char] <:< Array[Int] = false
>>>> StoredError: [log typer] ==> isSubType Array[Char] <:< String ?
>>>> StoredError: [log typer] <== isSubType Array[Char] <:< String = false
>>>> StoredError: [log typer] ==> isSubType String <:< Array[Char] ?
>>>> StoredError: [log typer] <== isSubType String <:< Array[Char] = false
>>>> StoredError: [log typer] <== resolve over (TestBad[Nothing]#<init> : (x$0: StringBuilder): String), (TestBad[Nothing]#<init> : (x$0: StringBuffer): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte]): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: String): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: String): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: Int): String
), (TestBad[Nothing]#<init> : (x$0: Array[Int], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char]): String), (TestBad[Nothing]#<init> : (x$0: String): String), (TestBad[Nothing]#<init> : (): String), pt = <?> = List(TermRef(AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module Playground$package),type TestBad),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),module scala),class Nothing))),method <init>))
>>>> StoredError: [log typer] ==> adapting new TestBad[Nothing] to <?>
?
>>>> StoredError: [log typer] ==> adapting new TestBad[Nothing]() to <?>
?
>>>> StoredError: [log typer] <== adapting new TestBad[Nothing]() to <?>
= new TestBad[Nothing]()
>>>> StoredError: [log typer] <== adapting new TestBad[Nothing] to <?>
= new TestBad[Nothing]()
>>>> StoredError: [log typer] <== adapting new TestBad[Nothing] to <?>
= new TestBad[Nothing]()
>>>> StoredError: [log typer] <== typing new TestBad[Nothing], pt = <?> = new TestBad[Nothing]()
[log typer] ==> typing TestBad, pt = <?>?
try new TestBad -> new TestBad[Nothing]()
[log typer] ==> adapting TestBad to <?>
?
[log typer] <== adapting TestBad to <?>
= TestBad
[log typer] <== typing TestBad, pt = <?> = TestBad
[log typer] ==> typing new TestBad[Nothing], pt = <?>?
[log typer] ==> typing new TestBad[Nothing], pt = <?>?
[log typer] ==> typing TestBad[Nothing], pt = <?>?
[log typer] ==> adapting TestBad[Nothing] to <?>
?
[log typer] <== adapting TestBad[Nothing] to <?>
= TestBad[Nothing]
[log typer] <== typing TestBad[Nothing], pt = <?> = TestBad[Nothing]
[log typer] ==> adapting new TestBad[Nothing] to <?>
?
[log typer] <== adapting new TestBad[Nothing] to <?>
= new TestBad[Nothing]
[log typer] <== typing new TestBad[Nothing], pt = <?> = new TestBad[Nothing]
[log typer] ==> adapting new TestBad[Nothing] to <?>
?
[log typer] ==> resolve over (TestBad[Nothing]#<init> : (x$0: StringBuilder): String), (TestBad[Nothing]#<init> : (x$0: StringBuffer): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte]): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: String): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: String): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: Int): String
), (TestBad[Nothing]#<init> : (x$0: Array[Int], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char]): String), (TestBad[Nothing]#<init> : (x$0: String): String), (TestBad[Nothing]#<init> : (): String), pt = <?>?
[log typer] <== resolve over (TestBad[Nothing]#<init> : (x$0: StringBuilder): String), (TestBad[Nothing]#<init> : (x$0: StringBuffer): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte]): String), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: String): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: java.nio.charset.Charset): String
), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: String): String
), (TestBad[Nothing]#<init> : (x$0: Array[Byte], x$1: Int): String), (TestBad[Nothing]#<init> :
(x$0: Array[Byte], x$1: Int, x$2: Int, x$3: Int): String
), (TestBad[Nothing]#<init> : (x$0: Array[Int], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char], x$1: Int, x$2: Int): String), (TestBad[Nothing]#<init> : (x$0: Array[Char]): String), (TestBad[Nothing]#<init> : (x$0: String): String), (TestBad[Nothing]#<init> : (): String), pt = <?> = List(TermRef(AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module Playground$package),type TestBad),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),module scala),class Nothing))),method <init>))
[log typer] ==> adapting new TestBad[Nothing] to <?>
?
[log typer] ==> adapting new TestBad[Nothing]() to <?>
?
[log typer] <== adapting new TestBad[Nothing]() to <?>
= new TestBad[Nothing]()
[log typer] <== adapting new TestBad[Nothing] to <?>
= new TestBad[Nothing]()
[log typer] <== adapting new TestBad[Nothing] to <?>
= new TestBad[Nothing]()
[log typer] <== typing new TestBad[Nothing], pt = <?> = new TestBad[Nothing]()
[log typer] ==> adapting new TestBad[Nothing]() to <?>
?
[log typer] <== adapting new TestBad[Nothing]() to <?>
= new TestBad[Nothing]()
[log typer] <== typing TestBad[Nothing], pt = <?> = new TestBad[Nothing]()
[log typer] ==> typing <notype>, pt = String?
ADAPT in val testBad
[log typer] ==> adapting String to String
?
[log typer] <== adapting String to String
= String
[log typer] <== typing <notype>, pt = String = String
[log typer] ==> typing String, pt = <?>?
ADAPT in val testBad
[log typer] ==> adapting String to <?>
?
[log typer] <== adapting String to <?>
= String
[log typer] <== typing String, pt = <?> = String
[log typer] ==> typing TestBad[Nothing], pt = String?
ADAPT in val testBad
[log typer] ==> adapting new TestBad[Nothing]() to String
?
[log typer] <== adapting new TestBad[Nothing]() to String
= new TestBad[Nothing]()
[log typer] <== typing TestBad[Nothing], pt = String = new TestBad[Nothing]()
[log typer] ==> adapting val testBad: String = new TestBad[Nothing]() to <?>
?
[log typer] <== adapting val testBad: String = new TestBad[Nothing]() to <?>
= val testBad: String = new TestBad[Nothing]()
[log typer] <== typing val testBad = TestBad[Nothing], pt = <?> = val testBad: String = new TestBad[Nothing]()
To be honest, I'm not sure what to do next. Could you give me another hint @liufengyun? ;)
I think the issue is that typedFunPart should only adapt E to new E when we're applying E to some term parameters: val x = String() works and expands to val x = new String(), but val x = String doesn't, it should be the same for the aliases of String. To do that we need to look at the expected type pt in typedFunPart: if it's a FunProto then we're good, if it's a PolyProto we need to look at its resType to see if it's a FunProto or not, otherwise we're not applying E to term parameters and so we shouldn't do the adaptation.
Thanks @smarter!
Indirectly fixed by https://github.com/lampepfl/dotty/pull/10784, see https://github.com/lampepfl/dotty/pull/10774#issuecomment-749007068
Most helpful comment
I think the issue is that
typedFunPartshould only adaptEtonew Ewhen we're applyingEto some term parameters:val x = String()works and expands toval x = new String(), butval x = Stringdoesn't, it should be the same for the aliases of String. To do that we need to look at the expected typeptintypedFunPart: if it's aFunProtothen we're good, if it's aPolyProtowe need to look at itsresTypeto see if it's aFunProtoor not, otherwise we're not applyingEto term parameters and so we shouldn't do the adaptation.