aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala7
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala14
-rw-r--r--tests/pos/Patterns.scala15
6 files changed, 30 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index b441da6b4..84a9d84e7 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -72,7 +72,7 @@ class TypeComparer(initctx: Context) extends DotClass {
def addConstraint(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean = {
param == bound ||
!frozenConstraint && {
- println(s"adding ${param.show} ${if (fromBelow) ">:>" else "<:<"} ${bound.show} to ${constraint.show}")
+ // println(s"adding ${param.show} ${if (fromBelow) ">:>" else "<:<"} ${bound.show} to ${constraint.show}")
bound match {
case bound: PolyParam if constraint contains bound =>
addConstraint1(param, bound, fromBelow) &&
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index a617f86d2..5976cf93b 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -550,6 +550,10 @@ object Types {
case _ => this
}
+ /** Widen from => T to T */
+ final def widenByName(implicit ctx: Context): Type =
+ if (this isRef defn.ByNameParamClass) this.typeArgs.head else this
+
/** Widen type if it is unstable (i.e. an EpxprType, or Termref to unstable symbol */
final def widenIfUnstable(implicit ctx: Context): Type = this match {
case tp: ExprType => tp.resultType.widenIfUnstable
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 857ff31ff..6f65cd231 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -360,7 +360,7 @@ trait Applications extends Compatibility { self: Typer =>
init()
def addArg(arg: Tree, formal: Type): Unit =
- typedArgBuf += adaptInterpolated(arg, formal)
+ typedArgBuf += adaptInterpolated(arg, formal.widenByName)
def makeVarArg(n: Int, elemFormal: Type): Unit = {
val args = typedArgBuf.takeRight(n).toList
@@ -411,7 +411,7 @@ trait Applications extends Compatibility { self: Typer =>
val result = {
var typedArgs = typedArgBuf.toList
- val ownType = ctx.traceIndented(i"apply $methRef to $typedArgs%, %", show = true) {
+ val ownType =
if (!success) ErrorType
else {
if (!sameSeq(args, orderedArgs)) {
@@ -426,7 +426,6 @@ trait Applications extends Compatibility { self: Typer =>
typedArgs = args.asInstanceOf[List[Tree]]
methodType.instantiate(typedArgs.tpes)
}
- }
wrapDefs(liftedDefs, cpy.Apply(app, normalizedFun, typedArgs).withType(ownType))
}
}
@@ -434,7 +433,7 @@ trait Applications extends Compatibility { self: Typer =>
/** Subclass of Application for type checking an Apply node with untyped arguments. */
class ApplyToUntyped(app: untpd.Apply, fun: Tree, methRef: TermRef, proto: FunProto, resultType: Type)(implicit ctx: Context)
extends TypedApply(app, fun, methRef, proto.args, resultType) {
- def typedArg(arg: untpd.Tree, formal: Type): TypedArg = proto.typedArg(arg, formal)
+ def typedArg(arg: untpd.Tree, formal: Type): TypedArg = proto.typedArg(arg, formal.widenByName)
def treeToArg(arg: Tree): untpd.Tree = untpd.TypedSplice(arg)
}
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 48b8bafe0..a6cbd58d1 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -263,13 +263,14 @@ trait Implicits { self: Typer =>
*/
def inferImplicit(pt: Type, argument: Tree, pos: Position)(implicit ctx: Context): SearchResult = track("inferImplicit") {
ctx.traceIndented(s"search implicit ${pt.show}, arg = ${argument.show}: ${argument.tpe.show}", show = true) {
+ assert(!(pt isRef defn.ByNameParamClass))
val isearch =
if (ctx.settings.explaintypes.value) new ExplainedImplicitSearch(pt, argument, pos)
else new ImplicitSearch(pt, argument, pos)
val result = isearch.bestImplicit
result match {
case success: SearchSuccess =>
- println(s"committing to ${success.tstate.show}")
+ // println(s"committing to ${success.tstate.show}")
success.tstate.commit()
case _ =>
}
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 4d418fe97..418bf44d1 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -29,11 +29,8 @@ object Inferencing {
* 2. `pt` is by name parameter type, and `tp` is compatible with its underlying type
* 3. there is an implicit conversion from `tp` to `pt`.
*/
- def isCompatible(tp: Type, pt: Type)(implicit ctx: Context): Boolean = {
- def skipByName(tp: Type): Type =
- if (tp isRef defn.ByNameParamClass) tp.typeArgs.head else tp
- skipByName(tp) <:< skipByName(pt) || viewExists(tp, pt)
- }
+ def isCompatible(tp: Type, pt: Type)(implicit ctx: Context): Boolean =
+ tp.widenByName <:< pt.widenByName || viewExists(tp, pt)
/** Test compatibility after normalization in a fresh typerstate */
def normalizedCompatible(tp: Type, pt: Type)(implicit ctx: Context) = {
@@ -313,18 +310,19 @@ object Inferencing {
val tp = tree.tpe.widen
val constraint = ctx.typerState.constraint
+ /* !!! DEBUG
println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}")
println(s"qualifying undet vars: ${constraint.uninstVars filter qualifies map (_.show)}")
println(s"fulltype: $tp") // !!! DEBUG
println(s"constraint: ${constraint.show}")
+ */
def qualifies(tvar: TypeVar) = tree contains tvar.owningTree
val vs = tp.variances(tvar => (constraint contains tvar) && qualifies(tvar))
- println(s"variances = $vs")
var changed = false
vs foreachBinding { (tvar, v) =>
if (v != 0) {
- println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}")
+ //println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}")
tvar.instantiate(fromBelow = v == 1)
changed = true
}
@@ -334,7 +332,7 @@ object Inferencing {
else
constraint.foreachUninstVar { tvar =>
if (!(vs contains tvar) && qualifies(tvar)) {
- println(s"instantiating non-occurring $tvar in $tp")
+ //println(s"instantiating non-occurring $tvar in $tp")
tvar.instantiate(fromBelow = true)
}
}
diff --git a/tests/pos/Patterns.scala b/tests/pos/Patterns.scala
index 1161e352b..fbcdc4c30 100644
--- a/tests/pos/Patterns.scala
+++ b/tests/pos/Patterns.scala
@@ -15,5 +15,18 @@ object Patterns {
case Nil => 0
case x :: xs1 => x + sum(xs1)
}
-
+
+ def len[T](xs: List[T]): Int = xs match {
+ case _ :: xs1 => 1 + len(xs1)
+ case Nil => 0
+ }
+
+ final def sameLength[T](xs: List[T], ys: List[T]): Boolean = xs match {
+ case _ :: xs1 =>
+ ys match {
+ case _ :: ys1 => sameLength(xs1, ys1)
+ case _ => false
+ }
+ case _ => ys.isEmpty
+ }
} \ No newline at end of file