这是indexloc提供的服务,不要输入任何密码
Skip to content

Tracking Issue for Sized Hierarchy #144404

@davidtwco

Description

@davidtwco

This is a tracking issue for the experimental implementation of RFC "Hierarchy of Sized traits" (rust-lang/rfcs#3729).
The feature gate for the issue is #![feature(sized_hierarchy)].

Approved by the language team for experimentation on Zulip.

This feature is part of the "Scalable Vectors" project goal from 2025h1 and 2025h2. It was discussed with the language team in the 2024/11/13 design meeting and the 2025/02/05 design meeting.

About tracking issues

Tracking issues are used to record the overall progress of implementation.

They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Discussion comments will get marked as off-topic or deleted. Repeated discussions on the tracking issue may lead to the tracking issue getting locked.

Steps

  1. Implement non-const parts of RFC (Sized Hierarchy: Part I #137944)
    • Introduces the MetaSized and PointeeSized traits and adds an implicit MetaSized supertrait to all traits by default
      • PointeeSized is a "fake" trait which is stripped out during lowering
    • There's value in this half of the changes, as it unblocks extern type, just not scalable vectors
    • ?Sized can be rewritten to MetaSized over an edition boundary and prohibit that syntax if desired
  2. Add #[rustc_no_implicit_bounds] (add #![rustc_no_implicit_bounds] #142671)
    • Requested by t-types. Useful for type system tests for debugging or simplification.
  3. Investigate relaxing Deref::Target
    • As with any associated type, the default Sized bound of Deref::Target cannot be relaxed backwards compatibly:

      trait Deref {
          type Target: ?Sized;
      }
      
      fn needs_metasized<T: ?Sized>() {}
      fn caller<T: Deref>() -> usize {
          needs_metasized::<<T as Deref>::Target>()
          //~^ error! the trait bound `<T as Deref>::Target: MetaSized` is not satisfied 
      }

      This is a known limitation of the proposal and for most use cases of the new sizedness traits is unlikely to be a major issue

      However, Deref is particularly tricky because in the limited relaxations in the standard library performed so far (because of the use of extern type in a couple places), plenty of code that could have been PointeeSized ended up being MetaSized only because of Deref. It seems unlikely enough that much code is relying solely on Deref::Target's ?Sized bound, so attempt to relax this to find out if it will break any code

    • Currently blocked on hir_analysis: add missing sizedness bounds #142712

    • If this is possible, then revert codegen_llvm: avoid Deref impls w/ extern type #137603

  4. Implement const parts of the RFC sizedness
    • Introduces const Sized and const MetaSized and is necessary to unblock scalable vectors
    • To maintain backwards compatibility:
      • T: const Sized is the default bound
      • Explicitly written Sized is interpreted as const Sized
        • There is no way to write a non-const Sized bound
        • Sized could be rewritten to const Sized in the next edition and then Sized would mean non-const Sized as expected
      • ?Sized is interpreted as const MetaSized
      • Default supertrait is const MetaSized
    • All default bounds would be their strictest possible, making existing code incompatible with non-const Sized types, that isn't ideal, but those scalable vectors are the only intended use for non-const Sized which are niche and localised, so is tolerable
    • Currently blocked waiting on the next solver
      • The only practical way to implement this feature is to have the sizedness traits always be const behind-the-scenes but without the user being able to refer to their constness
      • This requires an a sufficient const traits implementation in both the old and next solvers, and the old solver's implementation is not sufficient
  5. Investigate and implement edition migration
    • This work involves a complicated edition migration, there are two possibilities:
      1. No migration, keep strictest bounds
        • Simplest and most minimal migration leaves the default bounds as the strictest possible bounds (T: const Sized is default, etc.)
        • This isn't ideal but is the default state after a basic implementation of the traits and constness
        • We could stabilise with this if nothing else is possible
      2. Intelligently migrate to T: Sized as the default
        • T: Sized is the default bound in non-const fns, T: (const) Sized is default bound in const fns, remains the default bounds. There is no default supertrait.
        • Automatically add T: const Sized only when the constness is required to maintain backwards compatibility
          • i.e.
            • fn foo<T> { const { size_of::<T>() } } is migrated
            • fn foo<T> { size_of<T>() } is not migrated
          • Similarly for the const MetaSized default supertrait
        • This would be the smoothest migration for users while having optimal bounds in the next edition that allows non-const Sized types to use most existing code
        • This is likely very hard to implement if at all possible
  6. Update RFC following experienced gained with experimentation and discuss with t-lang
  7. Wait on stabilisation of prerequisites (i.e. const traits)
  8. Adjust documentation (see instructions on rustc-dev-guide)
  9. Style updates for any new syntax (nightly-style-procedure)
    • Style team decision on new formatting
    • Formatting for new syntax has been added to the Style Guide
    • (non-blocking) Formatting has been implemented in rustfmt
  10. Stabilization PR (see instructions on rustc-dev-guide)

Unresolved Questions

  • What names should be used for the traits?

Implementation history

Known issues

Sub-issues

Metadata

Metadata

Assignees

Labels

B-experimentalBlocker: In-tree experiment; RFC pending, not yet approved or unneeded (requires FCP to stabilize).C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-sized_hierarchy`#![feature(sized_hierarchy)]`S-tracking-impl-incompleteStatus: The implementation is incomplete.T-langRelevant to the language team

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions