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

Overhaul const-checking diagnostics #77354

Merged
merged 23 commits into from
Oct 1, 2020

Conversation

ecstatic-morse
Copy link
Contributor

@ecstatic-morse ecstatic-morse commented Sep 30, 2020

The primary purpose of this PR was to remove NonConstOp::STOPS_CONST_CHECKING, which causes any additional errors found by the const-checker to be silenced. I used this flag to preserve diagnostic parity with qualify_min_const_fn.rs, which has since been removed.

However, simply removing the flag caused a deluge of errors in some cases, since an error would be emitted any time a local or temporary had a wrong type. To remedy this, I added an alternative system (DiagnosticImportance) to silence additional error messages that were likely to distract the user from the underlying issue. When an error of the highest importance occurs, all less important errors are silenced. When no error of the highest importance occurs, all less important errors are emitted after checking is complete. Following the suggestions from the important error is usually enough to fix the less important errors, so this should lead to better UX most of the time.

There's also some unrelated diagnostics improvements in this PR isolated in their own commits. Splitting them out would be possible, but a bit of a pain. This isn't as tidy as some of my other PRs, but it should only affect diagnostics, never whether or not something passes const-checking. Note that there are a few trivial exceptions to this, like banning Yield in all const-contexts, not just const fn.

As always, meant to be reviewed commit-by-commit.

r? @oli-obk

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 30, 2020
This errors during AST lowering. Any errors we emit here are just noise.
This ensures that `emit_error` will actually cause compilation to fail.
The "otherwise" note is printed before the suggestion currently.
This helper function was meant to reduce code duplication between
const-checking pre- and post-drop-elaboration. Most of the functionality
is only relevant for the pre-drop-elaboration pass.
Comment on lines -4 to 5
#![feature(const_raw_ptr_deref)]
#![feature(const_raw_ptr_deref, const_mut_refs)]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was only failing pre-monomorphization due to a missing feature gate. It seemed like we wanted to exhaustively test this, especially since there is another test without the feature gate modified in this commit. This led to #77353.

@ecstatic-morse ecstatic-morse force-pushed the const-checking-moar-errors branch 2 times, most recently from e89a2c7 to 6533e40 Compare September 30, 2020 04:10
Now all structured errors must have their own error code
Inline assembly is now the only user of E0019. What is it doing that
E0015 is not?
@oli-obk
Copy link
Contributor

oli-obk commented Sep 30, 2020

cc @rust-lang/wg-diagnostics

}

fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "const fn generators are unstable");
ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`").emit();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is already checked in the syntax based checks, couldn't this also be a delay_span_bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't see a way to make a DiagnosticBuilder that gets emitted as a delay_span_bug. I could either inline the delay_span_bug, since the structured error is only emitted in one place, or wait until I change to Result<ErrorReported, DiagnosticBuilder>.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -49,7 +49,9 @@ pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> boo
return false;
}

op.emit_error(ccx, span);
let mut err = op.build_error(ccx, span);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "usual" way we do this is to return an ErrorReported instance

Copy link
Contributor

@oli-obk oli-obk Sep 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, nevermind, this is for the primary/secondary system. One possibility would be not to have the importance function, but instead return an Result<ErrorReported, DiagnosticBuilder<'tcx>> from build_error. Then this could internally decide whether to immediately report or whether to return the builder for later use.

@@ -33,7 +33,12 @@ pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> boo
concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
Applicability::HasPlaceholders,
)
.note("otherwise `#[allow_internal_unstable]` can be used to bypass stability checks")
.span_suggestion(
ccx.body.span,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should only be ccx.body.span.lo() I think? Or we may even the `ccx.tcx.def_span(ccx.def_id.to_def_id()) so it's inserted before the item and not as part of the body.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the def_span one seems most correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def_span seems to point before the block as well. I ended up using fn_sig().span.shrink_to_lo(), which should do the right thing.

@@ -301,7 +318,15 @@ impl Validator<'mir, 'tcx> {

let mut err = op.build_error(self.ccx, span);
assert!(err.is_error());
err.emit();

match op.importance() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned elsewhere, I think build_error should return a Result<ErrorReported, DiagnosticBuilder<'tcx>>. Additionally the error_emitted field could then be an Option<ErrorReported>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I just noticed that emit does not return Option<ErrorReported>.. sorry I thought we already had done all that. Let's carry on with this PR then and fix that together with making emit create instances of ErrorReported

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I like the ErrorReported approach.

@ecstatic-morse
Copy link
Contributor Author

ecstatic-morse commented Sep 30, 2020

@oli-obk I want to just do the Result<ErrorReported, ...> thing now. Does that work for you? I'll avoid rebasing for now and we can squash it before this gets merged.

@oli-obk
Copy link
Contributor

oli-obk commented Sep 30, 2020

Sure, I have no problem with that being done immediately in this PR, I just didn't want to make it a requirement for getting merged

@ecstatic-morse
Copy link
Contributor Author

ecstatic-morse commented Sep 30, 2020

I tried doing the Result<...> refactor and liked it less than the current approach, since most every emit_error function has to emit and then return an Ok. I'll try it in a follow-up PR and we can see if you feel the same. Do you want me to delay_span_bug on Generator MIR as part of this PR? It doesn't fit into the build_error framework since errors are emited unconditionally, so I'll have to circumvent check_op. I will probably use that error for the case in #77361, so I think it should remain inside the framework for now.

Other review comments should be addressed.

@oli-obk
Copy link
Contributor

oli-obk commented Oct 1, 2020

@bors r+

yea, I was a bit worried about that, especially since emit doesn't return Option<ErrorReported> yet. One thing that could be done (and would probably need to be done even with emit returning Option<ErrorReported>) is to add a helper trait that has an emit_err() method that returns Ok(ErrorReported), so you can just invoke that instead of emit. Once emit returns Option<ErrorReported> we can then make the body of emit_err() be Ok(diag.emit().unwrap()), since we know for sure we're not emitting lints. This way only the code that actually returns Err will actually need special handling.

@bors
Copy link
Contributor

bors commented Oct 1, 2020

📌 Commit 1301f43 has been approved by oli-obk

@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-review Status: Awaiting review from the assignee but also interested parties. labels Oct 1, 2020
@bors
Copy link
Contributor

bors commented Oct 1, 2020

⌛ Testing commit 1301f43 with merge fc42fb8...

@bors
Copy link
Contributor

bors commented Oct 1, 2020

☀️ Test successful - checks-actions, checks-azure
Approved by: oli-obk
Pushing fc42fb8 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 1, 2020
@bors bors merged commit fc42fb8 into rust-lang:master Oct 1, 2020
@rustbot rustbot added this to the 1.48.0 milestone Oct 1, 2020
@ecstatic-morse ecstatic-morse deleted the const-checking-moar-errors branch October 6, 2020 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. 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.

5 participants