scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Default implicit not enabled for outer object if it is not a singleton #12952

Closed tribbloid closed 4 months ago

tribbloid commented 4 months ago

Reproduction steps

Scala version: 2.13.12

object ImplicitDefaultScope {
  trait Case[T]
  object case1 {
    trait Outer {
      case class A(v: String)
      implicit def caseA: Case[A] = ???
    }
    {
      def fn(o: Outer) = {
        implicitly[Case[o.A]]
      }
    }
  }
}

Problem

Compiles in Scala 3 (tested 3.4-SNAPSHOT)

Failed in Scala 2:

: could not find implicit value for parameter e: ai.acyclic.prover.commons.util.ImplicitDefaultScope.Case[o.A]
tribbloid commented 4 months ago

wondering if there is an easy fix in Scala 2

SethTisue commented 4 months ago

When opening a ticket in scala/bug, please don't just offer code that doesn't compile; you are expected to make a case that this is a bug in Scala 2. Make arguments; link to related tickets; provide evidence that your minimization is actually minimal; consider quoting relevant spec language.

If you feel you don't have the time or energy for that and just want to ask your question, please use https://users.scala-lang.org instead of the bug tracker.

SethTisue commented 4 months ago

btw, we've recently improved the repo readme here in scala/bug to emphasize this more; see https://github.com/scala/bug/pull/12950 and the recent discussion on #12949

som-snytt commented 4 months ago

☑️ compiles in dotty

The implicit is available via the prefix of o.A, not just the prefix of Case. The implicit scope is the implicit scopes of all the parts.

(Note: these are not local types, which is a traditional heel of Achilles.)

SethTisue commented 4 months ago

Minimized a bit to remove distracting extra code:

trait Case[T]
trait Outer {
  case class A(v: String)
  implicit def caseA: Case[A] = ???
}
def fn(o: Outer) =
  implicitly[Case[o.A]]
SethTisue commented 4 months ago

As an example of what I mean by citing relevant documentation before filing a bug report, is there anything relevant in https://docs.scala-lang.org/scala3/reference/changed-features/implicit-resolution.html ...? If you looked carefully and you became convinced that there isn't, say so in your report.

som-snytt commented 4 months ago

☑️ tldr;

The important change is that packages in the prefix no longer contribute; that was lrytz's recent warning.

wondering if there is an easy fix in Scala 2

Not sure if "fix" means "workaround" or "fix that might make it into 2.13.14".

SethTisue commented 4 months ago

that was lrytz's recent warning

I guess you mean https://github.com/scala/scala/pull/10621 ? I haven't looked closely at it, but the title implies it's specific to package prefixes, but here the prefix o isn't a package?

som-snytt commented 4 months ago

Yes, I intended to say that the significant change does not apply to this case.

tribbloid commented 4 months ago

@SethTisue you are right they are different. The prefix o is a non-singleton, non-package object.

For the others, I'll try to revise all the tickets in the past (and re-open them if necessary)

SethTisue commented 4 months ago

thanks. and yes, any closing of tickets is only provisional

joroKr21 commented 4 months ago

I think the relevant difference in the spec is:

Scala 3

If T is a reference to an anchor of the form p.A then S also includes all term references on the path p.

Scala2

if T is a singleton type p.type, the parts of the type of p;

"Parts of the type of p" include e.g. object Outer (because o: Outer) but not o.type itself.