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.scala125
1 files changed, 46 insertions, 79 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ed7c1dec15..b6271b8ef1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -161,7 +161,7 @@ trait Typers { self: Analyzer =>
else mode
}
- abstract class Typer(context0: Context) {
+ abstract class Typer(context0: Context) extends TyperDiagnostics {
import context0.unit
val infer = new Inferencer(context0) {
@@ -252,35 +252,6 @@ trait Typers { self: Analyzer =>
private[typechecker] var context = context0
def context1 = context
- /** Report a type error.
- *
- * @param pos0 The position where to report the error
- * @param ex The exception that caused the error
- */
- def reportTypeError(pos: Position, ex: TypeError) {
- if (ex.pos == NoPosition) ex.pos = pos
- if (!context.reportGeneralErrors) throw ex
- if (settings.debug.value) ex.printStackTrace()
- ex match {
- case CyclicReference(sym, info: TypeCompleter) =>
- val msg =
- info.tree match {
- case ValDef(_, _, tpt, _) if (tpt.tpe eq null) =>
- "recursive "+sym+" needs type"
- case DefDef(_, _, _, _, tpt, _) if (tpt.tpe eq null) =>
- (if (sym.owner.isClass && sym.owner.info.member(sym.name).hasFlag(OVERLOADED)) "overloaded "
- else "recursive ")+sym+" needs result type"
- case _ =>
- ex.getMessage()
- }
- context.error(ex.pos, msg)
- if (sym == ObjectClass)
- throw new FatalError("cannot redefine root "+sym)
- case _ =>
- context.error(ex.pos, ex)
- }
- }
-
/** Check that <code>tree</code> is a stable expression.
*
* @param tree ...
@@ -2936,6 +2907,8 @@ trait Typers { self: Analyzer =>
* @return ...
*/
protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
+ def isPatternMode = (mode & PATTERNmode) != 0
+
//Console.println("typed1("+tree.getClass()+","+Integer.toHexString(mode)+","+pt+")")
def ptOrLub(tps: List[Type]) = if (isFullyDefined(pt)) (pt, false) else weakLub(tps map (_.deconst))
@@ -3056,32 +3029,36 @@ trait Typers { self: Analyzer =>
}
def typedAssign(lhs: Tree, rhs: Tree): Tree = {
- val lhs1 = typed(lhs, EXPRmode | LHSmode, WildcardType)
- val varsym = lhs1.symbol
- if ((varsym ne null) && treeInfo.mayBeVarGetter(varsym))
+ 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.tpe.isError)
+ error(tree.pos, failMsg)
+
+ setError(tree)
+ }
+ if (varsym == null)
+ return fail
+
+ if (treeInfo.mayBeVarGetter(varsym)) {
lhs1 match {
case Select(qual, name) =>
- return typed(
- Apply(
- Select(qual, nme.getterToSetter(name)) setPos lhs.pos,
- List(rhs)) setPos tree.pos,
- mode, pt)
+ val sel = Select(qual, nme.getterToSetter(name)) setPos lhs.pos
+ val app = Apply(sel, List(rhs)) setPos tree.pos
+ return typed(app, mode, pt)
case _ =>
-
}
- if ((varsym ne null) && (varsym.isVariable || varsym.isValue && phase.erasedTypes)) {
+ }
+ if (varsym.isVariable || varsym.isValue && phase.erasedTypes) {
val rhs1 = typed(rhs, EXPRmode | BYVALmode, lhs1.tpe)
treeCopy.Assign(tree, lhs1, checkDead(rhs1)) setType UnitClass.tpe
- } else {
- if (!lhs1.tpe.isError) {
- //println(lhs1+" = "+rhs+" "+varsym+" "+mayBeVarGetter(varsym)+" "+varsym.ownerChain+" "+varsym.info)// DEBUG
- error(tree.pos,
- if ((varsym ne null) && varsym.isValue) "reassignment to val"
- else "assignment to non variable")
- }
- setError(tree)
}
+ else fail
}
def typedIf(cond: Tree, thenp: Tree, elsep: Tree) = {
@@ -3227,19 +3204,19 @@ trait Typers { self: Analyzer =>
t
case ex: TypeError =>
stopTimer(failedApplyNanos, start)
- def errorInResult(tree: Tree): Boolean = tree.pos == ex.pos || {
- tree match {
- case Block(_, r) => errorInResult(r)
- case Match(_, cases) => cases exists errorInResult
- case CaseDef(_, _, r) => errorInResult(r)
- case Annotated(_, r) => errorInResult(r)
- case If(_, t, e) => errorInResult(t) || errorInResult(e)
- case Try(b, catches, _) => errorInResult(b) || (catches exists errorInResult)
- case Typed(r, Function(List(), EmptyTree)) => errorInResult(r)
- case _ => false
- }
- }
- if (errorInResult(fun) || (args exists errorInResult) || errorInResult(tree)) {
+ def treesInResult(tree: Tree): List[Tree] = tree :: (tree match {
+ case Block(_, r) => treesInResult(r)
+ case Match(_, cases) => cases
+ case CaseDef(_, _, r) => treesInResult(r)
+ case Annotated(_, r) => treesInResult(r)
+ case If(_, t, e) => treesInResult(t) ++ treesInResult(e)
+ case Try(b, catches, _) => treesInResult(b) ++ catches
+ case Typed(r, Function(Nil, EmptyTree)) => treesInResult(r)
+ case _ => Nil
+ })
+ def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == ex.pos)
+
+ if (fun :: tree :: args exists errorInResult) {
if (printTypings) println("second try for: "+fun+" and "+args)
val Select(qual, name) = fun
val args1 = tryTypedArgs(args, argMode(fun, mode), ex)
@@ -3260,11 +3237,11 @@ trait Typers { self: Analyzer =>
def typedApply(fun: Tree, args: List[Tree]) = {
val stableApplication = (fun.symbol ne null) && fun.symbol.isMethod && fun.symbol.isStable
- if (stableApplication && (mode & PATTERNmode) != 0) {
+ if (stableApplication && isPatternMode) {
// treat stable function applications f() as expressions.
typed1(tree, mode & ~PATTERNmode | EXPRmode, pt)
} else {
- val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType
+ val funpt = if (isPatternMode) pt else WildcardType
val appStart = startTimer(failedApplyNanos)
val opeqStart = startTimer(failedOpEqNanos)
silent(_.typed(fun, funMode(mode), funpt)) match {
@@ -3305,7 +3282,7 @@ trait Typers { self: Analyzer =>
case ex: TypeError =>
fun match {
case Select(qual, name)
- if (mode & PATTERNmode) == 0 && nme.isOpAssignmentName(name.decode) =>
+ if !isPatternMode && nme.isOpAssignmentName(name.decode) =>
val qual1 = typedQualifier(qual)
if (treeInfo.isVariableOrGetter(qual1)) {
stopTimer(failedOpEqNanos, opeqStart)
@@ -3482,19 +3459,9 @@ trait Typers { self: Analyzer =>
if (name == nme.ERROR && onlyPresentation)
return makeErrorTree
- if (!qual.tpe.widen.isErroneous) {
- error(tree.pos,
- if (name == nme.CONSTRUCTOR)
- qual.tpe.widen+" does not have a constructor"
- else
- decode(name)+" is not a member of "+
- (if (qual.tpe.typeSymbol.isTypeParameterOrSkolem) "type parameter " else "") +
- qual.tpe.widen +
- (if ((context.unit ne null) && // Martin: why is this condition needed?
- qual.pos.isDefined && tree.pos.isDefined && qual.pos.line < tree.pos.line)
- "\npossible cause: maybe a semicolon is missing before `"+decode(name)+"'?"
- else ""))
- }
+ if (!qual.tpe.widen.isErroneous)
+ notAMember(tree, qual, name)
+
if (onlyPresentation) makeErrorTree else setError(tree)
} else {
val tree1 = tree match {
@@ -3634,7 +3601,7 @@ trait Typers { self: Analyzer =>
if (settings.debug.value) {
log(context.imports)//debug
}
- error(tree.pos, "not found: "+decode(name))
+ error(tree.pos, "not found: "+decodeWithNamespace(name))
defSym = context.owner.newErrorSymbol(name)
}
}
@@ -3871,7 +3838,7 @@ trait Typers { self: Analyzer =>
val tpt1 = typedType(tpt, mode)
val expr1 = typed(expr, mode & stickyModes, tpt1.tpe.deconst)
val owntype =
- if ((mode & PATTERNmode) != 0) inferTypedPattern(tpt1.pos, tpt1.tpe, pt)
+ 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