Skip to content

Commit

Permalink
Merge branch 'master' into patmat
Browse files Browse the repository at this point in the history
Conflicts:
	src/compiler/scala/tools/nsc/Global.scala
	src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala
  • Loading branch information
paulp committed Aug 20, 2013
2 parents 6d4e71c + 1df7b32 commit 01f771e
Show file tree
Hide file tree
Showing 44 changed files with 181 additions and 148 deletions.
6 changes: 5 additions & 1 deletion src/compiler/scala/reflect/macros/compiler/Validators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ trait Validators {

// Technically this can be just an alias to MethodType, but promoting it to a first-class entity
// provides better encapsulation and convenient syntax for pattern matching.
private case class MacroImplSig(tparams: List[Symbol], paramss: List[List[Symbol]], ret: Type)
private case class MacroImplSig(tparams: List[Symbol], paramss: List[List[Symbol]], ret: Type) {
private def tparams_s = if (tparams.isEmpty) "" else tparams.map(_.defString).mkString("[", ", ", "]")
private def paramss_s = paramss map (ps => ps.map(s => s"${s.name}: ${s.tpe_*}").mkString("(", ", ", ")")) mkString ""
override def toString = "MacroImplSig(" + tparams_s + paramss_s + ret + ")"
}

/** An actual macro implementation signature extracted from a macro implementation method.
*
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
if (settings.debug)
body
}

override protected def isDeveloper = settings.developer || super.isDeveloper

/** This is for WARNINGS which should reach the ears of scala developers
* whenever they occur, but are not useful for normal users. They should
* be precise, explanatory, and infrequent. Please don't use this as a
Expand All @@ -270,7 +273,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
@inline final override def devWarning(msg: => String): Unit = devWarning(NoPosition, msg)
@inline final def devWarning(pos: Position, msg: => String) {
def pos_s = if (pos eq NoPosition) "" else s" [@ $pos]"
if (settings.developer || settings.debug)
if (isDeveloper)
warning(pos, "!!! " + msg)
else
log(s"!!!$pos_s $msg") // such warnings always at least logged
Expand Down
5 changes: 1 addition & 4 deletions src/compiler/scala/tools/nsc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
*/
def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): ClassDef = {
// "if they have symbols they should be owned by `sym`"
assert(
mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
((mmap(vparamss)(_.symbol), sym))
)
assert(mforall(vparamss)(_.symbol.owner == sym), (mmap(vparamss)(_.symbol), sym))

ClassDef(sym,
gen.mkTemplate(sym.info.parents map TypeTree,
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2693,7 +2693,7 @@ self =>
syntaxError("traits cannot have type parameters with context bounds `: ...' nor view bounds `<% ...'", skipIt = false)
classContextBounds = List()
}
val constrAnnots = constructorAnnotations()
val constrAnnots = if (!mods.isTrait) constructorAnnotations() else Nil
val (constrMods, vparamss) =
if (mods.isTrait) (Modifiers(Flags.TRAIT), List())
else (accessModifierOpt(), paramClauses(name, classContextBounds, ofCaseClass = mods.isCase))
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ abstract class Inliners extends SubComponent {
assert(clazz != NoSymbol, "Walked up past Object.superClass looking for " + sym +
", most likely this reveals the TFA at fault (receiver and callee don't match).")
if (sym.owner == clazz || isBottomType(clazz)) sym
else sym.overridingSymbol(clazz) match {
case NoSymbol => if (sym.owner.isTrait) sym else lookup(clazz.superClass)
case imp => imp
}
else sym.overridingSymbol(clazz) orElse (
if (sym.owner.isTrait) sym
else lookup(clazz.superClass)
)
}
if (needsLookup) {
val concreteMethod = lookup(clazz)
Expand Down
26 changes: 0 additions & 26 deletions src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
Original file line number Diff line number Diff line change
Expand Up @@ -367,29 +367,3 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
}
}
}
/*
val ensureNoEscapes = new TypeTraverser {
def ensureNoEscape(sym: Symbol) {
if (sym.hasFlag(PRIVATE)) {
var o = currentOwner;
while (o != NoSymbol && o != sym.owner && !o.isLocal && !o.hasFlag(PRIVATE))
o = o.owner
if (o == sym.owner) sym.makeNotPrivate(base);
}
}
def traverse(t: Type): TypeTraverser = {
t match {
case TypeRef(qual, sym, args) =>
ensureNoEscape(sym)
mapOver(t)
case ClassInfoType(parents, decls, clazz) =>
parents foreach { p => traverse; () }
traverse(t.typeOfThis)
case _ =>
mapOver(t)
}
this
}
}
*/
3 changes: 1 addition & 2 deletions src/compiler/scala/tools/nsc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,7 @@ abstract class Erasure extends AddInterfaces
private def isDifferentErasedValueType(tpe: Type, other: Type) =
isErasedValueType(tpe) && (tpe ne other)

