Skip to content

Commit efb171e

Browse files
committed
Auto merge of #98584 - lcnr:region-stuff-more-beans, r=oli-obk
continue nll transition by removing stuff r? `@jackh726` for now building on #98641
2 parents 54f79ba + 9f95c60 commit efb171e

File tree

21 files changed

+111
-1159
lines changed

21 files changed

+111
-1159
lines changed

Diff for: compiler/rustc_infer/src/infer/canonical/query_response.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
128128
let region_constraints = self.with_region_constraints(|region_constraints| {
129129
make_query_region_constraints(
130130
tcx,
131-
region_obligations.iter().map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)),
131+
region_obligations.iter().map(|r_o| (r_o.sup_type, r_o.sub_region)),
132132
region_constraints,
133133
)
134134
});

Diff for: compiler/rustc_infer/src/infer/free_regions.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
//! and use that to decide when one free region outlives another, and so forth.
55
66
use rustc_data_structures::transitive_relation::TransitiveRelation;
7-
use rustc_hir::def_id::DefId;
87
use rustc_middle::ty::{self, Lift, Region, TyCtxt};
98

109
/// Combines a `FreeRegionMap` and a `TyCtxt`.
@@ -14,16 +13,13 @@ use rustc_middle::ty::{self, Lift, Region, TyCtxt};
1413
pub(crate) struct RegionRelations<'a, 'tcx> {
1514
pub tcx: TyCtxt<'tcx>,
1615

17-
/// The context used for debug messages
18-
pub context: DefId,
19-
2016
/// Free-region relationships.
2117
pub free_regions: &'a FreeRegionMap<'tcx>,
2218
}
2319

2420
impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
25-
pub fn new(tcx: TyCtxt<'tcx>, context: DefId, free_regions: &'a FreeRegionMap<'tcx>) -> Self {
26-
Self { tcx, context, free_regions }
21+
pub fn new(tcx: TyCtxt<'tcx>, free_regions: &'a FreeRegionMap<'tcx>) -> Self {
22+
Self { tcx, free_regions }
2723
}
2824

2925
pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> {

Diff for: compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
120120
) -> LexicalRegionResolutions<'tcx> {
121121
let mut var_data = self.construct_var_data(self.tcx());
122122

123-
// Dorky hack to cause `dump_constraints` to only get called
124-
// if debug mode is enabled:
125-
debug!(
126-
"----() End constraint listing (context={:?}) {:?}---",
127-
self.region_rels.context,
128-
self.dump_constraints(self.region_rels)
129-
);
123+
if cfg!(debug_assertions) {
124+
self.dump_constraints();
125+
}
130126

131127
let graph = self.construct_graph();
132128
self.expand_givens(&graph);
@@ -156,8 +152,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
156152
}
157153
}
158154

