Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inlining failure when accessing same-named private members in sub and superclass #15612

Closed
WojciechMazur opened this issue Jul 7, 2022 · 2 comments · Fixed by #15619
Closed
Labels
area:inline itype:bug regression This worked in a previous version but doesn't anymore
Milestone

Comments

@WojciechMazur
Copy link
Contributor

Based on the community build failure https://scala3.westeurope.cloudapp.azure.com/blue/organizations/jenkins/buildCommunityProject/detail/buildCommunityProject/1136/pipeline/
Library maintainer @tabdulradi

Problem exists only if both open classes define extension methods using type matching

Compiler version

Works in 3.1.3
Fails in 3.2.0-RC1 and RC2
Fails in 3.2.1-RC1-bin-20220706-9d07d52-NIGHTLY

Minimized code

import scala.reflect.TypeTest

open class ForSyntax[E](using E: TypeTest[E | Any, E]):
  extension [A](aOrE: E | A)
    inline def flatMap[B](f: A => E | B): E | B =
      aOrE match
        case e: E => ???
        case _ => ???


open class UnhappyCase[E](using E: TypeTest[E | Any, E]) extends ForSyntax[E]: 
  extension [A](aOrE: E | A) 
    inline def fold[B](inline fe: E => B, inline fa: A => B): B =
      aOrE match
        case e: E => ??? 
        case _ => ???

Output

[error] ./test.scala:11:33: error overriding method inline$E in class ForSyntax of type => reflect.TypeTest[E | Any, E];
[error]   method inline$E of type => reflect.TypeTest[E | Any, E] cannot override final member method inline$E in class ForSyntax
[error] open class UnhappyCase[E](using E: TypeTest[E | Any, E]) extends ForSyntax[E]: 
[error]                                 ^
Error compiling project (Scala 3.2.1-RC1-bin-20220706-9d07d52-NIGHTLY, JVM)

Expectation

Should compile

@WojciechMazur WojciechMazur added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 7, 2022
@rochala rochala added area:typer regression This worked in a previous version but doesn't anymore area:pattern-matching and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jul 7, 2022
@SethTisue SethTisue changed the title Cannot match types in extenstion methods of open class extening other open class Cannot match types in extension methods of open class extending other open class Jul 7, 2022
@KacperFKorban
Copy link
Member

KacperFKorban commented Jul 8, 2022

Minimization

A bit smaller example:

class Parent[E](using u: Unit):
  inline def m: Any = u

class Klass[E](using u: Unit) extends Parent[E]:
  inline def n: Any = u

Error:

-- [E164] Declaration Error: tests/pos/i15612.scala:4:21 -----------------------
4 |class Klass[E](using u: Unit) extends Parent[E]:
  |                     ^
  |error overriding method inline$u in class Parent of type => Unit;
  |  method inline$u of type => Unit cannot override final member method inline$u in class Parent

Explanation

The first commit that breaks this is: 13df1bc

The problem here is that the given vals are private and so the inline accessors are generated to be final not to override them by mistake.

Generated tree (after refchecks):

package <empty> {
  @SourceFile("tests/pos/i15612.scala") class Parent[E](using u: Unit) extends 
    Object
  () {
    E
    private[this] given val u: Unit
    inline def m: Any = this.inline$u:Any
    final def inline$u: Unit = Parent.this.u
  }
  @SourceFile("tests/pos/i15612.scala") class Klass[E](using u: Unit) extends 
    Parent[E]
  (u)() {
    E
    private[this] given val u: Unit
    inline def n: Any = this.inline$u:Any
    final def inline$u: Unit = Klass.this.u
  }
}

Workaround

A possible workaround here is to make those givens protected and override them explicitly. (since semantically those TypeTests are the same for us)
Like so:

class Parent[E](using protected val u: Unit):
  inline def m: Any = u

class Klass[E](using override protected val u: Unit) extends Parent[E]:
  inline def n: Any = u

@odersky
Copy link
Contributor

odersky commented Jul 8, 2022

Minimization:

class A:
  private val a = 1
  inline def foo() = a
class B extends A:
  private val a = 2
  inline def bar() = a

@odersky odersky changed the title Cannot match types in extension methods of open class extending other open class Inlining failure when accessing same-named private members in sub and superclass Jul 8, 2022
odersky added a commit to dotty-staging/dotty that referenced this issue Jul 8, 2022
Kordyjan pushed a commit to dotty-staging/dotty that referenced this issue Jul 26, 2022
Kordyjan pushed a commit to dotty-staging/dotty that referenced this issue Jul 26, 2022
bishabosha pushed a commit to dotty-staging/dotty that referenced this issue Oct 18, 2022
@Kordyjan Kordyjan added this to the 3.2.1 milestone Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:inline itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants