Skip to content

Commit e9e0e7e

Browse files
committed
nll: don't normalize types for implied bounds
We now do it automatically inside implied_outlives_bounds query.
1 parent ba76f10 commit e9e0e7e

File tree

4 files changed

+39
-117
lines changed

4 files changed

+39
-117
lines changed

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+18-86
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_infer::infer::InferCtxt;
88
use rustc_middle::mir::ConstraintCategory;
99
use rustc_middle::traits::query::OutlivesBound;
1010
use rustc_middle::ty::{self, RegionVid, Ty};
11-
use rustc_span::Span;
1211
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1312
use std::rc::Rc;
1413
use type_op::TypeOpOutput;
@@ -35,16 +34,9 @@ pub(crate) struct UniversalRegionRelations<'tcx> {
3534
inverse_outlives: TransitiveRelation<RegionVid>,
3635
}
3736

38-
/// As part of computing the free region relations, we also have to
39-
/// normalize the input-output types, which we then need later. So we
40-
/// return those. This vector consists of first the input types and
41-
/// then the output type as the last element.
42-
type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
43-
4437
pub(crate) struct CreateResult<'tcx> {
4538
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
4639
pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
47-
pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
4840
}
4941

5042
pub(crate) fn create<'tcx>(
@@ -222,68 +214,27 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
222214
.chain(Some(self.universal_regions.unnormalized_output_ty));
223215

224216
// For each of the input/output types:
225-
// - Normalize the type. This will create some region
226-
// constraints, which we buffer up because we are
227-
// not ready to process them yet.
228-
// - Then compute the implied bounds. This will adjust
217+
// - Compute the implied bounds. This will adjust
229218
// the `region_bound_pairs` and so forth.
230219
// - After this is done, we'll process the constraints, once
231220
// the `relations` is built.
232-
let mut normalized_inputs_and_output =
233-
Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
234-
let mut constraints = vec![];
235-
for ty in unnormalized_input_output_tys {
236-
debug!("build: input_or_output={:?}", ty);
237-
// We add implied bounds from both the unnormalized and normalized ty.
238-
// See issue #87748
239-
let constraints_unnorm = self.add_implied_bounds(ty);
240-
if let Some(c) = constraints_unnorm {
241-
constraints.push(c)
242-
}
243-
let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self
244-
.param_env
245-
.and(type_op::normalize::Normalize::new(ty))
246-
.fully_perform(self.infcx)
247-
.unwrap_or_else(|_| {
248-
let guar = self
249-
.infcx
250-
.tcx
251-
.sess
252-
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
253-
TypeOpOutput {
254-
output: self.infcx.tcx.ty_error(guar),
255-
constraints: None,
256-
error_info: None,
257-
}
258-
});
259-
if let Some(c) = constraints_normalize {
260-
constraints.push(c)
261-
}
262-
263-
// Note: we need this in examples like
264-
// ```
265-
// trait Foo {
266-
// type Bar;
267-
// fn foo(&self) -> &Self::Bar;
268-
// }
269-
// impl Foo for () {
270-
// type Bar = ();
271-
// fn foo(&self) ->&() {}
272-
// }
273-
// ```
274-
// Both &Self::Bar and &() are WF
275-
if ty != norm_ty {
276-
let constraints_norm = self.add_implied_bounds(norm_ty);
277-
if let Some(c) = constraints_norm {
278-
constraints.push(c)
279-
}
280-
}
281-
282-
normalized_inputs_and_output.push(norm_ty);
283-
}
284-
285-
for c in constraints {
286-
self.push_region_constraints(c, span);
221+
let constraint_sets: Vec<_> =
222+
unnormalized_input_output_tys.flat_map(|ty| self.add_implied_bounds(ty)).collect();
223+
224+
// Subtle: We can convert constraints only after the relations are built.
225+
for data in &constraint_sets {
226+
constraint_conversion::ConstraintConversion::new(
227+
self.infcx,
228+
&self.universal_regions,
229+
&self.region_bound_pairs,
230+
self.implicit_region_bound,
231+
self.param_env,
232+
Locations::All(span),
233+
span,
234+
ConstraintCategory::Internal,
235+
&mut self.constraints,
236+
)
237+
.convert_all(data);
287238
}
288239

289240
CreateResult {
@@ -293,28 +244,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
293244
inverse_outlives: self.inverse_outlives.freeze(),
294245
}),
295246
region_bound_pairs: self.region_bound_pairs,
296-
normalized_inputs_and_output,
297247
}
298248
}
299249

