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

Miri: unleash all feature gates #71631

Merged
merged 10 commits into from
May 4, 2020
Merged

Conversation

RalfJung
Copy link
Member

IMO it is silly to unleash features that do not even have a feature gate yet, but not unleash features that do. The only thing this achieves is making unleashed mode annoying to use as we have to figure out the feature flags to enable (and not always do the error messages say what that flag is).

Given that the point of -Z unleash-the-miri-inside-of-you is to debug the Miri internals, I see no good reason for this extra hurdle. I cannot imagine a situation where we'd use that flag, realize the program also requires some feature gate, and then be like "oh I guess if this feature is unstable I will do something else". Instead, we'll always just add that flag to the code as well, so requiring the flag achieves nothing.

r? @oli-obk @ecstatic-morse
Fixes #71630

@rust-highfive

This comment has been minimized.

@ecstatic-morse
Copy link
Contributor

ecstatic-morse commented Apr 28, 2020

The goal of the current behavior is to prevent unnecessary use of -Zunleash in the test suite when feature gates would suffice. Requiring that test writers use feature gates makes it easy to see what tests no longer need -Zunleash when a new feature is implemented on nightly.

Without a diagnostics bug--we were not suggesting that nightly users enable #![feature(const_mut_refs)] when we saw a deref of a mutable reference--the solution to the problem you encountered would have been clear. We should fix this instead.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 28, 2020

the solution to the problem you encountered would have been clear.

Yes, it would have been clearer.

But I still think we should not ask for feature gates with unleash-miri. Even if the compiler tells me which feature gate is missing, that's just needless hoops for me to jump through. All it achieves is annoy me as I am crafting the testcase.

The goal of the current behavior is to prevent unnecessary use of -Zunleash in the test suite when feature gates would suffice.

I'm not a fan of that kind of nudging -- not when it has harmful effects elsewhere. The way to prevent people from unnecessarily adding the flag is to tell them during review. The flag name is already scary enough to nudge people away from it.

Requiring that test writers use feature gates makes it easy to see what tests no longer need -Zunleash when a new feature is implemented on nightly.

Most (all?) unleash tests that we have should remain unleash even when we get const-checking for those features -- the point of these tests is to check the underlying engine and the dynamic checks, not to check const-qualification. So I don't buy this motivation at well, we typically do not want to remove that flag ever.

@ecstatic-morse
Copy link
Contributor

ecstatic-morse commented Apr 28, 2020

This seems like a difference in values rather than a dispute over the facts. I'd rather have as many tests exercise the const-checker as possible. You would rather not have to think about it while writing -Zunleash tests.

The stakes here are pretty low, so I'm fine with any outcome, but I would appreciate it if you avoided -Zunleash going forward when it is possible to write the same test with just feature gates. Obviously this does not apply to the case in #71630.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 28, 2020

This seems like a difference in values rather than a dispute over the facts. I'd rather have as many tests exercise the const-checker as possible. You would rather not have to think about it while writing -Zunleash tests.

For those tests, why would you use the flag at all?
As far as I am concerned, the entire purpose to use this flag -- the only reason it even exists -- is to disable the const-checker and test the dynamic checks of the underlying motivation. Using this flag when the goal is exercising the const-checker seems outright contradictory.

So when your goal is exercising the const-checker, shouldn't you just not use this flag?

@ecstatic-morse
Copy link
Contributor

ecstatic-morse commented Apr 28, 2020

It's possible for the same test to exercise rare code paths in both the static checks and the dynamic ones. After this PR is merged, it will be possible for you to turn off the const-checker in tests you write (edit: both new and old) even if const-checking could handle them fine. I ask that you don't.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 28, 2020

@ecstatic-morse I don't think I entirely understand which tests you do not want me to modify how -- so I will just make sure to Cc you on every change I make to miri-unleash tests. That way you can make sure I do not accidentally regress test coverage for the static checks.

I think maybe you are saying I should not add the miri-unleash flag to existing tests ("turn off the const-checker"). I will make sure to never do that, and instead run the test both with and without miri-unleash, like what we ended up doing in #71604. This was anyway the first time I did that, usually I just wrote new miri-unleash tests from scratch. Does that work for you?

@RalfJung
Copy link
Member Author

r? @ecstatic-morse

@RalfJung RalfJung force-pushed the miri-unleash-the-gates branch 3 times, most recently from 6c1c529 to b8efed7 Compare April 29, 2020 08:49
@RalfJung RalfJung added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 29, 2020
@ecstatic-morse
Copy link
Contributor

