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

Non-definition prefix is not in implicit scope, unlike Dotty #12024

Open
neko-kai opened this issue Jun 1, 2020 · 3 comments
Open

Non-definition prefix is not in implicit scope, unlike Dotty #12024

neko-kai opened this issue Jun 1, 2020 · 3 comments
Labels
Milestone

Comments

@neko-kai
Copy link

neko-kai commented Jun 1, 2020

Minimized code

trait X {
  trait S
}

class Xa(val internal: X) {
  type S = internal.S
  def s: S = new S{}

  implicit class XS(s: S) {
    def printX: Unit = println(s)
  }
}

object Xa extends Xa(new X{})

object App extends App {
  Xa.s.printX
}

Output

  value printX is not a member of Xa.S

The above, unexpectedly, compiles and works with Dotty[1], but not with Scala 2.13[2]

Expectation

Expected Xa.s of type Xa.internal.S to have a distinct implicit scope from other values of type X#S and include the implicits in Xa in implicit scope - as it works in dotty

Another example:

object A {
  object B { object C { class S } }
}
object AX {
  final val B = A.B
  implicit val x: AX.B.C.S = new AX.B.C.S
}
object Test {
  def foo(implicit x: AX.B.C.S) = x
  foo // could not find implicit value for parameter x: AX.B.C.S
}

Expected reference to AX.B.C.S to have a different implicit scope than A.B.C.S, despite being the same type.

Companion issue in dotty scala/scala3#9094

@joroKr21
Copy link
Member

joroKr21 commented Jun 1, 2020

The parts of a type 𝑇 are:
...

  • if 𝑇 is a type alias, the parts of its expansion;
} else if (sym.isAliasType) {
  getParts(tp.normalize) // scala/bug#7180 Normalize needed to expand HK type refs

It looks like scalac and dotty disagree on the order in which rules should be applied 🤔

@neko-kai neko-kai changed the title Alias prefix is not in implicit scope, unlike Dotty Non-definition prefix is not in implicit scope, unlike Dotty Jun 1, 2020
@neko-kai
Copy link
Author

neko-kai commented Jun 1, 2020

@joroKr21 Ah, sorry for the misleading title, the issue in question is not about type aliases, it's about value aliases of form final val B = A.B, the first example above is the same even without the type alias[1]:

trait X {
  trait S
}

class Xa(val internal: X) {
  def s: internal.S = new internal.S{}

  implicit class XS(s: internal.S) {
    def printX: Unit = println(s)
  }
}

object Xa extends Xa(new X{})

object App extends App {
  Xa.s.printX // no such member
}

In dotty, Xa.s has type Xa.internal.S where Xa is prefix of internal and Xa.XS conversion is thus in implicit scope, allowing Xa.s.printX to resolve. This is not the behavior of scalac, for which the prefix of Xa.internal.S is only X because Xa.internal has type X.

@joroKr21
Copy link
Member

joroKr21 commented Jun 1, 2020

I guess it's this part of the spec:

if 𝑇 is a singleton type 𝑝.type, the parts of the type of 𝑝;

Which is interpreted as:

case _: SingletonType =>
  getParts(tp.widen)

@dwijnand dwijnand added this to the Backlog milestone Nov 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants