|
8 | 8 | //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
|
9 | 9 | use rustc_data_structures::stack::ensure_sufficient_stack;
|
10 | 10 | use rustc_hir::lang_items::LangItem;
|
11 |
| -use rustc_index::bit_set::GrowableBitSet; |
12 | 11 | use rustc_infer::infer::InferOk;
|
13 | 12 | use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
14 | 13 | use rustc_middle::ty::{
|
15 |
| - self, Binder, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef, |
16 |
| - ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeVisitable, |
| 14 | + self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, |
| 15 | + TraitRef, Ty, TyCtxt, TypeVisitable, |
17 | 16 | };
|
18 | 17 | use rustc_session::config::TraitSolver;
|
19 | 18 | use rustc_span::def_id::DefId;
|
@@ -1064,51 +1063,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
1064 | 1063 |
|
1065 | 1064 | // `Struct<T>` -> `Struct<U>`
|
1066 | 1065 | (&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => {
|
1067 |
| - let maybe_unsizing_param_idx = |arg: GenericArg<'tcx>| match arg.unpack() { |
1068 |
| - GenericArgKind::Type(ty) => match ty.kind() { |
1069 |
| - ty::Param(p) => Some(p.index), |
1070 |
| - _ => None, |
1071 |
| - }, |
1072 |
| - |
1073 |
| - // Lifetimes aren't allowed to change during unsizing. |
1074 |
| - GenericArgKind::Lifetime(_) => None, |
1075 |
| - |
1076 |
| - GenericArgKind::Const(ct) => match ct.kind() { |
1077 |
| - ty::ConstKind::Param(p) => Some(p.index), |
1078 |
| - _ => None, |
1079 |
| - }, |
1080 |
| - }; |
1081 |
| - |
1082 |
| - // FIXME(eddyb) cache this (including computing `unsizing_params`) |
1083 |
| - // by putting it in a query; it would only need the `DefId` as it |
1084 |
| - // looks at declared field types, not anything substituted. |
1085 |
| - |
1086 |
| - // The last field of the structure has to exist and contain type/const parameters. |
1087 |
| - let (tail_field, prefix_fields) = |
1088 |
| - def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?; |
1089 |
| - let tail_field_ty = tcx.bound_type_of(tail_field.did); |
1090 |
| - |
1091 |
| - let mut unsizing_params = GrowableBitSet::new_empty(); |
1092 |
| - for arg in tail_field_ty.0.walk() { |
1093 |
| - if let Some(i) = maybe_unsizing_param_idx(arg) { |
1094 |
| - unsizing_params.insert(i); |
1095 |
| - } |
1096 |
| - } |
1097 |
| - |
1098 |
| - // Ensure none of the other fields mention the parameters used |
1099 |
| - // in unsizing. |
1100 |
| - for field in prefix_fields { |
1101 |
| - for arg in tcx.type_of(field.did).walk() { |
1102 |
| - if let Some(i) = maybe_unsizing_param_idx(arg) { |
1103 |
| - unsizing_params.remove(i); |
1104 |
| - } |
1105 |
| - } |
1106 |
| - } |
1107 |
| - |
| 1066 | + let unsizing_params = tcx.unsizing_params_for_adt(def.did()); |
1108 | 1067 | if unsizing_params.is_empty() {
|
1109 | 1068 | return Err(Unimplemented);
|
1110 | 1069 | }
|
1111 | 1070 |
|
| 1071 | + let tail_field = def |
| 1072 | + .non_enum_variant() |
| 1073 | + .fields |
| 1074 | + .last() |
| 1075 | + .expect("expected unsized ADT to have a tail field"); |
| 1076 | + let tail_field_ty = tcx.bound_type_of(tail_field.did); |
| 1077 | + |
1112 | 1078 | // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
|
1113 | 1079 | // normalizing in the process, since `type_of` returns something directly from
|
1114 | 1080 | // astconv (which means it's un-normalized).
|
|
0 commit comments