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

Tracking issue for const <*const T>::is_null #74939

Open
oli-obk opened this issue Jul 30, 2020 · 5 comments
Open

Tracking issue for const <*const T>::is_null #74939

oli-obk opened this issue Jul 30, 2020 · 5 comments
Labels
A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature.

Comments

@oli-obk
Copy link
Contributor

oli-obk commented Jul 30, 2020

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 for is_null anyway, so that's ok. Thus, we implement is_null as ptr.guaranteed_eq(ptr::null()), which returns true if it's guaranteed that ptr is null, and there are no cases where it will return false where it may be null, but we don't know.

@oli-obk oli-obk added A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. labels Jul 30, 2020
@RalfJung
Copy link
Member

RalfJung commented Aug 7, 2020

and there are no cases where it will return false where it may be null, but we don't know.

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.

@oli-obk
Copy link
Contributor Author

oli-obk commented Aug 10, 2020

So, some examples that we ran reliably check:

  • std::ptr::null::<T>().is_null() will always be true
  • NonZeroUsize::new(x).unwrap().is_null() will always be false
  • `(&x as *const T).is_null() will always be false
  • ((&x as *const T as usize - &x as *const T as usize) as *const T).is_null() will always be true (if you get it or an equivalent to compile)

The problematic case (&x as *const T).offset(496).is_null() will be false, but at runtime could be true. We could set it up so it would be true instead, but then is_null() can return true when at runtime it would return false.

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:

  • use ptr.guaranteed_eq(std::ptr::null()), but then you get false for out of bounds pointers that at runtime are null
  • use !ptr.guaranteed_ne(std::ptr::null()), but then you get true for all out of bounds pointers, even the ones that are not null at runtime.
  • use both variants and assert that they return the same thing.

bors added a commit to rust-lang-ci/rust that referenced this issue Aug 17, 2020
Make `<*const T>::is_null` const fn

r? @RalfJung

cc @rust-lang/wg-const-eval

tracking issue: rust-lang#74939
@josephlr
Copy link
Contributor

  • use both variants and assert that they return the same thing.

As a user, this seems the most natural to me.

  • Integer pointer that's zero => return true
  • Integer pointer that's non-zero => return false
  • Real pointer that's in-bounds => return false
  • Real pointer that's out-of-bounds => panic, could be either true/false at runtime.

In general, panicking when doing something fundamentally non-const a cosnt fn seems fine.

@kupiakos
Copy link
Contributor

Is there anything blocking stabilization of this? This also blocks NonNull::new from stabilization.

@RalfJung
Copy link
Member

RalfJung commented Mar 22, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature.
Projects
None yet
Development

No branches or pull requests

4 participants