From 9adecd55675b38d6e9ba6b15099ba6fff6261753 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 15 Jul 2021 12:54:30 +0200 Subject: [PATCH] Fix definition of enclosingExtensionMethod Now also finds enclosing methods outside the current class. Fixes #13075 --- .../tools/dotc/core/SymDenotations.scala | 3 +- tests/neg/i13075.scala | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i13075.scala diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 112bd182b1ad..df2c195b9e74 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1140,11 +1140,10 @@ object SymDenotations { else NoSymbol /** The closest enclosing extension method containing this definition, - * provided the extension method appears in the same class. + * including methods outside the current class. */ final def enclosingExtensionMethod(using Context): Symbol = if this.is(ExtensionMethod) then symbol - else if this.isClass then NoSymbol else if this.exists then owner.enclosingExtensionMethod else NoSymbol diff --git a/tests/neg/i13075.scala b/tests/neg/i13075.scala new file mode 100644 index 000000000000..2a5ff70c0481 --- /dev/null +++ b/tests/neg/i13075.scala @@ -0,0 +1,40 @@ +object Implementing_Tuples: + + sealed trait Tup + case class ConsTup[T, H <: Tup](head: T, tail: H) extends Tup + case object EmptyTup extends Tup + + val *: = ConsTup // for unapply + type *:[H, T <: Tup] = ConsTup[H, T] // for type matching + type EmptyTup = EmptyTup.type // for type matching + + extension [H](head: H) + def *:[T <: Tup](tail: T) = ConsTup(head, tail) + + type Fold[T <: Tup, Seed, F[_,_]] = T match + case EmptyTup => Seed + case h *: t => Fold[t, F[Seed, h], F] + + extension [T <: Tup](v: T) + def fold[Seed, F[_,_]](seed: Seed)( + fn: [C, Acc] => (C, Acc) => F[C, Acc] + ): Fold[T, Seed, F] = + (v match + case EmptyTup => seed + case h *: t => t.fold(fn(h, seed))(fn) + ).asInstanceOf[Fold[T, Seed, F]] + + extension [T <: Tup](v: T) def reversed: Tup = + v.fold[EmptyTup, [C, Acc] =>> Acc match { + case h *: t => C *: h *: t + }](EmptyTup)( + [C, Acc] => (c: C, acc: Acc) => acc match + case _@(_ *: _) => c *: acc // error + ) + + @main def testProperFold = + val t = (1 *: '2' *: "foo" *: EmptyTup) + val reversed: (String *: Char *: Int *: EmptyTup) = t.reversed // error + println(reversed) + +end Implementing_Tuples \ No newline at end of file