Skip to content

Commit 36b02e0

Browse files
committed
Fix #8012: Disallow conversion to underspecified SAM type
We cannot write class C extends B[?] By the same token, we cannot do a SAM type conversion to B[?] since this would create code like the one above.
1 parent 83ab6c7 commit 36b02e0

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,15 +1100,16 @@ class Typer extends Namer
11001100
case SAMType(sam)
11011101
if !defn.isFunctionType(pt) && mt <:< sam =>
11021102
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
1103+
if isFullyDefined(pt, ForceDegree.all)
1104+
&& !pt.argInfos.exists(_.isInstanceOf[TypeBounds])
1105+
then
1106+
pt
1107+
else if pt.isRef(defn.PartialFunctionClass) then
1108+
// Replace the underspecified expected type by one based on the closure method type
1109+
defn.PartialFunctionOf(mt.firstParamTypes.head, mt.resultType)
1110+
else
1111+
ctx.error(ex"result type of lambda is an underspecified SAM type $pt", tree.sourcePos)
1112+
pt
11121113
if (pt.classSymbol.isOneOf(FinalOrSealed)) {
11131114
val offendingFlag = pt.classSymbol.flags & FinalOrSealed
11141115
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)