summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala30
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala17
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
4 files changed, 38 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index a09eaa8ebf..d0d77808ce 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -55,7 +55,7 @@ abstract class Constructors extends Transform {
parameterNamed(nme.getterName(acc.originalName))
def parameterNamed(name: Name): Symbol = {
- val ps = constrParams.filter(param => param.name == name)
+ val ps = constrParams.filter(param => param.name == name || param.originalName == name)
if (ps.isEmpty) assert(false, "" + name + " not in " + constrParams)
ps.head
}
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 24be97f712..c8d00acd59 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -390,6 +390,14 @@ abstract class Mixin extends InfoTransform {
private def selfRef(pos: PositionType) =
gen.mkAttributedIdent(self) setPos pos
+ /** Replace a super reference by this or the self parameter, depending
+ * on whether we are in an implementation class or not.
+ * Leave all other trees unchanged */
+ private def transformSuper(qual: Tree) =
+ if (!qual.isInstanceOf[Super]) qual
+ else if (currentOwner.enclClass.isImplClass) selfRef(qual.pos)
+ else gen.mkAttributedThis(currentOwner.enclClass)
+
/** Create a static reference to given symbol <code>sym</code> of the
* form <code>M.sym</code> where M is the symbol's implementation module.
*/
@@ -586,11 +594,7 @@ abstract class Mixin extends InfoTransform {
assert(false, "" + sym + ":" + sym.tpe + " " + sym.owner + " " + implClass(sym.owner) + " " + implClass(sym.owner).info.member(sym.name) + " " + atPhase(phase.prev)(implClass(sym.owner).info.member(sym.name).tpe) + " " + phase);//debug
localTyper.typed {
atPos(tree.pos) {
- val qual1 =
- if (!qual.isInstanceOf[Super]) qual
- else if (currentOwner.enclClass.isImplClass) selfRef(qual.pos)
- else gen.mkAttributedThis(currentOwner.enclClass);
- Apply(staticRef(target), qual1 :: args)
+ Apply(staticRef(target), transformSuper(qual) :: args)
}
}
}
@@ -607,9 +611,19 @@ abstract class Mixin extends InfoTransform {
// - otherwise return tree unchanged
if (mix == nme.EMPTY.toTypeName && currentOwner.enclClass.isImplClass)
assert(false, "illegal super in trait: " + currentOwner.enclClass + " " + tree);
- if (sym.owner hasFlag lateINTERFACE)
- staticCall(atPhase(phase.prev)(sym.overridingSymbol(implClass(sym.owner))))
- else {
+ if (sym.owner hasFlag lateINTERFACE) {
+ if (sym.hasFlag(ACCESSOR)) {
+ assert(args.isEmpty)
+ val sym1 = sym.overridingSymbol(currentOwner.enclClass)
+ localTyper.typed {
+ atPos(tree.pos) {
+ Apply(Select(transformSuper(qual), sym1), List())
+ }
+ }
+ } else {
+ staticCall(atPhase(phase.prev)(sym.overridingSymbol(implClass(sym.owner))))
+ }
+ } else {
assert(!currentOwner.enclClass.isImplClass)
tree
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index f85be9d6d7..2482bff9cd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -922,6 +922,16 @@ trait Infer requires Analyzer {
/* -- Overload Resolution ---------------------------------------------- */
+ def checkNotShadowed(pos: PositionType, pre: Type, best: Symbol, eligible: List[Symbol]) =
+ for (val alt <- eligible) {
+ if (alt.owner != best.owner && alt.owner.isSubClass(best.owner))
+ error(pos,
+ "erroneous reference to overloaded definition,\n"+
+ "most specific definition is: "+best+best.locationString+" of type "+pre.memberType(best)+
+ ",\nyet alternative definition "+alt+alt.locationString+" of type "+pre.memberType(alt)+
+ "\nis defined in a subclass")
+ }
+
/** Assign <code>tree</code> the symbol and type of the alternative which
* matches prototype <code>pt</code>, if it exists.
* If several alternatives match `pt', take parameterless one.
@@ -933,7 +943,6 @@ trait Infer requires Analyzer {
if (alts1.isEmpty) alts1 = alts
def improves(sym1: Symbol, sym2: Symbol): boolean =
sym2 == NoSymbol ||
- (sym1.owner isSubClass sym2.owner) &&
{ val tp1 = pre.memberType(sym1)
val tp2 = pre.memberType(sym2)
(tp2 == ErrorType ||
@@ -959,7 +968,9 @@ trait Infer requires Analyzer {
context.ambiguousError(tree.pos, pre, best, competing.head, "expected type " + pt)
setError(tree)
()
+
} else {
+ //checkNotShadowed(tree.pos, pre, best, alts1)
tree.setSymbol(best).setType(pre.memberType(best))
}
}
@@ -979,8 +990,7 @@ trait Infer requires Analyzer {
val applicable = alts filter (alt => isApplicable(undetparams, pre.memberType(alt), argtpes, pt))
def improves(sym1: Symbol, sym2: Symbol) = (
sym2 == NoSymbol || sym2.isError ||
- ((sym1.owner isSubClass sym2.owner) &&
- specializes(pre.memberType(sym1), pre.memberType(sym2)))
+ specializes(pre.memberType(sym1), pre.memberType(sym2))
)
val best = ((NoSymbol: Symbol) /: applicable) ((best, alt) =>
if (improves(alt, best)) alt else best)
@@ -999,6 +1009,7 @@ trait Infer requires Analyzer {
setError(tree)
()
} else {
+ //checkNotShadowed(tree.pos, pre, best, applicable)
tree.setSymbol(best).setType(pre.memberType(best))
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index db13b4e168..35a728dbbb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1004,7 +1004,7 @@ trait Typers requires Analyzer {
case Apply(fun, _) =>
if (fun.symbol.isConstructor &&
fun.symbol.owner == meth.owner && fun.symbol.pos >= meth.pos)
- error(fun.pos, "called constructor must precede calling constructor")
+ error(fun.pos, "called constructor's definition must precede calling constructor's definition")
case _ =>
}
def typedSuperCall(tree: Tree, pt: Type): Tree = {