-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix implicit scope without scalatest #6838
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
Fix implicit scope without scalatest #6838
Conversation
These need to be expanded to pattern definitions, not ValDefs, otherwise duplicate definition errors result.
Specialize types of ibline values even if a wider type was gven in an inherited definition. This generalizes a previous scheme for final vals.
The previous implicit scope was hard to understand, and did not conform to spec. The new implementation is simpler to understand. It also does not conform to spec as written but there's a chance that we might change the spec to conform to it.
@milessabin I am trying to clean up implicit scope, with a spec and code that are aligned. Right now, they are quite different, I am afraid. Shapeless 3 breaks with the new scope rules. The new spec is as follows:
Unfortunately shapeless3 breaks with that new definition of implicit scope. Can you take a look and either come up with a fix for shapeless or a suggestion how to tweak the spec to make it compile as is? Thanks! |
@odersky sure. Can you give me a quick sketch of what's changed? |
The previous code was hard to figure out, that's why I changed it. So it's difficult to say now what changed. One difference I know of is that in a type like
Previously, the implicit scope would have included companion objects of all supertypes of |
I guess this also solves #6716 ? |
Yes this also solves #6716. It's the reason I started the refactoring. Regarding shapeless, the first error I see is:
My question is: Where is the implicit that produces a |
I think I have it. The implicit is in
An alias does not count towards the implicit scope according to the new rules, and neither does its prefix. |
In fact, it looks very tricky to make prefixes of aliases count towards implicit scope. There's the danger of introducing ambiguities. For instance in the following:
This wil produce
If paths towards aliases count, that would produce an ambiguity between b and A.b. I tried to make ProductInstances in K0 opaque. This compiles fine in |
... but unfortunately would still not find the necessary implicit because it fails to recognize that the two types are aliases when implicits are searched. I then tried to make paths of abstract types count and to make shapeless instances abstract types instead of alias types. I.e. like this:
That causes the right implicit to be found. But unfortunately it causes errors afterwards in the inline expansion. So, I don't know what to do. I don't think we want to include paths of alias types in the implicit scope, for two reasons:
@milessabin Can you think of another solution to make the necessary instances visible? |
@odersky sorry, my machine has been tied up running @OlivierBlanvillain's benchmarks ... Yes, I suspected that might be the problem. I think it might be possible to make those aliases opaque ... I'm not surprised that just doing that on it's own leads to follow-on errors, but they're probably fixable. That said, now that we have companions for opaque aliases which can contribute to the implicit scope, I think the case for similar companions for transparent aliases is quite a bit more compelling, simply out of symmetry with the opaque case. If we did that, the fix would simply be to add companions for the aliases in If we don't go down that route, then I will in effect be simulating that with opaque aliases/companions and inline implicit conversions which undo the opacity. |
@odersky on your ambiguity example ... is it really an ambiguity? On current master the following compiles just fine, object A {
type B = Int
given b as B = 23
}
object Test {
export A._
export given A._
implicitly[B]
} What in this PR would render that ambiguous? I do agree, however, with your point about fragility. I've seen situations where differences in the compiler's enthusiasm for dealiasing has resulted in differences in implicit resolution. |
@odersky as it happens, I would quite like to make the various The first obstacle seems to be the following: just making
which suggests that we might have a double-vision problem of some sort. I'll see if I can minimize it. |
@milessabin Yes, I just hit the same problem. If you turn -Yprint-debug on you'll see that one of the types is in reality a this-type:
The opaque alias is visible from K0.this but not from the external type shapeless.K0 and TypeComparer assumes that it can always follow aliases without losing solutions. So this needs to be fixed (as well as the diagnostics output problem). |
So, I guess the type |
I am stuck. There are too many moving parts here. It seems there is some combination of opaque types and inlining that makes an this type escape from the scope where it is legal. Miles, can you try to minimize to minimize the code so that we get a chance to go to the bottom of this? |
@odersky sure, I can do that :-) |
I made some progress. Things are more complicated than it looked at first. We might have to outlaw combining opaque types and inline methods in the same scope. I'll open an issue shortly. |
@odersky it looks like your inline/opaque fix means we have a way to move forward. How do you want to sequence things? I'm happy to patch things up in shapeless following this PR, or alternatively you could put this change behind a flag and we could do it in two steps. |
Superseded by #6832 |
No description provided.