Skip to content

Commit b120130

Browse files
authored
Merge pull request #8013 from dotty-staging/fix-#8012
Fix #8012: Disallow conversion to underspecified SAM type
2 parents 9ab1842 + 28ac0e4 commit b120130

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,16 +1099,20 @@ class Typer extends Namer
10991099
pt match {
11001100
case SAMType(sam)
11011101
if !defn.isFunctionType(pt) && mt <:< sam =>
1102+
// SAMs of the form C[?] where C is a class cannot be conversion targets.
1103+
// The resulting class `class $anon extends C[?] {...}` would be illegal,
1104+
// since type arguments to `C`'s super constructor cannot be constructed.
1105+
def isWildcardClassSAM =
1106+
!pt.classSymbol.is(Trait) && pt.argInfos.exists(_.isInstanceOf[TypeBounds])
11021107
val targetTpe =
1103-
if (!isFullyDefined(pt, ForceDegree.all))
1104-
if (pt.isRef(defn.PartialFunctionClass))
1105-
// Replace the underspecified expected type by one based on the closure method type
1106-
defn.PartialFunctionOf(mt.firstParamTypes.head, mt.resultType)
1107-
else {
1108-
ctx.error(ex"result type of lambda is an underspecified SAM type $pt", tree.sourcePos)
1109-
pt
1110-
}
1111-
else pt
1108+
if isFullyDefined(pt, ForceDegree.all) && !isWildcardClassSAM then
1109+
pt
1110+
else if pt.isRef(defn.PartialFunctionClass) then
1111+
// Replace the underspecified expected type by one based on the closure method type
1112+
defn.PartialFunctionOf(mt.firstParamTypes.head, mt.resultType)
1113+
else
1114+
ctx.error(ex"result type of lambda is an underspecified SAM type $pt", tree.sourcePos)
1115+
pt
11121116
if (pt.classSymbol.isOneOf(FinalOrSealed)) {
11131117
val offendingFlag = pt.classSymbol.flags & FinalOrSealed
11141118
ctx.error(ex"lambda cannot implement $offendingFlag ${pt.classSymbol}", tree.sourcePos)

tests/neg/i8012.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
3+
@FunctionalInterface
4+
abstract class Q[A] {
5+
def apply(a: A): Int
6+
}
7+
8+
class C extends Q[?] // error: Type argument must be fully defined
9+
10+
object O {
11+
def m(i: Int): Int = i
12+
val x: Q[_] = m // error: result type of lambda is an underspecified SAM type Q[?]
13+
}

0 commit comments

Comments
 (0)