summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-05-11 13:02:54 -0700
committerPaul Phillips <paulp@improving.org>2013-05-11 13:02:54 -0700
commit24cad039b309cf3ccd79aca8f3bae398a42ab66b (patch)
tree7074df39940276bd2f93e156310a5bc4e2948508 /src/compiler
parentb174efbcbcf241903d2dc970f950f594b8c8c5e7 (diff)
downloadscala-24cad039b309cf3ccd79aca8f3bae398a42ab66b.tar.gz
scala-24cad039b309cf3ccd79aca8f3bae398a42ab66b.tar.bz2
scala-24cad039b309cf3ccd79aca8f3bae398a42ab66b.zip
Eliminated HKmode.
It becomes context mode "TypeConstructor".
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala75
3 files changed, 52 insertions, 36 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 48df7cb261..e0b7f8b670 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -244,6 +244,9 @@ trait Contexts { self: Analyzer =>
def inSecondTry = this(SecondTry)
def inSecondTry_=(value: Boolean) = this(SecondTry) = value
def inReturnExpr = this(ReturnExpr)
+ def inTypeConstructor = this(TypeConstructor)
+
+ def defaultModeForTyped: Mode = if (inTypeConstructor) Mode.NOmode else Mode.EXPRmode
/** These messages are printed when issuing an error */
var diagnostic: List[String] = Nil
@@ -361,6 +364,7 @@ trait Contexts { self: Analyzer =>
def withStarPatterns[T](op: => T): T = withMode(enabled = StarPatterns)(op)
def withSuperInit[T](op: => T): T = withMode(enabled = SuperInit)(op)
def withSecondTry[T](op: => T): T = withMode(enabled = SecondTry)(op)
+ def withTypeConstructor[T](op: => T): T = withMode(enabled = TypeConstructor)(op)
def withReturnExpr[T](op: => T): T = {
enclMethod.returnsSeen = true
@@ -1364,6 +1368,9 @@ object ContextMode {
/** Are we in return position? Formerly RETmode. */
final val ReturnExpr: ContextMode = 1 << 15
+ /** Are we typing a type constructor? Formerly HKmode. */
+ final val TypeConstructor: ContextMode = 1 << 16
+
final val DefaultMode: ContextMode = MacrosEnabled
private val contextModeNameMap = Map(
@@ -1379,7 +1386,8 @@ object ContextMode {
PatternAlternative -> "PatternAlternative",
StarPatterns -> "StarPatterns",
SuperInit -> "SuperInit",
- SecondTry -> "SecondTry"
+ SecondTry -> "SecondTry",
+ TypeConstructor -> "TypeConstructor"
)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 290ad76a1d..0b902318b2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -944,7 +944,8 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match {
case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 =>
- def isReferenceOp = name == nme.eq || name == nme.ne
+ // Make sure the 'eq' or 'ne' method is the one in AnyRef.
+ def isReferenceOp = fn.symbol == Object_eq || fn.symbol == Object_ne
def isNew(tree: Tree) = tree match {
case Function(_, _)
| Apply(Select(New(_), nme.CONSTRUCTOR), _) => true
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 3bcc670c89..f26b15b208 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -877,36 +877,43 @@ trait Typers extends Adaptations with Tags {
}
def adaptType(): Tree = {
- if (mode.inFunMode) {
- // todo. the commented line below makes sense for typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...))
- // because otherwise Ident will have its tpe set to a TypeRef, not to a PolyType, and `typedTypeApply` will fail
- // but this needs additional investigation, because it crashes t5228, gadts1 and maybe something else
- // tree setType tree.tpe.normalize
- tree
- } else if (tree.hasSymbolField && !tree.symbol.typeParams.isEmpty && !mode.inHKMode &&
- !(tree.symbol.isJavaDefined && context.unit.isJava)) { // (7)
- // @M When not typing a higher-kinded type ((mode & HKmode) == 0)
- // or raw type (tree.symbol.isJavaDefined && context.unit.isJava), types must be of kind *,
- // and thus parameterized types must be applied to their type arguments
- // @M TODO: why do kind-* tree's have symbols, while higher-kinded ones don't?
- MissingTypeParametersError(tree)
- } else if ( // (7.1) @M: check kind-arity
+ // @M When not typing a higher-kinded type (!context.inTypeConstructor)
+ // or raw type (tree.symbol.isJavaDefined && context.unit.isJava), types must be of kind *,
+ // and thus parameterized types must be applied to their type arguments
+ // @M TODO: why do kind-* tree's have symbols, while higher-kinded ones don't?
+ def kindStarRequired = (
+ tree.hasSymbolField
+ && !context.inTypeConstructor
+ && !(tree.symbol.isJavaDefined && context.unit.isJava)
+ )
+ // @M: don't check tree.tpe.symbol.typeParams. check tree.tpe.typeParams!!!
+ // (e.g., m[Int] --> tree.tpe.symbol.typeParams.length == 1, tree.tpe.typeParams.length == 0!)
// @M: removed check for tree.hasSymbolField and replace tree.symbol by tree.tpe.symbol
// (TypeTree's must also be checked here, and they don't directly have a symbol)
- mode.inHKMode &&
- // @M: don't check tree.tpe.symbol.typeParams. check tree.tpe.typeParams!!!
- // (e.g., m[Int] --> tree.tpe.symbol.typeParams.length == 1, tree.tpe.typeParams.length == 0!)
- !sameLength(tree.tpe.typeParams, pt.typeParams) &&
- !(tree.tpe.typeSymbol == AnyClass ||
- tree.tpe.typeSymbol == NothingClass ||
- pt == WildcardType)) {
- // Check that the actual kind arity (tree.symbol.typeParams.length) conforms to the expected
- // kind-arity (pt.typeParams.length). Full checks are done in checkKindBounds in Infer.
- // Note that we treat Any and Nothing as kind-polymorphic.
- // We can't perform this check when typing type arguments to an overloaded method before the overload is resolved
- // (or in the case of an error type) -- this is indicated by pt == WildcardType (see case TypeApply in typed1).
+ def kindArityMismatch = (
+ context.inTypeConstructor
+ && !sameLength(tree.tpe.typeParams, pt.typeParams)
+ )
+ // Note that we treat Any and Nothing as kind-polymorphic.
+ // We can't perform this check when typing type arguments to an overloaded method before the overload is resolved
+ // (or in the case of an error type) -- this is indicated by pt == WildcardType (see case TypeApply in typed1).
+ def kindArityMismatchOk = tree.tpe.typeSymbol match {
+ case NothingClass | AnyClass => true
+ case _ => pt == WildcardType
+ }
+
+ // todo. It would make sense when mode.inFunMode to instead use
+ // tree setType tree.tpe.normalize
+ // when typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...))
+ // because otherwise Ident will have its tpe set to a TypeRef, not to a PolyType, and `typedTypeApply` will fail
+ // but this needs additional investigation, because it crashes t5228, gadts1 and maybe something else
+ if (mode.inFunMode)
+ tree
+ else if (kindStarRequired && tree.symbol.typeParams.nonEmpty) // (7)
+ MissingTypeParametersError(tree)
+ else if (kindArityMismatch && !kindArityMismatchOk) // (7.1) @M: check kind-arity
KindArityMismatchError(tree, pt)
- } else tree match { // (6)
+ else tree match { // (6)
case TypeTree() => tree
case _ => TypeTree(tree.tpe) setOriginal tree
}
@@ -1028,7 +1035,7 @@ trait Typers extends Adaptations with Tags {
}
def insertApply(): Tree = {
- assert(!mode.inHKMode, mode) //@M
+ assert(!context.inTypeConstructor, mode) //@M
val adapted = adaptToName(tree, nme.apply)
def stabilize0(pre: Type): Tree = stabilize(adapted, pre, EXPRmode | QUALmode, WildcardType)
@@ -1212,7 +1219,7 @@ trait Typers extends Adaptations with Tags {
else if (shouldInsertApply(tree))
insertApply()
else if (hasUndetsInMonoMode) { // (9)
- assert(!mode.inHKMode, mode) //@M
+ assert(!context.inTypeConstructor, context) //@M
if (mode.typingExprNotFun && pt.typeSymbol == UnitClass)
instantiateExpectingUnit(tree, mode)
else
@@ -1246,7 +1253,7 @@ trait Typers extends Adaptations with Tags {
adapt(tree setType arg, mode, pt, original)
case tp if mode.typingExprNotLhs && isExistentialType(tp) =>
adapt(tree setType tp.dealias.skolemizeExistential(context.owner, tree), mode, pt, original)
- case PolyType(tparams, restpe) if mode.inNone(TAPPmode | PATTERNmode | HKmode) => // (3)
+ case PolyType(tparams, restpe) if mode.inNone(TAPPmode | PATTERNmode) && !context.inTypeConstructor => // (3)
// assert((mode & HKmode) == 0) //@M a PolyType in HKmode represents an anonymous type function,
// we're in HKmode since a higher-kinded type is expected --> hence, don't implicitly apply it to type params!
// ticket #2197 triggered turning the assert into a guard
@@ -5366,7 +5373,7 @@ trait Typers extends Adaptations with Tags {
/** Types expression or definition `tree`.
*/
def typed(tree: Tree): Tree = {
- val ret = typed(tree, EXPRmode, WildcardType)
+ val ret = typed(tree, context.defaultModeForTyped, WildcardType)
ret
}
@@ -5381,7 +5388,7 @@ trait Typers extends Adaptations with Tags {
/** Types expression `tree` with given prototype `pt`.
*/
def typed(tree: Tree, pt: Type): Tree =
- typed(tree, EXPRmode, pt)
+ typed(tree, context.defaultModeForTyped, pt)
def typed(tree: Tree, mode: Mode): Tree =
typed(tree, mode, WildcardType)
@@ -5444,10 +5451,10 @@ trait Typers extends Adaptations with Tags {
/** Types a higher-kinded type tree -- pt denotes the expected kind*/
def typedHigherKindedType(tree: Tree, mode: Mode, pt: Type): Tree =
if (pt.typeParams.isEmpty) typedType(tree, mode) // kind is known and it's *
- else typed(tree, HKmode, pt)
+ else context withTypeConstructor typed(tree, NOmode, pt)
def typedHigherKindedType(tree: Tree, mode: Mode): Tree =
- typed(tree, HKmode, WildcardType)
+ context withTypeConstructor typed(tree)
/** Types a type constructor tree used in a new or supertype */
def typedTypeConstructor(tree: Tree, mode: Mode): Tree = {