Skip to content

Commit be96d2c

Browse files
committed
Auto merge of rust-lang#141392 - compiler-errors:query-outlives, r=<try>
Avoid obligation construction dance with query region constraints And some renaming... r? `@ghost`
2 parents e3892a4 + d531757 commit be96d2c

File tree

9 files changed

+52
-96
lines changed

9 files changed

+52
-96
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ fn ty_known_to_outlive<'tcx>(
742742
region: ty::Region<'tcx>,
743743
) -> bool {
744744
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
745-
infcx.register_region_obligation(infer::RegionObligation {
745+
infcx.type_outlives_predicate(infer::RegionObligation {
746746
sub_region: region,
747747
sup_type: ty,
748748
origin: infer::RelateParamBound(DUMMY_SP, ty, None),

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

Lines changed: 8 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,20 @@ use std::iter;
1212

1313
use rustc_index::{Idx, IndexVec};
1414
use rustc_middle::arena::ArenaAllocatable;
15+
use rustc_middle::bug;
1516
use rustc_middle::mir::ConstraintCategory;
1617
use rustc_middle::ty::{self, BoundVar, GenericArg, GenericArgKind, Ty, TyCtxt, TypeFoldable};
17-
use rustc_middle::{bug, span_bug};
1818
use tracing::{debug, instrument};
1919

2020
use crate::infer::canonical::instantiate::{CanonicalExt, instantiate_value};
2121
use crate::infer::canonical::{
2222
Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues,
23-
QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse,
23+
QueryRegionConstraints, QueryResponse,
2424
};
2525
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
2626
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult};
2727
use crate::traits::query::NoSolution;
28-
use crate::traits::{
29-
Obligation, ObligationCause, PredicateObligation, PredicateObligations, ScrubbedTraitError,
30-
TraitEngine,
31-
};
28+
use crate::traits::{ObligationCause, PredicateObligations, ScrubbedTraitError, TraitEngine};
3229

3330
impl<'tcx> InferCtxt<'tcx> {
3431
/// This method is meant to be invoked as the final step of a canonical query
@@ -169,15 +166,13 @@ impl<'tcx> InferCtxt<'tcx> {
169166
where
170167
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
171168
{
172-
let InferOk { value: result_args, mut obligations } =
169+
let InferOk { value: result_args, obligations } =
173170
self.query_response_instantiation(cause, param_env, original_values, query_response)?;
174171

175-
obligations.extend(self.query_outlives_constraints_into_obligations(
176-
cause,
177-
param_env,
178-
&query_response.value.region_constraints.outlives,
179-
&result_args,
180-
));
172+
for (predicate, _category) in &query_response.value.region_constraints.outlives {
173+
let predicate = instantiate_value(self.tcx, &result_args, *predicate);
174+
self.outlives_predicate_with_cause(predicate, cause);
175+
}
181176

182177
let user_result: R =
183178
query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone());
@@ -525,47 +520,6 @@ impl<'tcx> InferCtxt<'tcx> {
525520
self.unify_canonical_vars(cause, param_env, original_values, instantiated_query_response)
526521
}
527522

528-
/// Converts the region constraints resulting from a query into an
529-
/// iterator of obligations.
530-
fn query_outlives_constraints_into_obligations(
531-
&self,
532-
cause: &ObligationCause<'tcx>,
533-
param_env: ty::ParamEnv<'tcx>,
534-
uninstantiated_region_constraints: &[QueryOutlivesConstraint<'tcx>],
535-
result_args: &CanonicalVarValues<'tcx>,
536-
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
537-
uninstantiated_region_constraints.iter().map(move |&constraint| {
538-
let predicate = instantiate_value(self.tcx, result_args, constraint);
539-
self.query_outlives_constraint_to_obligation(predicate, cause.clone(), param_env)
540-
})
541-
}
542-
543-
pub fn query_outlives_constraint_to_obligation(
544-
&self,
545-
(predicate, _): QueryOutlivesConstraint<'tcx>,
546-
cause: ObligationCause<'tcx>,
547-
param_env: ty::ParamEnv<'tcx>,
548-
) -> Obligation<'tcx, ty::Predicate<'tcx>> {
549-
let ty::OutlivesPredicate(k1, r2) = predicate;
550-
551-
let atom = match k1.unpack() {
552-
GenericArgKind::Lifetime(r1) => ty::PredicateKind::Clause(
553-
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)),
554-
),
555-
GenericArgKind::Type(t1) => ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
556-
ty::OutlivesPredicate(t1, r2),
557-
)),
558-
GenericArgKind::Const(..) => {
559-
// Consts cannot outlive one another, so we don't expect to
560-
// encounter this branch.
561-
span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
562-
}
563-
};
564-
let predicate = ty::Binder::dummy(atom);
565-
566-
Obligation::new(self.tcx, cause, param_env, predicate)
567-
}
568-
569523
/// Given two sets of values for the same set of canonical variables, unify them.
570524
/// The second set is produced lazily by supplying indices from the first set.
571525
fn unify_canonical_vars(

compiler/rustc_infer/src/infer/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
214214
}
215215

216216
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
217-
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
217+
self.type_outlives_predicate_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
218218
}
219219

220220
type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -738,19 +738,6 @@ impl<'tcx> InferCtxt<'tcx> {
738738
})
739739
}
740740

741-
pub fn region_outlives_predicate(
742-
&self,
743-
cause: &traits::ObligationCause<'tcx>,
744-
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
745-
) {
746-
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
747-
let origin = SubregionOrigin::from_obligation_cause(cause, || {
748-
RelateRegionParamBound(cause.span, None)
749-
});
750-
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
751-
})
752-
}
753-
754741
/// Number of type variables created so far.
755742
pub fn num_ty_vars(&self) -> usize {
756743
self.inner.borrow_mut().type_variables().num_vars()

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,47 @@ use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrig
8080
use crate::traits::{ObligationCause, ObligationCauseCode};
8181

8282
impl<'tcx> InferCtxt<'tcx> {
83+
pub fn outlives_predicate_with_cause(
84+
&self,
85+
ty::OutlivesPredicate(arg, r2): ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>,
86+
cause: &ObligationCause<'tcx>,
87+
) {
88+
match arg.unpack() {
89+
ty::GenericArgKind::Lifetime(r1) => {
90+
self.region_outlives_predicate(ty::OutlivesPredicate(r1, r2), cause);
91+
}
92+
ty::GenericArgKind::Type(ty1) => {
93+
self.type_outlives_predicate_with_cause(ty1, r2, cause);
94+
}
95+
ty::GenericArgKind::Const(_) => unreachable!(),
96+
}
97+
}
98+
99+
pub fn region_outlives_predicate(
100+
&self,
101+
ty::OutlivesPredicate(r_a, r_b): ty::RegionOutlivesPredicate<'tcx>,
102+
cause: &ObligationCause<'tcx>,
103+
) {
104+
let origin = SubregionOrigin::from_obligation_cause(cause, || {
105+
SubregionOrigin::RelateRegionParamBound(cause.span, None)
106+
});
107+
// `b : a` ==> `a <= b`
108+
self.sub_regions(origin, r_b, r_a);
109+
}
110+
83111
/// Registers that the given region obligation must be resolved
84112
/// from within the scope of `body_id`. These regions are enqueued
85113
/// and later processed by regionck, when full type information is
86114
/// available (see `region_obligations` field for more
87115
/// information).
88116
#[instrument(level = "debug", skip(self))]
89-
pub fn register_region_obligation(&self, obligation: RegionObligation<'tcx>) {
117+
pub fn type_outlives_predicate(&self, obligation: RegionObligation<'tcx>) {
90118
let mut inner = self.inner.borrow_mut();
91119
inner.undo_log.push(UndoLog::PushRegionObligation);
92120
inner.region_obligations.push(obligation);
93121
}
94122

95-
pub fn register_region_obligation_with_cause(
123+
pub fn type_outlives_predicate_with_cause(
96124
&self,
97125
sup_type: Ty<'tcx>,
98126
sub_region: Region<'tcx>,
@@ -124,7 +152,7 @@ impl<'tcx> InferCtxt<'tcx> {
124152
)
125153
});
126154

127-
self.register_region_obligation(RegionObligation { sup_type, sub_region, origin });
155+
self.type_outlives_predicate(RegionObligation { sup_type, sub_region, origin });
128156
}
129157

130158
/// Trait queries just want to pass back type obligations "as is"

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
7676
Some(HasChanged::No)
7777
}
7878
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
79-
self.0.register_region_obligation_with_cause(
79+
self.0.type_outlives_predicate_with_cause(
8080
outlives.0,
8181
outlives.1,
8282
&ObligationCause::dummy_with_span(span),

compiler/rustc_trait_selection/src/traits/auto_trait.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
726726
}
727727
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(binder)) => {
728728
let binder = bound_predicate.rebind(binder);
729-
selcx.infcx.region_outlives_predicate(&dummy_cause, binder)
729+
selcx.infcx.enter_forall(binder, |pred| {
730+
selcx.infcx.region_outlives_predicate(pred, &dummy_cause);
731+
});
730732
}
731733
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(binder)) => {
732734
let binder = bound_predicate.rebind(binder);
@@ -735,14 +737,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
735737
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
736738
) {
737739
(None, Some(t_a)) => {
738-
selcx.infcx.register_region_obligation_with_cause(
740+
selcx.infcx.type_outlives_predicate_with_cause(
739741
t_a,
740742
selcx.infcx.tcx.lifetimes.re_static,
741743
&dummy_cause,
742744
);
743745
}
744746
(Some(ty::OutlivesPredicate(t_a, r_b)), _) => {
745-
selcx.infcx.register_region_obligation_with_cause(
747+
selcx.infcx.type_outlives_predicate_with_cause(
746748
t_a,
747749
r_b,
748750
&dummy_cause,

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
428428

429429
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
430430
if infcx.considering_regions {
431-
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
431+
infcx.region_outlives_predicate(data, &obligation.cause);
432432
}
433433

434434
ProcessResult::Changed(Default::default())
@@ -439,7 +439,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
439439
r_b,
440440
))) => {
441441
if infcx.considering_regions {
442-
infcx.register_region_obligation_with_cause(t_a, r_b, &obligation.cause);
442+
infcx.type_outlives_predicate_with_cause(t_a, r_b, &obligation.cause);
443443
}
444444
ProcessResult::Changed(Default::default())
445445
}

compiler/rustc_trait_selection/src/traits/outlives_bounds.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_span::def_id::LocalDefId;
99
use tracing::instrument;
1010

1111
use crate::infer::InferCtxt;
12-
use crate::traits::{ObligationCause, ObligationCtxt};
12+
use crate::traits::ObligationCause;
1313

1414
/// Implied bounds are region relationships that we deduce
1515
/// automatically. The idea is that (e.g.) a caller must check that a
@@ -79,24 +79,9 @@ fn implied_outlives_bounds<'a, 'tcx>(
7979

8080
if !constraints.is_empty() {
8181
let QueryRegionConstraints { outlives } = constraints;
82-
// Instantiation may have produced new inference variables and constraints on those
83-
// variables. Process these constraints.
84-
let ocx = ObligationCtxt::new(infcx);
8582
let cause = ObligationCause::misc(span, body_id);
86-
for &constraint in &outlives {
87-
ocx.register_obligation(infcx.query_outlives_constraint_to_obligation(
88-
constraint,
89-
cause.clone(),
90-
param_env,
91-
));
92-
}
93-
94-
let errors = ocx.select_all_or_error();
95-
if !errors.is_empty() {
96-
infcx.dcx().span_bug(
97-
span,
98-
"implied_outlives_bounds failed to solve obligations from instantiation",
99-
);
83+
for &(predicate, _) in &outlives {
84+
infcx.outlives_predicate_with_cause(predicate, &cause);
10085
}
10186
};
10287

0 commit comments

Comments
 (0)