-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Adjust spans into the for loops context before creating the new desugaring spans.
#148465
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
base: master
Are you sure you want to change the base?
Conversation
… and `into_iter` call spans.
|
r? @davidtwco rustbot has assigned @davidtwco. Use |
| let head_span = | ||
| head.span.find_ancestor_in_same_ctxt(e.span).unwrap_or(head.span).with_ctxt(for_ctxt); |
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.
The currently failing tests/ui/suggest-dereferences/invalid-suggest-deref-issue127590 can be fixed by making a second mark rather than reusing for_ctxt. I'm not exactly clear why this matters since the only change this makes is using two identical, but separate SyntaxContexts.
Ideally only a single SyntaxContext would be created since there's only one for loop.
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.
Narrowed this down to being different expansion call sites. If we replace the for loop with a call to into_iter then it always produces three diagnostics.
Errors
error[E0277]: `&std::slice::Iter<'_, i32>` is not an iterator
--> src/main.rs:2:59
|
2 | IntoIterator::into_iter(std::iter::zip([1i32].iter(), &[1i32].iter()));
| -------------- ^^^^^^^^^^^^^^ `&std::slice::Iter<'_, i32>` is not an iterator
| |
| required by a bound introduced by this call
|
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, i32>`
= note: required for `&std::slice::Iter<'_, i32>` to implement `IntoIterator`
note: required by a bound in `std::iter::zip`
--> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/zip.rs:70:8
|
67 | pub fn zip<A, B>(a: A, b: B) -> Zip<A::IntoIter, B::IntoIter>
| --- required by a bound in this function
...
70 | B: IntoIterator,
| ^^^^^^^^^^^^ required by this bound in `zip`
help: consider removing the leading `&`-reference
|
2 - IntoIterator::into_iter(std::iter::zip([1i32].iter(), &[1i32].iter()));
2 + IntoIterator::into_iter(std::iter::zip([1i32].iter(), [1i32].iter()));
|
help: consider changing this borrow's mutability
|
2 | IntoIterator::into_iter(std::iter::zip([1i32].iter(), &mut [1i32].iter()));
| +++
error[E0277]: `&std::slice::Iter<'_, i32>` is not an iterator
--> src/main.rs:2:29
|
2 | IntoIterator::into_iter(std::iter::zip([1i32].iter(), &[1i32].iter()));
| ----------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, i32>` is not an iterator
| |
| required by a bound introduced by this call
|
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, i32>`
= help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>`
= note: `Iterator` is implemented for `&mut std::slice::Iter<'_, i32>`, but not for `&std::slice::Iter<'_, i32>`
= note: required for `Zip<std::slice::Iter<'_, i32>, &std::slice::Iter<'_, i32>>` to implement `Iterator`
= note: required for `Zip<std::slice::Iter<'_, i32>, &std::slice::Iter<'_, i32>>` to implement `IntoIterator`
error[E0277]: `&std::slice::Iter<'_, i32>` is not an iterator
--> src/main.rs:2:5
|
2 | IntoIterator::into_iter(std::iter::zip([1i32].iter(), &[1i32].iter()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, i32>` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, i32>`
= help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>`
= note: `Iterator` is implemented for `&mut std::slice::Iter<'_, i32>`, but not for `&std::slice::Iter<'_, i32>`
= note: required for `Zip<std::slice::Iter<'_, i32>, &std::slice::Iter<'_, i32>>` to implement `Iterator`
= note: required for `Zip<std::slice::Iter<'_, i32>, &std::slice::Iter<'_, i32>>` to implement `IntoIterator`
The third error is filtered on for loops since when deduplicating obligation failures if the cause span is in a desugaring then the call site span is used instead. Originally the call site span for the into_iter call is the head expression which causes it to be suppressed since this matches the second error. With this PR the call site span is the for loop itself which doesn't match the previous two errors.
If this is actually a problem I can mark the head expression separately. I don't see this as too big of a deal since the second error will be present in either case and it's just as useless as the third one.
|
The job Click to see the possible cause of the failure (guessed by this bot) |
When lowering
forloops, the spans for theinto_itercall and theSomepattern used the span of the provided pattern and head expression. If either of those came from a differentSyntaxContextthis would result in some very strange contexts. e.g.:This would result in the
into_itercall have a context chain ofdesugar => m!() => rootwhich is completely nonsensical;m!()does not have aforloop. Theinto_itercall also ends up located at{ $e }rather than inside thefor _ in _part.This fixes that by walking the spans up to the
forloop's context first. This will not handle adjusting the location of macro variable expansions (e.g.for _ in $e), but this does adjust the context to match theforloops.This ended up causing rust-lang/rust-clippy#16008. Clippy should be using a
debug_assertrather thanunreachable, but it still results in a bug either way.