Skip to content

Commit cd8996b

Browse files
committed
Drop extension_ name mangling
For the moment will still support extension_name references to extension methods in order to work with non-bootstrapped libraries. But we do not generate these names anymore.
1 parent 859bb52 commit cd8996b

Some content is hidden

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

44 files changed

+221
-275
lines changed

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

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ object desugar {
895895
mdef.tparams.head.srcPos)
896896
defDef(
897897
cpy.DefDef(mdef)(
898-
name = normalizeName(mdef, ext).toExtensionName,
898+
name = normalizeName(mdef, ext).asTermName,
899899
tparams = ext.tparams ++ mdef.tparams,
900900
vparamss = mdef.vparamss match
901901
case vparams1 :: vparamss1 if mdef.name.isRightAssocOperatorName =>
@@ -928,10 +928,10 @@ object desugar {
928928

929929
/** The normalized name of `mdef`. This means
930930
* 1. Check that the name does not redefine a Scala core class.
931-
* If it does redefine, issue an error and return a mangled name instead of the original one.
932-
* 2. Check that the name does not start with `extension_` unless the
933-
* method is an extension method.
934-
* 3. If the name is missing (this can be the case for instance definitions), invent one instead.
931+
* If it does redefine, issue an error and return a mangled name instead
932+
* of the original one.
933+
* 2. If the name is missing (this can be the case for instance definitions),
934+
* invent one instead.
935935
*/
936936
def normalizeName(mdef: MemberDef, impl: Tree)(using Context): Name = {
937937
var name = mdef.name
@@ -942,31 +942,16 @@ object desugar {
942942
report.error(IllegalRedefinitionOfStandardKind(kind, name), errPos)
943943
name = name.errorName
944944
}
945-
mdef match {
946-
case vdef: ValDef if name.isExtension && isSetterNeeded(vdef) =>
947-
report.error(em"illegal setter name: `extension_=`", errPos)
948-
case memDef if name.isExtensionName && !mdef.mods.is(ExtensionMethod) =>
949-
report.error(em"illegal name: $name may not start with `extension_`", errPos)
950-
case _ =>
951-
}
952945
name
953946
}
954947

955-
/** Invent a name for an anonympus given or extension of type or template `impl`. */
948+
/** Invent a name for an anonympus given of type or template `impl`. */
956949
def inventGivenOrExtensionName(impl: Tree)(using Context): SimpleName =
957950
val str = impl match
958951
case impl: Template =>
959952
if impl.parents.isEmpty then
960-
impl.body.find {
961-
case dd: DefDef if dd.mods.is(ExtensionMethod) => true
962-
case _ => false
963-
}
964-
match
965-
case Some(DefDef(name, _, (vparam :: _) :: _, _, _)) =>
966-
s"extension_${name}_${inventTypeName(vparam.tpt)}"
967-
case _ =>
968-
report.error(AnonymousInstanceCannotBeEmpty(impl), impl.srcPos)
969-
nme.ERROR.toString
953+
report.error(AnonymousInstanceCannotBeEmpty(impl), impl.srcPos)
954+
nme.ERROR.toString
970955
else
971956
impl.parents.map(inventTypeName(_)).mkString("given_", "_", "")
972957
case impl: Tree =>

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,7 @@ object Trees {
343343
if (rawMods.is(Synthetic) || span.isSynthetic || name.toTermName == nme.ERROR) Span(point)
344344
else {
345345
val realName = name.stripModuleClassSuffix.lastPart
346-
var length = realName.length
347-
if (rawMods.is(ExtensionMethod) || symbol.is(ExtensionMethod)) && name.isExtensionName then
348-
length -= "extension_".length
349-
Span(point, point + length, point)
346+
Span(point, point + realName.length, point)
350347
}
351348
}
352349
else span

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ class Definitions {
229229
@tu lazy val Compiletime_requireConst: Symbol = CompiletimePackageObject.requiredMethod("requireConst")
230230
@tu lazy val Compiletime_constValue : Symbol = CompiletimePackageObject.requiredMethod("constValue")
231231
@tu lazy val Compiletime_constValueOpt: Symbol = CompiletimePackageObject.requiredMethod("constValueOpt")
232-
@tu lazy val Compiletime_code : Symbol = CompiletimePackageObject.requiredMethod("extension_code")
233232
@tu lazy val Compiletime_summonFrom : Symbol = CompiletimePackageObject.requiredMethod("summonFrom")
234233
@tu lazy val CompiletimeTestingPackageObject: Symbol = requiredModule("scala.compiletime.testing.package")
235234
@tu lazy val CompiletimeTesting_typeChecks: Symbol = CompiletimeTestingPackageObject.requiredMethod("typeChecks")

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ object Flags {
152152
def flagsString: String = x.flagStrings("").mkString(" ")
153153
}
154154

155+
// Temporary while extension names are in flux
156+
def or(x1: FlagSet, x2: FlagSet) = x1 | x2
157+
def and(x1: FlagSet, x2: FlagSet) = x1 & x2
158+
155159
def termFlagSet(x: Long) = FlagSet(TERMS | x)
156160

157161
private inline val TYPESHIFT = 2

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,10 @@ object NameOps {
145145
case name: SimpleName => name.startsWith("extension_")
146146
case _ => false
147147

148+
// TODO: Drop next 3 methods once extension names have stabilized
148149
/** Add an `extension_` in front of this name */
149150
def toExtensionName(using Context): SimpleName = "extension_".concat(name)
150151

151-
/** Drop `extension_` in front of this name, if it has this prefix */
152-
def dropExtension = name match
153-
case name: SimpleName if name.startsWith("extension_") =>
154-
name.drop("extension_".length)
155-
case _ =>
156-
name
157-
158152
/** The expanded name.
159153
* This is the fully qualified name of `base` with `ExpandPrefixName` as separator,
160154
* followed by `kind` and the name.

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -750,11 +750,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
750750
private def useSymbol(tree: untpd.Tree) =
751751
tree.hasType && tree.symbol.exists && ctx.settings.YprintSyms.value
752752

753-
protected def nameIdText[T >: Untyped](tree: NameTree[T], dropExtension: Boolean = false): Text =
753+
protected def nameIdText[T >: Untyped](tree: NameTree[T]): Text =
754754
if (tree.hasType && tree.symbol.exists) {
755-
var str = nameString(tree.symbol)
756-
if tree.symbol.is(ExtensionMethod) && dropExtension && str.startsWith("extension_") then
757-
str = str.drop("extension_".length)
755+
val str = nameString(tree.symbol)
758756
tree match {
759757
case tree: RefTree => withPos(str, tree.sourcePos)
760758
case tree: MemberDef => withPos(str, tree.sourcePos.withSpan(tree.nameSpan))
@@ -806,7 +804,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
806804
case vparams1 :: rest =>
807805
(vparams1, rest)
808806
(keywordStr("extension") ~~ paramsText(leadingParams)
809-
~~ (defKeyword ~~ valDefText(nameIdText(tree, dropExtension = true))).close,
807+
~~ (defKeyword ~~ valDefText(nameIdText(tree))).close,
810808
otherParamss)
811809
else (defKeyword ~~ valDefText(nameIdText(tree)), tree.vparamss)
812810

compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,8 +2526,8 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext:
25262526
object FlagsMethodsImpl extends FlagsMethods:
25272527
extension (self: Flags):
25282528
def is(that: Flags): Boolean = self.isAllOf(that)
2529-
def |(that: Flags): Flags = dotc.core.Flags.extension_|(self)(that)
2530-
def &(that: Flags): Flags = dotc.core.Flags.extension_&(self)(that)
2529+
def |(that: Flags): Flags = dotc.core.Flags.or(self, that) // TODO: Replace with dotc.core.Flags.|(self)(that) once extension names have stabilized
2530+
def &(that: Flags): Flags = dotc.core.Flags.and(self, that)// TODO: Replace with dotc.core.Flags.&(self)(that) once extension names have stabilized
25312531
def showExtractors: String =
25322532
new ExtractorsPrinter[reflect.type](reflect).showFlags(self)
25332533
def show: String =

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ trait Applications extends Compatibility {
13921392
}
13931393

13941394
/** Does `tp` have an extension method named `xname` with this-argument `argType` and
1395-
* result matching `resultType`? `xname` is supposed to start with `extension_`.
1395+
* result matching `resultType`?
13961396
*/
13971397
def hasExtensionMethodNamed(tp: Type, xname: TermName, argType: Type, resultType: Type)(using Context) = {
13981398
def qualifies(mbr: Denotation) =

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ object Implicits:
7575
* method with the selecting name? False otherwise.
7676
*/
7777
def hasExtMethod(tp: Type, expected: Type)(using Context) = expected match
78-
case selProto @ SelectionProto(_: TermName, _, _, _) =>
79-
tp.memberBasedOnFlags(selProto.extensionName, required = ExtensionMethod).exists
78+
case selProto @ SelectionProto(selName: TermName, _, _, _) =>
79+
tp.memberBasedOnFlags(selName, required = ExtensionMethod).exists
80+
|| tp.memberBasedOnFlags(selProto.extensionName, required = ExtensionMethod).exists
8081
case _ => false
8182

8283
def strictEquality(using Context): Boolean =
@@ -1078,9 +1079,14 @@ trait Implicits:
10781079
pt, locked)
10791080
}
10801081
pt match
1081-
case selProto @ SelectionProto(_: TermName, mbrType, _, _) if cand.isExtension =>
1082+
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) if cand.isExtension =>
10821083
def tryExtension(using Context) =
1083-
extMethodApply(untpd.Select(untpdGenerated, selProto.extensionName), argument, mbrType)
1084+
val xname =
1085+
if ref.memberBasedOnFlags(selProto.extensionName, required = ExtensionMethod).exists then
1086+
selProto.extensionName
1087+
else
1088+
selName
1089+
extMethodApply(untpd.Select(untpdGenerated, xname), argument, mbrType)
10841090
if cand.isConversion then
10851091
val extensionCtx, conversionCtx = ctx.fresh.setNewTyperState()
10861092
val extensionResult = tryExtension(using extensionCtx)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ trait ImportSuggestions:
219219
* applicable to `argType`.
220220
*/
221221
def extensionMethod(site: TermRef, name: TermName, argType: Type): Option[TermRef] =
222-
site.member(name.toExtensionName)
222+
site.member(name)
223223
.alternatives
224224
.map(mbr => TermRef(site, mbr.symbol))
225225
.filter(ref =>
@@ -320,7 +320,7 @@ trait ImportSuggestions:
320320
def importString(ref: TermRef): String =
321321
val imported =
322322
if ref.symbol.is(ExtensionMethod) then
323-
s"${ctx.printer.toTextPrefix(ref.prefix).show}${ref.symbol.name.dropExtension}"
323+
s"${ctx.printer.toTextPrefix(ref.prefix).show}${ref.symbol.name}"
324324
else
325325
ctx.printer.toTextRef(ref).show
326326
s" import $imported"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ class Namer { typer: Typer =>
10161016

10171017
def addForwardersNamed(name: TermName, alias: TermName, span: Span): Unit = {
10181018
val size = buf.size
1019-
val mbrs = List(name, name.toTypeName, name.toExtensionName).flatMap(path.tpe.member(_).alternatives)
1019+
val mbrs = List(name, name.toTypeName).flatMap(path.tpe.member(_).alternatives)
10201020
mbrs.foreach(addForwarder(alias, _, span))
10211021
if (buf.size == size) {
10221022
val reason = mbrs.map(whyNoForwarder).dropWhile(_ == SKIP) match {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,9 @@ object ProtoTypes {
444444
def isMatchedBy(tp: Type, keepConstraint: Boolean)(using Context): Boolean =
445445
ctx.typer.isApplicableType(tp, argType :: Nil, resultType) || {
446446
resType match {
447-
case selProto @ SelectionProto(_: TermName, mbrType, _, _) =>
448-
ctx.typer.hasExtensionMethodNamed(tp, selProto.extensionName, argType, mbrType)
447+
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
448+
ctx.typer.hasExtensionMethodNamed(tp, selName, argType, mbrType)
449+
|| ctx.typer.hasExtensionMethodNamed(tp, selProto.extensionName, argType, mbrType)
449450
//.reporting(i"has ext $tp $name $argType $mbrType: $result")
450451
case _ =>
451452
false

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

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ class Typer extends Namer
133133
val noImports = ctx.mode.is(Mode.InPackageClauseName)
134134
def fail(msg: Message) = report.error(msg, pos)
135135

136+
def qualifies(denot: Denotation): Boolean =
137+
reallyExists(denot)
138+
&& {
139+
if required.is(ExtensionMethod) then
140+
denot.hasAltWith(_.symbol.is(ExtensionMethod))
141+
else
142+
denot.hasAltWith(!_.symbol.is(ExtensionMethod))
143+
}
144+
136145
/** A symbol qualifies if it really exists and is not a package class.
137146
* In addition, if we are in a constructor of a pattern, we ignore all definitions
138147
* which are methods and not accessors (note: if we don't do that
@@ -142,8 +151,8 @@ class Typer extends Namer
142151
* we could not reload them via `_.member`. On the other hand, accessing a
143152
* package as a type from source is always an error.
144153
*/
145-
def qualifies(denot: Denotation): Boolean =
146-
reallyExists(denot)
154+
def qualifiesAsDef(denot: Denotation): Boolean =
155+
qualifies(denot)
147156
&& !(pt.isInstanceOf[UnapplySelectionProto] && denot.symbol.is(Method, butNot = Accessor))
148157
&& !denot.symbol.is(PackageClass)
149158

@@ -204,7 +213,7 @@ class Typer extends Namer
204213
denot = denot.filterWithPredicate { mbr =>
205214
mbr.matchesImportBound(if mbr.symbol.is(Given) then imp.givenBound else imp.wildcardBound)
206215
}
207-
if reallyExists(denot) then
216+
if qualifies(denot) then
208217
if unimported.isEmpty || !unimported.contains(pre.termSymbol) then
209218
return pre.select(name, denot)
210219
case _ =>
@@ -217,13 +226,6 @@ class Typer extends Namer
217226
*/
218227
def namedImportRef(imp: ImportInfo)(using Context): Type = {
219228
val termName = name.toTermName
220-
221-
def adjustExtension(n: Name) =
222-
if required.is(ExtensionMethod) && termName.endsWith(n.lastPart)
223-
// pre-check to avoid forming a new string; form extension only if it has a chance of matching `termName`
224-
then n.toExtensionName
225-
else n
226-
227229
def recur(selectors: List[untpd.ImportSelector]): Type = selectors match
228230
case selector :: rest =>
229231
def checkUnambiguous(found: Type) =
@@ -232,12 +234,12 @@ class Typer extends Namer
232234
fail(em"reference to `$name` is ambiguous; it is imported twice")
233235
found
234236

235-
if adjustExtension(selector.rename) == termName then
237+
if selector.rename == termName then
236238
val memberName =
237239
if selector.name == termName then name
238240
else if name.isTypeName then selector.name.toTypeName
239241
else selector.name
240-
checkUnambiguous(selection(imp, adjustExtension(memberName), checkBounds = false))
242+
checkUnambiguous(selection(imp, memberName, checkBounds = false))
241243
else
242244
recur(rest)
243245

@@ -343,7 +345,7 @@ class Typer extends Namer
343345

344346
if isNewDefScope then
345347
val defDenot = ctx.denotNamed(name, required)
346-
if (qualifies(defDenot)) {
348+
if (qualifiesAsDef(defDenot)) {
347349
val found =
348350
if (isSelfDenot(defDenot)) curOwner.enclosingClass.thisType
349351
else {
@@ -456,21 +458,15 @@ class Typer extends Namer
456458
unimported = Set.empty
457459
foundUnderScala2 = NoType
458460
try
459-
val found = findRef(name, pt, EmptyFlags, tree.srcPos)
461+
val reqFlags = if pt.isExtensionApplyProto then ExtensionMethod else EmptyFlags
462+
val found = findRef(name, pt, reqFlags, tree.srcPos)
460463
if foundUnderScala2.exists && !(foundUnderScala2 =:= found) then
461464
report.migrationWarning(
462465
ex"""Name resolution will change.
463466
| currently selected : $foundUnderScala2
464467
| in the future, without -source 3.0-migration: $found""", tree.srcPos)
465468
foundUnderScala2
466-
else
467-
found match
468-
case found: TermRef
469-
if !found.denot.hasAltWith(!_.symbol.is(ExtensionMethod))
470-
&& !pt.isExtensionApplyProto =>
471-
NoType // direct calls to extension methods need a prefix
472-
case _ =>
473-
found
469+
else found
474470
finally
475471
unimported = saved1
476472
foundUnderScala2 = saved2
@@ -3324,8 +3320,12 @@ class Typer extends Namer
33243320
// where we have an argument that must be converted with another
33253321
// implicit conversion to the receiver type.
33263322
def sharpenedPt = pt match
3327-
case pt: SelectionProto if pt.name.isExtensionName => pt.deepenProto
3328-
case _ => pt
3323+
case pt: SelectionProto
3324+
if pt.name.isExtensionName
3325+
|| pt.memberProto.revealIgnored.isExtensionApplyProto =>
3326+
pt.deepenProto
3327+
case _ =>
3328+
pt
33293329

33303330
def adaptNoArgs(wtp: Type): Tree = {
33313331
val ptNorm = underlyingApplied(pt)
@@ -3468,17 +3468,17 @@ class Typer extends Namer
34683468

34693469
// try an extension method in scope
34703470
pt match {
3471-
case selProto @ SelectionProto(_: TermName, mbrType, _, _) =>
3471+
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
34723472
def tryExtension(using Context): Tree =
34733473
try
3474-
findRef(selProto.extensionName, WildcardType, ExtensionMethod, tree.srcPos) match {
3474+
findRef(selName, WildcardType, ExtensionMethod, tree.srcPos) match
34753475
case ref: TermRef =>
34763476
extMethodApply(untpd.ref(ref).withSpan(tree.span), tree, mbrType)
3477-
case _ => EmptyTree
3478-
}
3479-
catch {
3480-
case ex: TypeError => errorTree(tree, ex, tree.srcPos)
3481-
}
3477+
case _ => findRef(selProto.extensionName, WildcardType, ExtensionMethod, tree.srcPos) match
3478+
case ref: TermRef =>
3479+
extMethodApply(untpd.ref(ref).withSpan(tree.span), tree, mbrType)
3480+
case _ => EmptyTree
3481+
catch case ex: TypeError => errorTree(tree, ex, tree.srcPos)
34823482
val nestedCtx = ctx.fresh.setNewTyperState()
34833483
val app = tryExtension(using nestedCtx)
34843484
if (!app.isEmpty && !nestedCtx.reporter.hasErrors) {
@@ -3587,7 +3587,6 @@ class Typer extends Namer
35873587
case _ => tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply
35883588
}
35893589
case pt: SelectionProto if tree.isInstanceOf[ExtMethodApply] =>
3590-
assert(pt.extensionName == tree.symbol.name)
35913590
tree
35923591
case _ =>
35933592
if (ctx.mode is Mode.Type) adaptType(tree.tpe)

0 commit comments

Comments
 (0)