-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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 filtering option to rustc_on_unimplemented
and reword Iterator
E0277 errors
#54946
Conversation
- Detect one element array of `Range` type, which is potentially a typo: `for _ in [0..10] {}` where iterating between `0` and `10` was intended. (rust-lang#23141) - Suggest `.bytes()` and `.chars()` for `String`. - Suggest borrowing or `.iter()` on arrays (rust-lang#36391) - Suggest using range literal when iterating on integers (rust-lang#34353) - Do not suggest `.iter()` by default (rust-lang#50773, rust-lang#46806)
r? @varkor (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
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.
These diagnostic changes are a big improvement!
It'd be nice if we could get rid of the false positives (e.g. the "if you want to iterate between 0
until a value end
" message), but it's hard to tell how often they'd come up in practice, so if that's awkward to support, I'd probably be okay with leaving it how it is: I think it probably helps more than it confuses.
| | ||
= help: the trait `std::iter::Iterator` is not implemented for `i32` | ||
= note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` |
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 doesn't seem perfect: it's specific to loops, but I imagine people writing <{integer} as Iterator>
is so uncommon that this isn't really a problem.
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.
That was my thinking.
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 would also be fixed by marking all the spans part of a for loop as being part of a desugaring context, which we can filter on in rustc_on_unimplemented
and would improve the situation for many of this diagnostics that only apply when using a binding and not in type signatures.
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.
Ah, that would be good!
--> $DIR/array-of-ranges.rs:7:14 | ||
| | ||
LL | for _ in array_of_range {} | ||
| ^^^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets |
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 isn't ideal. Any way we could only make this happen for the literal syntax?
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 would have to change rustc_on_unimplemented
. I've tried to "poison" the span for the iterator with a "desugaring context", but was unable to get it working. It should be possible to add it, but given that the likelihood of this case in particular happening is so slim (you have to 1. create an array of ranges, already uncommon and 2. try to iterate over the array), I felt confident leaving it as is (at least for now).
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.
That's true; it could always be a follow-up.
- reword messages - apply custom comments to all types of ranges - fix indentation
src/libcore/iter/iterator.rs
Outdated
), | ||
on( | ||
_Self="[std::ops::RangeTo<Idx>; 1]", | ||
label="if you meant to iterate until a value, remove the square brackets", |
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.
You can't iterate over a RangeTo
, so I'm not sure this one is necessary.
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.
You're absolutely right, I just never had thought about it enough to look it up. I will still add a note to it in order to let users know that.
src/libcore/iter/iterator.rs
Outdated
), | ||
on( | ||
_Self="[std::ops::RangeToInclusive<Idx>; 1]", | ||
label="if you meant to iterate until a value, remove the square brackets", |
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.
Same with RangeToInclusive
.
r=me after the last couple of comments, if Travis passes. |
@bors r=varkor |
📌 Commit 5beeb53 has been approved by |
⌛ Testing commit 5beeb53 with merge 73008786a90f5da800834e1540ca6521d8b7c7ba... |
💔 Test failed - status-travis |
This comment has been minimized.
This comment has been minimized.
@bors try |
Add filtering option to `rustc_on_unimplemented` and reword `Iterator` E0277 errors - Add more targetting filters for arrays to `rustc_on_unimplemented` (Fix #53766) - Detect one element array of `Range` type, which is potentially a typo: `for _ in [0..10] {}` where iterating between `0` and `10` was intended. (Fix #23141) - Suggest `.bytes()` and `.chars()` for `String`. - Suggest borrowing or `.iter()` on arrays (Fix #36391) - Suggest using range literal when iterating on integers (Fix #34353) - Do not suggest `.iter()` by default (Fix #50773, fix #46806) - Add regression test (Fix #22872)
☀️ Test successful - status-travis |
@bors r=varkor |
📌 Commit f5cc6b5 has been approved by |
⌛ Testing commit f5cc6b5 with merge d502144fd36634a938d73bf1893580d420194443... |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), | ||
)); | ||
if let Some(len) = len.val.try_to_scalar().and_then(|scalar| { | ||
scalar.to_i64().ok() |
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.
Hi @oli-obk!
Could you take a look at how I'm using Scalar::to_i64
here? In travis I'm getting the following test error, and looking at the interface of Scalar
I don't see a safe way of figuring wether the value is 1
without tripping the assert on some platforms. I need to check wether len.val
is 1
(at the very least) or the actual value (more flexibility, but not needed now).
[00:46:27] thread 'main' panicked at 'assertion failed: `(left == right)`
[00:46:27] left: `8`,
[00:46:27] right: `4`', librustc/mir/interpret/value.rs:242:17
[00:46:27] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:46:27]
[00:46:27] error: internal compiler error: unexpected panic
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.
You can use scalar.to_usize(self.tcx).ok()
which actually takes the target platform's usize
size and should thus work on all platforms
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.
Thanks! I didn't realize that TyCtxt
implemented HasDataLayout
.
This comment has been minimized.
This comment has been minimized.
@bors r=varkor |
📌 Commit def0f54 has been approved by |
Add filtering option to `rustc_on_unimplemented` and reword `Iterator` E0277 errors - Add more targetting filters for arrays to `rustc_on_unimplemented` (Fix #53766) - Detect one element array of `Range` type, which is potentially a typo: `for _ in [0..10] {}` where iterating between `0` and `10` was intended. (Fix #23141) - Suggest `.bytes()` and `.chars()` for `String`. - Suggest borrowing or `.iter()` on arrays (Fix #36391) - Suggest using range literal when iterating on integers (Fix #34353) - Do not suggest `.iter()` by default (Fix #50773, fix #46806) - Add regression test (Fix #22872)
☀️ Test successful - status-appveyor, status-travis |
Late but... I think this just replaced several clippy lints with just one diagnostic change. |
rustc_on_unimplemented
(Fix Add filter torustc_on_unimplemented
forSelf: array
#53766)Range
type, which is potentially a typo:for _ in [0..10] {}
where iterating between0
and10
was intended.(Fix Add a special case error for
[Range<T>; 1]
#23141).bytes()
and.chars()
forString
..iter()
on arrays (Fix Better suggestion when attempting to iterate over array #36391).iter()
by default (Fix Don't suggest calling.iter()
when unsatifiedIterator
bound does not originate from an expression #50773, fix Wrong suggestion for struct's type-param that is not iter::Iterator but should #46806)