From 5724cae9efe168094f5f3d176f2606b9c43de6dc Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 10 Aug 2013 09:29:58 +0200 Subject: SI-7694 @uncheckedBounds, an opt-out from type bounds checking Synthetic defs introduced by transforms like named/default arguments, ANF (in scala-async) often introduce a type tree (the tpt of the temporary) that are based on the types of expressions. These types are scrutinized in RefChecks to check that type parameter bounds are satisfied. However, the type of the expression might be based on slack a LUB that fails to capture constraints between type parameters. This slackness is noted in `mergePrefixAndArgs`: // Martin: I removed this, because incomplete. Not sure there is a // good way to fix it. For the moment we just err on the conservative // side, i.e. with a bound that is too high. The synthesizer can now opt out of bounds by annotating the type as follows: val temp: ( @uncheckedBounds) = expr This facility is now used in named/default arguments for the temporaries used for the reciever and arguments. The annotation is hidden under scala.reflect.internal, rather than in the more prominent scala.annotation.unchecked, to reflect the intention that it should only be used in tree transformers. The library component of this change and test case will be included in the next commit. Why split like this? It shows that the 2.10.3 compiler will work with 2.10.2 scala-reflect.jar. --- src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala') diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index f3736f1519..bd2cac81ea 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -164,7 +164,7 @@ trait NamesDefaults { self: Analyzer => // never used for constructor calls, they always have a stable qualifier def blockWithQualifier(qual: Tree, selected: Name) = { - val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo qual.tpe + val sym = blockTyper.context.owner.newValue(unit.freshTermName("qual$"), qual.pos) setInfo uncheckedBounds(qual.tpe) blockTyper.context.scope enter sym val vd = atPos(sym.pos)(ValDef(sym, qual) setType NoType) // it stays in Vegas: SI-5720, SI-5727 @@ -289,9 +289,10 @@ trait NamesDefaults { self: Analyzer => // We have to deconst or types inferred from literal arguments will be Constant(_), e.g. pos/z1730.scala. gen.stableTypeFor(arg).filter(_ <:< paramTpe).getOrElse(arg.tpe).deconst ) - val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos) setInfo ( - if (byName) functionType(Nil, argTpe) else argTpe - ) + val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos) setInfo { + val tp = if (byName) functionType(Nil, argTpe) else argTpe + uncheckedBounds(tp) + } Some((context.scope.enter(s), byName, repeated)) }) map2(symPs, args) { -- cgit v1.2.3