Extend rustc_on_implemented to improve a ?-on-ControlFlow error message
This commit is contained in:
parent
3bcaeb0bf9
commit
8be67998a1
@ -186,6 +186,15 @@ fn on_unimplemented_note(
|
||||
};
|
||||
let name = param.name;
|
||||
flags.push((name, Some(value)));
|
||||
|
||||
if let GenericParamDefKind::Type { .. } = param.kind {
|
||||
let param_ty = trait_ref.substs[param.index as usize].expect_ty();
|
||||
if let Some(def) = param_ty.ty_adt_def() {
|
||||
// We also want to be able to select the parameter's
|
||||
// original signature with no type arguments resolved
|
||||
flags.push((name, Some(self.tcx.type_of(def.did).to_string())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) {
|
||||
|
@ -254,6 +254,18 @@ pub trait Try: FromResidual {
|
||||
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
|
||||
enclosing_scope = "this function returns a `Result`"
|
||||
),
|
||||
on(
|
||||
all(
|
||||
from_method = "from_residual",
|
||||
from_desugaring = "QuestionMark",
|
||||
_Self = "std::option::Option<T>",
|
||||
R = "std::result::Result<T, E>",
|
||||
),
|
||||
message = "the `?` operator can only be used on `Option`s, not `Result`s, \
|
||||
in {ItemContext} that returns `Option`",
|
||||
label = "use `.ok()?` if you want to discard the `{R}` error information",
|
||||
enclosing_scope = "this function returns an `Option`"
|
||||
),
|
||||
on(
|
||||
all(
|
||||
from_method = "from_residual",
|
||||
@ -272,13 +284,26 @@ pub trait Try: FromResidual {
|
||||
from_method = "from_residual",
|
||||
from_desugaring = "QuestionMark",
|
||||
_Self = "std::ops::ControlFlow<B, C>",
|
||||
R = "std::ops::ControlFlow<B, C>",
|
||||
),
|
||||
message = "the `?` operator can only be used on `ControlFlow<B, _>`s \
|
||||
in {ItemContext} that returns `ControlFlow<B, _>`",
|
||||
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
|
||||
can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
|
||||
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
|
||||
enclosing_scope = "this function returns a `ControlFlow`",
|
||||
note = "unlike `Result`, there's no `From`-conversion performed for `ControlFlow`"
|
||||
),
|
||||
on(
|
||||
all(
|
||||
from_method = "from_residual",
|
||||
from_desugaring = "QuestionMark",
|
||||
_Self = "std::ops::ControlFlow<B, C>",
|
||||
// `R` is not a `ControlFlow`, as that case was matched previously
|
||||
),
|
||||
message = "the `?` operator can only be used on `ControlFlow`s \
|
||||
in {ItemContext} that returns `ControlFlow`",
|
||||
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
|
||||
enclosing_scope = "this function returns a `ControlFlow`",
|
||||
),
|
||||
on(
|
||||
all(
|
||||
from_method = "from_residual",
|
||||
|
@ -20,7 +20,7 @@ fn control_flow_to_result() -> Result<u64, String> {
|
||||
|
||||
fn result_to_option() -> Option<u16> {
|
||||
Some(Err("hello")?)
|
||||
//~^ ERROR the `?` operator can only be used on `Option`s in a function that returns `Option`
|
||||
//~^ ERROR the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
|
||||
}
|
||||
|
||||
fn control_flow_to_option() -> Option<u64> {
|
||||
@ -30,18 +30,18 @@ fn control_flow_to_option() -> Option<u64> {
|
||||
|
||||
fn result_to_control_flow() -> ControlFlow<String> {
|
||||
ControlFlow::Continue(Err("hello")?)
|
||||
//~^ ERROR the `?` operator can only be used on `ControlFlow<B, _>`s in a function that returns `ControlFlow<B, _>`
|
||||
//~^ ERROR the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||
}
|
||||
|
||||
fn option_to_control_flow() -> ControlFlow<u64> {
|
||||
Some(3)?;
|
||||
//~^ ERROR the `?` operator can only be used on `ControlFlow<B, _>`s in a function that returns `ControlFlow<B, _>`
|
||||
//~^ ERROR the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||
ControlFlow::Break(10)
|
||||
}
|
||||
|
||||
fn control_flow_to_control_flow() -> ControlFlow<i64> {
|
||||
ControlFlow::Break(4_u8)?;
|
||||
//~^ ERROR the `?` operator can only be used on `ControlFlow<B, _>`s in a function that returns `ControlFlow<B, _>`
|
||||
//~^ ERROR the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,12 @@ LL | | }
|
||||
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
|
||||
= note: required by `from_residual`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
|
||||
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
|
||||
--> $DIR/bad-interconversion.rs:22:22
|
||||
|
|
||||
LL | / fn result_to_option() -> Option<u16> {
|
||||
LL | | Some(Err("hello")?)
|
||||
| | ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `Option<u16>`
|
||||
| | ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_- this function returns an `Option`
|
||||
@ -66,7 +66,7 @@ LL | | }
|
||||
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
|
||||
= note: required by `from_residual`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow<B, _>`s in a function that returns `ControlFlow<B, _>`
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||
--> $DIR/bad-interconversion.rs:32:39
|
||||
|
|
||||
LL | / fn result_to_control_flow() -> ControlFlow<String> {
|
||||
@ -77,10 +77,9 @@ LL | | }
|
||||
| |_- this function returns a `ControlFlow`
|
||||
|
|
||||
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
|
||||
= note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
|
||||
= note: required by `from_residual`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow<B, _>`s in a function that returns `ControlFlow<B, _>`
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||
--> $DIR/bad-interconversion.rs:37:12
|
||||
|
|
||||
LL | / fn option_to_control_flow() -> ControlFlow<u64> {
|
||||
@ -92,10 +91,9 @@ LL | | }
|
||||
| |_- this function returns a `ControlFlow`
|
||||
|
|
||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
|
||||
= note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
|
||||
= note: required by `from_residual`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow<B, _>`s in a function that returns `ControlFlow<B, _>`
|
||||
error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
|
||||
--> $DIR/bad-interconversion.rs:43:29
|
||||
|
|
||||
LL | / fn control_flow_to_control_flow() -> ControlFlow<i64> {
|
||||
|
@ -12,13 +12,13 @@ LL | | }
|
||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
|
||||
= note: required by `from_residual`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
|
||||
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
|
||||
--> $DIR/option-to-result.rs:11:6
|
||||
|
|
||||
LL | / fn test_option() -> Option<i32>{
|
||||
LL | | let a:Result<i32, i32> = Ok(5);
|
||||
LL | | a?;
|
||||
| | ^ this `?` produces `Result<Infallible, i32>`, which is incompatible with `Option<i32>`
|
||||
| | ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
|
||||
LL | | Some(5)
|
||||
LL | | }
|
||||
| |_- this function returns an `Option`
|
||||
|
Loading…
Reference in New Issue
Block a user