Skip to content

Commit cff8c42

Browse files
committed
-Znext-solver Ignore region constraints from the nested goals in leakcheck
1 parent f53b654 commit cff8c42

34 files changed

Lines changed: 500 additions & 154 deletions

File tree

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
7474
let assumptions =
7575
elaborate::elaborate_outlives_assumptions(self.infcx.tcx, assumptions.iter().copied());
7676

77-
for &(constraint, constraint_category) in constraints {
77+
for &(constraint, constraint_category, _) in constraints {
7878
constraint.iter_outlives().for_each(|predicate| {
7979
self.convert(predicate, constraint_category, &assumptions);
8080
});
@@ -296,7 +296,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
296296
// FIXME(higher_ranked_auto): What should we do with the assumptions here?
297297
if let Some(QueryRegionConstraints { constraints, assumptions: _ }) = constraints {
298298
next_outlives_predicates.extend(constraints.iter().flat_map(
299-
|(constraint, category)| {
299+
|(constraint, category, _)| {
300300
constraint.iter_outlives().map(|outlives| (outlives, *category))
301301
},
302302
));

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,7 @@ fn region_known_to_outlive<'tcx>(
728728
SubregionOrigin::RelateRegionParamBound(DUMMY_SP, None),
729729
region_b,
730730
region_a,
731+
ty::VisibleForLeakCheck::Yes,
731732
);
732733
})
733734
}

compiler/rustc_hir_analysis/src/coherence/builtin.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,12 @@ pub(crate) fn coerce_unsized_info<'tcx>(
496496
}
497497

498498
(&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
499-
infcx.sub_regions(SubregionOrigin::RelateObjectBound(span), r_b, r_a);
499+
infcx.sub_regions(
500+
SubregionOrigin::RelateObjectBound(span),
501+
r_b,
502+
r_a,
503+
ty::VisibleForLeakCheck::Yes,
504+
);
500505
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
501506
let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
502507
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty))

compiler/rustc_infer/src/infer/canonical/query_response.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,14 @@ impl<'tcx> InferCtxt<'tcx> {
188188
let InferOk { value: result_args, obligations } =
189189
self.query_response_instantiation(cause, param_env, original_values, query_response)?;
190190

191-
for (constraint, _category) in &query_response.value.region_constraints.constraints {
191+
for (constraint, _category, vis) in &query_response.value.region_constraints.constraints {
192192
let constraint = instantiate_value(self.tcx, &result_args, *constraint);
193193
match constraint {
194194
ty::RegionConstraint::Outlives(predicate) => {
195-
self.register_outlives_constraint(predicate, cause);
195+
self.register_outlives_constraint(predicate, *vis, cause);
196196
}
197197
ty::RegionConstraint::Eq(predicate) => {
198-
self.register_region_eq_constraint(predicate, cause);
198+
self.register_region_eq_constraint(predicate, *vis, cause);
199199
}
200200
}
201201
}
@@ -288,6 +288,7 @@ impl<'tcx> InferCtxt<'tcx> {
288288
output_query_region_constraints.constraints.push((
289289
ty::RegionEqPredicate(v_o.into(), v_r).into(),
290290
constraint_category,
291+
ty::VisibleForLeakCheck::Yes,
291292
));
292293
}
293294
}
@@ -586,6 +587,7 @@ impl<'tcx> InferCtxt<'tcx> {
586587
SubregionOrigin::RelateRegionParamBound(cause.span, None),
587588
v1,
588589
v2,
590+
ty::VisibleForLeakCheck::Yes,
589591
);
590592
}
591593
(GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
@@ -623,20 +625,24 @@ pub fn make_query_region_constraints<'tcx>(
623625
| ConstraintKind::RegSubReg => {
624626
// Swap regions because we are going from sub (<=) to outlives (>=).
625627
let constraint = ty::OutlivesPredicate(c.sup.into(), c.sub).into();
626-
(constraint, origin.to_constraint_category())
628+
(constraint, origin.to_constraint_category(), c.visible_for_leak_check)
627629
}
628630

629631
ConstraintKind::VarEqVar | ConstraintKind::VarEqReg | ConstraintKind::RegEqReg => {
630632
let constraint = ty::RegionEqPredicate(c.sup, c.sub).into();
631-
(constraint, origin.to_constraint_category())
633+
(constraint, origin.to_constraint_category(), c.visible_for_leak_check)
632634
}
633635
})
634-
.chain(outlives_obligations.into_iter().map(|obl| {
635-
(
636-
ty::OutlivesPredicate(obl.sup_type.into(), obl.sub_region).into(),
637-
obl.origin.to_constraint_category(),
638-
)
639-
}))
636+
.chain(outlives_obligations.into_iter().map(
637+
|TypeOutlivesConstraint { sub_region, sup_type, origin }| {
638+
(
639+
ty::OutlivesPredicate(sup_type.into(), sub_region).into(),
640+
origin.to_constraint_category(),
641+
// We don't do leak checks for type outlives
642+
ty::VisibleForLeakCheck::Unreachable,
643+
)
644+
},
645+
))
640646
.collect();
641647

