enable desugaring-sensitive error messages and use them in Try
Maybe I should allow error messages to check the *specific* desugaring? Thanks @huntiep for the idea!
This commit is contained in:
parent
6866aea5af
commit
02b3ae63e2
5 changed files with 74 additions and 9 deletions
|
@ -15,8 +15,16 @@
|
||||||
/// extracting those success or failure values from an existing instance and
|
/// extracting those success or failure values from an existing instance and
|
||||||
/// creating a new instance from a success or failure value.
|
/// creating a new instance from a success or failure value.
|
||||||
#[unstable(feature = "try_trait", issue = "42327")]
|
#[unstable(feature = "try_trait", issue = "42327")]
|
||||||
#[rustc_on_unimplemented = "the `?` operator can only be used in a function that returns `Result` \
|
#[cfg_attr(stage0,
|
||||||
(or another type that implements `{Try}`)"]
|
rustc_on_unimplemented = "the `?` operator can only be used in a \
|
||||||
|
function that returns `Result` \
|
||||||
|
(or another type that implements `{Try}`)")]
|
||||||
|
#[cfg_attr(not(stage0),
|
||||||
|
rustc_on_unimplemented(
|
||||||
|
on(all(direct, from_desugaring),
|
||||||
|
message="the `?` operator can only be used in a \
|
||||||
|
function that returns `Result` \
|
||||||
|
(or another type that implements `{Try}`)")))]
|
||||||
pub trait Try {
|
pub trait Try {
|
||||||
/// The type of this value when viewed as successful.
|
/// The type of this value when viewed as successful.
|
||||||
#[unstable(feature = "try_trait", issue = "42327")]
|
#[unstable(feature = "try_trait", issue = "42327")]
|
||||||
|
|
|
@ -327,10 +327,26 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
.unwrap_or(trait_ref.def_id());
|
.unwrap_or(trait_ref.def_id());
|
||||||
let trait_ref = *trait_ref.skip_binder();
|
let trait_ref = *trait_ref.skip_binder();
|
||||||
|
|
||||||
|
let mut flags = vec![];
|
||||||
|
let direct = match obligation.cause.code {
|
||||||
|
ObligationCauseCode::BuiltinDerivedObligation(..) |
|
||||||
|
ObligationCauseCode::ImplDerivedObligation(..) => false,
|
||||||
|
_ => true
|
||||||
|
};
|
||||||
|
if direct {
|
||||||
|
// this is a "direct", user-specified, rather than derived,
|
||||||
|
// obligation.
|
||||||
|
flags.push("direct");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(_) = obligation.cause.span.compiler_desugaring_kind() {
|
||||||
|
flags.push("from_desugaring");
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
|
if let Ok(Some(command)) = OnUnimplementedDirective::of_item(
|
||||||
self.tcx, trait_ref.def_id, def_id
|
self.tcx, trait_ref.def_id, def_id
|
||||||
) {
|
) {
|
||||||
command.evaluate(self.tcx, trait_ref, &[])
|
command.evaluate(self.tcx, trait_ref, &flags)
|
||||||
} else {
|
} else {
|
||||||
OnUnimplementedNote::empty()
|
OnUnimplementedNote::empty()
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,6 +205,18 @@ impl Span {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the compiler desugaring that created this span, or None
|
||||||
|
/// if this span is not from a desugaring.
|
||||||
|
pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
|
||||||
|
match self.ctxt().outer().expn_info() {
|
||||||
|
Some(info) => match info.callee.format {
|
||||||
|
ExpnFormat::CompilerDesugaring(k) => Some(k),
|
||||||
|
_ => None
|
||||||
|
},
|
||||||
|
None => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if a span is "internal" to a macro in which `unsafe`
|
/// Check if a span is "internal" to a macro in which `unsafe`
|
||||||
/// can be used without triggering the `unsafe_code` lint
|
/// can be used without triggering the `unsafe_code` lint
|
||||||
// (that is, a macro marked with `#[allow_internal_unsafe]`).
|
// (that is, a macro marked with `#[allow_internal_unsafe]`).
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::ops::Try;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
std::fs::File::open("foo")?;
|
std::fs::File::open("foo")?;
|
||||||
|
|
||||||
|
try_trait_generic::<()>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_trait_generic<T: Try>() {}
|
||||||
|
|
|
@ -1,14 +1,37 @@
|
||||||
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
|
error: use of unstable library feature 'try_trait' (see issue #42327)
|
||||||
--> $DIR/try-operator-on-main.rs:12:5
|
--> $DIR/try-operator-on-main.rs:11:5
|
||||||
|
|
|
|
||||||
12 | std::fs::File::open("foo")?;
|
11 | use std::ops::Try;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add #![feature(try_trait)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: use of unstable library feature 'try_trait' (see issue #42327)
|
||||||
|
--> $DIR/try-operator-on-main.rs:19:25
|
||||||
|
|
|
||||||
|
19 | fn try_trait_generic<T: Try>() {}
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= help: add #![feature(try_trait)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
|
||||||
|
--> $DIR/try-operator-on-main.rs:14:5
|
||||||
|
|
|
||||||
|
14 | std::fs::File::open("foo")?;
|
||||||
| ---------------------------
|
| ---------------------------
|
||||||
| |
|
| |
|
||||||
| the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
|
| the trait `std::ops::Try` is not implemented for `()`
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
|
|
|
|
||||||
= help: the trait `std::ops::Try` is not implemented for `()`
|
|
||||||
= note: required by `std::ops::Try::from_error`
|
= note: required by `std::ops::Try::from_error`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
|
||||||
|
--> $DIR/try-operator-on-main.rs:16:5
|
||||||
|
|
|
||||||
|
16 | try_trait_generic::<()>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
|
||||||
|
|
|
||||||
|
= note: required by `try_trait_generic`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue