Skip to content

Commit e30fb6a

Browse files
committed
Auto merge of #102618 - aliemjay:simplify-closure-promote, r=compiler-errors
rework applying closure requirements in borrowck Previously the promoted closure constraints were registered under the category `ConstraintCategory::ClosureBounds` in `type_check::prove_closure_bounds()` and then mapped back their original category in `regions_infer::best_blame_constraint` using the complicated map `closure_bounds_mapping`. Now we're registering promoted constraints under their original category and span earlier in `type_check::prove_closure_bounds`. See commit messages. Fixes #99245
2 parents a4ab2e0 + 02f78fd commit e30fb6a

26 files changed

+173
-349
lines changed

compiler/rustc_borrowck/src/constraints/graph.rs

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> {
163163
span: DUMMY_SP,
164164
category: ConstraintCategory::Internal,
165165
variance_info: VarianceDiagInfo::default(),
166+
from_closure: false,
166167
})
167168
} else {
168169
None

compiler/rustc_borrowck/src/constraints/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ pub struct OutlivesConstraint<'tcx> {
9696

9797
/// Variance diagnostic information
9898
pub variance_info: VarianceDiagInfo<'tcx>,
99+
100+
/// If this constraint is promoted from closure requirements.
101+
pub from_closure: bool,
99102
}
100103

101104
impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
181181
// Try to convert the lower-bound region into something named we can print for the user.
182182
let lower_bound_region = self.to_error_region(type_test.lower_bound);
183183

184-
let type_test_span = type_test.locations.span(&self.body);
184+
let type_test_span = type_test.span;
185185

186186
if let Some(lower_bound_region) = lower_bound_region {
187187
let generic_ty = type_test.generic_kind.to_ty(self.infcx.tcx);

compiler/rustc_borrowck/src/nll.rs

-2
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
242242
mut liveness_constraints,
243243
outlives_constraints,
244244
member_constraints,
245-
closure_bounds_mapping,
246245
universe_causes,
247246
type_tests,
248247
} = constraints;
@@ -264,7 +263,6 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
264263
universal_region_relations,
265264
outlives_constraints,
266265
member_constraints,
267-
closure_bounds_mapping,
268266
universe_causes,
269267
type_tests,
270268
liveness_constraints,

compiler/rustc_borrowck/src/region_infer/dump_mir.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
7474
let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
7575
constraints.sort_by_key(|c| (c.sup, c.sub));
7676
for constraint in &constraints {
77-
let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } =
78-
constraint;
77+
let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint;
7978
let (name, arg) = match locations {
8079
Locations::All(span) => {
8180
("All", tcx.sess.source_map().span_to_embeddable_string(*span))

compiler/rustc_borrowck/src/region_infer/mod.rs

+17-145
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ use rustc_data_structures::frozen::Frozen;
66
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
77
use rustc_data_structures::graph::scc::Sccs;
88
use rustc_errors::Diagnostic;
9-
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
9+
use rustc_hir::def_id::CRATE_DEF_ID;
1010
use rustc_hir::CRATE_HIR_ID;
1111
use rustc_index::vec::IndexVec;
12-
use rustc_infer::infer::canonical::QueryOutlivesConstraint;
1312
use rustc_infer::infer::outlives::test_type_match;
1413
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
1514
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
@@ -19,9 +18,7 @@ use rustc_middle::mir::{
1918
};
2019
use rustc_middle::traits::ObligationCause;
2120
use rustc_middle::traits::ObligationCauseCode;
22-
use rustc_middle::ty::{
23-
self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable,
24-
};
21+
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable};
2522
use rustc_span::Span;
2623

2724
use crate::{
@@ -89,10 +86,6 @@ pub struct RegionInferenceContext<'tcx> {
8986
/// `member_region_scc`.
9087
member_constraints_applied: Vec<AppliedMemberConstraint>,
9188

92-
/// Map closure bounds to a `Span` that should be used for error reporting.
93-
closure_bounds_mapping:
94-
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>,
95-
9689
/// Map universe indexes to information on why we created it.
9790
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
9891

@@ -221,8 +214,8 @@ pub struct TypeTest<'tcx> {
221214
/// The region `'x` that the type must outlive.
222215
pub lower_bound: RegionVid,
223216

224-
/// Where did this constraint arise and why?
225-
pub locations: Locations,
217+
/// The span to blame.
218+
pub span: Span,
226219

227220
/// A test which, if met by the region `'x`, proves that this type
228221
/// constraint is satisfied.
@@ -265,10 +258,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
265258
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
266259
outlives_constraints: OutlivesConstraintSet<'tcx>,
267260
member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
268-
closure_bounds_mapping: FxHashMap<
269-
Location,
270-
FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>,
271-
>,
272261
universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
273262
type_tests: Vec<TypeTest<'tcx>>,
274263
liveness_constraints: LivenessValues<RegionVid>,
@@ -310,7 +299,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
310299
rev_scc_graph: None,
311300
member_constraints,
312301
member_constraints_applied: Vec::new(),
313-
closure_bounds_mapping,
314302
universe_causes,
315303
scc_universes,
316304
scc_representatives,
@@ -882,13 +870,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
882870
if deduplicate_errors.insert((
883871
erased_generic_kind,
884872
type_test.lower_bound,
885-
type_test.locations,
873+
type_test.span,
886874
)) {
887875
debug!(
888876
"check_type_test: reporting error for erased_generic_kind={:?}, \
889877
lower_bound_region={:?}, \
890-
type_test.locations={:?}",
891-
erased_generic_kind, type_test.lower_bound, type_test.locations,
878+
type_test.span={:?}",
879+
erased_generic_kind, type_test.lower_bound, type_test.span,
892880
);
893881

894882
errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() });
@@ -931,7 +919,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
931919
) -> bool {
932920
let tcx = infcx.tcx;
933921

934-
let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
922+
let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test;
935923

936924
let generic_ty = generic_kind.to_ty(tcx);
937925
let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else {
@@ -959,7 +947,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
959947
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
960948
subject,
961949
outlived_free_region: static_r,
962-
blame_span: locations.span(body),
950+
blame_span: type_test.span,
963951
category: ConstraintCategory::Boring,
964952
});
965953

@@ -1011,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
1011999
let requirement = ClosureOutlivesRequirement {
10121000
subject,
10131001
outlived_free_region: upper_bound,
1014-
blame_span: locations.span(body),
1002+
blame_span: type_test.span,
10151003
category: ConstraintCategory::Boring,
10161004
};
10171005
debug!("try_promote_type_test: pushing {:#?}", requirement);
@@ -1804,18 +1792,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
18041792
}
18051793
}
18061794

1807-
pub(crate) fn retrieve_closure_constraint_info(
1808-
&self,
1809-
constraint: OutlivesConstraint<'tcx>,
1810-
) -> Option<(ConstraintCategory<'tcx>, Span)> {
1811-
match constraint.locations {
1812-
Locations::All(_) => None,
1813-
Locations::Single(loc) => {
1814-
self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)).copied()
1815-
}
1816-
}
1817-
}
1818-
18191795
/// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`.
18201796
pub(crate) fn find_outlives_blame_span(
18211797
&self,
@@ -1921,6 +1897,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19211897
span: p_c.definition_span,
19221898
category: ConstraintCategory::OpaqueType,
19231899
variance_info: ty::VarianceDiagInfo::default(),
1900+
from_closure: false,
19241901
};
19251902
handle_constraint(constraint);
19261903
}
@@ -2066,31 +2043,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20662043
// Classify each of the constraints along the path.
20672044
let mut categorized_path: Vec<BlameConstraint<'tcx>> = path
20682045
.iter()
2069-
.map(|constraint| {
2070-
let (category, span, from_closure, cause_code) =
2071-
if constraint.category == ConstraintCategory::ClosureBounds {
2072-
if let Some((category, span)) =
2073-
self.retrieve_closure_constraint_info(*constraint)
2074-
{
2075-
(category, span, true, ObligationCauseCode::MiscObligation)
2076-
} else {
2077-
(
2078-
constraint.category,
2079-
constraint.span,
2080-
false,
2081-
ObligationCauseCode::MiscObligation,
2082-
)
2083-
}
2084-
} else {
2085-
(constraint.category, constraint.span, false, cause_code.clone())
2086-
};
2087-
BlameConstraint {
2088-
category,
2089-
from_closure,
2090-
cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code),
2091-
variance_info: constraint.variance_info,
2092-
outlives_constraint: *constraint,
2093-
}
2046+
.map(|constraint| BlameConstraint {
2047+
category: constraint.category,
2048+
from_closure: constraint.from_closure,
2049+
cause: ObligationCause::new(constraint.span, CRATE_HIR_ID, cause_code.clone()),
2050+
variance_info: constraint.variance_info,
2051+
outlives_constraint: *constraint,
20942052
})
20952053
.collect();
20962054
debug!("categorized_path={:#?}", categorized_path);
@@ -2274,92 +2232,6 @@ impl<'tcx> RegionDefinition<'tcx> {
22742232
}
22752233
}
22762234

