summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-07-28 22:26:57 +0000
committerPaul Phillips <paulp@improving.org>2011-07-28 22:26:57 +0000
commit5bbb198b246f43b80dba8f4466862b2ca8b9a9cb (patch)
tree0fbe11c29eb9e14f32a5fb6cb5d154a762b29b7a /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parentcee5d977cbc2fff7c919a2d3026b81bd23120d9d (diff)
downloadscala-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/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala25
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