Skip to content
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

Merged
merged 11 commits into from
Mar 24, 2018

Conversation

tmandry
Copy link
Member

@tmandry tmandry commented Mar 19, 2018

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.

@rust-highfive
Copy link
Collaborator

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.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 19, 2018
@tmandry
Copy link
Member Author

tmandry commented Mar 19, 2018

cc @nikomatsakis

@nikomatsakis
Copy link
Contributor

r? @nikomatsakis

@nikomatsakis
Copy link
Contributor

@tmandry

First time contribution, so I'd really appreciate any feedback on how this PR can be better.

Woohoo, welcome! <3

Copy link
Contributor

@nikomatsakis nikomatsakis left a 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]
Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Contributor

@estebank estebank Mar 20, 2018

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`.

Copy link
Contributor

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.

@tmandry
Copy link
Member Author

tmandry commented Mar 20, 2018

I updated the tests to reflect the error label that's already there from rustc_on_unimplemented. Here's what the full output looks like:

error[E0277]: the trait bound `i32: std::process::Termination` is not satisfied
  --> src/bin/termination-trait-main-i32.rs:11:18
   |
11 |   fn main() -> i32 {
   |  __________________^
12 | | //~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277]
13 | |     0
14 | | }
   | |_^ `main` can only return types that implement std::process::Termination, not `i32`
   |
   = 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`.

@nikomatsakis
Copy link
Contributor

@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.

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);
Copy link
Contributor

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:

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:

decl: &'gcx hir::FnDecl,

The FnDecl struct is declared here:

rust/src/librustc/hir/mod.rs

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:

rust/src/librustc/hir/mod.rs

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.

@nikomatsakis nikomatsakis added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 20, 2018
@tmandry
Copy link
Member Author

tmandry commented Mar 20, 2018

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 tmandry changed the title [WIP] Stabilize termination_trait, split out termination_trait_test Stabilize termination_trait, split out termination_trait_test Mar 20, 2018
@nikomatsakis
Copy link
Contributor

@tmandry 🏂

@nikomatsakis
Copy link
Contributor

cc @rust-lang/docs -- I want to r+ this PR! It stabilizes fn main() -> T { } where T: Termination (though not the termination trait itself). What kind of documentation is needed and where?

@nikomatsakis
Copy link
Contributor

According to @aturon, for edition-related docs we're going to handle them out of band. Therefore, I'm allowed to r+.

@bors r+

@bors
Copy link
Contributor

bors commented Mar 20, 2018

📌 Commit 72334fe has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 20, 2018
@nikomatsakis
Copy link
Contributor

@tmandry nice work

@nikomatsakis
Copy link
Contributor

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 22, 2018
@nikomatsakis
Copy link
Contributor

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 E0580 code, so that we can have a --explain output that is tailored to this case. I can help @tmandry with the answer to this question:

since I'm not sure how to go from here to librustc::infer::error_reporting where E0580 is used (or vice versa)

in one second.

Regarding what @scottmcm wrote:

One thought: is there a canonical "I don't really care I just want to use ?" Result type we could point people to?

Interesting point. I don't think though that there is :( -- I wish that Result<_, Box<Error>> would work but for Reasons I don't think it will really will, and I don't think that Box<dyn Debug> would work because there needed Into clauses don't exist.

@nikomatsakis
Copy link
Contributor

@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 unsafe or the wrong ABI. So in a sense maybe using E0580 isn't the best option. If we did want to do it, we would create a refactored helper function somewhere that both the error-reporting modules can call into. But this code is in dire need of some refactoring.

Anyway, thanks @tmandry for all the effort you've put into this.

@bors
Copy link
Contributor

bors commented Mar 22, 2018

📌 Commit 2b13d95 has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 22, 2018
@estebank
Copy link
Contributor

@nikomatsakis I just realized that it could make sense to allow rustc_on_unimplemented to set an error code but I'd be worried about over/mis-use...

@scottmcm
Copy link
Member

Filed rust-lang/rfcs#2367 to track coming up with a good return type to suggest.

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Mar 23, 2018
…, 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.
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Mar 23, 2018
…, 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.
kennytm added a commit to kennytm/rust that referenced this pull request Mar 24, 2018
…, 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.
kennytm added a commit to kennytm/rust that referenced this pull request Mar 24, 2018
…, 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.
bors added a commit that referenced this pull request Mar 24, 2018
@bors bors merged commit 2b13d95 into rust-lang:master Mar 24, 2018
@tmandry tmandry deleted the stabilize-termination-trait branch March 24, 2018 21:56
@SimonSapin SimonSapin added the relnotes Marks issues that should be documented in the release notes of the next release. label Mar 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants