This commit is contained in:
Jack Huey 2021-01-04 16:50:36 -05:00
parent 7f24c21a50
commit 476bd53058
9 changed files with 25 additions and 66 deletions

View file

@ -541,7 +541,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
}
};
let predicate = predicate.rebind(atom).potentially_quantified(self.tcx);
let predicate = predicate.rebind(atom).to_predicate(self.tcx);
Obligation::new(cause.clone(), param_env, predicate)
})

View file

@ -1070,16 +1070,6 @@ impl<'tcx> Predicate<'tcx> {
self.inner.binder.skip_binder()
}
/// Returns the inner `PredicateAtom`.
///
/// Note that this method does not check if the predicate has unbound variables.
///
/// Rebinding the returned atom can causes the previously bound variables
/// to end up at the wrong binding level.
pub fn skip_binders_unchecked(self) -> PredicateAtom<'tcx> {
self.inner.binder.skip_binder()
}
/// Converts this to a `Binder<PredicateAtom<'tcx>>`. If the value was an
/// `Atom`, then it is not allowed to contain escaping bound vars.
pub fn bound_atom(self) -> Binder<PredicateAtom<'tcx>> {
@ -1089,12 +1079,6 @@ impl<'tcx> Predicate<'tcx> {
pub fn bound_atom_ref(self) -> &'tcx Binder<PredicateAtom<'tcx>> {
&self.inner.binder
}
/// Allows using a `Binder<PredicateAtom<'tcx>>` even if the given predicate previously
/// contained unbound variables by shifting these variables outwards.
pub fn bound_atom_with_opt_escaping(self, _tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
self.inner.binder
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
@ -1160,13 +1144,6 @@ pub enum PredicateAtom<'tcx> {
TypeWellFormedFromEnv(Ty<'tcx>),
}
impl<'tcx> Binder<PredicateAtom<'tcx>> {
/// Wraps `self` with the given qualifier if this predicate has any unbound variables.
pub fn potentially_quantified(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.to_predicate(tcx)
}
}
/// The crate outlives map is computed during typeck and contains the
/// outlives of every item in the local crate. You should not use it
/// directly, because to do so will make your pass dependent on the
@ -1254,7 +1231,7 @@ impl<'tcx> Predicate<'tcx> {
let substs = trait_ref.skip_binder().substs;
let pred = self.skip_binders();
let new = pred.subst(tcx, substs);
if new != pred { ty::Binder::bind(new).potentially_quantified(tcx) } else { self }
if new != pred { ty::Binder::bind(new).to_predicate(tcx) } else { self }
}
}
@ -1409,27 +1386,25 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitPredicate<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value
.map_bound(|value| PredicateAtom::Trait(value, self.constness))
.potentially_quantified(tcx)
self.value.map_bound(|value| PredicateAtom::Trait(value, self.constness)).to_predicate(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateAtom::RegionOutlives).potentially_quantified(tcx)
self.map_bound(PredicateAtom::RegionOutlives).to_predicate(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateAtom::TypeOutlives).potentially_quantified(tcx)
self.map_bound(PredicateAtom::TypeOutlives).to_predicate(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx)
self.map_bound(PredicateAtom::Projection).to_predicate(tcx)
}
}

View file

@ -627,7 +627,7 @@ pub trait PrettyPrinter<'tcx>:
// may contain unbound variables. We therefore do this manually.
//
// FIXME(lcnr): Find out why exactly this is the case :)
let bound_predicate = predicate.bound_atom_with_opt_escaping(self.tcx());
let bound_predicate = predicate.bound_atom();
if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
let trait_ref = bound_predicate.rebind(pred.trait_ref);
// Don't print +Sized, but rather +?Sized if absent.

View file