r? @oli-obk

If it were up to me, we wouldn't merge this. Someone else should approve.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 30, 2020

The stakes here are pretty low, so I'm fine with any outcome, but I would appreciate it if you avoided -Zunleash going forward when it is possible to write the same test with just feature gates.

Side note: we can make sure that when a test specifies unleash, it needs to actually unleash anything in order to pass, otherwise we report an additional error about that or just ICE.

@bors
Copy link
Contributor

bors commented Apr 30, 2020

☔ The latest upstream changes (presumably #71707) made this pull request unmergeable. Please resolve the merge conflicts.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 30, 2020

@ecstatic-morse: @oli-obk would like us to form consensus here, and I tend to agree. So let me make another attempt at trying to understand your concern.

If I understand you correctly, you are worried that this change will reduce test coverage for the static const-eval checks. I agree that would be bad. However, I am confused about this concern: in my mind, the entire point of the miri-unleash flag is to not run the static const-eval checks. A test that sets this flag is, by definition, not meant to test anything related to the static checks. Thus I fail to understand how any change in the behavior of this flag can have bad effects on test coverage for the static checks. Maybe you have been using this flag differently?

Currently, indeed the flag dos not disable the static checks entirely, but it disables them mostly, to the extend that I don't think any test meant to cover the static checks can meaningfully use this flag. In particular, the checks for all stable features are disabled, which actually means stabilizing a feature decreases test coverage (they no longer get tested in "miri-unleashed" tests). I don't think that is a good situation even just from the perspective of testing the static checks. Tests for them should simply never use this flag, period. (EDIT: Or maybe I am misunderstanding how the feature_gate() function is used... what would change e.g. in IfOrMatch when that feature becomes stable?) (EDIT2: probably I did, presumably that code will just disappear on stabilization, so we do not need its test coverage any more anyway.)

Maybe you could give a concrete example for how one of our existing tests becomes less useful with this change, or how this change might lead to someone accidentally not testing the thing they wanted to test -- or really any example. So far, whlle I understand your concern in the abstract, I fail to understand how it relates to this PR.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 30, 2020

The stakes here are pretty low, so I'm fine with any outcome, but I would appreciate it if you avoided -Zunleash going forward when it is possible to write the same test with just feature gates.

This is particularly confusing to me, as the unleash tests I write are usually tests that will never get accepted by rustc, even when the features all become stable. The point is to write const-unsound code and make sure it gets rejected by the dynamic checks. None of the tests in "miri-unleashed" is meant to exercise the static const-checker; that should all happen in dedicated tests (and I think it does so far, and I don't think this PR is likely to change that).

Do we have a single "pass" test with "miri-unleash"? I don't think so, they are all about exercising error paths in the CTFE engine that are otherwise unreachable because the static checks prevent even getting to those failures.

@RalfJung
Copy link
Member Author

RalfJung commented Apr 30, 2020

Or to put my confusion in one sentence: I don't understand how it make sense that miri-unleash disables the static checks that prevent non-const fn to be called (or any other operation that we will never permit), but does not disable the check that prevents if from being used. It allows the crazy dangerous things but disallows the "perfectly fine but not yet stable" things, which seems just nonsensical to me.

I am curious to understand why you think this makes sense.

@ecstatic-morse
Copy link
Contributor

ecstatic-morse commented Apr 30, 2020

Side note: we can make sure that when a test specifies unleash, it needs to actually unleash anything in order to pass.

This is the thing I want to enforce. The goal is to prevent you or (more importantly) others from using -Zunleash as a replacement for #![feature(many,different,things)] either in-tree or downstream. I've never said that this is currently going on in-tree, which I think your recent posts are assuming? If there's another way to guarantee this that you find less onerous, such as the one Oli mentioned, I'm happy to approve it.

I'm not a fan of that kind of nudging -- not when it has harmful effects elsewhere. The way to prevent people from unnecessarily adding the flag is to tell them during review. The flag name is already scary enough to nudge people away from it.

I'm a fan of nudging. I'm sorry that you ran into a bad diagnostic, but I don't think the current behavior is "harmful". If you had encountered a scenario that couldn't be resolved just by adding a feature gate, it would be much easier to understand your desire to remove this. The automated check is currently accomplishing the goal I stated above, and I believe that things that can be automated should be: There's no need to rely on the review process.

@RalfJung
Copy link
Member Author

This is the thing I want to enforce. The goal is to prevent you or (more importantly) others from using -Zunleash as a replacement for #![feature(many,different,things)] either in-tree or downstream.

So, what about making -Zunleash call delay_span_bug when it unleashes anything, to make sure that this is only ever used to test error paths? That seems easier than what @oli-obk suggests, and should also avoid your concern?

@RalfJung
Copy link
Member Author

RalfJung commented May 2, 2020

Okay I pushed my latest proposal: this is effectively a delay_span_bug (but through the Session like @oli-obk did to delay it properly) for whenever the miri-unleash flag is sued to get around a feature flag.

This lets me write tests that fail in CTFE without worrying about static checks (they fail anyway, so the delay_span_bug does not matter), but makes sure that run-pass tests properly set the feature flag.


if is_unleashable && self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
self.tcx.sess.span_warn(span, "skipping const checks");
self.tcx.sess.span_warn(self.tcx.def_span(self.def_id), "skipping const checks");
Copy link
Contributor

Choose a reason for hiding this comment

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

side note: what do you think about emitting the feature name that is being skipped if there is one?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure... or maybe not even emit the warning in that case? Either there will be other errors or a panic at the end listing the missing gates.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think emitting them is good, as it shows where things are being skipped. I mean, I added them on purpose so we'd be able so see exactly where a test is skipping checks, in order to notice when the checks change in any way

Copy link
Member Author

Choose a reason for hiding this comment

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

Otherwise I'm worried this will kill deduplication, so we'll have 5 annotations per const again.

Copy link
Member Author

Choose a reason for hiding this comment

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

in order to notice when the checks change in any way

The point of the flag is to not worry about the static checks, and focus on testing the underlying engine. Why would I care if the checks change? I explicitly do not want to care about that, that's why I use the flag.^^

Copy link
Contributor

Choose a reason for hiding this comment

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

I thought we agreed in your PR that this is not the right kind of error, and instead we should error when unleashing any feature gate (like my PR does now)?

Sorry, we've went back and forth too many times. You're right.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess I don't know what "labels" vs "spans" are...

https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagnosticBuilder.html#method.span_label allows you to add an arbitrary annotation to an arbitrary span. This is what gives us the ^^^^^ something here annotations.

Copy link
Member Author

@RalfJung RalfJung May 3, 2020

Choose a reason for hiding this comment

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

Hm... I did that, but it doesn't print the labels.

            let mut diag = self.struct_warn("skipping const checks");
            for &(span, feature_gate) in unleashed_features.iter() {
                if let Some(feature_gate) = feature_gate {
                    diag.span_label(span, format!("skipping check for `{}` feature", feature_gate));
                } else {
                    diag.span_label(span, "skipping check that does not even have a feature gate");
                }
            }
            diag.emit();

becomes just

warning: skipping const checks

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried passing a proper span to struct_warn, no luck.

Our diagnostics APIs are quite hard to use correctly, it seems. :/

Copy link
Member Author

Choose a reason for hiding this comment

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

I went for span_help now, that seems to work. It's quite the hack though...

@rust-highfive

This comment has been minimized.

@@ -1,5 +1,5 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
#![feature(const_mut_refs, box_syntax)]
// compile-flags: -Zunleash-the-miri-inside-of-you -Zdeduplicate-diagnostics
Copy link
Contributor

@oli-obk oli-obk May 3, 2020

Choose a reason for hiding this comment

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

the deduplication isn't necessary anymore, right? (same for the others)

@oli-obk
Copy link
Contributor

oli-obk commented May 3, 2020

@bors r+

@bors
Copy link
Contributor

bors commented May 3, 2020

📌 Commit 182133f 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 May 3, 2020
@bors
Copy link
Contributor

bors commented May 3, 2020

⌛ Testing commit 182133f with merge a0c61a9...

@bors
Copy link
Contributor

bors commented May 4, 2020

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

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label May 4, 2020
@bors bors merged commit a0c61a9 into rust-lang:master May 4, 2020
//~^ skipping const checks
//~| it is undefined behavior to use this value
//~^ ERROR it is undefined behavior to use this value
//~| NOTE encountered a reference pointing to a static variable
Copy link
Member Author

Choose a reason for hiding this comment

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

Another curious thing about diagnostic UI tests: looks like NOTE annotations match what the rustc API calls "labels". Do they also match what the rustc API calls "note"?

@RalfJung RalfJung deleted the miri-unleash-the-gates branch May 4, 2020 08:29
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.

Miri does not get entirely unleashed
5 participants