@@ -823,33 +823,62 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
823
823
} ,
824
824
} ;
825
825
826
+ // FIXME(eddyb) cache this (including computing `unsizing_params`)
827
+ // by putting it in a query; it would only need the `DefId` as it
828
+ // looks at declared field types, not anything substituted.
829
+
826
830
// The last field of the structure has to exist and contain type/const parameters.
827
831
let ( tail_field, prefix_fields) =
828
832
def. non_enum_variant ( ) . fields . split_last ( ) . ok_or ( Unimplemented ) ?;
829
833
let tail_field_ty = tcx. type_of ( tail_field. did ) ;
830
834
831
835
let mut unsizing_params = GrowableBitSet :: new_empty ( ) ;
832
- for arg in tail_field_ty. walk ( ) {
833
- if let Some ( i) = maybe_unsizing_param_idx ( arg) {
834
- unsizing_params. insert ( i) ;
836
+ if tcx. features ( ) . relaxed_struct_unsize {
837
+ for arg in tail_field_ty. walk ( ) {
838
+ if let Some ( i) = maybe_unsizing_param_idx ( arg) {
839
+ unsizing_params. insert ( i) ;
840
+ }
835
841
}
836
- }
837
842
838
- // Ensure none of the other fields mention the parameters used
839
- // in unsizing.
840
- // FIXME(eddyb) cache this (including computing `unsizing_params`)
841
- // by putting it in a query; it would only need the `DefId` as it
842
- // looks at declared field types, not anything substituted.
843
- for field in prefix_fields {
844
- for arg in tcx. type_of ( field. did ) . walk ( ) {
843
+ // Ensure none of the other fields mention the parameters used
844
+ // in unsizing.
845
+ for field in prefix_fields {
846
+ for arg in tcx. type_of ( field. did ) . walk ( ) {
847
+ if let Some ( i) = maybe_unsizing_param_idx ( arg) {
848
+ unsizing_params. remove ( i) ;
849
+ }
850
+ }
851
+ }
852
+
853
+ if unsizing_params. is_empty ( ) {
854
+ return Err ( Unimplemented ) ;
855
+ }
856
+ } else {
857
+ let mut found = false ;
858
+ for arg in tail_field_ty. walk ( ) {
845
859
if let Some ( i) = maybe_unsizing_param_idx ( arg) {
846
- unsizing_params. remove ( i) ;
860
+ unsizing_params. insert ( i) ;
861
+ found = true ;
847
862
}
848
863
}
849
- }
864
+ if !found {
865
+ return Err ( Unimplemented ) ;
866
+ }
850
867
851
- if unsizing_params. is_empty ( ) {
852
- return Err ( Unimplemented ) ;
868
+ // Ensure none of the other fields mention the parameters used
869
+ // in unsizing.
870
+ // FIXME(eddyb) cache this (including computing `unsizing_params`)
871
+ // by putting it in a query; it would only need the `DefId` as it
872
+ // looks at declared field types, not anything substituted.
873
+ for field in prefix_fields {
874
+ for arg in tcx. type_of ( field. did ) . walk ( ) {
875
+ if let Some ( i) = maybe_unsizing_param_idx ( arg) {
876
+ if unsizing_params. contains ( i) {
877
+ return Err ( Unimplemented ) ;
878
+ }
879
+ }
880
+ }
881
+ }
853
882
}
854
883
855
884
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
0 commit comments