From 09fe97aec626b875f68e057828c44a9b6f4344dc Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 19 Feb 2014 20:37:46 +0100 Subject: SI-8316 SI-8318 SI-8248 reintroduces resetAllAttrs Unfortunately, due to the aforementioned bugs we have to delay our triumph over resetAllAttrs. Therefore, I'm rolling back the internal changes to scalac introduced in https://github.com/scala/scala/pull/3485. Our public reflection API interface in Scala 2.11 is still going to contain only resetLocalAttrs, but both the reifier and the label typechecker are too heavily addicted to resetAllAttrs to do away with it right now. --- src/compiler/scala/reflect/reify/Reifier.scala | 10 +++++++++- src/compiler/scala/tools/nsc/ast/Trees.scala | 16 +++++++++++++--- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index 6b0a0ee8d7..b1cc797389 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -110,10 +110,18 @@ abstract class Reifier extends States // todo. this is a common problem with non-trivial macros in our current macro system // needs to be solved some day // upd. a new hope: https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ - val untyped = resetAttrs(result, leaveAlone = { + var importantSymbols = Set[Symbol]( + NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass, + ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, runDefinitions.ReflectRuntimeCurrentMirror) + importantSymbols ++= importantSymbols map (_.companionSymbol) + importantSymbols ++= importantSymbols map (_.moduleClass) + importantSymbols ++= importantSymbols map (_.linkedClassOfClass) + def isImportantSymbol(sym: Symbol): Boolean = sym != null && sym != NoSymbol && importantSymbols(sym) + val untyped = brutallyResetAttrs(result, leaveAlone = { case ValDef(_, u, _, _) if u == nme.UNIVERSE_SHORT => true case ValDef(_, m, _, _) if m == nme.MIRROR_SHORT => true case tree if symtab.syms contains tree.symbol => true + case tree if isImportantSymbol(tree.symbol) => true case _ => false }) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index d33ea5bb5c..9ca06427e8 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -194,8 +194,18 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => // // def resetAllAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(localOnly = false, leaveAlone).transform(x) + // upd. Unfortunately this didn't work out quite as we expected. The last two users of resetAllAttrs: + // reification and typedLabelDef broke in very weird ways when we replaced resetAllAttrs with resetLocalAttrs + // (see SI-8316 change from resetAllAttrs to resetLocalAttrs in reifiers broke Slick and + // SI-8318 NPE in mixin in scala-continuations for more information). + // Given that we're supposed to release 2.11.0-RC1 in less than a week, I'm temporarily reinstating resetAllAttrs + // until we have time to better understand what's going on. In order to dissuade people from using it, + // it now comes with a new, ridiculous name. /** @see ResetAttrs */ - def resetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(leaveAlone).transform(x) + def brutallyResetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(brutally = true, leaveAlone).transform(x) + + /** @see ResetAttrs */ + def resetAttrs(x: Tree): Tree = new ResetAttrs(brutally = false, leaveAlone = null).transform(x) /** A transformer which resets symbol and tpe fields of all nodes in a given tree, * with special treatment of: @@ -206,7 +216,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => * * (bq:) This transformer has mutable state and should be discarded after use */ - private class ResetAttrs(leaveAlone: Tree => Boolean = null) { + private class ResetAttrs(brutally: Boolean, leaveAlone: Tree => Boolean) { // this used to be based on -Ydebug, but the need for logging in this code is so situational // that I've reverted to a hard-coded constant here. val debug = false @@ -299,7 +309,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => // if we move these trees into lexical contexts different from their original locations. if (dupl.hasSymbol) { val sym = dupl.symbol - val vetoScope = !(locals contains sym) + val vetoScope = !brutally && !(locals contains sym) val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass if (!(vetoScope || vetoThis)) dupl.symbol = NoSymbol } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 8721450dc9..fa96d98bcc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2288,7 +2288,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val sym2 = namer.enterInScope( context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe)) val LabelDef(_, _, rhs1) = resetAttrs(ldef) - val rhs2 = typed(rhs1, restpe) + val rhs2 = typed(brutallyResetAttrs(rhs1), restpe) ldef.params foreach (param => param setType param.symbol.tpe) deriveLabelDef(ldef)(_ => rhs2) setSymbol sym2 setType restpe } -- cgit v1.2.3