private def isPrimitiveValueMember(sym: Symbol) =
sym != NoSymbol && isPrimitiveValueClass(sym.owner)
private def isPrimitiveValueMember(sym: Symbol) = isPrimitiveValueClass(sym.owner)

@inline private def box(tree: Tree, target: => String): Tree = {
val result = box1(tree)
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/transform/LambdaLift.scala
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ abstract class LambdaLift extends InfoTransform {
treeCopy.Assign(tree, qual, rhs)
case Ident(name) =>
val tree1 =
if (sym != NoSymbol && sym.isTerm && !sym.isLabel)
if (sym.isTerm && !sym.isLabel)
if (sym.isMethod)
atPos(tree.pos)(memberRef(sym))
else if (sym.isLocal && !isSameOwnerEnclosure(sym))
Expand Down
5 changes: 1 addition & 4 deletions src/compiler/scala/tools/nsc/transform/Mixin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -734,10 +734,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
sym
}

if (sym ne NoSymbol)
sym
else
createBitmap
sym orElse createBitmap
}

def maskForOffset(offset: Int, sym: Symbol, kind: ClassSymbol): Tree = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ trait MatchApproximation extends TreeAndTypeAnalysis with ScalaLogic with MatchT
// so that we don't introduce new aliases for existing symbols, thus keeping the set of bound symbols minimal
val (boundSubst, unboundSubst) = (subst.from zip subst.to) partition {
case (f, t) =>
t.isInstanceOf[Ident] && (t.symbol ne NoSymbol) && pointsToBound(f)
t.isInstanceOf[Ident] && t.symbol.exists && pointsToBound(f)
}
val (boundFrom, boundTo) = boundSubst.unzip
val (unboundFrom, unboundTo) = unboundSubst.unzip
Expand Down Expand Up @@ -620,9 +620,9 @@ trait MatchAnalysis extends MatchApproximation {
private lazy val uniqueEqualTo = equalTo filterNot (subsumed => equalTo.exists(better => (better ne subsumed) && instanceOfTpImplies(better.tp, subsumed.tp)))
private lazy val prunedEqualTo = uniqueEqualTo filterNot (subsumed => variable.staticTpCheckable <:< subsumed.tp)
private lazy val ctor = (prunedEqualTo match { case List(TypeConst(tp)) => tp case _ => variable.staticTpCheckable }).typeSymbol.primaryConstructor
private lazy val ctorParams = if (ctor == NoSymbol || ctor.paramss.isEmpty) Nil else ctor.paramss.head
private lazy val cls = if (ctor == NoSymbol) NoSymbol else ctor.owner
private lazy val caseFieldAccs = if (cls == NoSymbol) Nil else cls.caseFieldAccessors
private lazy val ctorParams = if (ctor.paramss.isEmpty) Nil else ctor.paramss.head
private lazy val cls = ctor.safeOwner
private lazy val caseFieldAccs = cls.caseFieldAccessors

def addField(symbol: Symbol, assign: VariableAssignment) {
// SI-7669 Only register this field if if this class contains it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,13 @@ trait MatchCodeGen extends Interface {
// catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default)
// if the last user-defined case is a default, it will never jump to the next case; it will go immediately to matchEnd
val catchAllDef = matchFailGen map { matchFailGen =>
val scrutRef = if(scrutSym ne NoSymbol) REF(scrutSym) else EmptyTree // for alternatives
val scrutRef = scrutSym.fold(EmptyTree: Tree)(REF) // for alternatives

LabelDef(_currCase, Nil, matchEnd APPLY (matchFailGen(scrutRef)))
} toList // at most 1 element

// scrutSym == NoSymbol when generating an alternatives matcher
val scrutDef = if(scrutSym ne NoSymbol) List(VAL(scrutSym) === scrut) else Nil // for alternatives
val scrutDef = scrutSym.fold(List[Tree]())(sym => (VAL(sym) === scrut) :: Nil) // for alternatives

// the generated block is taken apart in TailCalls under the following assumptions
// the assumption is once we encounter a case, the remainder of the block will consist of cases
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,8 @@ trait MatchTranslation {

object Bound {
def unapply(t: Tree): Option[(Symbol, Tree)] = t match {
case t@Bind(n, p) if (t.symbol ne null) && (t.symbol ne NoSymbol) => Some((t.symbol, p)) // pos/t2429 does not satisfy these conditions
case _ => None
case t@Bind(n, p) if t.hasExistingSymbol => Some((t.symbol, p)) // pos/t2429 does not satisfy these conditions
case _ => None
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,9 +597,8 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
t.symbol.owner = currentOwner
case d : DefTree if (d.symbol != NoSymbol) && ((d.symbol.owner == NoSymbol) || (d.symbol.owner == origOwner)) => // don't indiscriminately change existing owners! (see e.g., pos/t3440, pos/t3534, pos/unapplyContexts2)
debug.patmat("def: "+ ((d, d.symbol.ownerChain, currentOwner.ownerChain)))
if(d.symbol.moduleClass ne NoSymbol)
d.symbol.moduleClass.owner = currentOwner

d.symbol.moduleClass andAlso (_.owner = currentOwner)
d.symbol.owner = currentOwner
// case _ if (t.symbol != NoSymbol) && (t.symbol ne null) =>
debug.patmat("untouched "+ ((t, t.getClass, t.symbol.ownerChain, currentOwner.ownerChain)))
Expand Down
13 changes: 4 additions & 9 deletions src/compiler/scala/tools/nsc/typechecker/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ trait Contexts { self: Analyzer =>

/** The next enclosing context (potentially `this`) that is owned by a class or method */
def enclClassOrMethod: Context =
if ((owner eq NoSymbol) || (owner.isClass) || (owner.isMethod)) this
if (!owner.exists || owner.isClass || owner.isMethod) this
else outer.enclClassOrMethod

/** The next enclosing context (potentially `this`) that has a `CaseDef` as a tree */
Expand Down Expand Up @@ -653,13 +653,8 @@ trait Contexts { self: Analyzer =>
lastAccessCheckDetails = ""
// Console.println("isAccessible(%s, %s, %s)".format(sym, pre, superAccess))

def accessWithinLinked(ab: Symbol) = {
val linked = ab.linkedClassOfClass
// don't have access if there is no linked class
// (before adding the `ne NoSymbol` check, this was a no-op when linked eq NoSymbol,
// since `accessWithin(NoSymbol) == true` whatever the symbol)
(linked ne NoSymbol) && accessWithin(linked)
}
// don't have access if there is no linked class (so exclude linkedClass=NoSymbol)
def accessWithinLinked(ab: Symbol) = ab.linkedClassOfClass.fold(false)(accessWithin)

/* Are we inside definition of `ab`? */
def accessWithin(ab: Symbol) = {
Expand Down Expand Up @@ -957,7 +952,7 @@ trait Contexts { self: Analyzer =>
// 2) sym.owner is inherited by the correct package object class
// We try to establish 1) by inspecting the owners directly, and then we try
// to rule out 2), and only if both those fail do we resort to looking in the info.
!sym.isPackage && (sym.owner ne NoSymbol) && (
!sym.isPackage && sym.owner.exists && (
if (sym.owner.isPackageObjectClass)
sym.owner.owner == pkgClass
else
Expand Down
36 changes: 16 additions & 20 deletions src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,19 @@ abstract class Duplicators extends Analyzer {

override def mapOver(tpe: Type): Type = tpe match {
case TypeRef(NoPrefix, sym, args) if sym.isTypeParameterOrSkolem =>
var sym1 = context.scope.lookup(sym.name)
if (sym1 eq NoSymbol) {
// try harder (look in outer scopes)
// with virtpatmat, this can happen when the sym is referenced in the scope of a LabelDef but is defined in the scope of an outer DefDef (e.g., in AbstractPartialFunction's andThen)
BodyDuplicator.super.silent(_.typedType(Ident(sym.name))) match {
case SilentResultValue(t) =>
sym1 = t.symbol
debuglog("fixed by trying harder: "+((sym, sym1, context)))
case _ =>
}
}
// assert(sym1 ne NoSymbol, tpe)
if ((sym1 ne NoSymbol) && (sym1 ne sym)) {
debuglog("fixing " + sym + " -> " + sym1)
val sym1 = (
context.scope lookup sym.name orElse {
// try harder (look in outer scopes)
// with virtpatmat, this can happen when the sym is referenced in the scope of a LabelDef but
// is defined in the scope of an outer DefDef (e.g., in AbstractPartialFunction's andThen)
BodyDuplicator.super.silent(_ typedType Ident(sym.name)).fold(NoSymbol: Symbol)(_.symbol)
} filter (_ ne sym)
)
if (sym1.exists) {
debuglog(s"fixing $sym -> $sym1")
typeRef(NoPrefix, sym1, mapOverArgs(args, sym1.typeParams))
} else super.mapOver(tpe)
}
else super.mapOver(tpe)

case TypeRef(pre, sym, args) =>
val newsym = updateSym(sym)
Expand Down Expand Up @@ -157,7 +154,7 @@ abstract class Duplicators extends Analyzer {
case vdef @ ValDef(mods, name, _, rhs) if mods.hasFlag(Flags.LAZY) =>
debuglog("ValDef " + name + " sym.info: " + vdef.symbol.info)
invalidSyms(vdef.symbol) = vdef
val newowner = if (owner != NoSymbol) owner else context.owner
val newowner = owner orElse context.owner
val newsym = vdef.symbol.cloneSymbol(newowner)
newsym.setInfo(fixType(vdef.symbol.info))
vdef.symbol = newsym
Expand Down Expand Up @@ -362,12 +359,11 @@ abstract class Duplicators extends Analyzer {
case _ =>
debuglog("Duplicators default case: " + tree.summaryString)
debuglog(" ---> " + tree)
if (tree.hasSymbolField && tree.symbol != NoSymbol && (tree.symbol.owner == AnyClass)) {
if (tree.hasSymbolField && tree.symbol.safeOwner == AnyClass)
tree.symbol = NoSymbol // maybe we can find a more specific member in a subclass of Any (see AnyVal members, like ==)
}

val ntree = castType(tree, pt)
val res = super.typed(ntree, mode, pt)
res
super.typed(ntree, mode, pt)
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/compiler/scala/tools/nsc/typechecker/Namers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,7 @@ trait Namers extends MethodSynthesis {
* has been defined in a separate file.
*/
private def validateCompanionDefs(tree: ImplDef) {
val sym = tree.symbol
if (sym eq NoSymbol) return

val sym = tree.symbol orElse { return }
val ctx = if (context.owner.isPackageObjectClass) context.outer else context
val module = if (sym.isModule) sym else ctx.scope lookupModule tree.name
val clazz = if (sym.isClass) sym else ctx.scope lookupClass tree.name
Expand Down
39 changes: 29 additions & 10 deletions src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
var localTyper: analyzer.Typer = typer
var currentApplication: Tree = EmptyTree
var inPattern: Boolean = false
@inline final def savingInPattern[A](body: => A): A = {
val saved = inPattern
try body finally inPattern = saved
}

var checkedCombinations = Set[List[Type]]()

// only one overloaded alternative is allowed to define default arguments
Expand Down Expand Up @@ -211,7 +216,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
val inherited = clazz.info.nonPrivateMemberAdmitting(member.name, VBRIDGE)

// Delaying calling memberType as long as possible
if (inherited ne NoSymbol) {
if (inherited.exists) {
val jtpe = toJavaRepeatedParam(self memberType member)
// this is a bit tortuous: we look for non-private members or bridges
// if we find a bridge everything is OK. If we find another member,
Expand Down Expand Up @@ -1516,7 +1521,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
checkCompileTimeOnly(sym, tree.pos)
checkDelayedInitSelect(qual, sym, tree.pos)

if (sym eq NoSymbol)
if (!sym.exists)
devWarning("Select node has NoSymbol! " + tree + " / " + tree.tpe)
else if (sym.hasLocalFlag)
varianceValidator.checkForEscape(sym, currentClass)
Expand Down Expand Up @@ -1667,19 +1672,33 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans

case _ => tree
}

// skip refchecks in patterns....
result = result match {
case CaseDef(pat, guard, body) =>
inPattern = true
val pat1 = transform(pat)
inPattern = false
val pat1 = savingInPattern {
inPattern = true
transform(pat)
}
treeCopy.CaseDef(tree, pat1, transform(guard), transform(body))
case LabelDef(_, _, _) if treeInfo.hasSynthCaseSymbol(result) =>
val old = inPattern
inPattern = true
val res = deriveLabelDef(result)(transform)
inPattern = old
res
savingInPattern {
inPattern = true
deriveLabelDef(result)(transform)
}
case Apply(fun, args) if fun.symbol.isLabel && treeInfo.isSynthCaseSymbol(fun.symbol) =>
savingInPattern {
// SI-7756 If we were in a translated pattern, we can now switch out of pattern mode, as the label apply signals
// that we are in the user-supplied code in the case body.
//
// Relies on the translation of:
// (null: Any) match { case x: List[_] => x; x.reverse; case _ => }'
// to:
// <synthetic> val x2: List[_] = (x1.asInstanceOf[List[_]]: List[_]);
// matchEnd4({ x2; x2.reverse}) // case body is an argument to a label apply.
inPattern = false
super.transform(result)
}
case _ =>
super.transform(result)
}
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
&& sym.enclClass != currentClass
&& !sym.owner.isPackageClass // SI-7091 no accessor needed package owned (ie, top level) symbols
&& !sym.owner.isTrait
&& (sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass)
&& (qual.symbol.info.member(sym.name) ne NoSymbol)
&& sym.owner.enclosingPackageClass != currentClass.enclosingPackageClass
&& qual.symbol.info.member(sym.name).exists
&& !needsProtectedAccessor(sym, tree.pos)
)
if (shouldEnsureAccessor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ trait TypeDiagnostics {
def defaultMessage = moduleMessage + preResultString + tree.tpe
def applyMessage = defaultMessage + tree.symbol.locationString

if ((sym eq null) || (sym eq NoSymbol)) {
if (!tree.hasExistingSymbol) {
if (isTyperInPattern) patternMessage
else exprMessage
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}

sealed abstract class SilentResult[+T] {
@inline final def fold[U](none: => U)(f: T => U): U = this match {
case SilentResultValue(value) => f(value)
case _ => none
}
@inline final def map[U](f: T => U): SilentResult[U] = this match {
case SilentResultValue(value) => SilentResultValue(f(value))
case x: SilentTypeError => x
Expand Down
Loading

0 comments on commit 01f771e

Please sign in to comment.