642648
QueryRegionConstraints { constraints, assumptions }

compiler/rustc_infer/src/infer/context.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,19 +256,33 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
256256
self.probe(|_| probe())
257257
}
258258

259-
fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, span: Span) {
259+
fn sub_regions(
260+
&self,
261+
sub: ty::Region<'tcx>,
262+
sup: ty::Region<'tcx>,
263+
vis: ty::VisibleForLeakCheck,
264+
span: Span,
265+
) {
260266
self.inner.borrow_mut().unwrap_region_constraints().make_subregion(
261267
SubregionOrigin::RelateRegionParamBound(span, None),
262268
sub,
263269
sup,
270+
vis,
264271
);
265272
}
266273

267-
fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>, span: Span) {
274+
fn equate_regions(
275+
&self,
276+
a: ty::Region<'tcx>,
277+
b: ty::Region<'tcx>,
278+
vis: ty::VisibleForLeakCheck,
279+
span: Span,
280+
) {
268281
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(
269282
SubregionOrigin::RelateRegionParamBound(span, None),
270283
a,
271284
b,
285+
vis,
272286
);
273287
}
274288

compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
149149

150150
// Deduplicating constraints is shown to have a positive perf impact.
151151
let mut seen = UnordSet::default();
152-
self.data.constraints.retain(|(constraint, _)| seen.insert(*constraint));
152+
self.data.constraints.retain_mut(|(constraint, _)| {
153+
// We don't want to discern constraints by leak check visibility here
154+
constraint.visible_for_leak_check = ty::VisibleForLeakCheck::Unreachable;
155+
seen.insert(*constraint)
156+
});
153157

154158
if cfg!(debug_assertions) {
155159
self.dump_constraints();

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,8 +698,9 @@ impl<'tcx> InferCtxt<'tcx> {
698698
origin: SubregionOrigin<'tcx>,
699699
a: ty::Region<'tcx>,
700700
b: ty::Region<'tcx>,
701+
vis: ty::VisibleForLeakCheck,
701702
) {
702-
self.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin, a, b);
703+
self.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin, a, b, vis);
703704
}
704705

705706
#[instrument(skip(self), level = "debug")]
@@ -708,8 +709,9 @@ impl<'tcx> InferCtxt<'tcx> {
708709
origin: SubregionOrigin<'tcx>,
709710
a: ty::Region<'tcx>,
710711
b: ty::Region<'tcx>,
712+
vis: ty::VisibleForLeakCheck,
711713
) {
712-
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(origin, a, b);
714+
self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(origin, a, b, vis);
713715
}
714716

715717
/// Processes a `Coerce` predicate from the fulfillment context.

