-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
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
- Implement non-const parts of RFC (Sized Hierarchy: Part I #137944)
- Introduces the
MetaSizedandPointeeSizedtraits and adds an implicitMetaSizedsupertrait to all traits by defaultPointeeSizedis 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 ?Sizedcan be rewritten toMetaSizedover an edition boundary and prohibit that syntax if desired
- Introduces the
- Add
#[rustc_no_implicit_bounds](add #![rustc_no_implicit_bounds] #142671)- Requested by t-types. Useful for type system tests for debugging or simplification.
- Investigate relaxing
Deref::Target-
As with any associated type, the default
?Sizedbound ofDeref::Targetcannot 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,
Derefis particularly tricky because in the limited relaxations in the standard library performed so far (because of the use ofextern typein a couple places), plenty of code that could have beenPointeeSizedended up beingMetaSizedonly because ofDeref. It seems unlikely enough that much code is relying solely onDeref::Target's?Sizedbound, so attempt to relax this to find out if it will break any code -
Being tested in [EXPERIMENT] libs: relax
Deref::Target#148102 -
If this is possible, then revert codegen_llvm: avoid
Derefimpls w/ extern type #137603
-
- Implement const parts of the RFC sizedness
- Introduces
const Sizedandconst MetaSizedand is necessary to unblock scalable vectors - To maintain backwards compatibility:
T: const Sizedis the default bound- Explicitly written
Sizedis interpreted asconst Sized- There is no way to write a non-const
Sizedbound Sizedcould be rewritten toconst Sizedin the next edition and thenSizedwould mean non-const Sizedas expected
- There is no way to write a non-const
?Sizedis interpreted asconst MetaSized- Default supertrait is
const MetaSized
- All default bounds would be their strictest possible, making existing code incompatible with non-
const Sizedtypes, that isn't ideal, but those scalable vectors are the only intended use for non-const Sizedwhich 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
- Introduces
- Investigate and implement edition migration
- This work involves a complicated edition migration, there are two possibilities:
- No migration, keep strictest bounds
- Simplest and most minimal migration leaves the default bounds as the strictest possible bounds (
T: const Sizedis 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
- Simplest and most minimal migration leaves the default bounds as the strictest possible bounds (
- Intelligently migrate to
T: Sizedas the defaultT: Sizedis the default bound in non-const fns,T: (const) Sizedis default bound in const fns, remains the default bounds. There is no default supertrait.- Automatically add
T: const Sizedonly when the constness is required to maintain backwards compatibility- i.e.
fn foo<T> { const { size_of::<T>() } }is migratedfn foo<T> { size_of<T>() }is not migrated
- Similarly for the
const MetaSizeddefault supertrait
- i.e.
- This would be the smoothest migration for users while having optimal bounds in the next edition that allows non-
const Sizedtypes to use most existing code - This is likely very hard to implement if at all possible
- No migration, keep strictest bounds
- This work involves a complicated edition migration, there are two possibilities:
- Update RFC following experienced gained with experimentation and discuss with t-lang
- Wait on stabilisation of prerequisites (i.e. const traits)
- Adjust documentation (see instructions on rustc-dev-guide)
- 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
- Stabilization PR (see instructions on rustc-dev-guide)
Unresolved Questions
- What names should be used for the traits?
Implementation history
- Sized Hierarchy: Part I #137944
- Initial implementation of the non-const parts of the Sized Hierarchy RFC
- Approved to be merged by t-types in FCP at Sized Hierarchy: Part I #137944 (comment)
- Pre-requisites:
- tests: use minicore more #137599
- type_ir: remove redundant part of comment #137600
- ssa/mono: deduplicate
type_has_metadata#137601 - feature: fix typo in attribute description #137602
- codegen_llvm: avoid
Derefimpls w/ extern type #137603 - trait_sel: resolve vars in host effects #137604
- add a "future" edition #137606
- hir_analysis: skip self type of host effect preds in variances_of #137613
- re-use
Sizedfast-path #139577 - trait_sel: deep reject
match_normalize_trait_ref#140978
- add #![rustc_no_implicit_bounds] #142671
- Follow-up requested by t-types to simplify tests that would benefit from not having any default bounds
- hir_analysis: prohibit
dyn PointeeSized#143104 - trait_sel:
MetaSizedalways holds temporarily #144016- Temporary fix for where bounds regression in beta+nightly #143992 while a proper fix is implemented
- More robustly deal with relaxed bounds and improve their diagnostics #142693
- prefer alias candidates for sizedness + auto trait goals #144064
- Proper fix for trait_sel:
MetaSizedalways holds temporarily #144016, and pre-requisite to hir_analysis: add missing sizedness bounds #142712
- Proper fix for trait_sel:
- hir_analysis: add missing sizedness bounds #142712
- Fixes elaboration of item bounds on associated types to include sizedness
- Necessary to be able to experiment with relaxing
Deref::Target
- Do not consider a
T: !Sizedcandidate to satisfy aT: !MetaSizedobligation. #145537- Fixing a bug with
feature(negative_bounds)that meant!Sizedcould prove!MetaSized
- Fixing a bug with
- [EXPERIMENT] libs: relax
Deref::Target#148102- Testing whether
Deref::Targetcan be relaxed
- Testing whether
Known issues
- Regression: overflow evaluating X: MetaSized #143830
- This is known breakage that was accepted by the types team in Sized Hierarchy: Part I #137944 (comment)
- It is fixed in the next solver
Sub-issues
Metadata
Metadata
Assignees
Labels
Type
Projects
Status