From 83c9c764b528a7a1c1d39c480d22c8e3a71d5a58 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 9 Mar 2013 15:30:05 +0100 Subject: 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). --- .../scala/tools/nsc/typechecker/NamesDefaults.scala | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 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 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 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) { -- cgit v1.2.3 From 745c36a3289d9d5a9078ee07dc4f7187e1cb2fc3 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 9 Mar 2013 17:20:47 +0100 Subject: SI-7328 Bail out of names/defaults if args are error typed To avoid a crasher later on with a null type inside a sequence argument. --- src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 6 +++--- test/files/neg/t7238.check | 6 ++++++ test/files/neg/t7238.scala | 7 +++++++ 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 test/files/neg/t7238.check create mode 100644 test/files/neg/t7238.scala (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 2340c78f8c..d284be13bc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -329,11 +329,10 @@ trait NamesDefaults { self: Analyzer => // type the application without names; put the arguments in definition-site order val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt) - if (typedApp.isErrorTyped) tree - else typedApp match { + typedApp match { // Extract the typed arguments, restore the call-site evaluation order (using // ValDef's in the block), change the arguments to these local values. - case Apply(expr, typedArgs) => + case Apply(expr, typedArgs) if !(typedApp :: typedArgs).exists(_.isErrorTyped) => // bail out with erroneous args, see SI-7238 // typedArgs: definition-site order val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) // valDefs: call-site order @@ -361,6 +360,7 @@ trait NamesDefaults { self: Analyzer => context.namedApplyBlockInfo = Some((block, NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper))) block + case _ => tree } } diff --git a/test/files/neg/t7238.check b/test/files/neg/t7238.check new file mode 100644 index 0000000000..b87f83ff65 --- /dev/null +++ b/test/files/neg/t7238.check @@ -0,0 +1,6 @@ +t7238.scala:6: error: type mismatch; + found : Seq[Any] + required: Seq[String] + c.c()(Seq[Any](): _*) + ^ +one error found diff --git a/test/files/neg/t7238.scala b/test/files/neg/t7238.scala new file mode 100644 index 0000000000..d42dc8d385 --- /dev/null +++ b/test/files/neg/t7238.scala @@ -0,0 +1,7 @@ +trait Main { + trait C { + def c(x: Any = 0)(bs: String*) + } + def c: C + c.c()(Seq[Any](): _*) +} -- cgit v1.2.3