Skip to content

add const_leak and reject interning non-leaked const_allocate ptrs #143595

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fee1-dead
Copy link
Member

@fee1-dead fee1-dead commented Jul 7, 2025

Implements as discussed on Zulip: #t-compiler/const-eval > const heap

r? @rust-lang/wg-const-eval

Fixes #129233

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 7, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 7, 2025

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

@fee1-dead fee1-dead force-pushed the push-sylpykzkmynr branch 3 times, most recently from 67537c4 to 911c6a6 Compare July 7, 2025 16:33
@juntyr
Copy link
Contributor

juntyr commented Jul 7, 2025

I'm really excited about this experiment and the movement on const alloc, so thanks for working on it <3

),
};

// If an allocation is created in an another const,
Copy link
Contributor

Choose a reason for hiding this comment

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

For now we could just error on this. I don't think this should really happen. Either you leaked, then you don't have an owned value anymore, or you didn't, then it got an error

@@ -7,5 +7,6 @@ use std::intrinsics;

const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
//~^ error: mutable pointer in final value of constant
//~| error: encountered `const_allocate` pointer in final value that was not leaked
Copy link
Contributor

Choose a reason for hiding this comment

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

We also need a test that only errors with this error message and looks otherwise benign

size,
align,
interpret::MemoryKind::Machine(MemoryKind::Heap),
interpret::MemoryKind::Machine(MemoryKind::HeapLeaked),
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a separate memory kind? I think the interner will be happy with anything that didn't get deallocated

Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to how it interns stack allocations from the trailing expression

@rust-log-analyzer

This comment has been minimized.

return Err(());
};

if matches!(kind, MemoryKind::Machine(x) if x.is_const_heap()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please turn this into an exhaustive match on the base memory kind enum.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this not reusing the may_leak method?

Copy link
Member

Choose a reason for hiding this comment

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

This isn't about leaking though, it's about interning. I don't think it is the same condition as what Miri's leak check needs?

Copy link
Member Author

Choose a reason for hiding this comment

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

We intern stack allocations and those are marked as may_leak = false

Copy link
Member

Choose a reason for hiding this comment

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

Please turn this into an exhaustive match on the base memory kind enum.

I agree with this part though -- we should have a list of that we are allowed to intern. So the trait should be called AllowIntern or so, and it should be defined in intern.rs as that's the one place it is needed (not machine.rs).

kind: MemoryKind<M::MemoryKind>,
new_kind: MemoryKind<M::MemoryKind>,
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
self.reallocate_ptr_inner(
Copy link
Member

Choose a reason for hiding this comment

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

Why does this reallocate? I don't think that is the right semantics. It will be very hard to use this to intern a graph of allocations since you need to mutate the all pointers into the allocation. And it will be impossible to do this in a cyclic graph.

Copy link
Member Author

Choose a reason for hiding this comment

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

It will be very hard to use this to intern a graph of allocations since you need to mutate the all pointers into the allocation.

True. I originally went with a "just change the original memory kind" approach but got really scared by the following lines:

/// The result must be used immediately; it is not allowed to convert
/// the returned data back into a `Pointer` and store that in machine state.
/// (In fact that's not even possible since `M::ProvenanceExtra` is generic and
/// we don't have an operation to turn it back into `M::Provenance`.)
#[inline(always)]
pub fn ptr_get_alloc_id(

Copy link
Member

Choose a reason for hiding this comment

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

Hm, I don't see how that comment would conflict with "change the memory kind"?

Copy link
Member Author

Choose a reason for hiding this comment

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

I made it so that it now makes the allocation global (tcx managed).

@RalfJung
Copy link
Member

RalfJung commented Jul 7, 2025

In terms of naming, I think we said that Box::leak would not be performing this operation, so "leak" seems like a suboptimal choice. Maybe something like "make_global" or "into_static" or so?

The original plan I proposed also makes the allocation immutable when it gets marked as global -- basically, this operation should indicate that you are done preparing this allocation and it is ready to be interned. (We actually intern it later as that's easier, but for the API this does not matter.)

@fee1-dead fee1-dead force-pushed the push-sylpykzkmynr branch 2 times, most recently from aa4e8a9 to a1ef719 Compare July 8, 2025 06:07
Comment on lines +326 to +329
alloc.mutability = Mutability::Not;
let alloc = self.tcx.mk_const_alloc(alloc);
self.tcx.set_alloc_id_memory(alloc_id, alloc);
interp_ok(())
Copy link
Member

Choose a reason for hiding this comment

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

This risks breaking key invariants like "tcx-managed allocations do not have any dangling pointers". So as nice as this is I think it won't work.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm pretty sure both ptr_get_alloc_id and self.memory.alloc_map.remove(&alloc_id) calls above ensure that this allocation is valid, unless you mean that the allocation itself could contain values that are dangling pointers to other stuff?

Copy link
Member

Choose a reason for hiding this comment

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

Yes that's what I mean.

@fee1-dead fee1-dead force-pushed the push-sylpykzkmynr branch from a1ef719 to 575f024 Compare July 8, 2025 06:14
@fee1-dead fee1-dead force-pushed the push-sylpykzkmynr branch from 575f024 to b1cc426 Compare July 8, 2025 06:22
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-compiler Relevant to the compiler team, which will review and decide on the PR/issue. 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.

const_heap feature can be used to leak mutable memory into final value of constant
7 participants