mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Extend rustc_on_implemented to improve a ?-on-ControlFlow error message
This commit is contained in:
parent
3bcaeb0bf9
commit
8be67998a1
@ -186,6 +186,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
let name = param.name;
|
let name = param.name;
|
||||||
flags.push((name, Some(value)));
|
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()) {
|
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}`",
|
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
|
||||||
enclosing_scope = "this function returns a `Result`"
|
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(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
from_method = "from_residual",
|
||||||
@ -272,13 +284,26 @@ pub trait Try: FromResidual {
|
|||||||
from_method = "from_residual",
|
from_method = "from_residual",
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::ops::ControlFlow<B, C>",
|
_Self = "std::ops::ControlFlow<B, C>",
|
||||||
|
R = "std::ops::ControlFlow<B, C>",
|
||||||
),
|
),
|
||||||
message = "the `?` operator can only be used on `ControlFlow<B, _>`s \
|
message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
|
||||||
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}`",
|
label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
|
||||||
enclosing_scope = "this function returns a `ControlFlow`",
|
enclosing_scope = "this function returns a `ControlFlow`",
|
||||||
note = "unlike `Result`, there's no `From`-conversion performed for `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(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
from_method = "from_residual",
|
||||||
|
@ -20,7 +20,7 @@ fn control_flow_to_result() -> Result<u64, String> {
|
|||||||
|
|
||||||
fn result_to_option() -> Option<u16> {
|
fn result_to_option() -> Option<u16> {
|
||||||
Some(Err("hello")?)
|
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> {
|
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> {
|
fn result_to_control_flow() -> ControlFlow<String> {
|
||||||
ControlFlow::Continue(Err("hello")?)
|
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> {
|
fn option_to_control_flow() -> ControlFlow<u64> {
|
||||||
Some(3)?;
|
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)
|
ControlFlow::Break(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn control_flow_to_control_flow() -> ControlFlow<i64> {
|
fn control_flow_to_control_flow() -> ControlFlow<i64> {
|
||||||
ControlFlow::Break(4_u8)?;
|
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(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +40,12 @@ LL | | }
|
|||||||
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
|
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
|
||||||
= note: required by `from_residual`
|
= 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
|
--> $DIR/bad-interconversion.rs:22:22
|
||||||
|
|
|
|
||||||
LL | / fn result_to_option() -> Option<u16> {
|
LL | / fn result_to_option() -> Option<u16> {
|
||||||
LL | | Some(Err("hello")?)
|
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 | |
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_- this function returns an `Option`
|
| |_- this function returns an `Option`
|
||||||
@ -66,7 +66,7 @@ LL | | }
|
|||||||
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
|
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
|
||||||
= note: required by `from_residual`
|
= 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
|
--> $DIR/bad-interconversion.rs:32:39
|
||||||
|
|
|
|
||||||
LL | / fn result_to_control_flow() -> ControlFlow<String> {
|
LL | / fn result_to_control_flow() -> ControlFlow<String> {
|
||||||
@ -77,10 +77,9 @@ LL | | }
|
|||||||
| |_- this function returns a `ControlFlow`
|
| |_- this function returns a `ControlFlow`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
|
= 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`
|
= 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
|
--> $DIR/bad-interconversion.rs:37:12
|
||||||
|
|
|
|
||||||
LL | / fn option_to_control_flow() -> ControlFlow<u64> {
|
LL | / fn option_to_control_flow() -> ControlFlow<u64> {
|
||||||
@ -92,10 +91,9 @@ LL | | }
|
|||||||
| |_- this function returns a `ControlFlow`
|
| |_- this function returns a `ControlFlow`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
|
= 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`
|
= 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
|
--> $DIR/bad-interconversion.rs:43:29
|
||||||
|
|
|
|
||||||
LL | / fn control_flow_to_control_flow() -> ControlFlow<i64> {
|
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<(), ()>`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
|
||||||
= note: required by `from_residual`
|
= 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
|
--> $DIR/option-to-result.rs:11:6
|
||||||
|
|
|
|
||||||
LL | / fn test_option() -> Option<i32>{
|
LL | / fn test_option() -> Option<i32>{
|
||||||
LL | | let a:Result<i32, i32> = Ok(5);
|
LL | | let a:Result<i32, i32> = Ok(5);
|
||||||
LL | | a?;
|
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 | | Some(5)
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_- this function returns an `Option`
|
| |_- this function returns an `Option`
|
||||||
|
Loading…
Reference in New Issue
Block a user