159-
fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) {
160-
debug!("----() Start constraint listing (context={:?}) ()----", free_regions.context);
155+
#[instrument(level = "debug", skip(self))]
156+
fn dump_constraints(&self) {
161157
for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() {
162158
debug!("Constraint {} => {:?}", idx, constraint);
163159
}

Diff for: compiler/rustc_infer/src/infer/mod.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use rustc_data_structures::sync::Lrc;
1515
use rustc_data_structures::undo_log::Rollback;
1616
use rustc_data_structures::unify as ut;
1717
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
18-
use rustc_hir as hir;
1918
use rustc_hir::def_id::{DefId, LocalDefId};
2019
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
2120
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
@@ -147,7 +146,7 @@ pub struct InferCtxtInner<'tcx> {
147146
/// for each body-id in this map, which will process the
148147
/// obligations within. This is expected to be done 'late enough'
149148
/// that all type inference variables have been bound and so forth.
150-
region_obligations: Vec<(hir::HirId, RegionObligation<'tcx>)>,
149+
region_obligations: Vec<RegionObligation<'tcx>>,
151150

152151
undo_log: InferCtxtUndoLogs<'tcx>,
153152

@@ -171,7 +170,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
171170
}
172171

173172
#[inline]
174-
pub fn region_obligations(&self) -> &[(hir::HirId, RegionObligation<'tcx>)] {
173+
pub fn region_obligations(&self) -> &[RegionObligation<'tcx>] {
175174
&self.region_obligations
176175
}
177176

@@ -1267,7 +1266,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12671266
/// `resolve_vars_if_possible` as well as `fully_resolve`.
12681267
pub fn resolve_regions(
12691268
&self,
1270-
region_context: DefId,
12711269
outlives_env: &OutlivesEnvironment<'tcx>,
12721270
) -> Vec<RegionResolutionError<'tcx>> {
12731271
let (var_infos, data) = {
@@ -1286,8 +1284,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
12861284
.into_infos_and_data()
12871285
};
12881286

1289-
let region_rels =
1290-
&RegionRelations::new(self.tcx, region_context, outlives_env.free_region_map());
1287+
let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map());
12911288

12921289
let (lexical_region_resolutions, errors) =
12931290
lexical_region_resolve::resolve(outlives_env.param_env, region_rels, var_infos, data);
@@ -1302,12 +1299,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13021299
/// result. After this, no more unification operations should be
13031300
/// done -- or the compiler will panic -- but it is legal to use
13041301
/// `resolve_vars_if_possible` as well as `fully_resolve`.
1305-
pub fn resolve_regions_and_report_errors(
1306-
&self,
1307-
region_context: DefId,
1308-
outlives_env: &OutlivesEnvironment<'tcx>,
1309-
) {
1310-
let errors = self.resolve_regions(region_context, outlives_env);
1302+
pub fn resolve_regions_and_report_errors(&self, outlives_env: &OutlivesEnvironment<'tcx>) {
1303+
let errors = self.resolve_regions(outlives_env);
13111304

13121305
if !self.is_tainted_by_errors() {
13131306
// As a heuristic, just skip reporting region errors

Diff for: compiler/rustc_infer/src/infer/outlives/env.rs

+10-78
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::infer::free_regions::FreeRegionMap;
22
use crate::infer::{GenericKind, InferCtxt};
33
use crate::traits::query::OutlivesBound;
4-
use rustc_data_structures::fx::FxHashMap;
5-
use rustc_hir as hir;
64
use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
75

86
use super::explicit_outlives_bounds;
@@ -31,9 +29,7 @@ pub struct OutlivesEnvironment<'tcx> {
3129
pub param_env: ty::ParamEnv<'tcx>,
3230
free_region_map: FreeRegionMap<'tcx>,
3331

34-
// Contains, for each body B that we are checking (that is, the fn
35-
// item, but also any nested closures), the set of implied region
36-
// bounds that are in scope in that particular body.
32+
// Contains the implied region bounds in scope for our current body.
3733
//
3834
// Example:
3935
//
@@ -43,24 +39,15 @@ pub struct OutlivesEnvironment<'tcx> {
4339
// } // body B0
4440
// ```
4541
//
46-
// Here, for body B0, the list would be `[T: 'a]`, because we
42+
// Here, when checking the body B0, the list would be `[T: 'a]`, because we
4743
// infer that `T` must outlive `'a` from the implied bounds on the
4844
// fn declaration.
4945
//
50-
// For the body B1, the list would be `[T: 'a, T: 'b]`, because we
46+
// For the body B1 however, the list would be `[T: 'a, T: 'b]`, because we
5147
// also can see that -- within the closure body! -- `T` must
5248
// outlive `'b`. This is not necessarily true outside the closure
5349
// body, since the closure may never be called.
54-
//
55-
// We collect this map as we descend the tree. We then use the
56-
// results when proving outlives obligations like `T: 'x` later
57-
// (e.g., if `T: 'x` must be proven within the body B1, then we
58-
// know it is true if either `'a: 'x` or `'b: 'x`).
59-
region_bound_pairs_map: FxHashMap<hir::HirId, RegionBoundPairs<'tcx>>,
60-
61-
// Used to compute `region_bound_pairs_map`: contains the set of
62-
// in-scope region-bound pairs thus far.
63-
region_bound_pairs_accum: RegionBoundPairs<'tcx>,
50+
region_bound_pairs: RegionBoundPairs<'tcx>,
6451
}
6552

6653
/// "Region-bound pairs" tracks outlives relations that are known to
@@ -73,8 +60,7 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
7360
let mut env = OutlivesEnvironment {
7461
param_env,
7562
free_region_map: Default::default(),
76-
region_bound_pairs_map: Default::default(),
77-
region_bound_pairs_accum: vec![],
63+
region_bound_pairs: Default::default(),
7864
};
7965

8066
env.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
@@ -87,62 +73,9 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
8773
&self.free_region_map
8874
}
8975

90-
/// Borrows current value of the `region_bound_pairs`.
91-
pub fn region_bound_pairs_map(&self) -> &FxHashMap<hir::HirId, RegionBoundPairs<'tcx>> {
92-
&self.region_bound_pairs_map
93-
}
94-
95-
/// This is a hack to support the old-school regionck, which
96-
/// processes region constraints from the main function and the
97-
/// closure together. In that context, when we enter a closure, we
98-
/// want to be able to "save" the state of the surrounding a
99-
/// function. We can then add implied bounds and the like from the
100-
/// closure arguments into the environment -- these should only
101-
/// apply in the closure body, so once we exit, we invoke
102-
/// `pop_snapshot_post_typeck_child` to remove them.
103-
///
104-
/// Example:
105-
///
106-
/// ```ignore (pseudo-rust)
107-
/// fn foo<T>() {
108-
/// callback(for<'a> |x: &'a T| {
109-
/// // ^^^^^^^ not legal syntax, but probably should be
110-
/// // within this closure body, `T: 'a` holds
111-
/// })
112-
/// }
113-
/// ```
114-
///
115-
/// This "containment" of closure's effects only works so well. In
116-
/// particular, we (intentionally) leak relationships between free
117-
/// regions that are created by the closure's bounds. The case
118-
/// where this is useful is when you have (e.g.) a closure with a
119-
/// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
120-
/// case, we want to keep the relationship `'b: 'a` in the
121-
/// free-region-map, so that later if we have to take `LUB('b,
122-
/// 'a)` we can get the result `'b`.
123-
///
124-
/// I have opted to keep **all modifications** to the
125-
/// free-region-map, however, and not just those that concern free
126-
/// variables bound in the closure. The latter seems more correct,
127-
/// but it is not the existing behavior, and I could not find a
128-
/// case where the existing behavior went wrong. In any case, it
129-
/// seems like it'd be readily fixed if we wanted. There are
130-
/// similar leaks around givens that seem equally suspicious, to
131-
/// be honest. --nmatsakis
132-
pub fn push_snapshot_pre_typeck_child(&self) -> usize {
133-
self.region_bound_pairs_accum.len()
134-
}
135-
136-
/// See `push_snapshot_pre_typeck_child`.
137-
pub fn pop_snapshot_post_typeck_child(&mut self, len: usize) {
138-
self.region_bound_pairs_accum.truncate(len);
139-
}
140-
141-
/// Save the current set of region-bound pairs under the given `body_id`.
142-
pub fn save_implied_bounds(&mut self, body_id: hir::HirId) {
143-
let old =
144-
self.region_bound_pairs_map.insert(body_id, self.region_bound_pairs_accum.clone());
145-
assert!(old.is_none());
76+
/// Borrows current `region_bound_pairs`.
77+
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
78+
&self.region_bound_pairs
14679
}
14780

14881
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
@@ -164,11 +97,10 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
16497
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
16598
match outlives_bound {
16699
OutlivesBound::RegionSubParam(r_a, param_b) => {
167-
self.region_bound_pairs_accum.push((r_a, GenericKind::Param(param_b)));
100+
self.region_bound_pairs.push((r_a, GenericKind::Param(param_b)));
168101
}
169102
OutlivesBound::RegionSubProjection(r_a, projection_b) => {
170-
self.region_bound_pairs_accum
171-
.push((r_a, GenericKind::Projection(projection_b)));
103+
self.region_bound_pairs.push((r_a, GenericKind::Projection(projection_b)));
172104
}
173105
OutlivesBound::RegionSubRegion(r_a, r_b) => {
174106
if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {

Diff for: compiler/rustc_infer/src/infer/outlives/obligations.rs

+25-30
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,16 @@
6060
//! imply that `'b: 'a`.
6161
6262
use crate::infer::outlives::components::{push_outlives_components, Component};
63+
use crate::infer::outlives::env::OutlivesEnvironment;
6364
use crate::infer::outlives::env::RegionBoundPairs;
6465
use crate::infer::outlives::verify::VerifyBoundCx;
6566
use crate::infer::{
6667
self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound,
6768
};
6869
use crate::traits::{ObligationCause, ObligationCauseCode};
70+
use rustc_data_structures::undo_log::UndoLogs;
6971
use rustc_middle::ty::subst::GenericArgKind;
7072
use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
71-
72-
use rustc_data_structures::fx::FxHashMap;
73-
use rustc_data_structures::undo_log::UndoLogs;
74-
use rustc_hir as hir;
7573
use smallvec::smallvec;
7674

7775
impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
@@ -80,16 +78,11 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
8078
/// and later processed by regionck, when full type information is
8179
/// available (see `region_obligations` field for more
8280
/// information).
83-
pub fn register_region_obligation(
84-
&self,
85-
body_id: hir::HirId,
86-
obligation: RegionObligation<'tcx>,
87-
) {
88-
debug!("register_region_obligation(body_id={:?}, obligation={:?})", body_id, obligation);
89-
81+
#[instrument(level = "debug", skip(self))]
82+
pub fn register_region_obligation(&self, obligation: RegionObligation<'tcx>) {
9083
let mut inner = self.inner.borrow_mut();
9184
inner.undo_log.push(UndoLog::PushRegionObligation);
92-
inner.region_obligations.push((body_id, obligation));
85+
inner.region_obligations.push(obligation);
9386
}
9487

9588
pub fn register_region_obligation_with_cause(
@@ -109,14 +102,11 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
109102
)
110103
});
111104

112-
self.register_region_obligation(
113-
cause.body_id,
114-
RegionObligation { sup_type, sub_region, origin },
115-
);
105+
self.register_region_obligation(RegionObligation { sup_type, sub_region, origin });
116106
}
117107

118108
/// Trait queries just want to pass back type obligations "as is"
119-
pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> {
109+
pub fn take_registered_region_obligations(&self) -> Vec<RegionObligation<'tcx>> {
120110
std::mem::take(&mut self.inner.borrow_mut().region_obligations)
121111
}
122112

@@ -144,10 +134,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
144134
/// - `param_env` is the parameter environment for the enclosing function.
145135
/// - `body_id` is the body-id whose region obligations are being
146136
/// processed.
147-
#[instrument(level = "debug", skip(self, region_bound_pairs_map))]
137+
#[instrument(level = "debug", skip(self, region_bound_pairs))]
148138
pub fn process_registered_region_obligations(
149139
&self,
150-
region_bound_pairs_map: &FxHashMap<hir::HirId, RegionBoundPairs<'tcx>>,
140+
region_bound_pairs: &RegionBoundPairs<'tcx>,
151141
param_env: ty::ParamEnv<'tcx>,
152142
) {
153143
assert!(
@@ -157,26 +147,31 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
157147

158148
let my_region_obligations = self.take_registered_region_obligations();
159149

160-
for (body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations {
150+
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
161151
debug!(
162152
"process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}",
163153
sup_type, sub_region, origin
164154
);
165155

166156
let sup_type = self.resolve_vars_if_possible(sup_type);
167157

168-
if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
169-
let outlives =
170-
&mut TypeOutlives::new(self, self.tcx, &region_bound_pairs, None, param_env);
171-
outlives.type_must_outlive(origin, sup_type, sub_region);
172-
} else {
173-
self.tcx.sess.delay_span_bug(
174-
origin.span(),
175-
&format!("no region-bound-pairs for {:?}", body_id),
176-
);
177-
}
158+
let outlives =
159+
&mut TypeOutlives::new(self, self.tcx, &region_bound_pairs, None, param_env);
160+
outlives.type_must_outlive(origin, sup_type, sub_region);
178161
}
179162
}
163+
164+
pub fn check_region_obligations_and_report_errors(
165+
&self,
166+
outlives_env: &OutlivesEnvironment<'tcx>,
167+
) {
168+
self.process_registered_region_obligations(
169+
outlives_env.region_bound_pairs(),
170+
outlives_env.param_env,
171+
);
172+
173+
self.resolve_regions_and_report_errors(outlives_env)
174+
}
180175
}
181176

182177
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`

Diff for: compiler/rustc_trait_selection/src/traits/auto_trait.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -212,15 +212,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
212212
panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, errors);
213213
}
214214

215-
let body_id_map: FxHashMap<_, _> = infcx
216-
.inner
217-
.borrow()
218-
.region_obligations()
219-
.iter()
220-
.map(|&(id, _)| (id, vec![]))
221-
.collect();
222-
223-
infcx.process_registered_region_obligations(&body_id_map, full_env);
215+
infcx.process_registered_region_obligations(&Default::default(), full_env);
224216

225217
let region_data = infcx
226218
.inner

0 commit comments

Comments
 (0)