Skip to content

Commit d6cd533

Browse files
smartermichelou
authored andcommitted
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 e7ad78c commit d6cd533

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
@@ -5054,7 +5054,7 @@ object Types {
50545054
NoType
50555055
}
50565056
def isInstantiatable(tp: Type)(using Context): Boolean = zeroParamClass(tp) match {
5057-
case cinfo: ClassInfo =>
5057+
case cinfo: ClassInfo if !cinfo.cls.isOneOf(FinalOrSealed) =>
50585058
val selfType = cinfo.selfType.asSeenFrom(tp, cinfo.cls)
50595059
tp <:< selfType
50605060
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
@@ -1562,6 +1562,12 @@ import transform.SymUtils._
15621562
def explain = ""
15631563
}
15641564

1565+
class CannotExtendContextFunction(sym: Symbol)(using Context)
1566+
extends SyntaxMsg(CannotExtendFunctionID) {
1567+
def msg = em"""$sym cannot extend a context function class"""
1568+
def explain = ""
1569+
}
1570+
15651571
class JavaEnumParentArgs(parent: Type)(using Context)
15661572
extends TypeMsg(JavaEnumParentArgsID) {
15671573
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)