diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala index 63bac2fb0f2a..979546d0bbe1 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala @@ -59,8 +59,12 @@ class ExpandSAMs extends MiniPhase: case tpe => val tpe1 = checkRefinements(tpe.stripNull, fn) val Seq(samDenot) = tpe1.possibleSamMethods - cpy.Block(tree)(stats, - AnonClass(tpe1 :: Nil, fn.symbol.asTerm :: Nil, samDenot.symbol.asTerm.name :: Nil)) + if hasNoArgConstr(tpe1) then + cpy.Block(tree)(stats, + AnonClass(tpe1 :: Nil, fn.symbol.asTerm :: Nil, samDenot.symbol.asTerm.name :: Nil)) + else + report.error(em"${tpe1} cannot be instantiated with an empty constructor", tree.srcPos) + tree } case _ => tree @@ -182,4 +186,18 @@ class ExpandSAMs extends MiniPhase: case tpe => tpe } + + private def hasNoArgConstr(tpe: Type)(using Context): Boolean = { + def noArgs(ctpe: Type): Boolean = ctpe match { + case ctpe: PolyType => + noArgs(ctpe.resType) + case ctpe: MethodType => + ctpe.paramInfos.isEmpty + case _ => + false + } + val parent :: _ = tpe.parents: @unchecked + val constr = parent.dealias.decl(nme.CONSTRUCTOR).suchThat(constr => noArgs(constr.info)) + constr != SymDenotations.NoDenotation + } end ExpandSAMs diff --git a/tests/neg/i15855.scala b/tests/neg/i15855.scala new file mode 100644 index 000000000000..504a21b4a5a2 --- /dev/null +++ b/tests/neg/i15855.scala @@ -0,0 +1,56 @@ +class MyFunction(arg: String) { + def a: String = arg +} + +trait MyFun[+R] extends MyFunction { + def apply(i: Int): R +} + +val myFun: MyFun[Int] = (i: Int) => 1 // error + +// + +class MyFunction1(arg: String = "") { + def a: String = arg +} + +trait MyFun1[+R] extends MyFunction1 { + def apply(i: Int): R +} + +val myFun1: MyFun1[Int] = (i: Int) => 1 // error + +// + +trait MyFunction2(arg: String = "") { + def a: String = arg +} + +trait MyFun2[+R] extends MyFunction2 { + def apply(i: Int): R +} + +val myFun2: MyFun2[Int] = (i: Int) => 1 + +// + +trait MyFunction3(arg: String) { + def a: String = arg +} + +trait MyFun3[+R] extends MyFunction3 { + def apply(i: Int): R +} + +val myFun3: MyFun3[Int] = (i: Int) => 1 + +// + +class MyFunction4() { +} + +trait MyFun4[+R] extends MyFunction4 { + def apply(i: Int): R +} + +val myFun4: MyFun4[Int] = (i: Int) => 1