diff options
author | Paul Phillips <paulp@improving.org> | 2013-01-14 23:29:50 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-01-26 11:19:36 -0800 |
commit | 832fc9a67e5aa85bdde61883527d3ac9554094d7 (patch) | |
tree | b5bc08f2ef57331efa66c956112bface14cd530f /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | 72f36cbc80d5667c5ada3b7c0fe60435a4b202ad (diff) | |
download | scala-832fc9a67e5aa85bdde61883527d3ac9554094d7.tar.gz scala-832fc9a67e5aa85bdde61883527d3ac9554094d7.tar.bz2 scala-832fc9a67e5aa85bdde61883527d3ac9554094d7.zip |
SI-2577, SI-6860: annotation type inference.
This is less than ideal:
scala> class Bippy[T] extends annotation.StaticAnnotation
defined class Bippy
scala> def f: Int @Bippy = 5
f: Int @Bippy[T]
Turns out we can infer such types. Now it says:
scala> def f: Int @Bippy = 5
f: Int @Bippy[Nothing]
This should put to rest many an issue with parameterized
annotations.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index f2f8f47bf2..c12233b726 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3458,31 +3458,28 @@ trait Typers extends Adaptations with Tags { } // begin typedAnnotation - val (fun, argss) = { - def extract(fun: Tree, outerArgss: List[List[Tree]]): - (Tree, List[List[Tree]]) = fun match { - case Apply(f, args) => - extract(f, args :: outerArgss) - case Select(New(tpt), nme.CONSTRUCTOR) => - (fun, outerArgss) - case _ => - reportAnnotationError(UnexpectedTreeAnnotation(fun)) - (setError(fun), outerArgss) - } - extract(ann, List()) - } + val treeInfo.Applied(fun0, targs, argss) = treeInfo.dissectApplied(ann) + val typedFun0 = typed(fun0, forFunMode(mode), WildcardType) + val typedFunPart = ( + // If there are dummy type arguments in typeFun part, it suggests we + // must type the actual constructor call, not only the select. The value + // arguments are how the type arguments will be inferred. + if (targs.isEmpty && typedFun0.exists(t => isDummyAppliedType(t.tpe))) + logResult(s"Retyped $typedFun0 to find type args")(typed(argss.foldLeft(fun0)(Apply(_, _)))) + else + typedFun0 + ) + val typedFun @ Select(New(annTpt), _) = treeInfo.dissectApplied(typedFunPart).core + val annType = annTpt.tpe - val res = if (fun.isErroneous) ErroneousAnnotation + val res = if (typedFun.isErroneous) ErroneousAnnotation else { - val typedFun @ Select(New(tpt), _) = typed(fun, mode.forFunMode, WildcardType) - val annType = tpt.tpe - if (typedFun.isErroneous) ErroneousAnnotation else if (annType.typeSymbol isNonBottomSubClass ClassfileAnnotationClass) { // annotation to be saved as java classfile annotation val isJava = typedFun.symbol.owner.isJavaDefined if (!annType.typeSymbol.isNonBottomSubClass(annClass)) { - reportAnnotationError(AnnotationTypeMismatchError(tpt, annClass.tpe, annType)) + reportAnnotationError(AnnotationTypeMismatchError(annTpt, annType, annType)) } else if (argss.length > 1) { reportAnnotationError(MultipleArgumentListForAnnotationError(ann)) } else { @@ -3534,7 +3531,7 @@ trait Typers extends Adaptations with Tags { val typedAnn = if (selfsym == NoSymbol) { // local dummy fixes SI-5544 val localTyper = newTyper(context.make(ann, context.owner.newLocalDummy(ann.pos))) - localTyper.typed(ann, mode, annClass.tpe) + localTyper.typed(ann, mode, annType) } else { // Since a selfsym is supplied, the annotation should have an extra @@ -3548,7 +3545,7 @@ trait Typers extends Adaptations with Tags { // sometimes does. The problem is that "self" ident's within // annot.constr will retain the old symbol from the previous typing. val func = Function(funcparm :: Nil, ann.duplicate) - val funcType = appliedType(FunctionClass(1), selfsym.info, annClass.tpe_*) + val funcType = appliedType(FunctionClass(1), selfsym.info, annType) val Function(arg :: Nil, rhs) = typed(func, mode, funcType) rhs.substituteSymbols(arg.symbol :: Nil, selfsym :: Nil) |