diff options
author | Martin Odersky <odersky@gmail.com> | 2010-03-08 13:43:12 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2010-03-08 13:43:12 +0000 |
commit | 2b0dcfe63622e24dd03da82245cc584a146321c2 (patch) | |
tree | 2641bac8f551d65d94c9c65acf322d48a843011b /src | |
parent | 7144b4990f2c90002286ebf31a395c36024adcd2 (diff) | |
download | scala-2b0dcfe63622e24dd03da82245cc584a146321c2.tar.gz scala-2b0dcfe63622e24dd03da82245cc584a146321c2.tar.bz2 scala-2b0dcfe63622e24dd03da82245cc584a146321c2.zip |
Closes #3006.
Diffstat (limited to 'src')
4 files changed, 108 insertions, 97 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 1b7503f7d7..9097dd460e 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -332,6 +332,12 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable => case class Parens(args: List[Tree]) extends Tree // only used during parsing +// ----- subconstructors -------------------------------------------- + + class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args) + + class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args) + // ----- auxiliary objects and methods ------------------------------ abstract class TreeCopier { @@ -439,7 +445,11 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable => def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = new TypeApply(fun, args).copyAttrs(tree) def Apply(tree: Tree, fun: Tree, args: List[Tree]) = - new Apply(fun, args).copyAttrs(tree) + (tree match { + case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args) + case _: ApplyImplicitView => new ApplyImplicitView(fun, args) + case _ => new Apply(fun, args) + }).copyAttrs(tree) def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = new ApplyDynamic(qual, args).copyAttrs(tree) def Super(tree: Tree, qual: Name, mix: Name) = diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 6ab6927412..ea324799b4 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -147,8 +147,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { * only once per class. The mixedin flag is used to remember whether late * members have been added to an interface. * - lazy fields don't get a setter. - * - * @param clazz ... */ def addLateInterfaceMembers(clazz: Symbol) { if ((treatedClassInfos get clazz) != Some(clazz.info)) { diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 28eebdc033..7e7adb12be 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -922,8 +922,7 @@ abstract class RefChecks extends InfoTransform { if (sym.isDeprecated && !currentOwner.ownerChain.exists(_.isDeprecated)) { val dmsg = sym.deprecationMessage val msg = sym.toString + sym.locationString +" is deprecated"+ - (if (dmsg.isDefined) ": "+ dmsg.get - else "") + (if (dmsg.isDefined) ": "+ dmsg.get else "") unit.deprecationWarning(pos, msg) } } @@ -1021,7 +1020,7 @@ abstract class RefChecks extends InfoTransform { } } val newResult = localTyper.typedPos(tree.pos) { - Apply(Apply(Select(gen.mkAttributedRef(ArrayModule), nme.ofDim), args), List(manif)) + new ApplyToImplicitArgs(Apply(Select(gen.mkAttributedRef(ArrayModule), nme.ofDim), args), List(manif)) } currentApplication = tree newResult @@ -1079,106 +1078,109 @@ abstract class RefChecks extends InfoTransform { } } - override def transform(tree: Tree): Tree = try { + override def transform(tree: Tree): Tree = { val savedLocalTyper = localTyper val savedCurrentApplication = currentApplication - val sym = tree.symbol + try { + val sym = tree.symbol - // Apply RefChecks to annotations. Makes sure the annotations conform to - // type bounds (bug #935), issues deprecation warnings for symbols used - // inside annotations. - applyRefchecksToAnnotations(tree) + // Apply RefChecks to annotations. Makes sure the annotations conform to + // type bounds (bug #935), issues deprecation warnings for symbols used + // inside annotations. + applyRefchecksToAnnotations(tree) + + var result: Tree = tree match { + case DefDef(mods, name, tparams, vparams, tpt, EmptyTree) if tree.symbol.hasAnnotation(NativeAttr) => + tree.symbol.resetFlag(DEFERRED) + transform(treeCopy.DefDef(tree, mods, name, tparams, vparams, tpt, + typed(Apply(gen.mkAttributedRef(Predef_error), List(Literal("native method stub")))))) + + case ValDef(_, _, _, _) | DefDef(_, _, _, _, _, _) => + checkDeprecatedOvers(tree) + tree + + case Template(parents, self, body) => + localTyper = localTyper.atOwner(tree, currentOwner) + validateBaseTypes(currentOwner) + checkDefaultsInOverloaded(currentOwner) + val bridges = addVarargBridges(currentOwner) + checkAllOverrides(currentOwner) + + if (bridges.nonEmpty) treeCopy.Template(tree, parents, self, body ::: bridges) + else tree + + case TypeTree() => + val existentialParams = new ListBuffer[Symbol] + doTypeTraversal(tree) { // check all bounds, except those that are + // existential type parameters + case ExistentialType(tparams, tpe) => + existentialParams ++= tparams + case t: TypeRef => + val exparams = existentialParams.toList + val wildcards = exparams map (_ => WildcardType) + checkTypeRef(t.subst(exparams, wildcards), tree.pos) + case _ => + } + tree - var result: Tree = tree match { - case DefDef(mods, name, tparams, vparams, tpt, EmptyTree) if tree.symbol.hasAnnotation(NativeAttr) => - tree.symbol.resetFlag(DEFERRED) - transform(treeCopy.DefDef(tree, mods, name, tparams, vparams, tpt, - typed(Apply(gen.mkAttributedRef(Predef_error), List(Literal("native method stub")))))) + case TypeApply(fn, args) => + checkBounds(NoPrefix, NoSymbol, fn.tpe.typeParams, args map (_.tpe), tree.pos) + transformCaseApply(tree, ()) - case ValDef(_, _, _, _) | DefDef(_, _, _, _, _, _) => - checkDeprecatedOvers(tree) - tree + case x @ Apply(_, _) => + transformApply(x) - case Template(parents, self, body) => - localTyper = localTyper.atOwner(tree, currentOwner) - validateBaseTypes(currentOwner) - checkDefaultsInOverloaded(currentOwner) - val bridges = addVarargBridges(currentOwner) - checkAllOverrides(currentOwner) - - if (bridges.nonEmpty) treeCopy.Template(tree, parents, self, body ::: bridges) - else tree - - case TypeTree() => - val existentialParams = new ListBuffer[Symbol] - doTypeTraversal(tree) { // check all bounds, except those that are - // existential type parameters - case ExistentialType(tparams, tpe) => - existentialParams ++= tparams - case t: TypeRef => - val exparams = existentialParams.toList - val wildcards = exparams map (_ => WildcardType) - checkTypeRef(t.subst(exparams, wildcards), tree.pos) - case _ => - } - tree + case x @ If(_, _, _) => + transformIf(x) - case TypeApply(fn, args) => - checkBounds(NoPrefix, NoSymbol, fn.tpe.typeParams, args map (_.tpe), tree.pos) - transformCaseApply(tree, ()) + case New(tpt) => + enterReference(tree.pos, tpt.tpe.typeSymbol) + tree - case x @ Apply(_, _) => - transformApply(x) + case Typed(expr, tpt @ Ident(name)) if name == nme.WILDCARD_STAR.toTypeName && !isRepeatedParamArg(tree) => + unit.error(tree.pos, "no `: _*' annotation allowed here\n"+ + "(such annotations are only allowed in arguments to *-parameters)") + tree - case x @ If(_, _, _) => - transformIf(x) + case Ident(name) => + transformCaseApply(tree, + if (name != nme.WILDCARD && name != nme.WILDCARD_STAR.toTypeName) { + assert(sym != NoSymbol, tree) //debug + enterReference(tree.pos, sym) + } + ) - case New(tpt) => - enterReference(tree.pos, tpt.tpe.typeSymbol) - tree + case x @ Select(_, _) => + transformSelect(x) - case Typed(expr, tpt @ Ident(name)) if name == nme.WILDCARD_STAR.toTypeName && !isRepeatedParamArg(tree) => - unit.error(tree.pos, "no `: _*' annotation allowed here\n"+ - "(such annotations are only allowed in arguments to *-parameters)") + case _ => tree + } + result = result match { + case CaseDef(pat, guard, body) => + inPattern = true + val pat1 = transform(pat) + inPattern = false + treeCopy.CaseDef(tree, pat1, transform(guard), transform(body)) + case _ => + super.transform(result) + } + result match { + case ClassDef(_, _, _, _) + | TypeDef(_, _, _, _) => + if (result.symbol.isLocal || result.symbol.owner.isPackageClass) + varianceValidator.traverse(result) + case _ => + } + result + } catch { + case ex: TypeError => + if (settings.debug.value) ex.printStackTrace(); + unit.error(tree.pos, ex.getMessage()) tree - - case Ident(name) => - transformCaseApply(tree, - if (name != nme.WILDCARD && name != nme.WILDCARD_STAR.toTypeName) { - assert(sym != NoSymbol, tree) //debug - enterReference(tree.pos, sym) - } - ) - - case x @ Select(_, _) => - transformSelect(x) - - case _ => tree + } finally { + localTyper = savedLocalTyper + currentApplication = savedCurrentApplication } - result = result match { - case CaseDef(pat, guard, body) => - inPattern = true - val pat1 = transform(pat) - inPattern = false - treeCopy.CaseDef(tree, pat1, transform(guard), transform(body)) - case _ => - super.transform(result) - } - result match { - case ClassDef(_, _, _, _) - | TypeDef(_, _, _, _) => - if (result.symbol.isLocal || result.symbol.owner.isPackageClass) - varianceValidator.traverse(result) - case _ => - } - localTyper = savedLocalTyper - currentApplication = savedCurrentApplication - result - } catch { - case ex: TypeError => - if (settings.debug.value) ex.printStackTrace(); - unit.error(tree.pos, ex.getMessage()) - tree } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d64fc26f15..4a29491cde 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -208,7 +208,7 @@ trait Typers { self: Analyzer => s traverse fun for (arg <- args) s traverse arg } - Apply(fun, args) setPos fun.pos + new ApplyToImplicitArgs(fun, args) setPos fun.pos case ErrorType => fun } @@ -1009,7 +1009,7 @@ trait Typers { self: Analyzer => if (coercion != EmptyTree) { if (settings.debug.value) log("inferred view from "+tree.tpe+" to "+pt+" = "+coercion+":"+coercion.tpe) return newTyper(context.makeImplicit(context.reportAmbiguousErrors)).typed( - Apply(coercion, List(tree)) setPos tree.pos, mode, pt) + new ApplyImplicitView(coercion, List(tree)) setPos tree.pos, mode, pt) } } } @@ -1039,6 +1039,7 @@ trait Typers { self: Analyzer => ((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue) && phase.id <= currentRun.typerPhase.id && !qtpe.isError && qtpe.typeSymbol != NullClass && qtpe.typeSymbol != NothingClass && qtpe != WildcardType && + !qual.isInstanceOf[ApplyImplicitView] && // don't chain views context.implicitsEnabled) { // don't try to adapt a top-level type that's the subject of an implicit search // this happens because, if isView, typedImplicit tries to apply the "current" implicit value to // a value that needs to be coerced, so we check whether the implicit value has an `apply` method @@ -1050,7 +1051,7 @@ trait Typers { self: Analyzer => } val coercion = inferView(qual, qtpe, searchTemplate, true) if (coercion != EmptyTree) - typedQualifier(atPos(qual.pos)(Apply(coercion, List(qual)))) + typedQualifier(atPos(qual.pos)(new ApplyImplicitView(coercion, List(qual)))) else qual } else { @@ -3979,7 +3980,7 @@ trait Typers { self: Analyzer => error(tree.pos, "cannot create a generic multi-dimensional array of more than "+MaxArrayDims+" dimensions") val newArrayApp = atPos(tree.pos) { val manif = getManifestTree(tree.pos, manifType, false) - Apply(Select(manif, if (level == 1) "newArray" else "newArray"+level), args) + new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args) } typed(newArrayApp, mode, pt) case tree1 => |