From 6eb48824dac44b466ca03fe67760a63d8a45d1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2025 17:34:16 +0000 Subject: [PATCH] Don't mention `FromResidual` on bad `?` Unless `try_trait_v2` is enabled, don't mention that `FromResidual` isn't implemented for a specific type when the implicit `From` conversion of a `?` fails. For the end user on stable, `?` might as well be a compiler intrinsic, so we remove that note to avoid further confusion and allowing other parts of the error to be more prominent. ``` error[E0277]: `?` couldn't convert the error to `u8` --> $DIR/bad-interconversion.rs:4:20 | LL | fn result_to_result() -> Result { | --------------- expected `u8` because of this LL | Ok(Err(123_i32)?) | ------------^ the trait `From` is not implemented for `u8` | | | this can't be annotated with `?` because it has type `Result<_, i32>` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the following other types implement trait `From`: `u8` implements `From` `u8` implements `From` ``` --- .../src/error_reporting/traits/suggestions.rs | 8 ++++++++ tests/ui/traits/question-mark-result-err-mismatch.rs | 1 + tests/ui/traits/question-mark-result-err-mismatch.stderr | 6 +++--- tests/ui/try-block/try-block-bad-type.stderr | 1 - tests/ui/try-trait/bad-interconversion.stderr | 1 - tests/ui/try-trait/issue-32709.stderr | 1 - 6 files changed, 12 insertions(+), 6 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 527d2e54e4327..94d652a0e98f7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3293,6 +3293,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut parent_trait_pred = self.resolve_vars_if_possible(data.derived.parent_trait_pred); let parent_def_id = parent_trait_pred.def_id(); + if tcx.is_diagnostic_item(sym::FromResidual, parent_def_id) + && !tcx.features().enabled(sym::try_trait_v2) + { + // If `#![feature(try_trait_v2)]` is not enabled, then there's no point on + // talking about `FromResidual>`, as the end user has nothing they + // can do about it. As far as they are concerned, `?` is compiler magic. + return; + } let self_ty_str = tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path()); let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string(); diff --git a/tests/ui/traits/question-mark-result-err-mismatch.rs b/tests/ui/traits/question-mark-result-err-mismatch.rs index 0ca18b5b0ddce..df1d5105a34a1 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.rs +++ b/tests/ui/traits/question-mark-result-err-mismatch.rs @@ -1,3 +1,4 @@ +#![feature(try_trait_v2)] fn foo() -> Result { //~ NOTE expected `String` because of this let test = String::from("one,two"); let x = test diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr index bad325a672042..0f83c9e73a314 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.stderr +++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr @@ -1,5 +1,5 @@ error[E0277]: `?` couldn't convert the error to `String` - --> $DIR/question-mark-result-err-mismatch.rs:14:22 + --> $DIR/question-mark-result-err-mismatch.rs:15:22 | LL | fn foo() -> Result { | ---------------------- expected `String` because of this @@ -17,7 +17,7 @@ LL | .map(|()| "")?; = note: required for `Result` to implement `FromResidual>` error[E0277]: `?` couldn't convert the error to `String` - --> $DIR/question-mark-result-err-mismatch.rs:28:25 + --> $DIR/question-mark-result-err-mismatch.rs:29:25 | LL | fn bar() -> Result<(), String> { | ------------------ expected `String` because of this @@ -40,7 +40,7 @@ LL | .map_err(|_| ())?; = note: required for `Result<(), String>` to implement `FromResidual>` error[E0277]: `?` couldn't convert the error to `String` - --> $DIR/question-mark-result-err-mismatch.rs:48:11 + --> $DIR/question-mark-result-err-mismatch.rs:49:11 | LL | fn baz() -> Result { | ---------------------- expected `String` because of this diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index c67ad762a83b9..818ab499306f0 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -10,7 +10,6 @@ LL | Err("")?; = help: the trait `From<&str>` is not implemented for `TryFromSliceError` but trait `From` is implemented for it = help: for that trait implementation, expected `Infallible`, found `&str` - = note: required for `Result` to implement `FromResidual>` error[E0271]: type mismatch resolving ` as Try>::Output == &str` --> $DIR/try-block-bad-type.rs:12:9 diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index bb5e5646ad294..45422be946e82 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -12,7 +12,6 @@ LL | Ok(Err(123_i32)?) = help: the following other types implement trait `From`: `u8` implements `From` `u8` implements `From` - = note: required for `Result` to implement `FromResidual>` error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` --> $DIR/bad-interconversion.rs:9:12 diff --git a/tests/ui/try-trait/issue-32709.stderr b/tests/ui/try-trait/issue-32709.stderr index 475bd1ff3ac57..20454e12de558 100644 --- a/tests/ui/try-trait/issue-32709.stderr +++ b/tests/ui/try-trait/issue-32709.stderr @@ -19,7 +19,6 @@ LL | Err(5)?; `(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>` `(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>` and 4 others - = note: required for `Result` to implement `FromResidual>` error: aborting due to 1 previous error