diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 16 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Mode.scala | 32 |
3 files changed, 35 insertions, 34 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index fc1db32a2d..21c33aad0d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -365,6 +365,7 @@ trait Contexts { self: Analyzer => @inline final def withinSuperInit[T](op: => T): T = withMode(enabled = SuperInit)(op) @inline final def withinSecondTry[T](op: => T): T = withMode(enabled = SecondTry)(op) @inline final def withinTypeConstructor[T](op: => T): T = withMode(enabled = TypeConstructor)(op) + @inline final def withinPatAlternative[T](op: => T): T = withMode(enabled = PatternAlternative)(op) /* TODO - consolidate returnsSeen (which seems only to be used by checkDead) * and ReturnExpr. @@ -374,14 +375,8 @@ trait Contexts { self: Analyzer => withMode(enabled = ReturnExpr)(op) } - /** TODO: The "sticky modes" are EXPRmode, PATTERNmode, TYPEmode. - * To mimick the sticky mode behavior, when captain stickyfingers - * comes around we need to propagate those modes but forget the other - * context modes which were once mode bits; those being so far the - * ones listed here. - */ - @inline final def withOnlyStickyModes[T](op: => T): T = - withMode(disabled = PatternAlternative | StarPatterns | SuperInit | SecondTry | ReturnExpr | TypeConstructor | TypeApplication)(op) + // See comment on FormerNonStickyModes. + @inline final def withOnlyStickyModes[T](op: => T): T = withMode(disabled = FormerNonStickyModes)(op) /** @return true if the `expr` evaluates to true within a silent Context that incurs no errors */ @inline final def inSilentMode(expr: => Boolean): Boolean = { @@ -1389,6 +1384,16 @@ object ContextMode { */ final val TypeApplication: ContextMode = 1 << 17 + /** TODO: The "sticky modes" are EXPRmode, PATTERNmode, TYPEmode. + * To mimick the sticky mode behavior, when captain stickyfingers + * comes around we need to propagate those modes but forget the other + * context modes which were once mode bits; those being so far the + * ones listed here. + */ + final val FormerNonStickyModes: ContextMode = ( + PatternAlternative | StarPatterns | SuperInit | SecondTry | ReturnExpr | TypeConstructor | TypeApplication + ) + final val DefaultMode: ContextMode = MacrosEnabled private val contextModeNameMap = Map( diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index eeae7da94f..5cce4865cc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3039,7 +3039,7 @@ trait Typers extends Adaptations with Tags { } def typedArg(arg: Tree, mode: Mode, newmode: Mode, pt: Type): Tree = { - val typedMode = mode stickyPlus newmode + val typedMode = mode.onlySticky | newmode val t = withCondConstrTyper(mode.inSccMode)(_.typed(arg, typedMode, pt)) checkDead.inMode(typedMode, t) } @@ -3062,7 +3062,7 @@ trait Typers extends Adaptations with Tags { // No formals left or * indicates varargs. val isVarArgs = formals.isEmpty || formals.tail.isEmpty && isRepeatedParamType(formals.head) val isByName = formals.nonEmpty && isByNameParamType(formals.head) - def typedMode = mode stickyPlus ( if (isByName) NOmode else BYVALmode ) + def typedMode = if (isByName) mode.onlySticky else mode.onlySticky | BYVALmode def body = typedArg(args.head, mode, typedMode, adapted.head) def arg1 = if (isVarArgs) context.withinStarPatterns(body) else body @@ -4984,13 +4984,11 @@ trait Typers extends Adaptations with Tags { newTyper(context.makeNewScope(ddef, sym)).constrTyperIf(isConstrDefaultGetter) } - def typedAlternative(alt: Alternative) = { - val saved = context.inPatAlternative - context.inPatAlternative = true - try treeCopy.Alternative(tree, alt.trees mapConserve (alt => typed(alt, mode, pt))) setType pt - finally context.inPatAlternative = saved - } - + def typedAlternative(alt: Alternative) = ( + context withinPatAlternative ( + treeCopy.Alternative(tree, alt.trees mapConserve (alt => typed(alt, mode, pt))) setType pt + ) + ) def typedStar(tree: Star) = { if (!context.starPatterns && !isPastTyper) StarPatternWithVarargParametersError(tree) diff --git a/src/reflect/scala/reflect/internal/Mode.scala b/src/reflect/scala/reflect/internal/Mode.scala index 8b94431821..7a7c6c8c76 100644 --- a/src/reflect/scala/reflect/internal/Mode.scala +++ b/src/reflect/scala/reflect/internal/Mode.scala @@ -65,11 +65,11 @@ object Mode { */ final val TYPEPATmode: Mode = 0x10000 - final private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode - - final val MonoQualifierModes: Mode = EXPRmode | QUALmode - final val PolyQualifierModes: Mode = EXPRmode | QUALmode | POLYmode - final val OperatorModes: Mode = EXPRmode | POLYmode | TAPPmode | FUNmode + private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode + private val StickyModesForFun: Mode = StickyModes | SCCmode + final val MonoQualifierModes: Mode = EXPRmode | QUALmode + final val PolyQualifierModes: Mode = EXPRmode | QUALmode | POLYmode + final val OperatorModes: Mode = EXPRmode | POLYmode | TAPPmode | FUNmode /** Translates a mask of mode flags into something readable. */ @@ -96,16 +96,14 @@ object Mode { import Mode._ final class Mode private (val bits: Int) extends AnyVal { - def &(other: Mode): Mode = new Mode(bits & other.bits) - def |(other: Mode): Mode = new Mode(bits | other.bits) + def &(other: Mode): Mode = new Mode(bits & other.bits) + def |(other: Mode): Mode = new Mode(bits | other.bits) def &~(other: Mode): Mode = new Mode(bits & ~(other.bits)) def onlyTypePat = this & TYPEPATmode - - def stickyPlus(mode: Mode) = onlySticky | mode - def onlySticky = this & Mode.StickyModes - def forFunMode = this & (Mode.StickyModes | SCCmode) | FUNmode | POLYmode | BYVALmode - def forTypeMode = if (typingPatternOrTypePat) TYPEmode | TYPEPATmode else TYPEmode + def onlySticky = this & Mode.StickyModes + def forFunMode = this & Mode.StickyModesForFun | FUNmode | POLYmode | BYVALmode + def forTypeMode = if (typingPatternOrTypePat) TYPEmode | TYPEPATmode else TYPEmode def inAll(required: Mode) = (this & required) == required def inAny(required: Mode) = (this & required) != NOmode @@ -126,17 +124,17 @@ final class Mode private (val bits: Int) extends AnyVal { def inTappMode = inAll(TAPPmode) def inTypeMode = inAll(TYPEmode) - def typingPatternOrTypePat = inAny(PATTERNmode | TYPEPATmode) - def typingTypeByValue = inAll(TYPEmode | BYVALmode) def typingExprByValue = inAll(EXPRmode | BYVALmode) def typingExprFun = inAll(EXPRmode | FUNmode) - def typingPatternFun = inAll(PATTERNmode | FUNmode) - def typingExprNotValue = in(all = EXPRmode, none = BYVALmode) - def typingExprNotLhs = in(all = EXPRmode, none = LHSmode) def typingExprNotFun = in(all = EXPRmode, none = FUNmode) def typingExprNotFunNotLhs = in(all = EXPRmode, none = FUNmode | LHSmode) + def typingExprNotLhs = in(all = EXPRmode, none = LHSmode) + def typingExprNotValue = in(all = EXPRmode, none = BYVALmode) def typingMonoExprByValue = in(all = EXPRmode | BYVALmode, none = POLYmode) + def typingPatternFun = inAll(PATTERNmode | FUNmode) def typingPatternNotFun = in(all = PATTERNmode, none = FUNmode) + def typingPatternOrTypePat = inAny(PATTERNmode | TYPEPATmode) + def typingTypeByValue = inAll(TYPEmode | BYVALmode) override def toString = if (this == NOmode) "NOmode" |