Skip to content

Commit 3029908

Browse files
committed
SAM types cannot be sealed or final
Previously we caught this in Typer, but doing it in the `SAMType` extractor is more robust because it is used in overloading resolution, and this will be needed in a subsequent commit of this PR to avoid selecting the wrong overload in some cases. This required dropping the final flag from the compiler-generated ContextFunctionN, instead we explicitly prevent subclasses in RefChecks.
1 parent f3c1468 commit 3029908

File tree

6 files changed

+13
-9
lines changed

6 files changed

+13
-9
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,7 @@ class Definitions {
133133
ClassInfo(ScalaPackageClass.thisType, cls, ObjectType :: Nil, decls)
134134
}
135135
}
136-
val flags0 = Trait | NoInits
137-
val flags = if (name.isContextFunction) flags0 | Final else flags0
136+
val flags = Trait | NoInits
138137
newPermanentClassSymbol(ScalaPackageClass, name, flags, completer)
139138
}
140139

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5043,7 +5043,7 @@ object Types {
50435043
NoType
50445044
}
50455045
def isInstantiatable(tp: Type)(using Context): Boolean = zeroParamClass(tp) match {
5046-
case cinfo: ClassInfo =>
5046+
case cinfo: ClassInfo if !cinfo.cls.isOneOf(FinalOrSealed) =>
50475047
val selfType = cinfo.selfType.asSeenFrom(tp, cinfo.cls)
50485048
tp <:< selfType
50495049
case _ =>

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
173173
CaseClassInInlinedCodeID,
174174
OverrideTypeMismatchErrorID,
175175
OverrideErrorID,
176-
MatchableWarningID
176+
MatchableWarningID,
177+
CannotExtendFunctionID
177178

178179
def errorNumber = ordinal - 2
179180
}

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,6 +1558,12 @@ import transform.SymUtils._
15581558
def explain = ""
15591559
}
15601560

1561+
class CannotExtendContextFunction(sym: Symbol)(using Context)
1562+
extends SyntaxMsg(CannotExtendFunctionID) {
1563+
def msg = em"""$sym cannot extend a context function class"""
1564+
def explain = ""
1565+
}
1566+
15611567
class JavaEnumParentArgs(parent: Type)(using Context)
15621568
extends TypeMsg(JavaEnumParentArgsID) {
15631569
def msg = em"""not enough arguments for constructor Enum: ${hl("(name: String, ordinal: Int)")}: ${hl(parent.show)}"""

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ object RefChecks {
9696

9797
/** Check that self type of this class conforms to self types of parents
9898
* and required classes. Also check that only `enum` constructs extend
99-
* `java.lang.Enum`.
99+
* `java.lang.Enum` and no user-written class extends ContextFunctionN.
100100
*/
101101
private def checkParents(cls: Symbol, parentTrees: List[Tree])(using Context): Unit = cls.info match {
102102
case cinfo: ClassInfo =>
@@ -132,6 +132,8 @@ object RefChecks {
132132
case _ =>
133133
false
134134
}
135+
if psyms.exists(defn.isContextFunctionClass) then
136+
report.error(CannotExtendContextFunction(cls), cls.sourcePos)
135137

136138
/** Check that arguments passed to trait parameters conform to the parameter types
137139
* in the current class. This is necessary since parameter types might be narrowed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,10 +1399,6 @@ class Typer extends Namer
13991399
else
14001400
report.error(ex"result type of lambda is an underspecified SAM type $pt", tree.srcPos)
14011401
pt
1402-
if (pt.classSymbol.isOneOf(FinalOrSealed)) {
1403-
val offendingFlag = pt.classSymbol.flags & FinalOrSealed
1404-
report.error(ex"lambda cannot implement $offendingFlag ${pt.classSymbol}", tree.srcPos)
1405-
}
14061402
TypeTree(targetTpe)
14071403
case _ =>
14081404
if (mt.isParamDependent)

0 commit comments

Comments
 (0)