From cd7c8182dd48b2562153324915ba236f3c33cc5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 18:44:07 -0700 Subject: [PATCH 1/8] Add more targetting filters for arrays to rustc_on_unimplemented --- src/librustc/traits/error_reporting.rs | 38 +++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index da2173fead370..a7ebd0c8965c2 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -349,10 +349,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn on_unimplemented_note( &self, trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>) -> - OnUnimplementedNote - { - let def_id = self.impl_similar_to(trait_ref, obligation) + obligation: &PredicateObligation<'tcx>, + ) -> OnUnimplementedNote { + let def_id = self.impl_similar_to(trait_ref, obligation) .unwrap_or(trait_ref.def_id()); let trait_ref = *trait_ref.skip_binder(); @@ -410,6 +409,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { flags.push(("crate_local".to_owned(), None)); } + // Allow targetting all integers using `{integral}`, even if the exact type was resolved + if self_ty.is_integral() { + flags.push(("_Self".to_owned(), Some("{integral}".to_owned()))); + } + + if let ty::Array(aty, len) = self_ty.sty { + flags.push(("_Self".to_owned(), Some("[]".to_owned()))); + flags.push(("_Self".to_owned(), 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 + flags.push(( + "_Self".to_owned(), + Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), + )); + if let Some(len) = len.val.try_to_scalar().and_then(|scalar| { + scalar.to_u64().ok() + }) { + flags.push(( + "_Self".to_owned(), + Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), + )); + } else { + flags.push(( + "_Self".to_owned(), + Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), + )); + } + } + } + if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) { From 5b0223e8c6bfe89ab3697343d5314c72c806504e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 18:53:53 -0700 Subject: [PATCH 2/8] Reword `rustc_on_unimplemented` errors for `Iterator` - Detect one element array of `Range` type, which is potentially a typo: `for _ in [0..10] {}` where iterating between `0` and `10` was intended. (#23141) - Suggest `.bytes()` and `.chars()` for `String`. - Suggest borrowing or `.iter()` on arrays (#36391) - Suggest using range literal when iterating on integers (#34353) - Do not suggest `.iter()` by default (#50773, #46806) --- src/libcore/iter/iterator.rs | 21 +++++++++++++++- src/test/ui/conservative_impl_trait.rs | 2 +- src/test/ui/conservative_impl_trait.stderr | 4 ++-- .../feature-gate-trivial_bounds.stderr | 5 ++-- src/test/ui/for/for-c-in-str.rs | 2 +- src/test/ui/for/for-c-in-str.stderr | 2 +- src/test/ui/for/for-loop-bogosity.rs | 3 ++- src/test/ui/for/for-loop-bogosity.stderr | 6 ++--- src/test/ui/issues/issue-28098.rs | 12 +++++----- src/test/ui/issues/issue-28098.stderr | 24 +++++++++---------- src/test/ui/issues/issue-50480.rs | 2 +- src/test/ui/issues/issue-50480.stderr | 5 ++-- .../ui/suggestions/suggest-remove-refs-1.rs | 2 +- .../suggestions/suggest-remove-refs-1.stderr | 4 ++-- .../ui/suggestions/suggest-remove-refs-2.rs | 2 +- .../suggestions/suggest-remove-refs-2.stderr | 4 ++-- .../ui/suggestions/suggest-remove-refs-3.rs | 2 +- .../suggestions/suggest-remove-refs-3.stderr | 4 ++-- 18 files changed, 64 insertions(+), 42 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 4ed4ddb5b656f..b3fa5abd1c4eb 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -30,11 +30,30 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( + on( + _Self="[std::ops::Range; 1]", + label="if you meant to iterate between two values, remove the square brackets", + note="`[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end`" + ), on( _Self="&str", label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" ), - label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method" + on( + _Self="std::string::String", + label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + on( + _Self="[]", + label="borrow the array with `&` or call `.iter()` on it to iterate over it", + note="arrays are not an iterators, but slices like the following are: `&[1, 2, 3]`" + ), + on( + _Self="{integral}", + note="if you want to iterate between `0` until a value `end`, use the range syntax: `0..end`" + ), + label="`{Self}` is not an iterator", + message="`{Self}` is not an iterator" )] #[doc(spotlight)] pub trait Iterator { diff --git a/src/test/ui/conservative_impl_trait.rs b/src/test/ui/conservative_impl_trait.rs index 30895bce357bb..8554b346beb28 100644 --- a/src/test/ui/conservative_impl_trait.rs +++ b/src/test/ui/conservative_impl_trait.rs @@ -11,7 +11,7 @@ // #39872, #39553 fn will_ice(something: &u32) -> impl Iterator { - //~^ ERROR the trait bound `(): std::iter::Iterator` is not satisfied [E0277] + //~^ ERROR `()` is not an iterator } fn main() {} diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr index 6fcd384566cf8..cfa4618566ef1 100644 --- a/src/test/ui/conservative_impl_trait.stderr +++ b/src/test/ui/conservative_impl_trait.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/conservative_impl_trait.rs:13:33 | LL | fn will_ice(something: &u32) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr index f20c1ebb37aa9..a37980d0d5122 100644 --- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -75,15 +75,16 @@ LL | | } = help: see issue #48214 = help: add #![feature(trivial_bounds)] to the crate attributes to enable -error[E0277]: the trait bound `i32: std::iter::Iterator` is not satisfied +error[E0277]: `i32` is not an iterator --> $DIR/feature-gate-trivial_bounds.rs:50:1 | LL | / fn use_for() where i32: Iterator { //~ ERROR LL | | for _ in 2i32 {} LL | | } - | |_^ `i32` is not an iterator; maybe try calling `.iter()` or a similar method + | |_^ `i32` is not an iterator | = 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` = help: see issue #48214 = help: add #![feature(trivial_bounds)] to the crate attributes to enable diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs index 011886e807346..83ec6c2db9b80 100644 --- a/src/test/ui/for/for-c-in-str.rs +++ b/src/test/ui/for/for-c-in-str.rs @@ -12,7 +12,7 @@ fn main() { for c in "asdf" { - //~^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied + //~^ ERROR `&str` is not an iterator //~| NOTE `&str` is not an iterator //~| HELP the trait `std::iter::Iterator` is not implemented for `&str` //~| NOTE required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/for/for-c-in-str.stderr b/src/test/ui/for/for-c-in-str.stderr index b249df3b4ef6a..d3db935166eb4 100644 --- a/src/test/ui/for/for-c-in-str.stderr +++ b/src/test/ui/for/for-c-in-str.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied +error[E0277]: `&str` is not an iterator --> $DIR/for-c-in-str.rs:14:14 | LL | for c in "asdf" { diff --git a/src/test/ui/for/for-loop-bogosity.rs b/src/test/ui/for/for-loop-bogosity.rs index 96ad184fd3558..b54d445ae37f0 100644 --- a/src/test/ui/for/for-loop-bogosity.rs +++ b/src/test/ui/for/for-loop-bogosity.rs @@ -24,7 +24,8 @@ pub fn main() { x: 1, y: 2, }; - for x in bogus { //~ ERROR `MyStruct: std::iter::Iterator` is not satisfied + for x in bogus { + //~^ ERROR `MyStruct` is not an iterator drop(x); } } diff --git a/src/test/ui/for/for-loop-bogosity.stderr b/src/test/ui/for/for-loop-bogosity.stderr index 0476ec06c705a..1aaf12c5da029 100644 --- a/src/test/ui/for/for-loop-bogosity.stderr +++ b/src/test/ui/for/for-loop-bogosity.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `MyStruct: std::iter::Iterator` is not satisfied +error[E0277]: `MyStruct` is not an iterator --> $DIR/for-loop-bogosity.rs:27:14 | -LL | for x in bogus { //~ ERROR `MyStruct: std::iter::Iterator` is not satisfied - | ^^^^^ `MyStruct` is not an iterator; maybe try calling `.iter()` or a similar method +LL | for x in bogus { + | ^^^^^ `MyStruct` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `MyStruct` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/issues/issue-28098.rs b/src/test/ui/issues/issue-28098.rs index 5dded2b1e1697..11990c34fbae4 100644 --- a/src/test/ui/issues/issue-28098.rs +++ b/src/test/ui/issues/issue-28098.rs @@ -10,13 +10,13 @@ fn main() { let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator for _ in false {} - //~^ ERROR `bool: std::iter::Iterator` is not satisfied + //~^ ERROR `bool` is not an iterator let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator other() } @@ -25,11 +25,11 @@ pub fn other() { // check errors are still reported globally let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator let _ = Iterator::next(&mut ()); - //~^ ERROR `(): std::iter::Iterator` is not satisfied + //~^ ERROR `()` is not an iterator for _ in false {} - //~^ ERROR `bool: std::iter::Iterator` is not satisfied + //~^ ERROR `bool` is not an iterator } diff --git a/src/test/ui/issues/issue-28098.stderr b/src/test/ui/issues/issue-28098.stderr index 3a6e1aea28834..c7537065b32b6 100644 --- a/src/test/ui/issues/issue-28098.stderr +++ b/src/test/ui/issues/issue-28098.stderr @@ -1,53 +1,53 @@ -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:12:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `bool: std::iter::Iterator` is not satisfied +error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:15:14 | LL | for _ in false {} - | ^^^^^ `bool` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^ `bool` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `bool` = note: required by `std::iter::IntoIterator::into_iter` -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:18:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:27:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `(): std::iter::Iterator` is not satisfied +error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:30:13 | LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^ `()` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `()` = note: required by `std::iter::Iterator::next` -error[E0277]: the trait bound `bool: std::iter::Iterator` is not satisfied +error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:33:14 | LL | for _ in false {} - | ^^^^^ `bool` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^ `bool` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `bool` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/issues/issue-50480.rs b/src/test/ui/issues/issue-50480.rs index 3427cf6bf9ca2..565ba8dd4de45 100644 --- a/src/test/ui/issues/issue-50480.rs +++ b/src/test/ui/issues/issue-50480.rs @@ -12,6 +12,6 @@ //~^ ERROR the trait `Copy` may not be implemented for this type struct Foo(NotDefined, ::Item, Vec, String); //~^ ERROR cannot find type `NotDefined` in this scope -//~| ERROR the trait bound `i32: std::iter::Iterator` is not satisfied +//~| ERROR `i32` is not an iterator fn main() {} diff --git a/src/test/ui/issues/issue-50480.stderr b/src/test/ui/issues/issue-50480.stderr index f5281fec4d1ea..672484f401a2f 100644 --- a/src/test/ui/issues/issue-50480.stderr +++ b/src/test/ui/issues/issue-50480.stderr @@ -4,13 +4,14 @@ error[E0412]: cannot find type `NotDefined` in this scope LL | struct Foo(NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope -error[E0277]: the trait bound `i32: std::iter::Iterator` is not satisfied +error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:13:24 | LL | struct Foo(NotDefined, ::Item, Vec, String); - | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = 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` error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/issue-50480.rs:11:17 diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.rs b/src/test/ui/suggestions/suggest-remove-refs-1.rs index 0f19c48337b1e..d7c80a677a5e1 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-1.rs +++ b/src/test/ui/suggestions/suggest-remove-refs-1.rs @@ -12,7 +12,7 @@ fn main() { let v = vec![0, 1, 2, 3]; for (i, n) in &v.iter().enumerate() { - //~^ ERROR the trait bound + //~^ ERROR `&std::iter::Enumerate>` is not an iterator println!("{}", i); } } diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.stderr b/src/test/ui/suggestions/suggest-remove-refs-1.stderr index c47b4d283d7cd..1fc661efd91f4 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-1.stderr +++ b/src/test/ui/suggestions/suggest-remove-refs-1.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `&std::iter::Enumerate>: std::iter::Iterator` is not satisfied +error[E0277]: `&std::iter::Enumerate>` is not an iterator --> $DIR/suggest-remove-refs-1.rs:14:19 | LL | for (i, n) in &v.iter().enumerate() { | -^^^^^^^^^^^^^^^^^^^^ | | - | `&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | `&std::iter::Enumerate>` is not an iterator | help: consider removing 1 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate>` diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.rs b/src/test/ui/suggestions/suggest-remove-refs-2.rs index c427f697ae1ef..37af97323d598 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-2.rs +++ b/src/test/ui/suggestions/suggest-remove-refs-2.rs @@ -12,7 +12,7 @@ fn main() { let v = vec![0, 1, 2, 3]; for (i, n) in & & & & &v.iter().enumerate() { - //~^ ERROR the trait bound + //~^ ERROR `&&&&&std::iter::Enumerate>` is not an iterator println!("{}", i); } } diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.stderr b/src/test/ui/suggestions/suggest-remove-refs-2.stderr index fdd654ea3923f..96c6c92d59baa 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-2.stderr +++ b/src/test/ui/suggestions/suggest-remove-refs-2.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied +error[E0277]: `&&&&&std::iter::Enumerate>` is not an iterator --> $DIR/suggest-remove-refs-2.rs:14:19 | LL | for (i, n) in & & & & &v.iter().enumerate() { | ---------^^^^^^^^^^^^^^^^^^^^ | | - | `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | `&&&&&std::iter::Enumerate>` is not an iterator | help: consider removing 5 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.rs b/src/test/ui/suggestions/suggest-remove-refs-3.rs index f54ae30caebca..c9dff35f92c0b 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-3.rs +++ b/src/test/ui/suggestions/suggest-remove-refs-3.rs @@ -15,7 +15,7 @@ fn main() { & &v .iter() .enumerate() { - //~^^^^ ERROR the trait bound + //~^^^^ ERROR `&&&&&std::iter::Enumerate>` is not an println!("{}", i); } } diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.stderr b/src/test/ui/suggestions/suggest-remove-refs-3.stderr index b0920a0fa523e..4311c432b41d3 100644 --- a/src/test/ui/suggestions/suggest-remove-refs-3.stderr +++ b/src/test/ui/suggestions/suggest-remove-refs-3.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied +error[E0277]: `&&&&&std::iter::Enumerate>` is not an iterator --> $DIR/suggest-remove-refs-3.rs:14:19 | LL | for (i, n) in & & & @@ -9,7 +9,7 @@ LL | || & &v | ||___________- help: consider removing 5 leading `&`-references LL | | .iter() LL | | .enumerate() { - | |_____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | |_____________________^ `&&&&&std::iter::Enumerate>` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` From 330b7eda952689b03a66c9e22361d6153c321648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 19:00:41 -0700 Subject: [PATCH 3/8] Add regression test (#22872) --- src/test/ui/issues/issue-22872.rs | 23 +++++++++++++++++++++++ src/test/ui/issues/issue-22872.stderr | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/test/ui/issues/issue-22872.rs create mode 100644 src/test/ui/issues/issue-22872.stderr diff --git a/src/test/ui/issues/issue-22872.rs b/src/test/ui/issues/issue-22872.rs new file mode 100644 index 0000000000000..7a83b098e78fe --- /dev/null +++ b/src/test/ui/issues/issue-22872.rs @@ -0,0 +1,23 @@ +trait Wrap<'b> { + fn foo(&'b mut self); +} + +struct Wrapper

(P); + +impl<'b, P> Wrap<'b> for Wrapper

+where P: Process<'b>, +

>::Item: Iterator { + fn foo(&mut self) {} +} + + +pub trait Process<'a> { + type Item; + fn bar(&'a self); +} + +fn push_process

(process: P) where P: Process<'static> { + let _: Box Wrap<'b>> = Box::new(Wrapper(process)); +} + +fn main() {} diff --git a/src/test/ui/issues/issue-22872.stderr b/src/test/ui/issues/issue-22872.stderr new file mode 100644 index 0000000000000..231080add9bd0 --- /dev/null +++ b/src/test/ui/issues/issue-22872.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `for<'b> P: Process<'b>` is not satisfied + --> $DIR/issue-22872.rs:20:36 + | +LL | let _: Box Wrap<'b>> = Box::new(Wrapper(process)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'b> Process<'b>` is not implemented for `P` + | + = help: consider adding a `where for<'b> P: Process<'b>` bound + = note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper

