-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add some documentation to the resolver #5195
Conversation
r? @matklad (rust_highfive has picked a reviewer for you, use r? to override) |
src/cargo/core/resolver/mod.rs
Outdated
let mut has_past_conflicting_dep = just_here_for_the_error_messages; | ||
if !has_past_conflicting_dep { | ||
if let Some(conflicting) = frame | ||
.remaining_siblings | ||
.clone() | ||
.filter_map(|(_, (deb, _, _))| { | ||
past_conflicting_activations.get(&deb).and_then(|past_bad| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part I was a little confused about given that we also modify the past_conflicting_activations
above, and before merging I'd like to incorporate #5168 (comment) into the comment on this if
statement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
Looks great to me, modulo a couple of typos. However, as I don't really understand deeply how resolve works, it will take me large amount of time to actually verify that comments accurately describe the thing the code is doing, so
@bors r=Eh2406
src/cargo/core/resolver/mod.rs
Outdated
MissingFeatures(String), | ||
} | ||
|
||
enum ActivateError { | ||
Error(::failure::Error), | ||
Fatal(::failure::Error), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe change ::failure::Error
to CargoError
as well? They are one:
pub use failure::Error as CargoError;
src/cargo/core/resolver/mod.rs
Outdated
// `past_conflicting_activations`is a cache of the reasons for each time we | ||
// backtrack. For example after several backtracks we may have: | ||
// | ||
// past_conflicting_activations[`foo = "^1.0.2"`] = vac![ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/vac/vec/
src/cargo/core/resolver/mod.rs
Outdated
|
||
// `conflicting_activations` stores all the reasons we were unable to | ||
// activate candidates. One of these reasons will have to go away for | ||
// backtracking to find a place to restart It is also the list of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing .
before It
.
src/cargo/core/resolver/mod.rs
Outdated
})?; | ||
|
||
// TODO: explain this | ||
if just_here_for_the_error_messages && !backtracked && has_another { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know we are going to fail all the way to the user: if just_here_for_the_error_messages
and
yet we have another thing to try: has_another
so if we try this it won't make it all the way to the user. Insted it will fail and bactrak to us to try the next candidate. So let's just skip to the next candidate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha that definitely makes sense!
Put another way, if just_here_for_the_error_messages
is true, we basically want to exhaust the iterator immediately to collect the HashMap
it spits out as to why we filtered out candidates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sort of. If just_here_for_the_error_messages
then we ether want to
- Exhaust the iterator immediately (as you said) so this dep can bactrack to the users.
- Activate the last candidate so one of our dependencies can bactrack to the users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh hm I'm not sure I understand then. For that second condition where we want to activate the last candidate so we can backtrack, how come the last candidate is special? Is that because it's the only one which'll force a backtrack if it fails?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes? It is the only one that does not add a backtrack frame for our children to come back to. And we could just pick the first one and not add a backtrack frame, but then the error message will be different.
Befor: ... which is depended on by `bar v0.1.0`
After: ... which is depended on by `bar v0.1.99`
I have been reading the comments and they look great to me so far! I got up to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks like a lot of improvement.
src/cargo/core/resolver/mod.rs
Outdated
})?; | ||
|
||
// TODO: explain this | ||
if just_here_for_the_error_messages && !backtracked && has_another { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know we are going to fail all the way to the user: if just_here_for_the_error_messages
and
yet we have another thing to try: has_another
so if we try this it won't make it all the way to the user. Insted it will fail and bactrak to us to try the next candidate. So let's just skip to the next candidate.
src/cargo/core/resolver/mod.rs
Outdated
// global list of past conflicting activations, effectively | ||
// globally poisoning `dep` if `conflicting_activations` ever | ||
// shows up again. This is used during backtracking to ensure we | ||
// can skip over as much work as possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I miss read this
as meaning past_conflicting_activations
instead of conflicting_activations
src/cargo/core/resolver/mod.rs
Outdated
// If a dependency is known to fail we may want to skip this | ||
// frame as this is surely a dead end. If there are more | ||
// candidates we wait until the last one to generate an | ||
// error message in this case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is better than what I had, by a lot, but I wonder if it could be clearer. Semse like a lot of interacting clauses in the last sentence. What is in this case
modifying?
Maybe:
If a dependency is known to fail we want to skip this frame as this is surely a dead end. If there are more candidates then we can skip this frame without affecting error messages. However, if this is last candidate we activate to get its error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect!
src/cargo/core/resolver/mod.rs
Outdated
// backtrack from errors like these | ||
Err(ActivateError::Fatal(e)) => return Err(e), | ||
|
||
// We failed to do a bland conflict, bah! Record this in our |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't quite follow this sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, "to do" was meant to be "due to"
// `activate` changed `cx` and then failed so put things back. | ||
cx = b.context_backup; | ||
} // else we are just using the cx for the error message so we can live with a corrupted one | ||
backtrack_stack.extend(backtrack); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extend
brilliant!
☔ The latest upstream changes (presumably #5187) made this pull request unmergeable. Please resolve the merge conflicts. |
To be clear I am +1 when you feel this is ready and it is mergeable. :-) Then I think working together, we are in a good place to solve #4810 (comment); the last reproducible and in the wild exponentially slow resolution (that I have found). |
b574800
to
20239d2
Compare
Ok I've rebased and updated with the recent merge conflict, @Eh2406 mind giving it a once over to make sure it still makes sense? |
20239d2
to
92fb7d0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of good in this PR! Just some small nits, and ci is red.
src/cargo/core/resolver/mod.rs
Outdated
/// is defined within a `Context`. | ||
/// | ||
/// Candidates passed to `new` may not be returned from `next` as they could be | ||
/// filtered out, and if iteration stops a map of all failed candidates will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I think it returns a map of all conflicting already activated PackageId
not a map of the filtered (not yet activated) candidates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha yes indeed!
src/cargo/core/resolver/mod.rs
Outdated
/// | ||
/// If we've reached the end of the iterator here then `Err` will be | ||
/// returned. The error will contain a map of package id to conflict reason, | ||
/// where each package id was filtered out from the original list for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this has the structure backwards, where each package id that has already been activated that causes something to be filtered out to the reason it caused a candidate to be skipped.
// things to explain in the error message if we fail to resolve. | ||
// | ||
// This is a map of package id to a reason why that packaged caused a | ||
// conflict for us. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very well explained description of what is happening. Perhaps it can be used for my nits.
src/cargo/core/resolver/mod.rs
Outdated
// If we're only here for the error messages then we know | ||
// one of our candidate deps will fail, meaning we will | ||
// fail and that none of the backtrack frames will find a | ||
// candidate that will help. Consequently le'ts clean up the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
le'ts -> let's
This is currently my best-effort attempt to document various portions of the resolver with the logic that's been added recently. It at least helped me understand a bit what was going on so I hope it can help others as well!
92fb7d0
to
5695119
Compare
@bors: r=Eh2406 Ok cool, thanks for double checking me! |
📌 Commit 5695119 has been approved by |
⌛ Testing commit 5695119 with merge 6ececacf83586369c86be162153c9e45d75f6920... |
@bors: retry |
💔 Test failed - status-travis |
@bors: retry |
1 similar comment
@bors: retry |
Add some documentation to the resolver I spent a few hours yesterday re-teaching myself the resolver and wanted to add some comments along the way!
☀️ Test successful - status-appveyor, status-travis |
I spent a few hours yesterday re-teaching myself the resolver and wanted to add some comments along the way!