Permalink
Browse files

SI-7345 Factor out method to clear and restore undetparams.

Also refactored `handleOverloaded` to avoid use of a mutable Buffer
  • Loading branch information...
1 parent 0ce81c8 commit e112db6fc4afe0a7721ec87423eacd405fa6c89b @retronym retronym committed Apr 16, 2013
View
14 src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -262,6 +262,20 @@ trait Contexts { self: Analyzer =>
tparams
}
+ /** Run `body` with this context with no undetermined type parameters, restore the original
+ * the original list afterwards.
+ * @param reportAmbiguous Should ambiguous errors be reported during evaluation of `body`?
+ */
+ def savingUndeterminedTypeParams[A](reportAmbiguous: Boolean = ambiguousErrors)(body: => A): A = {
+ withMode() {
+ this(AmbiguousErrors) = reportAmbiguous
+ val savedParams = extractUndetparams()
+ try body
+ finally {
+ undetparams = savedParams
+ }
+ }
+ }
//
// Error reporting policies and buffer.
//
View
18 src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -451,21 +451,6 @@ trait NamesDefaults { self: Analyzer =>
} else NoSymbol
}
- // TODO SI-7345 Use a method in Context for this.
- private def savingUndeterminedTParams[T](context: Context)(fn: List[Symbol] => T): T = {
- val savedParams = context.extractUndetparams()
- val savedReporting = context.ambiguousErrors
-
- context.setAmbiguousErrors(false)
- try fn(savedParams)
- finally {
- context.setAmbiguousErrors(savedReporting)
- //@M note that we don't get here when an ambiguity was detected (during the computation of res),
- // as errorTree throws an exception
- context.undetparams = savedParams
- }
- }
-
/** A full type check is very expensive; let's make sure there's a name
* somewhere which could potentially be ambiguous before we go that route.
*/
@@ -480,7 +465,8 @@ trait NamesDefaults { self: Analyzer =>
// def f[T](x: T) = x
// var x = 0
// f(x = 1) << "x = 1" typechecks with expected type WildcardType
- savingUndeterminedTParams(context) { udp =>
+ val udp = context.undetparams
+ context.savingUndeterminedTypeParams(reportAmbiguous = false) {
val subst = new SubstTypeMap(udp, udp map (_ => WildcardType)) {
override def apply(tp: Type): Type = super.apply(tp match {
case TypeRef(_, ByNameParamClass, x :: Nil) => x
View
39 src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3090,30 +3090,29 @@ trait Typers extends Adaptations with Tags {
fun.tpe match {
case OverloadedType(pre, alts) =>
def handleOverloaded = {
- val undetparams = context.extractUndetparams()
- val argtpes = new ListBuffer[Type]
- val amode = forArgMode(fun, mode)
- val args1 = args map {
- case arg @ AssignOrNamedArg(Ident(name), rhs) =>
- // named args: only type the righthand sides ("unknown identifier" errors otherwise)
- val rhs1 = typedArg(rhs, amode, BYVALmode, WildcardType)
- argtpes += NamedType(name, rhs1.tpe.deconst)
- // the assign is untyped; that's ok because we call doTypedApply
- treeCopy.AssignOrNamedArg(arg, arg.lhs, rhs1)
- case arg @ Typed(repeated, Ident(tpnme.WILDCARD_STAR)) =>
- val arg1 = typedArg(arg, amode, BYVALmode, WildcardType)
- argtpes += RepeatedType(arg1.tpe.deconst)
- arg1
- case arg =>
- val arg1 = typedArg(arg, amode, BYVALmode, WildcardType)
- argtpes += arg1.tpe.deconst
- arg1
+ val undetparams = context.undetparams
+ val (args1, argTpes) = context.savingUndeterminedTypeParams() {
+ val amode = forArgMode(fun, mode)
+ def typedArg0(tree: Tree) = typedArg(tree, amode, BYVALmode, WildcardType)
+ args.map {
+ case arg @ AssignOrNamedArg(Ident(name), rhs) =>
+ // named args: only type the righthand sides ("unknown identifier" errors otherwise)
+ val rhs1 = typedArg0(rhs)
+ // the assign is untyped; that's ok because we call doTypedApply
+ val arg1 = treeCopy.AssignOrNamedArg(arg, arg.lhs, rhs1)
+ (arg1, NamedType(name, rhs1.tpe.deconst))
+ case arg @ Typed(repeated, Ident(tpnme.WILDCARD_STAR)) =>
+ val arg1 = typedArg0(arg)
+ (arg1, RepeatedType(arg1.tpe.deconst))
+ case arg =>
+ val arg1 = typedArg0(arg)
+ (arg1, arg1.tpe.deconst)
+ }.unzip
}
- context.undetparams = undetparams
if (context.hasErrors)
setError(tree)
else {
- inferMethodAlternative(fun, undetparams, argtpes.toList, pt)
+ inferMethodAlternative(fun, undetparams, argTpes, pt)
doTypedApply(tree, adapt(fun, mode.forFunMode, WildcardType), args1, mode, pt)
}
}

0 comments on commit e112db6

Please sign in to comment.