2277-
pub trait ClosureRegionRequirementsExt<'tcx> {
2278-
fn apply_requirements(
2279-
&self,
2280-
tcx: TyCtxt<'tcx>,
2281-
closure_def_id: DefId,
2282-
closure_substs: SubstsRef<'tcx>,
2283-
) -> Vec<QueryOutlivesConstraint<'tcx>>;
2284-
}
2285-
2286-
impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> {
2287-
/// Given an instance T of the closure type, this method
2288-
/// instantiates the "extra" requirements that we computed for the
2289-
/// closure into the inference context. This has the effect of
2290-
/// adding new outlives obligations to existing variables.
2291-
///
2292-
/// As described on `ClosureRegionRequirements`, the extra
2293-
/// requirements are expressed in terms of regionvids that index
2294-
/// into the free regions that appear on the closure type. So, to
2295-
/// do this, we first copy those regions out from the type T into
2296-
/// a vector. Then we can just index into that vector to extract
2297-
/// out the corresponding region from T and apply the
2298-
/// requirements.
2299-
fn apply_requirements(
2300-
&self,
2301-
tcx: TyCtxt<'tcx>,
2302-
closure_def_id: DefId,
2303-
closure_substs: SubstsRef<'tcx>,
2304-
) -> Vec<QueryOutlivesConstraint<'tcx>> {
2305-
debug!(
2306-
"apply_requirements(closure_def_id={:?}, closure_substs={:?})",
2307-
closure_def_id, closure_substs
2308-
);
2309-
2310-
// Extract the values of the free regions in `closure_substs`
2311-
// into a vector. These are the regions that we will be
2312-
// relating to one another.
2313-
let closure_mapping = &UniversalRegions::closure_mapping(
2314-
tcx,
2315-
closure_substs,
2316-
self.num_external_vids,
2317-
closure_def_id.expect_local(),
2318-
);
2319-
debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
2320-
2321-
// Create the predicates.
2322-
self.outlives_requirements
2323-
.iter()
2324-
.map(|outlives_requirement| {
2325-
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
2326-
2327-
match outlives_requirement.subject {
2328-
ClosureOutlivesSubject::Region(region) => {
2329-
let region = closure_mapping[region];
2330-
debug!(
2331-
"apply_requirements: region={:?} \
2332-
outlived_region={:?} \
2333-
outlives_requirement={:?}",
2334-
region, outlived_region, outlives_requirement,
2335-
);
2336-
(
2337-
ty::Binder::dummy(ty::OutlivesPredicate(
2338-
region.into(),
2339-
outlived_region,
2340-
)),
2341-
ConstraintCategory::BoringNoLocation,
2342-
)
2343-
}
2344-
2345-
ClosureOutlivesSubject::Ty(ty) => {
2346-
debug!(
2347-
"apply_requirements: ty={:?} \
2348-
outlived_region={:?} \
2349-
outlives_requirement={:?}",
2350-
ty, outlived_region, outlives_requirement,
2351-
);
2352-
(
2353-
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)),
2354-
ConstraintCategory::BoringNoLocation,
2355-
)
2356-
}
2357-
}
2358-
})
2359-
.collect()
2360-
}
2361-
}
2362-
23632235
#[derive(Clone, Debug)]
23642236
pub struct BlameConstraint<'tcx> {
23652237
pub category: ConstraintCategory<'tcx>,

0 commit comments

Comments
 (0)