More rebinds
This commit is contained in:
parent
af3b1cb0b5
commit
5e7095850c
24 changed files with 152 additions and 148 deletions
|
@ -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()),
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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!(
|
||||
|
@ -1440,7 +1435,7 @@ 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
|
||||
|
@ -1448,10 +1443,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
});
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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>(
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -1276,7 +1276,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
// FIXME(generic_associated_types): Compare the whole projections
|
||||
let data_poly_trait_ref = projection_ty.map_bound(|proj| proj.trait_ref(self.tcx()));
|
||||
let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
|
||||
let obligation_poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref);
|
||||
self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation_poly_trait_ref, data_poly_trait_ref)
|
||||
|
@ -1648,8 +1648,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
/// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
|
||||
/// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
|
||||
/// ```
|
||||
fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
|
||||
match *t.kind() {
|
||||
fn constituent_types_for_ty(&self, t: ty::Binder<Ty<'tcx>>) -> ty::Binder<Vec<Ty<'tcx>>> {
|
||||
match *t.skip_binder().kind() {
|
||||
ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
| ty::Bool
|
||||
|
@ -1660,7 +1660,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Error(_)
|
||||
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||
| ty::Never
|
||||
| ty::Char => Vec::new(),
|
||||
| ty::Char => ty::Binder::dummy(Vec::new()),
|
||||
|
||||
ty::Placeholder(..)
|
||||
| ty::Dynamic(..)
|
||||
|
@ -1673,44 +1673,44 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => {
|
||||
vec![element_ty]
|
||||
t.rebind(vec![element_ty])
|
||||
}
|
||||
|
||||
ty::Array(element_ty, _) | ty::Slice(element_ty) => vec![element_ty],
|
||||
ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]),
|
||||
|
||||
ty::Tuple(ref tys) => {
|
||||
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
|
||||
tys.iter().map(|k| k.expect_ty()).collect()
|
||||
t.rebind(tys.iter().map(|k| k.expect_ty()).collect())
|
||||
}
|
||||
|
||||
ty::Closure(_, ref substs) => {
|
||||
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
|
||||
vec![ty]
|
||||
t.rebind(vec![ty])
|
||||
}
|
||||
|
||||
ty::Generator(_, ref substs, _) => {
|
||||
let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
|
||||
let witness = substs.as_generator().witness();
|
||||
vec![ty].into_iter().chain(iter::once(witness)).collect()
|
||||
t.rebind(vec![ty].into_iter().chain(iter::once(witness)).collect())
|
||||
}
|
||||
|
||||
ty::GeneratorWitness(types) => {
|
||||
// This is sound because no regions in the witness can refer to
|
||||
// the binder outside the witness. So we'll effectivly reuse
|
||||
// the implicit binder around the witness.
|
||||
types.skip_binder().to_vec()
|
||||
debug_assert!(!types.has_escaping_bound_vars());
|
||||
types.map_bound(|types| types.to_vec())
|
||||
}
|
||||
|
||||
// For `PhantomData<T>`, we pass `T`.
|
||||
ty::Adt(def, substs) if def.is_phantom_data() => substs.types().collect(),
|
||||
ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()),
|
||||
|
||||
ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect(),
|
||||
ty::Adt(def, substs) => {
|
||||
t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
|
||||
}
|
||||
|
||||
ty::Opaque(def_id, substs) => {
|
||||
// We can resolve the `impl Trait` to its concrete type,
|
||||
// which enforces a DAG between the functions requiring
|
||||
// the auto trait bounds in question.
|
||||
vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]
|
||||
t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1738,10 +1738,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
|
||||
|
||||
types
|
||||
.as_ref()
|
||||
.skip_binder() // binder moved -\
|
||||
.iter()
|
||||
.flat_map(|ty| {
|
||||
let ty: ty::Binder<Ty<'tcx>> = ty::Binder::bind(ty); // <----/
|
||||
let ty: ty::Binder<Ty<'tcx>> = types.rebind(ty); // <----/
|
||||
|
||||
self.infcx.commit_unconditionally(|_| {
|
||||
let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty);
|
||||
|
|
|
@ -6,7 +6,7 @@ use smallvec::SmallVec;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
|
||||
use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
|
||||
pub use rustc_infer::traits::util::*;
|
||||
|
@ -333,11 +333,12 @@ pub fn closure_trait_ref_and_return_type(
|
|||
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
|
||||
TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
|
||||
};
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]),
|
||||
};
|
||||
ty::Binder::bind((trait_ref, sig.skip_binder().output()))
|
||||
sig.map_bound(|sig| (trait_ref, sig.output()))
|
||||
}
|
||||
|
||||
pub fn generator_trait_ref_and_outputs(
|
||||
|
@ -346,11 +347,12 @@ pub fn generator_trait_ref_and_outputs(
|
|||
self_ty: Ty<'tcx>,
|
||||
sig: ty::PolyGenSig<'tcx>,
|
||||
) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]),
|
||||
};
|
||||
ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
|
||||
sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
|
||||
}
|
||||
|
||||
pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue