Skip to content

core: Add core::ffi::c_intptr_t and core::ffi::c_uintptr_t#156626

Open
lygstate wants to merge 2 commits into
rust-lang:mainfrom
lygstate:c_ffi_new_type
Open

core: Add core::ffi::c_intptr_t and core::ffi::c_uintptr_t#156626
lygstate wants to merge 2 commits into
rust-lang:mainfrom
lygstate:c_ffi_new_type

Conversation

@lygstate

@lygstate lygstate commented May 15, 2026

Copy link
Copy Markdown
Contributor

View all comments

In summary, I want to give the following conclusion:

  1. usize, isize should be the same with C23's size_t ssize_t as @tgross35 said at comment.
    And from https://internals.rust-lang.org/t/pre-rfc-usize-semantics/19444/156

  2. (c_intptr_t, c_uintptr_t) be defined as one alias of (i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128) in core::ffi is enough.

  3. c_ptrdiff_t is very special, can be either ssize_t or intptr_t

  4. Add function expose_addr to pointer Trait for retrieve the raw integer value for the tagged-pointer.

impl *const T {
    fn addr(self) -> usize;
    fn expose_addr (self) -> c_uintptr_t;
    // ...
}

fn cast_between_pointer_uintptr() {
    let my_val = 42;
    let ptr = &my_val as *const i32;

    // Convert pointer to isize
    let tagged_ptr_integer = ptr as c_uintptr_t;
    let ptr2 = tagged_ptr_integer as *const i32;
}

maybe the as operator is enough.
And avoid cast pointer from/to usize/isize by stablize Tracking Issue for strict_provenance_lints

  1. Add a function to convert c_uintptr_t, c_intptr_t back to pointer. Maybe the as operator is enough.

  2. ptraddr_t is just a alias of usize, do not know if this need to be in core::ffi, not part of C standard yet, but Rust is a language for safety, add it into core::ffi seems make sense.

  3. The usage of usize/isize is guard by strict_provenance

Tracking issue: #88345

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 15, 2026
@rustbot

rustbot commented May 15, 2026

Copy link
Copy Markdown
Collaborator

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @scottmcm, libs
  • @scottmcm, libs expanded to 8 candidates

@rust-log-analyzer

This comment has been minimized.

@tgross35

Copy link
Copy Markdown
Contributor

There are some unresolved questions there that unfortunately haven't made much progress. I'm not sure it's worth adding more types without having a better story there.

@lygstate

Copy link
Copy Markdown
Contributor Author

There are some unresolved questions there that unfortunately haven't made much progress. I'm not sure it's worth adding more types without having a better story there.

libc is looking for release 1.0 I think it's time to resolve those questions. What's the questions comes from, can you give me the link.

@tgross35

Copy link
Copy Markdown
Contributor

libc is looking for release 1.0 I think it's time to resolve those questions. What's the questions comes from, can you give me the link.

As far as libc 1.0 is concerned, the only thing I'd like is for the lang team to say that size_t is always usize, if that's something we can rely on, because then we can delete the size_t alias. Anything else is not blocking, we can update aliases if/when things stabilize.

Info is scattered, see discussion around #88345 (comment) https://internals.rust-lang.org/t/pre-rfc-usize-semantics/19444/22, https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/Compat.20with.20size_t.2C.20ptrdiff_t.2C.20intptr_t.2C.20fnptr-sized.20int/with/547982505, and a few other places on Zulip.

Comment thread library/core/src/ffi/primitives.rs Outdated
@arichardson

Copy link
Copy Markdown
Contributor

CC: @xdoardo

@tgross35

Copy link
Copy Markdown
Contributor

For anybody who has opinions here about CHERI or otherwise, it would be good to hop in to the ongoing discussion at #t-lang > Compat with size_t, ptrdiff_t, intptr_t, fnptr-sized int.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lygstate lygstate force-pushed the c_ffi_new_type branch 2 times, most recently from 6487fd6 to 496d959 Compare May 17, 2026 21:26
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Comment thread library/core/src/ffi/primitives.rs
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Tracking issue: rust-lang#88345

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
@rust-log-analyzer

This comment has been minimized.

@lygstate lygstate force-pushed the c_ffi_new_type branch 2 times, most recently from ca30dca to 65b4266 Compare May 18, 2026 10:40
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

…t detail

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>

@arichardson arichardson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for this update, I like the transparent struct approach.

View changes since this review

assert_eq!(core::mem::size_of::<c_intptr_t>(), core::mem::size_of::<*const ()>());
assert_eq!(core::mem::size_of::<c_uintptr_t>(), core::mem::size_of::<*const ()>());

let ptr = core::ptr::with_exposed_provenance(16_usize);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
let ptr = core::ptr::with_exposed_provenance(16_usize);
let ptr = core::ptr::without_provenance(16_usize);

#[unstable(feature = "c_size_t", issue = "88345")]
#[rustc_const_unstable(feature = "c_size_t", issue = "88345")]
impl const TaggedPointer for c_uintptr_t {
fn new(ptr: *const ()) -> Self {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it would make a lot of sense to add a usize/isize constructor as well that creates a without_provenance pointer. This would make it more ergonomic to call APIs that use something like "valid pointer" or magic integer (e.g. -1).

@RalfJung

Copy link
Copy Markdown
Member

(c_intptr_t, c_uintptr_t) be defined as one alias of (i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128) in core::ffi is enough.

So is this a guarantee that it's never (isize, usize)? That seems odd, why exclude that type?

@lygstate

lygstate commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

(c_intptr_t, c_uintptr_t) be defined as one alias of (i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128) in core::ffi is enough.

So is this a guarantee that it's never (isize, usize)? That seems odd, why exclude that type?

Now I realized it, when I create this MR, I just followed the ISO-C; maybe we need introduce something like target_address_width, when target_address_width == target_pointer_width, then c_intptr_t::integer and c_uintptr_t::integer is just an alias of (isze, usize), otherwise it's one alias of (i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128)

@xdoardo

xdoardo commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

maybe we need introduce something like target_address_width, when target_address_width == target_pointer_width

For what it is worth, in the cheri-rust repo we are experimenting with this mechanism too: CHERIoT-Platform/cheri-rust#138. Let me explicitly mention @seharris, who might have interesting comments on this PR.

@rust-bors

rust-bors Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

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

@Mark-Simulacrum

Copy link
Copy Markdown
Member

r? tgross35

I think there's been a bunch of discussion on Zulip and I'm not quite sure what the current state is. I'll move reviewer to you but feel free to re-roll libs or nominate for team(s) -- I suspect we want some kind of approval of the API surface area (libs-api ACP?).

@rustbot rustbot assigned tgross35 and unassigned Mark-Simulacrum Jun 7, 2026
@rustbot

rustbot commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

tgross35 is currently at their maximum review capacity.
They may take a while to respond.

@lygstate

lygstate commented Jun 7, 2026

Copy link
Copy Markdown
Contributor Author

I am watching this, waiting for libs-api ACP, do I need create RFC for this?

/// Target features on bpf.
(unstable, bpf_target_feature, "1.54.0", Some(150247)),
/// Allows using size_t/ssize_t/uintptr_t/intptr_t/ptrdiff_t.
(unstable, c_size_t, "CURRENT_RUSTC_VERSION", Some(88345)),

@programmerjake programmerjake Jun 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if this is a library feature, afaik it doesn't need to be added here

View changes since the review

//! This module is intentionally standalone to facilitate parsing when retrieving
//! core C types.

use crate::mem::{self};

@programmerjake programmerjake Jun 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
use crate::mem::{self};
use crate::mem;

View changes since the review

#[unstable(feature = "c_size_t", issue = "88345")]
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
pub struct c_intptr_t(*const ());

@programmerjake programmerjake Jun 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this definition could have an incorrect ABI on some targets since some targets require integers to be sign/zero-extended to fill a register depending on the type's signedness, but if pointers are smaller than a register there is no way for rustc to know if it should sign or zero-extend.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, pointers are not ABI-compatible with any integer type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh, so this is a ABI break, c_intptr_t must be a integer after-all, uintptr_t is ABI in-compatiable with *const () for FFI passing? This is solely for FFI usage, not for writing code. does this will affect FFI-parameter passing? @arichardson , It's you suggested

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This type should be defined as a newtype around isize on current targets. If we ever have upstream CHERI support, then on that target it should be a newtype around *const (). That's pretty much exactly what clang does as well.

@lygstate lygstate Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh, I see, so for default, c_intptr_t is just a alais of isize? do I need pub struct c_intptr_t(isze);? The previous one should be compatiable with libc, but we would have non-consistence API cross current targets/(CHERI like targets)

@RalfJung RalfJung Jun 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah that's a question for t-libs-api. Should c_intptr_t be an opaque type that can work uniformly across all targets including CHERI, or should it be a type alias that exposes different operations on different targets?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's probably best to summarize the situation and open question(s) in a t-libs-api ACP. That's how the team will take a look and give feedback on the open question(s).

/// For handle interchange of rust `pointer` type and C's `intptr_t` and `uintptr_t` types.
#[unstable(feature = "c_size_t", issue = "88345")]
#[rustc_const_unstable(feature = "c_size_t", issue = "88345")]
pub const trait TaggedPointer {

@programmerjake programmerjake Jun 7, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this trait should probably be sealed

View changes since the review

@scottmcm scottmcm added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. and removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants