-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More general on_unimplemented
, with uses in Try
#44191
Conversation
cc @estebank @rust-lang/docs are there any more things you want in |
Position::ArgumentIs(_) => { | ||
span_err!(tcx.sess, span, E0231, | ||
"only named substitution \ | ||
parameters are allowed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note including all the possible valid named parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's preexisting.
src/librustc_typeck/check/mod.rs
Outdated
let item_def_id = tcx.hir.local_def_id(item.id); | ||
// an error would be reported if this fails. | ||
let _ = traits::OnUnimplementedDirective::of_item( | ||
tcx, trait_def_id, item_def_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't fit in <100?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it does. this just went through a few revisions.
@@ -4690,7 +4646,6 @@ register_diagnostics! { | |||
E0224, // at least one non-builtin train is required for an object type | |||
E0227, // ambiguous lifetime bound, explicit lifetime bound required | |||
E0228, // explicit lifetime bound required | |||
E0231, // only named substitution parameters are allowed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't these need to be commented out instead of deleted? I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to librustc/diagnostics
, not deleted.
| --------------------------- | ||
| | | ||
| 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 `()` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am worried that the error text is less prominent than the label, so moving the more relevant text to the error message makes it less useful for newbies. But this might just be an unfounded personal reaction.
Maybe adding an optional label
attribute to rustc_on_unimplemented
for text to be displayed in the label would be reasonable? (If I understood the code above correctly, the feature is already there, it just needs to be changed in the trait, right?)
--> $DIR/bad-annotation.rs:46:39 | ||
| | ||
46 | #[rustc_on_unimplemented(message="x", message="y")] | ||
| ^^^^^^^^^^^ expected value here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we handle duplicated values with a special label pointing at the first one encountered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't bother with precise error reporting here - this is an unstable feature that is going to be revised.
addressed |
Ah, this is a neat idea! :) I like the idea of improving Anyway, this seems good, but to truly handle the Put another way, can you add the test case from #43984? |
The test case from #43984 is present, it's the other one that isn't So the problem is basically to distinguish: fn main() {
Ok(4)?; //~ ERROR the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
}
fn foo() -> Result<(), ()> {
()?; //~ ERROR <want something else>
Ok(())
} |
I think I can arrange that, but I need to go AFK. |
@arielb1 right, that is the two cases to distinguish. The test case I was referring to included: fn source() -> u32 {
3u32?
} with the expected error message:
I think it's a bit debatable what the "main part" of that error should be, but anyway. |
Special |
std::fs::File::open("foo")?; | ||
|
||
// a non-`Try` type on a `Try` fn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a non-`Try` type on a non-`Try` fn
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()` | ||
| | ||
= note: required by `try_trait_generic` | ||
|
||
error: aborting due to 2 previous errors | ||
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be neat to also add a custom error message for this case along the lines of
the `?` operator can only be applied to elements that implement the trait `std::ops::Try`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think now that we have this feature one of the docs guys should use it (or variants of it) in all the traits.
flags.push(("from_desugaring", None)); | ||
flags.push(("from_desugaring", Some(&*s))); | ||
flags.push(("from_desugaring", Some(&*desugaring))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use .as_ref
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally use &*x
instead of .as_ref()
.
264bc78
to
0738768
Compare
src/libcore/ops/try.rs
Outdated
@@ -21,7 +21,9 @@ | |||
(or another type that implements `{Try}`)")] | |||
#[cfg_attr(not(stage0), | |||
rustc_on_unimplemented( | |||
on(all(direct, from_desugaring="?"), | |||
on(all( | |||
any(from_method="from_error", from_method="from_ok"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cute.
| in this macro invocation | ||
| | ||
= help: the trait `std::ops::Try` is not implemented for `()` | ||
= note: required by `std::ops::Try::from_error` | ||
|
||
error: aborting due to previous error | ||
error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
@bors r+ |
📌 Commit 0738768 has been approved by |
There's a bizarre error when running
|
@estebank I'm pretty sure that error (which isn't actually a hard error) happens on all builds, regardless of whether the build is successful or not. The actual error is in the
|
@bors r- |
0738768
to
9826f2d
Compare
Maybe I should allow error messages to check the *specific* desugaring? Thanks @huntiep for the idea!
9826f2d
to
291b4ed
Compare
@bors r+ |
📌 Commit 291b4ed has been approved by |
@bors r- |
@bors r=nikomatsakis |
📌 Commit 291b4ed has been approved by |
More general `on_unimplemented`, with uses in `Try` Allow `on_unimplemented` directives to specify both the label and the primary message of the trait error, and allow them to be controlled by flags - currently only to be desugaring-sensitive. e.g. ```Rust #[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}`)", label="cannot use the `?` operator in a function that returns `{Self}`"), )] ``` r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
Allow
on_unimplemented
directives to specify both the label and the primary message of the trait error, and allow them to be controlled by flags - currently only to be desugaring-sensitive.e.g.
r? @nikomatsakis