Skip to content

Commit 46dd282

Browse files
committed
trait_sel: temporary impl Sized for scalable vecs
Scalable vectors should behave like other value types - being permitted as arguments, locals, return types, etc. This requires that these types be `Sized`, despite not meeting the definition and requirements of `Sized`. `feature(sized_hierarchy)` is being implemented to enable scalable vectors to be non-`const Sized`, but in the mean time, add a builtin impl for scalable vectors. This must be addressed prior to stabilisation.
1 parent f9ec763 commit 46dd282

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

compiler/rustc_middle/src/ty/adt.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
208208
self.is_struct()
209209
}
210210

211+
fn is_scalable_vector(self) -> bool {
212+
self.repr().scalable()
213+
}
214+
211215
fn struct_tail_ty(self, interner: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
212216
Some(interner.type_of(self.non_enum_variant().tail_opt()?.did))
213217
}

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,9 +1834,12 @@ impl<'tcx> Ty<'tcx> {
18341834

18351835
ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness)),
18361836

1837-
ty::Adt(def, args) => def
1838-
.sizedness_constraint(tcx, sizedness)
1839-
.is_none_or(|ty| ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness)),
1837+
ty::Adt(def, args) => {
1838+
def.repr().scalable() // see comment on `sizedness_conditions`
1839+
|| def.sizedness_constraint(tcx, sizedness).is_none_or(|ty| {
1840+
ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness)
1841+
})
1842+
}
18401843

18411844
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false,
18421845

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,19 @@ where
174174
// "best effort" optimization and `{meta,pointee,}sized_constraint` may return `Some`,
175175
// even if the ADT is {meta,pointee,}sized for all possible args.
176176
ty::Adt(def, args) => {
177+
// FIXME(repr_scalable): Scalable vectors aren't actually `Sized`. They will be
178+
// non-const `Sized` after the `sized_hierarchy` feature is implemented, but until
179+
// then need to act like `Sized` types - either by forcing it in the trait solver,
180+
// as below, or by omitting the `Sized` constraints in the first place. Omitting the
181+
// constraints would require many small changes throughout the compiler and in some
182+
// cases would not be trivially limited to only the `repr(scalable)` types due
183+
// to inference variables, etc. When `sized_hierarchy` is fully implemented, this
184+
// line will be required anyway and will be correct, just that in the host effect
185+
// builtin impl for sizedness, it won't be `const Sized`.
186+
if def.is_scalable_vector() {
187+
return Ok(ty::Binder::dummy(vec![]));
188+
}
189+
177190
if let Some(crit) = def.sizedness_constraint(ecx.cx(), sizedness) {
178191
Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args)]))
179192
} else {

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,6 +2148,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
21482148
ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])),
21492149

21502150
ty::Adt(def, args) => {
2151+
// FIXME(repr_scalable): Scalable vectors aren't actually `Sized`. They will be
2152+
// non-const `Sized` after the `sized_hierarchy` feature is implemented, but until
2153+
// then need to act like `Sized` types - either by forcing it in the trait solver,
2154+
// as below, or by omitting the `Sized` constraints in the first place. Omitting the
2155+
// constraints would require many small changes throughout the compiler and in some
2156+
// cases would not be trivially limited to only the `repr(scalable)` types due
2157+
// to inference variables, etc. When `sized_hierarchy` is fully implemented, this
2158+
// line will be required anyway and will be correct, just that in the host effect
2159+
// builtin impl for sizedness, it won't be `const Sized`.
2160+
if def.repr().scalable() {
2161+
return Where(ty::Binder::dummy(Vec::new()));
2162+
}
2163+
21512164
if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) {
21522165
// (*) binder moved here
21532166
Where(obligation.predicate.rebind(vec![crit.instantiate(self.tcx(), args)]))

compiler/rustc_type_ir/src/inherent.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,8 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
597597

598598
fn is_struct(self) -> bool;
599599

600+
fn is_scalable_vector(self) -> bool;
601+
600602
/// Returns the type of the struct tail.
601603
///
602604
/// Expects the `AdtDef` to be a struct. If it is not, then this will panic.

0 commit comments

Comments
 (0)