summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala75
6 files changed, 85 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
index f8d213013d..4fc37dab5b 100644
--- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
+++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
@@ -121,7 +121,7 @@ with RightTracers {
_ : Literal => ; // no variables
case _ =>
- error("unknown pattern node:" + tree + " = " + tree.getClass());
+ cunit.error(tree.pos, "unknown pattern node:" + tree + " = " + tree.getClass());
}
}
traverse(pat);
@@ -243,7 +243,7 @@ with RightTracers {
//case _ =>
// Console.println(pat);
// Console.println(pat.getClass());
- // scala.Predef.error(" what is this ? ")
+ // scala.Predef.error"( what is this ? ")
}
var res:List[CaseDef] = Nil;
@@ -295,7 +295,8 @@ with RightTracers {
*/
System.out.println("" + sel + " match " + ocases);
- scala.Predef.error("regular expressions not yet implemented");
+ cunit.error(sel.pos, "regular expressions not yet implemented");
+ sel
} else {
val pm = new PatternMatcher();
pm.initialize(sel, currentOwner, true );
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 111ef5f6e5..2ba86159d8 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -964,7 +964,9 @@ trait Symbols requires SymbolTable {
override def cloneSymbolImpl(owner: Symbol): Symbol = {
throw new Error("should not clone a type skolem");
}
- override def nameString: String = super.nameString + "&";
+ override def nameString: String =
+ if (settings.debug.value) (super.nameString + "&")
+ else super.nameString;
}
/** A class for class symbols */
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index ea474a68bb..45367bf440 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -125,6 +125,14 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
} else
transformMixinInfo(erasure(tp));
+ val deconstMap = new TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case PolyType(_, _) => mapOver(tp)
+ case MethodType(_, _) => mapOver(tp)
+ case _ => tp.deconst
+ }
+ }
+
// -------- boxing/unboxing --------------------------------------------------------
override def newTyper(context: Context) = new Eraser(context);
@@ -477,6 +485,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
val otpe = erasure(other.tpe);
val bridgeNeeded = atPhase(phase.next) (
!(other.tpe =:= member.tpe) &&
+ !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) &&
{ var e = bridgesScope.lookupEntry(member.name);
while (e != null && !((e.sym.tpe =:= otpe) && (bridgeTarget(e.sym) == member)))
e = bridgesScope.lookupNextEntry(e);
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 0da9ee6177..d4833ba155 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -71,6 +71,7 @@ trait Contexts requires Analyzer {
// after the this constructor call?
var reportAmbiguousErrors = false;
var reportGeneralErrors = false;
+ var implicitsEnabled = false;
var checking = false;
var savedTypeBounds: List[Pair[Symbol, Type]] = List();
@@ -102,6 +103,7 @@ trait Contexts requires Analyzer {
c.imports = imports;
c.reportAmbiguousErrors = this.reportAmbiguousErrors;
c.reportGeneralErrors = this.reportGeneralErrors;
+ c.implicitsEnabled = this.implicitsEnabled;
c.checking = this.checking;
c.outer = this;
c
@@ -111,6 +113,7 @@ trait Contexts requires Analyzer {
val c = make(unit, EmptyTree, owner, scope, imports);
c.reportAmbiguousErrors = true;
c.reportGeneralErrors = true;
+ c.implicitsEnabled = true;
c
}
@@ -133,6 +136,7 @@ trait Contexts requires Analyzer {
val c = make(tree);
c.reportAmbiguousErrors = reportAmbiguousErrors;
c.reportGeneralErrors = false;
+ c.implicitsEnabled = false;
c
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 5df8be1170..9cabd952f0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -667,16 +667,20 @@ trait Infer requires Analyzer {
/** Try inference twice, once without views and once with views, unless views are already disabled.
*/
def tryTwice(infer: => unit): unit = {
- if (context.reportGeneralErrors) {
+ if (context.implicitsEnabled) {
+ val reportGeneralErrors = context.reportGeneralErrors;
context.reportGeneralErrors = false;
+ context.implicitsEnabled = false;
try {
infer
} catch {
case ex: TypeError =>
- context.reportGeneralErrors = true;
+ context.reportGeneralErrors = reportGeneralErrors;
+ context.implicitsEnabled = true;
infer
}
- context.reportGeneralErrors = true
+ context.reportGeneralErrors = reportGeneralErrors
+ context.implicitsEnabled = true
} else infer
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 63edcdb412..78197a0ab3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -22,6 +22,8 @@ trait Typers requires Analyzer {
var implcnt = 0
var impltime = 0l
+ final val xviews = false
+
private val transformed = new HashMap[Tree, Tree]
private val superDefs = new HashMap[Symbol, ListBuffer[Tree]]
@@ -40,7 +42,7 @@ trait Typers requires Analyzer {
val infer = new Inferencer(context0) {
override def isCoercible(tp: Type, pt: Type): boolean = (
tp.isError || pt.isError ||
- context0.reportGeneralErrors && // this condition prevents chains of views
+ context0.implicitsEnabled && // this condition prevents chains of views
inferView(Position.NOPOS, tp, pt, false) != EmptyTree
)
}
@@ -56,10 +58,10 @@ trait Typers requires Analyzer {
}
}
- private def inferView(pos: int, from: Type, name: Name, reportAmbiguous: boolean): Tree = {
+ private def inferView(pos: int, from: Type, name: Name, tp: Type, reportAmbiguous: boolean): Tree = {
val to = refinedType(List(WildcardType), NoSymbol)
val psym = (if (name.isTypeName) to.symbol.newAbstractType(pos, name)
- else to.symbol.newValue(pos, name)) setInfo WildcardType
+ else to.symbol.newValue(pos, name)) setInfo tp
to.decls.enter(psym)
inferView(pos, from, to, reportAmbiguous)
}
@@ -101,6 +103,10 @@ trait Typers requires Analyzer {
val SUPERCONSTRmode = 0x100; // Set for the `super' in a superclass constructor call
// super.<init>
+ val SNDTRYmode = 0x200; // indicates that an application is typed for the 2nd
+ // time. In that case functions may no longer be
+ // be coerced with implicit views.
+
private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode
/** Report a type error.
@@ -121,7 +127,7 @@ trait Typers requires Analyzer {
case _ =>
ex.getMessage()
}
- if (settings.debug.value) ex.printStackTrace()
+ //if (settings.debug.value) ex.printStackTrace()//DEBUG
if (context.reportGeneralErrors) error(pos, msg)
else throw new TypeError(msg)
}
@@ -369,7 +375,7 @@ trait Typers requires Analyzer {
} else if (!tree.symbol.isConstructor && mt.paramTypes.isEmpty) { // (4.3)
adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt)
} else {
- if (context.reportGeneralErrors) {
+ if (context.implicitsEnabled) {
if (settings.migrate.value && !tree.symbol.isConstructor && isCompatible(mt, pt))
error(tree.pos, migrateMsg + " method can be converted to function only if an expected function type is given");
else
@@ -451,7 +457,7 @@ trait Typers requires Analyzer {
return typed(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt)
case _ =>
}
- if (context.reportGeneralErrors && !tree.tpe.isError && !pt.isError) {
+ if (context.implicitsEnabled && !tree.tpe.isError && !pt.isError) {
// (13); the condition prevents chains of views
if (settings.debug.value) log("inferring view from "+tree.tpe+" to "+pt)
val coercion = inferView(tree.pos, tree.tpe, pt, true)
@@ -470,15 +476,19 @@ trait Typers requires Analyzer {
// adapt(tree, mode, pt)
// }
- def adaptToName(qual: Tree, name: Name): Tree =
+ def adaptToMember(qual: Tree, name: Name, tp: Type): Tree =
if (qual.isTerm && (qual.symbol == null || qual.symbol.isValue) &&
- !phase.erasedTypes && !qual.tpe.widen.isError &&
- qual.tpe.nonLocalMember(name) == NoSymbol) {
- val coercion = inferView(qual.pos, qual.tpe, name, true)
- if (coercion != EmptyTree) typedQualifier(atPos(qual.pos)(Apply(coercion, List(qual))))
+ !phase.erasedTypes && !qual.tpe.widen.isError) {
+ val coercion = inferView(qual.pos, qual.tpe, name, tp, true)
+ if (coercion != EmptyTree)
+ typedQualifier(atPos(qual.pos)(Apply(coercion, List(qual))))
else qual
} else qual
+ def adaptToName(qual: Tree, name: Name) =
+ if (qual.tpe.nonLocalMember(name) != NoSymbol) qual
+ else adaptToMember(qual, name, WildcardType)
+
private def completeParentType(tpt: Tree, tparams: List[Symbol], enclTparams: List[Symbol], vparamss: List[List[ValDef]], superargs: List[Tree]): Type = {
enclTparams foreach context.scope.enter
namer.enterValueParams(context.owner, vparamss)
@@ -980,10 +990,12 @@ trait Typers requires Analyzer {
argTyper.typed(arg, mode & stickyModes, pt)
}
+ def typedArgs(args: List[Tree]) =
+ List.mapConserve(args)(arg => typedArg(arg, WildcardType))
+
def typedApply(fun: Tree, args: List[Tree]): Tree = fun.tpe match {
case OverloadedType(pre, alts) =>
- val args1 = List.mapConserve(args)(arg =>
- typedArg(arg, WildcardType))
+ val args1 = typedArgs(args)
inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt)
typedApply(adapt(fun, funmode, WildcardType), args1)
case MethodType(formals0, restpe) =>
@@ -1034,6 +1046,31 @@ trait Typers requires Analyzer {
errorTree(tree, ""+fun+" does not take parameters")
}
+ def tryTypedApply(fun: Tree, args: List[Tree]): Tree = {
+ val reportGeneralErrors = context.reportGeneralErrors
+ val reportAmbiguousErrors = context.reportAmbiguousErrors
+ try {
+ context.reportGeneralErrors = false
+ context.reportAmbiguousErrors = false
+ typedApply(fun, args)
+ } catch {
+ case ex: TypeError =>
+ val args1 = typedArgs(args)
+ val Select(qual, name) = fun
+ context.reportGeneralErrors = reportGeneralErrors
+ context.reportAmbiguousErrors = reportAmbiguousErrors
+ val qual1 = adaptToMember(qual, name, MethodType(args1 map (.tpe), pt))
+ if (qual1 eq qual) typedApply(fun, args)
+ else
+ typed1(
+ Apply(Select(qual1, name) setPos fun.pos, args) setPos tree.pos,
+ mode | SNDTRYmode, pt)
+ } finally {
+ context.reportGeneralErrors = reportGeneralErrors
+ context.reportAmbiguousErrors = reportAmbiguousErrors
+ }
+ }
+
/** Attribute a selection where `tree' is `qual.name'.
* `qual' is already attributed.
*/
@@ -1397,7 +1434,11 @@ trait Typers requires Analyzer {
fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType)
}
if (util.Statistics.enabled) appcnt = appcnt + 1
- typedApply(fun1, args)
+ if (xviews &&
+ fun1.isInstanceOf[Select] &&
+ !fun1.tpe.isInstanceOf[ImplicitMethodType] &&
+ (mode & (EXPRmode | SNDTRYmode)) == EXPRmode) tryTypedApply(fun1, args)
+ else typedApply(fun1, args)
}
case Super(qual, mix) =>
@@ -1417,7 +1458,7 @@ trait Typers requires Analyzer {
else {
val ps = clazz.info.parents dropWhile (p => p.symbol.name != mix)
if (ps.isEmpty) {
- System.out.println(clazz.info.parents map (.symbol.name));//debug
+ if (settings.debug.value) System.out.println(clazz.info.parents map (.symbol.name));//debug
error(tree.pos, ""+mix+" does not name a base class of "+clazz)
ErrorType
} else ps.head
@@ -1498,7 +1539,7 @@ trait Typers requires Analyzer {
errorTree(tree, ""+tpt1.tpe+" does not take type parameters")
} else {
//System.out.println("\{tpt1}:\{tpt1.symbol}:\{tpt1.symbol.info}")
- System.out.println(""+tpt1+":"+tpt1.symbol+":"+tpt1.symbol.info);//debug
+ if (settings.debug.value) System.out.println(""+tpt1+":"+tpt1.symbol+":"+tpt1.symbol.info);//debug
errorTree(tree, "wrong number of type arguments for "+tpt1.tpe+", should be "+tparams.length)
}
case _ =>
@@ -1694,7 +1735,7 @@ trait Typers requires Analyzer {
if (arg != EmptyTree) arg
else errorTree(tree, "no implicit argument matching parameter type "+pt+" was found.")
}
- Apply(tree, formals map implicitArg) setPos tree.pos
+ Apply(tree, formals map implicitArg) setPos tree.pos
}
}
}