Skip to content

Commit 9a2455a

Browse files
committed
Merge pull request scala#2152 from retronym/topic/annotatedRetyping-2.10.1
SI-7163 backport of annotated retyping to 2.10.1
2 parents f62d35b + 26be206 commit 9a2455a

File tree

5 files changed

+87
-9
lines changed

5 files changed

+87
-9
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4153,15 +4153,11 @@ trait Typers extends Modes with Adaptations with Tags {
41534153
def resultingTypeTree(tpe: Type) = {
41544154
// we need symbol-ful originals for reification
41554155
// hence we go the extra mile to hand-craft tis guy
4156-
val original =
4157-
if (arg1.isType)
4158-
arg1 match {
4159-
case tt @ TypeTree() => Annotated(ann, tt.original)
4160-
// this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)"
4161-
case _ => Annotated(ann, arg1)
4162-
}
4163-
else
4164-
tree
4156+
val original = arg1 match {
4157+
case tt @ TypeTree() => Annotated(ann, tt.original)
4158+
// this clause is needed to correctly compile stuff like "new C @D" or "@(inline @getter)"
4159+
case _ => Annotated(ann, arg1)
4160+
}
41654161
original setType ann.tpe
41664162
TypeTree(tpe) setOriginal original setPos tree.pos.focus
41674163
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Bug {
2+
M.m {
3+
def s = ""
4+
M.m(s): @unchecked // error: macro has not been expanded.
5+
???
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import language.experimental.macros
2+
import reflect.macros.Context
3+
4+
object M {
5+
def impl(c: Context)(a: c.Expr[Any]) = c.Expr[Any](c.resetLocalAttrs(a.tree))
6+
def m(a: Any) = macro impl
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
typing List(1, 2).map(((x) => {
2+
val another = scala.Tuple2(t.nt, t.tr): @testAnn match {
3+
case scala.Tuple2(_, _) => 1
4+
};
5+
x
6+
}))
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import scala.tools.partest._
2+
import scala.tools.nsc._
3+
4+
object Test extends DirectTest {
5+
6+
override def extraSettings: String = "-usejavacp"
7+
8+
def code = """
9+
class testAnn extends annotation.Annotation
10+
11+
object t {
12+
def nt = 1
13+
def tr = "a"
14+
}
15+
16+
class Test {
17+
List(1,2).map(x => {
18+
val another = ((t.nt, t.tr): @testAnn) match { case (_, _) => 1 }
19+
x
20+
})
21+
}
22+
""".trim
23+
24+
25+
// point of this test: type-check the "Annotated" tree twice. first time the analyzer plugin types it,
26+
// second time the typer.
27+
28+
// bug was that typedAnnotated assigned a type to the Annotated tree. The second type check would consider
29+
// the tree as alreadyTyped, which is not cool, the Annotated needs to be transformed into a Typed tree.
30+
31+
def show() {
32+
val global = newCompiler()
33+
import global._
34+
import analyzer._
35+
import collection.{mutable => m}
36+
37+
object analyzerPlugin extends AnalyzerPlugin {
38+
val templates: m.Map[Symbol, (Template, Typer)] = m.Map()
39+
override def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = {
40+
defTree match {
41+
case impl: Template =>
42+
templates += typer.context.owner -> (impl, typer)
43+
44+
case dd: DefDef if dd.symbol.isPrimaryConstructor && templates.contains(dd.symbol.owner) =>
45+
val (impl, templTyper) = templates(dd.symbol.owner)
46+
for (stat <- impl.body.filterNot(_.isDef)) {
47+
println("typing "+ stat)
48+
val statsOwner = impl.symbol orElse templTyper.context.owner.newLocalDummy(impl.pos)
49+
val tpr = analyzer.newTyper(templTyper.context.make(stat, statsOwner))
50+
tpr.typed(stat)
51+
}
52+
53+
case _ =>
54+
}
55+
tpe
56+
}
57+
}
58+
59+
addAnalyzerPlugin(analyzerPlugin)
60+
compileString(global)(code)
61+
}
62+
}

0 commit comments

Comments
 (0)