Skip to content

Strengthening TB so that we can discard SB #573

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
RalfJung opened this issue Jun 9, 2025 · 2 comments
Open

Strengthening TB so that we can discard SB #573

RalfJung opened this issue Jun 9, 2025 · 2 comments
Labels
A-aliasing-model Topic: Related to the aliasing model (e.g. Stacked/Tree Borrows)

Comments

@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2025

We now have SB and TB as two aliasing models with quite different structure. While there's a bunch of questions on which both give the same answer that we may still want to explore (#450, and whether nested references have any aliasing requirements), it'd be good to converge towards a single model on the questions where the two do differ.

One of the biggest differences is that TB manages to get away with giving raw pointers the same tag as their parent pointer. This has multiple nice consequences:

  • Within a function, a let mut x and &raw mut x are allowed to be interleaved arbitrarily. Without this, it is wrong to tell people "if you do not use references (nor Box), you do not have to worry about aliasing". Technically, it is correct to say "if you only use raw pointers, you are good", but most people would not realize that accessing x directly runs afoul of that idea. c2rust had to be specifically adjusted to this SB behavior.
  • Casting a &mut T to a *const T and a *mut T finally gives the same result.
  • On the implementation side, we no longer have to worry about finding all the places where a "safe" point gets turned into a raw pointer, which is quite tricky for Box due to its weird state as a hybrid of primitive type and library type.

@rust-lang/opsem if we manage to otherwise make TB basically as strict as SB, do we have general consensus that having a raw pointer share the tag of its parent reference is the right way forward? My vision here is that instead of 2 fairly different models, we have one model with a bunch of parameters that we can tweak.

The remaining differences I can think of right now are:

  • TB does not track UnsafeCell as precisely as SB. This is currently being mitigated by a Bachelor student in my group.
  • TB allows using &T to access memory outside the T. Such "subobject provenance" could be useful for optimizations so we should not discard it prematurely. It should be fairly easy to add a flag to make this optional.
  • TB does not do implicit writes on &mut retags. Doing such implicit writes has been requested by Nikita so we should not discard this option lightly. It should be easy to add a flag for this but I don't know the consequences, it may well be that this breaks too much code without some of the other quirks of SB. So this is the biggest unknown here and likely the first experiment I would make to make progress here: function-entry retags (and only those!) could do an implicit write.
  • Foreign reads from an &mut freeze it rather than disabling it. That seems fine? I can't think of a good reason why we'd want to force-disable references in this case.
  • Anything else I forgot?
@RalfJung RalfJung added the A-aliasing-model Topic: Related to the aliasing model (e.g. Stacked/Tree Borrows) label Jun 9, 2025
@RalfJung RalfJung changed the title Strenghtening TB so that we can discard SB Strengthening TB so that we can discard SB Jun 9, 2025
@saethlin
Copy link
Member

saethlin commented Jun 9, 2025

TB does not do implicit writes on &mut retags. Doing such implicit writes has been requested by Nikita... ...likely the first experiment I would make to make progress here: function-entry retags (and only those!) could do an implicit write.

Is this in reference to rust-lang/rust#53105? I believe that is the example you are pointing out with function-entry retags, but I'm not sure other scenarios @nikic would have in mind for implicit writes on &mut retags.

@RalfJung
Copy link
Member Author

RalfJung commented Jun 9, 2025

It is in reference to the writeable attribute @nikic has been adding to LLVM and said he'd like to use on references as well. rust-lang/rust#53105 is a example that could be optimized with that attribute.

Within a function, certainly two-phase borrows can not get anything like writeable. We could distinguish regular and two-phase borrows in a function but I'd rather not; the fact that SB does this (since it cannot support two-phase borrows) regularly confuses people.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-aliasing-model Topic: Related to the aliasing model (e.g. Stacked/Tree Borrows)
Projects
None yet
Development

No branches or pull requests

2 participants