summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2004-04-08 13:25:45 +0000
committerMartin Odersky <odersky@gmail.com>2004-04-08 13:25:45 +0000
commit98a03600e089ca46db9fe74cd3a0295a44148fff (patch)
treec09ab0d0833c0f0c76617045b01ebdf5abbfdac8
parent645f87a5a839685fde5ee9fbeb55d242a32445d4 (diff)
downloadscala-98a03600e089ca46db9fe74cd3a0295a44148fff.tar.gz
scala-98a03600e089ca46db9fe74cd3a0295a44148fff.tar.bz2
scala-98a03600e089ca46db9fe74cd3a0295a44148fff.zip
*** empty log message ***
-rw-r--r--config/list/library.lst2
-rw-r--r--sources/scala/List.scala21
-rw-r--r--sources/scala/Ord.scala10
-rw-r--r--sources/scala/Predef.scala148
-rw-r--r--sources/scala/tools/scalac/ast/parser/Parser.scala2
-rw-r--r--sources/scala/tools/scalac/ast/parser/Tokens.scala2
-rw-r--r--sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala2
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala12
-rw-r--r--sources/scala/tools/scalac/typechecker/DeSugarize.scala6
-rw-r--r--sources/scala/tools/scalac/typechecker/Infer.scala83
-rw-r--r--sources/scalac/symtab/Modifiers.java2
-rw-r--r--sources/scalac/symtab/Symbol.java3
-rw-r--r--sources/scalac/typechecker/RefCheck.java61
13 files changed, 243 insertions, 111 deletions
diff --git a/config/list/library.lst b/config/list/library.lst
index aecb911127..45c9cf60d4 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -39,6 +39,8 @@ Nil.scala
None.scala
Option.scala
Ord.scala
+#Ordered.scala
+#PartiallyOrdered.scala
PartialFunction.scala
Predef.scala
Ref.java
diff --git a/sources/scala/List.scala b/sources/scala/List.scala
index 8483983e80..94341862c8 100644
--- a/sources/scala/List.scala
+++ b/sources/scala/List.scala
@@ -157,8 +157,27 @@ object List {
}
sb.toString()
}
-}
+ /** Lists with ordered elements are ordered
+ * not yet since not compilable with bootstrap
+ def view[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] {
+ def compareTo [b >: List[a] <% Ordered[b]](y: b): int = y match {
+ case y1: List[a] => compareLists(x, y1);
+ case _ => -(y compareTo x)
+ }
+ private def compareLists(xs: List[a], ys: List[a]): int = {
+ if (xs.isEmpty && ys.isEmpty) 0
+ else if (xs.isEmpty) -1
+ else if (ys.isEmpty) 1
+ else {
+ val s = xs.head compareTo ys.head;
+ if (s != 0) s
+ else compareLists(xs.tail, ys.tail)
+ }
+ }
+ }
+ */
+}
/** A trait representing an ordered collection of elements of type
* <code>a</code>. This class comes with two implementing case
diff --git a/sources/scala/Ord.scala b/sources/scala/Ord.scala
index ff352ac584..911d58d29f 100644
--- a/sources/scala/Ord.scala
+++ b/sources/scala/Ord.scala
@@ -26,3 +26,13 @@ trait Ord[+T <: Ord[T]] {
def > [S >: T <: Ord[S]](that: S): Boolean = that < this;
def >=[S >: T <: Ord[S]](that: S): Boolean = that <= this;
}
+
+/*
+trait Ord[+a] {
+ def compareTo [b >: a <% Ord[b]](that: b): int;
+ def < [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) < 0;
+ def > [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) > 0;
+ def <= [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) <= 0;
+ def >= [b >: a <% Ord[b]](that: b): boolean = (this compareTo that) >= 0;
+}
+*/
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index 6bc8e8c82a..21c9ba1820 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -16,56 +16,118 @@ package scala;
*/
object Predef {
- type byte = scala.Byte;
- type short = scala.Short;
- type char = scala.Char;
- type int = scala.Int;
- type long = scala.Long;
- type float = scala.Float;
- type double = scala.Double;
- type boolean = scala.Boolean;
- type unit = scala.Unit;
-
- type String = java.lang.String;
- type NullPointerException = java.lang.NullPointerException;
- type Throwable = java.lang.Throwable;
-
- /** Create an array with given elements.
- *
- * @param xs the elements to put in the array
- * @return the array containing elements xs.
- */
- def Array[A](xs: A*): Array[A] = {
- val array: Array[A] = new Array[A](xs.length);
- var i = 0;
- for (val x <- xs.elements) { array(i) = x; i = i + 1; }
- array;
- }
+// aliases -------------------------------------------------------
- def error(message: String): All = throw new Error(message);
+ type byte = scala.Byte;
+ type short = scala.Short;
+ type char = scala.Char;
+ type int = scala.Int;
+ type long = scala.Long;
+ type float = scala.Float;
+ type double = scala.Double;
+ type boolean = scala.Boolean;
+ type unit = scala.Unit;
- def exit: Unit = java.lang.System.exit(0);
+ type String = java.lang.String;
+ type NullPointerException = java.lang.NullPointerException;
+ type Throwable = java.lang.Throwable;
- def assert(assertion: Boolean): Unit = {
- if (!assertion)
- throw new Error("assertion failed");
- }
- def assert(assertion: Boolean, message: Any): Unit = {
- if (!assertion)
- throw new Error("assertion failed: " + message);
- }
+ type Pair[+p, +q] = Tuple2[p, q];
+ def Pair[a, b](x: a, y: b) = Tuple2(x, y);
- type Pair[+p, +q] = Tuple2[p, q];
- def Pair[a, b](x: a, y: b) = Tuple2(x, y);
+ type Triple[+a, +b, +c] = Tuple3[a, b, c];
+ def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z);
- type Triple[+a, +b, +c] = Tuple3[a, b, c];
- def Triple[a, b, c](x: a, y: b, z: c) = Tuple3(x, y, z);
-
- def id[a](x: a): a = x;
- def fst[a](x: a, y: Any): a = x;
- def scd[a](x: Any, y: a): a = y;
+ def id[a](x: a): a = x;
+ def fst[a](x: a, y: Any): a = x;
+ def scd[a](x: Any, y: a): a = y;
type Function[-a,+b] = Function1[a,b];
+// arrays -----------------------------------------------------------
+
+ /** Create an array with given elements.
+ *
+ * @param xs the elements to put in the array
+ * @return the array containing elements xs.
+ */
+ def Array[A](xs: A*): Array[A] = {
+ val array: Array[A] = new Array[A](xs.length);
+ var i = 0;
+ for (val x <- xs.elements) { array(i) = x; i = i + 1; }
+ array;
+ }
+
+// errors and asserts -------------------------------------------------
+
+ def error(message: String): All = throw new Error(message);
+
+ def exit: Unit = java.lang.System.exit(0);
+
+ def assert(assertion: Boolean): Unit = {
+ if (!assertion)
+ throw new Error("assertion failed");
+ }
+ def assert(assertion: Boolean, message: Any): Unit = {
+ if (!assertion)
+ throw new Error("assertion failed: " + message);
+ }
+
+// views -------------------------------------------------------------
+/* not yet compilable with bootstrap
+
+ def view(x: int): Ordered[int] = new Ordered[int] {
+ def compareTo [b >: int <% Ordered[b]](y: b): int = y match {
+ case y1: int =>
+ if (x < y1) -1
+ else if (x > y1) 1
+ else 0
+ case _ => -(y compareTo x)
+ }
+ }
+ def view(x: long): Ordered[long] = new Ordered[long] {
+ def compareTo [b >: long <% Ordered[b]](y: b): int = y match {
+ case y1: long =>
+ if (x < y1) -1
+ else if (x > y1) 1
+ else 0
+ case _ => -(y compareTo x)
+ }
+ }
+ def view(x: float): Ordered[float] = new Ordered[float] {
+ def compareTo [b >: float <% Ordered[b]](y: b): int = y match {
+ case y1: float =>
+ if (x < y1) -1
+ else if (x > y1) 1
+ else 0
+ case _ => -(y compareTo x)
+ }
+ }
+ def view(x: double): Ordered[double] = new Ordered[double] {
+ def compareTo [b >: double <% Ordered[b]](y: b): int = y match {
+ case y1: double =>
+ if (x < y1) -1
+ else if (x > y1) 1
+ else 0
+ case _ => -(y compareTo x)
+ }
+ }
+ def view(x: boolean): Ordered[boolean] = new Ordered[boolean] {
+ def compareTo [b >: boolean <% Ordered[b]](y: b): int = y match {
+ case y1: boolean =>
+ if (x == y1) 0
+ else if (x) 1
+ else -1
+ case _ => -(y compareTo x)
+ }
+ }
+ def view(x: String): Ordered[String] = new Ordered[String] {
+ def compareTo [b >: String <% Ordered[b]](y: b): int = y match {
+ case y1: String => x compareTo y1;
+ case _ => -(y compareTo x)
+ }
+ }
+
+*/
}
diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala
index c33e62a76e..05665e4a5e 100644
--- a/sources/scala/tools/scalac/ast/parser/Parser.scala
+++ b/sources/scala/tools/scalac/ast/parser/Parser.scala
@@ -1516,7 +1516,7 @@ class Parser(unit: Unit) {
typeBounds(s.pos, mods, ident())
}
- /** TypeBounds ::= [`>:' Type] [`<:' Type | `<+' Type]
+ /** TypeBounds ::= [`>:' Type] [`<:' Type | `<%' Type]
*/
def typeBounds(pos: int, _mods: int, name: Name): Tree = {
var mods = _mods;
diff --git a/sources/scala/tools/scalac/ast/parser/Tokens.scala b/sources/scala/tools/scalac/ast/parser/Tokens.scala
index fad884f6be..ca20940c35 100644
--- a/sources/scala/tools/scalac/ast/parser/Tokens.scala
+++ b/sources/scala/tools/scalac/ast/parser/Tokens.scala
@@ -205,7 +205,7 @@ object Tokens {
enterKeyword("<-", LARROW);
enterKeyword("<:", SUBTYPE);
enterKeyword(">:", SUPERTYPE);
- enterKeyword("<+", VIEWBOUND);
+ enterKeyword("<%", VIEWBOUND);
enterKeyword("#", HASH);
enterKeyword("@", AT);
diff --git a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala
index 14da5e6613..a17f54774c 100644
--- a/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala
+++ b/sources/scala/tools/scalac/ast/printer/TextTreePrinter.scala
@@ -166,7 +166,7 @@ class TextTreePrinter(writer: PrintWriter) with TreePrinter {
protected final val TXT_EQUAL = Simple("=");
protected final val TXT_SUPERTYPE = Simple(">:");
protected final val TXT_SUBTYPE = Simple("<:");
- protected final val TXT_VIEWBOUND = Simple("<+");
+ protected final val TXT_VIEWBOUND = Simple("<%");
protected final val TXT_HASH = Simple("#");
protected final val TXT_RIGHT_ARROW = Simple("=>");
protected final val TXT_LEFT_PAREN = Simple("(");
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index 18cae3fe6d..37b3ae2379 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -1052,8 +1052,14 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
tree, sym.primaryConstructor(), new Scope(context.scope));
val tparamSyms = enterParams(tparams);
var vparamSyms = enterParams(vparams);
- if (vparamSyms.length == 0)
+ if (vparamSyms.length == 0) {
vparamSyms = NewArray.SymbolArray{Symbol.EMPTY_ARRAY};
+ } else if (infer.isViewBounded(tparamSyms) && vparamSyms.length == 1) {
+ val vparamSyms1 = new Array[Array[Symbol]](2);
+ vparamSyms1(0) = vparamSyms(0);
+ vparamSyms1(1) = Symbol.EMPTY_ARRAY;
+ vparamSyms = vparamSyms1
+ }
if ((mods & CASE) != 0 && vparams.length > 0)
templ.body = desugarize.addCaseElements(
templ.body, vparams(vparams.length - 1));
@@ -2660,7 +2666,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
fn1 = infer.methodInstance(fn1, tparams, restp, argtypes, pt);
//System.out.println(fn1 + ":" + fn1.getType());//DEBUG
} catch {
- case ex: Type$Error => reportTypeError(tree.pos, ex);
+ case ex: Type$Error =>
+ //ex.printStackTrace();//DEBUG
+ reportTypeError(tree.pos, ex);
}
fn1.getType() match {
case Type$MethodType(params, restp1) =>
diff --git a/sources/scala/tools/scalac/typechecker/DeSugarize.scala b/sources/scala/tools/scalac/typechecker/DeSugarize.scala
index 59ec8946d6..ae21fac622 100644
--- a/sources/scala/tools/scalac/typechecker/DeSugarize.scala
+++ b/sources/scala/tools/scalac/typechecker/DeSugarize.scala
@@ -301,11 +301,15 @@ class DeSugarize(make: TreeFactory, copy: TreeCopier, gen: TreeGen, infer: scala
addViewParams(tparams, vparams), tpe, templ);
case Tree$DefDef(mods, name, tparams, vparams, tpe, rhs) =>
+ //System.out.println("DEF " + make.DefDef(tree.pos, mods, name, tparams, addViewParams(tparams, vparams), tpe, rhs));//DEBUG
make.DefDef(tree.pos, mods, name, tparams,
addViewParams(tparams, vparams), tpe, rhs)
+ case Tree$DocDef(comment, definition) =>
+ make.DocDef(tree.pos, comment, Definition(definition))
+
case _ =>
- return tree
+ tree
}
def addViewParams(tparams: Array[Tree$AbsTypeDef], vparams: Array[Array[Tree$ValDef]]): Array[Array[Tree$ValDef]] = {
diff --git a/sources/scala/tools/scalac/typechecker/Infer.scala b/sources/scala/tools/scalac/typechecker/Infer.scala
index 8dada48e1b..59f2a042ac 100644
--- a/sources/scala/tools/scalac/typechecker/Infer.scala
+++ b/sources/scala/tools/scalac/typechecker/Infer.scala
@@ -334,7 +334,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
}
}
- private def viewObj(meth: Tree, msym: Symbol) = msym.getType() match {
+ private def viewObj(meth: Tree) = meth.getType() match {
case Type$MethodType(params: Array[Symbol], _) =>
assert(params.length == 1);
val paramsym = params(0).cloneSymbol(getContext.owner);
@@ -360,10 +360,12 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
case Type$PolyType(vtparams, vrestype) =>
assert(vtparams.length != 0);
vmeth = exprInstance(vmeth, vtparams, vrestype, vtype);
- assert(vmeth.getType().isSubType(vtype));
case _ =>
}
- viewObj(vmeth, v.sym)
+ val vobj = viewObj(vmeth);
+ if (!vobj.getType().isSubType(vtype))
+ assert(false, "view argument " + vobj + ":" + vobj.getType() + " is not a subtype of view param type " + vtype);
+ vobj
} else {
error(pos,
"type instantiation with [" +
@@ -407,18 +409,19 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
}
def completeTypeApply(tree: Tree): Tree = {
+ //System.out.println("complete type apply: " + tree + ":" + tree.getType());//DEBUG
tree match {
- case Tree$TypeApply(fn, targs) =>
- fn.getType() match {
- case Type$PolyType(tparams, restp) if tparams.length == targs.length =>
- if (isViewBounded(tparams)) {
- val result = passViewArgs(tree, tparams, restp, Tree.typeOf(targs));
- //System.out.println("completed type apply: " + result + ":" + result.getType());//DEBUG
- result
- } else tree
- case _ => tree
- }
- case _ => tree
+ case Tree$TypeApply(fn, targs) =>
+ fn.getType() match {
+ case Type$PolyType(tparams, restp) if tparams.length == targs.length =>
+ if (isViewBounded(tparams)) {
+ val result = passViewArgs(tree, tparams, restp, Tree.typeOf(targs));
+ //System.out.println("completed type apply: " + result + ":" + result.getType());//DEBUG
+ result
+ } else tree
+ case _ => tree
+ }
+ case _ => tree
}
}
@@ -905,6 +908,19 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
tvars
}
+ private def methTypeArgsSkipViews(
+ tparams: Array[Symbol], params: Array[Symbol],
+ argtypes: Array[Type], restpe: Type,
+ pt: Type,
+ needToSucceed: boolean, regularValue: boolean): Array[Type] = restpe match {
+ case Type$MethodType(params1, restpe1) if isViewBounded(tparams) =>
+ methTypeArgs(
+ tparams, params1, argtypes, restpe1, pt, needToSucceed, regularValue);
+ case _ =>
+ methTypeArgs(
+ tparams, params, argtypes, restpe, pt, needToSucceed, regularValue);
+ }
+
/** Create and attribute type application node. Pass arguments for that
* `tparams' prefix which is owned by the tree's symbol. If there are remaining
* type parameters, substitute corresponding type arguments for them in the
@@ -957,9 +973,10 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
case _ =>
if (tparams.length != 0) {
- var targs: Array[Type] = exprTypeArgs(tparams, restype, pt1);
+ val skippedRestype = skipViewParams(tparams, restype);
+ var targs: Array[Type] = exprTypeArgs(tparams, skippedRestype, pt1);
if (targs == null)
- targs = exprTypeArgs(tparams, restype, pt2);
+ targs = exprTypeArgs(tparams, skippedRestype, pt2);
if (targs == null)
throw new Type$Error(
typeErrorMsg(
@@ -984,7 +1001,8 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
System.arraycopy(tparams1, 0, tparams2, tparams.length, tparams1.length);
exprInstance(tree, tparams2, restype1, pt)
case _ =>
- val targs: Array[Type] = exprTypeArgs(tparams, restype, pt);
+ val targs: Array[Type] =
+ exprTypeArgs(tparams, skipViewParams(tparams, restype), pt);
if (targs == null)
throw new Type$Error(
"polymorphic expression of type " + tree.getType() +
@@ -1010,14 +1028,8 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
case Type$MethodType(params, restpe) =>
var targs: Array[Type] = _;
try {
- restpe match {
- case Type$MethodType(params1, restpe1) if isViewBounded(tparams) =>
- targs = methTypeArgs(
- tparams, params1, argtypes, restpe1, pt, true, false);
- case _ =>
- targs = methTypeArgs(
- tparams, params, argtypes, restpe, pt, true, false);
- }
+ targs = methTypeArgsSkipViews(
+ tparams, params, argtypes, restpe, pt, true, false);
} catch {
case ex: NoInstance =>
throw new Type$Error(
@@ -1054,17 +1066,18 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
case _ =>
val tvars: Array[Type] = freshVars(tparams);
- val restype1: Type = restype.subst(tparams, tvars);
+ val restype0: Type = skipViewParams(tparams, restype);
+ val restype1: Type = restype0.subst(tparams, tvars);
val ctpe1: Type = restype1.resultType();
if (ctpe1.isSubType(pt)) {
try {
{ var i = 0; while (i < tvars.length) {
- solve(tparams, true, variance(tparams, restype.resultType()),
+ solve(tparams, true, variance(tparams, restype0.resultType()),
tvars, i);
i = i + 1
}}
checkBounds(tparams, tvars, "inferred ");
- tree.setType(restype.subst(tparams, tvars));
+ tree.setType(restype0.subst(tparams, tvars));
//System.out.println("inferred constructor type: " + tree.getType());//DEBUG
} catch {
case ex: NoInstance =>
@@ -1092,7 +1105,9 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
isApplicable(ftpe, argtypes, pt, Names.EMPTY, true);
def isApplicable(ftpe: Type, argtypes: Array[Type], pt: Type,
- fieldName: Name, regularValue: boolean): boolean = ftpe match {
+ fieldName: Name, regularValue: boolean): boolean = {
+ //if (!regularValue) System.out.println("is app " + ftpe + " to " + ArrayApply.toString(argtypes.asInstanceOf[Array[Object]]));//DEBUG
+ ftpe match {
case Type$MethodType(params, restpe) =>
// sequences ? List( a* )
val formals: Array[Type] = formalTypes(params, argtypes.length);
@@ -1102,16 +1117,17 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
(fieldName == Names.EMPTY || restpe.lookup(fieldName).kind != NONE)
case Type$PolyType(tparams, Type$MethodType(params, restpe)) =>
try {
- val targs: Array[Type] = methTypeArgs(
+ val targs: Array[Type] = methTypeArgsSkipViews(
tparams, params, argtypes, restpe, pt, false, regularValue);
if (targs != null) {
val uninstantiated: Array[Symbol] = normalizeArgs(targs, tparams, restpe);
+ val restpe1 = skipViewParams(tparams, restpe);
isWithinBounds(tparams, targs) &&
exprTypeArgs(uninstantiated,
- restpe.subst(tparams, targs), pt,
+ restpe1.subst(tparams, targs), pt,
regularValue) != null &&
(fieldName == Names.EMPTY ||
- restpe.subst(tparams, targs).lookup(fieldName).kind != NONE)
+ restpe1.subst(tparams, targs).lookup(fieldName).kind != NONE)
} else {
false
}
@@ -1124,7 +1140,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
ftpe1 != ftpe &&
isApplicable(ftpe1, argtypes, pt, fieldName, false);
} else false
- }
+ }}
def applyType(tp: Type) =
if (tp.isObjectType()) {
@@ -1274,6 +1290,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal
def bestView(tp: Type, pt: Type, name: Name): View = {
var best: View = null;
var viewMeths = getViews(tp);
+ //System.out.println("best view for " + tp + "/" + pt + " in " + viewMeths);//DEBUG
val argtypes = NewArray.Type(tp);
while (!viewMeths.isEmpty) {
if (isApplicable(viewMeths.head.symtype, argtypes, pt, name, false) &&
diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java
index afe215ea3d..dd6a6167ed 100644
--- a/sources/scalac/symtab/Modifiers.java
+++ b/sources/scalac/symtab/Modifiers.java
@@ -31,7 +31,7 @@ public interface Modifiers {
int JAVA = 0x00001000; // symbol was defined by a Java class
int MODUL = 0x00002000; // symbol is module or class implementing a module
int MUTABLE = 0x00004000; // symbol is a mutable variable.
- int VIEWBOUND = 0x00004000; // type symbol has a <+ bound.
+ int VIEWBOUND = 0x00004000; // type symbol has a <% bound.
int PARAM = 0x00008000; // symbol is a (type) parameter to a method
int INITIALIZED = 0x00010000; // symbol's definition is complete
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index ccd9f2632a..bbfd7c0301 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -1791,7 +1791,8 @@ final class AbsTypeSymbol extends TypeSymbol {
public Type vuBound() {
initialize();
- return vubound == null ? Global.instance.definitions.ANY_TYPE() : vubound;
+ return !isViewBounded() || vubound == null
+ ? Global.instance.definitions.ANY_TYPE() : vubound;
}
public Symbol setLoBound(Type lobound) {
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index 2bb96cbe69..f7649a9792 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -820,45 +820,54 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
* the case classe's primary constructor `constr'.
*/
private Tree toConstructor(Tree tree, Symbol constr) {
- switch (tree) {
- case Apply(Tree fn, Tree[] args):
- return copy.Apply(tree, toConstructor1(fn, constr), args);
- default:
- return gen.Apply(
- tree.pos, toConstructor1(tree, constr), Tree.EMPTY_ARRAY);
- }
+ int missing = constr.getType().paramSectionCount() - applyNesting(tree);
+ assert missing >= 0 && missing <= 1;
+ Tree tree1 = toConstructor1(tree, constr, missing > 0);
+ if (missing > 0) return gen.Apply(tree1, Tree.EMPTY_ARRAY);
+ else return tree1;
}
//where
- private Tree toConstructor1(Tree tree, Symbol constr) {
+ private int applyNesting(Tree tree) {
+ switch (tree) {
+ case Apply(Tree fn, Tree[] args):
+ return applyNesting(fn) + 1;
+ default:
+ return 0;
+ }
+ }
+
+ private Tree toConstructor1(Tree tree, Symbol constr, boolean addEmpty) {
+ Tree tree1 = toConstructor2(tree, constr, addEmpty);
+ if (addEmpty)
+ return tree1.duplicate()
+ .setType(addEmptyParams(tree1.getType()));
+ else
+ return tree1;
+ }
+
+ private Tree toConstructor2(Tree tree, Symbol constr, boolean addEmpty) {
switch (tree) {
+ case Apply(Tree fn, Tree[] args):
+ return copy.Apply(
+ tree, toConstructor1(fn, constr, addEmpty), args);
case TypeApply(Tree fn, Tree[] args):
- return toMethodType(
- copy.TypeApply(tree, toConstructor1(fn, constr), args));
+ return copy.TypeApply(
+ tree, toConstructor1(fn, constr, addEmpty), args);
case Ident(_):
- return toMethodType(
- copy.Ident(tree, constr));
+ return copy.Ident(tree, constr);
case Select(Tree qual, _):
- return toMethodType(
- copy.Select(tree, constr, qual));
+ return copy.Select(tree, constr, qual);
default:
throw new ApplicationError();
}
}
- private Tree toMethodType(Tree tree) {
- Type tp = toMethodType(tree.type);
- if (tp == tree.type) return tree;
- else return tree.duplicate().setType(tp);
- }
-
- private Type toMethodType(Type tp) {
+ private Type addEmptyParams(Type tp) {
switch (tp) {
- case MethodType(_, _):
- return tp;
+ case MethodType(Symbol[] vparams, Type restp):
+ return Type.MethodType(vparams, addEmptyParams(restp));
case PolyType(Symbol[] tparams, Type restp):
- Type restp1 = toMethodType(restp);
- if (restp == restp) return tp;
- else return Type.PolyType(tparams, restp1);
+ return Type.PolyType(tparams, addEmptyParams(restp));
default:
return Type.MethodType(Symbol.EMPTY_ARRAY, tp);
}