aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-01-06 15:37:11 +0100
committerMartin Odersky <odersky@gmail.com>2014-01-06 15:37:11 +0100
commit2948c91f06eacc1c1904576275b31d2872702917 (patch)
tree82e6328535100ea18274faf9328e4d12ab140529 /src/dotty/tools
parentd495cf9a0c24fb6ea63acb3e20f35b634814f1aa (diff)
downloaddotty-2948c91f06eacc1c1904576275b31d2872702917.tar.gz
dotty-2948c91f06eacc1c1904576275b31d2872702917.tar.bz2
dotty-2948c91f06eacc1c1904576275b31d2872702917.zip
Change to overloading behavior
Nullary methods are always as specific as non-nullary ones. Needed so that foo() takes precdennce over foo(x: T)
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/config/Platform.scala2
-rw-r--r--src/dotty/tools/dotc/config/Properties.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala6
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala44
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala3
5 files changed, 33 insertions, 24 deletions
diff --git a/src/dotty/tools/dotc/config/Platform.scala b/src/dotty/tools/dotc/config/Platform.scala
index 4909c8d68..972892d12 100644
--- a/src/dotty/tools/dotc/config/Platform.scala
+++ b/src/dotty/tools/dotc/config/Platform.scala
@@ -22,7 +22,7 @@ abstract class Platform {
def classPath(implicit ctx: Context): ClassPath
/** Update classpath with a substitution that maps entries to entries */
- def updateClassPath(subst: Map[ClassPath, ClassPath])
+ def updateClassPath(subst: Map[ClassPath, ClassPath]): Unit
/** Any platform-specific phases. */
//def platformPhases: List[SubComponent]
diff --git a/src/dotty/tools/dotc/config/Properties.scala b/src/dotty/tools/dotc/config/Properties.scala
index 47572e087..d592a7bb1 100644
--- a/src/dotty/tools/dotc/config/Properties.scala
+++ b/src/dotty/tools/dotc/config/Properties.scala
@@ -158,7 +158,7 @@ trait PropertiesTrait {
}
// provide a main method so version info can be obtained by running this
- def main(args: Array[String]) {
+ def main(args: Array[String]): Unit = {
val writer = new PrintWriter(Console.err, true)
writer println versionMsg
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index d281af733..930922b5b 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1451,9 +1451,11 @@ object Types {
}
}
+ trait MethodOrPoly extends SignedType
+
abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])
(resultTypeExp: MethodType => Type)
- extends CachedGroundType with BindingType with TermType with SignedType { thisMethodType =>
+ extends CachedGroundType with BindingType with TermType with MethodOrPoly { thisMethodType =>
override val resultType = resultTypeExp(this)
assert(resultType != NoType, this)
@@ -1584,7 +1586,7 @@ object Types {
}
case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
- extends UncachedGroundType with BindingType with TermType with SignedType {
+ extends UncachedGroundType with BindingType with TermType with MethodOrPoly {
val paramBounds = paramBoundsExp(this)
override val resultType = resultTypeExp(this)
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index ca29ff9f7..485cba1f0 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -740,28 +740,24 @@ trait Applications extends Compatibility { self: Typer =>
else (sym1 is Module) && isDerived(sym1.companionClass, sym2)
/** Is alternative `alt1` with type `tp1` as specific as alternative
- * `alt2` with type `tp2` ? This is the case if `tp2` can be applied to
- * `tp1` (without intervention of implicits) or `tp2' is a supertype of `tp1`,
- * or `tp2` is a method or poly type but `tp1` isn't.
+ * `alt2` with type `tp2` ? This is the case if
+ *
+ * 1. `tp2` is a method or poly type but `tp1` isn't, or `tp1` is nullary.
+ * 2. `tp2` and `tp1` are method or poly types and `tp2` can be applied to the parameters of `tp1`.
+ * 3. Neither `tp1` nor `tp2` are method or poly types and `tp1` is compatible with `tp2`.
*/
- def isAsSpecific(alt1: TermRef, tp1: Type, alt2: TermRef, tp2: Type): Boolean = tp1 match {
+ def isAsSpecific(alt1: TermRef, tp1: Type, alt2: TermRef, tp2: Type): Boolean = tp1 match {
case tp1: PolyType =>
def bounds(tparamRefs: List[TypeRef]) = tp1.paramBounds map (_.substParams(tp1, tparamRefs))
val tparams = ctx.newTypeParams(alt1.symbol.owner, tp1.paramNames, EmptyFlags, bounds)
isAsSpecific(alt1, tp1.instantiate(tparams map (_.typeRef)), alt2, tp2)
case tp1: MethodType =>
- isApplicable(alt2, tp1.paramTypes, WildcardType)
+ isApplicable(alt2, tp1.paramTypes, WildcardType) ||
+ tp1.paramTypes.isEmpty && tp2.isInstanceOf[MethodOrPoly]
case _ =>
tp2 match {
- case tp2: PolyType =>
- true
-// was:
-// assert(!ctx.typerState.isCommittable)
-// isAsSpecific(alt1, tp1, alt2, constrained(tp2).resultType)
- case tp2: MethodType =>
- true
- case _ =>
- isCompatible(tp1, tp2)
+ case tp2: MethodOrPoly => true
+ case _ => isCompatible(tp1, tp2)
}
}
@@ -792,11 +788,12 @@ trait Applications extends Compatibility { self: Typer =>
else /* 1/9 */ winsType1 || /* 2/27 */ !winsType2
}}
- def narrowMostSpecific(alts: List[TermRef])(implicit ctx: Context): List[TermRef] = track("narrowMostSpecific") {
+ def narrowMostSpecific(alts: List[TermRef], onTarget: Boolean = false)(implicit ctx: Context): List[TermRef] = track("narrowMostSpecific") {
(alts: @unchecked) match {
case alt :: alts1 =>
def winner(bestSoFar: TermRef, alts: List[TermRef]): TermRef = alts match {
case alt :: alts1 =>
+ println(i"comparing ${alt.widen} ${bestSoFar.widen}")
winner(if (isAsGood(alt, bestSoFar)) alt else bestSoFar, alts1)
case nil =>
bestSoFar
@@ -809,7 +806,7 @@ trait Applications extends Compatibility { self: Typer =>
case nil =>
Nil
}
- best :: asGood(alts1)
+ best :: asGood(alts)
}
}
@@ -820,6 +817,11 @@ trait Applications extends Compatibility { self: Typer =>
*/
def resolveOverloaded(alts: List[TermRef], pt: Type, targs: List[Type] = Nil)(implicit ctx: Context): List[TermRef] = track("resolveOverloaded") {
+ val onTarget = alts.head.name == "toLowerCase".toTermName
+
+ if (onTarget)
+ println(i"resolveOverloaded $alts, pt = $pt")
+
def isDetermined(alts: List[TermRef]) = alts.isEmpty || alts.tail.isEmpty
/** The shape of given tree as a type; cannot handle named arguments. */
@@ -878,10 +880,14 @@ trait Applications extends Compatibility { self: Typer =>
alts filter (isApplicable(_, targs, args, resultType))
val alts1 = narrowBySize(alts)
+ if (onTarget) println(i"narrow by size $alts")
+
if (isDetermined(alts1)) alts1
else {
val alts2 = narrowByShapes(alts1)
- if (isDetermined(alts2)) alts2
+ if (onTarget) println(i"narrow by shapes $alts")
+
+ if (isDetermined(alts2)) alts2
else narrowByTrees(alts2, pt.typedArgs, resultType)
}
@@ -895,9 +901,9 @@ trait Applications extends Compatibility { self: Typer =>
case pt =>
alts filter (normalizedCompatible(_, pt))
}
-
+ println(s"candidates = $alts")
if (isDetermined(candidates)) candidates
- else narrowMostSpecific(candidates)
+ else narrowMostSpecific(candidates, onTarget)
}
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index ee3c97af3..4c55b9d4f 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -254,7 +254,8 @@ class Typer extends Namer with Applications with Implicits {
val Name = name.toTermName
selectors match {
case Pair(Ident(from), Ident(Name)) :: rest =>
- checkUnambiguous(selectionType(site, name, tree.pos))
+ val selName = if (name.isTypeName) from.toTypeName else from
+ checkUnambiguous(selectionType(site, selName, tree.pos))
case Ident(Name) :: rest =>
checkUnambiguous(selectionType(site, name, tree.pos))
case _ :: rest =>