-
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
Stabilize termination_trait, split out termination_trait_test #49162
Conversation
This stabilizes `main` with non-() return types; see rust-lang#48453.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @petrochenkov (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Woohoo, welcome! <3 |
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.
This looks great! My one concern is whether we can improve that error message in the case of a bad return type for main
. I fear it is going to be confuse people as is.
@@ -8,6 +8,7 @@ | |||
// option. This file may not be copied, modified, or distributed | |||
// except according to those terms. | |||
|
|||
fn main() -> i32 { //~ ERROR main function has wrong type [E0580] | |||
fn main() -> i32 { | |||
//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] |
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.
Hmm, this is not your fault, but this error message seems less clear than before.
@estebank -- can we improve this readily enough with a #[rustc_on_unimplemented]
annotation perhaps?
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.
Yes, you could annotate std::process::Termination
using #[rustc_on_unimplemented]
to replace the error message to something appropriate. The only limitation is not knowing wether the requirement came from a return type or anywhere else, so the message will have to be more generic than it is now.
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 looks like there is already a #[rustc_on_unimplemented]
annotation, but it is not used in the error message for some reason.
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.
Nevermind, once I cleaned my rustc build the note showed up. But since it's a label, not the primary error message, I had to use the error-message:
directive to match against it.
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.
For what it's worth, you have further control on the rustc_on_unimplemented
output by being able to set a separate message and label, as well as customize either one for specific types.
That way, after including Niko's span change you could have the following output:
error[E0277]: `main` can only return types that implement `std::process::Termination`, not `i32`
--> src/bin/termination-trait-main-i32.rs:11:18
|
11 | fn main() -> i32 {
| ^^^ can only return types that implement `std::process::Termination`
|
= help: the trait `std::process::Termination` is not implemented for `i32`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
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.
since it's a label, not the primary error message, I had to use the error-message: directive to match against it.
You didn't need to use error-message
, you could use
//~^ NOTE `main` can only return types that implement std::process::Termination, not `i32`
instead for labels.
I updated the tests to reflect the error label that's already there from
|
@tmandry ok, so, that is looking better! the main problem is that the span we are giving for the error (i.e., the region in the source code that we highlight) is the function body, which makes it cross multiple lines and makes my eyes glaze over (I imagine others have the same reaction). Let me see if I can give any tips about how to get a better span. |
src/librustc_typeck/check/mod.rs
Outdated
let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); | ||
let trait_ref = ty::TraitRef::new(term_id, substs); | ||
let cause = traits::ObligationCause::new( | ||
span, fn_id, ObligationCauseCode::MainFunctionType); |
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.
the span is specified here; if you look up to line 1028 you can see it comes from the body:
rust/src/librustc_typeck/check/mod.rs
Line 1028 in 5ccf3ff
let span = body.value.span; |
In general, to get a good span, you want to look to the HIR, which corresponds pretty closely to the input program. In this case, we want to look at the argument decl
:
rust/src/librustc_typeck/check/mod.rs
Line 1001 in 5ccf3ff
decl: &'gcx hir::FnDecl, |
The FnDecl
struct is declared here:
Lines 1718 to 1727 in 5ccf3ff
/// Represents the header (not the body) of a function declaration | |
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] | |
pub struct FnDecl { | |
pub inputs: HirVec<P<Ty>>, | |
pub output: FunctionRetTy, | |
pub variadic: bool, | |
/// True if this function has an `self`, `&self` or `&mut self` receiver | |
/// (but not a `self: Xxx` one). | |
pub has_implicit_self: bool, | |
} |
We want to get the span from the return type, for which there is a convenient method:
Lines 1815 to 1820 in 5ccf3ff
pub fn span(&self) -> Span { | |
match *self { | |
DefaultReturn(span) => span, | |
Return(ref ty) => ty.span, | |
} | |
} |
So basically the span should be something like:
let return_ty_span = decl.output.span();
and use that instead of span
.
Thanks for your help! I agree, the error message is much better this way. Updated and converted one of the tests to a UI test. |
@tmandry 🏂 |
cc @rust-lang/docs -- I want to r+ this PR! It stabilizes |
According to @aturon, for edition-related docs we're going to handle them out of band. Therefore, I'm allowed to r+. @bors r+ |
📌 Commit 72334fe has been approved by |
@tmandry nice work |
@bors r- |
So, it does look great, but I did just want to make two comments: It does seem like it'd be marginally better to use the
in one second. Regarding what @scottmcm wrote:
Interesting point. I don't think though that there is :( -- I wish that |
@bors r+ Ugh. OK, digging into the code I see what @tmandry was tempted to leave it the way they did. =) It's a bit annoying to use E0580. I'm sort of inclined to land this now, and leave that for possible follow-up. So r+ again. One interesting thing is that E0580 is also issued for things unrelated to the return type -- e.g., supplying arguments, or making main Anyway, thanks @tmandry for all the effort you've put into this. |
📌 Commit 2b13d95 has been approved by |
@nikomatsakis I just realized that it could make sense to allow |
Filed rust-lang/rfcs#2367 to track coming up with a good return type to suggest. |
…, r=nikomatsakis Stabilize termination_trait, split out termination_trait_test For rust-lang#48453. First time contribution, so I'd really appreciate any feedback on how this PR can be better. Not sure exactly what kind of documentation update is needed. If there is no PR to update the reference, I can try doing that this week as I have time.
…, r=nikomatsakis Stabilize termination_trait, split out termination_trait_test For rust-lang#48453. First time contribution, so I'd really appreciate any feedback on how this PR can be better. Not sure exactly what kind of documentation update is needed. If there is no PR to update the reference, I can try doing that this week as I have time.
…, r=nikomatsakis Stabilize termination_trait, split out termination_trait_test For rust-lang#48453. First time contribution, so I'd really appreciate any feedback on how this PR can be better. Not sure exactly what kind of documentation update is needed. If there is no PR to update the reference, I can try doing that this week as I have time.
…, r=nikomatsakis Stabilize termination_trait, split out termination_trait_test For rust-lang#48453. First time contribution, so I'd really appreciate any feedback on how this PR can be better. Not sure exactly what kind of documentation update is needed. If there is no PR to update the reference, I can try doing that this week as I have time.
For #48453.
First time contribution, so I'd really appreciate any feedback on how this PR can be better.
Not sure exactly what kind of documentation update is needed. If there is no PR to update the reference, I can try doing that this week as I have time.