summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2014-10-04 11:32:36 +0200
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2014-10-04 11:32:36 +0200
commit7b2c3cb8bb0f5f96f3182f551eb82cb1c59d460c (patch)
tree19e6dd4ae9aa6e328bfb8b6daed4564365160b49 /src
parentc1492ac08e69e64e258ee9c5a0e5173165f4cba1 (diff)
parentee2b7d615be8e7d893b78d770cf68a95c8fa0621 (diff)
downloadscala-7b2c3cb8bb0f5f96f3182f551eb82cb1c59d460c.tar.gz
scala-7b2c3cb8bb0f5f96f3182f551eb82cb1c59d460c.tar.bz2
scala-7b2c3cb8bb0f5f96f3182f551eb82cb1c59d460c.zip
Merge pull request #3995 from retronym/ticket/8267
SI-8267 Avoid existentials after polymorphic overload resolution
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 422b940cd3..b498d9e667 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1100,7 +1100,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
adaptConstant(value)
case OverloadedType(pre, alts) if !mode.inFunMode => // (1)
inferExprAlternative(tree, pt)
- adapt(tree, mode, pt, original)
+ adaptAfterOverloadResolution(tree, mode, pt, original)
case NullaryMethodType(restpe) => // (2)
adapt(tree setType restpe, mode, pt, original)
case TypeRef(_, ByNameParamClass, arg :: Nil) if mode.inExprMode => // (2)
@@ -1133,6 +1133,12 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
}
+ // This just exists to help keep track of the spots where we have to adapt a tree after
+ // overload resolution. These proved hard to find during the fix for SI-8267.
+ def adaptAfterOverloadResolution(tree: Tree, mode: Mode, pt: Type = WildcardType, original: Tree = EmptyTree): Tree = {
+ adapt(tree, mode, pt, original)
+ }
+
def instantiate(tree: Tree, mode: Mode, pt: Type): Tree = {
inferExprInstance(tree, context.extractUndetparams(), pt)
adapt(tree, mode, pt)
@@ -3171,7 +3177,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (sym1 != NoSymbol) sym = sym1
}
if (sym == NoSymbol) fun
- else adapt(fun setSymbol sym setType pre.memberType(sym), mode.forFunMode, WildcardType)
+ else adaptAfterOverloadResolution(fun setSymbol sym setType pre.memberType(sym), mode.forFunMode)
} else fun
}
@@ -3216,7 +3222,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
setError(tree)
else {
inferMethodAlternative(fun, undetparams, argTpes, pt)
- doTypedApply(tree, adapt(fun, mode.forFunMode, WildcardType), args1, mode, pt)
+ doTypedApply(tree, adaptAfterOverloadResolution(fun, mode.forFunMode, WildcardType), args1, mode, pt)
}
}
handleOverloaded
@@ -3799,7 +3805,18 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
protected def typedTypeApply(tree: Tree, mode: Mode, fun: Tree, args: List[Tree]): Tree = fun.tpe match {
case OverloadedType(pre, alts) =>
inferPolyAlternatives(fun, mapList(args)(treeTpe))
- val tparams = fun.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree)
+
+ // SI-8267 `memberType` can introduce existentials *around* a PolyType/MethodType, see AsSeenFromMap#captureThis.
+ // If we had selected a non-overloaded symbol, `memberType` would have been called in `makeAccessible`
+ // and the resulting existential type would have been skolemized in `adapt` *before* we typechecked
+ // the enclosing type-/ value- application.
+ //
+ // However, if the selection is overloaded, we defer calling `memberType` until we can select a single
+ // alternative here. It is therefore necessary to skolemize the existential here.
+ //
+ val fun1 = adaptAfterOverloadResolution(fun, mode.forFunMode | TAPPmode)
+
+ val tparams = fun1.symbol.typeParams //@M TODO: fun.symbol.info.typeParams ? (as in typedAppliedTypeTree)
val args1 = if (sameLength(args, tparams)) {
//@M: in case TypeApply we can't check the kind-arities of the type arguments,
// as we don't know which alternative to choose... here we do
@@ -3813,7 +3830,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// ...actually this was looping anyway, see bug #278.
return TypedApplyWrongNumberOfTpeParametersError(fun, fun)
- typedTypeApply(tree, mode, fun, args1)
+ typedTypeApply(tree, mode, fun1, args1)
case SingleType(_, _) =>
typedTypeApply(tree, mode, fun setType fun.tpe.widen, args)
case PolyType(tparams, restpe) if tparams.nonEmpty =>