-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for unsafe operations in const fn #55607
Comments
Also cc @rust-lang/lang @RalfJung |
Details can be found via rust-lang/const-eval#14 the TLDR is that if we allow e.g. A prominent example is |
To elaborate on what @oli-obk said, imagine someone wrote const fn totally_safe_fn(x: &i32) {
unsafe { transmute::<&i32, usize>(x) / 2 }
} How do we communicate and teach that this is NOT okay? As usual there is a proof obligation that the unsafety is properly encapsulated within this safe function; it's just that adding |
Me and @oli-obk briefly discussed the matter further on Discord.
With this said, I think we can / should do the following:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@rfcbot merge I propose that we extend the stable
The points 1-2 are very conservative Among other things we will not allow (as noted in the issue description):
The implementation and tests for it is pending in #55635. |
Team member @Centril has proposed to merge this. The next step is review by the rest of the tagged teams:
Concerns:
Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
So what is this allowing? If You mentioned The way I see it, we have a (non-critical) hole in our safety checks: The following code should not be accepted in libcore: pub fn new_unchecked_safe(ptr: *mut T) -> Self {
NonNull { pointer: NonZero(ptr as _) }
} This is calling a constructor of a I think one consequence of doing that first will be that this proposal is useless, right? To make this useful, we would have to say that we also allow constructing |
@Centril your list does not include "taking references to fields of a packed struct", but I assume that also won't be allowed in Is there anything else that |
that is the intention. The disallowed list is by definition not exhaustive, because we are whitelisting allowed behavior, and thus don't really care about "forbidding" things. I added references to fields of packed structs to the list though, good to keep it as complete as we can |
I sort of implicitly assumed since that is the only stable
We discussed this further on Discord. The conclusion was that we should make construction of |
That wasn't clear from reading the description here. So the take-away from the Discord discussion is that this PR allows two kinds of unsafe operations in "min const fn":
The latter on its own gives no additional power because the functions thus called would be subject to the same restriction. The former, however, is already allowed because we forgot to account for such types to be unsafe to construct... Overall then this allows |
This might also be a good time to consider if we ever want to perform the kind of "validity check on every use" that miri does: Whenever data is I think we want this check, the question is just whether we are willing to pay the performance price this will incur. |
Such a check would be backwards incompatible: const F: Option<NonNull<i32>> = Some(unsafe { NonNull::new_unchecked(std::ptr::null_mut()) }); works on stable since 1.25 so it even predates miri |
We could at least lint cases like that, since they're abusing UB. |
@oli-obk We don't usually promise backwards compatibility for unsound code. If you write the same code outside |
@RalfJung is technically right I think. However, a crater run might be in order to see what the extent of the breakage might be and what sort of roll out plan we'd like here if any? |
@rfcbot concern unsafe-in-unsafe I don't really have an opinion on whether or not the decision to allow calling unsafe functions inside of other unsafe functions was right or not, but I don't think the behavior should diverge for const fn. If we want to change the behavior of |
I agree that we should aim for consistent behavior. My idea here was that since there's an outstanding RFC in rust-lang/rfcs#2585 to change the behavior of If at the end of reviewing RFC 2585 we decide that we don't want to make any changes to |
@Centril I don't agree that the proposal in this thread would ameliorate anything with regard to RFC 2585, since it applies to only a tiny minority of expressions that would be impacted by the lint proposed there. Even in a state of transition, I think its more important that we should keep orthogonal constructs independent of one another. EDIT: To be clear, I understood your reasoning in the initial proposal (and I understand your most recent post as reiterating the reasoning). I understand, but I don't agree. |
I've changed the proposal accordingly (@rust-lang/lang: point 3. is now stricken and |
@rfbot resolve unsafe-in-unsafe @Centril Thanks. As an anecdote, I was just reading an update about an unrelated issue in which someone asked about how two unrelated language features interact - my answer in brief would be "they don't." It's really nice to maintain this property for simplifying decision making down the road. |
@rfcbot resolve unsafe-in-unsafe |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
(FWIW, I agree with @withoutboats and had considered raising the same objection.) |
Make `const unsafe fn` bodies `unsafe` r? @Centril Updated for tracking issue discussion rust-lang#55607 (comment)
The final comment period, with a disposition to merge, as per the review above, is now complete. |
Filed stabilization PR: #57067 |
Filed reference issue for documentation: rust-lang/reference#482 |
…fn, r=oli-obk Stabilize min_const_unsafe_fn in 1.33 Fixes rust-lang#55607 r? @oli-obk
…fn, r=oli-obk Stabilize min_const_unsafe_fn in 1.33 Fixes rust-lang#55607 r? @oli-obk
This is a tracking issue for the RFC "Const functions and inherent methods" (rust-lang/rfcs#911).
This issue only tracks a subset of the proposal in 911 that we are (hopefully) comfortable with stabilizing. To opt into the minimal subset, use
#![feature(min_const_unsafe_fn)]
. To use the more expansive feature set, you can continue using#![feature(const_fn)]
and other associated feature gates.Currently, while you can write
unsafe {}
inside aconst fn
/unsafe const fn
, it is not possible to actually possible to call any unsafe operations inside the block. This makes it impossible to implement safeconst fn
abstractions such asVec::new
. This issue builds upon #53555 by allowing you to useunsafe
operations insideconst fn
so that we can make more abstractionsconst fn
.Exhaustive list of features supported in
const fn
with#![feature(min_const_unsafe_fn)]
:NonZero
) with#[rustc_layout_scalar_valid_range_start]
becomesunsafe
. This is an internal bug-fix that has no user facing consequences. A motivation is given in Tracking issue for unsafe operations in const fn #55607 (comment) and in Tracking issue for unsafe operations in const fn #55607 (comment).const unsafe fn
functions insideconst fn
functions inside anunsafe { ... }
block.const unsafe fn
functions insideconst unsafe fn
functions.Non-exhaustive lists of things that don't become allowed with
#![feature(min_const_unsafe_fn)]
:Callingconst unsafe fn
functions directly inside otherconst unsafe fn
functions.For example:
We impose this restriction because @RalfJung has noted that this is not a good thing inunsafe fn
andfn
. Thus, for now, we want to avoid making the situation worse inconst unsafe fn
. We can lift the restriction later if we want to.EDIT: This restriction has been removed.
Calling
ptr::read
,mem::transmute
or other functions that can't be written asconst unsafe fn
in user code (see discussion below...).Defererencing raw pointers; Tracked in [tracking issue] dereferencing raw pointers inside constants (const_raw_ptr_deref) #51911.
Union field accesses; Tracked in [tracking issue]
union
field access insideconst fn
#51909.Casting raw pointers to integers
Taking references to fields of packed structs
accessing
extern static
sThings to be done before stabilizing:
min_const_unsafe_fn
feature gate. (Allow callingconst unsafe fn
inconst fn
behind a feature gate #55635)Unresolved questions:
None.
Vocabulary:
cc #24111.
The text was updated successfully, but these errors were encountered: