Skip to content

Does &[!] have a restriction on its length metadata? #620

Closed

Description

@scottmcm

I think by the "size_of_val needs to not overflow"-motivated rule it arguably doesn't have any range restriction, same as &[()].

Should it require that the length is zero?

Activity

  1. RalfJung commented on Aug 21, 2026

    @RalfJung
    Member

    So what would the general rule be? For &T, if T has unsized tail [U], and if U is uninhabited, then the length must be 0?

    That does seem consistent with the fact that we'd consider &[!; 0] to be valid but &[!; 1] is insta-UB to create.

  2. Jules-Bertholet commented on Aug 24, 2026

    @Jules-Bertholet

    My understanding is that #510 was a stable guarantee of the validity invariant? So any new requirements would be a breaking change.

    (If we are going back on past decisions and making breaking changes, here's another one: we could require that the address part of the pointer plus the length of a T with that metadata can't overflow usize::MAX.)

  3. RalfJung commented on Aug 24, 2026

    @RalfJung
    Member

    My understanding is that #510 was a stable guarantee of the validity invariant? So any new requirements would be a breaking change.

    #510 on its own is not enough, you also need to know how validity acts behind references. Without #414, &[!] "obviously" must have length 0 or else we have UB due to "reference to invalid value". #414 is not yet on a stable branch. So if we wanted I think we could still extent #413 to also account for uninhabited slice tails.

    (If we are going back on past decisions and making breaking changes, here's another one: we could require that the address part of the pointer plus the length of a T with that metadata can't overflow usize::MAX.)

    (Let's take this to Zulip.)

  4. RalfJung commented on Aug 24, 2026

    @RalfJung
    Member

    I have added this to the Reference PR:

    +  For unsized types, this check considers dynamic information from the metadata:
    +  If `T` has an unsized tail of slice type (`[U]`), it is inhabited of the length encoded in the metadata is 0 or if `U` is inhabited.
    

    @rust-lang/opsem what do you think, does this make sense?

  5. inkreasing commented on Aug 24, 2026

    @inkreasing

    I think this wording might be confusing if you consider a type like:

    struct T {
      field1: !,
      field2: [u8],
    }

    Here T has an unsized tail and U = u8 which is inhabited, so T would be inhabited.

  6. RalfJung commented on Aug 24, 2026

    @RalfJung
    Member

    Ah, good point. I guess we need to phrase this as a condition on being uninhabited instead.

    New version:

    For unsized types, this check considers dynamic information from the metadata:
    In particular, if T has an unsized tail of slice type [U], and if U is uninhabited, and if the length encoded in the metadata is non-zero, then T is uninhabited.

  7. Jules-Bertholet commented on Aug 24, 2026

    @Jules-Bertholet

    if the length encoded in the metadata is non-zero, then T is uninhabited.

    That seems to be saying that if any instance of a type T has non-zero metadata, then the type T as a whole is uninhabited.

  8. RalfJung commented on Aug 24, 2026

    @RalfJung
    Member

    It's so much easier to write this out in math than in English, why do we bother with this nonsense. :/

    I changed it to "the pointee is uninhabited". Technically this is a predicate of "pointee type and metadata" now.

  9. RalfJung commented on Aug 26, 2026

    @RalfJung
    Member

    Since I think we effectively left this unresolved in our previous FCP on references to uninhabited types being themselves uninhabited, I propose that for validity of wide references to unsized types, we defined inhabitedness of the unsized tail as follows:

    • dyn Trait inherits the inhabitedness from the actual underlying type encoded in the metadata. In particular, &dyn Send with a vtable for the ! type is invalid as the pointee type is uninhabited.
    • [U] is inhabited if U is inhabited or the length metadata is 0. In particular, &[!] requires the length metadata to be 0.

    @rfcbot fcp merge

  10. rust-rfcbot commented on Aug 26, 2026

    @rust-rfcbot
    Collaborator

    @RalfJung 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!

    See this document for info about what commands tagged team members can give me.

  11. RalfJung commented on Sep 6, 2026

    @RalfJung
    Member

    Looks like we're doing this via joint FCP with t-lang in rust-lang/reference#2337. I'll close this one and carry over the checkmarks.

    @rfcbot fcp cancel

  12. rust-rfcbot commented on Sep 6, 2026

    @rust-rfcbot
    Collaborator

    @RalfJung proposal cancelled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions