From 2b7a6724c9eb0915d76e6f886ba6f782201aa19a Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Tue, 16 Jul 2024 23:38:45 +0200 Subject: [PATCH] fix: Only implement a deferred given in a class if its parent won't implement it [Cherry-picked 532c2871f9c71eb2a39c431ec3616c7df889e92a] --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 7 ++++++- tests/pos/i21189-alt.scala | 12 ++++++++++++ tests/pos/i21189.scala | 10 ++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i21189-alt.scala create mode 100644 tests/pos/i21189.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 96c9fcdc0d1e..b48cff3dc09c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3019,7 +3019,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer body /** Implement givens that were declared with a `deferred` rhs. - * The a given value matching the declared type is searched in a + * The given value matching the declared type is searched in a * context directly enclosing the current class, in which all given * parameters of the current class are also defined. */ @@ -3036,6 +3036,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer false else true + def willBeimplementedInParentClass(m: TermRef) = + val superCls = cls.superClass + superCls.exists && superCls.asClass.baseClasses.contains(m.symbol.owner) + def givenImpl(mbr: TermRef): ValDef = val dcl = mbr.symbol val target = dcl.info.asSeenFrom(cls.thisType, dcl.owner) @@ -3065,6 +3069,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer cls.thisType.implicitMembers //.showing(i"impl def givens for $cls/$result") .filter(_.symbol.isAllOf(DeferredGivenFlags, butNot = Param)) + .filter(!willBeimplementedInParentClass(_)) // only implement the given in the topmost class //.showing(i"impl def filtered givens for $cls/$result") .filter(isGivenValue) .map(givenImpl) diff --git a/tests/pos/i21189-alt.scala b/tests/pos/i21189-alt.scala new file mode 100644 index 000000000000..08213cd627d4 --- /dev/null +++ b/tests/pos/i21189-alt.scala @@ -0,0 +1,12 @@ +//> using options -source:future -language:experimental.modularity + +class MySortedSet[T : Ord] extends SortedSet[T] + +trait Ord[T] + +trait Sorted[T] extends ParentOfSorted[T] + +trait ParentOfSorted[T]: + given Ord[T] as ord = compiletime.deferred + +class SortedSet[T : Ord] extends Sorted[T] diff --git a/tests/pos/i21189.scala b/tests/pos/i21189.scala new file mode 100644 index 000000000000..88a0bf601476 --- /dev/null +++ b/tests/pos/i21189.scala @@ -0,0 +1,10 @@ +//> using options -source:future -language:experimental.modularity + +class MySortedSet[T : Ord] extends SortedSet[T] + +trait Ord[T] + +trait Sorted[T]: + given Ord[T] as ord = compiletime.deferred + +class SortedSet[T : Ord] extends Sorted[T]