diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 25 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/CleanUp.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Flatten.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 23 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 92 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 12 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeGen.scala | 5 | ||||
-rw-r--r-- | test/files/run/t0091.check | 1 | ||||
-rw-r--r-- | test/files/run/t0091.scala | 15 |
16 files changed, 119 insertions, 120 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index 3129748e9f..1c6bba19b3 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -30,24 +30,17 @@ trait TreeDSL { def returning[T](x: T)(f: T => Unit): T = util.returning(x)(f) object LIT extends (Any => Literal) { + def typed(x: Any) = apply(x) setType ConstantType(Constant(x)) def apply(x: Any) = Literal(Constant(x)) def unapply(x: Any) = condOpt(x) { case Literal(Constant(value)) => value } } - // You might think these could all be vals, but empirically I have found that - // at least in the case of UNIT the compiler breaks if you re-use trees. - // However we need stable identifiers to have attractive pattern matching. - // So it's inconsistent until I devise a better way. - val TRUE = LIT(true) - val FALSE = LIT(false) - val ZERO = LIT(0) - def NULL = LIT(null) - def UNIT = LIT(()) - - // for those preferring boring, predictable lives, without the thrills of tree-sharing - // (but with the perk of typed trees) - def TRUE_typed = LIT(true) setType ConstantType(Constant(true)) - def FALSE_typed = LIT(false) setType ConstantType(Constant(false)) + // Boring, predictable trees. + def TRUE = LIT typed true + def FALSE = LIT typed false + def ZERO = LIT(0) + def NULL = LIT(null) + def UNIT = LIT(()) object WILD { def empty = Ident(nme.WILDCARD) @@ -106,6 +99,10 @@ trait TreeDSL { def DOT(sym: Symbol) = SelectStart(Select(target, sym)) /** Assignment */ + // !!! This method is responsible for some tree sharing, but a diligent + // reviewer pointed out that we shouldn't blindly duplicate these trees + // as there might be DefTrees nested beneath them. It's not entirely + // clear how to proceed, so for now it retains the non-duplicating behavior. def ===(rhs: Tree) = Assign(target, rhs) /** Methods for sequences **/ diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index bec6de46d0..af874ed28c 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -65,28 +65,10 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { // Builds a tree of the form "{ lhs = rhs ; lhs }" def mkAssignAndReturn(lhs: Symbol, rhs: Tree): Tree = { - val lhsRef = mkUnattributedRef(lhs) + def lhsRef = if (lhs.owner.isClass) Select(This(lhs.owner), lhs) else Ident(lhs) Block(Assign(lhsRef, rhs) :: Nil, lhsRef) } - def mkModuleVarDef(accessor: Symbol) = { - val inClass = accessor.owner.isClass - val extraFlags = if (inClass) PrivateLocal | SYNTHETIC else 0 - - val mval = ( - accessor.owner.newVariable(nme.moduleVarName(accessor.name.toTermName), accessor.pos.focus, MODULEVAR | extraFlags) - setInfo accessor.tpe.finalResultType - addAnnotation VolatileAttr - ) - if (inClass) - mval.owner.info.decls enter mval - - ValDef(mval) - } - - def mkModuleAccessDef(accessor: Symbol, msym: Symbol) = - DefDef(accessor, Select(This(msym.owner), msym)) - def newModule(accessor: Symbol, tpe: Type) = { val ps = tpe.typeSymbol.primaryConstructor.info.paramTypes if (ps.isEmpty) New(tpe) diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 765ef39e6b..39460ef004 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -620,9 +620,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL { // create a symbol for the static field val stfieldSym = ( currentClass.newVariable(mkTerm("symbol$"), pos, PRIVATE | STATIC | SYNTHETIC | FINAL) - setInfo SymbolClass.tpe + setInfoAndEnter SymbolClass.tpe ) - currentClass.info.decls enter stfieldSym // create field definition and initialization val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ba799f9186..45bd5cf003 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -522,7 +522,7 @@ abstract class Erasure extends AddInterfaces && !exitingErasure((member.tpe <:< other.tpe))) // no static guarantees (TODO: is the subtype test ever true?) import CODE._ - val _false = FALSE_typed + val _false = FALSE val pt = member.tpe.resultType lazy val zero = if (_false.tpe <:< pt) _false diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala index 717c4b627b..77e7e013ab 100644 --- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala +++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala @@ -232,12 +232,13 @@ abstract class ExtensionMethods extends Transform with TypingTransformers { override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = super.transformStats(stats, exprOwner) map { - case md @ ModuleDef(_, _, _) if extensionDefs contains md.symbol => - val defns = extensionDefs(md.symbol).toList map (member => - atOwner(md.symbol)(localTyper.typedPos(md.pos.focus)(member)) - ) - extensionDefs -= md.symbol - deriveModuleDef(md)(tmpl => deriveTemplate(tmpl)(_ ++ defns)) + case md @ ModuleDef(_, _, _) => + val extraStats = extensionDefs remove md.symbol match { + case Some(defns) => defns.toList map (defn => atOwner(md.symbol)(localTyper.typedPos(md.pos.focus)(defn.duplicate))) + case _ => Nil + } + if (extraStats.isEmpty) md + else deriveModuleDef(md)(tmpl => deriveTemplate(tmpl)(_ ++ extraStats)) case stat => stat } diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index a52dadb134..b2602f47de 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -23,7 +23,7 @@ abstract class Flatten extends InfoTransform { val old = (scope lookupUnshadowedEntries sym.name).toList old foreach (scope unlink _) scope enter sym - log(s"lifted ${sym.fullLocationString}" + ( if (old.isEmpty) "" else " after unlinking $old from scope." )) + log(s"lifted ${sym.fullLocationString}" + ( if (old.isEmpty) "" else s" after unlinking $old from scope." )) old } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 39b894fbef..45ef083b66 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -867,7 +867,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { val cond = Apply(Select(moduleVarRef, Object_eq), List(NULL)) mkFastPathBody(clazz, moduleSym, cond, List(assign), List(NULL), returnTree, attrThis, args) case _ => - abort("Invalid getter " + rhs + " for module in class " + clazz) + abort(s"Invalid getter $rhs for module in $clazz") } def mkCheckedAccessor(clazz: Symbol, retVal: Tree, offset: Int, pos: Position, fieldSym: Symbol): Tree = { @@ -875,7 +875,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { val bitmapSym = bitmapFor(clazz, offset, sym) val kind = bitmapKind(sym) val mask = maskForOffset(offset, sym, kind) - val msg = "Uninitialized field: " + unit.source + ": " + pos.line + val msg = s"Uninitialized field: ${unit.source}: ${pos.line}" val result = IF (mkTest(clazz, mask, bitmapSym, false, kind)) . THEN (retVal) . @@ -1035,16 +1035,17 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { } // if class is not a trait add accessor definitions else if (!clazz.isTrait) { + // This needs to be a def to avoid sharing trees + def accessedRef = accessedReference(sym) if (sym.hasAccessorFlag && (!sym.isDeferred || sym.hasFlag(lateDEFERRED))) { // add accessor definitions addDefDef(sym, { - val accessedRef = accessedReference(sym) if (sym.isSetter) { if (isOverriddenSetter(sym)) UNIT else accessedRef match { - case Literal(_) => accessedRef - case _ => - val init = Assign(accessedRef, Ident(sym.firstParam)) + case ref @ Literal(_) => ref + case ref => + val init = Assign(ref, Ident(sym.firstParam)) val getter = sym.getter(clazz) if (!needsInitFlag(getter)) init @@ -1059,11 +1060,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { } else if (sym.isModule && !(sym hasFlag LIFTED | BRIDGE)) { // add modules - val vdef = gen.mkModuleVarDef(sym) - addDef(position(sym), vdef) + val vsym = sym.owner.newModuleVarSymbol(sym) + addDef(position(sym), ValDef(vsym)) - val rhs = gen.newModule(sym, vdef.symbol.tpe) - val assignAndRet = gen.mkAssignAndReturn(vdef.symbol, rhs) + // !!! TODO - unravel the enormous duplication between this code and + // eliminateModuleDefs in RefChecks. + val rhs = gen.newModule(sym, vsym.tpe) + val assignAndRet = gen.mkAssignAndReturn(vsym, rhs) val attrThis = gen.mkAttributedThis(clazz) val rhs1 = mkInnerClassAccessorDoubleChecked(attrThis, assignAndRet, sym, List()) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 90ea93d7b2..90ea6c94d8 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -362,11 +362,11 @@ abstract class UnCurry extends InfoTransform val body = bodyForIDA match { case Match(selector, cases) => - if (cases exists treeInfo.isDefaultCase) TRUE_typed + if (cases exists treeInfo.isDefaultCase) TRUE else doSubst(Match(/*gen.mkUnchecked*/(selector), - (cases map (c => deriveCaseDef(c)(x => TRUE_typed))) :+ ( - DEFAULT ==> FALSE_typed))) + (cases map (c => deriveCaseDef(c)(x => TRUE))) :+ ( + DEFAULT ==> FALSE))) } body.changeOwner(fun.symbol -> methSym) @@ -640,7 +640,7 @@ abstract class UnCurry extends InfoTransform tree1 } ) - assert(result.tpe != null, result + " tpe is null") + assert(result.tpe != null, result.shortClass + " tpe is null:\n" + result) result setType uncurryTreeType(result.tpe) } diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 18bc95af39..d74d5ecfbe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -50,7 +50,9 @@ trait MethodSynthesis { class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) { def mkThis = This(clazz) setPos clazz.pos.focus - def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(Select(mkThis, sym)) + def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)( + if (clazz.isClass) Select(This(clazz), sym) else Ident(sym) + ) private def isOverride(name: TermName) = clazzMember(name).alternatives exists (sym => !sym.isDeferred && (sym.owner != clazz)) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index 42c34526d7..ede117f51a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -1146,7 +1146,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val expectedOuter = expectedTp.prefix match { case ThisType(clazz) => THIS(clazz) case pre if pre != NoType => REF(pre.prefix, pre.termSymbol) - case _ => TRUE_typed // fallback for SI-6183 + case _ => TRUE // fallback for SI-6183 } // ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` by `Select(q, outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix` @@ -1278,10 +1278,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // one alternative may still generate multiple trees (e.g., an extractor call + equality test) // (for now,) alternatives may not bind variables (except wildcards), so we don't care about the final substitution built internally by makeTreeMakers val combinedAlts = altss map (altTreeMakers => - ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE_typed)))(casegen)) + ((casegen: Casegen) => combineExtractors(altTreeMakers :+ TrivialTreeMaker(casegen.one(TRUE)))(casegen)) ) - val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => FALSE_typed)) + val findAltMatcher = codegenAlt.matcher(EmptyTree, NoSymbol, BooleanClass.tpe)(combinedAlts, Some(x => FALSE)) codegenAlt.ifThenElseZero(findAltMatcher, substitution(next)) } } @@ -3241,7 +3241,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL } } - private val defaultLabel: Symbol = newSynthCaseLabel("default") + private val defaultLabel: Symbol = newSynthCaseLabel("default") /** Collapse guarded cases that switch on the same constant (the last case may be unguarded). * @@ -3682,7 +3682,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def flatMapCondStored(cond: Tree, condSym: Symbol, res: Tree, nextBinder: Symbol, next: Tree): Tree = ifThenElseZero(cond, BLOCK( - condSym === TRUE_typed, + condSym === TRUE, nextBinder === res, next )) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index b2334faa71..396c6acd38 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1251,57 +1251,61 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans finally popLevel() } - /** Eliminate ModuleDefs. - * - A top level object is replaced with their module class. - * - An inner object is transformed into a module var, created on first access. + /** Eliminate ModuleDefs. In all cases the ModuleDef (carrying a module symbol) is + * replaced with a ClassDef (carrying the corresponding module class symbol) with additional + * trees created as follows: * - * In both cases, this transformation returns the list of replacement trees: - * - Top level: the module class accessor definition - * - Inner: a class definition, declaration of module var, and module var accessor + * 1) A statically reachable object (either top-level or nested only in objects) receives + * no additional trees. + * 2) An inner object which matches an existing member (e.g. implements an interface) + * receives an accessor DefDef to implement the interface. + * 3) An inner object otherwise receives a private ValDef which declares a module var + * (the field which holds the module class - it has a name like Foo$module) and an + * accessor for that field. The instance is created lazily, on first access. */ - private def eliminateModuleDefs(tree: Tree): List[Tree] = { - val ModuleDef(mods, name, impl) = tree - val sym = tree.symbol - val classSym = sym.moduleClass - val cdef = ClassDef(mods | MODULE, name.toTypeName, Nil, impl) setSymbol classSym setType NoType - - def findOrCreateModuleVar() = localTyper.typedPos(tree.pos) { - // See SI-5012, SI-6712. + private def eliminateModuleDefs(moduleDef: Tree): List[Tree] = exitingRefchecks { + val ModuleDef(mods, name, impl) = moduleDef + val module = moduleDef.symbol + val site = module.owner + val moduleName = module.name.toTermName + // The typer doesn't take kindly to seeing this ClassDef; we have to + // set NoType so it will be ignored. + val cdef = ClassDef(module.moduleClass, impl) setType NoType + + // Create the module var unless the immediate owner is a class and + // the module var already exists there. See SI-5012, SI-6712. + def findOrCreateModuleVar() = { val vsym = ( - if (sym.owner.isTerm) NoSymbol - else sym.enclClass.info.decl(nme.moduleVarName(sym.name.toTermName)) + if (site.isTerm) NoSymbol + else site.info decl nme.moduleVarName(moduleName) ) - // In case we are dealing with local symbol then we already have - // to correct error with forward reference - if (vsym == NoSymbol) gen.mkModuleVarDef(sym) - else ValDef(vsym) + vsym orElse (site newModuleVarSymbol module) } - def createStaticModuleAccessor() = exitingRefchecks { - val method = ( - sym.owner.newMethod(sym.name.toTermName, sym.pos, (sym.flags | STABLE) & ~MODULE) - setInfoAndEnter NullaryMethodType(sym.moduleClass.tpe) - ) - localTyper.typedPos(tree.pos)(gen.mkModuleAccessDef(method, sym)) + def newInnerObject() = { + // Create the module var unless it is already in the module owner's scope. + // The lookup is on module.enclClass and not module.owner lest there be a + // nullary method between us and the class; see SI-5012. + val moduleVar = findOrCreateModuleVar() + val rhs = gen.newModule(module, moduleVar.tpe) + val body = if (site.isTrait) rhs else gen.mkAssignAndReturn(moduleVar, rhs) + val accessor = DefDef(module, body.changeOwner(moduleVar -> module)) + + ValDef(moduleVar) :: accessor :: Nil } - def createInnerModuleAccessor(vdef: Tree) = List( - vdef, - localTyper.typedPos(tree.pos) { - val vsym = vdef.symbol - exitingRefchecks { - val rhs = gen.newModule(sym, vsym.tpe) - val body = if (sym.owner.isTrait) rhs else gen.mkAssignAndReturn(vsym, rhs) - DefDef(sym, body.changeOwner(vsym -> sym)) - } - } - ) - transformTrees(cdef :: { - if (!sym.isStatic) - createInnerModuleAccessor(findOrCreateModuleVar) - else if (sym.isOverridingSymbol) - List(createStaticModuleAccessor()) + def matchingInnerObject() = { + val newFlags = (module.flags | STABLE) & ~MODULE + val newInfo = NullaryMethodType(module.moduleClass.tpe) + val accessor = site.newMethod(moduleName, module.pos, newFlags) setInfoAndEnter newInfo + + DefDef(accessor, Select(This(site), module)) :: Nil + } + val newTrees = cdef :: ( + if (module.isStatic) + if (module.isOverridingSymbol) matchingInnerObject() else Nil else - Nil - }) + newInnerObject() + ) + transformTrees(newTrees map localTyper.typedPos(moduleDef.pos)) } def transformStat(tree: Tree, index: Int): List[Tree] = tree match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index fd6acc25cc..a1c1b53cce 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2508,7 +2508,7 @@ trait Typers extends Modes with Adaptations with Tags { import CODE._ // need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up - val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE_typed)).duplicate.asInstanceOf[CaseDef]) else Nil + val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE)).duplicate.asInstanceOf[CaseDef]) else Nil // println("casesTrue "+ casesTrue) def parentsPartial(targs: List[Type]) = addSerializable(appliedType(AbstractPartialFunctionClass.typeConstructor, targs)) @@ -2594,7 +2594,7 @@ trait Typers extends Modes with Adaptations with Tags { methodSym setInfoAndEnter MethodType(paramSyms, BooleanClass.tpe) val match_ = methodBodyTyper.typedMatch(gen.mkUnchecked(selector), casesTrue, mode, BooleanClass.tpe) - val body = methodBodyTyper.virtualizedMatch(match_ updateAttachment DefaultOverrideMatchAttachment(FALSE_typed), mode, BooleanClass.tpe) + val body = methodBodyTyper.virtualizedMatch(match_ updateAttachment DefaultOverrideMatchAttachment(FALSE), mode, BooleanClass.tpe) DefDef(methodSym, body) } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 1f8658cc86..8e776b8590 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -243,6 +243,18 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newImport(pos: Position): TermSymbol = newTermSymbol(nme.IMPORT, pos) + def newModuleVarSymbol(accessor: Symbol): TermSymbol = { + val newName = nme.moduleVarName(accessor.name.toTermName) + val newFlags = MODULEVAR | ( if (this.isClass) PrivateLocal | SYNTHETIC else 0 ) + val newInfo = accessor.tpe.finalResultType + val mval = newVariable(newName, accessor.pos.focus, newFlags) addAnnotation VolatileAttr + + if (this.isClass) + mval setInfoAndEnter newInfo + else + mval setInfo newInfo + } + final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol] diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 072e94e069..f3aa37bd15 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -127,11 +127,6 @@ abstract class TreeGen extends macros.TreeBuilder { if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym) else mkAttributedIdent(sym) - /** Builds an untyped reference to given symbol. */ - def mkUnattributedRef(sym: Symbol): Tree = - if (sym.owner.isClass) Select(This(sym.owner), sym) - else Ident(sym) - /** Replaces tree type with a stable type if possible */ def stabilize(tree: Tree): Tree = { for(tp <- stableTypeFor(tree)) tree.tpe = tp diff --git a/test/files/run/t0091.check b/test/files/run/t0091.check index 7ed6ff82de..fd3c81a4d7 100644 --- a/test/files/run/t0091.check +++ b/test/files/run/t0091.check @@ -1 +1,2 @@ 5 +5 diff --git a/test/files/run/t0091.scala b/test/files/run/t0091.scala index eaddde0dbf..45235eb77b 100644 --- a/test/files/run/t0091.scala +++ b/test/files/run/t0091.scala @@ -4,10 +4,13 @@ object C extends B { object m extends A { def x = 5 } } object Test { - // The type annotation here is necessary, otherwise - // the compiler would reference C$m$ directly. - def o : B = C - def main(argv : Array[String]) : Unit = { - println(o.m.x) - } + // The type annotation here is necessary, otherwise + // the compiler would reference C$m$ directly. + def o1 : B = C + def o2 = C + + def main(argv : Array[String]) : Unit = { + println(o1.m.x) + println(o2.m.x) + } } |