diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 5746c28a2ab26..a128f8d31a134 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1165,7 +1165,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.push_suggestion(CodeSuggestion { substitutions, msg: self.subdiagnostic_message_to_diagnostic_message(msg), - style: SuggestionStyle::ShowCode, + style: SuggestionStyle::ShowAlways, applicability, }); self 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 3e64573aa0348..8c9eb41568f49 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 - // } - // ``` - 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 + // } + // ``` + 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 6d6bc157771a4..825b9e941584c 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/extern/unsized-extern-derefmove.stderr b/tests/ui/extern/unsized-extern-derefmove.stderr index d6be76a9d6261..a9efc2e66e3b0 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::::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/impl-trait/in-trait/default-body-type-err-2.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr index 856c92217b924..4c429624e0bfa 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr @@ -4,9 +4,12 @@ error[E0308]: mismatched types LL | async fn woopsie_async(&self) -> String { | ------ expected `String` because of return type LL | 42 - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer + | ^^ expected `String`, found integer + | +help: try using a conversion method + | +LL | 42.to_string() + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr index 8ccd28198afc4..027902a9f31e2 100644 --- a/tests/ui/inference/deref-suggestion.stderr +++ b/tests/ui/inference/deref-suggestion.stderr @@ -2,9 +2,8 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:8:9 | LL | foo(s); - | --- ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `&String` + | --- ^ expected `String`, found `&String` + | | | arguments to this function are incorrect | note: function defined here @@ -12,6 +11,10 @@ note: function defined here | LL | fn foo(_: String) {} | ^^^ --------- +help: try using a conversion method + | +LL | foo(s.to_string()); + | ++++++++++++ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:14:10 diff --git a/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr b/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr index ce2022374f7f4..9f31a731fed72 100644 --- a/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr +++ b/tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr @@ -38,9 +38,12 @@ error[E0308]: mismatched types --> $DIR/typo-in-repeat-expr-issue-80173.rs:32:29 | LL | let e = [String::new(), 10]; - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer + | ^^ expected `String`, found integer + | +help: try using a conversion method + | +LL | let e = [String::new(), 10.to_string()]; + | ++++++++++++ error[E0308]: mismatched types --> $DIR/typo-in-repeat-expr-issue-80173.rs:36:19 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 2da3925341e2f..7a3d8b43c2e3a 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) -> 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) -> 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/static/bad-const-type.stderr b/tests/ui/static/bad-const-type.stderr index 807cd2f7a25a7..8573a11ef2912 100644 --- a/tests/ui/static/bad-const-type.stderr +++ b/tests/ui/static/bad-const-type.stderr @@ -2,9 +2,12 @@ error[E0308]: mismatched types --> $DIR/bad-const-type.rs:1:20 | LL | static i: String = 10; - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer + | ^^ expected `String`, found integer + | +help: try using a conversion method + | +LL | static i: String = 10.to_string(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed index 95fd920dec229..00b92b42bb5cd 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.fixed @@ -4,14 +4,24 @@ struct S; trait Trait { fn foo() {} } -impl Trait for &S {} impl Trait for &mut S {} +trait Trait2 { + fn bar() {} +} +impl Trait2 for &S {} +impl Trait2 for &mut S {} fn main() { let _ = <&str>::from("value"); //~^ ERROR the trait bound `str: From<_>` is not satisfied //~| ERROR the size for values of type `str` cannot be known at compilation time let _ = <&mut S>::foo(); //~^ ERROR the trait bound `S: Trait` is not satisfied - let _ = <&S>::foo(); + let _ = <&mut S>::foo(); + //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = <&mut S>::foo(); //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = <&mut S>::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied + let _ = <&S>::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied } diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs index f79d2465062ac..3059ccdffb458 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.rs @@ -4,8 +4,12 @@ struct S; trait Trait { fn foo() {} } -impl Trait for &S {} impl Trait for &mut S {} +trait Trait2 { + fn bar() {} +} +impl Trait2 for &S {} +impl Trait2 for &mut S {} fn main() { let _ = &str::from("value"); //~^ ERROR the trait bound `str: From<_>` is not satisfied @@ -14,4 +18,10 @@ fn main() { //~^ ERROR the trait bound `S: Trait` is not satisfied let _ = &S::foo(); //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = S::foo(); + //~^ ERROR the trait bound `S: Trait` is not satisfied + let _ = &mut S::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied + let _ = &S::bar(); + //~^ ERROR the trait bound `S: Trait2` is not satisfied } diff --git a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr index ac96ec76da7b1..c2e2fe941a6b0 100644 --- a/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr +++ b/tests/ui/suggestions/dont-suggest-borrowing-existing-borrow.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `str: From<_>` is not satisfied - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:10:14 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:14:14 | LL | let _ = &str::from("value"); | ^^^ the trait `From<_>` is not implemented for `str` @@ -17,35 +17,71 @@ LL | let _ = <&str>::from("value"); | + + error[E0277]: the trait bound `S: Trait` is not satisfied - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:13:18 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:17:18 | LL | let _ = &mut S::foo(); | ^ the trait `Trait` is not implemented for `S` | - = help: the following other types implement trait `Trait`: - &S - &mut S + = help: the trait `Trait` is implemented for `&mut S` help: you likely meant to call the associated function `foo` for type `&mut S`, but the code as written calls associated function `foo` on type `S` | LL | let _ = <&mut S>::foo(); | + + error[E0277]: the trait bound `S: Trait` is not satisfied - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:15:14 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:19:14 | LL | let _ = &S::foo(); | ^ the trait `Trait` is not implemented for `S` | - = help: the following other types implement trait `Trait`: + = help: the trait `Trait` is implemented for `&mut S` +help: you likely meant to call the associated function `foo` for type `&S`, but the code as written calls associated function `foo` on type `S` + | +LL - let _ = &S::foo(); +LL + let _ = <&mut S>::foo(); + | + +error[E0277]: the trait bound `S: Trait` is not satisfied + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:21:13 + | +LL | let _ = S::foo(); + | ^ the trait `Trait` is not implemented for `S` + | +help: consider mutably borrowing here + | +LL | let _ = <&mut S>::foo(); + | +++++ + + +error[E0277]: the trait bound `S: Trait2` is not satisfied + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:23:18 + | +LL | let _ = &mut S::bar(); + | ^ the trait `Trait2` is not implemented for `S` + | + = help: the following other types implement trait `Trait2`: &S &mut S -help: you likely meant to call the associated function `foo` for type `&S`, but the code as written calls associated function `foo` on type `S` +help: you likely meant to call the associated function `bar` for type `&mut S`, but the code as written calls associated function `bar` on type `S` + | +LL | let _ = <&mut S>::bar(); + | + + + +error[E0277]: the trait bound `S: Trait2` is not satisfied + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:25:14 + | +LL | let _ = &S::bar(); + | ^ the trait `Trait2` is not implemented for `S` + | + = help: the following other types implement trait `Trait2`: + &S + &mut S +help: you likely meant to call the associated function `bar` for type `&S`, but the code as written calls associated function `bar` on type `S` | -LL | let _ = <&S>::foo(); +LL | let _ = <&S>::bar(); | + + error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/dont-suggest-borrowing-existing-borrow.rs:10:14 + --> $DIR/dont-suggest-borrowing-existing-borrow.rs:14:14 | LL | let _ = &str::from("value"); | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -53,6 +89,6 @@ LL | let _ = &str::from("value"); = help: the trait `Sized` is not implemented for `str` = note: the return type of a function must have a statically known size -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/issue-52820.stderr b/tests/ui/suggestions/issue-52820.stderr index a67d75014171f..de2c9542f6113 100644 --- a/tests/ui/suggestions/issue-52820.stderr +++ b/tests/ui/suggestions/issue-52820.stderr @@ -13,10 +13,13 @@ error[E0308]: mismatched types --> $DIR/issue-52820.rs:13:17 | LL | brains: guts.clone(), - | ^^^^^-----^^ - | | | - | | help: try using a conversion method: `to_string` - | expected `String`, found `&str` + | ^^^^^^^^^^^^ expected `String`, found `&str` + | +help: try using a conversion method + | +LL - brains: guts.clone(), +LL + brains: guts.to_string(), + | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-53692.stderr b/tests/ui/suggestions/issue-53692.stderr index 469a538411fb1..10ebb30a5b24a 100644 --- a/tests/ui/suggestions/issue-53692.stderr +++ b/tests/ui/suggestions/issue-53692.stderr @@ -2,24 +2,31 @@ error[E0308]: mismatched types --> $DIR/issue-53692.rs:7:33 | LL | let items_clone: Vec = ref_items.clone(); - | -------- ^^^^^^^^^^-----^^ - | | | | - | | | help: try using a conversion method: `to_vec` - | | expected `Vec`, found `&[i32]` + | -------- ^^^^^^^^^^^^^^^^^ expected `Vec`, found `&[i32]` + | | | expected due to this | = note: expected struct `Vec` found reference `&[i32]` +help: try using a conversion method + | +LL - let items_clone: Vec = ref_items.clone(); +LL + let items_clone: Vec = ref_items.to_vec(); + | error[E0308]: mismatched types --> $DIR/issue-53692.rs:14:26 | LL | let string: String = s.clone(); - | ------ ^^-----^^ - | | | | - | | | help: try using a conversion method: `to_string` - | | expected `String`, found `&str` + | ------ ^^^^^^^^^ expected `String`, found `&str` + | | | expected due to this + | +help: try using a conversion method + | +LL - let string: String = s.clone(); +LL + let string: String = s.to_string(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/issue-59819.stderr b/tests/ui/suggestions/issue-59819.stderr index 43acf9549c29a..ab91961192ff5 100644 --- a/tests/ui/suggestions/issue-59819.stderr +++ b/tests/ui/suggestions/issue-59819.stderr @@ -28,10 +28,14 @@ error[E0308]: mismatched types --> $DIR/issue-59819.rs:34:21 | LL | let g: String = f; - | ------ ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `Bar` + | ------ ^ expected `String`, found `Bar` + | | | expected due to this + | +help: try using a conversion method + | +LL | let g: String = f.to_string(); + | ++++++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/issue-83943.stderr b/tests/ui/suggestions/issue-83943.stderr index 1a085368485cf..e714a126f4a69 100644 --- a/tests/ui/suggestions/issue-83943.stderr +++ b/tests/ui/suggestions/issue-83943.stderr @@ -6,11 +6,14 @@ LL | | "A".to_string() | | --------------- expected because of this LL | | } else { LL | | "B" - | | ^^^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `&str` + | | ^^^ expected `String`, found `&str` LL | | }; | |_____- `if` and `else` have incompatible types + | +help: try using a conversion method + | +LL | "B".to_string() + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr index c721ceb11463f..ed94ebd27ffdf 100644 --- a/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr +++ b/tests/ui/suggestions/only-suggest-removal-of-conversion-method-calls.stderr @@ -5,9 +5,12 @@ LL | fn get_name() -> String { | ------ expected `String` because of return type ... LL | your_name.trim() - | ^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found `&str` + | ^^^^^^^^^^^^^^^^ expected `String`, found `&str` + | +help: try using a conversion method + | +LL | your_name.trim().to_string() + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/switched-expectations.stderr b/tests/ui/switched-expectations.stderr index cc57674740020..e235c2da1f736 100644 --- a/tests/ui/switched-expectations.stderr +++ b/tests/ui/switched-expectations.stderr @@ -2,9 +2,12 @@ error[E0308]: mismatched types --> $DIR/switched-expectations.rs:3:30 | LL | let ref string: String = var; - | ^^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found `i32` + | ^^^ expected `String`, found `i32` + | +help: try using a conversion method + | +LL | let ref string: String = var.to_string(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/conversion-methods.stderr b/tests/ui/typeck/conversion-methods.stderr index a9b5078ccdde3..fa8928f1454c0 100644 --- a/tests/ui/typeck/conversion-methods.stderr +++ b/tests/ui/typeck/conversion-methods.stderr @@ -2,28 +2,40 @@ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:5:41 | LL | let _tis_an_instants_play: String = "'Tis a fond Ambush—"; - | ------ ^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found `&str` + | ------ ^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `&str` + | | | expected due to this + | +help: try using a conversion method + | +LL | let _tis_an_instants_play: String = "'Tis a fond Ambush—".to_string(); + | ++++++++++++ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:6:40 | LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise"); - | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_path_buf()` - | | | - | | expected `PathBuf`, found `&Path` + | ------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `PathBuf`, found `&Path` + | | | expected due to this + | +help: try using a conversion method + | +LL | let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise").to_path_buf(); + | ++++++++++++++ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:9:40 | LL | let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here - | ------ ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found integer + | ------ ^ expected `String`, found integer + | | | expected due to this + | +help: try using a conversion method + | +LL | let _but_should_the_play: String = 2.to_string(); // Perhaps surprisingly, we suggest .to_string() here + | ++++++++++++ error[E0308]: mismatched types --> $DIR/conversion-methods.rs:12:47