-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Overhaul const-checking diagnostics #77354
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
Conversation
This doesn't change any UI test output
c85f2cd
to
97dc865
Compare
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.
97dc865
to
287993c
Compare
#![feature(const_raw_ptr_deref)] | ||
#![feature(const_raw_ptr_deref, const_mut_refs)] | ||
|
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 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.
e89a2c7
to
6533e40
Compare
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?
6533e40
to
7c6d685
Compare
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(); |
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 this is already checked in the syntax based checks, couldn't this also be a delay_span_bug
?
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 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>
.
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.
You invoke delay_as_bug
instead of emit
: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagnosticBuilder.html#method.delay_as_bug
@@ -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); |
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 "usual" way we do this is to return an ErrorReported
instance
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.
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, |
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 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.
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.
Yeah, the def_span
one seems most correct.
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.
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() { |
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.
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>
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... 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
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.
Sounds good. I like the ErrorReported
approach.
@oli-obk I want to just do the |
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 |
`def_span` has the same issues as `body.span`, so do it this way instead.
0d3960e
to
1301f43
Compare
I tried doing the Other review comments should be addressed. |
@bors r+ yea, I was a bit worried about that, especially since |
📌 Commit 1301f43 has been approved by |
☀️ Test successful - checks-actions, checks-azure |
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 withqualify_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 justconst fn
.As always, meant to be reviewed commit-by-commit.
r? @oli-obk