Skip to content

Commit 4411811

Browse files
authored
Merge pull request #10149 from dotty-staging/fix-alpha
Rename @Alpha to @TargetNAME
2 parents 0700573 + 773023b commit 4411811

File tree

72 files changed

+973
-509
lines changed

Some content is hidden

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

72 files changed

+973
-509
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -882,16 +882,16 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
882882
}
883883

884884
/** A select node with the given selector name and signature and a computed type */
885-
def selectWithSig(name: Name, sig: Signature)(using Context): Tree =
886-
untpd.SelectWithSig(tree, name, sig).withType(tree.tpe.select(name.asTermName, sig))
885+
def selectWithSig(name: Name, sig: Signature, target: Name)(using Context): Tree =
886+
untpd.SelectWithSig(tree, name, sig).withType(tree.tpe.select(name.asTermName, sig, target))
887887

888888
/** A select node with selector name and signature taken from `sym`.
889889
* Note: Use this method instead of select(sym) if the referenced symbol
890890
* might be overridden in the type of the qualifier prefix. See note
891891
* on select(sym: Symbol).
892892
*/
893893
def selectWithSig(sym: Symbol)(using Context): Tree =
894-
selectWithSig(sym.name, sym.signature)
894+
selectWithSig(sym.name, sym.signature, sym.targetName)
895895

