Skip to content

Commit

Permalink
Auto merge of #80106 - jackh726:binder-refactor-part-2, r=lcnr
Browse files Browse the repository at this point in the history
A lot of refactoring to remove more `Binder::bind`s

Split out from #76814
  • Loading branch information
bors committed Dec 19, 2020
2 parents e461b81 + 5e70958 commit 8bb302d
Show file tree
Hide file tree
Showing 25 changed files with 175 additions and 157 deletions.
11 changes: 6 additions & 5 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,10 +525,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
result_subst: &'a CanonicalVarValues<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx> {
unsubstituted_region_constraints.iter().map(move |&constraint| {
let ty::OutlivesPredicate(k1, r2) =
substitute_value(self.tcx, result_subst, constraint).skip_binder();
let predicate = substitute_value(self.tcx, result_subst, constraint);
let ty::OutlivesPredicate(k1, r2) = predicate.skip_binder();

let predicate = match k1.unpack() {
let atom = match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2))
}
Expand All @@ -540,8 +540,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// encounter this branch.
span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
}
}
.potentially_quantified(self.tcx, ty::PredicateKind::ForAll);
};
let predicate =
predicate.rebind(atom).potentially_quantified(self.tcx, ty::PredicateKind::ForAll);

Obligation::new(cause.clone(), param_env, predicate)
})
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
where
T: Relate<'tcx>,
{
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}

fn relate_item_substs(
Expand Down Expand Up @@ -833,7 +833,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
where
T: Relate<'tcx>,
{
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}

fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,6 @@ where
self.first_free_index.shift_in(1);
let result = self.relate(a.skip_binder(), a.skip_binder())?;
self.first_free_index.shift_out(1);
Ok(ty::Binder::bind(result))
Ok(a.rebind(result))
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,6 @@ impl TypeRelation<'tcx> for Match<'tcx> {
where
T: Relate<'tcx>,
{
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}
}
5 changes: 3 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ pub struct ResolvedOpaqueTy<'tcx> {
/// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
/// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
#[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
#[derive(TypeFoldable)]
pub struct GeneratorInteriorTypeCause<'tcx> {
/// Type of the captured binding.
pub ty: Ty<'tcx>,
Expand Down Expand Up @@ -423,7 +424,7 @@ pub struct TypeckResults<'tcx> {

/// Stores the type, expression, span and optional scope span of all types
/// that are live across the yield of this generator (if a generator).
pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
pub generator_interior_types: ty::Binder<Vec<GeneratorInteriorTypeCause<'tcx>>>,

/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
/// as `&[u8]`, depending on the pattern in which they are used.
Expand Down Expand Up @@ -455,7 +456,7 @@ impl<'tcx> TypeckResults<'tcx> {
concrete_opaque_types: Default::default(),
closure_captures: Default::default(),
closure_min_captures: Default::default(),
generator_interior_types: Default::default(),
generator_interior_types: ty::Binder::dummy(Default::default()),
treat_byte_string_as_slice: Default::default(),
}
}
Expand Down
38 changes: 24 additions & 14 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,17 +1149,16 @@ pub enum PredicateAtom<'tcx> {
TypeWellFormedFromEnv(Ty<'tcx>),
}

impl<'tcx> PredicateAtom<'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>,
qualifier: impl FnOnce(Binder<PredicateAtom<'tcx>>) -> PredicateKind<'tcx>,
) -> Predicate<'tcx> {
if self.has_escaping_bound_vars() {
qualifier(Binder::bind(self))
} else {
PredicateKind::Atom(self)
match self.no_bound_vars() {
Some(atom) => PredicateKind::Atom(atom),
None => qualifier(self),
}
.to_predicate(tcx)
}
Expand Down Expand Up @@ -1252,7 +1251,11 @@ 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 { new.potentially_quantified(tcx, PredicateKind::ForAll) } else { self }
if new != pred {
ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll)
} else {
self
}
}
}

Expand All @@ -1279,6 +1282,10 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
// Ok to skip binder since trait `DefId` does not care about regions.
self.skip_binder().def_id()
}

pub fn self_ty(self) -> ty::Binder<Ty<'tcx>> {
self.map_bound(|trait_ref| trait_ref.self_ty())
}
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
Expand Down Expand Up @@ -1403,37 +1410,39 @@ 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> {
PredicateAtom::Trait(self.value.skip_binder(), self.constness)
self.value
.map_bound(|value| PredicateAtom::Trait(value, self.constness))
.potentially_quantified(tcx, PredicateKind::ForAll)
}
}

impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateAtom::RegionOutlives(self.skip_binder())
self.map_bound(|value| PredicateAtom::RegionOutlives(value))
.potentially_quantified(tcx, PredicateKind::ForAll)
}
}

impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateAtom::TypeOutlives(self.skip_binder())
self.map_bound(|value| PredicateAtom::TypeOutlives(value))
.potentially_quantified(tcx, PredicateKind::ForAll)
}
}

impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateAtom::Projection(self.skip_binder())
self.map_bound(|value| PredicateAtom::Projection(value))
.potentially_quantified(tcx, PredicateKind::ForAll)
}
}

