Skip to content

Commit 0844344

Browse files
oderskymichelou
authored andcommitted
Refine & document clash detection scheme
1 parent d747c45 commit 0844344

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,9 +1080,14 @@ class Namer { typer: Typer =>
10801080
val renamed = mutable.Set[Name]()
10811081
val selectors = selectors0 map {
10821082
case sel @ ImportSelector(imported, id @ Ident(alias), bound) if alias != nme.WILDCARD =>
1083+
def noAliasSelector =
1084+
cpy.ImportSelector(sel)(imported, EmptyTree, bound).asInstanceOf[ImportSelector]
10831085
if renamed.contains(alias) then
10841086
report.error(i"duplicate rename target", id.srcPos)
1085-
cpy.ImportSelector(sel)(imported, EmptyTree, bound).asInstanceOf[ImportSelector]
1087+
noAliasSelector
1088+
else if alias == imported.name then
1089+
report.warning(i"redundant rename in export", id.srcPos)
1090+
noAliasSelector
10861091
else
10871092
renamed += alias
10881093
sel
@@ -1094,7 +1099,7 @@ class Namer { typer: Typer =>
10941099
lazy val wildcardBound = importBound(selectors, isGiven = false)
10951100
lazy val givenBound = importBound(selectors, isGiven = true)
10961101

1097-
def canForward(mbr: SingleDenotation): CanForward = {
1102+
def canForward(mbr: SingleDenotation, alias: TermName): CanForward = {
10981103
import CanForward.*
10991104
val sym = mbr.symbol
11001105
if !sym.isAccessibleFrom(path.tpe) then
@@ -1103,7 +1108,7 @@ class Namer { typer: Typer =>
11031108
Skip
11041109
else if cls.derivesFrom(sym.owner) && (sym.owner == cls || !sym.is(Deferred)) then
11051110
No(i"is already a member of $cls")
1106-
else if renamed.contains(sym.name.toTermName) then
1111+
else if alias == mbr.name.toTermName && renamed.contains(alias) then
11071112
No(i"clashes with a renamed export")
11081113
else if sym.is(Override) then
11091114
sym.allOverriddenSymbols.find(
@@ -1147,7 +1152,7 @@ class Namer { typer: Typer =>
11471152
case _ =>
11481153
acc.reverse ::: prefss
11491154

1150-
if canForward(mbr) == CanForward.Yes then
1155+
if canForward(mbr, alias) == CanForward.Yes then
11511156
val sym = mbr.symbol
11521157
val hasDefaults = sym.hasDefaultParams // compute here to ensure HasDefaultParams and NoDefaultParams flags are set
11531158
val forwarder =
@@ -1204,7 +1209,7 @@ class Namer { typer: Typer =>
12041209
val mbrs = List(name, name.toTypeName).flatMap(path.tpe.member(_).alternatives)
12051210
mbrs.foreach(addForwarder(alias, _, span))
12061211
if buf.size == size then
1207-
val reason = mbrs.map(canForward).collect {
1212+
val reason = mbrs.map(canForward(_, alias)).collect {
12081213
case CanForward.No(whyNot) => i"\n$path.$name cannot be exported because it $whyNot"
12091214
}.headOption.getOrElse("")
12101215
report.error(i"""no eligible member $name at $path$reason""", ctx.source.atSpan(span))

docs/_docs/reference/other-new-features/export.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ def f: c.T = ...
100100

101101
1. Export clauses can appear in classes or they can appear at the top-level. An export clause cannot appear as a statement in a block.
102102
1. If an export clause contains a wildcard or given selector, it is forbidden for its qualifier path to refer to a package. This is because it is not yet known how to safely track wildcard dependencies to a package for the purposes of incremental compilation.
103+
1. An export renaming hides un-renamed exports matching the target name. For instance, the following
104+
clause would be invalid since `B` is hidden by the renaming `A as B`.
105+
```scala
106+
export {A as B, B} // error: B is hidden
107+
```
108+
109+
1. Renamings in an export clause must have pairwise different target names. For instance, the following clause would be invalid:
110+
```scala
111+
export {A as C, B as C} // error: duplicate renaming
103112

104113
1. Simple renaming exports like
105114
```scala

tests/neg/i14818.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ object T3:
1818
object T4:
1919
export M.{A as C, B as C} // error
2020

21+
object T5:
22+
export M.{A as B, B as A} // OK
23+

0 commit comments

Comments
 (0)