Skip to content

Commit

Permalink
Fix problem with extension methods in givens
Browse files Browse the repository at this point in the history
For these we need an eligibility pre-check. That pre-check
did not skip leading implicit parameters, so failed to recognize
eligible extension methods.
  • Loading branch information
odersky committed Jan 5, 2021
1 parent 5cd3a3a commit 872082e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,10 @@ trait Applications extends Compatibility {
*/
def hasExtensionMethodNamed(tp: Type, xname: TermName, argType: Type, resultType: Type)(using Context) = {
def qualifies(mbr: Denotation) =
mbr.exists && isApplicableType(tp.select(xname, mbr), argType :: Nil, resultType)
mbr.exists
&& isApplicableType(
normalize(tp.select(xname, mbr), WildcardType),
argType :: Nil, resultType)
tp.memberBasedOnFlags(xname, required = ExtensionMethod) match {
case mbr: SingleDenotation => qualifies(mbr)
case mbr => mbr.hasAltWith(qualifies(_))
Expand Down
37 changes: 37 additions & 0 deletions tests/pos/i9530.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
trait Food
case class Banana(color: String) extends Food

trait Diet[A <: Animal]:
type F <: Food
def food: Seq[F]

trait Animal
object Animal:
extension [A <: Animal](using diet: Diet[A])(animal: A) def food1 = diet.food
extension [A <: Animal](animal: A)(using diet: Diet[A]) def food2 = diet.food

extension [A <: Animal](using diet: Diet[A])(animal: A) def food3 = diet.food
extension [A <: Animal](animal: A)(using diet: Diet[A]) def food4 = diet.food

trait Monkey extends Animal

given Diet[Monkey] with
type F = Banana
def food: Seq[Banana] = Seq(new Banana("yellow"), Banana("green"))

trait FoodOps
given FoodOps with
extension [A <: Animal](using diet: Diet[A])(animal: A) def food5 = diet.food
extension [A <: Animal](animal: A)(using diet: Diet[A]) def food6 = diet.food


val monkey = new Monkey {}

val foods = Seq(
monkey.food1, // doesn't compile
monkey.food2, // compiles
monkey.food3, // compiles
monkey.food4, // compiles
monkey.food5, // doesn't compile
monkey.food6, // compiles
)

0 comments on commit 872082e

Please sign in to comment.