|
1 |
| -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; |
| 1 | +use rustc_data_structures::fx::FxIndexMap; |
2 | 2 | use rustc_errors::ErrorGuaranteed;
|
3 | 3 | use rustc_hir::def::DefKind;
|
4 | 4 | use rustc_hir::def_id::LocalDefId;
|
5 | 5 | use rustc_hir::OpaqueTyOrigin;
|
6 |
| -use rustc_infer::infer::InferCtxt; |
7 | 6 | use rustc_infer::infer::TyCtxtInferExt as _;
|
| 7 | +use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; |
8 | 8 | use rustc_infer::traits::{Obligation, ObligationCause};
|
9 | 9 | use rustc_middle::traits::DefiningAnchor;
|
10 | 10 | use rustc_middle::ty::visit::TypeVisitableExt;
|
@@ -66,85 +66,48 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
66 | 66 | ) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
|
67 | 67 | let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
|
68 | 68 |
|
69 |
| - let member_constraints: FxIndexMap<_, _> = self |
70 |
| - .member_constraints |
71 |
| - .all_indices() |
72 |
| - .map(|ci| (self.member_constraints[ci].key, ci)) |
73 |
| - .collect(); |
74 |
| - debug!(?member_constraints); |
75 |
| - |
76 | 69 | for (opaque_type_key, concrete_type) in opaque_ty_decls {
|
77 |
| - let args = opaque_type_key.args; |
78 |
| - debug!(?concrete_type, ?args); |
| 70 | + debug!(?opaque_type_key, ?concrete_type); |
79 | 71 |
|
80 |
| - let mut subst_regions = vec![self.universal_regions.fr_static]; |
| 72 | + let mut arg_regions: Vec<(ty::RegionVid, ty::Region<'_>)> = |
| 73 | + vec![(self.universal_regions.fr_static, infcx.tcx.lifetimes.re_static)]; |
81 | 74 |
|
82 |
| - let to_universal_region = |vid, subst_regions: &mut Vec<_>| { |
83 |
| - trace!(?vid); |
84 |
| - let scc = self.constraint_sccs.scc(vid); |
85 |
| - trace!(?scc); |
86 |
| - match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| { |
87 |
| - self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?) |
88 |
| - }) { |
89 |
| - Some(region) => { |
90 |
| - let vid = self.universal_regions.to_region_vid(region); |
91 |
| - subst_regions.push(vid); |
92 |
| - region |
| 75 | + let opaque_type_key = |
| 76 | + opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |region| { |
| 77 | + let scc = self.constraint_sccs.scc(self.to_region_vid(region)); |
| 78 | + let vid = self.scc_representatives[scc]; |
| 79 | + let named = match self.definitions[vid].origin { |
| 80 | + NllRegionVariableOrigin::FreeRegion => self.definitions[vid].external_name, |
| 81 | + NllRegionVariableOrigin::Placeholder(placeholder) => { |
| 82 | + Some(ty::Region::new_placeholder(infcx.tcx, placeholder)) |
| 83 | + } |
| 84 | + NllRegionVariableOrigin::Existential { .. } => None, |
93 | 85 | }
|
94 |
| - None => { |
95 |
| - subst_regions.push(vid); |
| 86 | + .unwrap_or_else(|| { |
96 | 87 | ty::Region::new_error_with_message(
|
97 | 88 | infcx.tcx,
|
98 | 89 | concrete_type.span,
|
99 | 90 | "opaque type with non-universal region args",
|
100 | 91 | )
|
101 |
| - } |
102 |
| - } |
103 |
| - }; |
| 92 | + }); |
104 | 93 |
|
105 |
| - // Start by inserting universal regions from the member_constraint choice regions. |
106 |
| - // This will ensure they get precedence when folding the regions in the concrete type. |
107 |
| - if let Some(&ci) = member_constraints.get(&opaque_type_key) { |
108 |
| - for &vid in self.member_constraints.choice_regions(ci) { |
109 |
| - to_universal_region(vid, &mut subst_regions); |
110 |
| - } |
111 |
| - } |
112 |
| - debug!(?subst_regions); |
113 |
| - |
114 |
| - // Next, insert universal regions from args, so we can translate regions that appear |
115 |
| - // in them but are not subject to member constraints, for instance closure args. |
116 |
| - let universal_args = infcx.tcx.fold_regions(args, |region, _| { |
117 |
| - if let ty::RePlaceholder(..) = region.kind() { |
118 |
| - // Higher kinded regions don't need remapping, they don't refer to anything outside of this the args. |
119 |
| - return region; |
120 |
| - } |
| 94 | + arg_regions.push((vid, named)); |
| 95 | + named |
| 96 | + }); |
| 97 | + debug!(?opaque_type_key, ?arg_regions); |
| 98 | + |
| 99 | + let concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| { |
121 | 100 | let vid = self.to_region_vid(region);
|
122 |
| - to_universal_region(vid, &mut subst_regions) |
| 101 | + arg_regions |
| 102 | + .iter() |
| 103 | + .find(|&&(ur_vid, _)| self.eval_equal(vid, ur_vid)) |
| 104 | + .map(|&(_, ur_name)| ur_name) |
| 105 | + .unwrap_or(infcx.tcx.lifetimes.re_erased) |
123 | 106 | });
|
124 |
| - debug!(?universal_args); |
125 |
| - debug!(?subst_regions); |
126 |
| - |
127 |
| - // Deduplicate the set of regions while keeping the chosen order. |
128 |
| - let subst_regions = subst_regions.into_iter().collect::<FxIndexSet<_>>(); |
129 |
| - debug!(?subst_regions); |
130 |
| - |
131 |
| - let universal_concrete_type = |
132 |
| - infcx.tcx.fold_regions(concrete_type, |region, _| match *region { |
133 |
| - ty::ReVar(vid) => subst_regions |
134 |
| - .iter() |
135 |
| - .find(|ur_vid| self.eval_equal(vid, **ur_vid)) |
136 |
| - .and_then(|ur_vid| self.definitions[*ur_vid].external_name) |
137 |
| - .unwrap_or(infcx.tcx.lifetimes.re_erased), |
138 |
| - _ => region, |
139 |
| - }); |
140 |
| - debug!(?universal_concrete_type); |
| 107 | + debug!(?concrete_type); |
141 | 108 |
|
142 |
| - let opaque_type_key = |
143 |
| - OpaqueTypeKey { def_id: opaque_type_key.def_id, args: universal_args }; |
144 |
| - let ty = infcx.infer_opaque_definition_from_instantiation( |
145 |
| - opaque_type_key, |
146 |
| - universal_concrete_type, |
147 |
| - ); |
| 109 | + let ty = |
| 110 | + infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type); |
148 | 111 | // Sometimes two opaque types are the same only after we remap the generic parameters
|
149 | 112 | // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
|
150 | 113 | // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
|
|
0 commit comments