summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala1462
1 files changed, 548 insertions, 914 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 893384ece3..a1343fb7d7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -12,13 +12,13 @@
package scala.tools.nsc
package typechecker
-import scala.collection.mutable
-import mutable.ListBuffer
-
+import scala.collection.{ mutable, immutable }
import scala.tools.nsc.util.BatchSourceFile
+import mutable.ListBuffer
import symtab.Flags._
-import util.Statistics._
import util.Statistics
+import util.Statistics._
+import scala.tools.util.StringOps.{ countAsString, countElementsAsString }
// Suggestion check whether we can do without priming scopes with symbols of outer scopes,
// like the IDE does.
@@ -59,7 +59,7 @@ trait Typers extends Modes with Adaptations {
super.traverse(tree)
}
}
-/* needed for experimental version where early types can be type arguments
+/* needed for experimental version where eraly types can be type arguments
class EarlyMap(clazz: Symbol) extends TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(NoPrefix, sym, List()) if (sym hasFlag PRESUPER) =>
@@ -77,7 +77,7 @@ trait Typers extends Modes with Adaptations {
// that are turned private by typedBlock
private final val SYNTHETIC_PRIVATE = TRANS_FLAG
- abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with TyperErrorTrees {
+ abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation {
import context0.unit
import typeDebug.{ ptTree, ptBlock, ptLine }
@@ -99,6 +99,15 @@ trait Typers extends Modes with Adaptations {
def mkNamedArg(argTree: Tree, paramName: Name) = atPos(argTree.pos)(new AssignOrNamedArg(Ident(paramName), (argTree)))
var mkArg: (Tree, Name) => Tree = mkPositionalArg
+ def errorMessage(paramName: Name, paramTp: Type) =
+ paramTp.typeSymbol match {
+ case ImplicitNotFoundMsg(msg) => msg.format(paramName, paramTp)
+ case _ =>
+ "could not find implicit value for "+
+ (if (paramName startsWith nme.EVIDENCE_PARAM_PREFIX) "evidence parameter of type "
+ else "parameter "+paramName+": ")+paramTp
+ }
+
// DEPMETTODO: instantiate type vars that depend on earlier implicit args (see adapt (4.1))
//
// apply the substitutions (undet type param -> type) that were determined
@@ -115,9 +124,8 @@ trait Typers extends Modes with Adaptations {
argBuff += mkArg(res.tree, param.name)
} else {
mkArg = mkNamedArg // don't pass the default argument (if any) here, but start emitting named arguments for the following args
- if (!param.hasDefault) {
- argBuff += NoImplicitFoundError(fun, param)
- }
+ if (!param.hasDefault)
+ context.error(fun.pos, errorMessage(param.name, param.tpe))
/* else {
TODO: alternative (to expose implicit search failure more) -->
resolve argument, do type inference, keep emitting positional args, infer type params based on default value for arg
@@ -178,10 +186,6 @@ trait Typers extends Modes with Adaptations {
var context = context0
def context1 = context
- @inline
- private def wrapInBlock(errTree: Tree, original: Tree): Tree = Block(errTree, original) setType ErrorType
-
-
def dropExistential(tp: Type): Type = tp match {
case ExistentialType(tparams, tpe) =>
new SubstWildcardMap(tparams).apply(tp)
@@ -198,12 +202,22 @@ trait Typers extends Modes with Adaptations {
* @return ...
*/
def checkStable(tree: Tree): Tree =
- if (treeInfo.isPureExpr(tree)) tree else UnstableTreeError(tree)
+ if (treeInfo.isPureExpr(tree)) tree
+ else errorTree(
+ tree,
+ "stable identifier required, but "+tree+" found."+
+ (if (isStableExceptVolatile(tree)) {
+ val tpe = tree.symbol.tpe match {
+ case PolyType(_, rtpe) => rtpe
+ case t => t
+ }
+ "\n Note that "+tree.symbol+" is not stable because its type, "+tree.tpe+", is volatile."
+ } else ""))
/** Would tree be a stable (i.e. a pure expression) if the type
* of its symbol was not volatile?
*/
- protected def isStableExceptVolatile(tree: Tree) = {
+ private def isStableExceptVolatile(tree: Tree) = {
tree.hasSymbol && tree.symbol != NoSymbol && tree.tpe.isVolatile &&
{ val savedTpe = tree.symbol.info
val savedSTABLE = tree.symbol getFlag STABLE
@@ -217,21 +231,21 @@ trait Typers extends Modes with Adaptations {
}
/** Check that `tpt` refers to a non-refinement class type */
- def checkClassType(tpt: Tree, existentialOK: Boolean, stablePrefix: Boolean) = {
- def errorNotClass(found: AnyRef) = Some(ClassTypeRequiredError(tpt, found))
- def check(tpe: Type): Option[ErrorTree] = tpe.normalize match {
+ def checkClassType(tpt: Tree, existentialOK: Boolean, stablePrefix: Boolean) {
+ def errorNotClass(found: AnyRef) = error(tpt.pos, "class type required but "+found+" found")
+ def check(tpe: Type): Unit = tpe.normalize match {
case TypeRef(pre, sym, _) if sym.isClass && !sym.isRefinementClass =>
- if (stablePrefix && phase.id <= currentRun.typerPhase.id)
+ if (stablePrefix && phase.id <= currentRun.typerPhase.id) {
if (!pre.isStable)
- Some(TypeNotAStablePrefixError(pre, tpt.pos))
- else
- tpt match {
+ error(tpt.pos, "type "+pre+" is not a stable prefix")
+ // A type projection like X#Y can get by the stable check if the
+ // prefix is singleton-bounded, so peek at the tree too.
+ else tpt match {
case SelectFromTypeTree(qual, _) if !isSingleType(qual.tpe) => errorNotClass(tpt)
- case _ => None
- }
- else
- None
- case ErrorType => None
+ case _ => ;
+ }
+ }
+ case ErrorType => ;
case PolyType(_, restpe) => check(restpe)
case ExistentialType(_, restpe) if existentialOK => check(restpe)
case AnnotatedType(_, underlying, _) => check(underlying)
@@ -246,19 +260,18 @@ trait Typers extends Modes with Adaptations {
* @param tp ...
* @return <code>true</code> if <code>tp</code> is not a subtype of itself.
*/
- def checkNonCyclic(pos: Position, tp: Type): Option[ErrorTree] = {
- def checkNotLocked(sym: Symbol): Option[ErrorTree] = {
+ def checkNonCyclic(pos: Position, tp: Type): Boolean = {
+ def checkNotLocked(sym: Symbol): Boolean = {
sym.initialize
- if (sym.lockOK) None
- else Some(CyclicAliasingOrSubtypingError(pos, sym))
+ sym.lockOK || {error(pos, "cyclic aliasing or subtyping involving "+sym); false}
}
tp match {
case TypeRef(pre, sym, args) =>
- val check = checkNotLocked(sym)
- if (check.isDefined) check
- else if (!sym.isNonClassType) None
- else checkNonCyclic(pos, appliedType(pre.memberInfo(sym), args), sym)
-
+ (checkNotLocked(sym)) && (
+ !sym.isNonClassType ||
+ checkNonCyclic(pos, appliedType(pre.memberInfo(sym), args), sym) // @M! info for a type ref to a type parameter now returns a polytype
+ // @M was: checkNonCyclic(pos, pre.memberInfo(sym).subst(sym.typeParams, args), sym)
+ )
case SingleType(pre, sym) =>
checkNotLocked(sym)
/*
@@ -270,70 +283,51 @@ trait Typers extends Modes with Adaptations {
case st: SubType =>
checkNonCyclic(pos, st.supertype)
case ct: CompoundType =>
- val checkRes = ct.parents map (x => checkNonCyclic(pos, x)) flatten
-
- if (checkRes.isEmpty) None
- else Some(PendingErrors(checkRes))
+ ct.parents forall (x => checkNonCyclic(pos, x))
case _ =>
- None
+ true
}
}
- // TODO in order to return CyclicReferenceError we need to change the signature of lock
- // let's leave it for now
- def checkNonCyclic(pos: Position, tp: Type, lockedSym: Symbol): Option[ErrorTree] = try {
+ def checkNonCyclic(pos: Position, tp: Type, lockedSym: Symbol): Boolean = try {
lockedSym.lock {
throw new TypeError("illegal cyclic reference involving " + lockedSym)
}
checkNonCyclic(pos, tp)
- } catch {
- case _ :TypeError =>
- Some(CyclicReferenceError(pos, lockedSym))
} finally {
lockedSym.unlock()
}
- def checkNonCyclic(sym: Symbol): Option[ErrorTree] = {
- val check = checkNonCyclic(sym.pos, sym.tpe)
- if (check.isDefined)
- sym.setInfo(ErrorType)
- check
+ def checkNonCyclic(sym: Symbol) {
+ if (!checkNonCyclic(sym.pos, sym.tpe)) sym.setInfo(ErrorType)
}
- def checkNonCyclic(defn: Tree, tpt: Tree): Option[ErrorTree] = {
- val check = checkNonCyclic(defn.pos, tpt.tpe, defn.symbol)
- if (check.isDefined) {
+ def checkNonCyclic(defn: Tree, tpt: Tree) {
+ if (!checkNonCyclic(defn.pos, tpt.tpe, defn.symbol)) {
tpt.tpe = ErrorType
defn.symbol.setInfo(ErrorType)
}
- check
}
- def checkParamsConvertible(pos: Position, tpe0: Type): List[ErrorTree] = {
- var pending: List[ErrorTree] = List()
- def checkParamsConvertible0(tpe: Type) =
- tpe match {
- case MethodType(formals, restpe) =>
- /*
- if (formals.exists(_.typeSymbol == ByNameParamClass) && formals.length != 1)
- error(pos, "methods with `=>`-parameter can be converted to function values only if they take no other parameters")
- if (formals exists (isRepeatedParamType(_)))
- error(pos, "methods with `*`-parameters cannot be converted to function values");
- */
- if (restpe.isDependent)
- pending = DependentMethodTpeConversionToFunctionError(pos, tpe)::pending
- checkParamsConvertible(pos, restpe)
- case _ =>
- }
- checkParamsConvertible0(tpe0)
- pending
+ def checkParamsConvertible(pos: Position, tpe: Type) {
+ tpe match {
+ case MethodType(formals, restpe) =>
+ /*
+ if (formals.exists(_.typeSymbol == ByNameParamClass) && formals.length != 1)
+ error(pos, "methods with `=>`-parameter can be converted to function values only if they take no other parameters")
+ if (formals exists (isRepeatedParamType(_)))
+ error(pos, "methods with `*`-parameters cannot be converted to function values");
+ */
+ if (restpe.isDependent)
+ error(pos, "method with dependent type "+tpe+" cannot be converted to function value")
+ checkParamsConvertible(pos, restpe)
+ case _ =>
+ }
}
- @inline
- private def checkStarPatOK(pos: Position, mode: Int):Option[ErrorTree] =
+ def checkStarPatOK(pos: Position, mode: Int) =
if ((mode & STARmode) == 0 && phase.id <= currentRun.typerPhase.id)
- Some(StarPatternWithVarargParametersError(pos))
- else None
+ error(pos, "star patterns must correspond with varargs parameters")
/** Check that type of given tree does not contain local or private
* components.
@@ -351,7 +345,7 @@ trait Typers extends Modes with Adaptations {
* @param tree ...
* @return ...
*/
- def privates(owner: Symbol, tree: Tree): Tree =
+ def privates[T <: Tree](owner: Symbol, tree: T): T =
check(owner, EmptyScope, WildcardType, tree)
/** Check that type <code>tree</code> does not refer to entities
@@ -362,16 +356,16 @@ trait Typers extends Modes with Adaptations {
* @param tree ...
* @return ...
*/
- def locals(scope: Scope, pt: Type, tree: Tree): Tree =
+ def locals[T <: Tree](scope: Scope, pt: Type, tree: T): T =
check(NoSymbol, scope, pt, tree)
- private def check(owner: Symbol, scope: Scope, pt: Type, tree: Tree): Tree = {
+ def check[T <: Tree](owner: Symbol, scope: Scope, pt: Type, tree: T): T = {
this.owner = owner
this.scope = scope
hiddenSymbols = List()
val tp1 = apply(tree.tpe)
if (hiddenSymbols.isEmpty) tree setType tp1
- else if (hiddenSymbols exists (_.isErroneous)) HiddenSymbolWithError(tree)
+ else if (hiddenSymbols exists (_.isErroneous)) setError(tree)
else if (isFullyDefined(pt)) tree setType pt //todo: eliminate
else if (tp1.typeSymbol.isAnonymousClass) // todo: eliminate
check(owner, scope, pt, tree setType tp1.typeSymbol.classBound)
@@ -379,7 +373,10 @@ trait Typers extends Modes with Adaptations {
tree setType packSymbols(hiddenSymbols.reverse, tp1)
else if (!phase.erasedTypes) { // privates
val badSymbol = hiddenSymbols.head
- SymbolEscapesScopeError(tree, badSymbol)
+ error(tree.pos,
+ (if (badSymbol.isPrivate) "private " else "") + badSymbol +
+ " escapes its defining scope as part of type "+tree.tpe)
+ setError(tree)
} else tree
}
@@ -442,12 +439,16 @@ trait Typers extends Modes with Adaptations {
/** The qualifying class
* of a this or super with prefix <code>qual</code>.
*/
- def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean): Either[ErrorTree, Symbol] =
+ def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean): Symbol =
context.enclClass.owner.ownerChain.find(o => qual.isEmpty || o.isClass && o.name == qual) match {
case Some(c) if packageOK || !c.isPackageClass =>
- Right(c)
+ c
case _ =>
- Left(QualifyingClassError(tree, qual))
+ error(
+ tree.pos,
+ if (qual.isEmpty) tree+" can be used only in a class, object, or template"
+ else qual+" is not an enclosing class")
+ NoSymbol
}
/** The typer for an expression, depending on where we are. If we are before a superclass
@@ -564,19 +565,14 @@ trait Typers extends Modes with Adaptations {
* 2. Check that packages and static modules are not used as values
* 3. Turn tree type into stable type if possible and required by context.
*/
- private def stabilize(tree0: Tree, pre: Type, mode: Int, pt: Type): Tree = {
- val tree =
- if (tree0.symbol.isOverloaded && !inFunMode(mode))
- inferExprAlternative(tree0, pt) match {
- case Some(err) => err
- case _ => tree0
- }
- else tree0
+ private def stabilize(tree: Tree, pre: Type, mode: Int, pt: Type): Tree = {
+ if (tree.symbol.isOverloaded && !inFunMode(mode))
+ inferExprAlternative(tree, pt)
val sym = tree.symbol
- def fail() = NotAValueError(tree, sym)
+ def fail() = errorTree(tree, sym.kindString + " " + sym.fullName + " is not a value")
- if (tree.containsErrorOrIsErrorTyped()) tree
+ if (tree.tpe.isError) tree
else if ((mode & (PATTERNmode | FUNmode)) == PATTERNmode && tree.isTerm) { // (1)
if (sym.isValue) checkStable(tree)
else fail()
@@ -656,8 +652,6 @@ trait Typers extends Modes with Adaptations {
} catch {
case ex: CyclicReference => throw ex
case ex: TypeError =>
- // TODO: when move to error trees is complete we should
- // be able to just drop this case
stopCounter(rawTypeFailed, rawTypeStart)
stopCounter(findMemberFailed, findMemberStart)
stopCounter(subtypeFailed, subtypeStart)
@@ -666,6 +660,23 @@ trait Typers extends Modes with Adaptations {
}
}
+ /** Utility method: Try op1 on tree. If that gives an error try op2 instead.
+ */
+ def tryBoth(tree: Tree)(op1: (Typer, Tree) => Tree)(op2: (Typer, Tree) => Tree): Tree =
+ silent(op1(_, tree)) match {
+ case result1: Tree =>
+ result1
+ case ex1: TypeError =>
+ silent(op2(_, resetAllAttrs(tree))) match {
+ case result2: Tree =>
+// println("snd succeeded: "+result2)
+ result2
+ case ex2: TypeError =>
+ reportTypeError(tree.pos, ex1)
+ setError(tree)
+ }
+ }
+
def isCodeType(tpe: Type) = tpe.typeSymbol isNonBottomSubClass CodeClass
/** Perform the following adaptations of expression, pattern or type `tree` wrt to
@@ -711,6 +722,7 @@ trait Typers extends Modes with Adaptations {
if (context.undetparams nonEmpty) { // (9) -- should revisit dropped condition `(mode & POLYmode) == 0`
// dropped so that type args of implicit method are inferred even if polymorphic expressions are allowed
// needed for implicits in 2.8 collection library -- maybe once #3346 is fixed, we can reinstate the condition?
+ context.undetparams =
inferExprInstance(tree, context.extractUndetparams(), pt,
// approximate types that depend on arguments since dependency on implicit argument is like dependency on type parameter
if (settings.YdepMethTpes.value) mt.approximate else mt,
@@ -719,21 +731,14 @@ trait Typers extends Modes with Adaptations {
// Looking for a manifest of Nil: This has many potential types,
// so we need to instantiate to minimal type List[Nothing].
keepNothings = false, // retract Nothing's that indicate failure, ambiguities in manifests are dealt with in manifestOfType
- useWeaklyCompatible = true) match {// #3808
- case (Some(err), undetparams1) =>
- context.undetparams = undetparams1
- return err
- case (_, undetparams1) =>
- context.undetparams = undetparams1
- }
+ useWeaklyCompatible = true) // #3808
}
val typer1 = constrTyperIf(treeInfo.isSelfOrSuperConstrCall(tree))
if (original != EmptyTree && pt != WildcardType)
typer1.silent(tpr => tpr.typed(tpr.applyImplicitArgs(tree), mode, pt)) match {
- case result: Tree if !result.containsError() =>
- result
- case _ =>
+ case result: Tree => result
+ case ex: TypeError =>
debuglog("fallback on implicits: " + tree + "/" + resetAllAttrs(original))
val tree1 = typed(resetAllAttrs(original), mode, WildcardType)
tree1.tpe = addAnnotations(tree1, tree1.tpe)
@@ -751,10 +756,7 @@ trait Typers extends Modes with Adaptations {
}
if (!meth.isConstructor && isFunctionType(pt)) { // (4.2)
debuglog("eta-expanding " + tree + ":" + tree.tpe + " to " + pt)
- val errs = checkParamsConvertible(tree.pos, tree.tpe)
- if (!errs.isEmpty) {
- return PendingErrors(errs.reverse)
- }
+ checkParamsConvertible(tree.pos, tree.tpe)
val tree0 = etaExpand(context.unit, tree)
// println("eta "+tree+" ---> "+tree0+":"+tree0.tpe+" undet: "+context.undetparams+ " mode: "+Integer.toHexString(mode))
@@ -771,10 +773,11 @@ trait Typers extends Modes with Adaptations {
} else if (!meth.isConstructor && mt.params.isEmpty) { // (4.3)
adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt, original)
} else if (context.implicitsEnabled) {
- MissingArgsForMethodTpeError(tree, meth)
+ errorTree(tree, "missing arguments for " + meth + meth.locationString +
+ (if (meth.isConstructor) ""
+ else ";\nfollow this method with `_' if you want to treat it as a partially applied function"))
} else {
- // Relevant only for #4425 ?
- Bug4425Error(tree)
+ setError(tree)
}
}
@@ -787,7 +790,8 @@ trait Typers extends Modes with Adaptations {
// 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)
+ errorTree(tree, tree.symbol + " takes type parameters")
+ tree setType tree.tpe
} else if ( // (7.1) @M: check kind-arity
// @M: removed check for tree.hasSymbol and replace tree.symbol by tree.tpe.symbol (TypeTree's must also be checked here, and they don't directly have a symbol)
(inHKMode(mode)) &&
@@ -802,7 +806,9 @@ trait Typers extends Modes with Adaptations {
// 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).
- KindArityMismatchError(tree, pt)
+ errorTree(tree, tree.tpe + " takes " + countElementsAsString(tree.tpe.typeParams.length, "type parameter") +
+ ", expected: " + countAsString(pt.typeParams.length))
+ tree setType tree.tpe
} else tree match { // (6)
case TypeTree() => tree
case _ => TypeTree(tree.tpe) setOriginal (tree)
@@ -822,18 +828,13 @@ trait Typers extends Modes with Adaptations {
val tree1 = TypeTree(clazz.primaryConstructor.tpe.asSeenFrom(prefix, clazz.owner))
.setOriginal(tree)
- inferConstructorInstance(tree1, clazz.typeParams, pt) match {
- case Some(err) =>
- if (tree1.containsError())
- Block(List(err), tree1)
- else err
- case _ => tree1
- }
+ inferConstructorInstance(tree1, clazz.typeParams, pt)
+ tree1
} else {
tree
}
} else {
- CaseClassConstructorError(tree)
+ errorTree(tree, tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method")
}
}
@@ -851,8 +852,7 @@ trait Typers extends Modes with Adaptations {
case other =>
other
}
- if (qual.containsError()) qual // Fail quickly
- else typed(atPos(tree.pos)(Select(qual, nme.apply)), mode, pt)
+ typed(atPos(tree.pos)(Select(qual, nme.apply)), mode, pt)
}
// begin adapt
@@ -867,10 +867,8 @@ trait Typers extends Modes with Adaptations {
}
treeCopy.Literal(tree, value)
case OverloadedType(pre, alts) if !inFunMode(mode) => // (1)
- inferExprAlternative(tree, pt) match {
- case Some(err) => err
- case _ => adapt(tree, mode, pt, original)
- }
+ inferExprAlternative(tree, pt)
+ adapt(tree, mode, pt, original)
case NullaryMethodType(restpe) => // (2)
adapt(tree setType restpe, mode, pt, original)
case TypeRef(_, ByNameParamClass, List(arg)) if ((mode & EXPRmode) != 0) => // (2)
@@ -929,10 +927,7 @@ trait Typers extends Modes with Adaptations {
} else {
if (inPatternMode(mode)) {
if ((tree.symbol ne null) && tree.symbol.isModule)
- inferModulePattern(tree, pt) match {
- case Some(err) => return err
- case _ =>
- }
+ inferModulePattern(tree, pt)
if (isPopulated(tree.tpe, approximateAbstracts(pt)))
return tree
}
@@ -960,8 +955,7 @@ trait Typers extends Modes with Adaptations {
if (!context.undetparams.isEmpty) {
return instantiate(tree, mode, pt)
}
- val validTree = !tree.containsErrorOrIsErrorTyped()
- if (context.implicitsEnabled && !pt.isError && validTree) {
+ if (context.implicitsEnabled && !tree.tpe.isError && !pt.isError) {
// (14); the condition prevents chains of views
debuglog("inferring view from " + tree.tpe + " to " + pt)
val coercion = inferView(tree, tree.tpe, pt, true)
@@ -978,7 +972,7 @@ trait Typers extends Modes with Adaptations {
new ApplyImplicitView(coercion, List(tree)) setPos tree.pos, mode, pt)
}
}
- if (isCodeType(pt) && !isCodeType(tree.tpe) && validTree)
+ if (isCodeType(pt) && !isCodeType(tree.tpe) && !tree.tpe.isError)
return adapt(lifted(tree), mode, pt, original)
}
if (settings.debug.value) {
@@ -1009,7 +1003,7 @@ trait Typers extends Modes with Adaptations {
context.unit.warning(tree.pos, "recovering from existential Skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree)
adapt(tree, mode, pt.subst(pt.existentialSkolems, pt.existentialSkolems map (_ => WildcardType)))
} else
- TypeErrorTree(tree, pt, ex)
+ throw ex
}
}
}
@@ -1017,10 +1011,8 @@ trait Typers extends Modes with Adaptations {
}
def instantiate(tree: Tree, mode: Int, pt: Type): Tree = {
- inferExprInstance(tree, context.extractUndetparams(), pt) match {
- case (Some(err), _) => err
- case _ => adapt(tree, mode, pt)
- }
+ inferExprInstance(tree, context.extractUndetparams(), pt)
+ adapt(tree, mode, pt)
}
/** If the expected type is Unit: try instantiating type arguments
* with expected type Unit, but if that fails, try again with pt = WildcardType
@@ -1028,8 +1020,8 @@ trait Typers extends Modes with Adaptations {
*/
def instantiateExpectingUnit(tree: Tree, mode: Int): Tree = {
val savedUndetparams = context.undetparams
- instantiate(tree, mode, UnitClass.tpe) match {
- case t: Tree if !t.containsError() => t
+ silent(_.instantiate(tree, mode, UnitClass.tpe)) match {
+ case t: Tree => t
case _ =>
context.undetparams = savedUndetparams
val valueDiscard = atPos(tree.pos)(Block(List(instantiate(tree, mode, WildcardType)), Literal(Constant())))
@@ -1077,48 +1069,40 @@ trait Typers extends Modes with Adaptations {
adaptToMember(qual, HasMethodMatching(name, args map (_.tpe), restpe))
if (pt != WildcardType) {
silent(_ => doAdapt(pt)) match {
- case result: Tree if result != qual && !result.containsError() =>
+ case result: Tree if result != qual =>
result
case _ =>
debuglog("fallback on implicits in adaptToArguments: "+qual+" . "+name)
doAdapt(WildcardType)
}
- } else {
+ } else
doAdapt(pt)
- }
}
- /** Try to apply an implicit conversion to `qual` so that it contains
- * a method `name`. If that's ambiguous try taking arguments into
- * account using `adaptToArguments`.
+ /** Try o apply an implicit conversion to `qual` to that it contains
+ * a method `name`. If that's ambiguous try taking arguments into account using `adaptToArguments`.
*/
def adaptToMemberWithArgs(tree: Tree, qual: Tree, name: Name, mode: Int): Tree = {
- def onError(reportError: => Tree): Tree = {
- // last ditch effort
+ try {
+ adaptToMember(qual, HasMember(name))
+ } catch {
+ case ex: TypeError =>
+ // this happens if implicits are ambiguous; try again with more context info.
+ // println("last ditch effort: "+qual+" . "+name)
context.tree match {
case Apply(tree1, args) if (tree1 eq tree) && args.nonEmpty => // try handling the arguments
// println("typing args: "+args)
silent(_.typedArgs(args, mode)) match {
- case xs: List[_] =>
- val args = xs.asInstanceOf[List[Tree]]
- if (args exists (_.containsError()))
- reportError
- else
- adaptToArguments(qual, name, args, WildcardType)
- case _ =>
- reportError
+ case args: List[_] =>
+ adaptToArguments(qual, name, args.asInstanceOf[List[Tree]], WildcardType)
+ case _ =>
+ throw ex
}
case _ =>
- reportError
+ // println("not in an apply: "+context.tree+"/"+tree)
+ throw ex
}
}
- try {
- val res = adaptToMember(qual, HasMember(name))
- if (res.containsError()) onError(res) else res
- } catch {
- case ex: TypeError =>
- onError(AdaptToMemberWithArgsError(tree, ex))
- }
}
/** Try to apply an implicit conversion to `qual` to that it contains a
@@ -1151,7 +1135,6 @@ trait Typers extends Modes with Adaptations {
if (templ.parents.isEmpty) List()
else try {
val clazz = context.owner
- var pending: List[ErrorTree] = List()
// Normalize supertype and mixins so that supertype is always a class, not a trait.
var supertpt = typedTypeConstructor(templ.parents.head)
@@ -1160,13 +1143,7 @@ trait Typers extends Modes with Adaptations {
// If first parent is a trait, make it first mixin and add its superclass as first parent
while ((supertpt.tpe.typeSymbol ne null) && supertpt.tpe.typeSymbol.initialize.isTrait) {
val supertpt1 = typedType(supertpt)
- if (supertpt1.containsError()) {
- // we assume here that all errors in supertpt1 have already been reported
- supertpt setType ErrorType
- } else if (supertpt1.tpe.isError) {
- // Should not happen with ErrorTree
- assert(false, "Erroneous SuperType contains Error tree")
- } else {
+ if (!supertpt1.tpe.isError) {
mixins = supertpt1 :: mixins
supertpt = TypeTree(supertpt1.tpe.parents.head) setPos supertpt.pos.focus
}
@@ -1210,20 +1187,14 @@ trait Typers extends Modes with Adaptations {
val cbody2 = newTyper(cscope) // called both during completion AND typing.
.typePrimaryConstrBody(clazz,
cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate)))
-
- if (cbody2.containsError())
- pending = errorTreesFinder(cbody2).toList ::: pending
-
superCall match {
case Apply(_, _) =>
val sarg = treeInfo.firstArgument(superCall)
if (sarg != EmptyTree && supertpe.typeSymbol != firstParent)
- pending ::= ConstrArgsInTraitParentTpeError(sarg, firstParent)
- if (!supertparams.isEmpty)
- supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos.focus
+ error(sarg.pos, firstParent+" is a trait; does not take constructor arguments")
+ if (!supertparams.isEmpty) supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos.focus
case _ =>
- if (!supertparams.isEmpty)
- pending ::= MissingTypeArgumentsParentTpeError(supertpt)
+ if (!supertparams.isEmpty) error(supertpt.pos, "missing type arguments")
}
val preSuperVals = treeInfo.preSuperFields(templ.body)
@@ -1233,8 +1204,7 @@ trait Typers extends Modes with Adaptations {
(preSuperStats, preSuperVals).zipped map { case (ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe }
case _ =>
- if (!supertparams.isEmpty)
- pending ::= MissingTypeArgumentsParentTpeError(supertpt)
+ if (!supertparams.isEmpty) error(supertpt.pos, "missing type arguments")
}
/* experimental: early types as type arguments
val hasEarlyTypes = templ.body exists (treeInfo.isEarlyTypeDef)
@@ -1246,11 +1216,12 @@ trait Typers extends Modes with Adaptations {
*/
//Console.println("parents("+clazz") = "+supertpt :: mixins);//DEBUG
- supertpt :: pending ::: mixins mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
+ supertpt :: mixins mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
} catch {
case ex: TypeError =>
- // TODO: remove once error trees refactoring is done
- List(ParentTypesError(templ, ex))
+ templ.tpe = null
+ reportTypeError(templ.pos, ex)
+ List(TypeTree(AnyRefClass.tpe))
}
/** <p>Check that</p>
@@ -1267,35 +1238,32 @@ trait Typers extends Modes with Adaptations {
* <li>no two parents define same symbol.</li>
* </ul>
*/
- def validateParentClasses(parents: List[Tree], selfType: Type): Option[PendingErrors] = {
- var pending: List[ErrorTree] = List()
+ def validateParentClasses(parents: List[Tree], selfType: Type) {
def validateParentClass(parent: Tree, superclazz: Symbol) {
- if (!parent.containsErrorOrIsErrorTyped()) {
+ if (!parent.tpe.isError) {
val psym = parent.tpe.typeSymbol.initialize
- checkClassType(parent, false, true) match {
- case t@Some(err) =>
- pending = err::pending
- case _ =>
- }
+ checkClassType(parent, false, true)
if (psym != superclazz) {
if (psym.isTrait) {
val ps = psym.info.parents
if (!ps.isEmpty && !superclazz.isSubClass(ps.head.typeSymbol))
- pending = ParentSuperSubclassError(parent.pos, superclazz, ps.head.typeSymbol, psym)::pending
+ error(parent.pos, "illegal inheritance; super"+superclazz+
+ "\n is not a subclass of the super"+ps.head.typeSymbol+
+ "\n of the mixin " + psym)
} else {
- pending = ParentNotATraitMixinError(parent.pos, psym)::pending
+ error(parent.pos, psym+" needs to be a trait to be mixed in")
}
}
- if (psym.isFinal)
- pending = ParentFinalInheritanceError(parent.pos, psym)::pending
-
+ if (psym.isFinal) {
+ error(parent.pos, "illegal inheritance from final "+psym)
+ }
if (psym.isSealed && !phase.erasedTypes) {
// AnyVal is sealed, but we have to let the value classes through manually
if (context.unit.source.file == psym.sourceFile || isValueClass(context.owner))
psym addChild context.owner
else
- pending = ParentSealedInheritanceError(parent.pos, psym)::pending
+ error(parent.pos, "illegal inheritance from sealed "+psym)
}
if (!(selfType <:< parent.tpe.typeOfThis) &&
!phase.erasedTypes &&
@@ -1307,19 +1275,18 @@ trait Typers extends Modes with Adaptations {
//Console.println(context.owner);//DEBUG
//Console.println(context.owner.unsafeTypeParams);//DEBUG
//Console.println(List.fromArray(context.owner.info.closure));//DEBUG
- pending = ParentSelfTypeConformanceError(parent.pos, selfType, parent)::pending
+ error(parent.pos, "illegal inheritance;\n self-type "+
+ selfType+" does not conform to "+parent +
+ "'s selftype "+parent.tpe.typeOfThis)
if (settings.explaintypes.value) explainTypes(selfType, parent.tpe.typeOfThis)
}
if (parents exists (p => p != parent && p.tpe.typeSymbol == psym && !psym.isError))
- pending = ParentInheritedTwiceError(parent.pos, psym)::pending
+ error(parent.pos, psym+" is inherited twice")
}
}
- if (parents.forall(!_.containsError())) {
- // proceed as normal, we know that head.tpe is not error?
- if (!parents.isEmpty && !parents.head.tpe.isError)
- for (p <- parents) validateParentClass(p, parents.head.tpe.typeSymbol)
- }
- if (pending.isEmpty) None else Some(PendingErrors(pending.reverse))
+
+ if (!parents.isEmpty && !parents.head.tpe.isError)
+ for (p <- parents) validateParentClass(p, parents.head.tpe.typeSymbol)
/*
if (settings.Xshowcls.value != "" &&
@@ -1330,11 +1297,11 @@ trait Typers extends Modes with Adaptations {
*/
}
- def checkFinitary(classinfo: ClassInfoType): List[ErrorTree] = {
+ def checkFinitary(classinfo: ClassInfoType) {
val clazz = classinfo.typeSymbol
-
- clazz.typeParams.map(tparam =>
+ for (tparam <- clazz.typeParams) {
if (classinfo.expansiveRefs(tparam) contains tparam) {
+ error(tparam.pos, "class graph is not finitary because type parameter "+tparam.name+" is expansively recursive")
val newinfo = ClassInfoType(
classinfo.parents map (_.instantiateTypeParams(List(tparam), List(AnyRefClass.tpe))),
classinfo.decls,
@@ -1345,9 +1312,8 @@ trait Typers extends Modes with Adaptations {
case _ => newinfo
}
}
- Some(FinitaryError(tparam))
- } else None
- ).flatten
+ }
+ }
}
/**
@@ -1434,16 +1400,15 @@ trait Typers extends Modes with Adaptations {
val getter = if (isDeferred) value else value.getter(value.owner)
assert(getter != NoSymbol, stat)
- val gs = new ListBuffer[Tree]
if (getter.isOverloaded)
- gs.append(GetterDefinedTwiceError(getter))
+ error(getter.pos, getter+" is defined twice")
getter.setAnnotations(memberAnnots(allAnnots, GetterTargetClass))
if (value.isLazy) List(stat)
else {
- val vdef = treeCopy.ValDef(stat, mods | PrivateLocal, nme.getterToLocal(name), tpt, rhs)
- val getterDef = atPos(vdef.pos.focus) {
+ val vdef = treeCopy.ValDef(stat, mods | PRIVATE | LOCAL, nme.getterToLocal(name), tpt, rhs)
+ val getterDef: DefDef = atPos(vdef.pos.focus) {
if (isDeferred) {
val r = DefDef(getter, EmptyTree)
r.tpt.asInstanceOf[TypeTree].setOriginal(tpt) // keep type tree of original abstract field
@@ -1459,21 +1424,18 @@ trait Typers extends Modes with Adaptations {
r
}
}
-
- def setterDef(setter: Symbol, isBean: Boolean = false): Tree = {
+ checkNoEscaping.privates(getter, getterDef.tpt)
+ def setterDef(setter: Symbol, isBean: Boolean = false): DefDef = {
setter setAnnotations memberAnnots(allAnnots, if (isBean) BeanSetterTargetClass else SetterTargetClass)
val defTree =
if ((mods hasFlag DEFERRED) || (setter hasFlag OVERLOADED)) EmptyTree
else Assign(Select(This(value.owner), value), Ident(setter.paramss.head.head))
- typedPos(vdef.pos.focus)(DefDef(setter, defTree))
+ typedPos(vdef.pos.focus)(DefDef(setter, defTree)).asInstanceOf[DefDef]
}
- val privateErrors = checkNoEscaping.privates(getter, getterDef.tpt)
- if (privateErrors.containsError())
- privateErrors.foreach(err => gs.append(err))
-
+ val gs = new ListBuffer[DefDef]
gs.append(getterDef)
if (mods.isMutable) {
val setter = getter.setter(value.owner)
@@ -1489,7 +1451,7 @@ trait Typers extends Modes with Adaptations {
if (beanGetter == NoSymbol) {
// the namer decides wether to generate these symbols or not. at that point, we don't
// have symbolic information yet, so we only look for annotations named "BeanProperty".
- gs.append(BeanPropertyAnnotationLimitationError(stat))
+ unit.error(stat.pos, "implementation limitation: the BeanProperty annotation cannot be used in a type alias or renamed import")
}
beanGetter.setAnnotations(memberAnnots(allAnnots, BeanGetterTargetClass))
if (mods.isMutable && beanGetter != NoSymbol) {
@@ -1588,32 +1550,20 @@ trait Typers extends Modes with Adaptations {
// the following is necessary for templates generated later
assert(clazz.info.decls != EmptyScope)
enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body)
-
- var doNotTypeBody = false
- val parents2 = validateParentClasses(parents1, selfType) match {
- case Some(err) =>
- doNotTypeBody = err.pending0.exists(_.isInstanceOf[BlockingError])
- List(err)
- case _ => parents1
- }
+ validateParentClasses(parents1, selfType)
if (clazz.isCase)
validateNoCaseAncestor(clazz)
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
-
- val finitiaryErrs =
- if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
- checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
- else List()
+ if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
+ checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
val body =
- if (phase.id <= currentRun.typerPhase.id && !reporter.hasErrors && !doNotTypeBody)
+ if (phase.id <= currentRun.typerPhase.id && !reporter.hasErrors)
templ.body flatMap addGetterSetter
else templ.body
-
- val body1 = if (doNotTypeBody) body else typedStats(body, templ.symbol)
- val body2 = finitiaryErrs ++ body1
- treeCopy.Template(templ, parents2, self1, body2) setType clazz.tpe
+ val body1 = typedStats(body, templ.symbol)
+ treeCopy.Template(templ, parents1, self1, body1) setType clazz.tpe
}
/** Remove definition annotations from modifiers (they have been saved
@@ -1631,29 +1581,22 @@ trait Typers extends Modes with Adaptations {
val sym = vdef.symbol
val typer1 = constrTyperIf(sym.isParameter && sym.owner.isConstructor)
val typedMods = removeAnnotations(vdef.mods)
- var pending: List[ErrorTree] = List()
// complete lazy annotations
val annots = sym.annotations
var tpt1 = checkNoEscaping.privates(sym, typer1.typedType(vdef.tpt))
- checkNonCyclic(vdef, tpt1) match {
- case Some(cyclic) =>
- pending = cyclic::pending
- case _ =>
- }
+ checkNonCyclic(vdef, tpt1)
if (sym.hasAnnotation(definitions.VolatileAttr)) {
if (!sym.isMutable)
- pending = VolatileValueError(vdef)::pending
+ error(vdef.pos, "values cannot be volatile")
else if (sym.isFinal)
- pending = FinalVolatileVarError(vdef)::pending
+ error(vdef.pos, "final vars cannot be volatile")
}
val rhs1 =
- if (tpt1.containsError()) {
- vdef.rhs
- } else if (vdef.rhs.isEmpty) {
+ if (vdef.rhs.isEmpty) {
if (sym.isVariable && sym.owner.isTerm && phase.id <= currentRun.typerPhase.id)
- pending = LocalVarUninitializedError(vdef)::pending
+ error(vdef.pos, "local variables must be initialized")
vdef.rhs
} else {
val tpt2 = if (sym.hasDefault) {
@@ -1676,10 +1619,7 @@ trait Typers extends Modes with Adaptations {
} else tpt1.tpe
newTyper(typer1.context.make(vdef, sym)).transformedOrTyped(vdef.rhs, EXPRmode | BYVALmode, tpt2)
}
- val rhs2 = if (pending.nonEmpty) {
- PendingErrors(pending.reverse)
- } else rhs1
- treeCopy.ValDef(vdef, typedMods, vdef.name, tpt1, checkDead(rhs2)) setType NoType
+ treeCopy.ValDef(vdef, typedMods, vdef.name, tpt1, checkDead(rhs1)) setType NoType
}
/** Enter all aliases of local parameter accessors.
@@ -1688,7 +1628,7 @@ trait Typers extends Modes with Adaptations {
* @param vparamss ...
* @param rhs ...
*/
- def computeParamAliases(clazz: Symbol, vparamss: List[List[ValDef]], rhs: Tree): List[ErrorTree] = {
+ def computeParamAliases(clazz: Symbol, vparamss: List[List[ValDef]], rhs: Tree) {
debuglog("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
def decompose(call: Tree): (Tree, List[Tree]) = call match {
case Apply(fn, args) =>
@@ -1706,17 +1646,16 @@ trait Typers extends Modes with Adaptations {
val (superConstr, superArgs) = decompose(rhs)
assert(superConstr.symbol ne null)//debug
- var pending: List[ErrorTree] = List()
// an object cannot be allowed to pass a reference to itself to a superconstructor
// because of initialization issues; bug #473
for (arg <- superArgs ; tree <- arg) {
val sym = tree.symbol
if (sym != null && (sym.info.baseClasses contains clazz)) {
if (sym.isModule)
- pending = SuperConstrReferenceError(tree)::pending
+ error(tree.pos, "super constructor cannot be passed a self reference unless parameter is declared by-name")
tree match {
case This(qual) =>
- pending = SuperConstrArgsThisReferenceError(tree)::pending
+ error(tree.pos, "super constructor arguments cannot reference unconstructed `this`")
case _ => ()
}
}
@@ -1754,8 +1693,6 @@ trait Typers extends Modes with Adaptations {
}
}
}
-
- pending
}
/** Check if a structurally defined method violates implementation restrictions.
@@ -1804,7 +1741,7 @@ trait Typers extends Modes with Adaptations {
lookupVariable(name.toString.substring(1), enclClass) match {
case Some(repl) =>
silent(_.typedTypeConstructor(stringParser(repl).typ())) match {
- case tpt: Tree if !tpt.containsError()=>
+ case tpt: Tree =>
val alias = enclClass.newAliasType(useCase.pos, name.toTypeName)
val tparams = cloneSymbols(tpt.tpe.typeSymbol.typeParams, alias)
alias setInfo typeFun(tparams, appliedType(tpt.tpe, tparams map (_.tpe)))
@@ -1832,14 +1769,7 @@ trait Typers extends Modes with Adaptations {
* @return ...
*/
def typedDefDef(ddef: DefDef): DefDef = {
- def logErrorTree(t: Tree, errs: List[ErrorTree]) =
- t match {
- case errTree: ErrorTree => errTree::errs
- case _ => errs
- }
-
val meth = ddef.symbol
- var pending: List[ErrorTree] = List()
reenterTypeParams(ddef.tparams)
reenterValueParams(ddef.vparamss)
@@ -1861,22 +1791,17 @@ trait Typers extends Modes with Adaptations {
val annots = meth.annotations
for (vparams1 <- vparamss1; vparam1 <- vparams1 dropRight 1)
- if (isRepeatedParamType(vparam1.symbol.tpe)) {
- pending = StarParamNotLastError(vparam1)::pending
- }
+ if (isRepeatedParamType(vparam1.symbol.tpe))
+ error(vparam1.pos, "*-parameter must come last")
var tpt1 = checkNoEscaping.privates(meth, typedType(ddef.tpt))
if (!settings.YdepMethTpes.value) {
for (vparams <- vparamss1; vparam <- vparams) {
- pending = logErrorTree(checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt), pending)
+ checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
}
- pending = logErrorTree(checkNoEscaping.locals(context.scope, WildcardType, tpt1), pending)
- }
- checkNonCyclic(ddef, tpt1) match {
- case Some(cylic) =>
- pending = cylic::pending
- case _ =>
+ checkNoEscaping.locals(context.scope, WildcardType, tpt1)
}
+ checkNonCyclic(ddef, tpt1)
ddef.tpt.setType(tpt1.tpe)
val typedMods = removeAnnotations(ddef.mods)
var rhs1 =
@@ -1885,41 +1810,35 @@ trait Typers extends Modes with Adaptations {
(!meth.owner.isClass ||
meth.owner.isModuleClass ||
meth.owner.isAnonOrRefinementClass))
- pending = InvalidConstructorDefError(ddef)::pending
+ error(ddef.pos, "constructor definition not allowed here")
typed(ddef.rhs)
} else {
transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe)
}
if (meth.isPrimaryConstructor && meth.isClassConstructor &&
- phase.id <= currentRun.typerPhase.id && !reporter.hasErrors) {
- computeParamAliases(meth.owner, vparamss1, rhs1) match {
- case Nil => ()
- case pending0 =>
- pending = pending0 ::: pending
- }
- }
+ phase.id <= currentRun.typerPhase.id && !reporter.hasErrors)
+ computeParamAliases(meth.owner, vparamss1, rhs1)
if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass)
rhs1 = checkDead(rhs1)
if (phase.id <= currentRun.typerPhase.id && meth.owner.isClass &&
meth.paramss.exists(ps => ps.exists(_.hasDefaultFlag) && isRepeatedParamType(ps.last.tpe)))
- pending = StarWithDefaultError(meth)::pending
+ error(meth.pos, "a parameter section with a `*'-parameter is not allowed to have default arguments")
if (phase.id <= currentRun.typerPhase.id) {
val allParams = meth.paramss.flatten
for (p <- allParams) {
for (n <- p.deprecatedParamName) {
if (allParams.exists(p1 => p1.name == n || (p != p1 && p1.deprecatedParamName.exists(_ == n))))
- pending = DeprecatedParamNameError(p, n)::pending
+ error(p.pos, "deprecated parameter name "+ n +" has to be distinct from any other parameter name (deprecated or not).")
}
}
}
if (meth.isStructuralRefinementMember)
checkMethodStructuralCompatible(meth)
- if (pending.nonEmpty)
- rhs1 = wrapInBlock(PendingErrors(pending.reverse), rhs1)
+
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
@@ -1948,22 +1867,15 @@ trait Typers extends Modes with Adaptations {
}
val rhs1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.rhs))
- val rhs2 = checkNonCyclic(tdef.symbol) match {
- case Some(cyclic) =>
- wrapInBlock(cyclic, rhs1)
- case None =>
- if (tdef.symbol.owner.isType)
- rhs1.tpe match {
- case TypeBounds(lo1, hi1) if (!(lo1 <:< hi1)) =>
- wrapInBlock(
- LowerBoundError(tdef, lo1, hi1),
- rhs1)
- case _ =>
- rhs1
- }
- else rhs1
- }
- treeCopy.TypeDef(tdef, typedMods, tdef.name, tparams1, rhs2) setType NoType
+ checkNonCyclic(tdef.symbol)
+ if (tdef.symbol.owner.isType)
+ rhs1.tpe match {
+ case TypeBounds(lo1, hi1) =>
+ if (!(lo1 <:< hi1))
+ error(tdef.pos, "lower bound "+lo1+" does not conform to upper bound "+hi1)
+ case _ =>
+ }
+ treeCopy.TypeDef(tdef, typedMods, tdef.name, tparams1, rhs1) setType NoType
}
private def enterLabelDef(stat: Tree) {
@@ -2080,17 +1992,10 @@ trait Typers extends Modes with Adaptations {
*/
def typedCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {
// verify no _* except in last position
- var pending: List[ErrorTree] = List()
for (Apply(_, xs) <- cdef.pat ; x <- xs dropRight 1 ; if treeInfo isStar x)
- pending = StarPositionInPatternError(x.pos)::pending
+ error(x.pos, "_* may only come last")
- val pat0 = typedPattern(cdef.pat, pattpe)
- val pat1: Tree = pending match {
- case List() =>
- pat0
- case _ =>
- wrapInBlock(PendingErrors(pending.reverse), pat0)
- }
+ val pat1: Tree = typedPattern(cdef.pat, pattpe)
// When case classes have more than two parameter lists, the pattern ends
// up typed as a method. We only pattern match on the first parameter
// list, so substitute the final result type of the method, i.e. the type
@@ -2106,17 +2011,16 @@ trait Typers extends Modes with Adaptations {
val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree
else typed(cdef.guard, BooleanClass.tpe)
-
var body1: Tree = typed(cdef.body, pt)
if (!context.savedTypeBounds.isEmpty) {
body1.tpe = context.restoreTypeBounds(body1.tpe)
if (isFullyDefined(pt) && !(body1.tpe <:< pt)) {
- body1 = typed {
- atPos(body1.pos) {
- // @M no need for pt.normalize here, is done in erasure
- TypeApply(Select(body1, Any_asInstanceOf), List(TypeTree(pt)))
+ body1 =
+ typed {
+ atPos(body1.pos) {
+ TypeApply(Select(body1, Any_asInstanceOf), List(TypeTree(pt))) // @M no need for pt.normalize here, is done in erasure
+ }
}
- }
}
}
// body1 = checkNoEscaping.locals(context.scope, pt, body1)
@@ -2139,7 +2043,7 @@ trait Typers extends Modes with Adaptations {
val codeExpected = !forMSIL && (pt.typeSymbol isNonBottomSubClass CodeClass)
if (numVparams > definitions.MaxFunctionArity)
- return MaxFunctionArityError(fun)
+ return errorTree(fun, "implementation restricts functions to " + definitions.MaxFunctionArity + " parameters")
def decompose(pt: Type): (Symbol, List[Type], Type) =
if ((isFunctionType(pt)
@@ -2155,10 +2059,9 @@ trait Typers extends Modes with Adaptations {
(FunctionClass(numVparams), fun.vparams map (x => NoType), WildcardType)
val (clazz, argpts, respt) = decompose(if (codeExpected) pt.normalize.typeArgs.head else pt)
- val vparamErrors = new mutable.HashMap[ValDef, ErrorTree]()
if (argpts.lengthCompare(numVparams) != 0)
- WrongNumberOfParametersError(fun, argpts)
+ errorTree(fun, "wrong number of parameters; expected = " + argpts.length)
else {
val vparamSyms = (fun.vparams, argpts).zipped map { (vparam, argpt) =>
if (vparam.tpt.isEmpty) {
@@ -2168,7 +2071,7 @@ trait Typers extends Modes with Adaptations {
fun match {
case etaExpansion(vparams, fn, args) if !codeExpected =>
silent(_.typed(fn, forFunMode(mode), pt)) match {
- case fn1: Tree if context.undetparams.isEmpty && !fn1.containsError() =>
+ case fn1: Tree if context.undetparams.isEmpty =>
// if context,undetparams is not empty, the function was polymorphic,
// so we need the missing arguments to infer its type. See #871
//println("typing eta "+fun+":"+fn1.tpe+"/"+context.undetparams)
@@ -2179,7 +2082,7 @@ trait Typers extends Modes with Adaptations {
}
case _ =>
}
- vparamErrors += ((vparam, MissingParameterTypeError(fun, vparam, pt)))
+ error(vparam.pos, missingParameterTypeMsg(fun, vparam, pt))
ErrorType
}
if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus
@@ -2189,21 +2092,14 @@ trait Typers extends Modes with Adaptations {
vparam.symbol
}
- val vparams = fun.vparams mapConserve (p =>
- { val p0 = typedValDef(p)
- if (vparamErrors.contains(p)) {
- treeCopy.ValDef(p0, p0.mods, p0.name, vparamErrors(p), p0.rhs)
- }
- else p0
- })
+ val vparams = fun.vparams mapConserve (typedValDef)
// for (vparam <- vparams) {
// checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()
// }
- val body0 = typed(fun.body, respt)
+ var body = typed(fun.body, respt)
val formals = vparamSyms map (_.tpe)
- val (restpe0, errs) = packedType(body0, fun.symbol)//.deconst
- val body = if (errs.isEmpty) body0 else Block(errs, body0)
- val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe0.deconst)
+ val restpe = packedType(body, fun.symbol).deconst
+ val funtpe = typeRef(clazz.tpe.prefix, clazz, formals :+ restpe)
// body = checkNoEscaping.locals(context.scope, restpe, body)
val fun1 = treeCopy.Function(fun, vparams, body).setType(funtpe)
if (codeExpected) lifted(fun1) else fun1
@@ -2236,10 +2132,11 @@ trait Typers extends Modes with Adaptations {
case Some(imp1: Import) => imp1
case None => log("unhandled import: "+imp+" in "+unit); imp
}
+
private def isWarnablePureExpression(tree: Tree) = tree match {
case EmptyTree | Literal(Constant(())) => false
case _ =>
- !tree.containsErrorOrIsErrorTyped() && (treeInfo isPureExpr tree) && {
+ (treeInfo isPureExpr tree) && {
val sym = tree.symbol
(sym == null) || !(sym.isModule || sym.isLazy) || {
debuglog("'Pure' but side-effecting expression in statement position: " + tree)
@@ -2255,7 +2152,7 @@ trait Typers extends Modes with Adaptations {
val localTarget = stats exists includesTargetPos
def typedStat(stat: Tree): Tree = {
if (context.owner.isRefinementClass && !treeInfo.isDeclarationOrTypeDef(stat))
- OnlyDeclarationsError(stat)
+ errorTree(stat, "only declarations allowed here")
else
stat match {
case imp @ Import(_, _) =>
@@ -2273,19 +2170,16 @@ trait Typers extends Modes with Adaptations {
// XXX this creates a spurious dead code warning if an exception is thrown
// in a constructor, even if it is the only thing in the constructor.
val result = checkDead(localTyper.typed(stat, EXPRmode | BYVALmode, WildcardType))
-
- val result1 = if (treeInfo.isSelfOrSuperConstrCall(result)) {
- context.inConstructorSuffix = true
- if (treeInfo.isSelfConstrCall(result) && result.symbol.pos.pointOrElse(0) >= exprOwner.enclMethod.pos.pointOrElse(0))
- wrapInBlock(ConstructorsOrderError(stat), result)
- else result
- } else result
-
- if (isWarnablePureExpression(result1)) context.warning(stat.pos,
+ if (treeInfo.isSelfOrSuperConstrCall(result)) {
+ context.inConstructorSuffix = true
+ if (treeInfo.isSelfConstrCall(result) && result.symbol.pos.pointOrElse(0) >= exprOwner.enclMethod.pos.pointOrElse(0))
+ error(stat.pos, "called constructor's definition must precede calling constructor's definition")
+ }
+ if (isWarnablePureExpression(result)) context.warning(stat.pos,
"a pure expression does nothing in statement position; " +
"you may be omitting necessary parentheses"
)
- result1
+ result
}
}
}
@@ -2317,7 +2211,8 @@ trait Typers extends Modes with Adaptations {
// error for this is issued in RefChecks.checkDefaultsInOverloaded
if (!e.sym.isErroneous && !e1.sym.isErroneous && !e.sym.hasDefaultFlag &&
!e.sym.hasAnnotation(BridgeClass) && !e1.sym.hasAnnotation(BridgeClass)) {
- newStats += DefDefinedTwiceError(e.sym, e1.sym)
+ error(e.sym.pos, e1.sym+" is defined twice"+
+ {if(!settings.debug.value) "" else " in "+unit.toString})
scope.unlink(e1) // need to unlink to avoid later problems with lub; see #2779
}
e1 = scope.lookupNextEntry(e1)
@@ -2484,15 +2379,8 @@ trait Typers extends Modes with Adaptations {
arg1
}
context.undetparams = undetparams
-
- inferMethodAlternative(fun, undetparams, argtpes.toList, pt,
- varArgsOnly = treeInfo.isWildcardStarArgList(args)) match {
- case Some(err) =>
- err
- case _ =>
- doTypedApply(tree, adapt(fun, forFunMode(mode), WildcardType), args1, mode, pt)
- }
-
+ inferMethodAlternative(fun, undetparams, argtpes.toList, pt, varArgsOnly = treeInfo.isWildcardStarArgList(args))
+ doTypedApply(tree, adapt(fun, forFunMode(mode), WildcardType), args1, mode, pt)
case mt @ MethodType(params, _) =>
val paramTypes = mt.paramTypes
@@ -2512,7 +2400,7 @@ trait Typers extends Modes with Adaptations {
// the inner "doTypedApply" does "extractUndetparams" => restore when it fails
val savedUndetparams = context.undetparams
silent(_.doTypedApply(tree, fun, tupleArgs, mode, pt)) match {
- case t: Tree if !t.containsError() =>
+ case t: Tree =>
// Depending on user options, may warn or error here if
// a Unit or tuple was inserted.
Some(t) filter (tupledTree =>
@@ -2520,7 +2408,7 @@ trait Typers extends Modes with Adaptations {
|| tupledTree.symbol == null
|| checkValidAdaptation(tupledTree, args)
)
- case _ =>
+ case ex =>
context.undetparams = savedUndetparams
None
}
@@ -2538,24 +2426,19 @@ trait Typers extends Modes with Adaptations {
if (mt.isErroneous) setError(tree)
else if (inPatternMode(mode))
// #2064
- WrongNumberOfArgsError(tree, fun)
+ errorTree(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun))
else if (lencmp > 0) {
- tryTupleApply getOrElse TooManyArgsNamesDefaultsError(tree, fun)
+ tryTupleApply getOrElse errorTree(tree, "too many arguments for "+treeSymTypeMsg(fun))
} else if (lencmp == 0) {
// we don't need defaults. names were used, so this application is transformed
// into a block (@see transformNamedApplication in NamesDefaults)
-
val (namelessArgs, argPos) = removeNames(Typer.this)(args, params)
- if (namelessArgs exists (_.containsError())) {
- // This should maybe be special handled
- val tree1 = treeCopy.Apply(tree, fun, namelessArgs)
- setError(tree1)
- } else if (namelessArgs exists (_.isErroneous)) {
- assert(false, "removeNames for NamesDefaults returns only ErrorTrees in case of error. We got " + namelessArgs)
+ if (namelessArgs exists (_.isErroneous)) {
setError(tree)
} else if (!isIdentity(argPos) && !sameLength(formals, params))
// !isIdentity indicates that named arguments are used to re-order arguments
- MultipleVarargError(tree)
+ errorTree(tree, "when using named arguments, the vararg parameter "+
+ "has to be specified exactly once")
else if (isIdentity(argPos) && !isNamedApplyBlock(fun)) {
// if there's no re-ordering, and fun is not transformed, no need to transform
// more than an optimization, e.g. important in "synchronized { x = update-x }"
@@ -2569,8 +2452,7 @@ trait Typers extends Modes with Adaptations {
// calls to the default getters. Example:
// foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a))
val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x)
- if (fun1.containsError()) fun1
- else if (fun1.isErroneous) setError(tree)
+ if (fun1.isErroneous) setError(tree)
else {
assert(isNamedApplyBlock(fun1), fun1)
val NamedApplyInfo(qual, targs, previousArgss, _) = context.namedApplyBlockInfo.get._2
@@ -2587,20 +2469,17 @@ trait Typers extends Modes with Adaptations {
val lencmp2 = compareLengths(allArgs, formals)
if (!sameLength(allArgs, args) && callToCompanionConstr(context, funSym)) {
- ModuleUsingCompanionClassDefaultArgsErrror(tree)
+ errorTree(tree, "module extending its companion class cannot use default constructor arguments")
} else if (lencmp2 > 0) {
- val errors = removeNames(Typer.this)(allArgs, params)._1.filter(_.containsError()) // #3818
- if (!errors.isEmpty)
- wrapInBlock(PendingErrors(findAllNestedErrors(errors)), tree)
- else
- setError(tree)
+ removeNames(Typer.this)(allArgs, params) // #3818
+ setError(tree)
} else if (lencmp2 == 0) {
// useful when a default doesn't match parameter type, e.g. def f[T](x:T="a"); f[Int]()
val note = "Error occurred in an application involving default arguments."
if (!(context.diagnostic contains note)) context.diagnostic = note :: context.diagnostic
doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
} else {
- tryTupleApply getOrElse NotEnoughArgsError(tree, fun, missing)
+ tryTupleApply getOrElse errorTree(tree, notEnoughArgumentsMsg(fun, missing))
}
}
}
@@ -2624,7 +2503,6 @@ trait Typers extends Modes with Adaptations {
// instantiate dependent method types, must preserve singleton types where possible (stableTypeFor) -- example use case:
// val foo = "foo"; def precise(x: String)(y: x.type): x.type = {...}; val bar : foo.type = precise(foo)(foo)
// precise(foo) : foo.type => foo.type
-
val restpe = mt.resultType(args1 map (arg => gen.stableTypeFor(arg) getOrElse arg.tpe))
def ifPatternSkipFormals(tp: Type) = tp match {
case MethodType(_, rtp) if (inPatternMode(mode)) => rtp
@@ -2660,12 +2538,11 @@ trait Typers extends Modes with Adaptations {
atPos(tree.pos)(gen.mkNil setType restpe)
else
constfold(treeCopy.Apply(tree, fun, args1) setType ifPatternSkipFormals(restpe))
+
} else if (needsInstantiation(tparams, formals, args)) {
//println("needs inst "+fun+" "+tparams+"/"+(tparams map (_.info)))
- inferExprInstance(fun, tparams) match {
- case (Some(err), _) => err
- case _ => doTypedApply(tree, fun, args, mode, pt)
- }
+ inferExprInstance(fun, tparams)
+ doTypedApply(tree, fun, args, mode, pt)
} else {
assert(!inPatternMode(mode)) // this case cannot arise for patterns
val lenientTargs = protoTypeArgs(tparams, formals, mt.resultApprox, pt)
@@ -2682,31 +2559,20 @@ trait Typers extends Modes with Adaptations {
val argtparams = context.extractUndetparams()
if (!argtparams.isEmpty) {
val strictPt = formal.instantiateTypeParams(tparams, strictTargs)
- inferArgumentInstance(arg1, argtparams, strictPt, lenientPt) match {
- case Some(err) =>
- err
- case _ =>
- arg1
- }
- } else arg1
+ inferArgumentInstance(arg1, argtparams, strictPt, lenientPt)
+ }
+ arg1
}
val args1 = (args, formals).zipped map typedArgToPoly
- if (args1 exists {_.containsErrorOrIsErrorTyped()}) {
- val allNestedErrors = findAllNestedErrors(args1.filter(_.containsError()))
- if (allNestedErrors.isEmpty) SetErrorTree(tree) else PendingErrors(allNestedErrors)
- } else {
+ if (args1 exists (_.tpe.isError)) setError(tree)
+ else {
debuglog("infer method inst "+fun+", tparams = "+tparams+", args = "+args1.map(_.tpe)+", pt = "+pt+", lobounds = "+tparams.map(_.tpe.bounds.lo)+", parambounds = "+tparams.map(_.info)) //debug
// define the undetparams which have been fixed by this param list, replace the corresponding symbols in "fun"
// returns those undetparams which have not been instantiated.
- val undetparamsOrError = inferMethodInstance(fun, tparams, args1, pt)
- if (undetparamsOrError.isLeft) {
- context.undetparams = Nil
- undetparamsOrError.left.get
- } else {
- val result = doTypedApply(tree, fun, args1, mode, pt)
- context.undetparams = undetparamsOrError.right.get
- result
- }
+ val undetparams = inferMethodInstance(fun, tparams, args1, pt)
+ val result = doTypedApply(tree, fun, args1, mode, pt)
+ context.undetparams = undetparams
+ result
}
}
}
@@ -2715,15 +2581,12 @@ trait Typers extends Modes with Adaptations {
doTypedApply(tree, fun setType fun.tpe.widen, args, mode, pt)
case ErrorType =>
- if (tree.containsError())
- tree
- else
- ErroneousFunInTypeApplyError(fun, args)
+ setError(treeCopy.Apply(tree, fun, args))
/* --- begin unapply --- */
case otpe if inPatternMode(mode) && unapplyMember(otpe).exists =>
if (args.length > MaxTupleArity)
- return TooManyArgsPatternError(fun)
+ error(fun.pos, "too many arguments for unapply pattern, maximum = "+MaxTupleArity)
def freshArgType(tp: Type): (Type, List[Symbol]) = (tp: @unchecked) match {
case MethodType(param :: _, _) =>
@@ -2731,10 +2594,9 @@ trait Typers extends Modes with Adaptations {
case PolyType(tparams, restype) =>
val tparams1 = cloneSymbols(tparams)
(freshArgType(restype)._1.substSym(tparams, tparams1), tparams1)
- // No longer used, see test case neg/t960.scala (#960 has nothing to do with it)
-// case OverloadedType(_, _) =>
-// error(fun.pos, "cannot resolve overloaded unapply")
-// (ErrorType, Nil)
+ case OverloadedType(_, _) =>
+ error(fun.pos, "cannot resolve overloaded unapply")
+ (ErrorType, Nil)
}
val unapp = unapplyMember(otpe)
@@ -2749,11 +2611,7 @@ trait Typers extends Modes with Adaptations {
freeVars foreach context1.scope.enter
val typer1 = newTyper(context1)
- val pattp0 = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
- val pattp = pattp0 match {
- case Left(err) => return err // Fail quickly
- case Right(tp) => tp
- }
+ val pattp = typer1.infer.inferTypedPattern(tree.pos, unappFormal, arg.tpe)
// turn any unresolved type variables in freevars into existential skolems
val skolems = freeVars map { fv =>
@@ -2769,14 +2627,7 @@ trait Typers extends Modes with Adaptations {
// setType null is necessary so that ref will be stabilized; see bug 881
val fun1 = typedPos(fun.pos)(Apply(Select(fun setType null, unapp), List(arg)))
- // Set error tree
- if (fun1.containsError())
- ErroneousFunInTypeApplyError(fun1, args)
- else if (fun1.tpe.isErroneous) {
- assert(false, "Bug #4425 workaround is invalid")
- //Bug4425Error(tree)
- setError(tree)
- }
+ if (fun1.tpe.isErroneous) setError(tree)
else {
val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe)
val formals1 = formalTypes(formals0, args.length)
@@ -2791,13 +2642,14 @@ trait Typers extends Modes with Adaptations {
arg.tpe = pt1 // restore type (arg is a dummy tree, just needs to pass typechecking)
UnApply(fun1, args1) setPos tree.pos setType itype
}
- else
- WrongNumberArgsPatternError(tree, fun)
+ else {
+ errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
+ }
}
/* --- end unapply --- */
case _ =>
- ApplyWithoutArgsError(tree, fun)
+ errorTree(tree, fun.tpe+" does not take parameters")
}
}
@@ -2809,10 +2661,8 @@ trait Typers extends Modes with Adaptations {
def typedAnnotation(ann: Tree, mode: Int = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = {
lazy val annotationError = AnnotationInfo(ErrorType, Nil, Nil)
var hasError: Boolean = false
- var pending: List[ErrorTree] = List()
-
- def reportAnnotationError(errTree: ErrorTree) = {
- pending = errTree::pending
+ def error(pos: Position, msg: String) = {
+ context.error(pos, msg)
hasError = true
annotationError
}
@@ -2820,7 +2670,7 @@ trait Typers extends Modes with Adaptations {
/** Calling constfold right here is necessary because some trees (negated
* floats and literals in particular) are not yet folded.
*/
- def tryConst(tr: Tree, pt: Type): Either[ErrorTree, LiteralAnnotArg] = {
+ def tryConst(tr: Tree, pt: Type): Option[LiteralAnnotArg] = {
val const: Constant = typed(constfold(tr), EXPRmode, pt) match {
case l @ Literal(c) if !l.isErroneous => c
case tree => tree.tpe match {
@@ -2828,37 +2678,37 @@ trait Typers extends Modes with Adaptations {
case tpe => null
}
}
+ def fail(msg: String) = { error(tr.pos, msg) ; None }
- if (const == null) {
- Left(AnnotationNotAConstantError(tr))
- } else if (const.value == null)
- Left(AnnotationArgNullError(tr))
+ if (const == null)
+ fail("annotation argument needs to be a constant; found: " + tr)
+ else if (const.value == null)
+ fail("annotation argument cannot be null")
else
- Right(LiteralAnnotArg(const))
+ Some(LiteralAnnotArg(const))
}
/** Converts an untyped tree to a ClassfileAnnotArg. If the conversion fails,
* an error message is reported and None is returned.
*/
- def tree2ConstArg(tree: Tree, pt: Type): Either[Tree, ClassfileAnnotArg] = tree match {
+ def tree2ConstArg(tree: Tree, pt: Type): Option[ClassfileAnnotArg] = tree match {
case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) if (pt.typeSymbol == ArrayClass) =>
- Left(ArrayConstantsError(tree))
+ error(tree.pos, "Array constants have to be specified using the `Array(...)' factory method")
+ None
case ann @ Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
val annInfo = typedAnnotation(ann, mode, NoSymbol, pt.typeSymbol, true)
if (annInfo.atp.isErroneous) {
+ // recursive typedAnnotation call already printed an error, so don't call "error"
hasError = true
- Left(NullErrorTree)
- } else
- Right(NestedAnnotArg(annInfo))
+ None
+ } else Some(NestedAnnotArg(annInfo))
// use of Array.apply[T: ClassManifest](xs: T*): Array[T]
// and Array.apply(x: Int, xs: Int*): Array[Int] (and similar)
case Apply(fun, args) =>
val typedFun = typed(fun, forFunMode(mode), WildcardType)
- if (typedFun.containsError()) {
- Left(typedFun)
- } else if (typedFun.symbol.owner == ArrayModule.moduleClass && typedFun.symbol.name == nme.apply)
+ if (typedFun.symbol.owner == ArrayModule.moduleClass && typedFun.symbol.name == nme.apply)
pt match {
case TypeRef(_, ArrayClass, targ :: _) =>
trees2ConstArg(args, targ)
@@ -2867,24 +2717,21 @@ trait Typers extends Modes with Adaptations {
// BT = Int, .., String, Class[_], JavaAnnotClass
// T = BT | Array[BT]
// So an array literal as argument can only be valid if pt is Array[_]
- Left(ArrayConstantsTypeMismatchError(tree, pt))
+ error(tree.pos, "found array constant, expected argument of type "+ pt)
+ None
}
- else tryConst(tree, pt)
+ else
+ tryConst(tree, pt)
- case Typed(t, _) =>
- tree2ConstArg(t, pt)
+ case Typed(t, _) => tree2ConstArg(t, pt)
case tree =>
tryConst(tree, pt)
}
-
- def trees2ConstArg(trees: List[Tree], pt: Type): Either[ErrorTree, ArrayAnnotArg] = {
+ def trees2ConstArg(trees: List[Tree], pt: Type): Option[ArrayAnnotArg] = {
val args = trees.map(tree2ConstArg(_, pt))
- val par = args.filter(_.isLeft)
- if (!par.isEmpty)
- Left(PendingErrors(findAllNestedErrors(par.map(_.left.get))))
- else
- Right(ArrayAnnotArg(args.map(_.right.get).toArray))
+ if (args.exists(_.isEmpty)) None
+ else Some(ArrayAnnotArg(args.flatten.toArray))
}
// begin typedAnnotation
@@ -2896,18 +2743,14 @@ trait Typers extends Modes with Adaptations {
case Select(New(tpt), nme.CONSTRUCTOR) =>
(fun, outerArgss)
case _ =>
- (UnexpectedTreeAnnotation(fun), outerArgss)
+ error(fun.pos, "unexpected tree in annotation: "+ fun)
+ (setError(fun), outerArgss)
}
extract(ann, List())
}
-
- // It seems that fun.isErroneous was used due to check for deep error within fun?
- // We don't need it now because deep error within fun
- // is now detected by containsError()
- val res = if (fun.containsErrorOrIsErrorTyped()) {
- annotationError
- } else {
+ if (fun.isErroneous) annotationError
+ else {
val typedFun @ Select(New(tpt), _) = typed(fun, forFunMode(mode), WildcardType)
val annType = tpt.tpe
@@ -2916,9 +2759,9 @@ trait Typers extends Modes with Adaptations {
// annotation to be saved as java classfile annotation
val isJava = typedFun.symbol.owner.isJavaDefined
if (!annType.typeSymbol.isNonBottomSubClass(annClass)) {
- reportAnnotationError(AnnotationTypeMismatchError(tpt, annClass.tpe, annType))
+ error(tpt.pos, "expected annotation of type "+ annClass.tpe +", found "+ annType)
} else if (argss.length > 1) {
- reportAnnotationError(MultipleArgumentListForAnnotationError(ann))
+ error(ann.pos, "multiple argument lists on classfile annotation")
} else {
val args =
if (argss.head.length == 1 && !isNamed(argss.head.head))
@@ -2934,37 +2777,33 @@ trait Typers extends Modes with Adaptations {
val sym = if (isJava) annScope.lookup(name)
else typedFun.tpe.params.find(p => p.name == name).getOrElse(NoSymbol)
if (sym == NoSymbol) {
- reportAnnotationError(UnknownAnnotationNameError(arg, name))
+ error(arg.pos, "unknown annotation argument name: " + name)
(nme.ERROR, None)
} else if (!names.contains(sym)) {
- reportAnnotationError(DuplicateValueAnnotationError(arg, name))
+ error(arg.pos, "duplicate value for annotation argument " + name)
(nme.ERROR, None)
} else {
names -= sym
if (isJava) sym.cookJavaRawInfo() // #3429
val annArg = tree2ConstArg(rhs, sym.tpe.resultType)
- if (annArg.isLeft) {
- errorTreesFinder(annArg.left.get).foreach(reportAnnotationError)
- (nme.ERROR, None)
- } else
- (sym.name, Some(annArg.right.get))
+ (sym.name, annArg)
}
case arg =>
- reportAnnotationError(ClassfileAnnotationsAsNamedArgsError(arg))
+ error(arg.pos, "classfile annotation arguments have to be supplied as named arguments")
(nme.ERROR, None)
}
for (name <- names) {
if (!name.annotations.contains(AnnotationInfo(AnnotationDefaultAttr.tpe, List(), List())) &&
!name.hasDefaultFlag)
- reportAnnotationError(AnnotationMissingArgError(ann, annType, name))
+ error(ann.pos, "annotation " + annType.typeSymbol.fullName + " is missing argument " + name.name)
}
if (hasError) annotationError
else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}).setPos(ann.pos)
}
} else if (requireJava) {
- reportAnnotationError(NestedAnnotationError(ann, annType))
+ error(ann.pos, "nested classfile annotations must be defined in java; found: "+ annType)
} else {
val typedAnn = if (selfsym == NoSymbol) {
typed(ann, mode, annClass.tpe)
@@ -2992,9 +2831,6 @@ trait Typers extends Modes with Adaptations {
List(selfsym.info, annClass.tpe))
(typed(func, mode, funcType): @unchecked) match {
- case t if t.containsError() =>
- reportAnnotationError(NullErrorTree)
- t
case t @ Function(List(arg), rhs) =>
val subs =
new TreeSymSubstituter(List(arg.symbol),List(selfsym))
@@ -3019,27 +2855,16 @@ trait Typers extends Modes with Adaptations {
annInfo(fun)
case _ =>
- reportAnnotationError(UnexpectedTreeAnnotationError(t, typedAnn))
+ error(t.pos, "unexpected tree after typing annotation: "+ typedAnn)
}
if (annType.typeSymbol == DeprecatedAttr && argss.flatten.size < 2)
unit.deprecationWarning(ann.pos, "@deprecated now takes two arguments; see the scaladoc.")
- if (typedAnn.containsError() || (typedAnn.tpe == null) || typedAnn.tpe.isErroneous) annotationError
+ if ((typedAnn.tpe == null) || typedAnn.tpe.isErroneous) annotationError
else annInfo(typedAnn)
}
}
-
- if (hasError) {
- // We got errors, so now is the last chance to report them
- try {
- pending.foreach(_.emit(context))
- } catch {
- case _: TypeError =>
- assert(false, "Cannot throw type errors when creating AnnotationInfo")
- }
- annotationError
- } else res
}
def isRawParameter(sym: Symbol) = // is it a type parameter leaked by a raw type?
@@ -3098,8 +2923,7 @@ trait Typers extends Modes with Adaptations {
}
/** convert skolems to existentials */
- def packedType(tree: Tree, owner: Symbol): (Type, List[ErrorTree]) = {
- var pending: List[ErrorTree] = List()
+ def packedType(tree: Tree, owner: Symbol): Type = {
def defines(tree: Tree, sym: Symbol) =
sym.isExistentialSkolem && sym.unpackLocation == tree ||
tree.isDef && tree.symbol == sym
@@ -3125,7 +2949,7 @@ trait Typers extends Modes with Adaptations {
if (sym.isAliasType && containsLocal(tp)) apply(tp.normalize)
else {
if (pre.isVolatile)
- pending = InferTypeWithVolatileTypeSelectionError(tree, tp)::pending
+ context.error(tree.pos, "Inferred type "+tree.tpe+" contains type selection from volatile type "+pre)
mapOver(tp)
}
case _ =>
@@ -3142,7 +2966,8 @@ trait Typers extends Modes with Adaptations {
localSyms += sym
remainingSyms += sym
} else {
- pending = AbstractExistentiallyOverParamerizedTpeError(tree, tp)::pending
+ unit.error(tree.pos,
+ "can't existentially abstract over parameterized type " + tp)
}
}
}
@@ -3171,10 +2996,10 @@ trait Typers extends Modes with Adaptations {
}
for (sym <- remainingSyms) addLocals(sym.existentialBound)
}
+
val normalizedTpe = normalizeLocals(tree.tpe)
addLocals(normalizedTpe)
- val res = packSymbols(localSyms.toList, normalizedTpe)
- (res, pending.reverse)
+ packSymbols(localSyms.toList, normalizedTpe)
}
protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Int): Tree = {
@@ -3182,23 +3007,19 @@ trait Typers extends Modes with Adaptations {
if (wc.symbol == NoSymbol) { namer.enterSym(wc); wc.symbol setFlag EXISTENTIAL }
else context.scope enter wc.symbol
val whereClauses1 = typedStats(tree.whereClauses, context.owner)
- var pending: List[ErrorTree] = List()
for (vd @ ValDef(_, _, _, _) <- tree.whereClauses)
if (vd.symbol.tpe.isVolatile)
- pending = AbstractionFromVolatileTypeError(vd)::pending
+ error(vd.pos, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
val tpt1 = typedType(tree.tpt, mode)
val (typeParams, tpe) = existentialTransform(tree.whereClauses map (_.symbol), tpt1.tpe)
- val tt = TypeTree(ExistentialType(typeParams, tpe)) setOriginal tree
- if (pending.isEmpty) tt else tt.setErrorCause(PendingErrors(pending.reverse))
+ //println(tpe + ": " + tpe.getClass )
+ TypeTree(ExistentialType(typeParams, tpe)) setOriginal tree
}
// lifted out of typed1 because it's needed in typedImplicit0
protected def typedTypeApply(tree: Tree, mode: Int, fun: Tree, args: List[Tree]): Tree = fun.tpe match {
case OverloadedType(pre, alts) =>
- inferPolyAlternatives(fun, args map (_.tpe)) match {
- case Some(err) => return err
- case _ =>
- }
+ inferPolyAlternatives(fun, args map (_.tpe))
val tparams = fun.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree)
val args1 = if (sameLength(args, tparams)) {
//@M: in case TypeApply we can't check the kind-arities of the type arguments,
@@ -3211,7 +3032,7 @@ trait Typers extends Modes with Adaptations {
// Martin, I'm using fake trees, because, if you use args or arg.map(typedType),
// inferPolyAlternatives loops... -- I have no idea why :-(
// ...actually this was looping anyway, see bug #278.
- return TypedApplyWrongNumberOfTpeParametersError(fun, fun)
+ return errorTree(fun, "wrong number of type parameters for "+treeSymTypeMsg(fun))
typedTypeApply(tree, mode, fun, args1)
case SingleType(_, _) =>
@@ -3219,36 +3040,30 @@ trait Typers extends Modes with Adaptations {
case PolyType(tparams, restpe) if tparams.nonEmpty =>
if (sameLength(tparams, args)) {
val targs = args map (_.tpe)
- checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "") match {
- case Some(err) =>
- err
- case None =>
- if (fun.symbol == Predef_classOf) {
- checkClassType(args.head, true, false) match {
- case Some(err) => err
- case _ => atPos(tree.pos) { gen.mkClassOf(targs.head) }
- }
- } else {
- if (phase.id <= currentRun.typerPhase.id &&
- fun.symbol == Any_isInstanceOf && !targs.isEmpty)
- checkCheckable(tree.pos, targs.head, "")
- val resultpe = restpe.instantiateTypeParams(tparams, targs)
- //@M substitution in instantiateParams needs to be careful!
- //@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int]
- //@M --> first, m[a] gets changed to m[Int], then m gets substituted for List,
- // this must preserve m's type argument, so that we end up with List[Int], and not List[a]
- //@M related bug: #1438
- //println("instantiating type params "+restpe+" "+tparams+" "+targs+" = "+resultpe)
- treeCopy.TypeApply(tree, fun, args) setType resultpe
- }
+ checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "")
+ if (fun.symbol == Predef_classOf) {
+ checkClassType(args.head, true, false)
+ atPos(tree.pos) { gen.mkClassOf(targs.head) }
+ } else {
+ if (phase.id <= currentRun.typerPhase.id &&
+ fun.symbol == Any_isInstanceOf && !targs.isEmpty)
+ checkCheckable(tree.pos, targs.head, "")
+ val resultpe = restpe.instantiateTypeParams(tparams, targs)
+ //@M substitution in instantiateParams needs to be careful!
+ //@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int]
+ //@M --> first, m[a] gets changed to m[Int], then m gets substituted for List,
+ // this must preserve m's type argument, so that we end up with List[Int], and not List[a]
+ //@M related bug: #1438
+ //println("instantiating type params "+restpe+" "+tparams+" "+targs+" = "+resultpe)
+ treeCopy.TypeApply(tree, fun, args) setType resultpe
}
} else {
- TypedApplyWrongNumberOfTpeParametersError(tree, fun)
+ errorTree(tree, "wrong number of type parameters for "+treeSymTypeMsg(fun))
}
case ErrorType =>
setError(tree)
case _ =>
- TypedApplyDoesNotTakeTpeParametersError(tree, fun)
+ errorTree(tree, treeSymTypeMsg(fun)+" does not take type parameters.")
}
@inline final def deindentTyping() = context.typingIndentLevel -= 2
@@ -3318,10 +3133,9 @@ trait Typers extends Modes with Adaptations {
atype0 // do not record selfsym if
// this annotation did not need it
- if (ainfo.isErroneous) {
- // Erroneous annotations were already reported in typedAnnotation
+ if (ainfo.isErroneous)
arg1 // simply drop erroneous annotations
- } else {
+ else {
ann.tpe = atype
TypeTree(atype) setOriginal tree
}
@@ -3355,24 +3169,18 @@ trait Typers extends Modes with Adaptations {
tree setSymbol vble setType vble.tpe
}
def typedBindTerm(name: TermName) = {
- def typedBindTerm0() = {
- val body1 = typed(body, mode, pt)
- vble.setInfo(
- if (treeInfo.isSequenceValued(body)) seqType(body1.tpe)
- else body1.tpe)
- treeCopy.Bind(tree, name, body1) setSymbol vble setType body1.tpe // burak, was: pt
- }
if (vble == NoSymbol)
vble = context.owner.newValue(tree.pos, name)
if (vble.name.toTermName != nme.WILDCARD) {
- vble = namer.enterInScope(vble)
-
if ((mode & ALTmode) != 0)
- VariableInPatternAlternativeError(tree)
- else {
- typedBindTerm0()
- }
- } else typedBindTerm0()
+ error(tree.pos, "illegal variable in pattern alternative")
+ vble = namer.enterInScope(vble)
+ }
+ val body1 = typed(body, mode, pt)
+ vble.setInfo(
+ if (treeInfo.isSequenceValued(body)) seqType(body1.tpe)
+ else body1.tpe)
+ treeCopy.Bind(tree, name, body1) setSymbol vble setType body1.tpe // burak, was: pt
}
name match {
case x: TypeName => typedBindType(x)
@@ -3392,12 +3200,15 @@ trait Typers extends Modes with Adaptations {
def typedAssign(lhs: Tree, rhs: Tree): Tree = {
val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType)
val varsym = lhs1.symbol
+ def failMsg =
+ if (varsym != null && varsym.isValue) "reassignment to val"
+ else "assignment to non variable"
def fail = {
- if (lhs1.containsErrorOrIsErrorTyped())
- lhs1
- else // see #2494 for double error message example
- AssignmentError(tree, varsym)
+ if (!lhs1.tpe.isError)
+ error(tree.pos, failMsg)
+
+ setError(tree)
}
if (varsym == null)
return fail
@@ -3442,12 +3253,12 @@ trait Typers extends Modes with Adaptations {
enclMethod.owner.isConstructor ||
context.enclClass.enclMethod == enclMethod // i.e., we are in a constructor of a local class
) {
- ReturnOutsideOfDefError(tree)
+ errorTree(tree, "return outside method definition")
} else {
val DefDef(_, name, _, _, restpt, _) = enclMethod.tree
- if (restpt.tpe eq null) {
- ReturnWithoutTypeError(tree, enclMethod.owner)
- } else {
+ if (restpt.tpe eq null)
+ errorTree(tree, enclMethod.owner + " has return statement; needs result type")
+ else {
context.enclMethod.returnsSeen = true
val expr1: Tree = typed(expr, EXPRmode | BYVALmode, restpt.tpe)
// Warn about returning a value if no value can be returned.
@@ -3466,15 +3277,12 @@ trait Typers extends Modes with Adaptations {
def typedNew(tpt: Tree) = {
val tpt1 = {
val tpt0 = typedTypeConstructor(tpt)
- checkClassType(tpt0, false, true) match {
- case Some(err) => err
- case _ =>
- if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) {
- context.undetparams = cloneSymbols(tpt0.symbol.typeParams)
- TypeTree().setOriginal(tpt0)
- .setType(appliedType(tpt0.tpe, context.undetparams map (_.tpeHK))) // @PP: tpeHK! #3343, #4018, #4347.
- } else tpt0
- }
+ checkClassType(tpt0, false, true)
+ if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) {
+ context.undetparams = cloneSymbols(tpt0.symbol.typeParams)
+ TypeTree().setOriginal(tpt0)
+ .setType(appliedType(tpt0.tpe, context.undetparams map (_.tpeHK))) // @PP: tpeHK! #3343, #4018, #4347.
+ } else tpt0
}
/** If current tree <tree> appears in <val x(: T)? = <tree>>
@@ -3493,15 +3301,17 @@ trait Typers extends Modes with Adaptations {
val tp = tpt1.tpe
val sym = tp.typeSymbol
if (sym.isAbstractType || sym.hasAbstractFlag)
- IsAbstractError(tree, sym)
+ error(tree.pos, sym + " is abstract; cannot be instantiated")
else if (!( tp == sym.initialize.thisSym.tpe // when there's no explicit self type -- with (#3612) or without self variable
// sym.thisSym.tpe == tp.typeOfThis (except for objects)
|| narrowRhs(tp) <:< tp.typeOfThis
|| phase.erasedTypes
)) {
- DoesNotConformToSelfTypeError(tree, sym, tp.typeOfThis)
- } else
- treeCopy.New(tree, tpt1).setType(tp)
+ error(tree.pos, sym +
+ " cannot be instantiated because it does not conform to its self-type "+
+ tp.typeOfThis)
+ }
+ treeCopy.New(tree, tpt1).setType(tp)
}
def typedEta(expr1: Tree): Tree = expr1.tpe match {
@@ -3539,23 +3349,22 @@ trait Typers extends Modes with Adaptations {
case ErrorType =>
expr1
case _ =>
- UnderscoreEtaError(expr1)
+ errorTree(expr1, "_ must follow method; cannot follow " + expr1.tpe)
}
/**
* @param args ...
* @return ...
*/
- def tryTypedArgs(args: List[Tree], mode: Int): List[Tree] = {
+ def tryTypedArgs(args: List[Tree], mode: Int, other: TypeError): List[Tree] = {
val c = context.makeSilent(false)
c.retyping = true
try {
newTyper(c).typedArgs(args, mode)
} catch {
- case ex: CyclicReference =>
- throw ex
- case _: TypeError =>
- List(NullErrorTree)
+ case ex: CyclicReference => throw ex
+ case ex: TypeError =>
+ null
}
}
@@ -3564,8 +3373,10 @@ trait Typers extends Modes with Adaptations {
*/
def tryTypedApply(fun: Tree, args: List[Tree]): Tree = {
val start = startTimer(failedApplyNanos)
-
- def onError(treeWithError: Tree): Tree = {
+ silent(_.doTypedApply(tree, fun, args, mode, pt)) match {
+ case t: Tree =>
+ t
+ case ex: TypeError =>
stopTimer(failedApplyNanos, start)
// If the problem is with raw types, copnvert to existentials and try again.
@@ -3588,42 +3399,26 @@ trait Typers extends Modes with Adaptations {
case Typed(r, Function(Nil, EmptyTree)) => treesInResult(r)
case _ => Nil
})
- // Get correct posiition for the error
- val firstToReport = quickErrorTreeFinder(treeWithError)
- val ePos = firstToReport.pos
- def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == ePos)
-
- val retry = (ePos != null) && (fun :: tree :: args exists errorInResult)
- if (settings.errortrees.value)
- println("[ErrorTree retry] " + retry + " with " + treeWithError + " " + firstToReport.exception)
+ def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == ex.pos)
+ val retry = fun :: tree :: args exists errorInResult
printTyping {
val funStr = ptTree(fun) + " and " + (args map ptTree mkString ", ")
if (retry) "second try: " + funStr
- else "no second try: " + funStr + " because error not in result: " + ePos+"!="+tree.pos
+ else "no second try: " + funStr + " because error not in result: " + ex.pos+"!="+tree.pos
}
if (retry) {
val Select(qual, name) = fun
- val args1 = tryTypedArgs(args, forArgMode(fun, mode))
- val invalidArgs = args1.length == 1 && (args1.head.containsError() || args1.head.tpe.isErroneous)
+ val args1 = tryTypedArgs(args, forArgMode(fun, mode), ex)
val qual1 =
- if (!invalidArgs && !pt.isError) adaptToArguments(qual, name, args1, pt)
+ if ((args1 ne null) && !pt.isError) adaptToArguments(qual, name, args1, pt)
else qual
if (qual1 ne qual) {
val tree1 = Apply(Select(qual1, name) setPos fun.pos, args1) setPos tree.pos
return typed1(tree1, mode | SNDTRYmode, pt)
}
}
-
- firstToReport
- }
-
- silent(_.doTypedApply(tree, fun, args, mode, pt)) match {
- case t: Tree if !t.containsError() =>
- t
- case t: Tree =>
- onError(t)
- case ex: TypeError =>
- onError(TypedApplyError(fun, ex))
+ reportTypeError(tree.pos, ex)
+ setError(tree)
}
}
@@ -3636,32 +3431,10 @@ trait Typers extends Modes with Adaptations {
val funpt = if (isPatternMode) pt else WildcardType
val appStart = startTimer(failedApplyNanos)
val opeqStart = startTimer(failedOpEqNanos)
-
- def onError(reportError: => Tree): Tree = {
- fun match {
- case Select(qual, name)
- if !isPatternMode && nme.isOpAssignmentName(name.decode) =>
- val qual1 = typedQualifier(qual)
- if (treeInfo.isVariableOrGetter(qual1)) {
- stopTimer(failedOpEqNanos, opeqStart)
- convertToAssignment(fun, qual1, name, args)
- } else {
- stopTimer(failedApplyNanos, appStart)
- if ((qual1.symbol ne null) && qual1.symbol.isValue)
- AssignmentTypedApplyError(tree)
- else
- reportError
- }
- case _ =>
- stopTimer(failedApplyNanos, appStart)
- reportError
- }
- }
-
silent(_.typed(fun, forFunMode(mode), funpt),
if ((mode & EXPRmode) != 0) false else context.reportAmbiguousErrors,
if ((mode & EXPRmode) != 0) tree else context.tree) match {
- case fun1: Tree if !fun1.containsErrorOrIsErrorTyped() =>
+ case fun1: Tree =>
val fun2 = if (stableApplication) stabilizeFun(fun1, mode, pt) else fun1
incCounter(typedApplyCount)
def isImplicitMethod(tpe: Type) = tpe match {
@@ -3687,29 +3460,39 @@ trait Typers extends Modes with Adaptations {
//if (fun2.hasSymbol && fun2.symbol.name == nme.apply && fun2.symbol.owner == ArrayClass) {
// But this causes cyclic reference for Array class in Cleanup. It is easy to overcome this
// by calling ArrayClass.info here (or some other place before specialize).
- if (fun2.symbol == Array_apply && !res.containsError()) {
+ if (fun2.symbol == Array_apply) {
val checked = gen.mkCheckInit(res)
// this check is needed to avoid infinite recursion in Duplicators
// (calling typed1 more than once for the same tree)
if (checked ne res) typed { atPos(tree.pos)(checked) }
else res
} else res
-
- case eTree: Tree =>
- if (settings.errortrees.value)
- println("[ErrorTree silent] Encounter error in silent typing of apply")
-
- onError(if (eTree.containsError()) {val ex = quickErrorTreeFinder(eTree); if (ex.exception == null) ex else TypedApplyError(fun, ex.exception)} else eTree)
-
case ex: TypeError =>
- onError(TypedApplyError(fun, ex))
-
-
+ fun match {
+ case Select(qual, name)
+ if !isPatternMode && nme.isOpAssignmentName(name.decode) =>
+ val qual1 = typedQualifier(qual)
+ if (treeInfo.isVariableOrGetter(qual1)) {
+ stopTimer(failedOpEqNanos, opeqStart)
+ convertToAssignment(fun, qual1, name, args, ex)
+ } else {
+ stopTimer(failedApplyNanos, appStart)
+ if ((qual1.symbol ne null) && qual1.symbol.isValue)
+ error(tree.pos, "reassignment to val")
+ else
+ reportTypeError(fun.pos, ex)
+ setError(tree)
+ }
+ case _ =>
+ stopTimer(failedApplyNanos, appStart)
+ reportTypeError(fun.pos, ex)
+ setError(tree)
+ }
}
}
}
- def convertToAssignment(fun: Tree, qual: Tree, name: Name, args: List[Tree]): Tree = {
+ def convertToAssignment(fun: Tree, qual: Tree, name: Name, args: List[Tree], ex: TypeError): Tree = {
val prefix = name.subName(0, name.length - nme.EQL.length)
def mkAssign(vble: Tree): Tree =
Assign(
@@ -3750,11 +3533,10 @@ trait Typers extends Modes with Adaptations {
case Apply(fn, indices) =>
treeInfo.methPart(fn) match {
case Select(table, nme.apply) => mkUpdate(table, indices)
- case _ => UnexpectedTreeAssignmentConversionError(qual)
+ case _ => errorTree(qual, "Unexpected tree during assignment conversion.")
}
}
typed1(tree1, mode, pt)
-
/*
debuglog("retry assign: "+tree1)
silent(_.typed1(tree1, mode, pt)) match {
@@ -3767,8 +3549,8 @@ trait Typers extends Modes with Adaptations {
*/
}
- def qualifyingClassSym(qual: Name): Either[ErrorTree, Symbol] =
- if (tree.symbol != NoSymbol) Right(tree.symbol) else qualifyingClass(tree, qual, false)
+ def qualifyingClassSym(qual: Name): Symbol =
+ if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(tree, qual, false)
def typedSuper(qual: Tree, mix: TypeName) = {
val qual1 = typed(qual)
@@ -3779,7 +3561,7 @@ trait Typers extends Modes with Adaptations {
}
//println(clazz+"/"+qual1.tpe.typeSymbol+"/"+qual1)
- def findMixinSuper(site: Type): Either[ErrorTree, Type] = {
+ def findMixinSuper(site: Type): Type = {
var ps = site.parents filter (_.typeSymbol.name == mix)
if (ps.isEmpty)
ps = site.parents filter (_.typeSymbol.toInterface.name == mix)
@@ -3794,48 +3576,35 @@ trait Typers extends Modes with Adaptations {
// println(mix)
// the reference to super class got lost during erasure
restrictionError(tree.pos, unit, "traits may not select fields or methods from super[C] where C is a class")
- Left(NullErrorTree)
} else {
- Left(MixinMissingParentClassNameError(tree, mix, clazz))
+ error(tree.pos, mix+" does not name a parent class of "+clazz)
}
+ ErrorType
} else if (!ps.tail.isEmpty) {
- Left(AmbiguousParentClassError(tree))
+ error(tree.pos, "ambiguous parent class qualifier")
+ ErrorType
} else {
- Right(ps.head)
+ ps.head
}
}
val owntype =
if (mix.isEmpty) {
if ((mode & SUPERCONSTRmode) != 0)
- if (clazz.info.parents.isEmpty) Right(AnyRefClass.tpe) // can happen due to cyclic references ==> #1036
- else Right(clazz.info.parents.head)
- else Right(intersectionType(clazz.info.parents))
+ if (clazz.info.parents.isEmpty) AnyRefClass.tpe // can happen due to cyclic references ==> #1036
+ else clazz.info.parents.head
+ else intersectionType(clazz.info.parents)
} else {
findMixinSuper(clazz.tpe)
}
- val owntype1 = if (owntype.isLeft) {
- // Is there any way we can push the error tree into super?
- // Report here for the moment
- try {
- owntype.left.get.emit(context)
- } catch {
- case _: TypeError =>
- assert(false, "Invalid type error when typing Super")
- }
- ErrorType
- } else owntype.right.get
-
- treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype1)
+ treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
}
def typedThis(qual: Name) = {
- val clazzOrError = qualifyingClassSym(qual)
- if (clazzOrError.isLeft) clazzOrError.left.get
- else if (clazzOrError.right.get == NoSymbol) setError(tree)
+ val clazz = qualifyingClassSym(qual)
+ if (clazz == NoSymbol) setError(tree)
else {
- val clazz = clazzOrError.right.get
tree setSymbol clazz setType clazz.thisType.underlying
if (isStableContext(tree, mode, pt)) tree setType clazz.thisType
tree
@@ -3869,14 +3638,9 @@ trait Typers extends Modes with Adaptations {
}
if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & EXPRmode) != 0) {
val qual1 =
- if (member(qual, name) != NoSymbol) NullErrorTree
+ if (member(qual, name) != NoSymbol) qual
else adaptToMemberWithArgs(tree, qual, name, mode)
- if (!qual1.containsError()) {
- if (qual1 ne qual)
- return typed(treeCopy.Select(tree, qual1, name), mode, pt)
- } else {
- return qual1
- }
+ if (qual1 ne qual) return typed(treeCopy.Select(tree, qual1, name), mode, pt)
}
if (!reallyExists(sym)) {
@@ -3907,7 +3671,7 @@ trait Typers extends Modes with Adaptations {
)
}
- def makeInteractiveErrorTree = {
+ def makeErrorTree = {
val tree1 = tree match {
case Select(_, _) => treeCopy.Select(tree, qual, name)
case SelectFromTypeTree(_, _) => treeCopy.SelectFromTypeTree(tree, qual, name)
@@ -3915,15 +3679,16 @@ trait Typers extends Modes with Adaptations {
setError(tree1)
}
+ if (name == nme.ERROR && forInteractive)
+ return makeErrorTree
- if (forInteractive)
- makeInteractiveErrorTree
- else if (!qual.tpe.widen.isErroneous) {
+ if (!qual.tpe.widen.isErroneous) {
val lastTry = missingHook(qual.tpe.typeSymbol, name)
if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt)
- NotAMemberError(tree, qual, name)
- } else
- NotAMemberErroneous(tree)
+ notAMemberError(tree.pos, qual, name)
+ }
+
+ if (forInteractive) makeErrorTree else setError(tree)
} else {
val tree1 = tree match {
case Select(_, _) => treeCopy.Select(tree, qual, name)
@@ -3949,32 +3714,16 @@ trait Typers extends Modes with Adaptations {
result,
(TypeTreeWithDeferredRefCheck(){ () => val tp = qual.tpe; val sym = tp.typeSymbolDirect
// will execute during refchecks -- TODO: make private checkTypeRef in refchecks public and call that one?
- checkBounds(qual.pos, tp.prefix, sym.owner, sym.typeParams, tp.typeArgs, "") match {
- case Some(err) => Left(err)
- case _ => Right(qual) // you only get to see the wrapped tree after running this check :-p
- }
+ checkBounds(qual.pos, tp.prefix, sym.owner, sym.typeParams, tp.typeArgs, "")
+ qual // you only get to see the wrapped tree after running this check :-p
}) setType qual.tpe,
name)
- case tt if tt.containsError() =>
- val errTree = quickErrorTreeFinder(tt)
- errTree match {
- case accError: AccessError =>
- val qual1 =
- try adaptToMemberWithArgs(tree, qual, name, mode)
- catch {
- case _: TypeError =>
- // Ambigues implicits throw TypeError
- // and then they are reported here.
- NullErrorTree
- }
- if (!qual1.containsError() && (qual1 ne qual)) {
- typed(Select(qual1, name) setPos tree.pos, mode, pt)
- } else {
- accError
- }
- case _ =>
- tt
- }
+ case accErr: Inferencer#AccessError =>
+ val qual1 =
+ try adaptToMemberWithArgs(tree, qual, name, mode)
+ catch { case _: TypeError => qual }
+ if (qual1 ne qual) typed(Select(qual1, name) setPos tree.pos, mode, pt)
+ else accErr.emit()
case _ =>
result
}
@@ -3982,8 +3731,7 @@ trait Typers extends Modes with Adaptations {
// getClass, we have to catch it immediately so expressions
// like x.getClass().newInstance() are typed with the type of x.
val isRefinableGetClass = (
- !selection.containsError()
- && selection.symbol.name == nme.getClass_
+ selection.symbol.name == nme.getClass_
&& selection.tpe.params.isEmpty
// TODO: If the type of the qualifier is inaccessible, we can cause private types
// to escape scope here, e.g. pos/t1107. I'm not sure how to properly handle this
@@ -3991,7 +3739,7 @@ trait Typers extends Modes with Adaptations {
&& qual.tpe.typeSymbol.isPublic
)
if (isRefinableGetClass)
- selection setType MethodType(Nil, erasure.getClassReturnType(qual.tpe))
+ selection setType MethodType(Nil, erasure.getClassReturnType(qual.tpe))
else
selection
}
@@ -4005,17 +3753,8 @@ trait Typers extends Modes with Adaptations {
* (2) Change imported symbols to selections
*/
def typedIdent(name: Name): Tree = {
- var errorContainer: Tree = null
- @inline
- def ambiguousError(msg: String) = {
- assert(errorContainer == null, "Cannot set ambiguous error twice for identifier")
- errorContainer = AmbiguousIdentError(tree, name, msg)
- }
- @inline
- def identError(tree: ErrorTree) = {
- assert(errorContainer == null, "Cannot set ambiguous error twice for identifier")
- errorContainer = tree
- }
+ def ambiguousError(msg: String) =
+ error(tree.pos, "reference to " + name + " is ambiguous;\n" + msg)
var defSym: Symbol = tree.symbol // the directly found symbol
var pre: Type = NoPrefix // the prefix type of defSym, if a class member
@@ -4117,7 +3856,7 @@ trait Typers extends Modes with Adaptations {
ambiguousError(
"it is imported twice in the same scope by\n"+imports.head + "\nand "+imports1.head)
}
- while (errorContainer == null && !imports1.isEmpty &&
+ while (!imports1.isEmpty &&
(!imports.head.isExplicitImport(name) ||
imports1.head.depth == imports.head.depth)) {
var impSym1 = imports1.head.importedSymbol(name)
@@ -4132,17 +3871,11 @@ trait Typers extends Modes with Adaptations {
}
imports1 = imports1.tail
}
- if (errorContainer == null) {
- if (imports.head.qual.containsError()) {
- defSym = context.owner.newErrorSymbol(name)
- } else {
- defSym = impSym
- val qual0 = imports.head.qual
- if (!(shortenImports && qual0.symbol.isPackage)) // optimization: don't write out package prefixes
- qual = atPos(tree.pos.focusStart)(resetPos(qual0.duplicate))
- pre = qual.tpe
- }
- }
+ defSym = impSym
+ val qual0 = imports.head.qual
+ if (!(shortenImports && qual0.symbol.isPackage)) // optimization: don't write out package prefixes
+ qual = atPos(tree.pos.focusStart)(resetPos(qual0.duplicate))
+ pre = qual.tpe
}
else if (settings.exposeEmptyPackage.value && checkEmptyPackage())
log("Allowing empty package member " + name + " due to settings.")
@@ -4156,53 +3889,50 @@ trait Typers extends Modes with Adaptations {
if (inaccessibleSym eq NoSymbol) {
// Avoiding some spurious error messages: see SI-2388.
if (reporter.hasErrors && (name startsWith tpnme.ANON_CLASS_NAME)) ()
- else identError(SymbolNotFound(tree, name, context.owner))
- } else {
- identError(AccessError(
- tree, inaccessibleSym, context.enclClass.owner.thisType, context.enclClass.owner,
- inaccessibleExplanation
- ))
+ else error(tree.pos, "not found: "+decodeWithKind(name, context.owner))
}
+ else new AccessError(
+ tree, inaccessibleSym, context.enclClass.owner.thisType,
+ inaccessibleExplanation
+ ).emit()
defSym = context.owner.newErrorSymbol(name)
}
}
}
-
- if (errorContainer != null) {
- errorContainer
+ if (defSym.owner.isPackageClass) pre = defSym.owner.thisType
+ if (defSym.isThisSym) {
+ typed1(This(defSym.owner) setPos tree.pos, mode, pt)
} else {
- if (defSym.owner.isPackageClass) pre = defSym.owner.thisType
- if (defSym.isThisSym) {
- typed1(This(defSym.owner) setPos tree.pos, mode, pt)
- } else {
- val tree1 = if (qual == EmptyTree) tree
- else atPos(tree.pos)(Select(qual, name))
- // atPos necessary because qualifier might come from startContext
- val (tree2, pre2) = makeAccessible(tree1, defSym, pre, qual)
- // assert(pre.typeArgs isEmpty) // no need to add #2416-style check here, right?
- stabilize(tree2, pre2, mode, pt)
+ val tree1 = if (qual == EmptyTree) tree
+ else atPos(tree.pos)(Select(qual, name))
+ // atPos necessary because qualifier might come from startContext
+ val (tree2, pre2) = makeAccessible(tree1, defSym, pre, qual)
+ // assert(pre.typeArgs isEmpty) // no need to add #2416-style check here, right?
+ stabilize(tree2, pre2, mode, pt) match {
+ case accErr: Inferencer#AccessError => accErr.emit()
+ case result => result
}
}
}
def typedCompoundTypeTree(templ: Template) = {
val parents1 = templ.parents mapConserve (typedType(_, mode))
- if (parents1 exists (_.containsErrorOrIsErrorTyped())) tree setType ErrorType
+ if (parents1 exists (_.tpe.isError)) tree setType ErrorType
else {
val decls = new Scope
//Console.println("Owner: " + context.enclClass.owner + " " + context.enclClass.owner.id)
val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls, templ.pos)
newTyper(context.make(templ, self.typeSymbol, decls)).typedRefinement(templ.body)
- tree.setType(self)
+ tree setType self
}
}
def typedAppliedTypeTree(tpt: Tree, args: List[Tree]) = {
val tpt1 = typed1(tpt, mode | FUNmode | TAPPmode, WildcardType)
- if (tpt1.containsErrorOrIsErrorTyped()) {
- setError(treeCopy.AppliedTypeTree(tree, tpt1, args))
+ if (tpt1.tpe.isError) {
+ setError(tree)
} else if (!tpt1.hasSymbol) {
- AppliedTypeNoParametersError(tree, tpt1.tpe)
+ errorTree(tree, tpt1.tpe+" does not take type parameters")
} else {
val tparams = tpt1.symbol.typeParams
if (sameLength(tparams, args)) {
@@ -4235,18 +3965,16 @@ trait Typers extends Modes with Adaptations {
// wrap the tree and include the bounds check -- refchecks will perform this check (that the beta reduction was indeed allowed) and unwrap
// we can't simply use original in refchecks because it does not contains types
// (and the only typed trees we have have been mangled so they're not quite the original tree anymore)
- checkBounds(result.pos, tpt1.tpe.prefix, tpt1.symbol.owner, tpt1.symbol.typeParams, argtypes, "") match {
- case Some(err) => Left(err)
- case _ => Right(result) // you only get to see the wrapped tree after running this check :-p
- }
+ checkBounds(result.pos, tpt1.tpe.prefix, tpt1.symbol.owner, tpt1.symbol.typeParams, argtypes, "")
+ result // you only get to see the wrapped tree after running this check :-p
}).setType(result.tpe)
else result
} else if (tparams.isEmpty) {
- AppliedTypeNoParametersError(tree, tpt1.tpe)
+ errorTree(tree, tpt1.tpe+" does not take type parameters")
} else {
//Console.println("\{tpt1}:\{tpt1.symbol}:\{tpt1.symbol.info}")
if (settings.debug.value) Console.println(tpt1+":"+tpt1.symbol+":"+tpt1.symbol.info)//debug
- AppliedTypeWrongNumberOfArgsError(tree, "wrong number of type arguments for "+tpt1.tpe+", should be "+tparams.length)
+ errorTree(tree, "wrong number of type arguments for "+tpt1.tpe+", should be "+tparams.length)
}
}
}
@@ -4260,12 +3988,7 @@ trait Typers extends Modes with Adaptations {
//if (settings.debug.value && tree.isDef) log("typing definition of "+sym);//DEBUG
tree match {
case PackageDef(pid, stats) =>
- val pid1 = typedQualifier(pid) match {
- case e: ErrorTree =>
- RefTreeError(e, pid.name)
- case t: RefTree =>
- t
- }
+ val pid1 = typedQualifier(pid).asInstanceOf[RefTree]
assert(sym.moduleClass ne NoSymbol, sym)
// complete lazy annotations
val annots = sym.annotations
@@ -4300,9 +4023,6 @@ trait Typers extends Modes with Adaptations {
typer1.silent(_.typedUseCase(useCase)) match {
case ex: TypeError =>
unit.warning(useCase.pos, ex.msg)
- case tree: Tree if tree.containsError() =>
- val ex = quickErrorTreeFinder(tree)
- unit.warning(useCase.pos, ex.exception.msg)
case _ =>
}
for (useCaseSym <- useCase.defined) {
@@ -4325,14 +4045,9 @@ trait Typers extends Modes with Adaptations {
treeCopy.Alternative(tree, alts1) setType pt
case Star(elem) =>
- val err0 = checkStarPatOK(tree.pos, mode)
+ checkStarPatOK(tree.pos, mode)
val elem1 = typed(elem, mode, pt)
- val elem2 = err0 match {
- case Some(err) =>
- wrapInBlock(err, elem1)
- case _ => elem1
- }
- treeCopy.Star(tree, elem2) setType makeFullyDefined(pt)
+ treeCopy.Star(tree, elem1) setType makeFullyDefined(pt)
case Bind(name, body) =>
typedBind(name, body)
@@ -4416,32 +4131,25 @@ trait Typers extends Modes with Adaptations {
val tparam = context.owner freshExistential "" setInfo TypeBounds.upper(pt)
ExistentialType(List(tparam), arrayType(tparam.tpe))
}
-
- if (expr0.containsError())
- treeCopy.Typed(tree, expr0, tpt setType ErrorType) setType ErrorType
- else {
- val (expr1, baseClass) = expr0.tpe.typeSymbol match {
- case ArrayClass => (adapt(expr0, onlyStickyModes(mode), subArrayType(pt)), ArrayClass)
- case _ => (adapt(expr0, onlyStickyModes(mode), seqType(pt)), SeqClass)
- }
- expr1.tpe.baseType(baseClass) match {
- case TypeRef(_, _, List(elemtp)) =>
- treeCopy.Typed(tree, expr1, tpt setType elemtp) setType elemtp
- case _ =>
- setError(tree)
- }
+ val (expr1, baseClass) = expr0.tpe.typeSymbol match {
+ case ArrayClass => (adapt(expr0, onlyStickyModes(mode), subArrayType(pt)), ArrayClass)
+ case _ => (adapt(expr0, onlyStickyModes(mode), seqType(pt)), SeqClass)
+ }
+ expr1.tpe.baseType(baseClass) match {
+ case TypeRef(_, _, List(elemtp)) =>
+ treeCopy.Typed(tree, expr1, tpt setType elemtp) setType elemtp
+ case _ =>
+ setError(tree)
}
case Typed(expr, tpt) =>
val tpt1 = typedType(tpt, mode)
val expr1 = typed(expr, onlyStickyModes(mode), tpt1.tpe.deconst)
- val (expr2, ownType) = if (isPatternMode)
- inferTypedPattern(tpt1.pos, tpt1.tpe, pt) match {
- case Left(err) =>
- (wrapInBlock(expr1, err), ErrorType)
- case Right(tp) => (expr1, tp)
- } else (expr1, tpt1.tpe)
- treeCopy.Typed(tree, expr1, tpt1) setType ownType
+ val owntype =
+ if (isPatternMode) inferTypedPattern(tpt1.pos, tpt1.tpe, pt)
+ else tpt1.tpe
+ //Console.println(typed pattern: "+tree+":"+", tp = "+tpt1.tpe+", pt = "+pt+" ==> "+owntype)//DEBUG
+ treeCopy.Typed(tree, expr1, tpt1) setType owntype
case TypeApply(fun, args) =>
// @M: kind-arity checking is done here and in adapt, full kind-checking is in checkKindBounds (in Infer)
@@ -4484,8 +4192,6 @@ trait Typers extends Modes with Adaptations {
case Apply(fun, args) =>
typedApply(fun, args) match {
- case tree1 if tree1.containsError() =>
- tree1
case Apply(Select(New(tpt), name), args)
if (tpt.tpe != null &&
tpt.tpe.typeSymbol == ArrayClass &&
@@ -4495,14 +4201,12 @@ trait Typers extends Modes with Adaptations {
// convert new Array^N[T](len) for N > 1 to evidence[ClassManifest[T]].newArrayN(len)
val Some((level, manifType)) = erasure.GenericArray.unapply(tpt.tpe)
if (level > MaxArrayDims)
- MultiDimensionalArrayError(tree)
- else {
- val newArrayApp = atPos(tree.pos) {
- val manif = getManifestTree(tree.pos, manifType, false)
- new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args)
- }
- typed(newArrayApp, mode, pt)
+ error(tree.pos, "cannot create a generic multi-dimensional array of more than "+MaxArrayDims+" dimensions")
+ val newArrayApp = atPos(tree.pos) {
+ val manif = getManifestTree(tree.pos, manifType, false)
+ new ApplyToImplicitArgs(Select(manif, if (level == 1) "newArray" else "newArray"+level), args)
}
+ typed(newArrayApp, mode, pt)
case tree1 =>
tree1
}
@@ -4531,26 +4235,20 @@ trait Typers extends Modes with Adaptations {
if (name.isTypeName) qual1 = checkStable(qual1)
val tree1 = // temporarily use `filter` and an alternative for `withFilter`
- if (qual1.containsError())
- treeCopy.Select(tree, qual1, name) setType ErrorType
- else if (name == nme.withFilter)
+ if (name == nme.withFilter)
silent(_ => typedSelect(qual1, name)) match {
- case result1: Tree if !result1.containsError() =>
+ case result1: Tree =>
result1
- case ex1 =>
+ case ex1: TypeError =>
silent(_ => typed1(Select(qual1, nme.filter) setPos tree.pos, mode, pt)) match {
case result2: Tree =>
unit.deprecationWarning(
tree.pos, "`withFilter' method does not yet exist on "+qual1.tpe.widen+
", using `filter' method instead")
result2
- case _: TypeError =>
- val ex2 = ex1 match {
- case te: TypeError => te
- case t: Tree =>
- quickErrorTreeFinder(t).exception
- }
- WithFilterError(tree, ex2)
+ case ex2: TypeError =>
+ reportTypeError(tree.pos, ex1)
+ setError(tree)
}
}
else
@@ -4575,17 +4273,12 @@ trait Typers extends Modes with Adaptations {
case SingletonTypeTree(ref) =>
val ref1 = checkStable(
typed(ref, EXPRmode | QUALmode | (mode & TYPEPATmode), AnyRefClass.tpe))
- if (ref1.containsError())
- treeCopy.SingletonTypeTree(tree, ref1) setType ErrorType
- else
- tree setType ref1.tpe.resultType
+ tree setType ref1.tpe.resultType
case SelectFromTypeTree(qual, selector) =>
val qual1 = typedType(qual, mode)
- if (qual1.tpe.isVolatile)
- TypeSelectionFromVolatileTypeError(tree, qual)
- else
- typedSelect(qual1, selector)
+ if (qual1.tpe.isVolatile) error(tree.pos, "illegal type selection from volatile type "+qual.tpe)
+ typedSelect(qual1, selector)
case CompoundTypeTree(templ) =>
typedCompoundTypeTree(templ)
@@ -4618,39 +4311,6 @@ trait Typers extends Modes with Adaptations {
}
}
- def handleErrorTree(t: Tree) {
- val allErrors = errorTreesFinder(t)
-
- // Report any errors if possible in the current context
- // If an error tree throws type error (we are in silent mode), then we will not mark
- // tree as visited and it will be reported later if necessary
- allErrors.foreach { t0 =>
- try {
- if (settings.errortrees.value) {
- println("[ErrorTree emit] " + t0)
- if (t0.exception != null) {
- println(t0.exception.getClass)
- }
- }
- t0.emit(context)
- t0.reported = true
- } catch {
- case te: TypeError =>
- // Catch all type errors if we are in typer phase.
- // All typer errors will be reported at some point anyway.
- if (settings.errortrees.value)
- println("[ErrorTree TypeError] Throws " + te)
-
- // After typer all bets are off
- // and we do not try to hide TypeError within error tree
- if (phase.id > currentRun.typerPhase.id) {
- t0.reported = true
- throw te
- }
- }
- }
- }
-
/**
* @param tree ...
* @param mode ...
@@ -4694,36 +4354,22 @@ trait Typers extends Modes with Adaptations {
tree1
}
- if (tree1.containsError()) {
- handleErrorTree(tree1)
- if (phase.id <= currentRun.typerPhase.id) signalDone(context.asInstanceOf[analyzer.Context], tree, tree1)
- tree1
- } else {
- tree1.tpe = addAnnotations(tree1, tree1.tpe)
- val result = if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, tree)
+ tree1.tpe = addAnnotations(tree1, tree1.tpe)
+ val result = if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, tree)
- if (!alreadyTyped) {
- printTyping("adapted %s: %s to %s, %s".format(
- tree1, tree1.tpe.widen, pt, context.undetparamsString)
- ) //DEBUG
- }
- if (phase.id <= currentRun.typerPhase.id) signalDone(context.asInstanceOf[analyzer.Context], tree, result)
- if (result.containsError()) handleErrorTree(result)
- result
+ if (!alreadyTyped) {
+ printTyping("adapted %s: %s to %s, %s".format(
+ tree1, tree1.tpe.widen, pt, context.undetparamsString)
+ ) //DEBUG
}
+
+// for (t <- tree1.tpe) assert(t != WildcardType)
+// if ((mode & TYPEmode) != 0) println("type: "+tree1+" has type "+tree1.tpe)
+ if (phase.id <= currentRun.typerPhase.id) signalDone(context.asInstanceOf[analyzer.Context], tree, result)
+ result
} catch {
case ex: TypeError =>
tree.tpe = null
- // At some point we might want to get rid of the code below
- // because everything will be handled by error trees.
- // The only problematic case are Cyclic errors which can pop up almost anywhere
- if (settings.errortrees.value) {
- println("[ErrorTree CAUGHT] %s: while typing %s".format(ex, tree))
- println("TODO with error trees shouldn't throw non-cyclic errors")
- ex.printStackTrace()
- println("----------")
- }
-
printTyping("caught %s: while typing %s".format(ex, tree)) //DEBUG
reportTypeError(tree.pos, ex)
setError(tree)
@@ -4827,12 +4473,12 @@ trait Typers extends Modes with Adaptations {
// to see are those in the signatures. These do not need a unique object as a prefix.
// The situation is different for new's and super's, but scalac does not look deep
// enough to see those. See #3938
- return ConstructorPrefixError(tree, restpe)
+ error(tree.pos, restpe.prefix+" is not a legal prefix for a constructor")
}
//@M fix for #2208
// if there are no type arguments, normalization does not bypass any checks, so perform it to get rid of AnyRef
- if (result.tpe.typeArgs.isEmpty && !result.containsError()) {
+ if(result.tpe.typeArgs.isEmpty) {
// minimal check: if(result.tpe.typeSymbolDirect eq AnyRefClass) {
// must expand the fake AnyRef type alias, because bootstrapping (init in Definitions) is not
// designed to deal with the cycles in the scala package (ScalaObject extends
@@ -4848,23 +4494,10 @@ trait Typers extends Modes with Adaptations {
def typedTypeConstructor(tree: Tree): Tree = typedTypeConstructor(tree, NOmode)
- // Because this is called from Namers and pattern matcher, we
- // have to report missing errors (if any)
def computeType(tree: Tree, pt: Type): Type = {
val tree1 = typed(tree, pt)
- if (tree1.containsError())
- ErrorType
- else {
- transformed(tree) = tree1
- val (tpe, errs) = packedType(tree1, context.owner)
- try {
- errs.foreach(_.emit(context))
- tpe
- } catch {
- case _: TypeError =>
- ErrorType
- }
- }
+ transformed(tree) = tree1
+ packedType(tree1, context.owner)
}
def transformedOrTyped(tree: Tree, mode: Int, pt: Type): Tree = transformed.get(tree) match {
@@ -4882,7 +4515,8 @@ trait Typers extends Modes with Adaptations {
def getManifestTree(pos: Position, tp: Type, full: Boolean): Tree = {
val manifestOpt = findManifest(tp, full)
if (manifestOpt.tree.isEmpty) {
- MissingManifestError(pos, full, tp)
+ error(pos, "cannot find "+(if (full) "" else "class ")+"manifest for element type "+tp)
+ Literal(Constant(null))
} else {
manifestOpt.tree
}