diff options
author | Paul Phillips <paulp@improving.org> | 2013-08-19 15:12:04 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-08-19 15:12:04 -0700 |
commit | fde88c76ceb1e575b89c813a039df1967c6f995c (patch) | |
tree | a9210a6aa2165f69800a7471acc027dd42f01962 /src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala | |
parent | a124ab7f48dfc1e49b203af7a14904eaa5029577 (diff) | |
download | scala-fde88c76ceb1e575b89c813a039df1967c6f995c.tar.gz scala-fde88c76ceb1e575b89c813a039df1967c6f995c.tar.bz2 scala-fde88c76ceb1e575b89c813a039df1967c6f995c.zip |
No longer crash on NoSymbol.owner.
Historically calling NoSymbol.owner has crashed the compiler.
With this commit, NoSymbol owns itself. This is consistent with
the way ownership chains are handled elsewhere in the compiler
(e.g. NoContext.owner is NoContext, NoSymbol.enclClass is
NoSymbol, and so on) and frees every call site which handles
symbols from having to perform precondition tests against
NoSymbol.
Since calling NoSymbol.owner sometimes (not always) indicates
a bug which we'd like to catch sooner than later, I have
introduced a couple more methods for selected call sites.
def owner: Symbol // NoSymbol.owner is self, log if -Xdev
def safeOwner: Symbol // NoSymbol.owner is self, ignore
def assertOwner: Symbol // NoSymbol.owner is fatal
The idea is that everyone can call sym.owner without undue anxiety
or paranoid null-like tests. When compiling under -Xdev calls to
`owner` are logged with a stack trace, so any call sites for which
that is an expected occurrence should call safeOwner instead to
communicate the intention and stay out of the log. Conversely, any
call site where crashing on the owner call was a desirable behavior
can opt into calling assertOwner.
This commit also includes all the safeOwner calls necessary to
give us a silent log when compiling scala.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala index 1e4c56529c..6f597bef39 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala @@ -173,13 +173,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 |