Auto merge of #77685 - jackh726:binder-map, r=lcnr
Use rebind instead of Binder::bind when possible These are really only the easy places. I just searched for `Binder::bind` and replaced where it straightforward. r? `@lcnr` cc. `@nikomatsakis`
This commit is contained in:
commit
6f0ea299cf
24 changed files with 194 additions and 139 deletions
|
@ -673,17 +673,9 @@ fn codegen_emcc_try(
|
|||
fn gen_fn<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
name: &str,
|
||||
inputs: Vec<Ty<'tcx>>,
|
||||
output: Ty<'tcx>,
|
||||
rust_fn_sig: ty::PolyFnSig<'tcx>,
|
||||
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
||||
) -> &'ll Value {
|
||||
let rust_fn_sig = ty::Binder::bind(cx.tcx.mk_fn_sig(
|
||||
inputs.into_iter(),
|
||||
output,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust,
|
||||
));
|
||||
let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]);
|
||||
let llfn = cx.declare_fn(name, &fn_abi);
|
||||
cx.set_frame_pointer_elimination(llfn);
|
||||
|
@ -710,22 +702,31 @@ fn get_rust_try_fn<'ll, 'tcx>(
|
|||
// Define the type up front for the signature of the rust_try function.
|
||||
let tcx = cx.tcx;
|
||||
let i8p = tcx.mk_mut_ptr(tcx.types.i8);
|
||||
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
|
||||
// `unsafe fn(*mut i8) -> ()`
|
||||
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
iter::once(i8p),
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust,
|
||||
)));
|
||||
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
|
||||
// `unsafe fn(*mut i8, *mut i8) -> ()`
|
||||
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
[i8p, i8p].iter().cloned(),
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust,
|
||||
)));
|
||||
let output = tcx.types.i32;
|
||||
let rust_try = gen_fn(cx, "__rust_try", vec![try_fn_ty, i8p, catch_fn_ty], output, codegen);
|
||||
// `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
|
||||
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
|
||||
vec![try_fn_ty, i8p, catch_fn_ty].into_iter(),
|
||||
tcx.types.i32,
|
||||
false,
|
||||
hir::Unsafety::Unsafe,
|
||||
Abi::Rust,
|
||||
));
|
||||
let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
|
||||
cx.rust_try_fn.set(Some(rust_try));
|
||||
rust_try
|
||||
}
|
||||
|
|
|
@ -636,7 +636,7 @@ where
|
|||
if let (Some(a), Some(b)) = (a.no_bound_vars(), b.no_bound_vars()) {
|
||||
// Fast path for the common case.
|
||||
self.relate(a, b)?;
|
||||
return Ok(ty::Binder::bind(a));
|
||||
return Ok(ty::Binder::dummy(a));
|
||||
}
|
||||
|
||||
if self.ambient_covariance() {
|
||||
|
|
|
@ -126,14 +126,15 @@ impl Elaborator<'tcx> {
|
|||
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
|
||||
let tcx = self.visited.tcx;
|
||||
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(data, _) => {
|
||||
// Get predicates declared on the trait.
|
||||
let predicates = tcx.super_predicates_of(data.def_id());
|
||||
|
||||
let obligations = predicates.predicates.iter().map(|&(pred, _)| {
|
||||
predicate_obligation(
|
||||
pred.subst_supertrait(tcx, &ty::Binder::bind(data.trait_ref)),
|
||||
pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
)
|
||||
|
|
|
@ -1056,9 +1056,21 @@ impl<'tcx> Predicate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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>> {
|
||||
match self.kind() {
|
||||
&PredicateKind::ForAll(binder) => binder,
|
||||
&PredicateKind::Atom(atom) => {
|
||||
debug_assert!(!atom.has_escaping_bound_vars());
|
||||
Binder::dummy(atom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows using a `Binder<PredicateAtom<'tcx>>` even if the given predicate previously
|
||||
/// contained unbound variables by shifting these variables outwards.
|
||||
pub fn bound_atom(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
|
||||
pub fn bound_atom_with_opt_escaping(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
|
||||
match self.kind() {
|
||||
&PredicateKind::ForAll(binder) => binder,
|
||||
&PredicateKind::Atom(atom) => Binder::wrap_nonbinding(tcx, atom),
|
||||
|
|
|
@ -618,10 +618,9 @@ pub trait PrettyPrinter<'tcx>:
|
|||
// may contain unbound variables. We therefore do this manually.
|
||||
//
|
||||
// FIXME(lcnr): Find out why exactly this is the case :)
|
||||
if let ty::PredicateAtom::Trait(pred, _) =
|
||||
predicate.bound_atom(self.tcx()).skip_binder()
|
||||
{
|
||||
let trait_ref = ty::Binder::bind(pred.trait_ref);
|
||||
let bound_predicate = predicate.bound_atom_with_opt_escaping(self.tcx());
|
||||
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.
|
||||
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
|
||||
is_sized = true;
|
||||
|
|
|
@ -549,7 +549,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> {
|
|||
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
|
||||
type Lifted = ty::Binder<T::Lifted>;
|
||||
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(self.as_ref().skip_binder()).map(ty::Binder::bind)
|
||||
tcx.lift(self.as_ref().skip_binder()).map(|v| self.rebind(v))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -703,14 +703,16 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
|
|||
use crate::ty::ToPredicate;
|
||||
match self.skip_binder() {
|
||||
ExistentialPredicate::Trait(tr) => {
|
||||
Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
|
||||
self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
|
||||
}
|
||||
ExistentialPredicate::Projection(p) => {
|
||||
Binder(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
||||
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
||||
}
|
||||
ExistentialPredicate::AutoTrait(did) => {
|
||||
let trait_ref =
|
||||
Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) });
|
||||
let trait_ref = self.rebind(ty::TraitRef {
|
||||
def_id: did,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[]),
|
||||
});
|
||||
trait_ref.without_const().to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
@ -775,7 +777,7 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
|
|||
|
||||
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
|
||||
pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
|
||||
self.skip_binder().principal().map(Binder::bind)
|
||||
self.map_bound(|b| b.principal()).transpose()
|
||||
}
|
||||
|
||||
pub fn principal_def_id(&self) -> Option<DefId> {
|
||||
|
@ -858,8 +860,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
|||
}
|
||||
|
||||
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
|
||||
// Note that we preserve binding levels
|
||||
Binder(ty::TraitPredicate { trait_ref: self.skip_binder() })
|
||||
self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1001,6 +1002,19 @@ impl<T> Binder<T> {
|
|||
Binder(f(self.0))
|
||||
}
|
||||
|
||||
/// Wraps a `value` in a binder, using the same bound variables as the
|
||||
/// current `Binder`. This should not be used if the new value *changes*
|
||||
/// the bound variables. Note: the (old or new) value itself does not
|
||||
/// necessarily need to *name* all the bound variables.
|
||||
///
|
||||
/// This currently doesn't do anything different than `bind`, because we
|
||||
/// don't actually track bound vars. However, semantically, it is different
|
||||
/// because bound vars aren't allowed to change here, whereas they are
|
||||
/// in `bind`. This may be (debug) asserted in the future.
|
||||
pub fn rebind<U>(&self, value: U) -> Binder<U> {
|
||||
Binder(value)
|
||||
}
|
||||
|
||||
/// Unwraps and returns the value within, but only if it contains
|
||||
/// no bound vars at all. (In other words, if this binder --
|
||||
/// and indeed any enclosing binder -- doesn't bind anything at
|
||||
|
|
|
@ -642,7 +642,8 @@ impl AutoTraitFinder<'tcx> {
|
|||
// We check this by calling is_of_param on the relevant types
|
||||
// from the various possible predicates
|
||||
|
||||
match predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(p, _) => {
|
||||
if self.is_param_no_infer(p.trait_ref.substs)
|
||||
&& !only_projections
|
||||
|
@ -650,10 +651,10 @@ impl AutoTraitFinder<'tcx> {
|
|||
{
|
||||
self.add_user_pred(computed_preds, predicate);
|
||||
}
|
||||
predicates.push_back(ty::Binder::bind(p));
|
||||
predicates.push_back(bound_predicate.rebind(p));
|
||||
}
|
||||
ty::PredicateAtom::Projection(p) => {
|
||||
let p = ty::Binder::bind(p);
|
||||
let p = bound_predicate.rebind(p);
|
||||
debug!(
|
||||
"evaluate_nested_obligations: examining projection predicate {:?}",
|
||||
predicate
|
||||
|
@ -783,13 +784,13 @@ impl AutoTraitFinder<'tcx> {
|
|||
}
|
||||
}
|
||||
ty::PredicateAtom::RegionOutlives(binder) => {
|
||||
let binder = ty::Binder::bind(binder);
|
||||
let binder = bound_predicate.rebind(binder);
|
||||
if select.infcx().region_outlives_predicate(&dummy_cause, binder).is_err() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ty::PredicateAtom::TypeOutlives(binder) => {
|
||||
let binder = ty::Binder::bind(binder);
|
||||
let binder = bound_predicate.rebind(binder);
|
||||
match (
|
||||
binder.no_bound_vars(),
|
||||
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
|
||||
|
|
|
@ -255,9 +255,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(trait_predicate, _) => {
|
||||
let trait_predicate = ty::Binder::bind(trait_predicate);
|
||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
||||
let trait_predicate = self.resolve_vars_if_possible(&trait_predicate);
|
||||
|
||||
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
|
||||
|
@ -531,7 +532,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ty::PredicateAtom::RegionOutlives(predicate) => {
|
||||
let predicate = ty::Binder::bind(predicate);
|
||||
let predicate = bound_predicate.rebind(predicate);
|
||||
let predicate = self.resolve_vars_if_possible(&predicate);
|
||||
let err = self
|
||||
.region_outlives_predicate(&obligation.cause, predicate)
|
||||
|
@ -1078,9 +1079,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
|
||||
let (cond, error) = match (cond.skip_binders(), error.skip_binders()) {
|
||||
let bound_error = error.bound_atom();
|
||||
let (cond, error) = match (cond.skip_binders(), bound_error.skip_binder()) {
|
||||
(ty::PredicateAtom::Trait(..), ty::PredicateAtom::Trait(error, _)) => {
|
||||
(cond, ty::Binder::bind(error))
|
||||
(cond, bound_error.rebind(error))
|
||||
}
|
||||
_ => {
|
||||
// FIXME: make this work in other cases too.
|
||||
|
@ -1089,9 +1091,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
|
||||
if let ty::PredicateAtom::Trait(implication, _) = obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
if let ty::PredicateAtom::Trait(implication, _) = bound_predicate.skip_binder() {
|
||||
let error = error.to_poly_trait_ref();
|
||||
let implication = ty::Binder::bind(implication.trait_ref);
|
||||
let implication = bound_predicate.rebind(implication.trait_ref);
|
||||
// FIXME: I'm just not taking associated types at all here.
|
||||
// Eventually I'll need to implement param-env-aware
|
||||
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
|
||||
|
@ -1169,12 +1172,13 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
//
|
||||
// this can fail if the problem was higher-ranked, in which
|
||||
// cause I have no idea for a good error message.
|
||||
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom();
|
||||
if let ty::PredicateAtom::Projection(data) = bound_predicate.skip_binder() {
|
||||
let mut selcx = SelectionContext::new(self);
|
||||
let (data, _) = self.replace_bound_vars_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
infer::LateBoundRegionConversionTime::HigherRankedType,
|
||||
&ty::Binder::bind(data),
|
||||
&bound_predicate.rebind(data),
|
||||
);
|
||||
let mut obligations = vec![];
|
||||
let normalized_ty = super::normalize_projection_type(
|
||||
|
@ -1455,10 +1459,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut err = match predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom();
|
||||
let mut err = match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(data, _) => {
|
||||
let trait_ref = ty::Binder::bind(data.trait_ref);
|
||||
let self_ty = trait_ref.skip_binder().self_ty();
|
||||
let self_ty = data.trait_ref.self_ty();
|
||||
let trait_ref = bound_predicate.rebind(data.trait_ref);
|
||||
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind(), trait_ref);
|
||||
|
||||
if predicate.references_error() {
|
||||
|
@ -1582,7 +1587,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282)
|
||||
}
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
|
||||
let trait_ref = bound_predicate.rebind(data).to_poly_trait_ref(self.tcx);
|
||||
let self_ty = trait_ref.skip_binder().self_ty();
|
||||
let ty = data.ty;
|
||||
if predicate.references_error() {
|
||||
|
|
|
@ -353,7 +353,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
// This means we need to pass it the bound version of our
|
||||
// predicate.
|
||||
ty::PredicateAtom::Trait(trait_ref, _constness) => {
|
||||
let trait_obligation = obligation.with(Binder::bind(trait_ref));
|
||||
let trait_obligation = obligation.with(binder.rebind(trait_ref));
|
||||
|
||||
self.process_trait_obligation(
|
||||
obligation,
|
||||
|
@ -362,7 +362,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
)
|
||||
}
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let project_obligation = obligation.with(Binder::bind(data));
|
||||
let project_obligation = obligation.with(binder.rebind(data));
|
||||
|
||||
self.process_projection_obligation(
|
||||
project_obligation,
|
||||
|
|
|
@ -623,7 +623,8 @@ fn prune_cache_value_obligations<'a, 'tcx>(
|
|||
.obligations
|
||||
.iter()
|
||||
.filter(|obligation| {
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
// We found a `T: Foo<X = U>` predicate, let's check
|
||||
// if `U` references any unresolved type
|
||||
// variables. In principle, we only care if this
|
||||
|
@ -634,7 +635,7 @@ fn prune_cache_value_obligations<'a, 'tcx>(
|
|||
// but we have `T: Foo<X = ?1>` and `?1: Bar<X =
|
||||
// ?0>`).
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
infcx.unresolved_type_vars(&ty::Binder::bind(data.ty)).is_some()
|
||||
infcx.unresolved_type_vars(&bound_predicate.rebind(data.ty)).is_some()
|
||||
}
|
||||
|
||||
// We are only interested in `T: Foo<X = U>` predicates, whre
|
||||
|
@ -907,8 +908,9 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
|||
let infcx = selcx.infcx();
|
||||
for predicate in env_predicates {
|
||||
debug!(?predicate);
|
||||
let bound_predicate = predicate.bound_atom();
|
||||
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() {
|
||||
let data = ty::Binder::bind(data);
|
||||
let data = bound_predicate.rebind(data);
|
||||
let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
|
||||
|
||||
let is_match = same_def_id
|
||||
|
|
|
@ -449,16 +449,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
let result = ensure_sufficient_stack(|| {
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(t, _) => {
|
||||
let t = ty::Binder::bind(t);
|
||||
let t = bound_predicate.rebind(t);
|
||||
debug_assert!(!t.has_escaping_bound_vars());
|
||||
let obligation = obligation.with(t);
|
||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
|
||||
ty::PredicateAtom::Subtype(p) => {
|
||||
let p = ty::Binder::bind(p);
|
||||
let p = bound_predicate.rebind(p);
|
||||
// Does this code ever run?
|
||||
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
|
||||
Some(Ok(InferOk { mut obligations, .. })) => {
|
||||
|
@ -502,7 +503,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let data = ty::Binder::bind(data);
|
||||
let data = bound_predicate.rebind(data);
|
||||
let project_obligation = obligation.with(data);
|
||||
match project::poly_project_and_unify_type(self, &project_obligation) {
|
||||
Ok(Ok(Some(mut subobligations))) => {
|
||||
|
@ -1174,8 +1175,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, bound)| {
|
||||
if let ty::PredicateAtom::Trait(pred, _) = bound.skip_binders() {
|
||||
let bound = ty::Binder::bind(pred.trait_ref);
|
||||
let bound_predicate = bound.bound_atom();
|
||||
if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
|
||||
let bound = bound_predicate.rebind(pred.trait_ref);
|
||||
if self.infcx.probe(|_| {
|
||||
match self.match_projection(
|
||||
obligation,
|
||||
|
@ -1529,16 +1531,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
Where(ty::Binder::bind(tys.last().into_iter().map(|k| k.expect_ty()).collect()))
|
||||
}
|
||||
ty::Tuple(tys) => Where(
|
||||
obligation
|
||||
.predicate
|
||||
.rebind(tys.last().into_iter().map(|k| k.expect_ty()).collect()),
|
||||
),
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
let sized_crit = def.sized_constraint(self.tcx());
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(
|
||||
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect(),
|
||||
))
|
||||
Where(
|
||||
obligation.predicate.rebind({
|
||||
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect()
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None,
|
||||
|
@ -1561,7 +1567,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
use self::BuiltinImplConditions::{Ambiguous, None, Where};
|
||||
|
||||
match self_ty.kind() {
|
||||
match *self_ty.kind() {
|
||||
ty::Infer(ty::IntVar(_))
|
||||
| ty::Infer(ty::FloatVar(_))
|
||||
| ty::FnDef(..)
|
||||
|
@ -1590,12 +1596,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
ty::Array(element_ty, _) => {
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(vec![element_ty]))
|
||||
Where(obligation.predicate.rebind(vec![element_ty]))
|
||||
}
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(tys.iter().map(|k| k.expect_ty()).collect()))
|
||||
Where(obligation.predicate.rebind(tys.iter().map(|k| k.expect_ty()).collect()))
|
||||
}
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
|
@ -1605,7 +1611,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Not yet resolved.
|
||||
Ambiguous
|
||||
} else {
|
||||
Where(ty::Binder::bind(substs.as_closure().upvar_tys().collect()))
|
||||
Where(obligation.predicate.rebind(substs.as_closure().upvar_tys().collect()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,8 +81,11 @@ 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(interner.tcx));
|
||||
let (predicate, binders, _named_regions) = collect_bound_vars(
|
||||
interner,
|
||||
interner.tcx,
|
||||
&predicate.bound_atom_with_opt_escaping(interner.tcx),
|
||||
);
|
||||
let consequence = match predicate {
|
||||
ty::PredicateAtom::TypeWellFormedFromEnv(ty) => {
|
||||
chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner)))
|
||||
|
@ -133,8 +136,11 @@ 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(interner.tcx));
|
||||
let (predicate, binders, _named_regions) = collect_bound_vars(
|
||||
interner,
|
||||
interner.tcx,
|
||||
&self.bound_atom_with_opt_escaping(interner.tcx),
|
||||
);
|
||||
|
||||
let value = match predicate {
|
||||
ty::PredicateAtom::Trait(predicate, _) => {
|
||||
|
@ -653,8 +659,11 @@ 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(interner.tcx));
|
||||
let (predicate, binders, _named_regions) = collect_bound_vars(
|
||||
interner,
|
||||
interner.tcx,
|
||||
&self.bound_atom_with_opt_escaping(interner.tcx),
|
||||
);
|
||||
let value = match predicate {
|
||||
ty::PredicateAtom::Trait(predicate, _) => {
|
||||
Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)))
|
||||
|
@ -762,27 +771,22 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
|
|||
self,
|
||||
interner: &RustInterner<'tcx>,
|
||||
) -> Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>> {
|
||||
match self.bound_atom(interner.tcx).skip_binder() {
|
||||
ty::PredicateAtom::Trait(predicate, _) => {
|
||||
let (predicate, binders, _named_regions) =
|
||||
collect_bound_vars(interner, interner.tcx, &ty::Binder::bind(predicate));
|
||||
|
||||
Some(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_solve::rust_ir::InlineBound::TraitBound(
|
||||
predicate.trait_ref.lower_into(interner),
|
||||
),
|
||||
))
|
||||
}
|
||||
ty::PredicateAtom::Projection(predicate) => {
|
||||
let (predicate, binders, _named_regions) =
|
||||
collect_bound_vars(interner, interner.tcx, &ty::Binder::bind(predicate));
|
||||
|
||||
Some(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)),
|
||||
))
|
||||
}
|
||||
let (predicate, binders, _named_regions) = collect_bound_vars(
|
||||
interner,
|
||||
interner.tcx,
|
||||
&self.bound_atom_with_opt_escaping(interner.tcx),
|
||||
);
|
||||
match predicate {
|
||||
ty::PredicateAtom::Trait(predicate, _) => Some(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_solve::rust_ir::InlineBound::TraitBound(
|
||||
predicate.trait_ref.lower_into(interner),
|
||||
),
|
||||
)),
|
||||
ty::PredicateAtom::Projection(predicate) => Some(chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)),
|
||||
)),
|
||||
ty::PredicateAtom::TypeOutlives(_predicate) => None,
|
||||
ty::PredicateAtom::WellFormed(_ty) => None,
|
||||
|
||||
|
|
|
@ -1095,9 +1095,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
obligation.predicate
|
||||
);
|
||||
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(pred, _) => {
|
||||
let pred = ty::Binder::bind(pred);
|
||||
let pred = bound_predicate.rebind(pred);
|
||||
associated_types.entry(span).or_default().extend(
|
||||
tcx.associated_items(pred.def_id())
|
||||
.in_definition_order()
|
||||
|
@ -1106,7 +1107,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
);
|
||||
}
|
||||
ty::PredicateAtom::Projection(pred) => {
|
||||
let pred = ty::Binder::bind(pred);
|
||||
let pred = bound_predicate.rebind(pred);
|
||||
// A `Self` within the original bound will be substituted with a
|
||||
// `trait_object_dummy_self`, so check for that.
|
||||
let references_self =
|
||||
|
|
|
@ -192,6 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
obligation.predicate
|
||||
);
|
||||
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
if let ty::PredicateAtom::Projection(proj_predicate) =
|
||||
obligation.predicate.skip_binders()
|
||||
{
|
||||
|
@ -199,7 +200,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// the complete signature.
|
||||
self.deduce_sig_from_projection(
|
||||
Some(obligation.cause.span),
|
||||
ty::Binder::bind(proj_predicate),
|
||||
bound_predicate.rebind(proj_predicate),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -583,7 +583,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
while !queue.is_empty() {
|
||||
let obligation = queue.remove(0);
|
||||
debug!("coerce_unsized resolve step: {:?}", obligation);
|
||||
let trait_pred = match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom();
|
||||
let trait_pred = match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(trait_pred, _)
|
||||
if traits.contains(&trait_pred.def_id()) =>
|
||||
{
|
||||
|
@ -594,7 +595,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||
has_unsized_tuple_coercion = true;
|
||||
}
|
||||
}
|
||||
ty::Binder::bind(trait_pred)
|
||||
bound_predicate.rebind(trait_pred)
|
||||
}
|
||||
_ => {
|
||||
coercion.obligations.push(obligation);
|
||||
|
|
|
@ -226,12 +226,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
|||
// could be extended easily also to the other `Predicate`.
|
||||
let predicate_matches_closure = |p: Predicate<'tcx>| {
|
||||
let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
|
||||
match (predicate.skip_binders(), p.skip_binders()) {
|
||||
let predicate = predicate.bound_atom();
|
||||
let p = p.bound_atom();
|
||||
match (predicate.skip_binder(), p.skip_binder()) {
|
||||
(ty::PredicateAtom::Trait(a, _), ty::PredicateAtom::Trait(b, _)) => {
|
||||
relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok()
|
||||
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
|
||||
}
|
||||
(ty::PredicateAtom::Projection(a), ty::PredicateAtom::Projection(b)) => {
|
||||
relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok()
|
||||
relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
|
||||
}
|
||||
_ => predicate == p,
|
||||
}
|
||||
|
|
|
@ -328,14 +328,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
|
||||
kw::Try => {
|
||||
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
|
||||
let try_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
|
||||
let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
iter::once(mut_u8),
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::Rust,
|
||||
));
|
||||
let catch_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
|
||||
let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
[mut_u8, mut_u8].iter().cloned(),
|
||||
tcx.mk_unit(),
|
||||
false,
|
||||
|
|
|
@ -796,29 +796,29 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
// FIXME: do we want to commit to this behavior for param bounds?
|
||||
debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
|
||||
|
||||
let bounds =
|
||||
self.param_env.caller_bounds().iter().map(ty::Predicate::skip_binders).filter_map(
|
||||
|predicate| match predicate {
|
||||
ty::PredicateAtom::Trait(trait_predicate, _) => {
|
||||
match trait_predicate.trait_ref.self_ty().kind() {
|
||||
ty::Param(ref p) if *p == param_ty => {
|
||||
Some(ty::Binder::bind(trait_predicate.trait_ref))
|
||||
}
|
||||
_ => None,
|
||||
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||
let bound_predicate = predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(trait_predicate, _) => {
|
||||
match *trait_predicate.trait_ref.self_ty().kind() {
|
||||
ty::Param(p) if p == param_ty => {
|
||||
Some(bound_predicate.rebind(trait_predicate.trait_ref))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
ty::PredicateAtom::Subtype(..)
|
||||
| ty::PredicateAtom::Projection(..)
|
||||
| ty::PredicateAtom::RegionOutlives(..)
|
||||
| ty::PredicateAtom::WellFormed(..)
|
||||
| ty::PredicateAtom::ObjectSafe(..)
|
||||
| ty::PredicateAtom::ClosureKind(..)
|
||||
| ty::PredicateAtom::TypeOutlives(..)
|
||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||
| ty::PredicateAtom::ConstEquate(..)
|
||||
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||
},
|
||||
);
|
||||
}
|
||||
ty::PredicateAtom::Subtype(..)
|
||||
| ty::PredicateAtom::Projection(..)
|
||||
| ty::PredicateAtom::RegionOutlives(..)
|
||||
| ty::PredicateAtom::WellFormed(..)
|
||||
| ty::PredicateAtom::ObjectSafe(..)
|
||||
| ty::PredicateAtom::ClosureKind(..)
|
||||
| ty::PredicateAtom::TypeOutlives(..)
|
||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||
| ty::PredicateAtom::ConstEquate(..)
|
||||
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
|
||||
}
|
||||
});
|
||||
|
||||
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
|
||||
let trait_ref = this.erase_late_bound_regions(&poly_trait_ref);
|
||||
|
|
|
@ -637,9 +637,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
};
|
||||
let mut format_pred = |pred: ty::Predicate<'tcx>| {
|
||||
match pred.skip_binders() {
|
||||
let bound_predicate = pred.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Projection(pred) => {
|
||||
let pred = ty::Binder::bind(pred);
|
||||
let pred = bound_predicate.rebind(pred);
|
||||
// `<Foo as Iterator>::Item = String`.
|
||||
let trait_ref =
|
||||
pred.skip_binder().projection_ty.trait_ref(self.tcx);
|
||||
|
@ -658,8 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
Some((obligation, trait_ref.self_ty()))
|
||||
}
|
||||
ty::PredicateAtom::Trait(poly_trait_ref, _) => {
|
||||
let poly_trait_ref = ty::Binder::bind(poly_trait_ref);
|
||||
let p = poly_trait_ref.skip_binder().trait_ref;
|
||||
let p = poly_trait_ref.trait_ref;
|
||||
let self_ty = p.self_ty();
|
||||
let path = p.print_only_trait_path();
|
||||
let obligation = format!("{}: {}", self_ty, path);
|
||||
|
|
|
@ -850,7 +850,8 @@ fn bounds_from_generic_predicates<'tcx>(
|
|||
let mut projections = vec![];
|
||||
for (predicate, _) in predicates.predicates {
|
||||
debug!("predicate {:?}", predicate);
|
||||
match predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(trait_predicate, _) => {
|
||||
let entry = types.entry(trait_predicate.self_ty()).or_default();
|
||||
let def_id = trait_predicate.def_id();
|
||||
|
@ -861,7 +862,7 @@ fn bounds_from_generic_predicates<'tcx>(
|
|||
}
|
||||
}
|
||||
ty::PredicateAtom::Projection(projection_pred) => {
|
||||
projections.push(ty::Binder::bind(projection_pred));
|
||||
projections.push(bound_predicate.rebind(projection_pred));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: LocalDefId) {
|
|||
}
|
||||
}
|
||||
|
||||
let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
|
||||
let se_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
[tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(),
|
||||
tcx.types.isize,
|
||||
false,
|
||||
|
|
|
@ -315,12 +315,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
pred: ty::Predicate<'tcx>,
|
||||
) -> FxHashSet<GenericParamDef> {
|
||||
let regions = match pred.skip_binders() {
|
||||
let bound_predicate = pred.bound_atom();
|
||||
let regions = match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(poly_trait_pred, _) => {
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(poly_trait_pred))
|
||||
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_trait_pred))
|
||||
}
|
||||
ty::PredicateAtom::Projection(poly_proj_pred) => {
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(poly_proj_pred))
|
||||
tcx.collect_referenced_late_bound_regions(&bound_predicate.rebind(poly_proj_pred))
|
||||
}
|
||||
_ => return FxHashSet::default(),
|
||||
};
|
||||
|
|
|
@ -1689,7 +1689,10 @@ 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 trait_ref = match bound.bound_atom(cx.tcx).skip_binder() {
|
||||
let trait_ref = match bound
|
||||
.bound_atom_with_opt_escaping(cx.tcx)
|
||||
.skip_binder()
|
||||
{
|
||||
ty::PredicateAtom::Trait(tr, _constness) => {
|
||||
ty::Binder::bind(tr.trait_ref)
|
||||
}
|
||||
|
@ -1713,7 +1716,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
.iter()
|
||||
.filter_map(|bound| {
|
||||
if let ty::PredicateAtom::Projection(proj) =
|
||||
bound.bound_atom(cx.tcx).skip_binder()
|
||||
bound.bound_atom_with_opt_escaping(cx.tcx).skip_binder()
|
||||
{
|
||||
if proj.projection_ty.trait_ref(cx.tcx)
|
||||
== trait_ref.skip_binder()
|
||||
|
|
Loading…
Add table
Reference in a new issue