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

update array missing IntoIterator msg #82626

Merged
merged 2 commits into from
Mar 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -163,61 +163,65 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
flags.push((sym::from_desugaring, None));
flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
}
let generics = self.tcx.generics_of(def_id);
let self_ty = trait_ref.self_ty();
// This is also included through the generics list as `Self`,
// but the parser won't allow you to use it
flags.push((sym::_Self, Some(self_ty.to_string())));
if let Some(def) = self_ty.ty_adt_def() {
// We also want to be able to select self's original
// signature with no type arguments resolved
flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string())));
}

for param in generics.params.iter() {
let value = match param.kind {
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
trait_ref.substs[param.index as usize].to_string()
}
GenericParamDefKind::Lifetime => continue,
};
let name = param.name;
flags.push((name, Some(value)));
}
// Add all types without trimmed paths.
ty::print::with_no_trimmed_paths(|| {
let generics = self.tcx.generics_of(def_id);
let self_ty = trait_ref.self_ty();
// This is also included through the generics list as `Self`,
// but the parser won't allow you to use it
flags.push((sym::_Self, Some(self_ty.to_string())));
if let Some(def) = self_ty.ty_adt_def() {
// We also want to be able to select self's original
// signature with no type arguments resolved
flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string())));
}

if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
flags.push((sym::crate_local, None));
}
for param in generics.params.iter() {
let value = match param.kind {
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
trait_ref.substs[param.index as usize].to_string()
}
GenericParamDefKind::Lifetime => continue,
};
let name = param.name;
flags.push((name, Some(value)));
}

// Allow targeting all integers using `{integral}`, even if the exact type was resolved
if self_ty.is_integral() {
flags.push((sym::_Self, Some("{integral}".to_owned())));
}
if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
flags.push((sym::crate_local, None));
}

if let ty::Array(aty, len) = self_ty.kind() {
flags.push((sym::_Self, Some("[]".to_owned())));
flags.push((sym::_Self, Some(format!("[{}]", aty))));
if let Some(def) = aty.ty_adt_def() {
// We also want to be able to select the array's type's original
// signature with no type arguments resolved
let type_string = self.tcx.type_of(def.did).to_string();
flags.push((sym::_Self, Some(format!("[{}]", type_string))));
// Allow targeting all integers using `{integral}`, even if the exact type was resolved
if self_ty.is_integral() {
flags.push((sym::_Self, Some("{integral}".to_owned())));
}

let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
let string = match len {
Some(n) => format!("[{}; {}]", type_string, n),
None => format!("[{}; _]", type_string),
};
flags.push((sym::_Self, Some(string)));
if let ty::Array(aty, len) = self_ty.kind() {
flags.push((sym::_Self, Some("[]".to_owned())));
flags.push((sym::_Self, Some(format!("[{}]", aty))));
if let Some(def) = aty.ty_adt_def() {
// We also want to be able to select the array's type's original
// signature with no type arguments resolved
let type_string = self.tcx.type_of(def.did).to_string();
flags.push((sym::_Self, Some(format!("[{}]", type_string))));

let len = len.val.try_to_value().and_then(|v| v.try_to_machine_usize(self.tcx));
let string = match len {
Some(n) => format!("[{}; {}]", type_string, n),
None => format!("[{}; _]", type_string),
};
flags.push((sym::_Self, Some(string)));
}
}
}
if let ty::Dynamic(traits, _) = self_ty.kind() {
for t in traits.iter() {
if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
if let ty::Dynamic(traits, _) = self_ty.kind() {
for t in traits.iter() {
if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
}
}
}
}
});

