Tweak E0277 when predicate comes indirectly from ?
When a `?` operation requires an `Into` conversion with additional bounds (like having a concrete error but wanting to convert to a trait object), we handle it speficically and provide the same kind of information we give other `?` related errors. ``` error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied --> $DIR/bad-question-mark-on-trait-object.rs:5:13 | LL | fn foo() -> Result<(), Box<dyn std::error::Error>> { | -------------------------------------- required `E: std::error::Error` because of this LL | Ok(bar()?) | ^ the trait `std::error::Error` is not implemented for `E` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: required for `Box<dyn std::error::Error>` to implement `From<E>` ``` Avoid talking about `FromResidual` when other more relevant information is being given, particularly from `rust_on_unimplemented`.
This commit is contained in:
parent
28b83ee596
commit
e565eeed78
11 changed files with 103 additions and 65 deletions
|
@ -192,19 +192,38 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let have_alt_message = message.is_some() || label.is_some();
|
let have_alt_message = message.is_some() || label.is_some();
|
||||||
let is_try_conversion = self.is_try_conversion(span, main_trait_predicate.def_id());
|
let is_try_conversion = self.is_try_conversion(span, main_trait_predicate.def_id());
|
||||||
|
let is_question_mark = matches!(
|
||||||
|
root_obligation.cause.code().peel_derives(),
|
||||||
|
ObligationCauseCode::QuestionMark,
|
||||||
|
) && !(
|
||||||
|
self.tcx.is_diagnostic_item(sym::FromResidual, main_trait_predicate.def_id())
|
||||||
|
|| self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::Try)
|
||||||
|
);
|
||||||
let is_unsize =
|
let is_unsize =
|
||||||
self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Unsize);
|
self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Unsize);
|
||||||
|
let question_mark_message = "the question mark operation (`?`) implicitly \
|
||||||
|
performs a conversion on the error value \
|
||||||
|
using the `From` trait";
|
||||||
let (message, notes, append_const_msg) = if is_try_conversion {
|
let (message, notes, append_const_msg) = if is_try_conversion {
|
||||||
|
// We have a `-> Result<_, E1>` and `gives_E2()?`.
|
||||||
(
|
(
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"`?` couldn't convert the error to `{}`",
|
"`?` couldn't convert the error to `{}`",
|
||||||
main_trait_predicate.skip_binder().self_ty(),
|
main_trait_predicate.skip_binder().self_ty(),
|
||||||
)),
|
)),
|
||||||
vec![
|
vec![question_mark_message.to_owned()],
|
||||||
"the question mark operation (`?`) implicitly performs a \
|
Some(AppendConstMessage::Default),
|
||||||
conversion on the error value using the `From` trait"
|
)
|
||||||
.to_owned(),
|
} else if is_question_mark {
|
||||||
],
|
// Similar to the case above, but in this case the conversion is for a
|
||||||
|
// trait object: `-> Result<_, Box<dyn Error>` and `gives_E()?` when
|
||||||
|
// `E: Error` isn't met.
|
||||||
|
(
|
||||||
|
Some(format!(
|
||||||
|
"`?` couldn't convert the error: `{main_trait_predicate}` is \
|
||||||
|
not satisfied",
|
||||||
|
)),
|
||||||
|
vec![question_mark_message.to_owned()],
|
||||||
Some(AppendConstMessage::Default),
|
Some(AppendConstMessage::Default),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -220,8 +239,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
&mut long_ty_file,
|
&mut long_ty_file,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::TransmuteTrait)
|
let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(
|
||||||
{
|
main_trait_predicate.def_id(),
|
||||||
|
LangItem::TransmuteTrait,
|
||||||
|
) {
|
||||||
// Recompute the safe transmute reason and use that for the error reporting
|
// Recompute the safe transmute reason and use that for the error reporting
|
||||||
match self.get_safe_transmute_error_and_reason(
|
match self.get_safe_transmute_error_and_reason(
|
||||||
obligation.clone(),
|
obligation.clone(),
|
||||||
|
@ -249,18 +270,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
*err.long_ty_path() = long_ty_file;
|
*err.long_ty_path() = long_ty_file;
|
||||||
|
|
||||||
let mut suggested = false;
|
let mut suggested = false;
|
||||||
if is_try_conversion {
|
if is_try_conversion || is_question_mark {
|
||||||
suggested = self.try_conversion_context(&obligation, main_trait_predicate, &mut err);
|
suggested = self.try_conversion_context(&obligation, main_trait_predicate, &mut err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) {
|
if let Some(ret_span) = self.return_type_span(&obligation) {
|
||||||
err.span_label(
|
if is_try_conversion {
|
||||||
ret_span,
|
err.span_label(
|
||||||
format!(
|
ret_span,
|
||||||
"expected `{}` because of this",
|
format!(
|
||||||
main_trait_predicate.skip_binder().self_ty()
|
"expected `{}` because of this",
|
||||||
),
|
main_trait_predicate.skip_binder().self_ty()
|
||||||
);
|
),
|
||||||
|
);
|
||||||
|
} else if is_question_mark {
|
||||||
|
err.span_label(ret_span, format!("required `{main_trait_predicate}` because of this"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Tuple) {
|
if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Tuple) {
|
||||||
|
@ -302,10 +327,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
// If it has a custom `#[rustc_on_unimplemented]`
|
// If it has a custom `#[rustc_on_unimplemented]`
|
||||||
// error message, let's display it as the label!
|
// error message, let's display it as the label!
|
||||||
err.span_label(span, s);
|
err.span_label(span, s);
|
||||||
if !matches!(leaf_trait_predicate.skip_binder().self_ty().kind(), ty::Param(_)) {
|
if !matches!(leaf_trait_predicate.skip_binder().self_ty().kind(), ty::Param(_))
|
||||||
// When the self type is a type param We don't need to "the trait
|
// When the self type is a type param We don't need to "the trait
|
||||||
// `std::marker::Sized` is not implemented for `T`" as we will point
|
// `std::marker::Sized` is not implemented for `T`" as we will point
|
||||||
// at the type param with a label to suggest constraining it.
|
// at the type param with a label to suggest constraining it.
|
||||||
|
&& !self.tcx.is_diagnostic_item(sym::FromResidual, leaf_trait_predicate.def_id())
|
||||||
|
// Don't say "the trait `FromResidual<Option<Infallible>>` is
|
||||||
|
// not implemented for `Result<T, E>`".
|
||||||
|
{
|
||||||
err.help(explanation);
|
err.help(explanation);
|
||||||
}
|
}
|
||||||
} else if let Some(custom_explanation) = safe_transmute_explanation {
|
} else if let Some(custom_explanation) = safe_transmute_explanation {
|
||||||
|
@ -2035,6 +2064,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let &[cand] = &candidates[..] {
|
if let &[cand] = &candidates[..] {
|
||||||
|
if self.tcx.is_diagnostic_item(sym::FromResidual, cand.def_id)
|
||||||
|
&& !self.tcx.features().enabled(sym::try_trait_v2)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let (desc, mention_castable) =
|
let (desc, mention_castable) =
|
||||||
match (cand.self_ty().kind(), trait_pred.self_ty().skip_binder().kind()) {
|
match (cand.self_ty().kind(), trait_pred.self_ty().skip_binder().kind()) {
|
||||||
(ty::FnPtr(..), ty::FnDef(..)) => {
|
(ty::FnPtr(..), ty::FnDef(..)) => {
|
||||||
|
|
|
@ -17,8 +17,6 @@ LL | | test()?;
|
||||||
... |
|
... |
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_- this function should return `Result` or `Option` to accept `?`
|
| |_- this function should return `Result` or `Option` to accept `?`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<_>` is not implemented for `()`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@ LL | async {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ cannot use the `?` operator in an async block that returns `{integer}`
|
| ^ cannot use the `?` operator in an async block that returns `{integer}`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||||
--> $DIR/try-on-option-in-async.rs:16:10
|
--> $DIR/try-on-option-in-async.rs:16:10
|
||||||
|
@ -20,8 +18,6 @@ LL | | x?;
|
||||||
LL | | 22_u32
|
LL | | 22_u32
|
||||||
LL | | };
|
LL | | };
|
||||||
| |_____- this function should return `Result` or `Option` to accept `?`
|
| |_____- this function should return `Result` or `Option` to accept `?`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||||
--> $DIR/try-on-option-in-async.rs:25:6
|
--> $DIR/try-on-option-in-async.rs:25:6
|
||||||
|
@ -34,8 +30,6 @@ LL | | x?;
|
||||||
LL | | 22
|
LL | | 22
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_- this function should return `Result` or `Option` to accept `?`
|
| |_- this function should return `Result` or `Option` to accept `?`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ LL | fn test1() {
|
||||||
LL | let mut _file = File::create("foo.txt")?;
|
LL | let mut _file = File::create("foo.txt")?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `()`
|
| ^ cannot use the `?` operator in a function that returns `()`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
LL ~ fn test1() -> Result<(), Box<dyn std::error::Error>> {
|
LL ~ fn test1() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -23,7 +22,6 @@ LL | fn test2() {
|
||||||
LL | let mut _file = File::create("foo.txt")?;
|
LL | let mut _file = File::create("foo.txt")?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `()`
|
| ^ cannot use the `?` operator in a function that returns `()`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
LL ~ fn test2() -> Result<(), Box<dyn std::error::Error>> {
|
LL ~ fn test2() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -41,7 +39,6 @@ LL | fn test4(&self) {
|
||||||
LL | let mut _file = File::create("foo.txt")?;
|
LL | let mut _file = File::create("foo.txt")?;
|
||||||
| ^ cannot use the `?` operator in a method that returns `()`
|
| ^ cannot use the `?` operator in a method that returns `()`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
LL ~ fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
|
LL ~ fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -59,7 +56,6 @@ LL | fn test5(&self) {
|
||||||
LL | let mut _file = File::create("foo.txt")?;
|
LL | let mut _file = File::create("foo.txt")?;
|
||||||
| ^ cannot use the `?` operator in a method that returns `()`
|
| ^ cannot use the `?` operator in a method that returns `()`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
LL ~ fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
|
LL ~ fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -78,7 +74,6 @@ LL | fn main() {
|
||||||
LL | let mut _file = File::create("foo.txt")?;
|
LL | let mut _file = File::create("foo.txt")?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `()`
|
| ^ cannot use the `?` operator in a function that returns `()`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -99,7 +94,6 @@ LL | let mut _file = File::create("foo.txt")?;
|
||||||
LL | mac!();
|
LL | mac!();
|
||||||
| ------ in this macro invocation
|
| ------ in this macro invocation
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
|
|
|
@ -20,9 +20,6 @@ LL | fn option_to_result() -> Result<u64, String> {
|
||||||
| -------------------------------------------- this function returns a `Result`
|
| -------------------------------------------- this function returns a `Result`
|
||||||
LL | Some(3)?;
|
LL | Some(3)?;
|
||||||
| ^ use `.ok_or(...)?` to provide an error compatible with `Result<u64, String>`
|
| ^ use `.ok_or(...)?` to provide an error compatible with `Result<u64, String>`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>`
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
|
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
|
||||||
--> $DIR/bad-interconversion.rs:15:31
|
--> $DIR/bad-interconversion.rs:15:31
|
||||||
|
@ -31,9 +28,6 @@ LL | fn control_flow_to_result() -> Result<u64, String> {
|
||||||
| -------------------------------------------------- this function returns a `Result`
|
| -------------------------------------------------- this function returns a `Result`
|
||||||
LL | Ok(ControlFlow::Break(123)?)
|
LL | Ok(ControlFlow::Break(123)?)
|
||||||
| ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result<u64, String>`
|
| ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result<u64, String>`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`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:20:22
|
--> $DIR/bad-interconversion.rs:20:22
|
||||||
|
@ -42,9 +36,6 @@ LL | fn result_to_option() -> Option<u16> {
|
||||||
| ------------------------------------ this function returns an `Option`
|
| ------------------------------------ this function returns an `Option`
|
||||||
LL | Some(Err("hello")?)
|
LL | Some(Err("hello")?)
|
||||||
| ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
|
| ^ use `.ok()?` if you want to discard the `Result<Infallible, &str>` error information
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>`
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
|
|
||||||
|
|
||||||
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 in a function that returns `Option`
|
||||||
--> $DIR/bad-interconversion.rs:25:33
|
--> $DIR/bad-interconversion.rs:25:33
|
||||||
|
@ -53,9 +44,6 @@ LL | fn control_flow_to_option() -> Option<u64> {
|
||||||
| ------------------------------------------ this function returns an `Option`
|
| ------------------------------------------ this function returns an `Option`
|
||||||
LL | Some(ControlFlow::Break(123)?)
|
LL | Some(ControlFlow::Break(123)?)
|
||||||
| ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>`
|
| ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option<u64>`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||||
--> $DIR/bad-interconversion.rs:30:39
|
--> $DIR/bad-interconversion.rs:30:39
|
||||||
|
|
26
tests/ui/try-trait/bad-question-mark-on-trait-object.rs
Normal file
26
tests/ui/try-trait/bad-question-mark-on-trait-object.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
struct E;
|
||||||
|
struct X;
|
||||||
|
|
||||||
|
fn foo() -> Result<(), Box<dyn std::error::Error>> { //~ NOTE required `E: std::error::Error` because of this
|
||||||
|
Ok(bar()?)
|
||||||
|
//~^ ERROR `?` couldn't convert the error: `E: std::error::Error` is not satisfied
|
||||||
|
//~| NOTE the trait `std::error::Error` is not implemented for `E`
|
||||||
|
//~| NOTE the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||||
|
//~| NOTE required for `Box<dyn std::error::Error>` to implement `From<E>`
|
||||||
|
//~| NOTE in this expansion
|
||||||
|
//~| NOTE in this expansion
|
||||||
|
//~| NOTE in this expansion
|
||||||
|
}
|
||||||
|
fn bat() -> Result<(), X> { //~ NOTE expected `X` because of this
|
||||||
|
Ok(bar()?)
|
||||||
|
//~^ ERROR `?` couldn't convert the error to `X`
|
||||||
|
//~| NOTE the trait `From<E>` is not implemented for `X`
|
||||||
|
//~| NOTE this can't be annotated with `?` because it has type `Result<_, E>`
|
||||||
|
//~| NOTE the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||||
|
//~| NOTE in this expansion
|
||||||
|
//~| NOTE in this expansion
|
||||||
|
}
|
||||||
|
fn bar() -> Result<(), E> {
|
||||||
|
Err(E)
|
||||||
|
}
|
||||||
|
fn main() {}
|
26
tests/ui/try-trait/bad-question-mark-on-trait-object.stderr
Normal file
26
tests/ui/try-trait/bad-question-mark-on-trait-object.stderr
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied
|
||||||
|
--> $DIR/bad-question-mark-on-trait-object.rs:5:13
|
||||||
|
|
|
||||||
|
LL | fn foo() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
| -------------------------------------- required `E: std::error::Error` because of this
|
||||||
|
LL | Ok(bar()?)
|
||||||
|
| ^ the trait `std::error::Error` is not implemented for `E`
|
||||||
|
|
|
||||||
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||||
|
= note: required for `Box<dyn std::error::Error>` to implement `From<E>`
|
||||||
|
|
||||||
|
error[E0277]: `?` couldn't convert the error to `X`
|
||||||
|
--> $DIR/bad-question-mark-on-trait-object.rs:15:13
|
||||||
|
|
|
||||||
|
LL | fn bat() -> Result<(), X> {
|
||||||
|
| ------------- expected `X` because of this
|
||||||
|
LL | Ok(bar()?)
|
||||||
|
| -----^ the trait `From<E>` is not implemented for `X`
|
||||||
|
| |
|
||||||
|
| this can't be annotated with `?` because it has type `Result<_, E>`
|
||||||
|
|
|
||||||
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -6,9 +6,6 @@ LL | fn test_result() -> Result<(),()> {
|
||||||
LL | let a:Option<()> = Some(());
|
LL | let a:Option<()> = Some(());
|
||||||
LL | a?;
|
LL | a?;
|
||||||
| ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>`
|
| ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`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
|
||||||
|
@ -18,9 +15,6 @@ 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?;
|
||||||
| ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
|
| ^ use `.ok()?` if you want to discard the `Result<Infallible, i32>` error information
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>`
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@ LL | fn a_function() -> u32 {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `u32`
|
| ^ cannot use the `?` operator in a function that returns `u32`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||||
--> $DIR/try-on-option-diagnostics.rs:14:10
|
--> $DIR/try-on-option-diagnostics.rs:14:10
|
||||||
|
@ -17,8 +15,6 @@ LL | let a_closure = || {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ cannot use the `?` operator in a closure that returns `{integer}`
|
| ^ cannot use the `?` operator in a closure that returns `{integer}`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||||
--> $DIR/try-on-option-diagnostics.rs:26:14
|
--> $DIR/try-on-option-diagnostics.rs:26:14
|
||||||
|
@ -28,8 +24,6 @@ LL | fn a_method() {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ cannot use the `?` operator in a method that returns `()`
|
| ^ cannot use the `?` operator in a method that returns `()`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||||
--> $DIR/try-on-option-diagnostics.rs:39:14
|
--> $DIR/try-on-option-diagnostics.rs:39:14
|
||||||
|
@ -39,8 +33,6 @@ LL | fn a_trait_method() {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ cannot use the `?` operator in a trait method that returns `()`
|
| ^ cannot use the `?` operator in a trait method that returns `()`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,6 @@ LL | fn foo() -> Result<u32, ()> {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ use `.ok_or(...)?` to provide an error compatible with `Result<u32, ()>`
|
| ^ use `.ok_or(...)?` to provide an error compatible with `Result<u32, ()>`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>`
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
|
|
||||||
|
|
||||||
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||||
--> $DIR/try-on-option.rs:11:6
|
--> $DIR/try-on-option.rs:11:6
|
||||||
|
@ -18,8 +15,6 @@ LL | fn bar() -> u32 {
|
||||||
LL | let x: Option<u32> = None;
|
LL | let x: Option<u32> = None;
|
||||||
LL | x?;
|
LL | x?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `u32`
|
| ^ cannot use the `?` operator in a function that returns `u32`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ LL | // error for a `Try` type on a non-`Try` fn
|
||||||
LL | std::fs::File::open("foo")?;
|
LL | std::fs::File::open("foo")?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `()`
|
| ^ cannot use the `?` operator in a function that returns `()`
|
||||||
|
|
|
|
||||||
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
|
|
||||||
help: consider adding return type
|
help: consider adding return type
|
||||||
|
|
|
|
||||||
LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
@ -33,8 +32,6 @@ LL | fn main() {
|
||||||
...
|
...
|
||||||
LL | ()?;
|
LL | ()?;
|
||||||
| ^ cannot use the `?` operator in a function that returns `()`
|
| ^ cannot use the `?` operator in a function that returns `()`
|
||||||
|
|
|
||||||
= help: the trait `FromResidual<_>` is not implemented for `()`
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): Try` is not satisfied
|
error[E0277]: the trait bound `(): Try` is not satisfied
|
||||||
--> $DIR/try-operator-on-main.rs:14:25
|
--> $DIR/try-operator-on-main.rs:14:25
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue