summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2009-11-10 10:51:03 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2009-11-10 10:51:03 +0000
commitacd28e3fd19eca41c624d5cb131e8d6c8de9a38a (patch)
tree4460a9e00e8b1226bd33eb0758e6d4659b0c77ba
parenteea79567f1a02299f714daec11faf008d40648bd (diff)
downloadscala-acd28e3fd19eca41c624d5cb131e8d6c8de9a38a.tar.gz
scala-acd28e3fd19eca41c624d5cb131e8d6c8de9a38a.tar.bz2
scala-acd28e3fd19eca41c624d5cb131e8d6c8de9a38a.zip
fixed comment for adjustTypeArgs
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala21
2 files changed, 15 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index fddb02cd71..6bbacfa311 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -433,8 +433,10 @@ self: Analyzer =>
checkBounds(itree2.pos, NoPrefix, NoSymbol, undetParams, targs, "inferred ") // #2421
// filter out failures from type inference, don't want to remove them from undetParams!
+ // we must be conservative in leaving type params in undetparams
val uninstantiated = new ListBuffer[Symbol]
- val detargs = adjustTypeArgs(undetParams, targs, WildcardType, uninstantiated) // TODO: WildcardType should be pt, need to fix adjustTypeArgs first
+ val detargs = adjustTypeArgs(undetParams, targs, WildcardType, uninstantiated) // prototype == WildcardType: want to remove all inferred Nothing's
+ // even if Nothing was inferred correctly, it's okay to ignore it (if it was the only solution, we'll infer it again next time)
val (okParams, okArgs) = (undetParams zip detargs) filter {case (p, a) => !uninstantiated.contains(p)} unzip
// TODO: optimise above line(s?) once `zipped filter` works (oh, the irony! this line is needed to get Zipped to type check...)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 2313f166f7..8ed799ed60 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -583,19 +583,22 @@ trait Infer {
tvars map (tvar => WildcardType)
}
- /** Retract any Nothing arguments which appear covariantly in result type,
- * and treat them as uninstantiated parameters instead.
- * Map T* entries to Seq[T].
+ /** Retract arguments that were inferred to Nothing because inference failed. Correct types for repeated params.
+ *
+ * We detect Nothing-due-to-failure by only retracting a parameter if either:
+ * - it occurs in an invariant/contravariant position in `restpe`
+ * - `restpe == WildcardType`
+ *
+ * Retracted parameters are collected in `uninstantiated`.
+ *
+ * Rewrite for repeated param types: Map T* entries to Seq[T].
*/
def adjustTypeArgs(tparams: List[Symbol], targs: List[Type], restpe: Type, uninstantiated: ListBuffer[Symbol]): List[Type] = {
- @inline def covariant/*OrNotContained*/(variance: Int) =
- ((variance & COVARIANT) == 0)/* || // tparam occurred covariantly
- (variance == VARIANCES) // tparam did not occur */ // TODO: fix
+ @inline def notCovariantIn(tparam: Symbol, restpe: Type) =
+ (varianceInType(restpe)(tparam) & COVARIANT) == 0 // tparam occurred non-covariantly (in invariant or contravariant position)
List.map2(tparams, targs) {(tparam, targ) =>
- if (targ.typeSymbol == NothingClass &&
- ( restpe == WildcardType
- || covariant/*OrNotContained*/(varianceInType(restpe)(tparam)))) {
+ if (targ.typeSymbol == NothingClass && (restpe == WildcardType || notCovariantIn(tparam, restpe))) {
uninstantiated += tparam
tparam.tpeHK //@M tparam.tpe was wrong: we only want the type constructor,
// not the type constructor applied to dummy arguments