300-
#[instrument(skip(self, data), level = "debug")]
301-
fn push_region_constraints(&mut self, data: &QueryRegionConstraints<'tcx>, span: Span) {
302-
debug!("constraints generated: {:#?}", data);
303-
304-
constraint_conversion::ConstraintConversion::new(
305-
self.infcx,
306-
&self.universal_regions,
307-
&self.region_bound_pairs,
308-
self.implicit_region_bound,
309-
self.param_env,
310-
Locations::All(span),
311-
span,
312-
ConstraintCategory::Internal,
313-
&mut self.constraints,
314-
)
315-
.convert_all(data);
316-
}
317-
318250
/// Update the type of a single local, which should represent
319251
/// either the return type of the MIR or one of its arguments. At
320252
/// the same time, compute and add any implied bounds that come

compiler/rustc_borrowck/src/type_check/input_output.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ use rustc_middle::mir::*;
1313
use rustc_middle::ty::{self, Ty};
1414
use rustc_span::Span;
1515

16-
use crate::universal_regions::UniversalRegions;
17-
1816
use super::{Locations, TypeChecker};
1917

2018
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -60,21 +58,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
6058
);
6159
}
6260

63-
#[instrument(skip(self, body, universal_regions), level = "debug")]
64-
pub(super) fn equate_inputs_and_outputs(
65-
&mut self,
66-
body: &Body<'tcx>,
67-
universal_regions: &UniversalRegions<'tcx>,
68-
normalized_inputs_and_output: &[Ty<'tcx>],
69-
) {
70-
let (&normalized_output_ty, normalized_input_tys) =
71-
normalized_inputs_and_output.split_last().unwrap();
61+
#[instrument(skip(self, body), level = "debug")]
62+
pub(super) fn equate_inputs_and_outputs(&mut self, body: &Body<'tcx>) {
63+
let universal_regions = self.borrowck_context.universal_regions;
7264

73-
debug!(?normalized_output_ty);
74-
debug!(?normalized_input_tys);
65+
debug!(?universal_regions.unnormalized_input_tys, ?body.local_decls);
7566

7667
// Equate expected input tys with those in the MIR.
77-
for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() {
68+
for (argument_index, &unnormalized_input_ty) in
69+
universal_regions.unnormalized_input_tys.iter().enumerate()
70+
{
7871
if argument_index + 1 >= body.local_decls.len() {
7972
self.tcx()
8073
.sess
@@ -88,6 +81,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
8881
let mir_input_ty = body.local_decls[local].ty;
8982

9083
let mir_input_span = body.local_decls[local].source_info.span;
84+
let normalized_input_ty =
85+
self.normalize(unnormalized_input_ty, Locations::All(mir_input_span));
9186
self.equate_normalized_input_or_output(
9287
normalized_input_ty,
9388
mir_input_ty,
@@ -125,6 +120,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
125120
// Return types are a bit more complex. They may contain opaque `impl Trait` types.
126121
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
127122
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
123+
let normalized_output_ty =
124+
self.normalize(universal_regions.unnormalized_output_ty, Locations::All(output_span));
128125
if let Err(terr) = self.eq_types(
129126
normalized_output_ty,
130127
mir_output_ty,

compiler/rustc_borrowck/src/type_check/mod.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,14 @@ pub(crate) fn type_check<'mir, 'tcx>(
147147
universe_causes: FxIndexMap::default(),
148148
};
149149

150-
let CreateResult {
151-
universal_region_relations,
152-
region_bound_pairs,
153-
normalized_inputs_and_output,
154-
} = free_region_relations::create(
155-
infcx,
156-
param_env,
157-
implicit_region_bound,
158-
universal_regions,
159-
&mut constraints,
160-
);
161-
162-
debug!(?normalized_inputs_and_output);
150+
let CreateResult { universal_region_relations, region_bound_pairs } =
151+
free_region_relations::create(
152+
infcx,
153+
param_env,
154+
implicit_region_bound,
155+
universal_regions,
156+
&mut constraints,
157+
);
163158

164159
for u in ty::UniverseIndex::ROOT..=infcx.universe() {
165160
constraints.universe_causes.insert(u, UniverseInfo::other());
@@ -194,7 +189,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
194189
checker.typeck_mir(body);
195190
}
196191

197-
checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
192+
checker.equate_inputs_and_outputs(&body);
198193
checker.check_signature_annotation(&body);
199194

200195
liveness::generate(

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,8 @@ fn compare_method_predicate_entailment<'tcx>(
259259
// we have to do this before normalization, since the normalized ty may
260260
// not contain the input parameters. See issue #87748.
261261
wf_tys.extend(trait_sig.inputs_and_output.iter());
262+
262263
let trait_sig = ocx.normalize(&norm_cause, param_env, trait_sig);
263-
// We also have to add the normalized trait signature
264-
// as we don't normalize during implied bounds computation.
265-
wf_tys.extend(trait_sig.inputs_and_output.iter());
266264
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
267265

268266
debug!("compare_impl_method: trait_fty={:?}", trait_fty);

0 commit comments

Comments
 (0)