diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-03-09 15:30:05 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-03-09 18:57:22 +0100 |
commit | 83c9c764b528a7a1c1d39c480d22c8e3a71d5a58 (patch) | |
tree | 484277f12fd7aefd287e6ca2dd39441ca5adbac2 | |
parent | 889020dfab9f99a3198528fedb699c061027acab (diff) | |
download | scala-83c9c764b528a7a1c1d39c480d22c8e3a71d5a58.tar.gz scala-83c9c764b528a7a1c1d39c480d22c8e3a71d5a58.tar.bz2 scala-83c9c764b528a7a1c1d39c480d22c8e3a71d5a58.zip |
SI-7234 Make named args play nice with dep. method types
Some care is needed to avoid interaction with constant
types (e.g pos/z1730.scala) and with existentials
(e.g. t3507-old.scala).
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 17 | ||||
-rw-r--r-- | test/files/pos/t7234.scala | 15 | ||||
-rw-r--r-- | test/files/pos/t7234b.scala | 20 |
3 files changed, 45 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 2340c78f8c..525a67a923 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -273,22 +273,25 @@ trait NamesDefaults { self: Analyzer => */ def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[Option[ValDef]] = { val context = blockTyper.context - val symPs = map2(args, paramTypes)((arg, tpe) => arg match { + val symPs = map2(args, paramTypes)((arg, paramTpe) => arg match { case Ident(nme.SELECTOR_DUMMY) => None // don't create a local ValDef if the argument is <unapply-selector> case _ => - val byName = isByNameParamType(tpe) - val repeated = isScalaRepeatedParamType(tpe) + val byName = isByNameParamType(paramTpe) + val repeated = isScalaRepeatedParamType(paramTpe) val argTpe = ( if (repeated) arg match { case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe case _ => seqType(arg.tpe) } - else arg.tpe - ).widen // have to widen or types inferred from literal defaults will be singletons + else + // Note stabilizing can lead to a non-conformant argument when existentials are involved, e.g. neg/t3507-old.scala, hence the filter. + // 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 - ) + if (byName) functionType(Nil, argTpe) else argTpe + ) Some((context.scope.enter(s), byName, repeated)) }) map2(symPs, args) { diff --git a/test/files/pos/t7234.scala b/test/files/pos/t7234.scala new file mode 100644 index 0000000000..59a233d835 --- /dev/null +++ b/test/files/pos/t7234.scala @@ -0,0 +1,15 @@ +trait Main { + trait A { + type B + } + trait C { + def c(a: A, x: Int = 0)(b: a.B) + } + def c: C + def d(a: A, x: Int = 0)(b: a.B) + + def ok1(a: A)(b: a.B) = c.c(a, 42)(b) + def ok2(a: A)(b: a.B) = d(a)(b) + + def fail(a: A)(b: a.B) = c.c(a)(b) +} diff --git a/test/files/pos/t7234b.scala b/test/files/pos/t7234b.scala new file mode 100644 index 0000000000..fee98e87a8 --- /dev/null +++ b/test/files/pos/t7234b.scala @@ -0,0 +1,20 @@ +trait Main { + trait A { + type B + def b: B + } + trait C { + def c(a: A, x: Int = 0)(b: => a.B, bs: a.B*) + def d(a: A = null, x: Int = 0)(b1: => a.B = a.b, b2: a.B = a.b) + } + def c: C + def ok(a: A)(b: a.B) = c.c(a, 42)(b) + def fail(a: A)(b: a.B) = c.c(a)(b) + def fail2(a: A)(b: a.B) = c.c(a)(b, b) + def fail3(a: A)(b: a.B) = c.c(a)(b, Seq[a.B](b): _*) + + def fail4(a: A)(b: a.B) = c.d(a)() + def fail5(a: A)(b: a.B) = c.d(a)(b1 = a.b) + def fail6(a: A)(b: a.B) = c.d(a)(b2 = a.b) + def fail7(a: A)(b: a.B) = c.d()() +} |