Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3277,7 +3277,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val superCls = cls.superClass
superCls.exists && superCls.asClass.baseClasses.contains(m.symbol.owner)

def givenImpl(mbr: TermRef): ValDef =
def givenImpl(mbr: TermRef): ValDef | EmptyTree.type =
val dcl = mbr.symbol
val target = dcl.info.asSeenFrom(cls.thisType, dcl.owner)
val constr = cls.primaryConstructor
Expand Down Expand Up @@ -3315,7 +3315,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
cpy.Select(id)(This(cls), id.name)
case _ =>
super.transform(tree)
ValDef(impl, anchorParams.transform(rhs)).withSpan(impl.span.endPos)

rhs.tpe match
case tp: NamedType if tp.prefix.typeSymbol == cls && tp.name == mbr.name && !tp.typeSymbol.is(Method) =>
report.error(
em"""Inferred implementation of the deferred ${dcl.showLocated} is self-recursive.
|An implementing given needs to be written explicitly.""",
cdef.srcPos)
EmptyTree
case _ =>
ValDef(impl, anchorParams.transform(rhs)).withSpan(impl.span.endPos)
end givenImpl

val givenImpls =
Expand Down
7 changes: 7 additions & 0 deletions tests/neg/i22589.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Error: tests/neg/i22589.scala:15:7 ----------------------------------------------------------------------------------
15 |object Person extends CompanionEssentials[Person]: // error
|^
|Inferred implementation of the deferred given instance given_MyCodec_E in trait CompanionEssentials is self-recursive.
|An implementing given needs to be written explicitly.
16 | //override final lazy given given_MyCodec_E: MyCodec[Person] = Person.given_MyCodec_E
17 | override def toString = ""
17 changes: 17 additions & 0 deletions tests/neg/i22589.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

//> using options -Wsafe-init -Ysafe-init-global

import scala.compiletime.deferred

trait MyCodec[E]

object auto:
trait CompanionEssentials[E]:
given MyCodec[E] = deferred

import auto.CompanionEssentials

case class Person(name: String, age: Int)
object Person extends CompanionEssentials[Person]: // error
//override final lazy given given_MyCodec_E: MyCodec[Person] = Person.given_MyCodec_E
override def toString = ""
8 changes: 8 additions & 0 deletions tests/neg/i22589b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Error: tests/neg/i22589b.scala:13:7 ---------------------------------------------------------------------------------
13 |object Person extends CompanionEssentials[Person]: // error
|^
|Inferred implementation of the deferred given instance myc in trait CompanionEssentials is self-recursive.
|An implementing given needs to be written explicitly.
14 | given String = "hw"
15 | given myc(using String): MyCodec[Person] = new MyCodec[Person] {}
16 | override def toString = ""
16 changes: 16 additions & 0 deletions tests/neg/i22589b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

import scala.compiletime.deferred

trait MyCodec[E]

object auto:
trait CompanionEssentials[E]:
given myc: MyCodec[E] = deferred

import auto.CompanionEssentials

case class Person(name: String, age: Int)
object Person extends CompanionEssentials[Person]: // error
given String = "hw"
given myc(using String): MyCodec[Person] = new MyCodec[Person] {}
override def toString = ""
7 changes: 7 additions & 0 deletions tests/neg/i22589c.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Error: tests/neg/i22589c.scala:8:7 ----------------------------------------------------------------------------------
8 |object A extends Base[A.P] { // error
|^
|Inferred implementation of the deferred given instance given_TC_T in trait Base is self-recursive.
|An implementing given needs to be written explicitly.
9 | case class P()
10 |}
10 changes: 10 additions & 0 deletions tests/neg/i22589c.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

trait TC[T]

trait Base[T] {
given TC[T] = scala.compiletime.deferred
}

object A extends Base[A.P] { // error
case class P()
}
17 changes: 17 additions & 0 deletions tests/pos/i22589.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

import scala.compiletime.deferred

trait MyCodec[E]

object auto:
trait CompanionEssentials[E]:
//given [E] => MyCodec[E] = deferred
given MyCodec[E] = deferred

import auto.CompanionEssentials

case class Person(name: String, age: Int)
object Person extends CompanionEssentials[Person]:
//given something: [E] => MyCodec[E] = new MyCodec[E] {}
given something: MyCodec[Person] = new MyCodec[Person] {}
override def toString = ""
Loading