7
7
//! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
8
8
//! contain revealed `impl Trait` values).
9
9
10
+ use crate::type_check::constraint_conversion::ConstraintConversion;
10
11
use rustc_index::vec::Idx;
11
12
use rustc_infer::infer::LateBoundRegionConversionTime;
12
13
use rustc_middle::mir::*;
13
- use rustc_middle::traits::ObligationCause;
14
- use rustc_middle::ty::{self, Ty};
14
+ use rustc_middle::ty::Ty;
15
15
use rustc_span::Span;
16
- use rustc_trait_selection::traits::query::normalize::AtExt;
16
+ use rustc_span::DUMMY_SP;
17
+ use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
18
+ use rustc_trait_selection::traits::query::Fallible;
19
+ use type_op::TypeOpOutput;
17
20
18
21
use crate::universal_regions::UniversalRegions;
19
22
@@ -30,6 +33,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
30
33
let (&normalized_output_ty, normalized_input_tys) =
31
34
normalized_inputs_and_output.split_last().unwrap();
32
35
36
+ debug!(?normalized_output_ty);
37
+ debug!(?normalized_input_tys);
38
+
33
39
let mir_def_id = body.source.def_id().expect_local();
34
40
35
41
// If the user explicitly annotated the input types, extract
@@ -75,10 +81,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
75
81
.delay_span_bug(body.span, "found more normalized_input_ty than local_decls");
76
82
break;
77
83
}
84
+
78
85
// In MIR, argument N is stored in local N+1.
79
86
let local = Local::new(argument_index + 1);
80
87
81
88
let mir_input_ty = body.local_decls[local].ty;
89
+
82
90
let mir_input_span = body.local_decls[local].source_info.span;
83
91
self.equate_normalized_input_or_output(
84
92
normalized_input_ty,
@@ -100,6 +108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
100
108
// If the user explicitly annotated the input types, enforce those.
101
109
let user_provided_input_ty =
102
110
self.normalize(user_provided_input_ty, Locations::All(mir_input_span));
111
+
103
112
self.equate_normalized_input_or_output(
104
113
user_provided_input_ty,
105
114
mir_input_ty,
@@ -167,30 +176,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
167
176
// `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd
168
177
// like to normalize *before* inserting into `local_decls`, but
169
178
// doing so ends up causing some other trouble.
170
- let b = match self
171
- .infcx
172
- .at(&ObligationCause::dummy(), ty::ParamEnv::empty())
173
- .normalize(b)
174
- {
175
- Ok(n) => {
176
- debug!("equate_inputs_and_outputs: {:?}", n);
177
- if n.obligations.iter().all(|o| {
178
- matches!(
179
- o.predicate.kind().skip_binder(),
180
- ty::PredicateKind::RegionOutlives(_)
181
- | ty::PredicateKind::TypeOutlives(_)
182
- )
183
- }) {
184
- n.value
185
- } else {
186
- b
187
- }
188
- }
179
+ let b = match self.normalize_and_add_constraints(b) {
180
+ Ok(n) => n,
189
181
Err(_) => {
190
182
debug!("equate_inputs_and_outputs: NoSolution");
191
183
b
192
184
}
193
185
};
186
+
194
187
// Note: if we have to introduce new placeholders during normalization above, then we won't have
195
188
// added those universes to the universe info, which we would want in `relate_tys`.
196
189
if let Err(terr) =
@@ -207,4 +200,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
207
200
}
208
201
}
209
202
}
203
+
204
+ pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible<Ty<'tcx>> {
205
+ let TypeOpOutput { output: norm_ty, constraints, .. } =
206
+ self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?;
207
+
208
+ debug!("{:?} normalized to {:?}", t, norm_ty);
209
+
210
+ for data in constraints.into_iter().collect::<Vec<_>>() {
211
+ ConstraintConversion::new(
212
+ self.infcx,
213
+ &self.borrowck_context.universal_regions,
214
+ &self.region_bound_pairs,
215
+ Some(self.implicit_region_bound),
216
+ self.param_env,
217
+ Locations::All(DUMMY_SP),
218
+ ConstraintCategory::Internal,
219
+ &mut self.borrowck_context.constraints,
220
+ )
221
+ .convert_all(&*data);
222
+ }
223
+
224
+ Ok(norm_ty)
225
+ }
210
226
}
0 commit comments