Skip to content

Commit ada6be7

Browse files
committed
Don't use member type name for deferred givens
When expanding a context bound of a member type, don't use the member name as the name of the generated deferred given. The same member type might have different single context bounds in different traits. A class inheriting several of these traits would then get double definitions in its given clauses. Partial revert of "Changes to default names for context bound witnesses"
1 parent 8472030 commit ada6be7

File tree

4 files changed

+11
-22
lines changed

4 files changed

+11
-22
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,16 @@ object desugar {
232232
flags: FlagSet,
233233
freshName: => TermName)(using Context): Tree = rhs match
234234
case ContextBounds(tbounds, cxbounds) =>
235+
val isMember = flags.isAllOf(DeferredGivenFlags)
235236
for bound <- cxbounds do
236237
val evidenceName = bound match
237238
case ContextBoundTypeTree(_, _, ownName) if !ownName.isEmpty =>
238239
ownName
239-
case _ if Feature.enabled(Feature.modularity) && cxbounds.tail.isEmpty =>
240+
case _ if !isMember && cxbounds.tail.isEmpty && Feature.enabled(Feature.modularity) =>
240241
tname.toTermName
241242
case _ =>
242-
freshName
243+
if isMember then inventGivenOrExtensionName(bound)
244+
else freshName
243245
val evidenceParam = ValDef(evidenceName, bound, EmptyTree).withFlags(flags)
244246
evidenceParam.pushAttachment(ContextBoundParam, ())
245247
evidenceBuf += evidenceParam
@@ -1202,6 +1204,8 @@ object desugar {
12021204
case tree: TypeDef => tree.name.toString
12031205
case tree: AppliedTypeTree if followArgs && tree.args.nonEmpty =>
12041206
s"${apply(x, tree.tpt)}_${extractArgs(tree.args)}"
1207+
case ContextBoundTypeTree(tycon, paramName, _) =>
1208+
s"${apply(x, tycon)}_$paramName"
12051209
case InfixOp(left, op, right) =>
12061210
if followArgs then s"${op.name}_${extractArgs(List(left, right))}"
12071211
else op.name.toString

docs/_docs/reference/experimental/typeclasses-syntax.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -185,22 +185,15 @@ The compiler expands this to the following implementation:
185185
```scala
186186
trait Sorted:
187187
type Element
188-
given Ord[Element] as Element = compiletime.deferred
188+
given Ord[Element] = compiletime.deferred
189189

190190
class SortedSet[A](using A: Ord[A]) extends Sorted:
191191
type Element = A
192-
override given Ord[Element] as Element = A // i.e. the A defined by the using clause
192+
override given Ord[Element] = A // i.e. the A defined by the using clause
193193
```
194194

195195
The using clause in class `SortedSet` provides an implementation for the deferred given in trait `Sorted`.
196196

197-
If there is a single context bound, as in
198-
```scala
199-
type T : C
200-
```
201-
the synthesized deferred given will get the (term-)name of the constrained type `T`. If there are multiple bounds,
202-
the standard convention for naming anonymous givens applies.
203-
204197
**Benefits:**
205198

206199
- Better orthogonality, type parameters and abstract type members now accept the same kinds of bounds.

docs/_docs/reference/experimental/typeclasses.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -306,22 +306,15 @@ The compiler expands this to the following implementation:
306306
```scala
307307
trait Sorted:
308308
type Element
309-
given Ord[Element] as Element = compiletime.deferred
309+
given Ord[Element] = compiletime.deferred
310310

311311
class SortedSet[A](using A: Ord[A]) extends Sorted:
312312
type Element = A
313-
override given Ord[Element] as Element = A // i.e. the A defined by the using clause
313+
override given Ord[Element] = A // i.e. the A defined by the using clause
314314
```
315315

316316
The using clause in class `SortedSet` provides an implementation for the deferred given in trait `Sorted`.
317317

318-
If there is a single context bound, as in
319-
```scala
320-
type T : C
321-
```
322-
the synthesized deferred given will get the (term-)name of the constrained type `T`. If there are multiple bounds,
323-
the standard convention for naming anonymous givens applies.
324-
325318
**Benefits:**
326319

327320
- Better orthogonality, type parameters and abstract type members now accept the same kinds of bounds.

tests/pos/deferred-givens.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait A:
99

1010
class AC extends A:
1111
type Elem = Double
12-
override given Ord[Elem] as Elem = ???
12+
override given Ord[Elem] = ???
1313

1414
class AD extends A:
1515
type Elem = Double
@@ -34,4 +34,3 @@ class E(using x: Ord[String]) extends B:
3434

3535
class F[X: Ord] extends B:
3636
type Elem = X
37-

0 commit comments

Comments
 (0)