diff options
author | Paul Phillips <paulp@improving.org> | 2011-07-28 22:26:57 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-07-28 22:26:57 +0000 |
commit | 5bbb198b246f43b80dba8f4466862b2ca8b9a9cb (patch) | |
tree | 0fbe11c29eb9e14f32a5fb6cb5d154a762b29b7a /src | |
parent | cee5d977cbc2fff7c919a2d3026b81bd23120d9d (diff) | |
download | scala-5bbb198b246f43b80dba8f4466862b2ca8b9a9cb.tar.gz scala-5bbb198b246f43b80dba8f4466862b2ca8b9a9cb.tar.bz2 scala-5bbb198b246f43b80dba8f4466862b2ca8b9a9cb.zip |
Expression type argument instantiation should n...
Expression type argument instantiation should not fail in a context
expecting Unit if there is any valid instantiation, because value
discarding should kick in and offer a literal (). Closes SI-4853, review
by odersky.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 185529ed74..13e0f13d4c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -882,7 +882,10 @@ trait Typers extends Modes { typed(atPos(tree.pos)(Select(qual, nme.apply)), mode, pt) } else if (!context.undetparams.isEmpty && !inPolyMode(mode)) { // (9) assert(!inHKMode(mode)) //@M - instantiate(tree, mode, pt) + if ((mode & (EXPRmode | FUNmode)) == EXPRmode && (pt.typeSymbol == UnitClass)) + instantiateExpectingUnit(tree, mode) + else + instantiate(tree, mode, pt) } else if (tree.tpe <:< pt) { tree } else { @@ -969,16 +972,24 @@ trait Typers extends Modes { } } - /** - * @param tree ... - * @param mode ... - * @param pt ... - * @return ... - */ def instantiate(tree: Tree, mode: Int, pt: Type): Tree = { inferExprInstance(tree, context.extractUndetparams(), pt) adapt(tree, mode, pt) } + /** If the expected type is Unit: try instantiating type arguments + * with expected type Unit, but if that fails, try again with pt = WildcardType + * and discard the expression. + */ + def instantiateExpectingUnit(tree: Tree, mode: Int): Tree = { + val savedUndetparams = context.undetparams + silent(_.instantiate(tree, mode, UnitClass.tpe)) match { + case t: Tree => t + case _ => + context.undetparams = savedUndetparams + val valueDiscard = atPos(tree.pos)(Block(List(instantiate(tree, mode, WildcardType)), Literal(()))) + typed(valueDiscard, mode, UnitClass.tpe) + } + } def adaptToMember(qual: Tree, searchTemplate: Type): Tree = { var qtpe = qual.tpe.widen |