diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index fc0e2c7c803..f954ec21ad0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -481,7 +481,7 @@ trait Infer extends Checkable { else if (targ.typeSymbol == JavaRepeatedParamClass) targ.baseType(ArrayClass) // this infers Foo.type instead of "object Foo" (see also widenIfNecessary) else if (targ.typeSymbol.isModuleClass || tvar.constr.avoidWiden) targ - else targ.widen + else targ.deconst.widen ) )) } @@ -533,7 +533,7 @@ trait Infer extends Checkable { // Then define remaining type variables from argument types. map2(argtpes, formals) { (argtpe, formal) => - val tp1 = argtpe.deconst.instantiateTypeParams(tparams, tvars) + val tp1 = argtpe.instantiateTypeParams(tparams, tvars) val pt1 = formal.instantiateTypeParams(tparams, tvars) // Note that isCompatible side-effects: subtype checks involving typevars @@ -975,7 +975,7 @@ trait Infer extends Checkable { try { val pt = if (pt0.typeSymbol == UnitClass) WildcardType else pt0 val formals = formalTypes(mt.paramTypes, args.length) - val argtpes = tupleIfNecessary(formals, args map (x => elimAnonymousClass(x.tpe.deconst))) + val argtpes = tupleIfNecessary(formals, args map (x => elimAnonymousClass(x.tpe))) val restpe = fn.tpe.resultType(argtpes) val AdjustedTypeArgs.AllArgsAndUndets(okparams, okargs, allargs, leftUndet) = diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index f26315c5389..e585eede065 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2781,18 +2781,24 @@ trait Types * See SI-5359. */ val bounds = tparam.info.bounds + /* We can seed the type constraint with the type parameter * bounds as long as the types are concrete. This should lower * the complexity of the search even if it doesn't improve * any results. */ - if (propagateParameterBoundsToTypeVars) { - val exclude = bounds.isEmptyBounds || (bounds exists typeIsNonClassType) + val constr = + if (propagateParameterBoundsToTypeVars) { + val exclude = bounds.isEmptyBounds || (bounds exists typeIsNonClassType) - if (exclude) new TypeConstraint - else TypeVar.trace("constraint", "For " + tparam.fullLocationString)(new TypeConstraint(bounds)) - } - else new TypeConstraint + if (exclude) new TypeConstraint + else TypeVar.trace("constraint", "For " + tparam.fullLocationString)(new TypeConstraint(bounds)) + } + else new TypeConstraint + + if (bounds.hi.contains(SingletonClass)) constr.stopWidening() + + constr } def untouchable(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = true) def apply(tparam: Symbol): TypeVar = createTypeVar(tparam, untouchable = false) diff --git a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala index c1c43178e51..9071d6ce5cb 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala @@ -93,6 +93,7 @@ private[internal] trait TypeConstraints { def loBounds: List[Type] = if (numlo == NoType) lobounds else numlo :: lobounds def hiBounds: List[Type] = if (numhi == NoType) hibounds else numhi :: hibounds def avoidWiden: Boolean = avoidWidening + def stopWidening(): Unit = avoidWidening = true def addLoBound(tp: Type, isNumericBound: Boolean = false) { // For some reason which is still a bit fuzzy, we must let Nothing through as @@ -117,9 +118,9 @@ private[internal] trait TypeConstraints { } def checkWidening(tp: Type) { - if(tp.isStable) avoidWidening = true + if(tp.isStable) stopWidening() else tp match { - case HasTypeMember(_, _) => avoidWidening = true + case HasTypeMember(_, _) => stopWidening() case _ => } }