impl<'tcx> Predicate<'tcx> {
pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
match self.skip_binders() {
let predicate = self.bound_atom();
match predicate.skip_binder() {
PredicateAtom::Trait(t, constness) => {
Some(ConstnessAnd { constness, value: ty::Binder::bind(t.trait_ref) })
Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) })
}
PredicateAtom::Projection(..)
| PredicateAtom::Subtype(..)
Expand All @@ -1449,8 +1458,9 @@ impl<'tcx> Predicate<'tcx> {
}

pub fn to_opt_type_outlives(self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
match self.skip_binders() {
PredicateAtom::TypeOutlives(data) => Some(ty::Binder::bind(data)),
let predicate = self.bound_atom();
match predicate.skip_binder() {
PredicateAtom::TypeOutlives(data) => Some(predicate.rebind(data)),
PredicateAtom::Trait(..)
| PredicateAtom::Projection(..)
| PredicateAtom::Subtype(..)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1151,9 +1151,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
) -> DiagnosticBuilder<'tcx> {
crate fn build_fn_sig_string<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> String {
let inputs = trait_ref.substs.type_at(1);
let inputs = trait_ref.skip_binder().substs.type_at(1);
let sig = if let ty::Tuple(inputs) = inputs.kind() {
tcx.mk_fn_sig(
inputs.iter().map(|k| k.expect_ty()),
Expand All @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
abi::Abi::Rust,
)
};
ty::Binder::bind(sig).to_string()
trait_ref.rebind(sig).to_string()
}

let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
Expand All @@ -1183,17 +1183,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if argument_is_closure { "closure" } else { "function" }
);

let found_str = format!(
"expected signature of `{}`",
build_fn_sig_string(self.tcx, found.skip_binder())
);
let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));
err.span_label(span, found_str);

let found_span = found_span.unwrap_or(span);
let expected_str = format!(
"found signature of `{}`",
build_fn_sig_string(self.tcx, expected_ref.skip_binder())
);
let expected_str =
format!("found signature of `{}`", build_fn_sig_string(self.tcx, expected_ref));
err.span_label(found_span, expected_str);

err
Expand Down Expand Up @@ -1422,7 +1417,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// generator frame. Bound regions are preserved by
// `erase_regions` and so we must also call
// `erase_late_bound_regions`.
let ty_erased = self.tcx.erase_late_bound_regions(ty::Binder::bind(ty));
let ty_erased = self.tcx.erase_late_bound_regions(ty);
let ty_erased = self.tcx.erase_regions(ty_erased);
let eq = ty::TyS::same_type(ty_erased, target_ty_erased);
debug!(
Expand All @@ -1440,18 +1435,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
interior_or_upvar_span = upvars.iter().find_map(|(upvar_id, upvar)| {
let upvar_ty = typeck_results.node_type(*upvar_id);
let upvar_ty = self.resolve_vars_if_possible(upvar_ty);
if ty_matches(&upvar_ty) {
if ty_matches(ty::Binder::dummy(upvar_ty)) {
Some(GeneratorInteriorOrUpvar::Upvar(upvar.span))
} else {
None
}
});
};

if let Some(cause) = typeck_results
.generator_interior_types
.iter()
.find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty))
// The generator interior types share the same binders
if let Some(cause) =
typeck_results.generator_interior_types.as_ref().skip_binder().iter().find(
|ty::GeneratorInteriorTypeCause { ty, .. }| {
ty_matches(typeck_results.generator_interior_types.rebind(ty))
},
)
{
// Check to see if any awaited expressions have the target type.
let from_awaited_ty = visitor
Expand All @@ -1464,7 +1462,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
"maybe_note_obligation_cause_for_async_await: await_expr={:?}",
await_expr
);
ty_matches(ty)
ty_matches(ty::Binder::dummy(ty))
})
.map(|expr| expr.span);
let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,11 @@ fn virtual_call_violation_for_method<'tcx>(
}

for (i, &input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() {
if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) {
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.rebind(input_ty)) {
return Some(MethodViolationCode::ReferencesSelfInput(i));
}
}
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) {
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
return Some(MethodViolationCode::ReferencesSelfOutput);
}

Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(

// If we are resolving `<T as TraitRef<...>>::Item == Type`,
// start out by selecting the predicate `T as TraitRef<...>`:
let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
let poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref);
let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
let _ = selcx.infcx().commit_if_ok(|_| {
let impl_source = match selcx.select(&trait_obligation) {
Expand Down Expand Up @@ -1247,7 +1247,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
ty: self_ty.discriminant_ty(tcx),
};

confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate), false)
// We get here from `poly_project_and_unify_type` which replaces bound vars
// with placeholders, so dummy is okay here.
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
}

fn confirm_fn_pointer_candidate<'cx, 'tcx>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
debug!(?obligation, ?trait_def_id, "confirm_auto_impl_candidate");

let types = obligation.predicate.map_bound(|inner| {
let self_ty = self.infcx.shallow_resolve(inner.self_ty());
self.constituent_types_for_ty(self_ty)
});
let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty());
let types = self.constituent_types_for_ty(self_ty);
self.vtable_auto_impl(obligation, trait_def_id, types)
}

Expand Down
Loading

0 comments on commit 8bb302d

Please sign in to comment.