Add bound_fn_sig

This commit is contained in:
Jack Huey 2022-05-08 15:43:18 -04:00
parent c92248ab9f
commit 6c05e8d009
16 changed files with 59 additions and 36 deletions

View File

@ -1385,8 +1385,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1);
let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2);
let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1);
let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2);
let mut values = self.cmp_fn_sig(&sig1, &sig2);
let path1 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did1, substs1));
let path2 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did2, substs2));
@ -1397,7 +1397,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
(ty::FnDef(did1, substs1), ty::FnPtr(sig2)) => {
let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1);
let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1);
let mut values = self.cmp_fn_sig(&sig1, sig2);
values.0.push_highlighted(format!(
" {{{}}}",
@ -1407,7 +1407,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
(ty::FnPtr(sig1), ty::FnDef(did2, substs2)) => {
let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2);
let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2);
let mut values = self.cmp_fn_sig(sig1, &sig2);
values.1.push_normal(format!(
" {{{}}}",

View File

@ -2749,10 +2749,9 @@ impl<'tcx> ty::Instance<'tcx> {
// `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping
// track of a polymorphization `ParamEnv` to allow normalizing later.
let mut sig = match *ty.kind() {
ty::FnDef(def_id, substs) => EarlyBinder(
tcx.normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id)),
)
.subst(tcx, substs),
ty::FnDef(def_id, substs) => tcx
.normalize_erasing_regions(tcx.param_env(def_id), tcx.bound_fn_sig(def_id))
.subst(tcx, substs),
_ => unreachable!(),
};

View File

@ -589,7 +589,7 @@ pub trait PrettyPrinter<'tcx>:
p!(")")
}
ty::FnDef(def_id, substs) => {
let sig = EarlyBinder(self.tcx().fn_sig(def_id)).subst(self.tcx(), substs);
let sig = self.tcx().bound_fn_sig(def_id).subst(self.tcx(), substs);
p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
}
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),

View File

@ -860,6 +860,27 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
}
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::EarlyBinder<T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
self.try_map_bound(|ty| ty.try_fold_with(folder))
}
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
self.try_map_bound(|ty| ty.try_fold_with(folder))
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.as_ref().0.visit_with(visitor)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.as_ref().0.visit_with(visitor)
}
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,

View File

@ -2180,7 +2180,7 @@ impl<'tcx> Ty<'tcx> {
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
match self.kind() {
FnDef(def_id, substs) => EarlyBinder(tcx.fn_sig(*def_id)).subst(tcx, substs),
FnDef(def_id, substs) => tcx.bound_fn_sig(*def_id).subst(tcx, substs),
FnPtr(f) => *f,
Error(_) => {
// ignore errors (#54954)

View File

@ -596,6 +596,10 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn bound_type_of(self, def_id: DefId) -> EarlyBinder<Ty<'tcx>> {
EarlyBinder(self.type_of(def_id))
}
pub fn bound_fn_sig(self, def_id: DefId) -> EarlyBinder<ty::PolyFnSig<'tcx>> {
EarlyBinder(self.fn_sig(def_id))
}
}
struct OpaqueTypeExpander<'tcx> {

View File

@ -8,7 +8,7 @@ use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, ConstKind, EarlyBinder, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
use rustc_target::spec::abi::Abi;
@ -260,7 +260,7 @@ impl<'tcx> Inliner<'tcx> {
return None;
}
let fn_sig = EarlyBinder(self.tcx.fn_sig(def_id)).subst(self.tcx, substs);
let fn_sig = self.tcx.bound_fn_sig(def_id).subst(self.tcx, substs);
return Some(CallSite {
callee,

View File

@ -151,7 +151,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
} else {
InternalSubsts::identity_for_item(tcx, def_id)
};
let sig = EarlyBinder(tcx.fn_sig(def_id)).subst(tcx, substs);
let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs);
let sig = tcx.erase_late_bound_regions(sig);
let span = tcx.def_span(def_id);
@ -343,7 +343,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
// otherwise going to be TySelf and we can't index
// or access fields of a Place of type TySelf.
let substs = tcx.mk_substs_trait(self_ty, &[]);
let sig = EarlyBinder(tcx.fn_sig(def_id)).subst(tcx, substs);
let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs);
let sig = tcx.erase_late_bound_regions(sig);
let span = tcx.def_span(def_id);

View File

