aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-11-15 12:25:13 +0100
committerMartin Odersky <odersky@gmail.com>2013-11-15 12:25:13 +0100
commit18da7faf93ffaefa0ee7e37211c740c1f34ddfa2 (patch)
tree272e28de24a61720d8cf278124c325afdfc0823c /src/dotty/tools/dotc
parent7a9e632c64865084e6e8559a0e6ea90e2b706a8b (diff)
downloaddotty-18da7faf93ffaefa0ee7e37211c740c1f34ddfa2.tar.gz
dotty-18da7faf93ffaefa0ee7e37211c740c1f34ddfa2.tar.bz2
dotty-18da7faf93ffaefa0ee7e37211c740c1f34ddfa2.zip
Tweaks to adaptation and interpolation
1. Needed to interpolate aftyer implicit parameyters are added. 2. Also needed to avoid constraining typevars if compared against selection proto. Original coder example now typechecks.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala24
6 files changed, 25 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 8e0b1d01c..22d0a1d0b 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -216,7 +216,7 @@ class TypeComparer(initctx: Context) extends DotClass {
case tp2: TypeVar =>
(tp1 eq tp2) || isSubType(tp1, tp2.underlying)
case tp2: ProtoType =>
- tp2.isMatchedBy(tp1)
+ isMatchedByProto(tp2, tp1)
case tp2: WildcardType =>
tp2.optBounds match {
case TypeBounds(_, hi) => isSubType(tp1, hi)
@@ -388,6 +388,12 @@ class TypeComparer(initctx: Context) extends DotClass {
case _ => param.binder.paramBounds(param.paramNum)
}
+ /** Defer constraining type variables when comnpared against prototypes */
+ def isMatchedByProto(proto: ProtoType, tp: Type) = tp.stripTypeVar match {
+ case tp: PolyParam if constraint(tp).exists => true
+ case _ => proto.isMatchedBy(tp)
+ }
+
/* not needed
def isSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[TypeSymbol]): Boolean = tparams match {
case tparam :: tparams1 =>
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 201f928a9..ba67d2b1e 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -356,7 +356,7 @@ trait Applications extends Compatibility { self: Typer =>
init()
def addArg(arg: Tree, formal: Type): Unit =
- typedArgBuf += adapt(arg, formal)
+ typedArgBuf += adaptInterpolated(arg, formal)
def makeVarArg(n: Int, elemFormal: Type): Unit = {
val args = typedArgBuf.takeRight(n).toList
@@ -467,7 +467,7 @@ trait Applications extends Compatibility { self: Typer =>
} { failed => fun1 match {
case Select(qual, name) =>
tryEither { implicit ctx =>
- val qual1 = adapt(qual, new SelectionProto(name, proto))
+ val qual1 = adaptInterpolated(qual, new SelectionProto(name, proto))
if (qual1.tpe.isError || (qual1 eq qual)) qual1
else
typedApply(
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 6cda24808..10e3dbbca 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -299,7 +299,7 @@ trait Implicits { self: Typer =>
generated = typedUnadapted(
untpd.Apply(untpd.TypedSplice(generated), untpd.TypedSplice(argument) :: Nil),
pt)
- val generated1 = interpolateAndAdapt(generated, pt)
+ val generated1 = adapt(generated, pt)
lazy val shadowing =
typed(untpd.Ident(ref.name) withPos pos.toSynthetic, ref)(nestedContext).tpe
if (ctx.typerState.reporter.hasErrors) nonMatchingImplicit(ref)
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 154fdcbd2..f804feda4 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -88,7 +88,7 @@ object Inferencing {
targ = typer.typedUnadapted(arg, formal)
myTypedArg = myTypedArg.updated(arg, targ)
}
- typer.interpolateAndAdapt(targ, formal)
+ typer.adapt(targ, formal)
}
override def toString = s"FunProto(${args mkString ","} => $resultType)"
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index fb2aef90d..62405abd9 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -391,7 +391,7 @@ class Namer { typer: Typer =>
tp & itpe
}
}
- def rhsType = interpolateAndAdapt(typedAheadExpr(mdef.rhs), WildcardType).tpe.widen
+ def rhsType = adapt(typedAheadExpr(mdef.rhs), WildcardType).tpe.widen
def lhsType = fullyDefinedType(rhsType, "right-hand side", mdef.pos)
inherited orElse lhsType
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 1e84fad65..bf9572a46 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -862,7 +862,7 @@ class Typer extends Namer with Applications with Implicits {
}
def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ctx.traceIndented (s"typing ${tree.show}", show = true) {
- try interpolateAndAdapt(typedUnadapted(tree, pt), pt)
+ try adapt(typedUnadapted(tree, pt), pt)
catch {
case ex: FatalTypeError => errorTree(tree, ex.getMessage)
}
@@ -925,10 +925,12 @@ class Typer extends Namer with Applications with Implicits {
fallBack
}
- def interpolateAndAdapt(tree: Tree, pt: Type)(implicit ctx: Context) = {
- ctx.interpolateUndetVars(tree)
- tree overwriteType tree.tpe.simplified
- adapt(tree, pt)
+ def adapt(tree: Tree, pt: Type)(implicit ctx: Context) = track("adapt") {
+ ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", show = true) {
+ ctx.interpolateUndetVars(tree)
+ tree overwriteType tree.tpe.simplified
+ adaptInterpolated(tree, pt)
+ }
}
/** (-1) For expressions with annotated types, let AnnotationCheckers decide what to do
@@ -969,7 +971,7 @@ class Typer extends Namer with Applications with Implicits {
* (14) When in mode EXPRmode, apply a view
* If all this fails, error
*/
- def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = track("adapt") { ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", show = true) {
+ def adaptInterpolated(tree: Tree, pt: Type)(implicit ctx: Context): Tree = {
assert(pt.exists)
@@ -982,7 +984,7 @@ class Typer extends Namer with Applications with Implicits {
def expectedStr = err.expectedTypeStr(pt)
resolveOverloaded(alts, pt)(ctx.fresh.withExploreTyperState) match {
case alt :: Nil =>
- adapt(tree.withType(alt), pt)
+ adaptInterpolated(tree.withType(alt), pt)
case Nil =>
def noMatches =
errorTree(tree,
@@ -1021,7 +1023,7 @@ class Typer extends Namer with Applications with Implicits {
def adaptNoArgs(wtp: Type) = wtp match {
case wtp: ExprType =>
- adapt(tree.withType(wtp.resultType), pt)
+ adaptInterpolated(tree.withType(wtp.resultType), pt)
case wtp: ImplicitMethodType =>
def implicitArgError(msg: => String): Tree = {
ctx.error(msg, tree.pos.endPos)
@@ -1044,7 +1046,7 @@ class Typer extends Namer with Applications with Implicits {
!tree.symbol.isConstructor)
etaExpand(tree, wtp)
else if (wtp.paramTypes.isEmpty)
- adapt(tpd.Apply(tree, Nil), pt)
+ adaptInterpolated(tpd.Apply(tree, Nil), pt)
else
errorTree(tree,
i"""missing arguments for $methodStr
@@ -1102,7 +1104,7 @@ class Typer extends Namer with Applications with Implicits {
val tracked = ctx.track(poly)
ctx.newTypeVars(tracked, tree)
}
- adapt(tree appliedToTypes tvars, pt)
+ adaptInterpolated(tree appliedToTypes tvars, pt)
}
case wtp =>
pt match {
@@ -1115,5 +1117,5 @@ class Typer extends Namer with Applications with Implicits {
}
}
}
- }}
+ }
} \ No newline at end of file