Skip to content

Instantly share code, notes, and snippets.

@VladUreche
Created June 10, 2014 22:00
Show Gist options
  • Save VladUreche/e4a1939ea271088fa7f1 to your computer and use it in GitHub Desktop.
Save VladUreche/e4a1939ea271088fa7f1 to your computer and use it in GitHub Desktop.
Type inference issue
$ cat infer.scala
package p
class ann extends annotation.StaticAnnotation with annotation.TypeConstraint
class Seq[T] {
def map[U](f: T => U): Seq[U] = ???
}
object Test {
def test() = {
val seq1 = new Seq[Int @ann]
val seq2 = seq1.map(x => x)
// ^ ^
// | |
// | correctly inferred to Int @ann => Int @ann
// |
// typer infers Seq[Int] instead of Seq[Int @ann]
}
}
$ scalac infer.scala -Xprint:typer
[[syntax trees at end of typer]] // infer.scala
package p {
class ann extends scala.annotation.Annotation with scala.annotation.StaticAnnotation with scala.annotation.TypeConstraint {
def <init>(): p.ann = {
ann.super.<init>();
()
}
};
class Seq[T] extends scala.AnyRef {
def <init>(): p.Seq[T] = {
Seq.super.<init>();
()
};
def map[U](f: T => U): p.Seq[U] = scala.this.Predef.???
};
object Test extends scala.AnyRef {
def <init>(): p.Test.type = {
Test.super.<init>();
()
};
def test(): Unit = {
val seq1: p.Seq[Int @p.ann] = new p.Seq[Int @p.ann]();
val seq2: p.Seq[Int] = seq1.map[Int](((x: Int @p.ann) => x));
()
}
}
}
$ scalac infer.scala -Ytyper-debug -Yinfer-debug -Xprint:typer -Ydebug
[running phase parser on infer.scala]
[running phase namer on infer.scala]
[running phase packageobjects on infer.scala]
[running phase typer on infer.scala]
|-- package p EXPRmode (site: package class <root>, a RootClass with flags final <module> <package> <java> <static>)
| |-- p EXPRmode-POLYmode-QUALmode (site: package class <root>, a RootClass with flags final <module> <package> <java> <static>)
| | \-> <root>.this.p.type
| |-- class ann BYVALmode-EXPRmode (site: package class p, a PackageClassSymbol with flags final <module> <package> <java>)
| | |-- annotation.StaticAnnotation FUNmode-TYPEmode (site: class ann, a ClassSymbol with flags <locked>)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol with flags <locked>)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.StaticAnnotation
| | |-- annotation.StaticAnnotation TYPEmode (site: class ann, a ClassSymbol with flags <locked>)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol with flags <locked>)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.StaticAnnotation
| | |-- annotation.TypeConstraint FUNmode-TYPEmode (site: class ann, a ClassSymbol with flags <locked>)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol with flags <locked>)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.TypeConstraint
| | |-- annotation.TypeConstraint TYPEmode (site: class ann, a ClassSymbol with flags <locked>)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol with flags <locked>)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.TypeConstraint
| | |-- annotation.StaticAnnotation FUNmode-TYPEmode (site: class ann, a ClassSymbol)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.StaticAnnotation
| | |-- annotation.StaticAnnotation TYPEmode (site: class ann, a ClassSymbol)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.StaticAnnotation
| | |-- annotation.TypeConstraint FUNmode-TYPEmode (site: class ann, a ClassSymbol)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.TypeConstraint
| | |-- annotation.TypeConstraint TYPEmode (site: class ann, a ClassSymbol)
| | | |-- annotation EXPRmode-POLYmode-QUALmode (site: class ann, a ClassSymbol)
| | | | \-> scala.this.annotation.type
| | | \-> annotation.this.TypeConstraint
| | |-- def <init> BYVALmode-EXPRmode (site: class ann, a ClassSymbol)
| | | |-- { super.<init>(); () } EXPRmode (site: <init> in ann, a MethodSymbol with flags <method>)
| | | | |-- super.<init>() BYVALmode-EXPRmode (site: <init> in ann, a MethodSymbol with flags <method>)
| | | | | |-- super.<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: <init> in ann, a MethodSymbol with flags <method>)
| | | | | | |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in ann, a MethodSymbol with flags <method>)
| | | | | | | |-- this EXPRmode (silent: <init> in ann, a MethodSymbol with flags <method>)
| | | | | | | | \-> p.this.ann
| | | | | | | \-> ann.super.type (with underlying type annotation.this.Annotation)
| | | | | | \-> ()annotation.this.Annotation
| | | | | \-> annotation.this.Annotation
| | | | |-- () EXPRmode (site: <init> in ann, a MethodSymbol with flags <method>)
| | | | | \-> scala.this.Unit
| | | | \-> scala.this.Unit
| | | \-> [def <init>] ()p.this.ann
| | \-> [class ann] p.this.ann
| |-- class Seq[T] BYVALmode-EXPRmode (site: package class p, a PackageClassSymbol with flags final <module> <package> <java>)
| | |-- scala.AnyRef FUNmode-TYPEmode (site: class Seq, a ClassSymbol with flags <locked>)
| | | |-- type EXPRmode-POLYmode-QUALmode (site: class Seq, a ClassSymbol with flags <locked>)
| | | | \-> scala.type
| | | \-> scala.this.AnyRef
| | |-- scala.AnyRef FUNmode-TYPEmode (site: class Seq, a ClassSymbol with flags <locked>)
| | | |-- type EXPRmode-POLYmode-QUALmode (site: class Seq, a ClassSymbol with flags <locked>)
| | | | \-> scala.type
| | | \-> scala.this.AnyRef
| | |-- TYPEmode (site: type T in p, a AbstractTypeSymbol with flags <deferred> <param> <locked>)
| | | [adapt] is now a TypeTree()
| | | \->
| | |-- TYPEmode (site: class Seq, a ClassSymbol)
| | | [adapt] is now a TypeTree()
| | | \->
| | |-- def <init> BYVALmode-EXPRmode (site: class Seq, a ClassSymbol)
| | | |-- { super.<init>(); () } EXPRmode (site: <init> in Seq, a MethodSymbol with flags <method>)
| | | | |-- super.<init>() BYVALmode-EXPRmode (site: <init> in Seq, a MethodSymbol with flags <method>)
| | | | | |-- super.<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: <init> in Seq, a MethodSymbol with flags <method>)
| | | | | | |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in Seq, a MethodSymbol with flags <method>)
| | | | | | | |-- this EXPRmode (silent: <init> in Seq, a MethodSymbol with flags <method>)
| | | | | | | | \-> p.this.Seq[T]
| | | | | | | \-> Seq.super.type (with underlying type scala.this.AnyRef)
| | | | | | \-> ()lang.this.Object
| | | | | \-> lang.this.Object
| | | | |-- () EXPRmode (site: <init> in Seq, a MethodSymbol with flags <method>)
| | | | | \-> scala.this.Unit
| | | | \-> scala.this.Unit
| | | \-> [def <init>] ()p.this.Seq[T]
| | |-- def map[U] BYVALmode-EXPRmode (site: class Seq, a ClassSymbol)
| | | |-- Seq[U] TYPEmode (site: method map in Seq, a MethodSymbol with flags <method> <locked>)
| | | | |-- U TYPEmode (site: method map in Seq, a MethodSymbol with flags <method> <locked>)
| | | | | |-- TYPEmode (site: type U in Seq, a TypeSkolem with flags <deferred> <param> <locked>)
| | | | | | [adapt] is now a TypeTree()
| | | | | | \->
| | | | | \-> U&0
| | | | \-> p.this.Seq[U&0]
| | | |-- _root_.scala.Function1[T, U] TYPEmode (site: value f in Seq, a TermSymbol with flags <param> <locked>)
| | | | |-- type EXPRmode-POLYmode-QUALmode (site: value f in Seq, a TermSymbol with flags <param> <locked>)
| | | | | |-- _root_ EXPRmode-POLYmode-QUALmode (site: value f in Seq, a TermSymbol with flags <param> <locked>)
| | | | | | \-> <root>
| | | | | \-> scala.type
| | | | |-- T TYPEmode (site: value f in Seq, a TermSymbol with flags <param> <locked>)
| | | | | \-> T
| | | | |-- U TYPEmode (site: value f in Seq, a TermSymbol with flags <param> <locked>)
| | | | | \-> U&0
| | | | \-> scala.this.Function1[T,U&0]
| | | |-- TYPEmode (site: method map in Seq, a MethodSymbol with flags <method>)
| | | | [adapt] is now a TypeTree()
| | | | \->
| | | |-- _root_.scala.Function1[T, U&0] TYPEmode (site: value f in Seq, a TermSymbol with flags <param>)
| | | | \-> scala.this.Function1[T,U&0]
| | | |-- p.this.Seq[T] TYPEmode (site: method map in Seq, a MethodSymbol with flags <method>)
| | | | \-> p.this.Seq[U&0]
| | | |-- $qmark$qmark$qmark : pt=p.this.Seq[U&0] EXPRmode (site: method map in Seq, a MethodSymbol with flags <method>)
| | | | \-> scala.this.Nothing
| | | \-> [def map] [U](<param> f: scala.this.Function1[T,U])p.this.Seq[U]
| | \-> [class Seq] p.this.Seq[T]
| |-- object Test BYVALmode-EXPRmode (site: package class p, a PackageClassSymbol with flags final <module> <package> <java>)
| | |-- scala.AnyRef FUNmode-TYPEmode (site: module class Test, a ModuleClassSymbol with flags <module>)
| | | |-- type EXPRmode-POLYmode-QUALmode (site: module class Test, a ModuleClassSymbol with flags <module>)
| | | | \-> scala.type
| | | \-> scala.this.AnyRef
| | |-- scala.AnyRef FUNmode-TYPEmode (site: module class Test, a ModuleClassSymbol with flags <module>)
| | | |-- type EXPRmode-POLYmode-QUALmode (site: module class Test, a ModuleClassSymbol with flags <module>)
| | | | \-> scala.type
| | | \-> scala.this.AnyRef
| | |-- def <init> BYVALmode-EXPRmode (site: module class Test, a ModuleClassSymbol with flags <module>)
| | | |-- { super.<init>(); () } EXPRmode (site: <init> in Test, a MethodSymbol with flags <method>)
| | | | |-- super.<init>() BYVALmode-EXPRmode (site: <init> in Test, a MethodSymbol with flags <method>)
| | | | | |-- super.<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: <init> in Test, a MethodSymbol with flags <method>)
| | | | | | |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in Test, a MethodSymbol with flags <method>)
| | | | | | | |-- this EXPRmode (silent: <init> in Test, a MethodSymbol with flags <method>)
| | | | | | | | \-> p.this.Test.type
| | | | | | | \-> Test.super.type
| | | | | | \-> ()lang.this.Object
| | | | | \-> lang.this.Object
| | | | |-- () EXPRmode (site: <init> in Test, a MethodSymbol with flags <method>)
| | | | | \-> scala.this.Unit
| | | | \-> scala.this.Unit
| | | \-> [def <init>] ()p.this.Test.type (with underlying type ()p.this.Test.type)
| | |-- def test BYVALmode-EXPRmode (site: module class Test, a ModuleClassSymbol with flags <module>)
| | | |-- { val seq1 = new Seq[Int @ann].<init>(); val seq2 = seq1.map(((x) => x)); () } EXPRmode (site: method test in Test, a MethodSymbol with flags <method> <locked>)
| | | | |-- new Seq[Int @ann].<init>() EXPRmode (site: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | |-- new Seq[Int @ann].<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | |-- new Seq[Int @ann] EXPRmode-POLYmode-QUALmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | |-- Seq[Int @ann] FUNmode-TYPEmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | | |-- Int @ann TYPEmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | | | |-- Int TYPEmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | | | | \-> scala.this.Int
| | | | | | | | | |-- new ann.<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | | | | |-- new ann EXPRmode-POLYmode-QUALmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | | | | | |-- ann FUNmode-TYPEmode (silent: value seq1 in Test, a TermSymbol with flags <locked>)
| | | | | | | | | | | | \-> p.this.ann
| | | | | | | | | | | \-> p.this.ann
| | | | | | | | | | \-> ()p.this.ann
| | | | | | | | | |-- ()p.this.ann : pt=p.this.ann EXPRmode (silent: value <local seq1> in Test, a TermSymbol)
| | | | | | | | | | \-> p.this.ann
| | | | | | | | | \-> scala.this.Int @p.this.ann
| | | | | | | | \-> p.this.Seq[scala.this.Int @p.this.ann]
| | | | | | | \-> p.this.Seq[scala.this.Int @p.this.ann]
| | | | | | \-> ()p.this.Seq[scala.this.Int @p.this.ann]
| | | | | \-> p.this.Seq[scala.this.Int @p.this.ann]
| | | | |-- p.this.Seq[scala.this.Int @p.this.ann] BYVALmode-EXPRmode (site: method test in Test, a MethodSymbol with flags <method> <locked>)
| | | | | \-> [val seq1] p.this.Seq[scala.this.Int @p.this.ann]
| | | | |-- seq1.map(((x) => x)) EXPRmode (site: value seq2 in Test, a TermSymbol with flags <locked>)
| | | | | |-- seq1.map BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value seq2 in Test, a TermSymbol with flags <locked>)
| | | | | | |-- seq1 EXPRmode-POLYmode-QUALmode (silent: value seq2 in Test, a TermSymbol with flags <locked>)
| | | | | | | \-> seq1.type (with underlying type p.this.Seq[scala.this.Int @p.this.ann])
| | | | | | [adapt] [U](<param> f: scala.this.Function1[T,U])p.this.Seq[U] adapted to [U](<param> f: scala.this.Function1[T,U])p.this.Seq[U]
| | | | | | \-> (<param> f: scala.this.Function1[scala.this.Int @p.this.ann,U])p.this.Seq[U]
| | | | | |-- ((x) => x) : pt=scala.this.Function1[scala.this.Int @p.this.ann,?] BYVALmode-EXPRmode-POLYmode (site: value seq2 in Test, a TermSymbol with flags <locked>)
| | | | | | |-- x EXPRmode (site: value $anonfun in Test, a TermSymbol with flags <synthetic>)
| | | | | | | \-> scala.this.Int @p.this.ann
| | | | | | \-> scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]
| | | | | solving for (U: ?U)
| | | | | \-> p.this.Seq[scala.this.Int]
| | | | |-- p.this.Seq[scala.this.Int] BYVALmode-EXPRmode (site: method test in Test, a MethodSymbol with flags <method> <locked>)
| | | | | \-> [val seq2] p.this.Seq[scala.this.Int]
| | | | |-- () EXPRmode (site: method test in Test, a MethodSymbol with flags <method> <locked>)
| | | | | \-> scala.this.Unit
| | | | \-> scala.this.Unit
| | | \-> [def test] ()scala.this.Unit
| | \-> [object Test] p.this.Test.type
| \-> [package p] <root>.this.p.type
[[syntax trees at end of typer]] // infer.scala
package p {
class ann extends annotation.this.Annotation with annotation.this.StaticAnnotation with annotation.this.TypeConstraint {
<method> <triedcooking> def <init>(): p.this.ann = {
ann.super.<init>();
()
}
};
class Seq[T] extends scala.AnyRef {
<method> <triedcooking> def <init>(): p.this.Seq[T] = {
Seq.super.<init>();
()
};
<method> <triedcooking> def map[U](f: scala.this.Function1[T,U&0]): p.this.Seq[U] = scala.this.Predef.$qmark$qmark$qmark
};
<module> object Test extends scala.AnyRef {
<method> def <init>(): p.this.Test.type = {
Test.super.<init>();
()
};
<method> def test(): scala.this.Unit = {
<triedcooking> val seq1: p.this.Seq[scala.this.Int @p.this.ann] = new p.this.Seq[scala.this.Int @p.this.ann].<init>();
val seq2: p.this.Seq[scala.this.Int] = seq1.map[scala.this.Int](((x: scala.this.Int @p.this.ann) => x));
()
}
}
}
[running phase patmat on infer.scala]
[running phase superaccessors on infer.scala]
[running phase extmethods on infer.scala]
[running phase pickler on infer.scala]
[running phase refchecks on infer.scala]
[running phase uncurry on infer.scala]
|-- { @scala.this.SerialVersionUID(0) final <synthetic> class $anonfun extends runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable { def <init>() = { super.<init>(); () }; <method> final def apply(x: scala.this.Int @p.this.ann): scala.this.Int @p.this.ann = x }; (new <$anon: scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]>.<init>(): scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]) } EXPRmode (site: value seq2 in Test, a TermSymbol) implicits disabled
| |-- class $anonfun BYVALmode-EXPRmode (site: value seq2 in Test, a TermSymbol) implicits disabled
| | |-- def <init> BYVALmode-EXPRmode (site: anonymous class $anonfun, a ClassSymbol with flags final <synthetic>) implicits disabled
| | | |-- { super.<init>(); () } EXPRmode (site: <init> in $anonfun, a MethodSymbol with flags <method>) implicits disabled
| | | | |-- super.<init>() BYVALmode-EXPRmode (site: <init> in $anonfun, a MethodSymbol with flags <method>) implicits disabled
| | | | | |-- super.<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: <init> in $anonfun, a MethodSymbol with flags <method>) implicits disabled
| | | | | | |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in $anonfun, a MethodSymbol with flags <method>) implicits disabled
| | | | | | | |-- this EXPRmode (silent: <init> in $anonfun, a MethodSymbol with flags <method>) implicits disabled
| | | | | | | | \-> runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable
| | | | | | | \-> $anonfun.super.type (with underlying type runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann])
| | | | | | \-> ()runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]
| | | | | \-> runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]
| | | | |-- () EXPRmode (site: <init> in $anonfun, a MethodSymbol with flags <method>) implicits disabled
| | | | | \-> scala.this.Unit
| | | | \-> scala.this.Unit
| | | \-> [def <init>] ()runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable
| | |-- def apply BYVALmode-EXPRmode (site: anonymous class $anonfun, a ClassSymbol with flags final <synthetic>) implicits disabled
| | | \-> [def apply] (<param> <synthetic> x: scala.this.Int @p.this.ann)scala.this.Int @p.this.ann
| | \-> [class $anonfun] runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable
| |-- (new <$anon: scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]>.<init>(): scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]) EXPRmode (site: value seq2 in Test, a TermSymbol) implicits disabled
| | |-- new <$anon: scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]>.<init>() : pt=scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] EXPRmode (site: value seq2 in Test, a TermSymbol) implicits disabled
| | | |-- new <$anon: scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]>.<init> BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value seq2 in Test, a TermSymbol) implicits disabled
| | | | |-- new <$anon: scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]> EXPRmode-POLYmode-QUALmode (silent: value seq2 in Test, a TermSymbol) implicits disabled
| | | | | \-> runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable
| | | | \-> ()runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable
| | | \-> runtime.this.AbstractFunction1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann] with scala.this.Serializable
| | \-> scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]
| \-> scala.this.Function1[scala.this.Int @p.this.ann,scala.this.Int @p.this.ann]
[running phase tailcalls on infer.scala]
[running phase specialize on infer.scala]
[running phase explicitouter on infer.scala]
[running phase erasure on infer.scala]
[running phase posterasure on infer.scala]
[running phase lazyvals on infer.scala]
[running phase lambdalift on infer.scala]
[running phase constructors on infer.scala]
[running phase flatten on infer.scala]
[running phase mixin on infer.scala]
[running phase cleanup on infer.scala]
[running phase delambdafy on infer.scala]
[running phase icode on infer.scala]
[running phase jvm on icode]
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
one warning found
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment