Skip to content

Commit 48b583b

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents ca11a07 + 22e64e2 commit 48b583b

File tree

41 files changed

+495
-84
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+495
-84
lines changed
Submodule intent updated 51 files

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ object desugar {
483483
if (isEnum) {
484484
val (enumCases, enumStats) = stats.partition(DesugarEnums.isEnumCase)
485485
if (enumCases.isEmpty)
486-
ctx.error("Enumerations must constain at least one case", namePos)
486+
ctx.error("Enumerations must contain at least one case", namePos)
487487
val enumCompanionRef = TermRefTree()
488488
val enumImport =
489489
Import(enumCompanionRef, enumCases.flatMap(caseIds).map(ImportSelector(_)))

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
182182

183183
case class Opaque()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Opaque)
184184

185+
case class Open()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Open)
186+
185187
case class Override()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Override)
186188

187189
case class Abstract()(implicit @constructorOnly src: SourceFile) extends Mod(Flags.Abstract)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ class Definitions {
4343
ctx.newSymbol(owner, name, flags | Permanent, info)
4444

4545
private def newClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, infoFn: ClassSymbol => Type) =
46-
ctx.newClassSymbol(owner, name, flags | Permanent | NoInits, infoFn)
46+
ctx.newClassSymbol(owner, name, flags | Permanent | NoInits | Open, infoFn)
4747

4848
private def enterCompleteClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, parents: List[TypeRef], decls: Scope = newScope) =
49-
ctx.newCompleteClassSymbol(owner, name, flags | Permanent | NoInits, parents, decls).entered
49+
ctx.newCompleteClassSymbol(owner, name, flags | Permanent | NoInits | Open, parents, decls).entered
5050

5151
private def enterTypeField(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
5252
scope.enter(newSymbol(cls, name, flags, TypeBounds.empty))
@@ -279,7 +279,7 @@ class Definitions {
279279
val cls = ctx.requiredClass("java.lang.Object")
280280
assert(!cls.isCompleted, "race for completing java.lang.Object")
281281
cls.info = ClassInfo(cls.owner.thisType, cls, AnyClass.typeRef :: Nil, newScope)
282-
cls.setFlag(NoInits)
282+
cls.setFlag(NoInits | JavaDefined)
283283

284284
// The companion object doesn't really exist, so it needs to be marked as
285285
// absent. Here we need to set it before completing attempt to load Object's

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object Flags {
3737
else {
3838
val tbits = x.bits & y.bits & KINDFLAGS
3939
if (tbits == 0)
40-
assert(false, s"illegal flagset combination: $x and $y")
40+
assert(false, s"illegal flagset combination: ${x.flagsString} and ${y.flagsString}")
4141
FlagSet(tbits | ((x.bits | y.bits) & ~KINDFLAGS))
4242
}
4343

@@ -237,8 +237,8 @@ object Flags {
237237
/** A value or variable accessor (getter or setter) */
238238
val (AccessorOrSealed @ _, Accessor @ _, Sealed @ _) = newFlags(11, "<accessor>", "sealed")
239239

240-
/** A mutable var */
241-
val (_, Mutable @ _, _) = newFlags(12, "mutable")
240+
/** A mutable var, an open class */
241+
val (MutableOrOpen @ __, Mutable @ _, Open @ _) = newFlags(12, "mutable", "open")
242242

243243
/** Symbol is local to current class (i.e. private[this] or protected[this]
244244
* pre: Private or Protected are also set
@@ -422,7 +422,7 @@ object Flags {
422422
commonFlags(Private, Protected, Final, Case, Implicit, Given, Override, JavaStatic)
423423

424424
val TypeSourceModifierFlags: FlagSet =
425-
CommonSourceModifierFlags.toTypeFlags | Abstract | Sealed | Opaque
425+
CommonSourceModifierFlags.toTypeFlags | Abstract | Sealed | Opaque | Open
426426

427427
val TermSourceModifierFlags: FlagSet =
428428
CommonSourceModifierFlags.toTermFlags | Inline | AbsOverride | Lazy | Erased
@@ -439,7 +439,7 @@ object Flags {
439439
val FromStartFlags: FlagSet = commonFlags(
440440
Module, Package, Deferred, Method, Case,
441441
HigherKinded, Param, ParamAccessor,
442-
Scala2ExistentialCommon, Mutable, Opaque, Touched, JavaStatic,
442+
Scala2ExistentialCommon, MutableOrOpen, Opaque, Touched, JavaStatic,
443443
OuterOrCovariant, LabelOrContravariant, CaseAccessor,
444444
Extension, NonMember, Implicit, Given, Permanent, Synthetic,
445445
SuperAccessorOrScala2x, Inline, Macro)
@@ -509,12 +509,16 @@ object Flags {
509509
/** Flags retained in export forwarders */
510510
val RetainedExportFlags = Given | Implicit | Extension
511511

512+
/** Flags that apply only to classes */
513+
val ClassOnlyFlags = Sealed | Open | Abstract.toTypeFlags
514+
512515
// ------- Other flag sets -------------------------------------
513516

514517
val AbstractFinal: FlagSet = Abstract | Final
515518
val AbstractOverride: FlagSet = Abstract | Override
516519
val AbstractSealed: FlagSet = Abstract | Sealed
517520
val AbstractOrTrait: FlagSet = Abstract | Trait
521+
val EffectivelyOpenFlags = Abstract | JavaDefined | Open | Scala2x | Trait
518522
val PrivateAccessor: FlagSet = Accessor | Private
519523
val AccessorOrSynthetic: FlagSet = Accessor | Synthetic
520524
val EnumCase: FlagSet = Case | Enum

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@ object StdNames {
367367
val TypeApply: N = "TypeApply"
368368
val TypeRef: N = "TypeRef"
369369
val UNIT : N = "UNIT"
370-
val add_ : N = "add"
371370
val acc: N = "acc"
371+
val adhocExtensions: N = "adhocExtensions"
372372
val annotation: N = "annotation"
373373
val any2stringadd: N = "any2stringadd"
374374
val anyHash: N = "anyHash"
@@ -506,6 +506,7 @@ object StdNames {
506506
val nullExpr: N = "nullExpr"
507507
val ofDim: N = "ofDim"
508508
val opaque: N = "opaque"
509+
val open: N = "open"
509510
val ordinal: N = "ordinal"
510511
val ordinalDollar: N = "$ordinal"
511512
val ordinalDollar_ : N = "_$ordinal"

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,12 @@ object SymDenotations {
10641064
final def isEffectivelyFinal(implicit ctx: Context): Boolean =
10651065
isOneOf(EffectivelyFinalFlags) || !owner.isClass || owner.isOneOf(FinalOrModuleClass) || owner.isAnonymousClass
10661066

1067+
/** A class is effectively sealed if has the `final` or `sealed` modifier, or it
1068+
* is defined in Scala 3 and is neither abstract nor open.
1069+
*/
1070+
final def isEffectivelySealed(given Context): Boolean =
1071+
isOneOf(FinalOrSealed) || isClass && !isOneOf(EffectivelyOpenFlags)
1072+
10671073
/** The class containing this denotation which has the given effective name. */
10681074
final def enclosingClassNamed(name: Name)(implicit ctx: Context): Symbol = {
10691075
val cls = enclosingClass
@@ -1362,16 +1368,16 @@ object SymDenotations {
13621368
*/
13631369
def typeParamCreationFlags: FlagSet = TypeParam
13641370

1365-
override def toString: String = {
1366-
val kindString =
1367-
if (myFlags.is(ModuleClass)) "module class"
1368-
else if (isClass) "class"
1369-
else if (isType) "type"
1370-
else if (myFlags.is(Module)) "module"
1371-
else if (myFlags.is(Method)) "method"
1372-
else "val"
1373-
s"$kindString $name"
1374-
}
1371+
def kindString: String =
1372+
if myFlags.is(ModuleClass) then "module class"
1373+
else if myFlags.is(Trait) then "trait"
1374+
else if isClass then "class"
1375+
else if isType then "type"
1376+
else if myFlags.is(Module) then "module"
1377+
else if myFlags.is(Method) then "method"
1378+
else "val"
1379+
1380+
override def toString: String = s"$kindString $name"
13751381

13761382
// ----- Sanity checks and debugging */
13771383

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ Standard-Section: "ASTs" TopLevelStat*
211211
EXTENSION -- An extension method
212212
PARAMsetter -- The setter part `x_=` of a var parameter `x` which itself is pickled as a PARAM
213213
EXPORTED -- An export forwarder
214+
OPEN -- an open class
214215
Annotation
215216
216217
Annotation = ANNOTATION Length tycon_Type fullAnnotation_Term -- An annotation, given (class) type of constructor, and full application tree
@@ -332,6 +333,7 @@ object TastyFormat {
332333
final val GIVEN = 37
333334
final val PARAMsetter = 38
334335
final val EXPORTED = 39
336+
final val OPEN = 40
335337

336338
// Cat. 2: tag Nat
337339

@@ -460,7 +462,7 @@ object TastyFormat {
460462

461463
/** Useful for debugging */
462464
def isLegalTag(tag: Int): Boolean =
463-
firstSimpleTreeTag <= tag && tag <= EXPORTED ||
465+
firstSimpleTreeTag <= tag && tag <= OPEN ||
464466
firstNatTreeTag <= tag && tag <= RENAMED ||
465467
firstASTTreeTag <= tag && tag <= BOUNDED ||
466468
firstNatASTTreeTag <= tag && tag <= NAMEDARG ||
@@ -505,6 +507,7 @@ object TastyFormat {
505507
| GIVEN
506508
| PARAMsetter
507509
| EXPORTED
510+
| OPEN
508511
| ANNOTATION
509512
| PRIVATEqualified
510513
| PROTECTEDqualified => true
@@ -565,6 +568,7 @@ object TastyFormat {
565568
case GIVEN => "GIVEN"
566569
case PARAMsetter => "PARAMsetter"
567570
case EXPORTED => "EXPORTED"
571+
case OPEN => "OPEN"
568572

569573
case SHAREDterm => "SHAREDterm"
570574
case SHAREDtype => "SHAREDtype"

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ class TreePickler(pickler: TastyPickler) {
669669
if (flags.is(Covariant)) writeModTag(COVARIANT)
670670
if (flags.is(Contravariant)) writeModTag(CONTRAVARIANT)
671671
if (flags.is(Opaque)) writeModTag(OPAQUE)
672+
if (flags.is(Open)) writeModTag(OPEN)
672673
}
673674
}
674675

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ class TreeUnpickler(reader: TastyReader,
631631
case GIVEN => addFlag(Given)
632632
case PARAMsetter => addFlag(ParamAccessor)
633633
case EXPORTED => addFlag(Exported)
634+
case OPEN => addFlag(Open)
634635
case PRIVATEqualified =>
635636
readByte()
636637
privateWithin = readWithin(ctx)
@@ -890,9 +891,9 @@ class TreeUnpickler(reader: TastyReader,
890891
untpd.ValDef(readName(), readTpt(), EmptyTree).withType(NoType)
891892
}
892893
else EmptyValDef
894+
cls.setNoInitsFlags(parentsKind(parents), bodyFlags)
893895
cls.info = ClassInfo(cls.owner.thisType, cls, parentTypes, cls.unforcedDecls,
894896
if (self.isEmpty) NoType else self.tpt.tpe)
895-
cls.setNoInitsFlags(parentsKind(parents), bodyFlags)
896897
val constr = readIndexedDef().asInstanceOf[DefDef]
897898
val mappedParents = parents.map(_.changeOwner(localDummy, constr.symbol))
898899

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2590,6 +2590,7 @@ object Parsers {
25902590
name match {
25912591
case nme.inline => Mod.Inline()
25922592
case nme.opaque => Mod.Opaque()
2593+
case nme.open => Mod.Open()
25932594
}
25942595
}
25952596

@@ -2661,7 +2662,7 @@ object Parsers {
26612662
* | AccessModifier
26622663
* | override
26632664
* | opaque
2664-
* LocalModifier ::= abstract | final | sealed | implicit | lazy | erased | inline
2665+
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | erased | inline
26652666
*/
26662667
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers()): Modifiers = {
26672668
@tailrec

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ object Scanners {
10681068
}
10691069
else if (ch == '$') {
10701070
nextRawChar()
1071-
if (ch == '$') {
1071+
if (ch == '$' || ch == '"') {
10721072
putChar(ch)
10731073
nextRawChar()
10741074
getStringPart(multiLine)
@@ -1089,7 +1089,7 @@ object Scanners {
10891089
finishNamed(target = next)
10901090
}
10911091
else
1092-
error("invalid string interpolation: `$$', `$'ident or `$'BlockExpr expected")
1092+
error("invalid string interpolation: `$$', `$\"`, `$'ident or `$'BlockExpr expected")
10931093
}
10941094
else {
10951095
val isUnclosedLiteral = !isUnicodeEscape && (ch == SU || (!multiLine && (ch == CR || ch == LF)))

compiler/src/dotty/tools/dotc/parsing/Tokens.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,5 +286,5 @@ object Tokens extends TokensCommon {
286286

287287
final val scala3keywords = BitSet(ENUM, ERASED, GIVEN)
288288

289-
final val softModifierNames = Set(nme.inline, nme.opaque)
289+
final val softModifierNames = Set(nme.inline, nme.opaque, nme.open)
290290
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ trait Reporting { this: Context =>
108108
else {
109109
reporter.reportNewFeatureUseSite(featureUseSite)
110110
s"""
111-
|This can be achieved by adding the import clause 'import $fqname'
112-
|or by setting the compiler option -language:$feature.
113111
|See the Scala docs for value $fqname for a discussion
114112
|why the feature $req be explicitly enabled.""".stripMargin
115113
}
116114

117-
val msg = s"$featureDescription $req be enabled\nby making the implicit value $fqname visible.$explain"
115+
val msg = s"""$featureDescription $req be enabled
116+
|by adding the import clause 'import $fqname'
117+
|or by setting the compiler option -language:$feature.$explain""".stripMargin
118118
if (required) error(msg, pos)
119119
else reportWarning(new FeatureWarning(msg, pos))
120120
}

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,13 +1790,10 @@ object messages {
17901790
extends Message(ClassAndCompanionNameClashID) {
17911791
val kind: String = "Naming"
17921792
val msg: String = em"Name clash: both ${cls.owner} and its companion object defines ${cls.name.stripModuleClassSuffix}"
1793-
val explanation: String = {
1794-
val kind = if (cls.owner.is(Flags.Trait)) "trait" else "class"
1795-
1796-
em"""|A $kind and its companion object cannot both define a ${hl("class")}, ${hl("trait")} or ${hl("object")} with the same name:
1793+
val explanation: String =
1794+
em"""|A ${cls.kindString} and its companion object cannot both define a ${hl("class")}, ${hl("trait")} or ${hl("object")} with the same name:
17971795
| - ${cls.owner} defines ${cls}
17981796
| - ${other.owner} defines ${other}"""
1799-
}
18001797
}
18011798

18021799
case class TailrecNotApplicable(symbol: Symbol)(implicit ctx: Context)

compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
15441544
def Flags_Private: Flags = core.Flags.Private
15451545
def Flags_Protected: Flags = core.Flags.Protected
15461546
def Flags_Abstract: Flags = core.Flags.Abstract
1547+
def Flags_Open: Flags = core.Flags.Open
15471548
def Flags_Final: Flags = core.Flags.Final
15481549
def Flags_Sealed: Flags = core.Flags.Sealed
15491550
def Flags_Case: Flags = core.Flags.Case

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class SymUtils(val self: Symbol) extends AnyVal {
9292
*/
9393
def whyNotGenericSum(implicit ctx: Context): String =
9494
if (!self.is(Sealed))
95-
s"it is not a sealed ${if (self.is(Trait)) "trait" else "class"}"
95+
s"it is not a sealed ${self.kindString}"
9696
else {
9797
val children = self.children
9898
val companion = self.linkedClass
@@ -175,12 +175,18 @@ class SymUtils(val self: Symbol) extends AnyVal {
175175
def isEnumAnonymClass(implicit ctx: Context): Boolean =
176176
self.isAnonymousClass && (self.owner.name.eq(nme.DOLLAR_NEW) || self.owner.is(CaseVal))
177177

178-
/** Is this symbol defined locally (i.e. at some level owned by a term) and
179-
* defined in a different toplevel class than its supposed parent class `cls`?
180-
* Such children are not pickled, and have to be reconstituted manually.
178+
/** Is this symbol defined locally (i.e. at some level owned by a term) so that
179+
* it cannot be seen from parent class `cls`?
181180
*/
182-
def isInaccessibleChildOf(cls: Symbol)(implicit ctx: Context): Boolean =
183-
self.isLocal && !cls.topLevelClass.isLinkedWith(self.topLevelClass)
181+
def isInaccessibleChildOf(cls: Symbol)(given Context): Boolean =
182+
def isAccessible(sym: Symbol, cls: Symbol): Boolean =
183+
if cls.isType && !cls.is(Package) then
184+
isAccessible(sym, cls.owner)
185+
else
186+
sym == cls
187+
|| sym.is(Package)
188+
|| sym.isType && isAccessible(sym.owner, cls)
189+
!isAccessible(self.owner, cls)
184190

185191
/** If this is a sealed class, its known children in the order of textual occurrence */
186192
def children(implicit ctx: Context): List[Symbol] = {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,10 @@ object Checking {
417417
}
418418
if (!sym.isClass && sym.is(Abstract))
419419
fail(OnlyClassesCanBeAbstract(sym))
420+
// note: this is not covered by the next test since terms can be abstract (which is a dual-mode flag)
421+
// but they can never be one of ClassOnlyFlags
422+
if !sym.isClass && sym.isOneOf(ClassOnlyFlags) then
423+
fail(em"only classes can be ${(sym.flags & ClassOnlyFlags).flagsString}")
420424
if (sym.is(AbsOverride) && !sym.owner.is(Trait))
421425
fail(AbstractOverrideOnlyInTraits(sym))
422426
if (sym.is(Trait) && sym.is(Final))
@@ -437,6 +441,8 @@ object Checking {
437441
}
438442
if (sym.isValueClass && sym.is(Trait) && !sym.isRefinementClass)
439443
fail(CannotExtendAnyVal(sym))
444+
checkCombination(Final, Open)
445+
checkCombination(Sealed, Open)
440446
checkCombination(Final, Sealed)
441447
checkCombination(Private, Protected)
442448
checkCombination(Abstract, Override)

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,16 +197,14 @@ object Inliner {
197197
/** Expand call to scala.compiletime.testing.typeChecks */
198198
def typeChecks(tree: Tree)(implicit ctx: Context): Tree = {
199199
assert(tree.symbol == defn.CompiletimeTesting_typeChecks)
200-
def getCodeArgValue(t: Tree): Option[String] = t match {
201-
case Literal(Constant(code: String)) => Some(code)
202-
case Typed(t2, _) => getCodeArgValue(t2)
203-
case Inlined(_, Nil, t2) => getCodeArgValue(t2)
204-
case Block(Nil, t2) => getCodeArgValue(t2)
205-
case _ => None
200+
def stripTyped(t: Tree): Tree = t match {
201+
case Typed(t2, _) => stripTyped(t2)
202+
case _ => t
206203
}
204+
207205
val Apply(_, codeArg :: Nil) = tree
208-
getCodeArgValue(codeArg.underlyingArgument) match {
209-
case Some(code) =>
206+
ConstFold(stripTyped(codeArg.underlyingArgument)).tpe.widenTermRefExpr match {
207+
case ConstantType(Constant(code: String)) =>
210208
val ctx2 = ctx.fresh.setNewTyperState().setTyper(new Typer)
211209
val tree2 = new Parser(SourceFile.virtual("tasty-reflect", code))(ctx2).block()
212210
val res =
@@ -216,7 +214,8 @@ object Inliner {
216214
!ctx2.reporter.hasErrors
217215
}
218216
Literal(Constant(res))
219-
case _ =>
217+
case t =>
218+
assert(ctx.reporter.hasErrors) // at least: argument to inline parameter must be a known value
220219
EmptyTree
221220
}
222221
}

0 commit comments

Comments
 (0)