-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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 const <*const T>::is_null
#74939
Comments
That's not entirely correct. It will at some point be possible to create out-of-bounds raw pointers in const-eval (it might be possible already with enough hacks, I am not sure). Once that is possible, a pointer could be offset enough such that it is NULL at run-time but still non-NULL when checked during CTFE -- we cannot know if out-of-bounds pointers are NULL as that depends on their concrete base address. |
So, some examples that we ran reliably check:
The problematic case Another alternative is to panic if no exact solution is known (this can be done in a way that it compiles away to nothing at runtime) Basically the options are:
|
Make `<*const T>::is_null` const fn r? @RalfJung cc @rust-lang/wg-const-eval tracking issue: rust-lang#74939
As a user, this seems the most natural to me.
In general, panicking when doing something fundamentally non-const a |
Is there anything blocking stabilization of this? This also blocks |
We still need to decide how "maybe null" pointers should be handled, see the discussion above.
|
Given in particular the use of Or of course we could panic and thus abort const-eval. We'll never panic at runtime so this may be acceptable. @rust-lang/wg-const-eval any opinions on this? |
const: make ptr.is_null() stop execution on ambiguity This seems better than saying `false` -- saying `false` is in fact actively unsound if `NonNull` then uses this to permit putting this pointer inside of it, but at runtime it turns out to be null. Part of rust-lang#74939 Cc `@rust-lang/wg-const-eval`
const: make ptr.is_null() stop execution on ambiguity This seems better than saying `false` -- saying `false` is in fact actively unsound if `NonNull` then uses this to permit putting this pointer inside of it, but at runtime it turns out to be null. Part of rust-lang#74939 Cc ``@rust-lang/wg-const-eval``
const: make ptr.is_null() stop execution on ambiguity This seems better than saying `false` -- saying `false` is in fact actively unsound if `NonNull` then uses this to permit putting this pointer inside of it, but at runtime it turns out to be null. Part of rust-lang#74939 Cc ```@rust-lang/wg-const-eval```
Rollup merge of rust-lang#130107 - RalfJung:const-ptr-is-null, r=oli-obk const: make ptr.is_null() stop execution on ambiguity This seems better than saying `false` -- saying `false` is in fact actively unsound if `NonNull` then uses this to permit putting this pointer inside of it, but at runtime it turns out to be null. Part of rust-lang#74939 Cc ```@rust-lang/wg-const-eval```
move some const fn out of the const_ptr_as_ref feature When a `const fn` is still `#[unstable]`, it should generally use the same feature to track its regular stability and const-stability. Then when that feature moves towards stabilization we can decide whether the const-ness can be stabilized as well, or whether it should be moved into a new feature. Also, functions like `ptr::as_ref` (which returns an `Option<&mut T>`) require `is_null`, which is tricky and blocked on some design concerns (see rust-lang#74939). So move those to the is_null feature gate, as they should be stabilized together with `ptr.is_null()`. Affects rust-lang#91822, rust-lang#122034, rust-lang#75402, rust-lang#74939
move some const fn out of the const_ptr_as_ref feature When a `const fn` is still `#[unstable]`, it should generally use the same feature to track its regular stability and const-stability. Then when that feature moves towards stabilization we can decide whether the const-ness can be stabilized as well, or whether it should be moved into a new feature. Also, functions like `ptr::as_ref` (which returns an `Option<&mut T>`) require `is_null`, which is tricky and blocked on some design concerns (see rust-lang#74939). So move those to the is_null feature gate, as they should be stabilized together with `ptr.is_null()`. Affects rust-lang#91822, rust-lang#122034, rust-lang#75402, rust-lang#74939
Rollup merge of rust-lang#130164 - RalfJung:const_ptr_as_ref, r=dtolnay move some const fn out of the const_ptr_as_ref feature When a `const fn` is still `#[unstable]`, it should generally use the same feature to track its regular stability and const-stability. Then when that feature moves towards stabilization we can decide whether the const-ness can be stabilized as well, or whether it should be moved into a new feature. Also, functions like `ptr::as_ref` (which returns an `Option<&mut T>`) require `is_null`, which is tricky and blocked on some design concerns (see rust-lang#74939). So move those to the is_null feature gate, as they should be stabilized together with `ptr.is_null()`. Affects rust-lang#91822, rust-lang#122034, rust-lang#75402, rust-lang#74939
move some const fn out of the const_ptr_as_ref feature When a `const fn` is still `#[unstable]`, it should generally use the same feature to track its regular stability and const-stability. Then when that feature moves towards stabilization we can decide whether the const-ness can be stabilized as well, or whether it should be moved into a new feature. Also, functions like `ptr::as_ref` (which returns an `Option<&mut T>`) require `is_null`, which is tricky and blocked on some design concerns (see #74939). So move those to the is_null feature gate, as they should be stabilized together with `ptr.is_null()`. Affects #91822, #122034, #75402, rust-lang/rust#74939
Stabilization ReportSummaryPointers can be definitely null: std::ptr::null().is_null() // always `true` Or definitely not null: (&x as *const T).is_null() // always `false` Sometimes though, pointers are "maybe null", which is what makes stabilizing (&x as *const T).wrapping_offset(-0x12345).is_null() // who knows? Given that pointer comparison is a deterministic operation, What we're left with then is no option but to abort const-evaluation if Concretely, the supported inputs are:
(also) Stabilize
|
I have updated the tracking issue with all const fn listed under this feature flag. |
@RalfJung I love the idea of making |
We talked about this in today's @rust-lang/libs-api meeting. libs-api would like to largely delegate the pointer-semantics aspects of this to lang (or opsem or whichever is appropriate). The main property we'd like to see preserved is that |
Yes, that is exactly the case.
Indeed, I think that would be a big problem. That's why I made that case into a panic. |
In general, I think it's perfectly reasonable for there to be (uncommon) situations where const eval results in a panic and runtime eval doesn't. (Unlike the other way around, or giving different return values, etc.) |
This message has 👍 from all of wg-const eval, so what remains is the lang team. @rust-lang/lang we'd like to make |
My mental model for const eval is that it can sometimes fail to evaluate (panic) in value-dependent ways that are not tracked by the type system. For example, integers created by (exposed) pointers or other things may support a limited set of operations, etc, or (under nightly extensions to const generics) we may wish to distinguish This seems to fit that model fairly well-- do something complex enough in a const fn, and the value you produce may not be usable in all downstream operations, even if the type system would otherwise allow it. Is that a reasonable mental model or am I missing something? If this roughly tracks, I am in favor of exposing Another question: if we do expose |
That sounds right. Note however that there is no UB-free way to turn a pointer into an integer in const eval (unless it was created by casting an integer to a pointer). |
We discussed this in the lang triage meeting today, and are happy with the "compiler error in odd cases" as proposed by the two bullets in #74939 (comment) So let's lang+libs-api stabilize this! @rfcbot fcp merge As I understood the discussion, we liked this for a couple reasons:
|
Team member @scottmcm has proposed to merge this. The next step is review by the rest of the tagged team members:
No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), 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! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
This is tracking
#[feature(const_ptr_is_null)]
.Comparing pointers in const eval is dangerous business.
But checking whether a pointer is the null pointer is actually completely fine, as Rust does not support items being placed at the null address. Any otherwise created null pointers are supposed to return
true
foris_null
anyway, so that's ok. Thus, we implementis_null
asptr.guaranteed_eq(ptr::null())
, which returns true if it's guaranteed thatptr
is null, and there are no cases where it will return false where it may benull
, but we don't know.The text was updated successfully, but these errors were encountered: