Skip to content

Commit 8e309b0

Browse files
authored
Merge pull request #15712 from dotty-staging/fix-15702
Fix expansion and unexpansion of mixin qualified names
2 parents 6c7acf9 + 9f4871b commit 8e309b0

File tree

6 files changed

+50
-6
lines changed

6 files changed

+50
-6
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ object NameOps {
146146

147147
/** Revert the expanded name. */
148148
def unexpandedName: N = likeSpacedN {
149-
name.replace { case ExpandedName(_, unexp) => unexp }
149+
name.replaceDeep {
150+
case ExpandedName(_, unexp) => unexp
151+
}
150152
}
151153

152154
def errorName: N = likeSpacedN(name ++ nme.ERROR)

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,18 @@ object Names {
6969

7070
/** Apply rewrite rule given by `f` to some part of this name, skipping and rewrapping
7171
* other decorators.
72-
* Stops at derived names whose kind has `definesNewName = true`.
72+
* Stops at DerivedNames with infos of kind QualifiedInfo.
7373
* If `f` does not apply to any part, return name unchanged.
7474
*/
7575
def replace(f: PartialFunction[Name, Name]): ThisName
7676

77+
/** Same as replace, but does not stop at DerivedNames with infos of kind QualifiedInfo. */
78+
def replaceDeep(f: PartialFunction[Name, Name]): ThisName =
79+
replace(f.orElse {
80+
case DerivedName(underlying, info: QualifiedInfo) =>
81+
underlying.replaceDeep(f).derived(info)
82+
})
83+
7784
/** If partial function `f` is defined for some part of this name, apply it
7885
* in a Some, otherwise None.
7986
* Stops at derived names whose kind has `definesNewName = true`.

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,11 +486,10 @@ object SymDenotations {
486486
def qualify(n: SimpleName) =
487487
val qn = kind(prefix.toTermName, if (filler.isEmpty) n else termName(filler + n))
488488
if kind == FlatName && !encl.is(JavaDefined) then qn.compactified else qn
489-
val fn = name replace {
490-
case name: SimpleName => qualify(name)
491-
case name @ AnyQualifiedName(_, _) => qualify(name.toSimpleName)
489+
val fn = name.replaceDeep {
490+
case n: SimpleName => qualify(n)
492491
}
493-
if (name.isTypeName) fn.toTypeName else fn.toTermName
492+
if name.isTypeName then fn.toTypeName else fn.toTermName
494493
}
495494

496495
/** The encoded flat name of this denotation, where joined names are separated by `separator` characters. */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ object Mixin {
2323
val description: String = "expand trait fields and trait initializers"
2424

2525
def traitSetterName(getter: TermSymbol)(using Context): TermName =
26+
extension (name: Name) def qualifiedToSimple = name.replace {
27+
case n @ AnyQualifiedName(_, _) => n.toSimpleName
28+
}
2629
getter.ensureNotPrivate.name
30+
.qualifiedToSimple // TODO: Find out why TraitSetterNames can't be defined over QualifiedNames
2731
.expandedName(getter.owner, TraitSetterName)
2832
.asTermName.syntheticSetterName
2933
}

tests/run/i15702.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
10
2+
20
3+
200

tests/run/i15702.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
abstract class A:
2+
val n: Int
3+
def foo(): Int = n
4+
5+
trait B:
6+
val m: Int
7+
def foo(): Int = m
8+
9+
trait M extends A with B:
10+
val a: Int
11+
override def foo(): Int = a + super.foo()
12+
13+
trait N extends A with B:
14+
val b: Int
15+
override def foo(): Int = b * super.foo()
16+
17+
class Inner:
18+
println(N.super[A].foo())
19+
println(N.super.foo())
20+
println(foo())
21+
22+
object C extends A with M with N:
23+
val a = 10
24+
val b = 10
25+
val m = 10
26+
val n = 10
27+
new Inner()
28+
29+
@main def Test = C

0 commit comments

Comments
 (0)