Rollup merge of #106360 - estebank:remove-borrow-suggestion, r=compiler-errors
Tweak E0277 `&`-removal suggestions Fix #64068, fix #84837.
This commit is contained in:
commit
54f6fea818
17 changed files with 253 additions and 76 deletions
|
@ -1361,57 +1361,117 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let span = obligation.cause.span;
|
let mut span = obligation.cause.span;
|
||||||
|
let mut trait_pred = trait_pred;
|
||||||
|
let mut code = obligation.cause.code();
|
||||||
|
while let Some((c, Some(parent_trait_pred))) = code.parent() {
|
||||||
|
// We want the root obligation, in order to detect properly handle
|
||||||
|
// `for _ in &mut &mut vec![] {}`.
|
||||||
|
code = c;
|
||||||
|
trait_pred = parent_trait_pred;
|
||||||
|
}
|
||||||
|
while span.desugaring_kind().is_some() {
|
||||||
|
// Remove all the hir desugaring contexts while maintaining the macro contexts.
|
||||||
|
span.remove_mark();
|
||||||
|
}
|
||||||
|
let mut expr_finder = super::FindExprBySpan::new(span);
|
||||||
|
let Some(hir::Node::Expr(body)) = self.tcx.hir().find(obligation.cause.body_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
expr_finder.visit_expr(&body);
|
||||||
|
let mut maybe_suggest = |suggested_ty, count, suggestions| {
|
||||||
|
// Remapping bound vars here
|
||||||
|
let trait_pred_and_suggested_ty =
|
||||||
|
trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty));
|
||||||
|
|
||||||
let mut suggested = false;
|
let new_obligation = self.mk_trait_obligation_with_new_self_ty(
|
||||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
obligation.param_env,
|
||||||
let refs_number =
|
trait_pred_and_suggested_ty,
|
||||||
snippet.chars().filter(|c| !c.is_whitespace()).take_while(|c| *c == '&').count();
|
);
|
||||||
if let Some('\'') = snippet.chars().filter(|c| !c.is_whitespace()).nth(refs_number) {
|
|
||||||
// Do not suggest removal of borrow from type arguments.
|
if self.predicate_may_hold(&new_obligation) {
|
||||||
return false;
|
let msg = if count == 1 {
|
||||||
|
"consider removing the leading `&`-reference".to_string()
|
||||||
|
} else {
|
||||||
|
format!("consider removing {count} leading `&`-references")
|
||||||
|
};
|
||||||
|
|
||||||
|
err.multipart_suggestion_verbose(
|
||||||
|
&msg,
|
||||||
|
suggestions,
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Skipping binder here, remapping below
|
// Maybe suggest removal of borrows from types in type parameters, like in
|
||||||
let mut suggested_ty = trait_pred.self_ty().skip_binder();
|
// `src/test/ui/not-panic/not-panic-safe.rs`.
|
||||||
|
let mut count = 0;
|
||||||
|
let mut suggestions = vec![];
|
||||||
|
// Skipping binder here, remapping below
|
||||||
|
let mut suggested_ty = trait_pred.self_ty().skip_binder();
|
||||||
|
if let Some(mut hir_ty) = expr_finder.ty_result {
|
||||||
|
while let hir::TyKind::Ref(_, mut_ty) = &hir_ty.kind {
|
||||||
|
count += 1;
|
||||||
|
let span = hir_ty.span.until(mut_ty.ty.span);
|
||||||
|
suggestions.push((span, String::new()));
|
||||||
|
|
||||||
for refs_remaining in 0..refs_number {
|
|
||||||
let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
|
let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
suggested_ty = *inner_ty;
|
suggested_ty = *inner_ty;
|
||||||
|
|
||||||
// Remapping bound vars here
|
hir_ty = mut_ty.ty;
|
||||||
let trait_pred_and_suggested_ty =
|
|
||||||
trait_pred.map_bound(|trait_pred| (trait_pred, suggested_ty));
|
|
||||||
|
|
||||||
let new_obligation = self.mk_trait_obligation_with_new_self_ty(
|
if maybe_suggest(suggested_ty, count, suggestions.clone()) {
|
||||||
obligation.param_env,
|
return true;
|
||||||
trait_pred_and_suggested_ty,
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.predicate_may_hold(&new_obligation) {
|
|
||||||
let sp = self
|
|
||||||
.tcx
|
|
||||||
.sess
|
|
||||||
.source_map()
|
|
||||||
.span_take_while(span, |c| c.is_whitespace() || *c == '&');
|
|
||||||
|
|
||||||
let remove_refs = refs_remaining + 1;
|
|
||||||
|
|
||||||
let msg = if remove_refs == 1 {
|
|
||||||
"consider removing the leading `&`-reference".to_string()
|
|
||||||
} else {
|
|
||||||
format!("consider removing {} leading `&`-references", remove_refs)
|
|
||||||
};
|
|
||||||
|
|
||||||
err.span_suggestion_short(sp, &msg, "", Applicability::MachineApplicable);
|
|
||||||
suggested = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
suggested
|
|
||||||
|
// Maybe suggest removal of borrows from expressions, like in `for i in &&&foo {}`.
|
||||||
|
let Some(mut expr) = expr_finder.result else { return false; };
|
||||||
|
let mut count = 0;
|
||||||
|
let mut suggestions = vec![];
|
||||||
|
// Skipping binder here, remapping below
|
||||||
|
let mut suggested_ty = trait_pred.self_ty().skip_binder();
|
||||||
|
'outer: loop {
|
||||||
|
while let hir::ExprKind::AddrOf(_, _, borrowed) = expr.kind {
|
||||||
|
count += 1;
|
||||||
|
let span = if expr.span.eq_ctxt(borrowed.span) {
|
||||||
|
expr.span.until(borrowed.span)
|
||||||
|
} else {
|
||||||
|
expr.span.with_hi(expr.span.lo() + BytePos(1))
|
||||||
|
};
|
||||||
|
suggestions.push((span, String::new()));
|
||||||
|
|
||||||
|
let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else {
|
||||||
|
break 'outer;
|
||||||
|
};
|
||||||
|
suggested_ty = *inner_ty;
|
||||||
|
|
||||||
|
expr = borrowed;
|
||||||
|
|
||||||
|
if maybe_suggest(suggested_ty, count, suggestions.clone()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
|
||||||
|
&& let hir::def::Res::Local(hir_id) = path.res
|
||||||
|
&& let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id)
|
||||||
|
&& let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
|
||||||
|
&& let None = local.ty
|
||||||
|
&& let Some(binding_expr) = local.init
|
||||||
|
{
|
||||||
|
expr = binding_expr;
|
||||||
|
} else {
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) {
|
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied
|
||||||
LL | is_defaulted::<&'static u32>();
|
LL | is_defaulted::<&'static u32>();
|
||||||
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
|
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
|
||||||
|
|
|
|
||||||
= help: the trait `Signed` is implemented for `i32`
|
|
||||||
note: required for `&'static u32` to implement `Defaulted`
|
note: required for `&'static u32` to implement `Defaulted`
|
||||||
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
|
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
|
||||||
|
|
|
|
||||||
|
@ -17,6 +16,11 @@ note: required by a bound in `is_defaulted`
|
||||||
|
|
|
|
||||||
LL | fn is_defaulted<T:Defaulted>() { }
|
LL | fn is_defaulted<T:Defaulted>() { }
|
||||||
| ^^^^^^^^^ required by this bound in `is_defaulted`
|
| ^^^^^^^^^ required by this bound in `is_defaulted`
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - is_defaulted::<&'static u32>();
|
||||||
|
LL + is_defaulted::<u32>();
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,15 @@ error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
--> $DIR/issue-102140.rs:23:22
|
--> $DIR/issue-102140.rs:23:22
|
||||||
|
|
|
|
||||||
LL | MyTrait::foo(&self)
|
LL | MyTrait::foo(&self)
|
||||||
| ------------ -^^^^
|
| ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
||||||
| | |
|
| |
|
||||||
| | the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
|
||||||
| | help: consider removing the leading `&`-reference
|
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - MyTrait::foo(&self)
|
||||||
|
LL + MyTrait::foo(self)
|
||||||
|
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
--> $DIR/issue-102140.rs:23:9
|
--> $DIR/issue-102140.rs:23:9
|
||||||
|
|
|
@ -4,12 +4,16 @@ error[E0277]: the trait bound `&'static mut isize: Copy` is not satisfied
|
||||||
LL | assert_copy::<&'static mut isize>();
|
LL | assert_copy::<&'static mut isize>();
|
||||||
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize`
|
| ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'static mut isize`
|
||||||
|
|
|
|
||||||
= help: the trait `Copy` is implemented for `isize`
|
|
||||||
note: required by a bound in `assert_copy`
|
note: required by a bound in `assert_copy`
|
||||||
--> $DIR/kindck-copy.rs:5:18
|
--> $DIR/kindck-copy.rs:5:18
|
||||||
|
|
|
|
||||||
LL | fn assert_copy<T:Copy>() { }
|
LL | fn assert_copy<T:Copy>() { }
|
||||||
| ^^^^ required by this bound in `assert_copy`
|
| ^^^^ required by this bound in `assert_copy`
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - assert_copy::<&'static mut isize>();
|
||||||
|
LL + assert_copy::<isize>();
|
||||||
|
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied
|
error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied
|
||||||
--> $DIR/kindck-copy.rs:28:19
|
--> $DIR/kindck-copy.rs:28:19
|
||||||
|
@ -17,12 +21,16 @@ error[E0277]: the trait bound `&'a mut isize: Copy` is not satisfied
|
||||||
LL | assert_copy::<&'a mut isize>();
|
LL | assert_copy::<&'a mut isize>();
|
||||||
| ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize`
|
| ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `&'a mut isize`
|
||||||
|
|
|
|
||||||
= help: the trait `Copy` is implemented for `isize`
|
|
||||||
note: required by a bound in `assert_copy`
|
note: required by a bound in `assert_copy`
|
||||||
--> $DIR/kindck-copy.rs:5:18
|
--> $DIR/kindck-copy.rs:5:18
|
||||||
|
|
|
|
||||||
LL | fn assert_copy<T:Copy>() { }
|
LL | fn assert_copy<T:Copy>() { }
|
||||||
| ^^^^ required by this bound in `assert_copy`
|
| ^^^^ required by this bound in `assert_copy`
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - assert_copy::<&'a mut isize>();
|
||||||
|
LL + assert_copy::<isize>();
|
||||||
|
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `Box<isize>: Copy` is not satisfied
|
error[E0277]: the trait bound `Box<isize>: Copy` is not satisfied
|
||||||
--> $DIR/kindck-copy.rs:31:19
|
--> $DIR/kindck-copy.rs:31:19
|
||||||
|
|
|
@ -12,6 +12,11 @@ note: required by a bound in `assert`
|
||||||
|
|
|
|
||||||
LL | fn assert<T: UnwindSafe + ?Sized>() {}
|
LL | fn assert<T: UnwindSafe + ?Sized>() {}
|
||||||
| ^^^^^^^^^^ required by this bound in `assert`
|
| ^^^^^^^^^^ required by this bound in `assert`
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - assert::<&RefCell<i32>>();
|
||||||
|
LL + assert::<RefCell<i32>>();
|
||||||
|
|
|
||||||
|
|
||||||
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
|
||||||
--> $DIR/not-panic-safe-4.rs:9:14
|
--> $DIR/not-panic-safe-4.rs:9:14
|
||||||
|
@ -28,6 +33,11 @@ note: required by a bound in `assert`
|
||||||
|
|
|
|
||||||
LL | fn assert<T: UnwindSafe + ?Sized>() {}
|
LL | fn assert<T: UnwindSafe + ?Sized>() {}
|
||||||
| ^^^^^^^^^^ required by this bound in `assert`
|
| ^^^^^^^^^^ required by this bound in `assert`
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - assert::<&RefCell<i32>>();
|
||||||
|
LL + assert::<RefCell<i32>>();
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,6 @@ use std::panic::UnwindSafe;
|
||||||
fn assert<T: UnwindSafe + ?Sized>() {}
|
fn assert<T: UnwindSafe + ?Sized>() {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert::<&mut i32>();
|
assert::<&mut &mut &i32>();
|
||||||
//~^ ERROR the type `&mut i32` may not be safely transferred across an unwind boundary
|
//~^ ERROR the type `&mut &mut &i32` may not be safely transferred across an unwind boundary
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
error[E0277]: the type `&mut i32` may not be safely transferred across an unwind boundary
|
error[E0277]: the type `&mut &mut &i32` may not be safely transferred across an unwind boundary
|
||||||
--> $DIR/not-panic-safe.rs:8:14
|
--> $DIR/not-panic-safe.rs:8:14
|
||||||
|
|
|
|
||||||
LL | assert::<&mut i32>();
|
LL | assert::<&mut &mut &i32>();
|
||||||
| -^^^^^^^
|
| ^^^^^^^^^^^^^^ `&mut &mut &i32` may not be safely transferred across an unwind boundary
|
||||||
| |
|
|
||||||
| `&mut i32` may not be safely transferred across an unwind boundary
|
|
||||||
| help: consider removing the leading `&`-reference
|
|
||||||
|
|
|
|
||||||
= help: the trait `UnwindSafe` is not implemented for `&mut i32`
|
= help: the trait `UnwindSafe` is not implemented for `&mut &mut &i32`
|
||||||
= note: `UnwindSafe` is implemented for `&i32`, but not for `&mut i32`
|
= note: `UnwindSafe` is implemented for `&&mut &i32`, but not for `&mut &mut &i32`
|
||||||
note: required by a bound in `assert`
|
note: required by a bound in `assert`
|
||||||
--> $DIR/not-panic-safe.rs:5:14
|
--> $DIR/not-panic-safe.rs:5:14
|
||||||
|
|
|
|
||||||
LL | fn assert<T: UnwindSafe + ?Sized>() {}
|
LL | fn assert<T: UnwindSafe + ?Sized>() {}
|
||||||
| ^^^^^^^^^^ required by this bound in `assert`
|
| ^^^^^^^^^^ required by this bound in `assert`
|
||||||
|
help: consider removing 2 leading `&`-references
|
||||||
|
|
|
||||||
|
LL - assert::<&mut &mut &i32>();
|
||||||
|
LL + assert::<&i32>();
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,15 @@ error[E0277]: `&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
||||||
--> $DIR/suggest-remove-refs-1.rs:6:19
|
--> $DIR/suggest-remove-refs-1.rs:6:19
|
||||||
|
|
|
|
||||||
LL | for (i, _) in &v.iter().enumerate() {
|
LL | for (i, _) in &v.iter().enumerate() {
|
||||||
| -^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^ `&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
||||||
| |
|
|
||||||
| `&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
|
||||||
| help: consider removing the leading `&`-reference
|
|
||||||
|
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
|
= help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
|
||||||
= note: required for `&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
|
= note: required for `&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - for (i, _) in &v.iter().enumerate() {
|
||||||
|
LL + for (i, _) in v.iter().enumerate() {
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,15 @@ error[E0277]: `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterat
|
||||||
--> $DIR/suggest-remove-refs-2.rs:6:19
|
--> $DIR/suggest-remove-refs-2.rs:6:19
|
||||||
|
|
|
|
||||||
LL | for (i, _) in & & & & &v.iter().enumerate() {
|
LL | for (i, _) in & & & & &v.iter().enumerate() {
|
||||||
| ---------^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
||||||
| |
|
|
||||||
| `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
|
||||||
| help: consider removing 5 leading `&`-references
|
|
||||||
|
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
|
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
|
||||||
= note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
|
= note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
|
||||||
|
help: consider removing 5 leading `&`-references
|
||||||
|
|
|
||||||
|
LL - for (i, _) in & & & & &v.iter().enumerate() {
|
||||||
|
LL + for (i, _) in v.iter().enumerate() {
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
error[E0277]: `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
error[E0277]: `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
||||||
--> $DIR/suggest-remove-refs-3.rs:6:19
|
--> $DIR/suggest-remove-refs-3.rs:6:19
|
||||||
|
|
|
|
||||||
LL | for (i, _) in & & &
|
LL | for (i, _) in & & &
|
||||||
| ____________________^
|
| ___________________^
|
||||||
| | ___________________|
|
LL | | & &v
|
||||||
| ||
|
LL | | .iter()
|
||||||
LL | || & &v
|
LL | | .enumerate() {
|
||||||
| ||___________- help: consider removing 5 leading `&`-references
|
| |____________________^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
||||||
LL | | .iter()
|
|
||||||
LL | | .enumerate() {
|
|
||||||
| |_____________________^ `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
|
|
||||||
|
|
|
|
||||||
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
|
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
|
||||||
= note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
|
= note: required for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
|
||||||
|
help: consider removing 5 leading `&`-references
|
||||||
|
|
|
||||||
|
LL - for (i, _) in & & &
|
||||||
|
LL + for (i, _) in v
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
5
tests/ui/suggestions/suggest-remove-refs-4.fixed
Normal file
5
tests/ui/suggestions/suggest-remove-refs-4.fixed
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// run-rustfix
|
||||||
|
fn main() {
|
||||||
|
let foo = [1,2,3].iter();
|
||||||
|
for _i in foo {} //~ ERROR E0277
|
||||||
|
}
|
5
tests/ui/suggestions/suggest-remove-refs-4.rs
Normal file
5
tests/ui/suggestions/suggest-remove-refs-4.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// run-rustfix
|
||||||
|
fn main() {
|
||||||
|
let foo = &[1,2,3].iter();
|
||||||
|
for _i in &foo {} //~ ERROR E0277
|
||||||
|
}
|
17
tests/ui/suggestions/suggest-remove-refs-4.stderr
Normal file
17
tests/ui/suggestions/suggest-remove-refs-4.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0277]: `&&std::slice::Iter<'_, {integer}>` is not an iterator
|
||||||
|
--> $DIR/suggest-remove-refs-4.rs:4:15
|
||||||
|
|
|
||||||
|
LL | for _i in &foo {}
|
||||||
|
| ^^^^ `&&std::slice::Iter<'_, {integer}>` is not an iterator
|
||||||
|
|
|
||||||
|
= help: the trait `Iterator` is not implemented for `&&std::slice::Iter<'_, {integer}>`
|
||||||
|
= note: required for `&&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
|
||||||
|
help: consider removing 2 leading `&`-references
|
||||||
|
|
|
||||||
|
LL ~ let foo = [1,2,3].iter();
|
||||||
|
LL ~ for _i in foo {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
8
tests/ui/suggestions/suggest-remove-refs-5.fixed
Normal file
8
tests/ui/suggestions/suggest-remove-refs-5.fixed
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// run-rustfix
|
||||||
|
fn main() {
|
||||||
|
let v = &mut Vec::<i32>::new();
|
||||||
|
for _ in v {} //~ ERROR E0277
|
||||||
|
|
||||||
|
let v = &mut [1u8];
|
||||||
|
for _ in v {} //~ ERROR E0277
|
||||||
|
}
|
8
tests/ui/suggestions/suggest-remove-refs-5.rs
Normal file
8
tests/ui/suggestions/suggest-remove-refs-5.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// run-rustfix
|
||||||
|
fn main() {
|
||||||
|
let v = &mut &mut Vec::<i32>::new();
|
||||||
|
for _ in &mut &mut v {} //~ ERROR E0277
|
||||||
|
|
||||||
|
let v = &mut &mut [1u8];
|
||||||
|
for _ in &mut v {} //~ ERROR E0277
|
||||||
|
}
|
37
tests/ui/suggestions/suggest-remove-refs-5.stderr
Normal file
37
tests/ui/suggestions/suggest-remove-refs-5.stderr
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
error[E0277]: `Vec<i32>` is not an iterator
|
||||||
|
--> $DIR/suggest-remove-refs-5.rs:4:14
|
||||||
|
|
|
||||||
|
LL | for _ in &mut &mut v {}
|
||||||
|
| ^^^^^^^^^^^ `Vec<i32>` is not an iterator; try calling `.into_iter()` or `.iter()`
|
||||||
|
|
|
||||||
|
= help: the trait `Iterator` is not implemented for `Vec<i32>`
|
||||||
|
= note: required for `&mut Vec<i32>` to implement `Iterator`
|
||||||
|
= note: 3 redundant requirements hidden
|
||||||
|
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
|
||||||
|
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `IntoIterator`
|
||||||
|
help: consider removing 3 leading `&`-references
|
||||||
|
|
|
||||||
|
LL ~ let v = &mut Vec::<i32>::new();
|
||||||
|
LL ~ for _ in v {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0277]: `[u8; 1]` is not an iterator
|
||||||
|
--> $DIR/suggest-remove-refs-5.rs:7:14
|
||||||
|
|
|
||||||
|
LL | for _ in &mut v {}
|
||||||
|
| ^^^^^^ `[u8; 1]` is not an iterator; try calling `.into_iter()` or `.iter()`
|
||||||
|
|
|
||||||
|
= help: the trait `Iterator` is not implemented for `[u8; 1]`
|
||||||
|
= note: required for `&mut [u8; 1]` to implement `Iterator`
|
||||||
|
= note: 2 redundant requirements hidden
|
||||||
|
= note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
|
||||||
|
= note: required for `&mut &mut &mut [u8; 1]` to implement `IntoIterator`
|
||||||
|
help: consider removing 2 leading `&`-references
|
||||||
|
|
|
||||||
|
LL ~ let v = &mut [1u8];
|
||||||
|
LL ~ for _ in v {}
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -2,14 +2,17 @@ error[E0277]: `&mut ()` is not a tuple
|
||||||
--> $DIR/issue-57404.rs:6:41
|
--> $DIR/issue-57404.rs:6:41
|
||||||
|
|
|
|
||||||
LL | handlers.unwrap().as_mut().call_mut(&mut ());
|
LL | handlers.unwrap().as_mut().call_mut(&mut ());
|
||||||
| -------- -^^^^^^
|
| -------- ^^^^^^^ the trait `Tuple` is not implemented for `&mut ()`
|
||||||
| | |
|
| |
|
||||||
| | the trait `Tuple` is not implemented for `&mut ()`
|
|
||||||
| | help: consider removing the leading `&`-reference
|
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
note: required by a bound in `call_mut`
|
note: required by a bound in `call_mut`
|
||||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||||
|
help: consider removing the leading `&`-reference
|
||||||
|
|
|
||||||
|
LL - handlers.unwrap().as_mut().call_mut(&mut ());
|
||||||
|
LL + handlers.unwrap().as_mut().call_mut(());
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue