From acd28e3fd19eca41c624d5cb131e8d6c8de9a38a Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 10 Nov 2009 10:51:03 +0000 Subject: fixed comment for adjustTypeArgs --- .../scala/tools/nsc/typechecker/Implicits.scala | 4 +++- .../scala/tools/nsc/typechecker/Infer.scala | 21 ++++++++++++--------- 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 -- cgit v1.2.3