summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-01-14 23:29:50 -0800
committerPaul Phillips <paulp@improving.org>2013-01-26 11:19:36 -0800
commit832fc9a67e5aa85bdde61883527d3ac9554094d7 (patch)
treeb5bc08f2ef57331efa66c956112bface14cd530f /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent72f36cbc80d5667c5ada3b7c0fe60435a4b202ad (diff)
downloadscala-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.scala37
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)