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

More perseverant resolve (second try) #27439

Merged
merged 4 commits into from
Aug 5, 2015

Conversation

elinorbgr
Copy link
Contributor

(This is a second try at #26242. This time I think things should be ok.)

The current algorithm handling import resolutions works sequentially, handling imports in the order they appear in the source file, and blocking/bailing on the first one generating an error/being unresolved.

This can lead to situations where the order of the use statements can make the difference between "this code compiles" and "this code fails on an unresolved import" (see #18083 for example). This is especially true when considering glob imports.

This PR changes the behaviour of the algorithm to instead try to resolve all imports in a module. If one fails, it is recorded and the next one is tried (instead of directly giving up). Also, all errors generated are stored (and not reported directly).

The main loop of the algorithms guaranties that the algorithm will always finish: if a round of resolution does not resolve anything new, we are stuck and give up. At this point, the new version of the algorithm will display all errors generated by the last round of resolve. This way we are sure to not silence relevant errors or help messages, but also to not give up too early.

As a consequence, the import resolution becomes independent of the order in which the use statements are written in the source files. I personally don't see any situations where this could be a problem, but this might need some thought.

I passed rpass and cfail tests on my computer, and now am compiling a full stage2 compiler to ensure the crates reporting errors in my previous attempts still build correctly. I guess once I have checked it, this will need a crater run?

Fixes #18083.

r? @alexcrichton , cc @nrc @brson

There is not situation where `foo` would be unresolved but not `foo::*`.
Most errors generated by resolve might be caused by
not-yet-resolved glob imports. This changes the behavior of the
resolve imports algorithms to not fail prematurally on first
error, but instead buffer intermediate errors and report them
only when stuck.

Fixes rust-lang#18083
The precedent resolve modification changed the order in which
imports are handled, so 2 tests needed to be updated.
@alexcrichton
Copy link
Member

Hm this has gotten more hairy since the last time I looked at it, so I'm gonna transfer review:

r? @nrc

@rust-highfive rust-highfive assigned nrc and unassigned alexcrichton Jul 31, 2015
@elinorbgr
Copy link
Contributor Author

I just finished testing, the crates rand and hyper, which were the two ones that had caused issues with my previous PR now build fine with this version.

@elinorbgr
Copy link
Contributor Author

@fzzy This is due to an other difficulty in the import resolution algorithm, that this PR does not change:

  • The algorithm will delay an import if the module containing the target of the import still has unresolved glob imports
  • The algorithm will delay a glob import of the target module still has unresolved imports

In your example case, use b::*; is waiting on use a; to be resolved, and use a; is waiting on use b::*; to resolved as well, hence a lock and the algorithm giving up.

I think it can be possible to relax the two rules I described just above to only block on pub imports, but this would be on the scope of an other PR.

@retep998
Copy link
Member

retep998 commented Aug 1, 2015

@vberger It would mean so much to me, and make my code so much nicer, if you made it so glob imports only blocked on pub imports. I hope to see such a PR soon.

@nrc
Copy link
Member

nrc commented Aug 4, 2015

lgtm, I'd like to get a crater run before landing though

@nrc
Copy link
Member

nrc commented Aug 4, 2015

@brson: can we get a crater run for this PR please? (Sorry, can't find the instructions you sent out)

@elinorbgr
Copy link
Contributor Author

@nrc Are the descriptions in the tests ok now ?

@alexcrichton
Copy link
Member

Kicking off some crater builds now

@nrc
Copy link
Member

nrc commented Aug 4, 2015

@vberger yep, lgtm, thanks!

@alexcrichton
Copy link
Member

Crater says zero regressions

@alexcrichton
Copy link
Member

@bors: r=nrc 58e35d7

@bors
Copy link
Contributor

bors commented Aug 5, 2015

⌛ Testing commit 58e35d7 with merge 6a3545e...

bors added a commit that referenced this pull request Aug 5, 2015
(This is a second try at #26242. This time I think things should be ok.)

The current algorithm handling import resolutions works sequentially, handling imports in the order they appear in the source file, and blocking/bailing on the first one generating an error/being unresolved.

This can lead to situations where the order of the `use` statements can make the difference between "this code compiles" and "this code fails on an unresolved import" (see #18083 for example). This is especially true when considering glob imports.

This PR changes the behaviour of the algorithm to instead try to resolve all imports in a module. If one fails, it is recorded and the next one is tried (instead of directly giving up). Also, all errors generated are stored (and not reported directly).

The main loop of the algorithms guaranties that the algorithm will always finish: if a round of resolution does not resolve anything new, we are stuck and give up. At this point, the new version of the algorithm will display all errors generated by the last round of resolve. This way we are sure to not silence relevant errors or help messages, but also to not give up too early.

**As a consequence, the import resolution becomes independent of the order in which the `use` statements are written in the source files.** I personally don't see any situations where this could be a problem, but this might need some thought.

I passed `rpass` and `cfail` tests on my computer, and now am compiling a full stage2 compiler to ensure the crates reporting errors in my previous attempts still build correctly. I guess once I have checked it, this will need a crater run?

Fixes #18083.

r? @alexcrichton , cc @nrc @brson
@bors bors merged commit 58e35d7 into rust-lang:master Aug 5, 2015
bors added a commit that referenced this pull request Aug 10, 2015
As noted in my previous PR #27439 , the import resolution algorithm has two cases where it bails out:

- The algorithm will delay an import if the module containing the target of the import still has unresolved glob imports
- The algorithm will delay a glob import of the target module still has unresolved imports

This PR alters the behaviour to only bail out when the above described unresolved imports are `pub`, as non-pub imports don't affect the result anyway.

It is still possible to fail the algorithm with examples like
```rust
pub mod a {
    pub use b::*;
}

pub mod b {
    pub use a::*;
}
```
but such configurations cannot be resolved in any meaningful way, as these are cyclic imports.

Closes #4865
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.

Resolve failure with multiple reexports
5 participants