compiler/rustc_infer/src/infer/outlives/obligations.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,12 @@ impl<'tcx> InferCtxt<'tcx> {
8585
pub fn register_outlives_constraint(
8686
&self,
8787
ty::OutlivesPredicate(arg, r2): ty::ArgOutlivesPredicate<'tcx>,
88+
vis: ty::VisibleForLeakCheck,
8889
cause: &ObligationCause<'tcx>,
8990
) {
9091
match arg.kind() {
9192
ty::GenericArgKind::Lifetime(r1) => {
92-
self.register_region_outlives_constraint(ty::OutlivesPredicate(r1, r2), cause);
93+
self.register_region_outlives_constraint(ty::OutlivesPredicate(r1, r2), vis, cause);
9394
}
9495
ty::GenericArgKind::Type(ty1) => {
9596
self.register_type_outlives_constraint(ty1, r2, cause);
@@ -101,24 +102,26 @@ impl<'tcx> InferCtxt<'tcx> {
101102
pub fn register_region_eq_constraint(
102103
&self,
103104
ty::RegionEqPredicate(r_a, r_b): ty::RegionEqPredicate<'tcx>,
105+
vis: ty::VisibleForLeakCheck,
104106
cause: &ObligationCause<'tcx>,
105107
) {
106108
let origin = SubregionOrigin::from_obligation_cause(cause, || {
107109
SubregionOrigin::RelateRegionParamBound(cause.span, None)
108110
});
109-
self.equate_regions(origin, r_a, r_b);
111+
self.equate_regions(origin, r_a, r_b, vis);
110112
}
111113

112114
pub fn register_region_outlives_constraint(
113115
&self,
114116
ty::OutlivesPredicate(r_a, r_b): ty::RegionOutlivesPredicate<'tcx>,
117+
vis: ty::VisibleForLeakCheck,
115118
cause: &ObligationCause<'tcx>,
116119
) {
117120
let origin = SubregionOrigin::from_obligation_cause(cause, || {
118121
SubregionOrigin::RelateRegionParamBound(cause.span, None)
119122
});
120123
// `'a: 'b` ==> `'b <= 'a`
121-
self.sub_regions(origin, r_b, r_a);
124+
self.sub_regions(origin, r_b, r_a, vis);
122125
}
123126

124127
/// Registers that the given region obligation must be resolved
@@ -577,7 +580,8 @@ impl<'cx, 'tcx> TypeOutlivesDelegate<'tcx> for &'cx InferCtxt<'tcx> {
577580
b: ty::Region<'tcx>,
578581
_constraint_category: ConstraintCategory<'tcx>,
579582
) {
580-
self.sub_regions(origin, a, b)
583+
// We don't do leak check in borrowck
584+
self.sub_regions(origin, a, b, ty::VisibleForLeakCheck::Unreachable)
581585
}
582586

583587
fn push_verify(

compiler/rustc_infer/src/infer/region_constraints/leak_check.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,15 @@ impl<'tcx> MiniGraph<'tcx> {
392392
{
393393
match undo_entry {
394394
&AddConstraint(i) => {
395-
region_constraints.data().constraints[i]
396-
.0
397-
.iter_outlives()
398-
.for_each(|c| each_edge(c.sub, c.sup));
395+
region_constraints.data().constraints[i].0.iter_outlives().for_each(
396+
|Constraint { kind: _, sub, sup, visible_for_leak_check }| {
397+
match visible_for_leak_check {
398+
ty::VisibleForLeakCheck::Yes => each_edge(sub, sup),
399+
ty::VisibleForLeakCheck::No => {}
400+
ty::VisibleForLeakCheck::Unreachable => unreachable!(),
401+
}
402+
},
403+
);
399404
}
400405
&AddVerify(i) => span_bug!(
401406
region_constraints.data().verifys[i].origin.span(),
@@ -410,7 +415,13 @@ impl<'tcx> MiniGraph<'tcx> {
410415
.constraints
411416
.iter()
412417
.flat_map(|(c, _)| c.iter_outlives())
413-
.for_each(|c| each_edge(c.sub, c.sup))
418+
.for_each(|Constraint { kind: _, sub, sup, visible_for_leak_check }| {
419+
match visible_for_leak_check {
420+
ty::VisibleForLeakCheck::Yes => each_edge(sub, sup),
421+
ty::VisibleForLeakCheck::No => {}
422+
ty::VisibleForLeakCheck::Unreachable => unreachable!(),
423+
}
424+
})
414425
}
415426
}
416427

0 commit comments

Comments
 (0)