summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/package.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala37
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala117
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Mode.scala68
5 files changed, 118 insertions, 111 deletions
diff --git a/src/compiler/scala/tools/nsc/package.scala b/src/compiler/scala/tools/nsc/package.scala
index ee1668a38a..761fd79358 100644
--- a/src/compiler/scala/tools/nsc/package.scala
+++ b/src/compiler/scala/tools/nsc/package.scala
@@ -10,10 +10,6 @@ package object nsc {
val Mode = scala.reflect.internal.Mode
def EXPRmode = Mode.EXPRmode
- def BYVALmode = Mode.BYVALmode
- def POLYmode = Mode.POLYmode
- def TAPPmode = Mode.TAPPmode
- def FUNmode = Mode.FUNmode
type Phase = scala.reflect.internal.Phase
val NoPhase = scala.reflect.internal.NoPhase
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index e3bb595bd7..0633c1485f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -219,8 +219,14 @@ trait Contexts { self: Analyzer =>
var namedApplyBlockInfo: Option[(Tree, NamedApplyInfo)] = None
var prefix: Type = NoPrefix
+ def inSuperInit_=(value: Boolean) = this(SuperInit) = value
+ def inSuperInit = this(SuperInit)
def inConstructorSuffix_=(value: Boolean) = this(ConstructorSuffix) = value
def inConstructorSuffix = this(ConstructorSuffix)
+ def inPatAlternative_=(value: Boolean) = this(PatternAlternative) = value
+ def inPatAlternative = this(PatternAlternative)
+ def starPatterns_=(value: Boolean) = this(StarPatterns) = value
+ def starPatterns = this(StarPatterns)
def returnsSeen_=(value: Boolean) = this(ReturnsSeen) = value
def returnsSeen = this(ReturnsSeen)
def inSelfSuperCall_=(value: Boolean) = this(SelfSuperCall) = value
@@ -349,6 +355,8 @@ trait Contexts { self: Analyzer =>
def withImplicitsDisabledAllowEnrichment[T](op: => T): T = withMode(enabled = EnrichmentEnabled, disabled = ImplicitsEnabled)(op)
def withMacrosEnabled[T](op: => T): T = withMode(enabled = MacrosEnabled)(op)
def withMacrosDisabled[T](op: => T): T = withMode(disabled = MacrosEnabled)(op)
+ def withStarPatterns[T](op: => T): T = withMode(enabled = StarPatterns)(op)
+ def withSuperInit[T](op: => T): T = withMode(enabled = SuperInit)(op)
/** @return true if the `expr` evaluates to true within a silent Context that incurs no errors */
@inline final def inSilentMode(expr: => Boolean): Boolean = {
@@ -1329,18 +1337,29 @@ object ContextMode {
// TODO This seems to directly overlap with Mode.SNDTRYmode
final val ReTyping: ContextMode = 1 << 10
+ /** Are we typechecking pattern alternatives. Formerly ALTmode. */
+ final val PatternAlternative: ContextMode = 1 << 11
+
+ /** Are star patterns allowed. Formerly STARmode. */
+ final val StarPatterns: ContextMode = 1 << 12
+
+ /** Are we typing the "super" in a superclass constructor call super.<init>. Formerly SUPERCONSTRmode. */
+ final val SuperInit: ContextMode = 1 << 13
+
final val DefaultMode: ContextMode = MacrosEnabled
private val contextModeNameMap = Map(
- ReportErrors -> "ReportErrors",
- BufferErrors -> "BufferErrors",
- AmbiguousErrors -> "AmbiguousErrors",
- ConstructorSuffix -> "ConstructorSuffix",
- SelfSuperCall -> "SelfSuperCall",
- ImplicitsEnabled -> "ImplicitsEnabled",
- MacrosEnabled -> "MacrosEnabled",
- Checking -> "Checking",
- ReTyping -> "ReTyping"
+ ReportErrors -> "ReportErrors",
+ BufferErrors -> "BufferErrors",
+ AmbiguousErrors -> "AmbiguousErrors",
+ ConstructorSuffix -> "ConstructorSuffix",
+ SelfSuperCall -> "SelfSuperCall",
+ ImplicitsEnabled -> "ImplicitsEnabled",
+ MacrosEnabled -> "MacrosEnabled",
+ Checking -> "Checking",
+ ReTyping -> "ReTyping",
+ PatternAlternative -> "PatternAlternative",
+ StarPatterns -> "StarPatterns"
)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6969768ef3..f80fede3f9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -612,7 +612,7 @@ trait Typers extends Adaptations with Tags {
else tree1
}
else fail()
- } else if (mode.inExprModeButNot(QUALmode) && !sym.isValue && !phase.erasedTypes) { // (2)
+ } else if (mode.in(all = EXPRmode, none = QUALmode) && !sym.isValue && !phase.erasedTypes) { // (2)
fail()
} else {
if (sym.isStable && pre.isStable && !isByNameParamType(tree.tpe) &&
@@ -3036,13 +3036,13 @@ trait Typers extends Adaptations with Tags {
else {
// No formals left or * indicates varargs.
val isVarArgs = formals.isEmpty || formals.tail.isEmpty && isRepeatedParamType(formals.head)
- val typedMode = sticky | (
- if (isVarArgs) STARmode | BYVALmode
- else if (isByNameParamType(formals.head)) NOmode
- else BYVALmode
- )
+ val isByName = formals.nonEmpty && isByNameParamType(formals.head)
+ def typedMode = if (isByName) sticky else sticky | BYVALmode
+ def body = typedArg(args.head, mode, typedMode, adapted.head)
+ def arg1 = if (isVarArgs) context.withStarPatterns(body) else body
+
// formals may be empty, so don't call tail
- typedArg(args.head, mode, typedMode, adapted.head) :: loop(args.tail, formals drop 1, adapted.tail)
+ arg1 :: loop(args.tail, formals drop 1, adapted.tail)
}
}
loop(args0, formals0, adapted0)
@@ -3531,7 +3531,7 @@ trait Typers extends Adaptations with Tags {
def tryConst(tr: Tree, pt: Type): Option[LiteralAnnotArg] = {
// The typed tree may be relevantly different than the tree `tr`,
// e.g. it may have encountered an implicit conversion.
- val ttree = typed(constfold(tr), EXPRmode, pt)
+ val ttree = typed(constfold(tr), pt)
val const: Constant = ttree match {
case l @ Literal(c) if !l.isErroneous => c
case tree => tree.tpe match {
@@ -3570,7 +3570,7 @@ trait Typers extends Adaptations with Tags {
// use of Array.apply[T: ClassTag](xs: T*): Array[T]
// and Array.apply(x: Int, xs: Int*): Array[Int] (and similar)
case Apply(fun, args) =>
- val typedFun = typed(fun, mode.forFunMode, WildcardType)
+ val typedFun = typed(fun, mode.forFunMode)
if (typedFun.symbol.owner == ArrayModule.moduleClass && typedFun.symbol.name == nme.apply)
pt match {
case TypeRef(_, ArrayClass, targ :: _) =>
@@ -3601,7 +3601,7 @@ trait Typers extends Adaptations with Tags {
val treeInfo.Applied(fun0, targs, argss) = ann
if (fun0.isErroneous)
return finish(ErroneousAnnotation)
- val typedFun0 = typed(fun0, mode.forFunMode, WildcardType)
+ val typedFun0 = typed(fun0, mode.forFunMode)
val typedFunPart = (
// If there are dummy type arguments in typeFun part, it suggests we
// must type the actual constructor call, not only the select. The value
@@ -4148,7 +4148,9 @@ trait Typers extends Adaptations with Tags {
else context.owner.newValue(name, tree.pos)
if (name != nme.WILDCARD) {
- if (mode.inAltMode) VariableInPatternAlternativeError(tree)
+ if (context.inPatAlternative)
+ VariableInPatternAlternativeError(tree)
+
namer.enterInScope(sym)
}
@@ -4181,7 +4183,7 @@ trait Typers extends Adaptations with Tags {
}
def typedAssign(lhs: Tree, rhs: Tree): Tree = {
- val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType)
+ val lhs1 = typed(lhs, EXPRmode | LHSmode)
val varsym = lhs1.symbol
// see #2494 for double error message example
@@ -4499,7 +4501,7 @@ trait Typers extends Adaptations with Tags {
)
val isFirstTry = !noSecondTry && (
fun2 match {
- case Select(_, _) => mode inExprModeButNot SNDTRYmode
+ case Select(_, _) => mode.in(all = EXPRmode, none = SNDTRYmode)
case _ => false
}
)
@@ -4620,7 +4622,7 @@ trait Typers extends Adaptations with Tags {
val owntype = (
if (!mix.isEmpty) findMixinSuper(clazz.tpe)
- else if (mode.inAll(SUPERCONSTRmode)) clazz.info.firstParent
+ else if (context.inSuperInit) clazz.info.firstParent
else intersectionType(clazz.info.parents)
)
treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
@@ -4664,7 +4666,7 @@ trait Typers extends Adaptations with Tags {
// symbol not found? --> try to convert implicitly to a type that does have the required
// member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an
// xml member to StringContext, which in turn has an unapply[Seq] method)
- if (name != nme.CONSTRUCTOR && mode.inExprModeOr(PATTERNmode)) {
+ if (name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) {
val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, reportAmbiguous = true, saveErrors = true)
if ((qual1 ne qual) && !qual1.isErrorTyped)
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
@@ -4752,44 +4754,41 @@ trait Typers extends Adaptations with Tags {
}
}
- def typedSelectOrSuperCall(tree: Select) = {
- val qual = tree.qualifier
- val name = tree.name
- qual match {
- case _: Super if name == nme.CONSTRUCTOR =>
- val qual1 =
- typed(qual, EXPRmode | QUALmode | POLYmode | SUPERCONSTRmode, WildcardType)
- // the qualifier type of a supercall constructor is its first parent class
- typedSelect(tree, qual1, nme.CONSTRUCTOR)
- case _ =>
- if (Statistics.canEnable) Statistics.incCounter(typedSelectCount)
- var qual1 = checkDead(typedQualifier(qual, mode))
- if (name.isTypeName) qual1 = checkStable(qual1)
-
- val tree1 = // temporarily use `filter` and an alternative for `withFilter`
- if (name == nme.withFilter)
- silent(_ => typedSelect(tree, qual1, name)) orElse { _ =>
- silent(_ => typed1(Select(qual1, nme.filter) setPos tree.pos, mode, pt)) match {
- case SilentResultValue(result2) =>
- unit.deprecationWarning(
- tree.pos, "`withFilter' method does not yet exist on " + qual1.tpe.widen +
- ", using `filter' method instead")
- result2
- case SilentTypeError(err) =>
- WithFilterError(tree, err)
- }
- }
- else
- typedSelect(tree, qual1, name)
+ // temporarily use `filter` as an alternative for `withFilter`
+ def tryWithFilterAndFilter(tree: Select, qual: Tree): Tree = {
+ def warn() = unit.deprecationWarning(tree.pos, s"`withFilter' method does not yet exist on ${qual.tpe.widen}, using `filter' method instead")
- if (tree.isInstanceOf[PostfixSelect])
- checkFeature(tree.pos, PostfixOpsFeature, name.decode)
- if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember)
- checkFeature(tree1.pos, ReflectiveCallsFeature, tree1.symbol.toString)
+ silent(_ => typedSelect(tree, qual, nme.withFilter)) orElse (_ =>
+ silent(_ => typed1(Select(qual, nme.filter) setPos tree.pos, mode, pt)) match {
+ case SilentResultValue(res) => warn() ; res
+ case SilentTypeError(err) => WithFilterError(tree, err)
+ }
+ )
+ }
- if (qual1.hasSymbolWhich(_.isRootPackage)) treeCopy.Ident(tree1, name)
- else tree1
- }
+ def typedSelectOrSuperCall(tree: Select) = tree match {
+ case Select(qual @ Super(_, _), nme.CONSTRUCTOR) =>
+ typedSelect(tree, typedSelectOrSuperQualifier(qual), nme.CONSTRUCTOR)
+ case Select(qual, name) =>
+ if (Statistics.canEnable) Statistics.incCounter(typedSelectCount)
+ val qual1 = checkDead(typedQualifier(qual, mode)) match {
+ case q if name.isTypeName => checkStable(q)
+ case q => q
+ }
+ val tree1 = name match {
+ case nme.withFilter => tryWithFilterAndFilter(tree, qual1)
+ case _ => typedSelect(tree, qual1, name)
+ }
+ def sym = tree1.symbol
+ if (tree.isInstanceOf[PostfixSelect])
+ checkFeature(tree.pos, PostfixOpsFeature, name.decode)
+ if (sym != null && sym.isOnlyRefinementMember)
+ checkFeature(tree1.pos, ReflectiveCallsFeature, sym.toString)
+
+ qual1.symbol match {
+ case s: Symbol if s.isRootPackage => treeCopy.Ident(tree1, name)
+ case _ => tree1
+ }
}
/* A symbol qualifies if:
@@ -4962,13 +4961,16 @@ trait Typers extends Adaptations with Tags {
}
def typedAlternative(alt: Alternative) = {
- val alts1 = alt.trees mapConserve (alt => typed(alt, mode | ALTmode, pt))
- treeCopy.Alternative(tree, alts1) setType pt
+ 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 typedStar(tree: Star) = {
- if (mode.inNone(STARmode) && !isPastTyper)
+ if (!context.starPatterns && !isPastTyper)
StarPatternWithVarargParametersError(tree)
+
treeCopy.Star(tree, typed(tree.elem, mode, pt)) setType makeFullyDefined(pt)
}
@@ -5382,6 +5384,9 @@ trait Typers extends Adaptations with Tags {
def typed(tree: Tree, pt: Type): Tree =
typed(tree, EXPRmode, pt)
+ def typed(tree: Tree, mode: Mode): Tree =
+ typed(tree, mode, WildcardType)
+
/** Types qualifier `tree` of a select node.
* E.g. is tree occurs in a context like `tree.m`.
*/
@@ -5400,6 +5405,10 @@ trait Typers extends Adaptations with Tags {
def typedOperator(tree: Tree): Tree =
typed(tree, EXPRmode | FUNmode | POLYmode | TAPPmode, WildcardType)
+ // the qualifier type of a supercall constructor is its first parent class
+ private def typedSelectOrSuperQualifier(qual: Tree) =
+ context withSuperInit typed(qual, EXPRmode | QUALmode | POLYmode)
+
/** Types a pattern with prototype `pt` */
def typedPattern(tree: Tree, pt: Type): Tree = {
// We disable implicits because otherwise some constructs will
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 7f7bcd70d2..602982337f 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -2,7 +2,6 @@ package scala
package tools
package reflect
-import scala.tools.nsc.EXPRmode
import scala.tools.nsc.reporters._
import scala.tools.nsc.CompilerCommand
import scala.tools.nsc.io.VirtualDirectory
@@ -166,7 +165,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, expr) => {
trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
- currentTyper.silent(_.typed(expr, EXPRmode, pt)) match {
+ currentTyper.silent(_.typed(expr, pt)) match {
case analyzer.SilentResultValue(result) =>
trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
result
diff --git a/src/reflect/scala/reflect/internal/Mode.scala b/src/reflect/scala/reflect/internal/Mode.scala
index 05fd5c3337..0cfd802b01 100644
--- a/src/reflect/scala/reflect/internal/Mode.scala
+++ b/src/reflect/scala/reflect/internal/Mode.scala
@@ -48,11 +48,6 @@ object Mode {
*/
final val TAPPmode: Mode = 0x080
- /** SUPERCONSTRmode is set for the super
- * in a superclass constructor call super.<init>.
- */
- final val SUPERCONSTRmode: Mode = 0x100
-
/** SNDTRYmode indicates that an application is typed for the 2nd time.
* In that case functions may no longer be coerced with implicit views.
*/
@@ -62,15 +57,6 @@ object Mode {
*/
final val LHSmode: Mode = 0x400
- /** STARmode is set when star patterns are allowed.
- * (This was formerly called REGPATmode.)
- */
- final val STARmode: Mode = 0x1000
-
- /** ALTmode is set when we are under a pattern alternative.
- */
- final val ALTmode: Mode = 0x2000
-
/** HKmode is set when we are typing a higher-kinded type.
* adapt should then check kind-arity based on the prototypical type's
* kind arity. Type arguments should not be inferred.
@@ -94,7 +80,7 @@ object Mode {
*/
final val RETmode: Mode = 0x20000
- final private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode | ALTmode
+ final private val StickyModes: Mode = EXPRmode | PATTERNmode | TYPEmode
/** Translates a mask of mode flags into something readable.
*/
@@ -107,12 +93,12 @@ object Mode {
(1 << 5) -> "POLYmode",
(1 << 6) -> "QUALmode",
(1 << 7) -> "TAPPmode",
- (1 << 8) -> "SUPERCONSTRmode",
+ (1 << 8) -> "<NO SUCH MODE>", // formerly SUPERCONSTRmode
(1 << 9) -> "SNDTRYmode",
(1 << 10) -> "LHSmode",
- (1 << 11) -> "<DOES NOT EXIST mode>",
- (1 << 12) -> "STARmode",
- (1 << 13) -> "ALTmode",
+ (1 << 11) -> "<NO SUCH MODE>",
+ (1 << 12) -> "<NO SUCH MODE>", // formerly STARmode
+ (1 << 13) -> "<NO SUCH MODE>", // formerly ALTmode
(1 << 14) -> "HKmode",
(1 << 15) -> "BYVALmode",
(1 << 16) -> "TYPEPATmode"
@@ -131,40 +117,38 @@ final class Mode private (val bits: Int) extends AnyVal {
if (inAny(PATTERNmode | TYPEPATmode)) TYPEmode | TYPEPATmode
else TYPEmode
- def inAll(required: Mode) = (this & required) == required
- def inAny(required: Mode) = (this & required) != NOmode
- def inNone(prohibited: Mode) = (this & prohibited) == NOmode
- def inAllButNone(required: Mode, prohibited: Mode) = inAll(required) && inNone(prohibited)
- def in(allOf: Mode = NOmode, noneOf: Mode = NOmode) = inAll(allOf) && inNone(noneOf)
+ def inAll(required: Mode) = (this & required) == required
+ def inAny(required: Mode) = (this & required) != NOmode
+ def inNone(prohibited: Mode) = (this & prohibited) == NOmode
- def inSccMode = inAll(SCCmode)
- def inQualMode = inAll(QUALmode)
- def inHKMode = inAll(HKmode)
+ /** True if this mode matches every mode in the 'all' Mode,
+ * and no modes in the 'none' Mode.
+ */
+ def in(all: Mode = NOmode, none: Mode = NOmode) = inAll(all) && inNone(none)
+
+ def inByValMode = inAll(BYVALmode)
+ def inExprMode = inAll(EXPRmode)
def inFunMode = inAll(FUNmode)
- def inPolyMode = inAll(POLYmode)
+ def inHKMode = inAll(HKmode)
+ def inLhsMode = inAll(LHSmode)
def inPatternMode = inAll(PATTERNmode)
- def inExprMode = inAll(EXPRmode)
- def inByValMode = inAll(BYVALmode)
+ def inPolyMode = inAll(POLYmode)
+ def inQualMode = inAll(QUALmode)
def inRetMode = inAll(RETmode)
- def inLhsMode = inAll(LHSmode)
+ def inSccMode = inAll(SCCmode)
def inTappMode = inAll(TAPPmode)
- def inAltMode = inAll(ALTmode)
def inTypeMode = inAll(TYPEmode)
def typingTypeByValue = inAll(TYPEmode | BYVALmode)
def typingExprByValue = inAll(EXPRmode | BYVALmode)
def typingExprFun = inAll(EXPRmode | FUNmode)
- def typingExprNotValue = inAllButNone(EXPRmode, BYVALmode)
- def typingExprNotLhs = inAllButNone(EXPRmode, LHSmode)
- def typingExprNotFun = inAllButNone(EXPRmode, FUNmode)
- def typingExprNotFunNotLhs = inAllButNone(EXPRmode, FUNmode | LHSmode)
- def typingMonoExprByValue = inAllButNone(EXPRmode | BYVALmode, POLYmode)
-
- def typingPatternNotFun = inAllButNone(PATTERNmode, FUNmode)
def typingPatternFun = inAll(PATTERNmode | FUNmode)
-
- def inExprModeOr(others: Mode) = inAny(EXPRmode | others)
- def inExprModeButNot(prohibited: Mode) = inAllButNone(EXPRmode, prohibited)
+ 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 typingMonoExprByValue = in(all = EXPRmode | BYVALmode, none = POLYmode)
+ def typingPatternNotFun = in(all = PATTERNmode, none = FUNmode)
override def toString =
if (bits == 0) "NOmode"