if let Ok(Some(command)) =
OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id)
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
),
on(
_Self = "[]",
label = "borrow the array with `&` or call `.iter()` on it to iterate over it",
note = "arrays are not iterators, but slices like the following are: `&[1, 2, 3]`"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to suggest the &?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, i wasn't sure how to explain that in a concise way, as adding & changes the element type.

Do you have an idea for a second label here?

label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`",
note = "see <https://github.com/rust-lang/rust/pull/65819> for more details"
),
on(
_Self = "{integral}",
Expand Down
24 changes: 12 additions & 12 deletions src/test/ui/iterators/array-of-ranges.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,43 @@ error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator
--> $DIR/array-of-ranges.rs:4:14
|
LL | for _ in [0..=1] {}
| ^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^^^ if you meant to iterate between two values, remove the square brackets
|
= help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]`
= note: required by `into_iter`

error[E0277]: `[RangeFrom<{integer}>; 1]` is not an iterator
--> $DIR/array-of-ranges.rs:6:14
|
LL | for _ in [0..] {}
| ^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^ if you meant to iterate from a value onwards, remove the square brackets
|
= help: the trait `Iterator` is not implemented for `[RangeFrom<{integer}>; 1]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: `[start..]` is an array of one `RangeFrom`; you might have meant to have a `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an unbounded iterator will run forever unless you `break` or `return` from within the loop
= note: required because of the requirements on the impl of `IntoIterator` for `[RangeFrom<{integer}>; 1]`
= note: required by `into_iter`

error[E0277]: `[RangeTo<{integer}>; 1]` is not an iterator
--> $DIR/array-of-ranges.rs:8:14
|
LL | for _ in [..1] {}
| ^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^ if you meant to iterate until a value, remove the square brackets and add a starting value
|
= help: the trait `Iterator` is not implemented for `[RangeTo<{integer}>; 1]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: `[..end]` is an array of one `RangeTo`; you might have meant to have a bounded `Range` without the brackets: `0..end`
= note: required because of the requirements on the impl of `IntoIterator` for `[RangeTo<{integer}>; 1]`
= note: required by `into_iter`

error[E0277]: `[RangeToInclusive<{integer}>; 1]` is not an iterator
--> $DIR/array-of-ranges.rs:10:14
|
LL | for _ in [..=1] {}
| ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^^ if you meant to iterate until a value (including it), remove the square brackets and add a starting value
|
= help: the trait `Iterator` is not implemented for `[RangeToInclusive<{integer}>; 1]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: `[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a bounded `RangeInclusive` without the brackets: `0..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `[RangeToInclusive<{integer}>; 1]`
= note: required by `into_iter`

Expand Down Expand Up @@ -79,21 +79,21 @@ error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator
--> $DIR/array-of-ranges.rs:19:14
|
LL | for _ in [0..1, 2..3] {}
| ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
|
= help: the trait `Iterator` is not implemented for `[std::ops::Range<{integer}>; 2]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: see <https://github.com/rust-lang/rust/pull/65819> for more details
= note: required because of the requirements on the impl of `IntoIterator` for `[std::ops::Range<{integer}>; 2]`
= note: required by `into_iter`

error[E0277]: `[RangeInclusive<{integer}>; 1]` is not an iterator
--> $DIR/array-of-ranges.rs:21:14
|
LL | for _ in [0..=1] {}
| ^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^^^ if you meant to iterate between two values, remove the square brackets
|
= help: the trait `Iterator` is not implemented for `[RangeInclusive<{integer}>; 1]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `[RangeInclusive<{integer}>; 1]`
= note: required by `into_iter`

Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/iterators/array.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@ error[E0277]: `[{integer}; 2]` is not an iterator
--> $DIR/array.rs:2:14
|
LL | for _ in [1, 2] {}
| ^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
|
= help: the trait `Iterator` is not implemented for `[{integer}; 2]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: see <https://github.com/rust-lang/rust/pull/65819> for more details
= note: required because of the requirements on the impl of `IntoIterator` for `[{integer}; 2]`
= note: required by `into_iter`

error[E0277]: `[{integer}; 2]` is not an iterator
--> $DIR/array.rs:5:14
|
LL | for _ in x {}
| ^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
|
= help: the trait `Iterator` is not implemented for `[{integer}; 2]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: see <https://github.com/rust-lang/rust/pull/65819> for more details
= note: required because of the requirements on the impl of `IntoIterator` for `[{integer}; 2]`
= note: required by `into_iter`

error[E0277]: `[{float}; 2]` is not an iterator
--> $DIR/array.rs:7:14
|
LL | for _ in [1.0, 2.0] {}
| ^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it
| ^^^^^^^^^^ arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`
|
= help: the trait `Iterator` is not implemented for `[{float}; 2]`
= note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]`
= note: see <https://github.com/rust-lang/rust/pull/65819> for more details
= note: required because of the requirements on the impl of `IntoIterator` for `[{float}; 2]`
= note: required by `into_iter`

Expand Down
6 changes: 4 additions & 2 deletions src/test/ui/iterators/ranges.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ error[E0277]: `RangeTo<{integer}>` is not an iterator
--> $DIR/ranges.rs:2:14
|
LL | for _ in ..10 {}
| ^^^^ `RangeTo<{integer}>` is not an iterator
| ^^^^ if you meant to iterate until a value, add a starting value
|
= help: the trait `Iterator` is not implemented for `RangeTo<{integer}>`
= note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end`
= note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
= note: required by `into_iter`

error[E0277]: `RangeToInclusive<{integer}>` is not an iterator
--> $DIR/ranges.rs:4:14
|
LL | for _ in ..=10 {}
| ^^^^^ `RangeToInclusive<{integer}>` is not an iterator
| ^^^^^ if you meant to iterate until a value (including it), add a starting value
|
= help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>`
= note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
= note: required by `into_iter`

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/iterators/string.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0277]: `String` is not an iterator
--> $DIR/string.rs:2:14
|
LL | for _ in "".to_owned() {}
| ^^^^^^^^^^^^^ `String` is not an iterator
| ^^^^^^^^^^^^^ `String` is not an iterator; try calling `.chars()` or `.bytes()`
|
= help: the trait `Iterator` is not implemented for `String`
= note: required because of the requirements on the impl of `IntoIterator` for `String`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
LL | Pin::new(x)
| ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
|
= note: consider using `Box::pin`
= note: required by `Pin::<P>::new`

error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
Expand All @@ -54,6 +55,7 @@ error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
LL | Pin::new(Box::new(x))
| ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
|
= note: consider using `Box::pin`
= note: required by `Pin::<P>::new`

error[E0308]: mismatched types
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/suggestions/into-str.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
LL | foo(String::new());
| ^^^ the trait `From<String>` is not implemented for `&str`
|
= note: to coerce a `String` into a `&str`, use `&*` as a prefix
= note: required because of the requirements on the impl of `Into<&str>` for `String`

error: aborting due to previous error
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/suggestions/path-display.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ error[E0277]: `Path` doesn't implement `std::fmt::Display`
--> $DIR/path-display.rs:5:20
|
LL | println!("{}", path);
| ^^^^ `Path` cannot be formatted with the default formatter
| ^^^^ `Path` cannot be formatted with the default formatter; call `.display()` on it
|
= help: the trait `std::fmt::Display` is not implemented for `Path`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data
= note: required because of the requirements on the impl of `std::fmt::Display` for `&Path`
= note: required by `std::fmt::Display::fmt`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Expand Down