-
Notifications
You must be signed in to change notification settings - Fork 778
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
Filter and flatten markers #4639
Conversation
crates/uv-resolver/src/marker.rs
Outdated
pub(crate) fn normalize(tree: MarkerTree) -> Option<MarkerTree> { | ||
pub(crate) fn normalize(mut tree: MarkerTree) -> Option<MarkerTree> { | ||
filter_all(&mut tree); | ||
normalize_all(tree) |
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.
Are there redundant expressions that we'd only notice after normalizing (e.g., flattening)? In other words, is filter_all(normalize_all(...))
idempotent? Or is there some risk that we don't normalize everything by way of this ordering?
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.
filter_all
was written to handle non-flattened trees and can also leave the tree in a denormalized (not flattened) state.
Thinking about it more though, I suppose it is possible that there are duplicates that only show up after combining version ranges, so maybe we have to normalize before and after? I was trying to avoid this by writing filter_all
to handle non-flattened ranges, but maybe normalizing before is unavoidable. I can try to create a test case where this happens.
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.
Fixed and added a test.
Relatedly, after this change, if we have a marker that contains an |
crates/uv-resolver/src/marker.rs
Outdated
} | ||
} | ||
|
||
// Collect all expressions from a tree. |
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.
Scroll-by Nit: //
-> ///
so it's rustdoc
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 might add a little more rustdoc for cases like these. As it is, I think the comment is effectively strictly redundant with the name and type signature. I think I'd write something like this:
/// For a given slice of marker trees, this collects
/// all direct leaf expressions from each marker tree,
/// and skips any marker trees that are themselves
/// not leaves.
I might also add some context as to why this routine is useful.
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.
Added some more documentation.
@charliermarsh it does not, does that ever come up? |
@ibraheemdev -- I was considering making some changes elsewhere that would benefit from it, but it's not critical. Although I do think What's left to do here? |
Another one we could do: #4852 |
99d8f4e
to
a3abf28
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.
I think this overall LGTM. This does seem like playing whack-a-mole, but I think we figured out it would require significant investment to do this fully correctly right?
crates/uv-resolver/src/marker.rs
Outdated
} | ||
} | ||
|
||
// Collect all expressions from a tree. |
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 might add a little more rustdoc for cases like these. As it is, I think the comment is effectively strictly redundant with the name and type signature. I think I'd write something like this:
/// For a given slice of marker trees, this collects
/// all direct leaf expressions from each marker tree,
/// and skips any marker trees that are themselves
/// not leaves.
I might also add some context as to why this routine is useful.
crates/uv-resolver/src/marker.rs
Outdated
} | ||
} | ||
|
||
// Filters out matching expressions from any nested conjunctions. |
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.
Is there a reason why this doesn't also filter them out for a direct leaf expression? I guess it would need to rewrite the marker expression as MarkerTree::And(vec![])
in that case...
Another perspective that I find helpful for routines like this is phrasing like, "returns a marker tree in which the given expression is assumed to be true in all conjunctions." I think that captures better the essence of the contract here if I'm understanding correctly.
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.
Yeah, that's covered by the dedup
calls in normalize_all
. It's a bit trickier to do that here because we want to filter recursively, but only deduplicate from the outer conjunction or disjunction, depending on the context (we don't just want to remove the expression everywhere).
@@ -1,4 +1,4 @@ | |||
#![allow(clippy::enum_glob_use)] | |||
#![allow(clippy::enum_glob_use, clippy::single_match_else)] |
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 Clippy. (I agree with your stylistic choice here.)
cb06b14
to
aee0891
Compare
aee0891
to
a500e82
Compare
Summary
More marker simplification:
a and (a or b)
simplifies toa
.(a and b) and c
Resolves #4536.