diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index a826e186c9b0..f458b703472d 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -232,14 +232,16 @@ object desugar { flags: FlagSet, freshName: => TermName)(using Context): Tree = rhs match case ContextBounds(tbounds, cxbounds) => + val isMember = flags.isAllOf(DeferredGivenFlags) for bound <- cxbounds do val evidenceName = bound match case ContextBoundTypeTree(_, _, ownName) if !ownName.isEmpty => ownName - case _ if Feature.enabled(Feature.modularity) && cxbounds.tail.isEmpty => + case _ if !isMember && cxbounds.tail.isEmpty && Feature.enabled(Feature.modularity) => tname.toTermName case _ => - freshName + if isMember then inventGivenOrExtensionName(bound) + else freshName val evidenceParam = ValDef(evidenceName, bound, EmptyTree).withFlags(flags) evidenceParam.pushAttachment(ContextBoundParam, ()) evidenceBuf += evidenceParam @@ -1202,6 +1204,8 @@ object desugar { case tree: TypeDef => tree.name.toString case tree: AppliedTypeTree if followArgs && tree.args.nonEmpty => s"${apply(x, tree.tpt)}_${extractArgs(tree.args)}" + case ContextBoundTypeTree(tycon, paramName, _) => + s"${apply(x, tycon)}_$paramName" case InfixOp(left, op, right) => if followArgs then s"${op.name}_${extractArgs(List(left, right))}" else op.name.toString diff --git a/docs/_docs/reference/experimental/typeclasses-syntax.md b/docs/_docs/reference/experimental/typeclasses-syntax.md index 03e64be1955f..1d746a995dad 100644 --- a/docs/_docs/reference/experimental/typeclasses-syntax.md +++ b/docs/_docs/reference/experimental/typeclasses-syntax.md @@ -185,22 +185,15 @@ The compiler expands this to the following implementation: ```scala trait Sorted: type Element - given Ord[Element] as Element = compiletime.deferred + given Ord[Element] = compiletime.deferred class SortedSet[A](using A: Ord[A]) extends Sorted: type Element = A - override given Ord[Element] as Element = A // i.e. the A defined by the using clause + override given Ord[Element] = A // i.e. the A defined by the using clause ``` The using clause in class `SortedSet` provides an implementation for the deferred given in trait `Sorted`. -If there is a single context bound, as in -```scala - type T : C -``` -the synthesized deferred given will get the (term-)name of the constrained type `T`. If there are multiple bounds, -the standard convention for naming anonymous givens applies. - **Benefits:** - Better orthogonality, type parameters and abstract type members now accept the same kinds of bounds. diff --git a/docs/_docs/reference/experimental/typeclasses.md b/docs/_docs/reference/experimental/typeclasses.md index 91541400ed13..79abed7be6a8 100644 --- a/docs/_docs/reference/experimental/typeclasses.md +++ b/docs/_docs/reference/experimental/typeclasses.md @@ -306,22 +306,15 @@ The compiler expands this to the following implementation: ```scala trait Sorted: type Element - given Ord[Element] as Element = compiletime.deferred + given Ord[Element] = compiletime.deferred class SortedSet[A](using A: Ord[A]) extends Sorted: type Element = A - override given Ord[Element] as Element = A // i.e. the A defined by the using clause + override given Ord[Element] = A // i.e. the A defined by the using clause ``` The using clause in class `SortedSet` provides an implementation for the deferred given in trait `Sorted`. -If there is a single context bound, as in -```scala - type T : C -``` -the synthesized deferred given will get the (term-)name of the constrained type `T`. If there are multiple bounds, -the standard convention for naming anonymous givens applies. - **Benefits:** - Better orthogonality, type parameters and abstract type members now accept the same kinds of bounds. diff --git a/tests/pos/deferred-givens.scala b/tests/pos/deferred-givens.scala index 3419ac8d8a4d..b9018c97e151 100644 --- a/tests/pos/deferred-givens.scala +++ b/tests/pos/deferred-givens.scala @@ -9,7 +9,7 @@ trait A: class AC extends A: type Elem = Double - override given Ord[Elem] as Elem = ??? + override given Ord[Elem] = ??? class AD extends A: type Elem = Double @@ -34,4 +34,3 @@ class E(using x: Ord[String]) extends B: class F[X: Ord] extends B: type Elem = X -