@ -81,11 +81,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
interner: &RustInterner<'tcx>,
) -> chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>> {
let clauses = self.environment.into_iter().map(|predicate| {
let (predicate, binders, _named_regions) = collect_bound_vars(
interner,
interner.tcx,
predicate.bound_atom_with_opt_escaping(interner.tcx),
);
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, predicate.bound_atom());
let consequence = match predicate {
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner)))
@ -136,11 +133,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predicate<'tcx> {
fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
let (predicate, binders, _named_regions) = collect_bound_vars(
interner,
interner.tcx,
self.bound_atom_with_opt_escaping(interner.tcx),
);
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, self.bound_atom());
let value = match predicate {
ty::PredicateAtom::Trait(predicate, _) => {
@ -573,11 +567,8 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
self,
interner: &RustInterner<'tcx>,
) -> Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> {
let (predicate, binders, _named_regions) = collect_bound_vars(
interner,
interner.tcx,
self.bound_atom_with_opt_escaping(interner.tcx),
);
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, self.bound_atom());
let value = match predicate {
ty::PredicateAtom::Trait(predicate, _) => {
Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)))
@ -707,11 +698,8 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
self,
interner: &RustInterner<'tcx>,
) -> Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>> {
let (predicate, binders, _named_regions) = collect_bound_vars(
interner,
interner.tcx,
self.bound_atom_with_opt_escaping(interner.tcx),
);
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, self.bound_atom());
match predicate {
ty::PredicateAtom::Trait(predicate, _) => Some(chalk_ir::Binders::new(
binders,

View file

@ -544,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.infcx.instantiate_opaque_types(id, self.body_id, self.param_env, ty, span);
let mut suggest_box = !impl_trait_ret_ty.obligations.is_empty();
for o in impl_trait_ret_ty.obligations {
match o.predicate.skip_binders_unchecked() {
match o.predicate.bound_atom().skip_binder() {
ty::PredicateAtom::Trait(t, constness) => {
let pred = ty::PredicateAtom::Trait(
ty::TraitPredicate {

View file

@ -1949,7 +1949,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
let predicate = ty::Binder::bind(ty::PredicateAtom::TypeOutlives(
ty::OutlivesPredicate(ty, re_root_empty),
));
predicates.insert((predicate.potentially_quantified(tcx), span));
predicates.insert((predicate.to_predicate(tcx), span));
}
}
@ -1993,7 +1993,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
ty::Binder::bind(ty::PredicateAtom::TypeOutlives(
ty::OutlivesPredicate(ty, region),
))
.potentially_quantified(tcx),
.to_predicate(tcx),
lifetime.span,
));
}

View file

@ -30,13 +30,10 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate
if tcx.has_attr(item_def_id, sym::rustc_outlives) {
let mut pred: Vec<String> = predicates
.iter()
.map(|(out_pred, _)| {
let binder = out_pred.bound_atom();
match binder.skip_binder() {
ty::PredicateAtom::RegionOutlives(p) => p.to_string(),
ty::PredicateAtom::TypeOutlives(p) => p.to_string(),
err => bug!("unexpected predicate {:?}", err),
}
.map(|(out_pred, _)| match out_pred.bound_atom().skip_binder() {
ty::PredicateAtom::RegionOutlives(p) => p.to_string(),
ty::PredicateAtom::TypeOutlives(p) => p.to_string(),
err => bug!("unexpected predicate {:?}", err),
})
.collect();
pred.sort();

View file

@ -1686,7 +1686,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
.filter_map(|bound| {
// Note: The substs of opaque types can contain unbound variables,
// meaning that we have to use `ignore_quantifiers_with_unbound_vars` here.
let bound_predicate = bound.bound_atom_with_opt_escaping(cx.tcx);
let bound_predicate = bound.bound_atom();
let trait_ref = match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(tr, _constness) => {
bound_predicate.rebind(tr.trait_ref)
@ -1711,7 +1711,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
.iter()
.filter_map(|bound| {
if let ty::PredicateAtom::Projection(proj) =
bound.bound_atom_with_opt_escaping(cx.tcx).skip_binder()
bound.bound_atom().skip_binder()
{
if proj.projection_ty.trait_ref(cx.tcx)
== trait_ref.skip_binder()

View file

@ -115,8 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
.filter(|p| !p.is_global())
.filter_map(|obligation| {
// Note that we do not want to deal with qualified predicates here.
let binder = obligation.predicate.bound_atom();
match binder.skip_binder() {
match obligation.predicate.bound_atom().skip_binder() {
ty::PredicateAtom::Trait(pred, _) if !pred.has_escaping_bound_vars() => {
if pred.def_id() == sized_trait {
return None;