Implement the min_const_fn feature gate#53604
Conversation
This comment has been minimized.
This comment has been minimized.
src/libsyntax/feature_gate.rs
Outdated
There was a problem hiding this comment.
We will need to ensure that the standard library has not enabled #![feature(const_fn)]; this includes libstd, liballoc, libcore.
There was a problem hiding this comment.
Well, we will want it for NonZero::new_unchecked, right?
There was a problem hiding this comment.
Hmm... I was hoping on using the stabilization of min_const_fn but exclusion of const_fn from libstd so that standard library functions could be const-ified en masse instead of piecemeal. This kinda relies on not having #![feature(const_fn)] enabled so that accidental things don't happen.
Could we handle new_unchecked through some other internal means instead temporarily?
EDIT: like rustc_const_stable or something...
There was a problem hiding this comment.
I'd say:
const fnwithout#[rustc_const_unstable]is stable if it passesmin_const_fnconst fnnot passingmin_const_fncan be forced stable with#[rustc_const_fn_force_stable]
This way the active feature gates have no influence on stability, but we're checking the right thing and can't accidentally do anything wrong.
There was a problem hiding this comment.
What is const_raw_ptr_deref?
Can't we somehow check unsafety, instead of trying to get an exhaustive list of unsafe behavior?
There was a problem hiding this comment.
If it aint possible to detect this in MIR perhaps do it in HIR instead?
EDIT: Add a test with an empty unsafe { ... } block in it
There was a problem hiding this comment.
AFAIK MIR has some unsafety information; we do some unsafety checks in MIR.
There was a problem hiding this comment.
Done as in, the reference to const_raw_ptr_deref is gone? If not, please mention the filename where that function is defined...^^
There was a problem hiding this comment.
As in there's a test. And const_raw_ptr_deref is a feature gate.
There was a problem hiding this comment.
Oh, I see. That's not clear.^^
But the feature is ruled out independent of whether that gate is set...?
There was a problem hiding this comment.
well... it's additionally prevented in min_const_fn due to its unsafety. The same doesn't hold for casting *const T to usize. I'll add some more sanity checks. This will annoy the heck out of nightly users since they are now getting a lot of messages twice in different wording (already happening with a bunch of things in this PR)
There was a problem hiding this comment.
That's a consequence of doing multiple analyses, right?
I do not think that is the right approach... even if we have separate analyses, we should only call one.
|
Is it really better to have all that code duplicated into a second analysis, than changing the existing analysis to qualify every |
The existing analysis is supposed to be split up into three separate analyses. Me adding a fourth one to be split out in the future would not help the process. |
|
Three?!? I can see that promotion is separate, but other than that everything else should be just "const checking", which should (eventually) be the same for |
The checks for |
There was a problem hiding this comment.
fun side effect: the two cases below which are future compat lints are hard errors inside const fns
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
I specifically do want a test here that ensures that even without access, const fn no_inner_fn_ptr2(x: Hide) { } is banned.
There was a problem hiding this comment.
That requires a lot of code... I'll impl it, but I don't think it's a good addition to rustc
There was a problem hiding this comment.
So you already have the erroring tests:
const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
const fn no_fn_ptrs(_x: fn()) {}This is good, because it leaves open the possibility that this means &dyn const std::fmt::Debug or const fn(); If we didn't reject this, then users could pass in values where you don't have a const implementation of std::fmt::Debug, and so we wouldn't be able to change this in the future. However, as for situations where you have:
struct Hide<'a>(&'a dyn Debug);
const fn foo(_x: Hide) {}... this would only prevent a situation in the future where we decided to split up our nominal type universe into one for the const restriction and one for impure... This seems like a very unlikely future... as such... I think the tests you have currently are sufficient.
So you don't need to implement it.
This comment has been minimized.
This comment has been minimized.
|
Should be fine to merge once the tests pass. :) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@Centril this is ready now I think |
|
So... while I could actually implement a check that validates the MIR of constants in Can we just decide to treat Alternatively I can rewrite the entire |
|
I am perfectly fine with treating |
|
@oli-obk I'm fine with this; I guess T-libs will just be a bit more careful with respect to |
|
@bors r=Centril,varkor |
|
📌 Commit 2839f4f has been approved by |
Implement the `min_const_fn` feature gate cc @RalfJung @eddyb r? @Centril implements the feature gate for #53555 I added a hack so the `const_fn` feature gate also enables the `min_const_fn` feature gate. This ensures that nightly users of `const_fn` don't have to touch their code at all. The `min_const_fn` checks are run first, and if they succeeded, the `const_fn` checks are run additionally to ensure we didn't miss anything.
|
☀️ Test successful - status-appveyor, status-travis |
|
I had this code in a PR I was working on, how should I write this now? impl<T> UnsafeList<T> {
pub const fn new() -> Self {
unsafe {
UnsafeList {
head_tail: NonNull::new_unchecked(1 as _),
head_tail_entry: None
}
}
}
} |
|
Minimal repro on playground: #![feature(staged_api, const_fn)]
use std::ptr::NonNull;
pub struct UnsafeList<T>(NonNull<T>);
impl<T> UnsafeList<T> {
pub const fn new() -> Self {
unsafe {
UnsafeList(NonNull::new_unchecked(1 as _))
}
}
}The only way to get around this is to add an |
|
@jethrogb Is this for a PR to the standard library or the compiler, or is this for code outside of that? |
|
PR for |
|
@jethrogb if |
|
@Centril that is not sufficient. You also need to add an |
|
@jethrogb |
cc @RalfJung @eddyb
r? @Centril
implements the feature gate for #53555
I added a hack so the
const_fnfeature gate also enables themin_const_fnfeature gate. This ensures that nightly users ofconst_fndon't have to touch their code at all.The
min_const_fnchecks are run first, and if they succeeded, theconst_fnchecks are run additionally to ensure we didn't miss anything.