Skip to content

Commit 6c4eace

Browse files
authored
fix: Only implement a deferred given in a class if its parent won't implement it (#21206)
It should be possible to extend a class that inherits a deferred given, so a generated given implementation should not be final. closes #21189
2 parents e261fa2 + 532c287 commit 6c4eace

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3044,7 +3044,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
30443044
body
30453045

30463046
/** Implement givens that were declared with a `deferred` rhs.
3047-
* The a given value matching the declared type is searched in a
3047+
* The given value matching the declared type is searched in a
30483048
* context directly enclosing the current class, in which all given
30493049
* parameters of the current class are also defined.
30503050
*/
@@ -3061,6 +3061,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
30613061
false
30623062
else true
30633063

3064+
def willBeimplementedInParentClass(m: TermRef) =
3065+
val superCls = cls.superClass
3066+
superCls.exists && superCls.asClass.baseClasses.contains(m.symbol.owner)
3067+
30643068
def givenImpl(mbr: TermRef): ValDef =
30653069
val dcl = mbr.symbol
30663070
val target = dcl.info.asSeenFrom(cls.thisType, dcl.owner)
@@ -3090,6 +3094,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
30903094
cls.thisType.implicitMembers
30913095
//.showing(i"impl def givens for $cls/$result")
30923096
.filter(_.symbol.isAllOf(DeferredGivenFlags, butNot = Param))
3097+
.filter(!willBeimplementedInParentClass(_)) // only implement the given in the topmost class
30933098
//.showing(i"impl def filtered givens for $cls/$result")
30943099
.filter(isGivenValue)
30953100
.map(givenImpl)

tests/pos/i21189-alt.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//> using options -source:future -language:experimental.modularity
2+
3+
class MySortedSet[T : Ord] extends SortedSet[T]
4+
5+
trait Ord[T]
6+
7+
trait Sorted[T] extends ParentOfSorted[T]
8+
9+
trait ParentOfSorted[T]:
10+
given Ord[T] as ord = compiletime.deferred
11+
12+
class SortedSet[T : Ord] extends Sorted[T]

tests/pos/i21189.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//> using options -source:future -language:experimental.modularity
2+
3+
class MySortedSet[T : Ord] extends SortedSet[T]
4+
5+
trait Ord[T]
6+
7+
trait Sorted[T]:
8+
given Ord[T] as ord = compiletime.deferred
9+
10+
class SortedSet[T : Ord] extends Sorted[T]

0 commit comments

Comments
 (0)