summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Infer.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-08-15 15:02:18 -0700
committerPaul Phillips <paulp@improving.org>2013-08-17 08:22:52 -0700
commit35122d6cda84bb2df69ca51c6b1b80e61693bf6f (patch)
treedfd4cc3b62e40917a154cebb4afb876c50c95aff /src/compiler/scala/tools/nsc/typechecker/Infer.scala
parent9672a80d08148e9f3223077bf96aaa4ddf17c599 (diff)
downloadscala-35122d6cda84bb2df69ca51c6b1b80e61693bf6f.tar.gz
scala-35122d6cda84bb2df69ca51c6b1b80e61693bf6f.tar.bz2
scala-35122d6cda84bb2df69ca51c6b1b80e61693bf6f.zip
Minor improvement in pattern typer inference.
This exploits the infrastructure developed for checking the checkability of type patterns to improve pattern type inference, which suffered from a similar deficit. There was a hack for SI-2486, the best I could manage at the time I wrote it; that is replaced with the principled approach.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Infer.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 8ca0d82e93..2f86e23415 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1227,7 +1227,6 @@ trait Infer extends Checkable {
val tpparams = freeTypeParamsOfTerms(pattp)
def ptMatchesPattp = pt matchesPattern pattp.widen
- def pattpMatchesPt = pattp matchesPattern pt
/* If we can absolutely rule out a match we can fail early.
* This is the case if the scrutinee has no unresolved type arguments
@@ -1237,9 +1236,15 @@ trait Infer extends Checkable {
IncompatibleScrutineeTypeError(tree0, pattp, pt)
return ErrorType
}
+ // This performs the "reverse" propagation of type information already used
+ // in pattern matcher checkability testing. See pos/t2486.scala for sample
+ // code which would not compile without such propagation.
+ def propagated = propagateKnownTypes(pt, pattp.widen.typeSymbol)
- checkCheckable(tree0, pattp, pt, inPattern = true, canRemedy)
+ checkCheckable(tree0, pattp, pt0, inPattern = true, canRemedy)
if (pattp <:< pt) ()
+ else if (pattp <:< propagated)
+ log(s"!($pattp <:< $pt), but after propagateKnownTypes we find ($pattp <:< $propagated) - pattern inference improved")
else {
debuglog("free type params (1) = " + tpparams)
@@ -1256,9 +1261,7 @@ trait Infer extends Checkable {
val ptvars = ptparams map freshVar
val pt1 = pt.instantiateTypeParams(ptparams, ptvars)
- // See ticket #2486 for an example of code which would incorrectly
- // fail if we didn't allow for pattpMatchesPt.
- if (isPopulated(tp, pt1) && isInstantiatable(tvars ++ ptvars) || pattpMatchesPt)
+ if (isPopulated(tp, pt1) && isInstantiatable(tvars ++ ptvars))
ptvars foreach instantiateTypeVar
else {
PatternTypeIncompatibleWithPtError1(tree0, pattp, pt)
@@ -1311,10 +1314,10 @@ trait Infer extends Checkable {
// properly, we can avoid it by ignoring type parameters which
// have type constructors amongst their bounds. See SI-4070.
def isFreeTypeParamOfTerm(sym: Symbol) = (
- sym.isAbstractType
- && sym.owner.isTerm
- && !sym.info.bounds.exists(_.typeParams.nonEmpty)
- )
+ sym.isAbstractType
+ && sym.owner.isTerm
+ && !sym.info.bounds.exists(_.typeParams.nonEmpty)
+ )
// Intentionally *not* using `Type#typeSymbol` here, which would normalize `tp`
// and collect symbols from the result type of any resulting `PolyType`s, which