Skip to content

A lot of refactoring to remove more Binder::binds #80106

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

Merged
merged 2 commits into from
Dec 19, 2020
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
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