diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index a48aa77fe79f..eb1692e00a12 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -855,7 +855,7 @@ object Semantic: // init "fake" param fields for parameters of primary and secondary constructors def addParamsAsFields(args: List[Value], ref: Ref, ctorDef: DefDef) = val params = ctorDef.termParamss.flatten.map(_.symbol) - assert(args.size == params.size, "arguments = " + args.size + ", params = " + params.size) + assert(args.size == params.size, "arguments = " + args.size + ", params = " + params.size + ", ctor = " + ctor.show) for (param, value) <- params.zip(args) do ref.updateField(param, value) printer.println(param.show + " initialized with " + value) @@ -1663,9 +1663,14 @@ object Semantic: // term arguments to B. That can only be done in a concrete class. val tref = typeRefOf(klass.typeRef.baseType(mixin).typeConstructor) val ctor = tref.classSymbol.primaryConstructor - if ctor.exists then extendTrace(superParent) { - superCall(tref, ctor, Nil, tasks) - } + if ctor.exists then + // The parameter check of traits comes late in the mixin phase. + // To avoid crash we supply hot values for erroneous parent calls. + // See tests/neg/i16438.scala. + val args: List[ArgInfo] = ctor.info.paramInfoss.flatten.map(_ => ArgInfo(Hot, Trace.empty)) + extendTrace(superParent) { + superCall(tref, ctor, args, tasks) + } } // initialize super classes after outers are set diff --git a/tests/neg/i16438.scala b/tests/neg/i16438.scala new file mode 100644 index 000000000000..33873b13384b --- /dev/null +++ b/tests/neg/i16438.scala @@ -0,0 +1,4 @@ +// scalac: -Ysafe-init +trait ATrait(val string: String, val int: Int) +trait AnotherTrait( override val string: String, override val int: Int) extends ATrait +case class ACaseClass(override val string: String) extends AnotherTrait(string, 3) // error