Skip to content

Fix #9103: Fix implicit scopes #9119

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

Merged
merged 10 commits into from
Jun 9, 2020

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jun 7, 2020

Clarify implicit scope rules and implement accordingly.

Fixes #9103
Fixes #9094

odersky added 6 commits June 7, 2020 14:32
The idea of LazyRefs is that they are always completed in the current context.
But that did not work if the LazyRef is mapped in a type map. Here, the TypeMap's
context was used to do the remap. We now use the context that forced the LazyVal
instead.

The problem manifested itself with failing replTests when the new implicitScope
scheme was used.
Compute anchors directly instead of relying on namedPartsWith. This
gives more precise control for what is part of the implicit scope.
In that way, we include all of the implicit scope of Scala 2, except
for package objects. The idea is that everything that is reasonable
should be included in the implicit scope.

Package objects were excluded since they had a dual purpose:

 1. as a way to define implicits that are in scope for a whole project
 2. as a prefix for implicits of all types coming out of that project

It's often that one wants only (1) but then is surprised to also get (2).

# Conflicts:
#	compiler/src/dotty/tools/dotc/typer/Implicits.scala
#	tests/pos/i9103.scala
@odersky odersky force-pushed the fix-implicit-scope-2 branch from 29faa18 to 5d520ec Compare June 7, 2020 12:46
@odersky
Copy link
Contributor Author

odersky commented Jun 7, 2020

@milessabin I had to disable two places in shapeless that failed after the changes in this PR. Once was the derives clause for Pure in Opt (other derives clauses of Pure work). The other was a test the tries to summon Pure[Clist]. I tried to track it down further but failed. Essentially, the previous implementation of type scope contained some underspecified behavior in the way it made use of the namedPartsWith call. That's now cleaned up, with a clear spec what implicit scope is (see updated in implicit-resolution.md and an implementation that follows the spec closely. Unfortunately, these cleanups caused the two failures. Can you take a look to see what goes wrong? Thanks!

@odersky
Copy link
Contributor Author

odersky commented Jun 7, 2020

test performance please

@dottybot
Copy link
Member

dottybot commented Jun 7, 2020

performance test scheduled: 1 job(s) in queue, 0 running.

@dottybot
Copy link
Member

dottybot commented Jun 7, 2020

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/9119/ to see the changes.

Benchmarks is based on merging with master (345c8bc)

@odersky
Copy link
Contributor Author

odersky commented Jun 8, 2020

@milessabin I might have found the issue: The missing elements are associated with match types. I'll see whether I can fix that.

@odersky odersky force-pushed the fix-implicit-scope-2 branch from 65e17b2 to e124d19 Compare June 8, 2020 09:45
@odersky
Copy link
Contributor Author

odersky commented Jun 8, 2020

All good now. Shapeless compiles without changes.

@odersky
Copy link
Contributor Author

odersky commented Jun 9, 2020

@anatoliykmetyuk It would be good to get this into 0.25, since it changes search implicit behavior, could potentially introduce errors in code using the old behavior.

@anatoliykmetyuk anatoliykmetyuk merged commit 9f43ede into scala:master Jun 9, 2020
@anatoliykmetyuk anatoliykmetyuk deleted the fix-implicit-scope-2 branch June 9, 2020 09:39
&& tp.hash != NotCached
&& !provisional
&& (tp eq rootTp) // first type traversed is always cached
|| !incomplete.contains(tp) // other types are cached if they are not incomplete
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A pair of parentheses are missing here, which means this last condition is top-level, that is: all types that are not incomplete are cached, even if:

  • Config.cacheImplicitScopes is false, or
  • the types hash is NotCached, or
  • the type is provisional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ambiguous implicit arguments when referencing an object via a val Non-definition prefix is in implicit scope, unlike Scala 2
4 participants