` + = note: required for the cast to the object type `dyn for<'b> Wrap<'b>` + +error[E0277]: `

>::Item` is not an iterator + --> $DIR/issue-22872.rs:20:36 + | +LL | let _: Box Wrap<'b>> = Box::new(Wrapper(process)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `

>::Item` is not an iterator + | + = help: the trait `for<'b> std::iter::Iterator` is not implemented for `

>::Item` + = note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for `Wrapper

` + = note: required for the cast to the object type `dyn for<'b> Wrap<'b>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 2305d02c1af360ac32f2679418621ade1c3469b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 19:01:17 -0700 Subject: [PATCH 4/8] Add tests for handled cases --- src/test/ui/iterators/array-of-ranges.rs | 9 ++ src/test/ui/iterators/array-of-ranges.stderr | 43 +++++++ src/test/ui/iterators/array.rs | 6 + src/test/ui/iterators/array.stderr | 33 +++++ src/test/ui/iterators/bound.rs | 3 + src/test/ui/iterators/bound.stderr | 17 +++ src/test/ui/iterators/integral.rs | 26 ++++ src/test/ui/iterators/integral.stderr | 122 +++++++++++++++++++ src/test/ui/iterators/string.rs | 6 + src/test/ui/iterators/string.stderr | 21 ++++ 10 files changed, 286 insertions(+) create mode 100644 src/test/ui/iterators/array-of-ranges.rs create mode 100644 src/test/ui/iterators/array-of-ranges.stderr create mode 100644 src/test/ui/iterators/array.rs create mode 100644 src/test/ui/iterators/array.stderr create mode 100644 src/test/ui/iterators/bound.rs create mode 100644 src/test/ui/iterators/bound.stderr create mode 100644 src/test/ui/iterators/integral.rs create mode 100644 src/test/ui/iterators/integral.stderr create mode 100644 src/test/ui/iterators/string.rs create mode 100644 src/test/ui/iterators/string.stderr diff --git a/src/test/ui/iterators/array-of-ranges.rs b/src/test/ui/iterators/array-of-ranges.rs new file mode 100644 index 0000000000000..eb2309f7a3f12 --- /dev/null +++ b/src/test/ui/iterators/array-of-ranges.rs @@ -0,0 +1,9 @@ +fn main() { + for _ in [0..1] {} + let start = 0; + let end = 0; + for _ in [start..end] {} + let array_of_range = [start..end]; + for _ in array_of_range {} + for _ in [0..1, 2..3] {} +} diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr new file mode 100644 index 0000000000000..95839ebc53a7c --- /dev/null +++ b/src/test/ui/iterators/array-of-ranges.stderr @@ -0,0 +1,43 @@ +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:2:14 + | +LL | for _ in [0..1] {} + | ^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` + = note: `[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:5:14 + | +LL | for _ in [start..end] {} + | ^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` + = note: `[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $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 + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` + = note: `[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator + --> $DIR/array-of-ranges.rs:8:14 + | +LL | for _ in [0..1, 2..3] {} + | ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/array.rs b/src/test/ui/iterators/array.rs new file mode 100644 index 0000000000000..f54bb81274362 --- /dev/null +++ b/src/test/ui/iterators/array.rs @@ -0,0 +1,6 @@ +fn main() { + for _ in [1, 2] {} + let x = [1, 2]; + for _ in x {} + for _ in [1.0, 2.0] {} +} diff --git a/src/test/ui/iterators/array.stderr b/src/test/ui/iterators/array.stderr new file mode 100644 index 0000000000000..fd74cd7a727e2 --- /dev/null +++ b/src/test/ui/iterators/array.stderr @@ -0,0 +1,33 @@ +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 + | + = help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[{integer}; 2]` is not an iterator + --> $DIR/array.rs:4:14 + | +LL | for _ in x {} + | ^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[{integer}; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[{float}; 2]` is not an iterator + --> $DIR/array.rs:5:14 + | +LL | for _ in [1.0, 2.0] {} + | ^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it + | + = help: the trait `std::iter::Iterator` is not implemented for `[{float}; 2]` + = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/bound.rs b/src/test/ui/iterators/bound.rs new file mode 100644 index 0000000000000..78285b8161c38 --- /dev/null +++ b/src/test/ui/iterators/bound.rs @@ -0,0 +1,3 @@ +struct S(I); +struct T(S); +fn main() {} diff --git a/src/test/ui/iterators/bound.stderr b/src/test/ui/iterators/bound.stderr new file mode 100644 index 0000000000000..2ddbd93c83c36 --- /dev/null +++ b/src/test/ui/iterators/bound.stderr @@ -0,0 +1,17 @@ +error[E0277]: `u8` is not an iterator + --> $DIR/bound.rs:2:10 + | +LL | struct T(S); + | ^^^^^ `u8` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u8` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` +note: required by `S` + --> $DIR/bound.rs:1:1 + | +LL | struct S(I); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/integral.rs b/src/test/ui/iterators/integral.rs new file mode 100644 index 0000000000000..7537c7904c0bf --- /dev/null +++ b/src/test/ui/iterators/integral.rs @@ -0,0 +1,26 @@ +fn main() { + for _ in 42 {} + //~^ ERROR `{integer}` is not an iterator + for _ in 42 as u8 {} + //~^ ERROR `u8` is not an iterator + for _ in 42 as i8 {} + //~^ ERROR `i8` is not an iterator + for _ in 42 as u16 {} + //~^ ERROR `u16` is not an iterator + for _ in 42 as i16 {} + //~^ ERROR `i16` is not an iterator + for _ in 42 as u32 {} + //~^ ERROR `u32` is not an iterator + for _ in 42 as i32 {} + //~^ ERROR `i32` is not an iterator + for _ in 42 as u64 {} + //~^ ERROR `u64` is not an iterator + for _ in 42 as i64 {} + //~^ ERROR `i64` is not an iterator + for _ in 42 as usize {} + //~^ ERROR `usize` is not an iterator + for _ in 42 as isize {} + //~^ ERROR `isize` is not an iterator + for _ in 42.0 {} + //~^ ERROR `{float}` is not an iterator +} diff --git a/src/test/ui/iterators/integral.stderr b/src/test/ui/iterators/integral.stderr new file mode 100644 index 0000000000000..3662d97d72e6a --- /dev/null +++ b/src/test/ui/iterators/integral.stderr @@ -0,0 +1,122 @@ +error[E0277]: `{integer}` is not an iterator + --> $DIR/integral.rs:2:14 + | +LL | for _ in 42 {} + | ^^ `{integer}` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `{integer}` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u8` is not an iterator + --> $DIR/integral.rs:4:14 + | +LL | for _ in 42 as u8 {} + | ^^^^^^^^ `u8` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u8` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i8` is not an iterator + --> $DIR/integral.rs:6:14 + | +LL | for _ in 42 as i8 {} + | ^^^^^^^^ `i8` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i8` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u16` is not an iterator + --> $DIR/integral.rs:8:14 + | +LL | for _ in 42 as u16 {} + | ^^^^^^^^^ `u16` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u16` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i16` is not an iterator + --> $DIR/integral.rs:10:14 + | +LL | for _ in 42 as i16 {} + | ^^^^^^^^^ `i16` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i16` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u32` is not an iterator + --> $DIR/integral.rs:12:14 + | +LL | for _ in 42 as u32 {} + | ^^^^^^^^^ `u32` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u32` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i32` is not an iterator + --> $DIR/integral.rs:14:14 + | +LL | for _ in 42 as i32 {} + | ^^^^^^^^^ `i32` is not an iterator + | + = 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` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `u64` is not an iterator + --> $DIR/integral.rs:16:14 + | +LL | for _ in 42 as u64 {} + | ^^^^^^^^^ `u64` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `u64` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `i64` is not an iterator + --> $DIR/integral.rs:18:14 + | +LL | for _ in 42 as i64 {} + | ^^^^^^^^^ `i64` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `i64` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `usize` is not an iterator + --> $DIR/integral.rs:20:14 + | +LL | for _ in 42 as usize {} + | ^^^^^^^^^^^ `usize` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `usize` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `isize` is not an iterator + --> $DIR/integral.rs:22:14 + | +LL | for _ in 42 as isize {} + | ^^^^^^^^^^^ `isize` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `isize` + = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `{float}` is not an iterator + --> $DIR/integral.rs:24:14 + | +LL | for _ in 42.0 {} + | ^^^^ `{float}` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `{float}` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/string.rs b/src/test/ui/iterators/string.rs new file mode 100644 index 0000000000000..4373dcaabe57b --- /dev/null +++ b/src/test/ui/iterators/string.rs @@ -0,0 +1,6 @@ +fn main() { + for _ in "".to_owned() {} + //~^ ERROR `std::string::String` is not an iterator + for _ in "" {} + //~^ ERROR `&str` is not an iterator +} diff --git a/src/test/ui/iterators/string.stderr b/src/test/ui/iterators/string.stderr new file mode 100644 index 0000000000000..927de952cc827 --- /dev/null +++ b/src/test/ui/iterators/string.stderr @@ -0,0 +1,21 @@ +error[E0277]: `std::string::String` is not an iterator + --> $DIR/string.rs:2:14 + | +LL | for _ in "".to_owned() {} + | ^^^^^^^^^^^^^ `std::string::String` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `std::iter::Iterator` is not implemented for `std::string::String` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `&str` is not an iterator + --> $DIR/string.rs:4:14 + | +LL | for _ in "" {} + | ^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `std::iter::Iterator` is not implemented for `&str` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From a0fd68b088fc8ce869ad89bdea4c8ef4441f1874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Oct 2018 20:19:57 -0700 Subject: [PATCH 5/8] fix tidy --- src/libcore/iter/iterator.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index b3fa5abd1c4eb..9e68ab92882f4 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -33,7 +33,8 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} on( _Self="[std::ops::Range; 1]", label="if you meant to iterate between two values, remove the square brackets", - note="`[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end`" + note="`[start..end]` is an array of one `Range`, you might have meant to have a `Range`: \ + `start..end`" ), on( _Self="&str", @@ -50,7 +51,8 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} ), on( _Self="{integral}", - note="if you want to iterate between `0` until a value `end`, use the range syntax: `0..end`" + note="if you want to iterate between `0` until a value `end`, use the range syntax: \ + `0..end`" ), label="`{Self}` is not an iterator", message="`{Self}` is not an iterator" From c71228e2f4d6ea82c9538391454801baa7946bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 11 Oct 2018 12:11:23 -0700 Subject: [PATCH 6/8] review comments - reword messages - apply custom comments to all types of ranges - fix indentation --- src/libcore/iter/iterator.rs | 32 ++++++++++++++++--- src/librustc/traits/error_reporting.rs | 2 +- .../feature-gate-trivial_bounds.stderr | 2 +- src/test/ui/issues/issue-50480.stderr | 2 +- src/test/ui/iterators/array-of-ranges.stderr | 6 ++-- src/test/ui/iterators/bound.stderr | 2 +- src/test/ui/iterators/integral.stderr | 22 ++++++------- 7 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 9e68ab92882f4..ff1bd71bd5515 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -33,8 +33,32 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} on( _Self="[std::ops::Range; 1]", label="if you meant to iterate between two values, remove the square brackets", - note="`[start..end]` is an array of one `Range`, you might have meant to have a `Range`: \ - `start..end`" + note="`[start..end]` is an array of one `Range`; you might have meant to have a `Range` \ + without the brackets: `start..end`" + ), + on( + _Self="[std::ops::RangeFrom; 1]", + label="if you meant to iterate from a value onwards, remove the square brackets", + note="`[start..]` is an array of one `RangeFrom`; you might have meant to have a \ + `RangeFrom` without the brackets: `start..`" + ), + on( + _Self="[std::ops::RangeTo; 1]", + label="if you meant to iterate until a value, remove the square brackets", + note="`[..end]` is an array of one `RangeTo`; you might have meant to have a \ + `RangeTo` without the brackets: `..end`" + ), + on( + _Self="[std::ops::RangeInclusive; 1]", + label="if you meant to iterate between two values, remove the square brackets", + note="`[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a \ + `RangeInclusive` without the brackets: `start..=end`" + ), + on( + _Self="[std::ops::RangeToInclusive; 1]", + label="if you meant to iterate until a value, remove the square brackets", + note="`[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a \ + `RangeToInclusive` without the brackets: `..=end`" ), on( _Self="&str", @@ -51,8 +75,8 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} ), on( _Self="{integral}", - note="if you want to iterate between `0` until a value `end`, use the range syntax: \ - `0..end`" + note="if you want to iterate between `start` until a value `end`, use the exclusive range \ + syntax `start..end` or the inclusive range syntax `start..=end`" ), label="`{Self}` is not an iterator", message="`{Self}` is not an iterator" diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index a7ebd0c8965c2..8288a45ad636b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -351,7 +351,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> OnUnimplementedNote { - let def_id = self.impl_similar_to(trait_ref, obligation) + let def_id = self.impl_similar_to(trait_ref, obligation) .unwrap_or(trait_ref.def_id()); let trait_ref = *trait_ref.skip_binder(); diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr index a37980d0d5122..14764b4e9f0f8 100644 --- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -84,7 +84,7 @@ LL | | } | |_^ `i32` is not an iterator | = 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` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = help: see issue #48214 = help: add #![feature(trivial_bounds)] to the crate attributes to enable diff --git a/src/test/ui/issues/issue-50480.stderr b/src/test/ui/issues/issue-50480.stderr index 672484f401a2f..cbff927ac74d4 100644 --- a/src/test/ui/issues/issue-50480.stderr +++ b/src/test/ui/issues/issue-50480.stderr @@ -11,7 +11,7 @@ LL | struct Foo(NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = 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` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` error[E0204]: the trait `Copy` may not be implemented for this type --> $DIR/issue-50480.rs:11:17 diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr index 95839ebc53a7c..073baab67b2b4 100644 --- a/src/test/ui/iterators/array-of-ranges.stderr +++ b/src/test/ui/iterators/array-of-ranges.stderr @@ -5,7 +5,7 @@ LL | for _ in [0..1] {} | ^^^^^^ if you meant to iterate between two values, remove the square brackets | = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` - = note: `[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end` + = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator @@ -15,7 +15,7 @@ LL | for _ in [start..end] {} | ^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets | = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` - = note: `[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end` + = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator @@ -25,7 +25,7 @@ LL | for _ in array_of_range {} | ^^^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets | = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::Range<{integer}>; 1]` - = note: `[start..end]` is an array of one `Range`, you might have meant to have a `Range`: `start..end` + = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator diff --git a/src/test/ui/iterators/bound.stderr b/src/test/ui/iterators/bound.stderr index 2ddbd93c83c36..14057387c4f40 100644 --- a/src/test/ui/iterators/bound.stderr +++ b/src/test/ui/iterators/bound.stderr @@ -5,7 +5,7 @@ LL | struct T(S); | ^^^^^ `u8` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `u8` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` note: required by `S` --> $DIR/bound.rs:1:1 | diff --git a/src/test/ui/iterators/integral.stderr b/src/test/ui/iterators/integral.stderr index 3662d97d72e6a..71e1e81e5afec 100644 --- a/src/test/ui/iterators/integral.stderr +++ b/src/test/ui/iterators/integral.stderr @@ -5,7 +5,7 @@ LL | for _ in 42 {} | ^^ `{integer}` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `{integer}` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `u8` is not an iterator @@ -15,7 +15,7 @@ LL | for _ in 42 as u8 {} | ^^^^^^^^ `u8` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `u8` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `i8` is not an iterator @@ -25,7 +25,7 @@ LL | for _ in 42 as i8 {} | ^^^^^^^^ `i8` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `i8` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `u16` is not an iterator @@ -35,7 +35,7 @@ LL | for _ in 42 as u16 {} | ^^^^^^^^^ `u16` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `u16` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `i16` is not an iterator @@ -45,7 +45,7 @@ LL | for _ in 42 as i16 {} | ^^^^^^^^^ `i16` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `i16` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `u32` is not an iterator @@ -55,7 +55,7 @@ LL | for _ in 42 as u32 {} | ^^^^^^^^^ `u32` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `u32` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `i32` is not an iterator @@ -65,7 +65,7 @@ LL | for _ in 42 as i32 {} | ^^^^^^^^^ `i32` is not an iterator | = 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` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `u64` is not an iterator @@ -75,7 +75,7 @@ LL | for _ in 42 as u64 {} | ^^^^^^^^^ `u64` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `u64` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `i64` is not an iterator @@ -85,7 +85,7 @@ LL | for _ in 42 as i64 {} | ^^^^^^^^^ `i64` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `i64` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `usize` is not an iterator @@ -95,7 +95,7 @@ LL | for _ in 42 as usize {} | ^^^^^^^^^^^ `usize` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `usize` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `isize` is not an iterator @@ -105,7 +105,7 @@ LL | for _ in 42 as isize {} | ^^^^^^^^^^^ `isize` is not an iterator | = help: the trait `std::iter::Iterator` is not implemented for `isize` - = note: if you want to iterate between `0` until a value `end`, use the range syntax: `0..end` + = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `{float}` is not an iterator From 5beeb535e1cbe0e93d623f674a33c57ed885c812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 11 Oct 2018 13:25:28 -0700 Subject: [PATCH 7/8] Reword Range*/[Range*]: Iterator E0277 messages --- src/libcore/iter/iterator.rs | 28 ++++++++-- src/test/ui/iterators/array-of-ranges.rs | 5 ++ src/test/ui/iterators/array-of-ranges.stderr | 58 ++++++++++++++++++-- src/test/ui/iterators/ranges.rs | 9 +++ src/test/ui/iterators/ranges.stderr | 23 ++++++++ 5 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/iterators/ranges.rs create mode 100644 src/test/ui/iterators/ranges.stderr diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index ff1bd71bd5515..5b6d9e2033caa 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -40,13 +40,16 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} _Self="[std::ops::RangeFrom; 1]", label="if you meant to iterate from a value onwards, remove the square brackets", note="`[start..]` is an array of one `RangeFrom`; you might have meant to have a \ - `RangeFrom` without the brackets: `start..`" + `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" ), on( _Self="[std::ops::RangeTo; 1]", - label="if you meant to iterate until a value, remove the square brackets", - note="`[..end]` is an array of one `RangeTo`; you might have meant to have a \ - `RangeTo` without the brackets: `..end`" + label="if you meant to iterate until a value, remove the square brackets and add a \ + starting value", + note="`[..end]` is an array of one `RangeTo`; you might have meant to have a bounded \ + `Range` without the brackets: `0..end`" ), on( _Self="[std::ops::RangeInclusive; 1]", @@ -56,9 +59,22 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} ), on( _Self="[std::ops::RangeToInclusive; 1]", - label="if you meant to iterate until a value, remove the square brackets", + label="if you meant to iterate until a value (including it), remove the square brackets \ + and add a starting value", note="`[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a \ - `RangeToInclusive` without the brackets: `..=end`" + bounded `RangeInclusive` without the brackets: `0..=end`" + ), + on( + _Self="std::ops::RangeTo", + label="if you meant to iterate until a value, add a starting value", + note="`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \ + bounded `Range`: `0..end`" + ), + on( + _Self="std::ops::RangeToInclusive", + label="if you meant to iterate until a value (including it), add a starting value", + note="`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \ + to have a bounded `RangeInclusive`: `0..=end`" ), on( _Self="&str", diff --git a/src/test/ui/iterators/array-of-ranges.rs b/src/test/ui/iterators/array-of-ranges.rs index eb2309f7a3f12..a7d6e80bae5f7 100644 --- a/src/test/ui/iterators/array-of-ranges.rs +++ b/src/test/ui/iterators/array-of-ranges.rs @@ -1,9 +1,14 @@ fn main() { for _ in [0..1] {} + for _ in [0..=1] {} + for _ in [0..] {} + for _ in [..1] {} + for _ in [..=1] {} let start = 0; let end = 0; for _ in [start..end] {} let array_of_range = [start..end]; for _ in array_of_range {} for _ in [0..1, 2..3] {} + for _ in [0..=1] {} } diff --git a/src/test/ui/iterators/array-of-ranges.stderr b/src/test/ui/iterators/array-of-ranges.stderr index 073baab67b2b4..fbe7e0ee74889 100644 --- a/src/test/ui/iterators/array-of-ranges.stderr +++ b/src/test/ui/iterators/array-of-ranges.stderr @@ -8,9 +8,49 @@ LL | for _ in [0..1] {} = note: `[start..end]` is an array of one `Range`; you might have meant to have a `Range` without the brackets: `start..end` = note: required by `std::iter::IntoIterator::into_iter` -error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator +error[E0277]: `[std::ops::RangeInclusive<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:3:14 + | +LL | for _ in [0..=1] {} + | ^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeInclusive<{integer}>; 1]` + = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeFrom<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:4:14 + | +LL | for _ in [0..] {} + | ^^^^^ if you meant to iterate from a value onwards, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeFrom<{integer}>; 1]` + = 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 by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeTo<{integer}>; 1]` is not an iterator --> $DIR/array-of-ranges.rs:5:14 | +LL | for _ in [..1] {} + | ^^^^^ if you meant to iterate until a value, remove the square brackets and add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeTo<{integer}>; 1]` + = note: `[..end]` is an array of one `RangeTo`; you might have meant to have a bounded `Range` without the brackets: `0..end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::RangeToInclusive<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:6:14 + | +LL | for _ in [..=1] {} + | ^^^^^^ if you meant to iterate until a value (including it), remove the square brackets and add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeToInclusive<{integer}>; 1]` + = note: `[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a bounded `RangeInclusive` without the brackets: `0..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:9:14 + | LL | for _ in [start..end] {} | ^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets | @@ -19,7 +59,7 @@ LL | for _ in [start..end] {} = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `[std::ops::Range<{integer}>; 1]` is not an iterator - --> $DIR/array-of-ranges.rs:7:14 + --> $DIR/array-of-ranges.rs:11:14 | LL | for _ in array_of_range {} | ^^^^^^^^^^^^^^ if you meant to iterate between two values, remove the square brackets @@ -29,7 +69,7 @@ LL | for _ in array_of_range {} = note: required by `std::iter::IntoIterator::into_iter` error[E0277]: `[std::ops::Range<{integer}>; 2]` is not an iterator - --> $DIR/array-of-ranges.rs:8:14 + --> $DIR/array-of-ranges.rs:12:14 | LL | for _ in [0..1, 2..3] {} | ^^^^^^^^^^^^ borrow the array with `&` or call `.iter()` on it to iterate over it @@ -38,6 +78,16 @@ LL | for _ in [0..1, 2..3] {} = note: arrays are not an iterators, but slices like the following are: `&[1, 2, 3]` = note: required by `std::iter::IntoIterator::into_iter` -error: aborting due to 4 previous errors +error[E0277]: `[std::ops::RangeInclusive<{integer}>; 1]` is not an iterator + --> $DIR/array-of-ranges.rs:13:14 + | +LL | for _ in [0..=1] {} + | ^^^^^^^ if you meant to iterate between two values, remove the square brackets + | + = help: the trait `std::iter::Iterator` is not implemented for `[std::ops::RangeInclusive<{integer}>; 1]` + = note: `[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a `RangeInclusive` without the brackets: `start..=end` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/ranges.rs b/src/test/ui/iterators/ranges.rs new file mode 100644 index 0000000000000..925d2d61a1247 --- /dev/null +++ b/src/test/ui/iterators/ranges.rs @@ -0,0 +1,9 @@ +fn main() { + for _ in ..10 {} + //~^ ERROR E0277 + for _ in ..=10 {} + //~^ ERROR E0277 + for _ in 0..10 {} + for _ in 0..=10 {} + for _ in 0.. {} +} diff --git a/src/test/ui/iterators/ranges.stderr b/src/test/ui/iterators/ranges.stderr new file mode 100644 index 0000000000000..e5e2d87879d23 --- /dev/null +++ b/src/test/ui/iterators/ranges.stderr @@ -0,0 +1,23 @@ +error[E0277]: `std::ops::RangeTo<{integer}>` is not an iterator + --> $DIR/ranges.rs:2:14 + | +LL | for _ in ..10 {} + | ^^^^ if you meant to iterate until a value, add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `std::ops::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 by `std::iter::IntoIterator::into_iter` + +error[E0277]: `std::ops::RangeToInclusive<{integer}>` is not an iterator + --> $DIR/ranges.rs:4:14 + | +LL | for _ in ..=10 {} + | ^^^^^ if you meant to iterate until a value (including it), add a starting value + | + = help: the trait `std::iter::Iterator` is not implemented for `std::ops::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 by `std::iter::IntoIterator::into_iter` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From def0f544a31bc6cc3dbf153f28304219fa38fa5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Oct 2018 10:12:29 -0700 Subject: [PATCH 8/8] Change Scalar to numeric cast --- src/librustc/traits/error_reporting.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8288a45ad636b..fc34a71f39221 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -424,8 +424,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "_Self".to_owned(), Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), )); + let tcx = self.tcx; if let Some(len) = len.val.try_to_scalar().and_then(|scalar| { - scalar.to_u64().ok() + scalar.to_usize(tcx).ok() }) { flags.push(( "_Self".to_owned(),