896896
/** A unary apply node with given argument: `tree(arg)` */
897897
def appliedTo(arg: Tree)(using Context): Apply =

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ object Printers {
3737
val pickling = noPrinter
3838
val quotePickling = noPrinter
3939
val plugins = noPrinter
40+
val refcheck = noPrinter
4041
val simplify = noPrinter
4142
val staging = noPrinter
4243
val subtyping = noPrinter

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class ScalaSettings extends Settings.SettingGroup {
173173
val YexplicitNulls: Setting[Boolean] = BooleanSetting("-Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
174174
val YerasedTerms: Setting[Boolean] = BooleanSetting("-Yerased-terms", "Allows the use of erased terms.")
175175
val YcheckInit: Setting[Boolean] = BooleanSetting("-Ycheck-init", "Check initialization of objects")
176-
val YrequireAlpha: Setting[Boolean] = BooleanSetting("-Yrequire-alpha", "Warn if an operator is defined without an @alpha annotation")
176+
val YrequireTargetName: Setting[Boolean] = BooleanSetting("-Yrequire-targetName", "Warn if an operator is defined without a @targetName annotation")
177177

178178
/** Area-specific debug output */
179179
val YexplainLowlevel: Setting[Boolean] = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ class Definitions {
937937
@tu lazy val ShowAsInfixAnnot: ClassSymbol = requiredClass("scala.annotation.showAsInfix")
938938
@tu lazy val FunctionalInterfaceAnnot: ClassSymbol = requiredClass("java.lang.FunctionalInterface")
939939
@tu lazy val InfixAnnot: ClassSymbol = requiredClass("scala.annotation.infix")
940-
@tu lazy val AlphaAnnot: ClassSymbol = requiredClass("scala.annotation.alpha")
940+
@tu lazy val TargetNameAnnot: ClassSymbol = requiredClass("scala.annotation.targetName")
941941
@tu lazy val VarargsAnnot: ClassSymbol = requiredClass("scala.annotation.varargs")
942942

943943
// A list of annotations that are commonly used to indicate that a field/method argument or return

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

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ object Denotations {
222222
* when seen from prefix `site`.
223223
* @param relaxed When true, consider only parameter signatures for a match.
224224
*/
225-
def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(using Context): Denotation
225+
def atSignature(sig: Signature, targetName: Name, site: Type = NoPrefix, relaxed: Boolean = false)(using Context): Denotation
226226

227227
/** The variant of this denotation that's current in the given context.
228228
* If no such denotation exists, returns the denotation with each alternative
@@ -347,13 +347,15 @@ object Denotations {
347347
}
348348

349349
/** The alternative of this denotation that has a type matching `targetType` when seen
350-
* as a member of type `site`, `NoDenotation` if none exists.
350+
* as a member of type `site` and that has a target name matching `targetName`, or
351+
* `NoDenotation` if none exists.
351352
*/
352-
def matchingDenotation(site: Type, targetType: Type)(using Context): SingleDenotation = {
353-
def qualifies(sym: Symbol) = site.memberInfo(sym).matchesLoosely(targetType)
353+
def matchingDenotation(site: Type, targetType: Type, targetName: Name)(using Context): SingleDenotation = {
354+
def qualifies(sym: Symbol) =
355+
site.memberInfo(sym).matchesLoosely(targetType) && sym.hasTargetName(targetName)
354356
if (isOverloaded)
355-
atSignature(targetType.signature, site, relaxed = true) match {
356-
case sd: SingleDenotation => sd.matchingDenotation(site, targetType)
357+
atSignature(targetType.signature, targetName, site, relaxed = true) match {
358+
case sd: SingleDenotation => sd.matchingDenotation(site, targetType, targetName)
357359
case md => md.suchThat(qualifies(_))
358360
}
359361
else if (exists && !qualifies(symbol)) NoDenotation
@@ -610,9 +612,9 @@ object Denotations {
610612
def accessibleFrom(pre: Type, superAccess: Boolean)(using Context): Denotation =
611613
if (!symbol.exists || symbol.isAccessibleFrom(pre, superAccess)) this else NoDenotation
612614

613-
def atSignature(sig: Signature, site: Type, relaxed: Boolean)(using Context): SingleDenotation =
615+
def atSignature(sig: Signature, targetName: Name, site: Type, relaxed: Boolean)(using Context): SingleDenotation =
614616
val situated = if site == NoPrefix then this else asSeenFrom(site)
615-
val matches = sig.matchDegree(situated.signature) match
617+
val sigMatches = sig.matchDegree(situated.signature) match
616618
case FullMatch =>
617619
true
618620
case MethodNotAMethodMatch =>
@@ -622,7 +624,7 @@ object Denotations {
622624
relaxed
623625
case noMatch =>
624626
false
625-
if matches then this else NoDenotation
627+
if sigMatches && symbol.hasTargetName(targetName) then this else NoDenotation
626628

627629
def matchesImportBound(bound: Type)(using Context): Boolean =
628630
if bound.isRef(defn.NothingClass) then false
@@ -983,8 +985,12 @@ object Denotations {
983985
final def last: SingleDenotation = this
984986

985987
def matches(other: SingleDenotation)(using Context): Boolean =
986-
val d = signature.matchDegree(other.signature)
988+
symbol.hasTargetName(other.symbol.targetName)
989+
&& matchesLoosely(other)
987990

991+
/** matches without a target name check */
992+
def matchesLoosely(other: SingleDenotation)(using Context): Boolean =
993+
val d = signature.matchDegree(other.signature)
988994
d match
989995
case FullMatch =>
990996
true
@@ -1006,11 +1012,10 @@ object Denotations {
10061012
other.symbol.is(Method)
10071013
}
10081014
case ParamMatch =>
1009-
// The signatures do not tell us enough to be sure about matching
1015+
// The signatures do not tell us enough to be sure about matching
10101016
!ctx.erasedTypes && info.matches(other.info)
10111017
case noMatch =>
10121018
false
1013-
end matches
10141019

10151020
def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(using Context): SingleDenotation =
10161021
if hasUniqueSym && prevDenots.containsSym(symbol) then NoDenotation
@@ -1164,9 +1169,11 @@ object Denotations {
11641169
final def hasUniqueSym: Boolean = false
11651170
final def name(using Context): Name = denot1.name
11661171
final def signature(using Context): Signature = Signature.OverloadedSignature
1167-
def atSignature(sig: Signature, site: Type, relaxed: Boolean)(using Context): Denotation =
1172+
def atSignature(sig: Signature, targetName: Name, site: Type, relaxed: Boolean)(using Context): Denotation =
11681173
if (sig eq Signature.OverloadedSignature) this
1169-
else derivedUnionDenotation(denot1.atSignature(sig, site, relaxed), denot2.atSignature(sig, site, relaxed))
1174+
else derivedUnionDenotation(
1175+
denot1.atSignature(sig, targetName, site, relaxed),
1176+
denot2.atSignature(sig, targetName, site, relaxed))
11701177
def current(using Context): Denotation =
11711178
derivedUnionDenotation(denot1.current, denot2.current)
11721179
def altsWith(p: Symbol => Boolean): List[SingleDenotation] =
@@ -1263,7 +1270,6 @@ object Denotations {
12631270
else ctx.run.staticRefs.getOrElseUpdate(path, recur(path))
12641271
}
12651272

1266-
12671273
/** If we are looking for a non-existing term name in a package,
12681274
* assume it is a package for which we do not have a directory and
12691275
* enter it.

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,17 +371,19 @@ object NameKinds {
371371
/** A name together with a signature. Used in Tasty trees. */
372372
object SignedName extends NameKind(SIGNED) {
373373

374-
case class SignedInfo(sig: Signature) extends Info {
374+
case class SignedInfo(sig: Signature, target: TermName) extends Info {
375375
assert(sig ne Signature.NotAMethod)
376-
override def toString: String = s"$infoString $sig"
376+
override def toString: String =
377+
val targetStr = if target.isEmpty then "" else s" @$target"
378+
s"$infoString $sig$targetStr"
377379
override def hashCode = scala.runtime.ScalaRunTime._hashCode(this) * 31 + kind.hashCode
378380
}
379381
type ThisInfo = SignedInfo
380382

381-
def apply(qual: TermName, sig: Signature): TermName =
382-
qual.derived(new SignedInfo(sig))
383-
def unapply(name: DerivedName): Option[(TermName, Signature)] = name match {
384-
case DerivedName(underlying, info: SignedInfo) => Some((underlying, info.sig))
383+
def apply(qual: TermName, sig: Signature, target: TermName): TermName =
384+
qual.derived(new SignedInfo(sig, target))
385+
def unapply(name: DerivedName): Option[(TermName, Signature, TermName)] = name match {
386+
case DerivedName(underlying, info: SignedInfo) => Some((underlying, info.sig, info.target))
385387
case _ => None
386388
}
387389

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ object NameOps {
170170
}
171171
}
172172

173+
/** Do two target names match? An empty target name matchws any other name. */
174+
def matchesTargetName(other: Name) =
175+
name == other || name.isEmpty || other.isEmpty
176+
173177
private def functionSuffixStart: Int =
174178
val first = name.firstPart
175179
var idx = first.length - 1

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@ object NameTags extends TastyFormat.NameTags {
5252
case OBJECTCLASS => "OBJECTCLASS"
5353

5454
case SIGNED => "SIGNED"
55+
case TARGETSIGNED => "TARGETSIGNED"
5556
}
5657
}

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

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -495,26 +495,40 @@ object SymDenotations {
495495
/** `fullName` where `.' is the separator character */
496496
def fullName(using Context): Name = fullNameSeparated(QualifiedName)
497497

498-
/** The name given in an `@alpha` annotation if one is present, `name` otherwise */
499-
final def erasedName(using Context): Name =
500-
val alphaAnnot =
501-
if isAllOf(ModuleClass | Synthetic) then companionClass.getAnnotation(defn.AlphaAnnot)
502-
else getAnnotation(defn.AlphaAnnot)
503-
alphaAnnot match {
498+
private var myTargetName: Name = null
499+
500+
private def computeTargetName(targetNameAnnot: Option[Annotation])(using Context): Name =
501+
targetNameAnnot match
504502
case Some(ann) =>
505-
ann.arguments match {
503+
ann.arguments match
506504
case Literal(Constant(str: String)) :: Nil =>
507-
if (isType)
508-
if (is(ModuleClass))
509-
str.toTypeName.moduleClassName
510-
else
511-
str.toTypeName
512-
else
513-
str.toTermName
505+
if isType then
506+
if is(ModuleClass) then str.toTypeName.moduleClassName
507+
else str.toTypeName
508+
else str.toTermName
514509
case _ => name
515-
}
516510
case _ => name
517-
}
511+
512+
def setTargetName(name: Name): Unit =
513+
myTargetName = name
514+
515+
def hasTargetName(name: Name)(using Context): Boolean =
516+
targetName.matchesTargetName(name)
517+
518+
/** The name given in a `@targetName` annotation if one is present, `name` otherwise */
519+
def targetName(using Context): Name =
520+
if myTargetName == null then
521+
val carrier: SymDenotation =
522+
if isAllOf(ModuleClass | Synthetic) then companionClass else this
523+
val targetNameAnnot =
524+
if carrier.isCompleting // annotations have been set already in this case
525+
then carrier.unforcedAnnotation(defn.TargetNameAnnot)
526+
else carrier.getAnnotation(defn.TargetNameAnnot)
527+
myTargetName = computeTargetName(targetNameAnnot)
528+
if name.is(SuperAccessorName) then
529+
myTargetName = myTargetName.unmangle(List(ExpandedName, SuperAccessorName, ExpandPrefixName))
530+
531+
myTargetName
518532

519533
// ----- Tests -------------------------------------------------
520534

@@ -1243,7 +1257,7 @@ object SymDenotations {
12431257
final def matchingDecl(inClass: Symbol, site: Type)(using Context): Symbol = {
12441258
var denot = inClass.info.nonPrivateDecl(name)
12451259
if (denot.isTerm) // types of the same name always match
1246-
denot = denot.matchingDenotation(site, site.memberInfo(symbol))
1260+
denot = denot.matchingDenotation(site, site.memberInfo(symbol), symbol.targetName)
12471261
denot.symbol
12481262
}
12491263

@@ -1252,7 +1266,7 @@ object SymDenotations {
12521266
final def matchingMember(site: Type)(using Context): Symbol = {
12531267
var denot = site.nonPrivateMember(name)
12541268
if (denot.isTerm) // types of the same name always match
1255-
denot = denot.matchingDenotation(site, site.memberInfo(symbol))
1269+
denot = denot.matchingDenotation(site, site.memberInfo(symbol), symbol.targetName)
12561270
denot.symbol
12571271
}
12581272

@@ -2323,6 +2337,7 @@ object SymDenotations {
23232337
override def mapInfo(f: Type => Type)(using Context): SingleDenotation = this
23242338

23252339
override def matches(other: SingleDenotation)(using Context): Boolean = false
2340+
override def targetName(using Context): Name = EmptyTermName
23262341
override def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(using Context): SingleDenotation = this
23272342
override def filterWithPredicate(p: SingleDenotation => Boolean): SingleDenotation = this
23282343
override def filterDisjoint(denots: PreDenotation)(using Context): SingleDenotation = this

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,8 +1457,8 @@ object Types {
14571457
def select(name: TermName)(using Context): TermRef =
14581458
TermRef(this, name, member(name))
14591459

1460-
def select(name: TermName, sig: Signature)(using Context): TermRef =
1461-
TermRef(this, name, member(name).atSignature(sig, relaxed = !ctx.erasedTypes))
1460+
def select(name: TermName, sig: Signature, target: Name)(using Context): TermRef =
1461+
TermRef(this, name, member(name).atSignature(sig, target, relaxed = !ctx.erasedTypes))
14621462

14631463
// ----- Access to parts --------------------------------------------
14641464

@@ -2084,14 +2084,14 @@ object Types {
20842084
}
20852085

20862086
private def disambiguate(d: Denotation)(using Context): Denotation =
2087-
disambiguate(d, currentSignature)
2087+
disambiguate(d, currentSignature, currentSymbol.targetName)
20882088

2089-
private def disambiguate(d: Denotation, sig: Signature)(using Context): Denotation =
2089+
private def disambiguate(d: Denotation, sig: Signature, target: Name)(using Context): Denotation =
20902090
if (sig != null)
2091-
d.atSignature(sig, relaxed = !ctx.erasedTypes) match {
2091+
d.atSignature(sig, target, relaxed = !ctx.erasedTypes) match {
20922092
case d1: SingleDenotation => d1
20932093
case d1 =>
2094-
d1.atSignature(sig, relaxed = false) match {
2094+
d1.atSignature(sig, target, relaxed = false) match {
20952095
case d2: SingleDenotation => d2
20962096
case d2 => d2.suchThat(currentSymbol.eq).orElse(d2)
20972097
}
@@ -2395,7 +2395,8 @@ object Types {
23952395
if (d.isOverloaded && lastSymbol.exists)
23962396
d = disambiguate(d,
23972397
if (lastSymbol.signature == Signature.NotAMethod) Signature.NotAMethod
2398-
else lastSymbol.asSeenFrom(prefix).signature)
2398+
else lastSymbol.asSeenFrom(prefix).signature,
2399+
lastSymbol.targetName)
23992400
NamedType(prefix, name, d)
24002401
}
24012402
if (prefix eq this.prefix) this

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import TastyBuffer._
99
import collection.mutable
1010
import Names.{Name, chrs, SimpleName, DerivedName, TypeName}
1111
import NameKinds._
12+
import NameOps._
1213
import Decorators._
1314
import scala.io.Codec
15+
import NameTags.{SIGNED, TARGETSIGNED}
1416

1517
class NameBuffer extends TastyBuffer(10000) {
1618
import NameBuffer._
@@ -24,8 +26,9 @@ class NameBuffer extends TastyBuffer(10000) {
2426
ref
2527
case None =>
2628
name1 match {
27-
case SignedName(original, Signature(params, result)) =>
29+
case SignedName(original, Signature(params, result), target) =>
2830
nameIndex(original)
31+
if !original.matchesTargetName(target) then nameIndex(target)
2932
nameIndex(result)
3033
params.foreach {
3134
case param: TypeName =>
@@ -70,29 +73,39 @@ class NameBuffer extends TastyBuffer(10000) {
7073

7174
def pickleNameContents(name: Name): Unit = {
7275
val tag = name.toTermName.info.kind.tag
73-
writeByte(tag)
7476
name.toTermName match {
7577
case name: SimpleName =>
78+
writeByte(tag)
7679
val bytes =
7780
if (name.length == 0) new Array[Byte](0)
7881
else Codec.toUTF8(chrs, name.start, name.length)
7982
writeNat(bytes.length)
8083
writeBytes(bytes, bytes.length)
8184
case AnyQualifiedName(prefix, name) =>
85+
writeByte(tag)
8286
withLength { writeNameRef(prefix); writeNameRef(name) }
8387
case AnyUniqueName(original, separator, num) =>
88+
writeByte(tag)
8489
withLength {
8590
writeNameRef(separator)
8691
writeNat(num)
8792
if (!original.isEmpty) writeNameRef(original)
8893
}
8994
case AnyNumberedName(original, num) =>
95+
writeByte(tag)
9096
withLength { writeNameRef(original); writeNat(num) }
91-
case SignedName(original, Signature(paramsSig, result)) =>
97+
case SignedName(original, Signature(paramsSig, result), target) =>
98+
val needsTarget = !original.matchesTargetName(target)
99+
writeByte(if needsTarget then TARGETSIGNED else SIGNED)
92100
withLength(
93-
{ writeNameRef(original); writeNameRef(result); paramsSig.foreach(writeParamSig) },
94-
if ((paramsSig.length + 2) * maxIndexWidth <= maxNumInByte) 1 else 2)
101+
{ writeNameRef(original)
102+
if needsTarget then writeNameRef(target)
103+
writeNameRef(result)
104+
paramsSig.foreach(writeParamSig)
105+
},
106+
if ((paramsSig.length + 3) * maxIndexWidth <= maxNumInByte) 1 else 2)
95107
case DerivedName(original, _) =>
108+
writeByte(tag)
96109
withLength { writeNameRef(original) }
97110
}
98111
}

0 commit comments

Comments
 (0)