mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
relax adt unsizing requirements
This commit is contained in:
parent
120b2a704a
commit
50e394a05e
@ -707,6 +707,18 @@ impl<T: Idx> GrowableBitSet<T> {
|
|||||||
self.bit_set.insert(elem)
|
self.bit_set.insert(elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the set has changed.
|
||||||
|
#[inline]
|
||||||
|
pub fn remove(&mut self, elem: T) -> bool {
|
||||||
|
self.ensure(elem.index() + 1);
|
||||||
|
self.bit_set.remove(elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.bit_set.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains(&self, elem: T) -> bool {
|
pub fn contains(&self, elem: T) -> bool {
|
||||||
let (word_index, mask) = word_index_and_mask(elem);
|
let (word_index, mask) = word_index_and_mask(elem);
|
||||||
|
@ -829,16 +829,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let tail_field_ty = tcx.type_of(tail_field.did);
|
let tail_field_ty = tcx.type_of(tail_field.did);
|
||||||
|
|
||||||
let mut unsizing_params = GrowableBitSet::new_empty();
|
let mut unsizing_params = GrowableBitSet::new_empty();
|
||||||
let mut found = false;
|
|
||||||
for arg in tail_field_ty.walk() {
|
for arg in tail_field_ty.walk() {
|
||||||
if let Some(i) = maybe_unsizing_param_idx(arg) {
|
if let Some(i) = maybe_unsizing_param_idx(arg) {
|
||||||
unsizing_params.insert(i);
|
unsizing_params.insert(i);
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
|
||||||
return Err(Unimplemented);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure none of the other fields mention the parameters used
|
// Ensure none of the other fields mention the parameters used
|
||||||
// in unsizing.
|
// in unsizing.
|
||||||
@ -848,12 +843,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
for field in prefix_fields {
|
for field in prefix_fields {
|
||||||
for arg in tcx.type_of(field.did).walk() {
|
for arg in tcx.type_of(field.did).walk() {
|
||||||
if let Some(i) = maybe_unsizing_param_idx(arg) {
|
if let Some(i) = maybe_unsizing_param_idx(arg) {
|
||||||
if unsizing_params.contains(i) {
|
unsizing_params.remove(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if unsizing_params.is_empty() {
|
||||||
return Err(Unimplemented);
|
return Err(Unimplemented);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
|
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
|
||||||
let source_tail = tail_field_ty.subst(tcx, substs_a);
|
let source_tail = tail_field_ty.subst(tcx, substs_a);
|
||||||
|
11
src/test/ui/unsized/unchanged-param.rs
Normal file
11
src/test/ui/unsized/unchanged-param.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// run-pass
|
||||||
|
// Test that we allow unsizing even if there is an unchanged param in the
|
||||||
|
// field getting unsized.
|
||||||
|
struct A<T, U: ?Sized + 'static>(T, B<T, U>);
|
||||||
|
struct B<T, U: ?Sized>(T, U);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: A<[u32; 1], [u32; 1]> = A([0; 1], B([0; 1], [0; 1]));
|
||||||
|
let y: &A<[u32; 1], [u32]> = &x;
|
||||||
|
assert_eq!(y.1.1.len(), 1);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user