diff options
author | Martin Odersky <odersky@gmail.com> | 2016-04-21 15:32:31 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-04-21 15:32:37 +0200 |
commit | 2460f9603b0f0ed1d73dfea99edcee9ba6261d36 (patch) | |
tree | ff9664d323adac7a8d882ba04b8a26590db3dfe2 | |
parent | 0514d0efcdf159ea0ffdb51ac1e9a59d3ee429c0 (diff) | |
download | dotty-2460f9603b0f0ed1d73dfea99edcee9ba6261d36.tar.gz dotty-2460f9603b0f0ed1d73dfea99edcee9ba6261d36.tar.bz2 dotty-2460f9603b0f0ed1d73dfea99edcee9ba6261d36.zip |
Always minimize type variables when interpolating an expected type of an implicit.
This was suggested in #878.
-rw-r--r-- | src/dotty/tools/dotc/transform/PatternMatcher.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 13 |
2 files changed, 8 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index 35e772cd1..740fd5460 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -1611,7 +1611,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans // (otherwise equality is required) def compareOp: (Tree, Tree) => Tree = if (aligner.isStar) _.select(defn.Int_>=).appliedTo(_) - else _.select(defn.Int_==).appliedTo(_) + else _.select(defn.Int_==).appliedTo(_) // `if (binder != null && $checkExpectedLength [== | >=] 0) then else zero` (seqTree(binder).select(defn.Any_!=).appliedTo(Literal(Constant(null)))).select(defn.Boolean_&&).appliedTo(compareOp(checkExpectedLength, Literal(Constant(0)))) diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 99e8cd150..b3968f7c3 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -46,7 +46,7 @@ object Inferencing { /** Instantiate selected type variables `tvars` in type `tp` */ def instantiateSelected(tp: Type, tvars: List[Type])(implicit ctx: Context): Unit = - new IsFullyDefinedAccumulator(new ForceDegree.Value(tvars.contains)).process(tp) + new IsFullyDefinedAccumulator(new ForceDegree.Value(tvars.contains, minimizeAll = true)).process(tp) /** The accumulator which forces type variables using the policy encoded in `force` * and returns whether the type is fully defined. The direction in which @@ -81,11 +81,12 @@ object Inferencing { force.appliesTo(tvar) && { val direction = instDirection(tvar.origin) if (direction != 0) { - //if (direction > 0) println(s"inst $tvar dir = up") + if (direction > 0) println(s"inst $tvar dir = up") instantiate(tvar, direction < 0) } else { val minimize = + force.minimizeAll || variance >= 0 && !( force == ForceDegree.noBottom && defn.isBottomType(ctx.typeComparer.approximation(tvar.origin, fromBelow = true))) @@ -293,9 +294,9 @@ object Inferencing { /** An enumeration controlling the degree of forcing in "is-dully-defined" checks. */ @sharable object ForceDegree { - class Value(val appliesTo: TypeVar => Boolean) - val none = new Value(_ => false) - val all = new Value(_ => true) - val noBottom = new Value(_ => true) + class Value(val appliesTo: TypeVar => Boolean, val minimizeAll: Boolean) + val none = new Value(_ => false, minimizeAll = false) + val all = new Value(_ => true, minimizeAll = false) + val noBottom = new Value(_ => true, minimizeAll = false) } |