@ -2693,7 +2693,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_ref.def_id,
)?;
let fn_sig = EarlyBinder(tcx.fn_sig(assoc.def_id)).subst(
let fn_sig = tcx.bound_fn_sig(assoc.def_id).subst(
tcx,
trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
);

View File

@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
};
use rustc_middle::ty::subst::{Subst, SubstsRef};
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_target::spec::abi;
@ -339,7 +339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let (fn_sig, def_id) = match *callee_ty.kind() {
ty::FnDef(def_id, subst) => {
let fn_sig = EarlyBinder(self.tcx.fn_sig(def_id)).subst(self.tcx, subst);
let fn_sig = self.tcx.bound_fn_sig(def_id).subst(self.tcx, subst);
// Unit testing: function items annotated with
// `#[rustc_evaluate_where_clauses]` trigger special output

View File

@ -265,9 +265,8 @@ fn compare_predicate_entailment<'tcx>(
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
// First liberate late bound regions and subst placeholders
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id));
let trait_sig = EarlyBinder(trait_sig).subst(tcx, trait_to_placeholder_substs);
let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
let trait_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig);
// Add the resulting inputs and output as well-formed.

View File

@ -1044,8 +1044,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) {
let (sig, did, substs) = match (&expected.kind(), &found.kind()) {
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
let sig1 = EarlyBinder(self.tcx.fn_sig(*did1)).subst(self.tcx, substs1);
let sig2 = EarlyBinder(self.tcx.fn_sig(*did2)).subst(self.tcx, substs2);
let sig1 = self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1);
let sig2 = self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2);
if sig1 != sig2 {
return;
}
@ -1056,7 +1056,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(sig1, *did1, substs1)
}
(ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
let sig1 = EarlyBinder(self.tcx.fn_sig(*did)).subst(self.tcx, substs);
let sig1 = self.tcx.bound_fn_sig(*did).subst(self.tcx, substs);
if sig1 != *sig2 {
return;
}

View File

@ -11,7 +11,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{self, Subst, SubstsRef};
use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty};
use rustc_middle::ty::{self, GenericParamDefKind, Ty};
use rustc_span::Span;
use rustc_trait_selection::traits;
@ -460,9 +460,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
debug!("method_predicates after subst = {:?}", method_predicates);
let sig = self.tcx.fn_sig(def_id);
let sig = self.tcx.bound_fn_sig(def_id);
let sig = EarlyBinder(sig).subst(self.tcx, all_substs);
let sig = sig.subst(self.tcx, all_substs);
debug!("type scheme substituted, sig={:?}", sig);
let sig = self.replace_bound_vars_with_fresh_vars(sig);

View File

@ -21,7 +21,7 @@ use rustc_infer::infer::{self, InferOk};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, EarlyBinder, ToPredicate, Ty, TypeFoldable};
use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable};
use rustc_span::symbol::Ident;
use rustc_span::Span;
use rustc_trait_selection::traits;
@ -460,8 +460,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// N.B., instantiate late-bound regions first so that
// `instantiate_type_scheme` can normalize associated types that
// may reference those regions.
let fn_sig = tcx.fn_sig(def_id);
let fn_sig = EarlyBinder(fn_sig).subst(self.tcx, substs);
let fn_sig = tcx.bound_fn_sig(def_id);
let fn_sig = fn_sig.subst(self.tcx, substs);
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig).0;
let InferOk { value, obligations: o } = if is_op {

View File

@ -901,10 +901,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
) -> bool {
match method.kind {
ty::AssocKind::Fn => {
let fty = self.tcx.fn_sig(method.def_id);
let fty = self.tcx.bound_fn_sig(method.def_id);
self.probe(|_| {
let substs = self.fresh_substs_for_item(self.span, method.def_id);
let fty = EarlyBinder(fty).subst(self.tcx, substs);
let fty = fty.subst(self.tcx, substs);
let (fty, _) =
self.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, fty);
@ -1771,7 +1771,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> {
let fn_sig = self.tcx.fn_sig(method);
let fn_sig = self.tcx.bound_fn_sig(method);
debug!(?fn_sig);
assert!(!substs.has_escaping_bound_vars());
@ -1785,7 +1785,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
assert_eq!(substs.len(), generics.parent_count as usize);
let xform_fn_sig = if generics.params.is_empty() {
EarlyBinder(fn_sig).subst(self.tcx, substs)
fn_sig.subst(self.tcx, substs)
} else {
let substs = InternalSubsts::for_item(self.tcx, method, |param, _| {
let i = param.index as usize;
@ -1803,7 +1803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}
});
EarlyBinder(fn_sig).subst(self.tcx, substs)
fn_sig.subst(self.tcx, substs)
};
self.erase_late_bound_regions(xform_fn_sig)

View File

@ -13,7 +13,7 @@ use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
use rustc_middle::ty::{
self, AdtDef, Binder, EarlyBinder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr,
self, AdtDef, Binder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr,
};
use rustc_span::symbol::Ident;
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
@ -520,7 +520,7 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnS
let ty = cx.typeck_results().expr_ty_adjusted(expr).peel_refs();
match *ty.kind() {
ty::Closure(_, subs) => Some(ExprFnSig::Closure(subs.as_closure().sig())),
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(EarlyBinder(cx.tcx.fn_sig(id)).subst(cx.tcx, subs))),
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs))),
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig)),
ty::Dynamic(bounds, _) => {
let lang_items = cx.tcx.lang_items();