Skip to content

Commit 50e394a

Browse files
committed
relax adt unsizing requirements
1 parent 120b2a7 commit 50e394a

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

compiler/rustc_index/src/bit_set.rs

+12
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,18 @@ impl<T: Idx> GrowableBitSet<T> {
707707
self.bit_set.insert(elem)
708708
}
709709

710+
/// Returns `true` if the set has changed.
711+
#[inline]
712+
pub fn remove(&mut self, elem: T) -> bool {
713+
self.ensure(elem.index() + 1);
714+
self.bit_set.remove(elem)
715+
}
716+
717+
#[inline]
718+
pub fn is_empty(&self) -> bool {
719+
self.bit_set.is_empty()
720+
}
721+
710722
#[inline]
711723
pub fn contains(&self, elem: T) -> bool {
712724
let (word_index, mask) = word_index_and_mask(elem);

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

+5-8
Original file line numberDiff line numberDiff line change
@@ -829,16 +829,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
829829
let tail_field_ty = tcx.type_of(tail_field.did);
830830

831831
let mut unsizing_params = GrowableBitSet::new_empty();
832-
let mut found = false;
833832
for arg in tail_field_ty.walk() {
834833
if let Some(i) = maybe_unsizing_param_idx(arg) {
835834
unsizing_params.insert(i);
836-
found = true;
837835
}
838836
}
839-
if !found {
840-
return Err(Unimplemented);
841-
}
842837

843838
// Ensure none of the other fields mention the parameters used
844839
// in unsizing.
@@ -848,13 +843,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
848843
for field in prefix_fields {
849844
for arg in tcx.type_of(field.did).walk() {
850845
if let Some(i) = maybe_unsizing_param_idx(arg) {
851-
if unsizing_params.contains(i) {
852-
return Err(Unimplemented);
853-
}
846+
unsizing_params.remove(i);
854847
}
855848
}
856849
}
857850

851+
if unsizing_params.is_empty() {
852+
return Err(Unimplemented);
853+
}
854+
858855
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
859856
let source_tail = tail_field_ty.subst(tcx, substs_a);
860857
let target_tail = tail_field_ty.subst(tcx, substs_b);
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// run-pass
2+
// Test that we allow unsizing even if there is an unchanged param in the
3+
// field getting unsized.
4+
struct A<T, U: ?Sized + 'static>(T, B<T, U>);
5+
struct B<T, U: ?Sized>(T, U);
6+
7+
fn main() {
8+
let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
9+
let y: &A<[u32; 1], [u32]> = &x;
10+
assert_eq!(y.1.1.len(), 1);
11+
}

0 commit comments

Comments
 (0)