Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove binder from query constraints #107755

Merged
merged 1 commit into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
self.constraints.member_constraints = tmp;

for (predicate, constraint_category) in outlives {
// At the moment, we never generate any "higher-ranked"
// region constraints like `for<'a> 'a: 'b`. At some point
// when we move to universes, we will, and this assertion
// will start to fail.
Comment on lines -87 to -90
Copy link
Contributor Author

@lcnr lcnr Feb 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this assumption is probably why we've had a binder here in the first place.

I believe this to be wrong. We've already mostly moved to universes. I think we want to avoid mapping placeholders back to bound variables inside of the solver so even in the future we won't deal with bound vars here. And finally I expect us to move higher ranked region solving into the trait solver at some point in the future to deal with implications in binders. At that point we not only not return higher ranked outlives predicates from queries, we completely stop returning placeholders from a universe created in the query.

let predicate = predicate.no_bound_vars().unwrap_or_else(|| {
bug!("query_constraint {:?} contained bound vars", predicate,);
});

self.convert(predicate, *constraint_category);
for &(predicate, constraint_category) in outlives {
self.convert(predicate, constraint_category);
}
}

Expand Down
41 changes: 16 additions & 25 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,12 @@ impl<'tcx> InferCtxt<'tcx> {
(GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => {
// To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`.
if v_o != v_r {
output_query_region_constraints.outlives.push((
ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)),
constraint_category,
));
output_query_region_constraints.outlives.push((
ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)),
constraint_category,
));
output_query_region_constraints
.outlives
.push((ty::OutlivesPredicate(v_o.into(), v_r), constraint_category));
output_query_region_constraints
.outlives
.push((ty::OutlivesPredicate(v_r.into(), v_o), constraint_category));
}
}

Expand Down Expand Up @@ -318,10 +316,8 @@ impl<'tcx> InferCtxt<'tcx> {
query_response.value.region_constraints.outlives.iter().filter_map(|&r_c| {
let r_c = substitute_value(self.tcx, &result_subst, r_c);

// Screen out `'a: 'a` cases -- we skip the binder here but
// only compare the inner values to one another, so they are still at
// consistent binding levels.
let ty::OutlivesPredicate(k1, r2) = r_c.0.skip_binder();
// Screen out `'a: 'a` cases.
let ty::OutlivesPredicate(k1, r2) = r_c.0;
if k1 != r2.into() { Some(r_c) } else { None }
}),
);
Expand Down Expand Up @@ -559,11 +555,11 @@ impl<'tcx> InferCtxt<'tcx> {

pub fn query_outlives_constraint_to_obligation(
&self,
predicate: QueryOutlivesConstraint<'tcx>,
(predicate, _): QueryOutlivesConstraint<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Obligation<'tcx, ty::Predicate<'tcx>> {
let ty::OutlivesPredicate(k1, r2) = predicate.0.skip_binder();
let ty::OutlivesPredicate(k1, r2) = predicate;

let atom = match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
Expand All @@ -578,7 +574,7 @@ impl<'tcx> InferCtxt<'tcx> {
span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
}
};
let predicate = predicate.0.rebind(atom);
let predicate = ty::Binder::dummy(atom);

Obligation::new(self.tcx, cause, param_env, predicate)
}
Expand Down Expand Up @@ -643,8 +639,7 @@ pub fn make_query_region_constraints<'tcx>(
let outlives: Vec<_> = constraints
.iter()
.map(|(k, origin)| {
// no bound vars in the code above
let constraint = ty::Binder::dummy(match *k {
let constraint = match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
Expand All @@ -658,16 +653,12 @@ pub fn make_query_region_constraints<'tcx>(
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
});
};
(constraint, origin.to_constraint_category())
})
.chain(
outlives_obligations
// no bound vars in the code above
.map(|(ty, r, constraint_category)| {
(ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), r)), constraint_category)
}),
)
.chain(outlives_obligations.map(|(ty, r, constraint_category)| {
(ty::OutlivesPredicate(ty.into(), r), constraint_category)
}))
.collect();

QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() }
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,8 @@ impl<'tcx, V> Canonical<'tcx, V> {
}
}

pub type QueryOutlivesConstraint<'tcx> = (
ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>,
ConstraintCategory<'tcx>,
);
pub type QueryOutlivesConstraint<'tcx> =
(ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>, ConstraintCategory<'tcx>);

TrivialTypeTraversalAndLiftImpls! {
for <'tcx> {
Expand Down