diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2025-07-10 17:15:42 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2025-07-10 17:23:29 +0000 |
| commit | 7dfc3e9af45ad54832c083baf0d2d0ca8e0d979a (patch) | |
| tree | 402cbafb83b5b24077b444f4e71f38d0a613a088 | |
| parent | 78a6e132984dba0303ebad7dcfd1305c93ad5835 (diff) | |
| download | rust-7dfc3e9af45ad54832c083baf0d2d0ca8e0d979a.tar.gz rust-7dfc3e9af45ad54832c083baf0d2d0ca8e0d979a.zip | |
Rework borrowing suggestions to use `Expr` instead of just `Span`
In the suggestion machinery for borrowing expressions and types, always use the available obligation `Span` to find the appropriate `Expr` to perform appropriateness checks no the `ExprKind` instead of on the textual snippet corresponding to the `Span`. Unify the logic for the case where `&` *and* `&mut` are appropriate with the logic for only one of those cases. Handle the case when `S::foo()` should have been `<&S>::foo()` (instead of suggesting the prior `&S::foo()`.
16 files changed, 217 insertions, 213 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 3e64573aa03..8c9eb41568f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1321,7 +1321,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let imm_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_imm_ref); let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); - let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = + let (ref_inner_ty_satisfies_pred, ref_inner_ty_is_mut) = if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { @@ -1333,117 +1333,139 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (false, false) }; - if imm_ref_self_ty_satisfies_pred - || mut_ref_self_ty_satisfies_pred - || ref_inner_ty_satisfies_pred - { - if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - // We don't want a borrowing suggestion on the fields in structs, - // ``` - // struct Foo { - // the_foos: Vec<Foo> - // } - // ``` - if !matches!( - span.ctxt().outer_expn_data().kind, - ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) - ) { - return false; - } - if snippet.starts_with('&') { - // This is already a literal borrow and the obligation is failing - // somewhere else in the obligation chain. Do not suggest non-sense. - return false; - } - // We have a very specific type of error, where just borrowing this argument - // might solve the problem. In cases like this, the important part is the - // original type obligation, not the last one that failed, which is arbitrary. - // Because of this, we modify the error to refer to the original obligation and - // return early in the caller. - - let msg = format!( - "the trait bound `{}` is not satisfied", - self.tcx.short_string(old_pred, err.long_ty_path()), - ); - let self_ty_str = - self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); - if has_custom_message { - err.note(msg); - } else { - err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; - } - err.span_label( - span, - format!( - "the trait `{}` is not implemented for `{self_ty_str}`", - old_pred.print_modifiers_and_trait_path() - ), - ); + let is_immut = imm_ref_self_ty_satisfies_pred + || (ref_inner_ty_satisfies_pred && !ref_inner_ty_is_mut); + let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_is_mut; + if !is_immut && !is_mut { + return false; + } + let Ok(_snippet) = self.tcx.sess.source_map().span_to_snippet(span) else { + return false; + }; + // We don't want a borrowing suggestion on the fields in structs + // ``` + // #[derive(Clone)] + // struct Foo { + // the_foos: Vec<Foo> + // } + // ``` + if !matches!( + span.ctxt().outer_expn_data().kind, + ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) + ) { + return false; + } + // We have a very specific type of error, where just borrowing this argument + // might solve the problem. In cases like this, the important part is the + // original type obligation, not the last one that failed, which is arbitrary. + // Because of this, we modify the error to refer to the original obligation and + // return early in the caller. - if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred { - err.span_suggestions( - span.shrink_to_lo(), - "consider borrowing here", - ["&".to_string(), "&mut ".to_string()], - Applicability::MaybeIncorrect, - ); - } else { - let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut; - let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" }); - let sugg_msg = format!( - "consider{} borrowing here", - if is_mut { " mutably" } else { "" } - ); + let mut label = || { + let msg = format!( + "the trait bound `{}` is not satisfied", + self.tcx.short_string(old_pred, err.long_ty_path()), + ); + let self_ty_str = + self.tcx.short_string(old_pred.self_ty().skip_binder(), err.long_ty_path()); + if has_custom_message { + err.note(msg); + } else { + err.messages = vec![(rustc_errors::DiagMessage::from(msg), Style::NoStyle)]; + } + err.span_label( + span, + format!( + "the trait `{}` is not implemented for `{self_ty_str}`", + old_pred.print_modifiers_and_trait_path() + ), + ); + }; - // Issue #109436, we need to add parentheses properly for method calls - // for example, `foo.into()` should be `(&foo).into()` - if let Some(_) = - self.tcx.sess.source_map().span_look_ahead(span, ".", Some(50)) - { - err.multipart_suggestion_verbose( - sugg_msg, - vec![ - (span.shrink_to_lo(), format!("({sugg_prefix}")), - (span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MaybeIncorrect, - ); - return true; - } + let mut sugg_prefixes = vec![]; + if is_immut { + sugg_prefixes.push("&"); + } + if is_mut { + sugg_prefixes.push("&mut "); + } + let sugg_msg = format!( + "consider{} borrowing here", + if is_mut && !is_immut { " mutably" } else { "" }, + ); - // Issue #104961, we need to add parentheses properly for compound expressions - // for example, `x.starts_with("hi".to_string() + "you")` - // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) - else { - return false; - }; - let mut expr_finder = FindExprBySpan::new(span, self.tcx); - expr_finder.visit_expr(body.value); - let Some(expr) = expr_finder.result else { - return false; - }; - let needs_parens = expr_needs_parens(expr); + // Issue #104961, we need to add parentheses properly for compound expressions + // for example, `x.starts_with("hi".to_string() + "you")` + // should be `x.starts_with(&("hi".to_string() + "you"))` + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { + return false; + }; + let mut expr_finder = FindExprBySpan::new(span, self.tcx); + expr_finder.visit_expr(body.value); - let span = if needs_parens { span } else { span.shrink_to_lo() }; - let suggestions = if !needs_parens { - vec![(span.shrink_to_lo(), sugg_prefix)] - } else { + if let Some(ty) = expr_finder.ty_result { + if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(ty.hir_id) + && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, _)) = expr.kind + && ty.span == span + { + // We've encountered something like `str::from("")`, where the intended code + // was likely `<&str>::from("")`. #143393. + label(); + err.multipart_suggestions( + sugg_msg, + sugg_prefixes.into_iter().map(|sugg_prefix| { vec![ - (span.shrink_to_lo(), format!("{sugg_prefix}(")), - (span.shrink_to_hi(), ")".to_string()), + (span.shrink_to_lo(), format!("<{sugg_prefix}")), + (span.shrink_to_hi(), ">".to_string()), ] - }; - err.multipart_suggestion_verbose( - sugg_msg, - suggestions, - Applicability::MaybeIncorrect, - ); - } + }), + Applicability::MaybeIncorrect, + ); return true; } + return false; } - return false; + let Some(expr) = expr_finder.result else { + return false; + }; + if let hir::ExprKind::AddrOf(_, _, _) = expr.kind { + return false; + } + let needs_parens_post = expr_needs_parens(expr); + let needs_parens_pre = match self.tcx.parent_hir_node(expr.hir_id) { + Node::Expr(e) + if let hir::ExprKind::MethodCall(_, base, _, _) = e.kind + && base.hir_id == expr.hir_id => + { + true + } + _ => false, + }; + + label(); + let suggestions = sugg_prefixes.into_iter().map(|sugg_prefix| { + match (needs_parens_pre, needs_parens_post) { + (false, false) => vec![(span.shrink_to_lo(), sugg_prefix.to_string())], + // We have something like `foo.bar()`, where we want to bororw foo, so we need + // to suggest `(&mut foo).bar()`. + (false, true) => vec![ + (span.shrink_to_lo(), format!("{sugg_prefix}(")), + (span.shrink_to_hi(), ")".to_string()), + ], + // Issue #109436, we need to add parentheses properly for method calls + // for example, `foo.into()` should be `(&foo).into()` + (true, false) => vec![ + (span.shrink_to_lo(), format!("({sugg_prefix}")), + (span.shrink_to_hi(), ")".to_string()), + ], + (true, true) => vec![ + (span.shrink_to_lo(), format!("({sugg_prefix}(")), + (span.shrink_to_hi(), "))".to_string()), + ], + } + }); + err.multipart_suggestions(sugg_msg, suggestions, Applicability::MaybeIncorrect); + return true; }; if let ObligationCauseCode::ImplDerived(cause) = &*code { diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index 6d6bc157771..825b9e94158 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -2,25 +2,37 @@ error[E0277]: the size for values of type `Opaque` cannot be known --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; - | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` | | | required by a bound introduced by this call | - = help: the trait `MetaSized` is not implemented for `Opaque` + = note: the trait bound `Opaque: MetaSized` is not satisfied note: required by a bound in `std::intrinsics::size_of_val` --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL +help: consider borrowing here + | +LL | const _SIZE: usize = unsafe { size_of_val(&(&4 as *const i32 as *const Opaque)) }; + | ++ + +LL | const _SIZE: usize = unsafe { size_of_val(&mut (&4 as *const i32 as *const Opaque)) }; + | ++++++ + error[E0277]: the size for values of type `Opaque` cannot be known --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45 | LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; - | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` | | | required by a bound introduced by this call | - = help: the trait `MetaSized` is not implemented for `Opaque` + = note: the trait bound `Opaque: MetaSized` is not satisfied note: required by a bound in `std::intrinsics::align_of_val` --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL +help: consider borrowing here + | +LL | const _ALIGN: usize = unsafe { align_of_val(&(&4 as *const i32 as *const Opaque)) }; + | ++ + +LL | const _ALIGN: usize = unsafe { align_of_val(&mut (&4 as *const i32 as *const Opaque)) }; + | ++++++ + error: aborting due to 2 previous errors diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index befff880280..707a63ba28d 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -2,8 +2,10 @@ error[E0277]: the trait bound `B<C>: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:31:26 | LL | is_copy(B { a: 1, b: C }); - | ------- ^ the trait `Copy` is not implemented for `B<C>` - | | + | ------- ^ + | | | + | | the trait `Copy` is not implemented for `B<C>` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | note: required for `B<C>` to implement `Copy` @@ -16,17 +18,15 @@ note: required by a bound in `is_copy` | LL | fn is_copy<T: Copy>(_: T) {} | ^^^^ required by this bound in `is_copy` -help: consider borrowing here - | -LL | is_copy(B { a: 1, b: &C }); - | + error[E0277]: the trait bound `B<C>: Clone` is not satisfied --> $DIR/deriving-copyclone.rs:32:27 | LL | is_clone(B { a: 1, b: C }); - | -------- ^ the trait `Clone` is not implemented for `B<C>` - | | + | -------- ^ + | | | + | | the trait `Clone` is not implemented for `B<C>` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | note: required for `B<C>` to implement `Clone` @@ -39,17 +39,15 @@ note: required by a bound in `is_clone` | LL | fn is_clone<T: Clone>(_: T) {} | ^^^^^ required by this bound in `is_clone` -help: consider borrowing here - | -LL | is_clone(B { a: 1, b: &C }); - | + error[E0277]: the trait bound `B<D>: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:35:26 | LL | is_copy(B { a: 1, b: D }); - | ------- ^ the trait `Copy` is not implemented for `B<D>` - | | + | ------- ^ + | | | + | | the trait `Copy` is not implemented for `B<D>` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | note: required for `B<D>` to implement `Copy` @@ -62,10 +60,6 @@ note: required by a bound in `is_copy` | LL | fn is_copy<T: Copy>(_: T) {} | ^^^^ required by this bound in `is_copy` -help: consider borrowing here - | -LL | is_copy(B { a: 1, b: &D }); - | + error: aborting due to 3 previous errors diff --git a/tests/ui/extern/unsized-extern-derefmove.stderr b/tests/ui/extern/unsized-extern-derefmove.stderr index d6be76a9d62..a9efc2e66e3 100644 --- a/tests/ui/extern/unsized-extern-derefmove.stderr +++ b/tests/ui/extern/unsized-extern-derefmove.stderr @@ -21,10 +21,10 @@ note: required by a bound in `Box::<T>::from_raw` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL help: consider borrowing here | -LL | Box::from_raw(&0 as *mut _) - | + -LL | Box::from_raw(&mut 0 as *mut _) - | ++++ +LL | Box::from_raw(&(0 as *mut _)) + | ++ + +LL | Box::from_raw(&mut (0 as *mut _)) + | ++++++ + error[E0277]: the size for values of type `Device` cannot be known --> $DIR/unsized-extern-derefmove.rs:11:5 diff --git a/tests/ui/for/issue-20605.current.stderr b/tests/ui/for/issue-20605.current.stderr index 1a66cb41464..289dca289ae 100644 --- a/tests/ui/for/issue-20605.current.stderr +++ b/tests/ui/for/issue-20605.current.stderr @@ -2,14 +2,13 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator --> $DIR/issue-20605.rs:6:17 | LL | for item in *things { *item = 0 } - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>` + | -^^^^^^ + | | + | the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>` + | help: consider mutably borrowing here: `&mut` | = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied = note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator` -help: consider mutably borrowing here - | -LL | for item in &mut *things { *item = 0 } - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 1a66cb41464..289dca289ae 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -2,14 +2,13 @@ error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator --> $DIR/issue-20605.rs:6:17 | LL | for item in *things { *item = 0 } - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>` + | -^^^^^^ + | | + | the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>` + | help: consider mutably borrowing here: `&mut` | = note: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied = note: required for `dyn Iterator<Item = &'a mut u8>` to implement `IntoIterator` -help: consider mutably borrowing here - | -LL | for item in &mut *things { *item = 0 } - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr index 2da3925341e..7a3d8b43c2e 100644 --- a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr +++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr @@ -30,10 +30,10 @@ LL | fn a(self: impl Receiver<Target=Self>) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::a` help: consider borrowing here | -LL | &foo.a(); - | + -LL | &mut foo.a(); - | ++++ +LL | (&foo).a(); + | ++ + +LL | (&mut foo).a(); + | +++++ + error[E0277]: the trait bound `Foo: Deref` is not satisfied --> $DIR/arbitrary_self_types_generic_over_receiver.rs:21:9 @@ -48,10 +48,10 @@ LL | fn b(self: impl Deref<Target=Self>) -> u32 { | ^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::b` help: consider borrowing here | -LL | &foo.b(); - | + -LL | &mut foo.b(); - | ++++ +LL | (&foo).b(); + | ++ + +LL | (&mut foo).b(); + | +++++ + error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/imm-ref-trait-object-literal.stderr b/tests/ui/suggestions/imm-ref-trait-object-literal.stderr index 4b770d572c5..62f1c03e9aa 100644 --- a/tests/ui/suggestions/imm-ref-trait-object-literal.stderr +++ b/tests/ui/suggestions/imm-ref-trait-object-literal.stderr @@ -21,8 +21,10 @@ error[E0277]: the trait bound `S: Trait` is not satisfied --> $DIR/imm-ref-trait-object-literal.rs:13:7 | LL | foo(s); - | --- ^ the trait `Trait` is not implemented for `S` - | | + | --- ^ + | | | + | | the trait `Trait` is not implemented for `S` + | | help: consider mutably borrowing here: `&mut` | required by a bound introduced by this call | note: required by a bound in `foo` @@ -30,10 +32,6 @@ note: required by a bound in `foo` | LL | fn foo<X: Trait>(_: X) {} | ^^^^^ required by this bound in `foo` -help: consider mutably borrowing here - | -LL | foo(&mut s); - | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-104961.stderr b/tests/ui/suggestions/issue-104961.stderr index 0d229e6dada..6f02c125cad 100644 --- a/tests/ui/suggestions/issue-104961.stderr +++ b/tests/ui/suggestions/issue-104961.stderr @@ -18,17 +18,15 @@ error[E0277]: the trait bound `String: Pattern` is not satisfied --> $DIR/issue-104961.rs:9:19 | LL | x.starts_with("hi".to_string()) - | ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern` is not implemented for `String` - | | + | ----------- -^^^^^^^^^^^^^^^ + | | | + | | the trait `Pattern` is not implemented for `String` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | = note: required for `String` to implement `Pattern` note: required by a bound in `core::str::<impl str>::starts_with` --> $SRC_DIR/core/src/str/mod.rs:LL:COL -help: consider borrowing here - | -LL | x.starts_with(&"hi".to_string()) - | + error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-62843.stderr b/tests/ui/suggestions/issue-62843.stderr index c3c0360b3a9..c3480a8e396 100644 --- a/tests/ui/suggestions/issue-62843.stderr +++ b/tests/ui/suggestions/issue-62843.stderr @@ -2,17 +2,15 @@ error[E0277]: the trait bound `String: Pattern` is not satisfied --> $DIR/issue-62843.rs:4:32 | LL | println!("{:?}", line.find(pattern)); - | ---- ^^^^^^^ the trait `Pattern` is not implemented for `String` - | | + | ---- -^^^^^^ + | | | + | | the trait `Pattern` is not implemented for `String` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | = note: required for `String` to implement `Pattern` note: required by a bound in `core::str::<impl str>::find` --> $SRC_DIR/core/src/str/mod.rs:LL:COL -help: consider borrowing here - | -LL | println!("{:?}", line.find(&pattern)); - | + error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-84973-2.stderr b/tests/ui/suggestions/issue-84973-2.stderr index 74995a0500a..914307008ef 100644 --- a/tests/ui/suggestions/issue-84973-2.stderr +++ b/tests/ui/suggestions/issue-84973-2.stderr @@ -2,8 +2,10 @@ error[E0277]: the trait bound `i32: Tr` is not satisfied --> $DIR/issue-84973-2.rs:11:9 | LL | foo(a); - | --- ^ the trait `Tr` is not implemented for `i32` - | | + | --- ^ + | | | + | | the trait `Tr` is not implemented for `i32` + | | help: consider mutably borrowing here: `&mut` | required by a bound introduced by this call | note: required by a bound in `foo` @@ -11,10 +13,6 @@ note: required by a bound in `foo` | LL | fn foo<T: Tr>(i: T) {} | ^^ required by this bound in `foo` -help: consider mutably borrowing here - | -LL | foo(&mut a); - | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-84973-negative.stderr b/tests/ui/suggestions/issue-84973-negative.stderr index ce838bce09e..e3e6296890f 100644 --- a/tests/ui/suggestions/issue-84973-negative.stderr +++ b/tests/ui/suggestions/issue-84973-negative.stderr @@ -17,8 +17,10 @@ error[E0277]: the trait bound `f32: Tr` is not satisfied --> $DIR/issue-84973-negative.rs:11:9 | LL | bar(b); - | --- ^ the trait `Tr` is not implemented for `f32` - | | + | --- ^ + | | | + | | the trait `Tr` is not implemented for `f32` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | note: required by a bound in `bar` @@ -26,10 +28,6 @@ note: required by a bound in `bar` | LL | fn bar<T: Tr>(t: T) {} | ^^ required by this bound in `bar` -help: consider borrowing here - | -LL | bar(&b); - | + error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-84973.stderr b/tests/ui/suggestions/issue-84973.stderr index c5e1958e030..5ca91c544db 100644 --- a/tests/ui/suggestions/issue-84973.stderr +++ b/tests/ui/suggestions/issue-84973.stderr @@ -2,8 +2,10 @@ error[E0277]: the trait bound `Fancy: SomeTrait` is not satisfied --> $DIR/issue-84973.rs:6:24 | LL | let o = Other::new(f); - | ---------- ^ the trait `SomeTrait` is not implemented for `Fancy` - | | + | ---------- ^ + | | | + | | the trait `SomeTrait` is not implemented for `Fancy` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | note: required by a bound in `Other::<'a, G>::new` @@ -14,10 +16,6 @@ LL | G: SomeTrait, LL | { LL | pub fn new(g: G) -> Self { | --- required by a bound in this associated function -help: consider borrowing here - | -LL | let o = Other::new(&f); - | + error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr b/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr index 485015a98f2..146d6705243 100644 --- a/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr +++ b/tests/ui/suggestions/suggest-adding-reference-to-trait-assoc-item.stderr @@ -2,23 +2,19 @@ error[E0277]: the trait bound `&mut usize: Default` is not satisfied --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:13:9 | LL | foo(Default::default()); - | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&mut usize` - | -help: consider mutably borrowing here - | -LL | foo(&mut Default::default()); - | ++++ + | -^^^^^^^^^^^^^^^^^ + | | + | the trait `Default` is not implemented for `&mut usize` + | help: consider mutably borrowing here: `&mut` error[E0277]: the trait bound `&usize: Default` is not satisfied --> $DIR/suggest-adding-reference-to-trait-assoc-item.rs:14:9 | LL | bar(Default::default()); - | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&usize` - | -help: consider borrowing here - | -LL | bar(&Default::default()); - | + + | -^^^^^^^^^^^^^^^^^ + | | + | the trait `Default` is not implemented for `&usize` + | help: consider borrowing here: `&` error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/suggest-imm-mut-trait-implementations.stderr b/tests/ui/suggestions/suggest-imm-mut-trait-implementations.stderr index f2eb651eaa4..b3a0c68450e 100644 --- a/tests/ui/suggestions/suggest-imm-mut-trait-implementations.stderr +++ b/tests/ui/suggestions/suggest-imm-mut-trait-implementations.stderr @@ -22,8 +22,10 @@ error[E0277]: the trait bound `B: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:21:9 | LL | foo(b); - | --- ^ the trait `Trait` is not implemented for `B` - | | + | --- ^ + | | | + | | the trait `Trait` is not implemented for `B` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | note: required by a bound in `foo` @@ -31,17 +33,15 @@ note: required by a bound in `foo` | LL | fn foo<X: Trait>(_: X) {} | ^^^^^ required by this bound in `foo` -help: consider borrowing here - | -LL | foo(&b); - | + error[E0277]: the trait bound `C: Trait` is not satisfied --> $DIR/suggest-imm-mut-trait-implementations.rs:22:9 | LL | foo(c); - | --- ^ the trait `Trait` is not implemented for `C` - | | + | --- ^ + | | | + | | the trait `Trait` is not implemented for `C` + | | help: consider mutably borrowing here: `&mut` | required by a bound introduced by this call | note: required by a bound in `foo` @@ -49,10 +49,6 @@ note: required by a bound in `foo` | LL | fn foo<X: Trait>(_: X) {} | ^^^^^ required by this bound in `foo` -help: consider mutably borrowing here - | -LL | foo(&mut c); - | ++++ error: aborting due to 3 previous errors diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr index 8f5b937e586..cc5ca471788 100644 --- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -61,8 +61,10 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:48:13 | LL | is_send(Box::new(TestType)); - | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique<dummy2::TestType>` - | | + | ------- -^^^^^^^^^^^^^^^^^ + | | | + | | the trait `Send` is not implemented for `Unique<dummy2::TestType>` + | | help: consider borrowing here: `&` | required by a bound introduced by this call | = note: the trait bound `Unique<dummy2::TestType>: Send` is not satisfied @@ -74,10 +76,6 @@ note: required by a bound in `is_send` | LL | fn is_send<T: Send>(_: T) {} | ^^^^ required by this bound in `is_send` -help: consider borrowing here - | -LL | is_send(&Box::new(TestType)); - | + error[E0277]: `dummy3::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:56:13 |
