Rollup merge of #137232 - estebank:from-residual-note, r=petrochenkov
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<u64, u8> { | --------------- expected `u8` because of this LL | Ok(Err(123_i32)?) | ------------^ the trait `From<i32>` 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<T>`: `u8` implements `From<Char>` `u8` implements `From<bool>` ```
This commit is contained in:
commit
dd60b6ca27
6 changed files with 12 additions and 6 deletions
|
@ -3289,6 +3289,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
let mut parent_trait_pred =
|
let mut parent_trait_pred =
|
||||||
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
||||||
let parent_def_id = parent_trait_pred.def_id();
|
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<Result<A, B>>`, 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 =
|
let self_ty_str =
|
||||||
tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
|
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();
|
let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![feature(try_trait_v2)]
|
||||||
fn foo() -> Result<String, String> { //~ NOTE expected `String` because of this
|
fn foo() -> Result<String, String> { //~ NOTE expected `String` because of this
|
||||||
let test = String::from("one,two");
|
let test = String::from("one,two");
|
||||||
let x = test
|
let x = test
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0277]: `?` couldn't convert the error to `String`
|
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<String, String> {
|
LL | fn foo() -> Result<String, String> {
|
||||||
| ---------------------- expected `String` because of this
|
| ---------------------- expected `String` because of this
|
||||||
|
@ -17,7 +17,7 @@ LL | .map(|()| "")?;
|
||||||
= note: required for `Result<String, String>` to implement `FromResidual<Result<Infallible, ()>>`
|
= note: required for `Result<String, String>` to implement `FromResidual<Result<Infallible, ()>>`
|
||||||
|
|
||||||
error[E0277]: `?` couldn't convert the error to `String`
|
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> {
|
LL | fn bar() -> Result<(), String> {
|
||||||
| ------------------ expected `String` because of this
|
| ------------------ expected `String` because of this
|
||||||
|
@ -40,7 +40,7 @@ LL | .map_err(|_| ())?;
|
||||||
= note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
|
= note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
|
||||||
|
|
||||||
error[E0277]: `?` couldn't convert the error to `String`
|
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<String, String> {
|
LL | fn baz() -> Result<String, String> {
|
||||||
| ---------------------- expected `String` because of this
|
| ---------------------- expected `String` because of this
|
||||||
|
|
|
@ -10,7 +10,6 @@ LL | Err("")?;
|
||||||
= help: the trait `From<&str>` is not implemented for `TryFromSliceError`
|
= help: the trait `From<&str>` is not implemented for `TryFromSliceError`
|
||||||
but trait `From<Infallible>` is implemented for it
|
but trait `From<Infallible>` is implemented for it
|
||||||
= help: for that trait implementation, expected `Infallible`, found `&str`
|
= help: for that trait implementation, expected `Infallible`, found `&str`
|
||||||
= note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
|
|
||||||
|
|
||||||
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
|
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
|
||||||
--> $DIR/try-block-bad-type.rs:12:9
|
--> $DIR/try-block-bad-type.rs:12:9
|
||||||
|
|
|
@ -12,7 +12,6 @@ LL | Ok(Err(123_i32)?)
|
||||||
= help: the following other types implement trait `From<T>`:
|
= help: the following other types implement trait `From<T>`:
|
||||||
`u8` implements `From<Char>`
|
`u8` implements `From<Char>`
|
||||||
`u8` implements `From<bool>`
|
`u8` implements `From<bool>`
|
||||||
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
|
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
|
--> $DIR/bad-interconversion.rs:9:12
|
||||||
|
|
|
@ -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)` implements `From<[T; 8]>`
|
||||||
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
|
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
|
||||||
and 4 others
|
and 4 others
|
||||||
= note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue