mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Auto merge of #128812 - nnethercote:shrink-TyKind-FnPtr, r=compiler-errors
Shrink `TyKind::FnPtr`. By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and `FnHeader`, which can be packed more efficiently. This reduces the size of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms. This reduces peak memory usage by a few percent on some benchmarks. It also reduces cache misses and page faults similarly, though this doesn't translate to clear cycles or wall-time improvements on CI. r? `@compiler-errors`
This commit is contained in:
commit
e9c965df7b
@ -3989,7 +3989,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
} else {
|
||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
||||
match ty.kind() {
|
||||
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
||||
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
|
||||
self.mir_def_id(),
|
||||
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
||||
),
|
||||
|
@ -1644,7 +1644,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
| ty::Pat(_, _)
|
||||
| ty::Slice(_)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::CoroutineClosure(_, _)
|
||||
@ -1689,7 +1689,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -1364,7 +1364,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
debug!("func_ty.kind: {:?}", func_ty.kind());
|
||||
|
||||
let sig = match func_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx),
|
||||
ty::FnDef(..) | ty::FnPtr(..) => func_ty.fn_sig(tcx),
|
||||
_ => {
|
||||
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
||||
return;
|
||||
@ -2411,7 +2411,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let ty_left = left.ty(body, tcx);
|
||||
match ty_left.kind() {
|
||||
// Types with regions are comparable if they have a common super-type.
|
||||
ty::RawPtr(_, _) | ty::FnPtr(_) => {
|
||||
ty::RawPtr(_, _) | ty::FnPtr(..) => {
|
||||
let ty_right = right.ty(body, tcx);
|
||||
let common_ty = self.infcx.next_ty_var(body.source_info(location).span);
|
||||
self.sub_types(
|
||||
|
@ -69,7 +69,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
|
||||
FloatTy::F64 => types::F64,
|
||||
FloatTy::F128 => unimplemented!("f16_f128"),
|
||||
},
|
||||
ty::FnPtr(_) => pointer_ty(tcx),
|
||||
ty::FnPtr(..) => pointer_ty(tcx),
|
||||
ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
|
||||
if has_ptr_meta(tcx, *pointee_ty) {
|
||||
return None;
|
||||
|
@ -874,7 +874,7 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
(ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => {
|
||||
assert_assignable(fx, *a, *b, limit - 1);
|
||||
}
|
||||
(ty::FnPtr(_), ty::FnPtr(_)) => {
|
||||
(ty::FnPtr(..), ty::FnPtr(..)) => {
|
||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
ParamEnv::reveal_all(),
|
||||
from_ty.fn_sig(fx.tcx),
|
||||
|
@ -213,9 +213,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
|
||||
// NOTE: we cannot remove this match like in the LLVM codegen because the call
|
||||
// to fn_ptr_backend_type handle the on-stack attribute.
|
||||
// TODO(antoyo): find a less hackish way to hande the on-stack attribute.
|
||||
ty::FnPtr(sig) => {
|
||||
cx.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig, ty::List::empty()))
|
||||
}
|
||||
ty::FnPtr(sig_tys, hdr) => cx
|
||||
.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig_tys.with(hdr), ty::List::empty())),
|
||||
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
|
||||
};
|
||||
cx.scalar_types.borrow_mut().insert(self.ty, ty);
|
||||
|
@ -456,7 +456,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
|
||||
{
|
||||
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
|
||||
}
|
||||
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
|
||||
ty::FnDef(..) | ty::FnPtr(..) => build_subroutine_type_di_node(cx, unique_type_id),
|
||||
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
|
||||
ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id),
|
||||
ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
|
||||
|
@ -331,7 +331,7 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
output.push(')');
|
||||
}
|
||||
}
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
// We've encountered a weird 'recursive type'
|
||||
// Currently, the only way to generate such a type
|
||||
// is by using 'impl trait':
|
||||
|
@ -846,7 +846,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
),
|
||||
None,
|
||||
),
|
||||
ty::FnPtr(_) => (None, Some(callee.immediate())),
|
||||
ty::FnPtr(..) => (None, Some(callee.immediate())),
|
||||
_ => bug!("{} is not callable", callee.layout.ty),
|
||||
};
|
||||
|
||||
|
@ -171,7 +171,7 @@ struct LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
||||
impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||
match t.kind() {
|
||||
ty::FnPtr(_) => {}
|
||||
ty::FnPtr(..) => {}
|
||||
ty::Ref(_, _, hir::Mutability::Mut) => {
|
||||
self.checker.check_op(ops::mut_ref::MutRef(self.kind));
|
||||
t.super_visit_with(self)
|
||||
@ -726,7 +726,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
let (mut callee, mut fn_args) = match *fn_ty.kind() {
|
||||
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
self.check_op(ops::FnCallIndirect);
|
||||
return;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ fn const_to_valtree_inner<'tcx>(
|
||||
|
||||
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
|
||||
// agree with runtime equality tests.
|
||||
ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType(ty)),
|
||||
ty::FnPtr(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
|
||||
|
||||
ty::Ref(_, _, _) => {
|
||||
let derefd_place = ecx.deref_pointer(place)?;
|
||||
@ -353,7 +353,7 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Str
|
||||
| ty::Slice(_)
|
||||
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
|
||||
|
@ -97,7 +97,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
|
||||
let src = self.read_immediate(src)?;
|
||||
match cast_ty.kind() {
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
// No change to value
|
||||
self.write_immediate(*src, dest)?;
|
||||
}
|
||||
@ -230,7 +230,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
src: &ImmTy<'tcx, M::Provenance>,
|
||||
cast_to: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
||||
assert_matches!(src.layout.ty.kind(), ty::RawPtr(_, _) | ty::FnPtr(_));
|
||||
assert_matches!(src.layout.ty.kind(), ty::RawPtr(_, _) | ty::FnPtr(..));
|
||||
assert!(cast_to.ty.is_integral());
|
||||
|
||||
let scalar = src.to_scalar();
|
||||
|
@ -81,7 +81,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::CoroutineClosure(_, _)
|
||||
|
@ -483,7 +483,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
|
@ -424,7 +424,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty));
|
||||
|
||||
let (callee, fn_abi, with_caller_location) = match *func.layout.ty.kind() {
|
||||
ty::FnPtr(_sig) => {
|
||||
ty::FnPtr(..) => {
|
||||
let fn_ptr = self.read_pointer(&func)?;
|
||||
let fn_val = self.get_ptr_fn(fn_ptr)?;
|
||||
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
|
||||
|
@ -616,7 +616,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
self.check_safe_pointer(value, PointerKind::Ref(*mutbl))?;
|
||||
Ok(true)
|
||||
}
|
||||
ty::FnPtr(_sig) => {
|
||||
ty::FnPtr(..) => {
|
||||
let value = self.read_scalar(value, ExpectedKind::FnPtr)?;
|
||||
|
||||
// If we check references recursively, also check that this points to a function.
|
||||
|
@ -35,7 +35,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
|
||||
|
@ -68,7 +68,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
|
||||
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
|
||||
ty::Float(FloatTy::F128) => Some(InlineAsmType::F128),
|
||||
ty::FnPtr(_) => Some(asm_ty_isize),
|
||||
ty::FnPtr(..) => Some(asm_ty_isize),
|
||||
ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
|
||||
ty::Adt(adt, args) if adt.repr().simd() => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
|
@ -951,7 +951,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
||||
} else {
|
||||
let mut diag = match ty.kind() {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => return Ok(()),
|
||||
ty::FnPtr(_) => tcx.dcx().struct_span_err(
|
||||
ty::FnPtr(..) => tcx.dcx().struct_span_err(
|
||||
hir_ty.span,
|
||||
"using function pointers as const generic parameters is forbidden",
|
||||
),
|
||||
|
@ -172,7 +172,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
| ty::Never
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Tuple(..) => self.check_primitive_impl(id, self_ty),
|
||||
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => {
|
||||
Err(self.tcx.dcx().emit_err(errors::InherentNominal { span: item_span }))
|
||||
|
@ -317,8 +317,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraint(current, data.index, variance);
|
||||
}
|
||||
|
||||
ty::FnPtr(sig) => {
|
||||
self.add_constraints_from_sig(current, sig, variance);
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
self.add_constraints_from_sig(current, sig_tys.with(hdr), variance);
|
||||
}
|
||||
|
||||
ty::Error(_) => {
|
||||
|
@ -137,7 +137,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// If the callee is a bare function or a closure, then we're all set.
|
||||
match *adjusted_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
let adjustments = self.adjust_steps(autoderef);
|
||||
self.apply_adjustments(callee_expr, adjustments);
|
||||
return Some(CallStep::Builtin(adjusted_ty));
|
||||
@ -467,7 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
(fn_sig, Some(def_id))
|
||||
}
|
||||
// FIXME(effects): these arms should error because we can't enforce them
|
||||
ty::FnPtr(sig) => (sig, None),
|
||||
ty::FnPtr(sig_tys, hdr) => (sig_tys.with(hdr), None),
|
||||
_ => {
|
||||
for arg in arg_exprs {
|
||||
self.check_expr(arg);
|
||||
|
@ -336,9 +336,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.into_iter()
|
||||
.map(|obl| (obl.predicate, obl.cause.span)),
|
||||
),
|
||||
ty::FnPtr(sig) => match closure_kind {
|
||||
ty::FnPtr(sig_tys, hdr) => match closure_kind {
|
||||
hir::ClosureKind::Closure => {
|
||||
let expected_sig = ExpectedSig { cause_span: None, sig };
|
||||
let expected_sig = ExpectedSig { cause_span: None, sig: sig_tys.with(hdr) };
|
||||
(Some(expected_sig), Some(ty::ClosureKind::Fn))
|
||||
}
|
||||
hir::ClosureKind::Coroutine(_) | hir::ClosureKind::CoroutineClosure(_) => {
|
||||
|
@ -225,10 +225,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// items to drop the unsafe qualifier.
|
||||
self.coerce_from_fn_item(a, b)
|
||||
}
|
||||
ty::FnPtr(a_f) => {
|
||||
ty::FnPtr(a_sig_tys, a_hdr) => {
|
||||
// We permit coercion of fn pointers to drop the
|
||||
// unsafe qualifier.
|
||||
self.coerce_from_fn_pointer(a, a_f, b)
|
||||
self.coerce_from_fn_pointer(a, a_sig_tys.with(a_hdr), b)
|
||||
}
|
||||
ty::Closure(closure_def_id_a, args_a) => {
|
||||
// Non-capturing closures are coercible to
|
||||
@ -788,9 +788,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
self.commit_if_ok(|snapshot| {
|
||||
let outer_universe = self.infcx.universe();
|
||||
|
||||
let result = if let ty::FnPtr(fn_ty_b) = b.kind()
|
||||
&& let (hir::Safety::Safe, hir::Safety::Unsafe) =
|
||||
(fn_ty_a.safety(), fn_ty_b.safety())
|
||||
let result = if let ty::FnPtr(_, hdr_b) = b.kind()
|
||||
&& let (hir::Safety::Safe, hir::Safety::Unsafe) = (fn_ty_a.safety(), hdr_b.safety)
|
||||
{
|
||||
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
|
||||
self.unify_and(unsafe_a, b, to_unsafe)
|
||||
@ -842,7 +841,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
|
||||
|
||||
match b.kind() {
|
||||
ty::FnPtr(b_sig) => {
|
||||
ty::FnPtr(_, b_hdr) => {
|
||||
let a_sig = a.fn_sig(self.tcx);
|
||||
if let ty::FnDef(def_id, _) = *a.kind() {
|
||||
// Intrinsics are not coercible to function pointers
|
||||
@ -852,7 +851,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
|
||||
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
|
||||
|
||||
if b_sig.safety() == hir::Safety::Safe
|
||||
if b_hdr.safety == hir::Safety::Safe
|
||||
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
|
||||
{
|
||||
return Err(TypeError::TargetFeatureCast(def_id));
|
||||
@ -910,7 +909,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
//
|
||||
// All we care here is if any variable is being captured and not the exact paths,
|
||||
// so we check `upvars_mentioned` for root variables being captured.
|
||||
ty::FnPtr(fn_ty)
|
||||
ty::FnPtr(_, hdr)
|
||||
if self
|
||||
.tcx
|
||||
.upvars_mentioned(closure_def_id_a.expect_local())
|
||||
@ -923,7 +922,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// or
|
||||
// `unsafe fn(arg0,arg1,...) -> _`
|
||||
let closure_sig = args_a.as_closure().sig();
|
||||
let safety = fn_ty.safety();
|
||||
let safety = hdr.safety;
|
||||
let pointer_ty =
|
||||
Ty::new_fn_ptr(self.tcx, self.tcx.signature_unclosure(closure_sig, safety));
|
||||
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty);
|
||||
|
@ -1530,7 +1530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::Int(_) | ty::Uint(_) => Some(ty),
|
||||
ty::Char => Some(tcx.types.u8),
|
||||
ty::RawPtr(..) => Some(tcx.types.usize),
|
||||
ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
|
||||
ty::FnDef(..) | ty::FnPtr(..) => Some(tcx.types.usize),
|
||||
_ => None,
|
||||
});
|
||||
opt_ty.unwrap_or_else(|| self.next_int_var())
|
||||
|
@ -604,7 +604,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
) -> bool {
|
||||
if let (ty::FnPtr(_), ty::Closure(def_id, _)) = (expected.kind(), found.kind()) {
|
||||
if let (ty::FnPtr(..), ty::Closure(def_id, _)) = (expected.kind(), found.kind()) {
|
||||
if let Some(upvars) = self.tcx.upvars_mentioned(*def_id) {
|
||||
// Report upto four upvars being captured to reduce the amount error messages
|
||||
// reported back to the user.
|
||||
|
@ -50,7 +50,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Not all of these (e.g., unsafe fns) implement `FnOnce`,
|
||||
// so we look for these beforehand.
|
||||
// FIXME(async_closures): These don't impl `FnOnce` by default.
|
||||
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
|
||||
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(..) => true,
|
||||
// If it's not a simple function, look for things which implement `FnOnce`.
|
||||
_ => {
|
||||
let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
|
||||
|
@ -438,7 +438,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(..)
|
||||
|
@ -1022,7 +1022,7 @@ fn ty_is_known_nonnull<'tcx>(
|
||||
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
|
||||
|
||||
match ty.kind() {
|
||||
ty::FnPtr(_) => true,
|
||||
ty::FnPtr(..) => true,
|
||||
ty::Ref(..) => true,
|
||||
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
|
||||
ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => {
|
||||
@ -1473,7 +1473,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
|
||||
ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
|
||||
|
||||
ty::FnPtr(sig) => {
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
let sig = sig_tys.with(hdr);
|
||||
if self.is_internal_abi(sig.abi()) {
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
@ -1709,8 +1710,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
type Result = ControlFlow<Ty<'tcx>>;
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||
if let ty::FnPtr(sig) = ty.kind()
|
||||
&& !self.visitor.is_internal_abi(sig.abi())
|
||||
if let ty::FnPtr(_, hdr) = ty.kind()
|
||||
&& !self.visitor.is_internal_abi(hdr.abi)
|
||||
{
|
||||
self.tys.push(ty);
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
|
@ -130,7 +130,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
||||
_ => "fn item".into(),
|
||||
},
|
||||
ty::FnPtr(_) => "fn pointer".into(),
|
||||
ty::FnPtr(..) => "fn pointer".into(),
|
||||
ty::Dynamic(inner, ..) if let Some(principal) = inner.principal() => {
|
||||
format!("`dyn {}`", tcx.def_path_str(principal.def_id())).into()
|
||||
}
|
||||
@ -194,7 +194,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
||||
_ => "fn item".into(),
|
||||
},
|
||||
ty::FnPtr(_) => "fn pointer".into(),
|
||||
ty::FnPtr(..) => "fn pointer".into(),
|
||||
ty::Dynamic(..) => "trait object".into(),
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(),
|
||||
ty::Coroutine(def_id, ..) => {
|
||||
|
@ -250,9 +250,8 @@ impl FlagComputation {
|
||||
self.add_args(args);
|
||||
}
|
||||
|
||||
&ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {
|
||||
computation.add_tys(fn_sig.inputs());
|
||||
computation.add_ty(fn_sig.output());
|
||||
&ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| {
|
||||
computation.add_tys(sig_tys.inputs_and_output);
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -801,7 +801,7 @@ where
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::FnDef(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
@ -986,9 +986,11 @@ where
|
||||
safe: None,
|
||||
})
|
||||
}
|
||||
ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
|
||||
tcx.layout_of(param_env.and(Ty::new_fn_ptr(tcx, fn_sig))).ok().map(|layout| {
|
||||
PointeeInfo { size: layout.size, align: layout.align.abi, safe: None }
|
||||
ty::FnPtr(..) if offset.bytes() == 0 => {
|
||||
tcx.layout_of(param_env.and(this.ty)).ok().map(|layout| PointeeInfo {
|
||||
size: layout.size,
|
||||
align: layout.align.abi,
|
||||
safe: None,
|
||||
})
|
||||
}
|
||||
ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
|
||||
|
@ -2150,6 +2150,6 @@ mod size_asserts {
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(PredicateKind<'_>, 32);
|
||||
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 56);
|
||||
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ fn characteristic_def_id_of_type_cached<'a>(
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Str
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Param(_)
|
||||
|
@ -696,7 +696,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
p!(print(sig), " {{", print_value_path(def_id, args), "}}");
|
||||
}
|
||||
}
|
||||
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
|
||||
ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
|
||||
ty::Infer(infer_ty) => {
|
||||
if self.should_print_verbose() {
|
||||
p!(write("{:?}", ty.kind()));
|
||||
@ -1678,7 +1678,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
// FIXME: We should probably have a helper method to share code with the "Byte strings"
|
||||
// printing above (which also has to handle pointers to all sorts of things).
|
||||
if let Some(GlobalAlloc::Function { instance, .. }) =
|
||||
@ -1741,7 +1741,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
p!(write("{:?}", char::try_from(int).unwrap()))
|
||||
}
|
||||
// Pointer types
|
||||
ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(_) => {
|
||||
ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(..) => {
|
||||
let data = int.to_bits(self.tcx().data_layout.pointer_size);
|
||||
self.typed_value(
|
||||
|this| {
|
||||
|
@ -374,7 +374,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
),
|
||||
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
|
||||
ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?),
|
||||
ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
|
||||
ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
|
||||
ty::Ref(r, ty, mutbl) => {
|
||||
ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
|
||||
}
|
||||
@ -424,7 +424,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
}
|
||||
ty::Tuple(ts) => ts.visit_with(visitor),
|
||||
ty::FnDef(_, args) => args.visit_with(visitor),
|
||||
ty::FnPtr(ref f) => f.visit_with(visitor),
|
||||
ty::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor),
|
||||
ty::Ref(r, ty, _) => {
|
||||
try_visit!(r.visit_with(visitor));
|
||||
ty.visit_with(visitor)
|
||||
|
@ -658,7 +658,8 @@ impl<'tcx> Ty<'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
Ty::new(tcx, FnPtr(fty))
|
||||
let (sig_tys, hdr) = fty.split();
|
||||
Ty::new(tcx, FnPtr(sig_tys, hdr))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -1182,7 +1183,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| Float(_)
|
||||
| Uint(_)
|
||||
| FnDef(..)
|
||||
| FnPtr(_)
|
||||
| FnPtr(..)
|
||||
| RawPtr(_, _)
|
||||
| Infer(IntVar(_) | FloatVar(_))
|
||||
)
|
||||
@ -1333,7 +1334,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
|
||||
match self.kind() {
|
||||
FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
|
||||
FnPtr(f) => *f,
|
||||
FnPtr(sig_tys, hdr) => sig_tys.with(*hdr),
|
||||
Error(_) => {
|
||||
// ignore errors (#54954)
|
||||
Binder::dummy(ty::FnSig {
|
||||
@ -1352,12 +1353,12 @@ impl<'tcx> Ty<'tcx> {
|
||||
|
||||
#[inline]
|
||||
pub fn is_fn(self) -> bool {
|
||||
matches!(self.kind(), FnDef(..) | FnPtr(_))
|
||||
matches!(self.kind(), FnDef(..) | FnPtr(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_fn_ptr(self) -> bool {
|
||||
matches!(self.kind(), FnPtr(_))
|
||||
matches!(self.kind(), FnPtr(..))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -1599,7 +1600,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
@ -1791,7 +1792,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
@ -1941,7 +1942,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| RawPtr(_, _)
|
||||
| Ref(_, _, _)
|
||||
| FnDef(_, _)
|
||||
| FnPtr(_)
|
||||
| FnPtr(..)
|
||||
| Dynamic(_, _, _)
|
||||
| Closure(_, _)
|
||||
| CoroutineClosure(_, _)
|
||||
@ -1955,9 +1956,12 @@ impl<'tcx> Ty<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Tys<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
|
||||
fn split_inputs_and_output(self) -> (&'tcx [Ty<'tcx>], Ty<'tcx>) {
|
||||
let (output, inputs) = self.split_last().unwrap();
|
||||
(inputs, *output)
|
||||
fn inputs(self) -> &'tcx [Ty<'tcx>] {
|
||||
self.split_last().unwrap().1
|
||||
}
|
||||
|
||||
fn output(self) -> Ty<'tcx> {
|
||||
*self.split_last().unwrap().0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1969,6 +1973,6 @@ mod size_asserts {
|
||||
use super::*;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(ty::RegionKind<'_>, 24);
|
||||
static_assert_size!(ty::TyKind<'_>, 32);
|
||||
static_assert_size!(ty::TyKind<'_>, 24);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
@ -1272,7 +1272,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::FnDef(..)
|
||||
| ty::Error(_)
|
||||
| ty::FnPtr(_) => true,
|
||||
| ty::FnPtr(..) => true,
|
||||
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_freeze),
|
||||
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_freeze(),
|
||||
ty::Adt(..)
|
||||
@ -1312,7 +1312,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::FnDef(..)
|
||||
| ty::Error(_)
|
||||
| ty::FnPtr(_) => true,
|
||||
| ty::FnPtr(..) => true,
|
||||
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_unpin),
|
||||
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_unpin(),
|
||||
ty::Adt(..)
|
||||
@ -1351,7 +1351,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::Ref(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop,
|
||||
|
||||
@ -1534,7 +1534,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
ty::Pat(..) | ty::Ref(..) | ty::Array(..) | ty::Slice(_) | ty::Tuple(..) => true,
|
||||
|
||||
// Raw pointers use bitwise comparison.
|
||||
ty::RawPtr(_, _) | ty::FnPtr(_) => true,
|
||||
ty::RawPtr(_, _) | ty::FnPtr(..) => true,
|
||||
|
||||
// Floating point numbers are not `Eq`.
|
||||
ty::Float(_) => false,
|
||||
@ -1665,7 +1665,7 @@ pub fn needs_drop_components_with_async<'tcx>(
|
||||
| ty::Float(_)
|
||||
| ty::Never
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Char
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
@ -1732,7 +1732,7 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::Foreign(_) => true,
|
||||
|
||||
|
@ -189,9 +189,10 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||
stack.extend(args.iter().rev());
|
||||
}
|
||||
ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
|
||||
ty::FnPtr(sig) => {
|
||||
stack.push(sig.skip_binder().output().into());
|
||||
stack.extend(sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()));
|
||||
ty::FnPtr(sig_tys, _hdr) => {
|
||||
stack.extend(
|
||||
sig_tys.skip_binder().inputs_and_output.iter().rev().map(|ty| ty.into()),
|
||||
);
|
||||
}
|
||||
},
|
||||
GenericArgKind::Lifetime(_) => {}
|
||||
|
@ -158,7 +158,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
| ty::Pat(_, _)
|
||||
| ty::Slice(_)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
@ -201,7 +201,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -64,7 +64,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
|
||||
let ty = func.ty(body, tcx);
|
||||
let sig = ty.fn_sig(tcx);
|
||||
let fn_def_id = match ty.kind() {
|
||||
ty::FnPtr(_) => None,
|
||||
ty::FnPtr(..) => None,
|
||||
&ty::FnDef(def_id, _) => Some(def_id),
|
||||
_ => span_bug!(span, "invalid callee of type {:?}", ty),
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
|
||||
};
|
||||
|
||||
let fn_def_id = match ty.kind() {
|
||||
ty::FnPtr(_) => None,
|
||||
ty::FnPtr(..) => None,
|
||||
&ty::FnDef(def_id, _) => {
|
||||
// Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust ABI).
|
||||
// So the leak of the foreign unwind into Rust can only be elsewhere, not here.
|
||||
|
@ -437,7 +437,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
|
||||
let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
|
||||
|
||||
match self_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => builder.copy_shim(),
|
||||
ty::FnDef(..) | ty::FnPtr(..) => builder.copy_shim(),
|
||||
ty::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()),
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
builder.tuple_like_shim(dest, src, args.as_coroutine_closure().upvar_tys())
|
||||
|
@ -360,7 +360,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::Pat(_, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
|
@ -334,7 +334,7 @@ where
|
||||
| ty::Str
|
||||
| ty::FnDef(..)
|
||||
| ty::Pat(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Array(..)
|
||||
| ty::Slice(..)
|
||||
| ty::RawPtr(..)
|
||||
|
@ -533,7 +533,7 @@ where
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
@ -620,7 +620,7 @@ where
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
|
@ -31,7 +31,7 @@ where
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Error(_)
|
||||
| ty::Never
|
||||
| ty::Char => Ok(vec![]),
|
||||
@ -117,7 +117,7 @@ where
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
@ -178,7 +178,7 @@ where
|
||||
{
|
||||
match ty.kind() {
|
||||
// impl Copy/Clone for FnDef, FnPtr
|
||||
ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Ok(vec![]),
|
||||
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Ok(vec![]),
|
||||
|
||||
// Implementations are provided in core
|
||||
ty::Uint(_)
|
||||
@ -269,7 +269,8 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
|
||||
}
|
||||
}
|
||||
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
|
||||
ty::FnPtr(sig) => {
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
let sig = sig_tys.with(hdr);
|
||||
if sig.is_fn_trait_compatible() {
|
||||
Ok(Some(
|
||||
sig.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
|
||||
@ -460,7 +461,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
|
||||
ty::FnDef(def_id, _) => {
|
||||
let sig = self_ty.fn_sig(cx);
|
||||
if sig.skip_binder().is_fn_trait_compatible() && !cx.has_target_features(def_id) {
|
||||
if sig.is_fn_trait_compatible() && !cx.has_target_features(def_id) {
|
||||
fn_item_to_async_callable(cx, sig)
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
@ -468,7 +469,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
}
|
||||
ty::FnPtr(..) => {
|
||||
let sig = self_ty.fn_sig(cx);
|
||||
if sig.skip_binder().is_fn_trait_compatible() {
|
||||
if sig.is_fn_trait_compatible() {
|
||||
fn_item_to_async_callable(cx, sig)
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
|
@ -1145,7 +1145,7 @@ where
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
|
@ -127,14 +127,17 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||
for meta_item in meta_items {
|
||||
match meta_item.name_or_empty() {
|
||||
sym::debug => {
|
||||
let ty::FnPtr(sig) = ty.kind() else {
|
||||
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
|
||||
span_bug!(
|
||||
meta_item.span(),
|
||||
"`#[rustc_abi(debug)]` on a type alias requires function pointer type"
|
||||
);
|
||||
};
|
||||
let abi = unwrap_fn_abi(
|
||||
tcx.fn_abi_of_fn_ptr(param_env.and((*sig, /* extra_args */ ty::List::empty()))),
|
||||
tcx.fn_abi_of_fn_ptr(
|
||||
param_env
|
||||
.and((sig_tys.with(*hdr), /* extra_args */ ty::List::empty())),
|
||||
),
|
||||
tcx,
|
||||
item_def_id,
|
||||
);
|
||||
@ -155,7 +158,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||
"`#[rustc_abi(assert_eq)]` on a type alias requires pair type"
|
||||
);
|
||||
};
|
||||
let ty::FnPtr(sig1) = field1.kind() else {
|
||||
let ty::FnPtr(sig_tys1, hdr1) = field1.kind() else {
|
||||
span_bug!(
|
||||
meta_item.span(),
|
||||
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
|
||||
@ -163,12 +166,13 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||
};
|
||||
let abi1 = unwrap_fn_abi(
|
||||
tcx.fn_abi_of_fn_ptr(
|
||||
param_env.and((*sig1, /* extra_args */ ty::List::empty())),
|
||||
param_env
|
||||
.and((sig_tys1.with(*hdr1), /* extra_args */ ty::List::empty())),
|
||||
),
|
||||
tcx,
|
||||
item_def_id,
|
||||
);
|
||||
let ty::FnPtr(sig2) = field2.kind() else {
|
||||
let ty::FnPtr(sig_tys2, hdr2) = field2.kind() else {
|
||||
span_bug!(
|
||||
meta_item.span(),
|
||||
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
|
||||
@ -176,7 +180,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
|
||||
};
|
||||
let abi2 = unwrap_fn_abi(
|
||||
tcx.fn_abi_of_fn_ptr(
|
||||
param_env.and((*sig2, /* extra_args */ ty::List::empty())),
|
||||
param_env
|
||||
.and((sig_tys2.with(*hdr2), /* extra_args */ ty::List::empty())),
|
||||
),
|
||||
tcx,
|
||||
item_def_id,
|
||||
|
@ -413,7 +413,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||
| ty::Foreign(_)
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Pat(_, _)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(..)
|
||||
|
@ -607,10 +607,15 @@ pub fn encode_ty<'tcx>(
|
||||
typeid.push_str(&s);
|
||||
}
|
||||
|
||||
ty::FnPtr(fn_sig) => {
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
// PF<return-type><parameter-type1..parameter-typeN>E
|
||||
let mut s = String::from("P");
|
||||
s.push_str(&encode_fnsig(tcx, &fn_sig.skip_binder(), dict, TypeIdOptions::empty()));
|
||||
s.push_str(&encode_fnsig(
|
||||
tcx,
|
||||
&sig_tys.with(*hdr).skip_binder(),
|
||||
dict,
|
||||
TypeIdOptions::empty(),
|
||||
));
|
||||
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
|
||||
typeid.push_str(&s);
|
||||
}
|
||||
|
@ -131,7 +131,10 @@ impl RustcInternal for RigidTy {
|
||||
RigidTy::FnDef(def, args) => {
|
||||
rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx))
|
||||
}
|
||||
RigidTy::FnPtr(sig) => rustc_ty::TyKind::FnPtr(sig.internal(tables, tcx)),
|
||||
RigidTy::FnPtr(sig) => {
|
||||
let (sig_tys, hdr) = sig.internal(tables, tcx).split();
|
||||
rustc_ty::TyKind::FnPtr(sig_tys, hdr)
|
||||
}
|
||||
RigidTy::Closure(def, args) => {
|
||||
rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx))
|
||||
}
|
||||
|
@ -352,7 +352,9 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
|
||||
ty::FnDef(def_id, generic_args) => {
|
||||
TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
|
||||
}
|
||||
ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))),
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
TyKind::RigidTy(RigidTy::FnPtr(sig_tys.with(*hdr).stable(tables)))
|
||||
}
|
||||
ty::Dynamic(existential_predicates, region, dyn_kind) => {
|
||||
TyKind::RigidTy(RigidTy::Dynamic(
|
||||
existential_predicates
|
||||
|
@ -427,7 +427,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
self.print_def_path(def_id, &[])?;
|
||||
}
|
||||
|
||||
ty::FnPtr(sig) => {
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
let sig = sig_tys.with(hdr);
|
||||
self.push("F");
|
||||
self.in_binder(&sig, |cx, sig| {
|
||||
if sig.safety == hir::Safety::Unsafe {
|
||||
|
@ -1087,9 +1087,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
values
|
||||
}
|
||||
|
||||
(ty::FnDef(did1, args1), ty::FnPtr(sig2)) => {
|
||||
(ty::FnDef(did1, args1), ty::FnPtr(sig_tys2, hdr2)) => {
|
||||
let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1);
|
||||
let mut values = self.cmp_fn_sig(&sig1, sig2);
|
||||
let mut values = self.cmp_fn_sig(&sig1, &sig_tys2.with(*hdr2));
|
||||
values.0.push_highlighted(format!(
|
||||
" {{{}}}",
|
||||
self.tcx.def_path_str_with_args(*did1, args1)
|
||||
@ -1097,16 +1097,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
values
|
||||
}
|
||||
|
||||
(ty::FnPtr(sig1), ty::FnDef(did2, args2)) => {
|
||||
(ty::FnPtr(sig_tys1, hdr1), ty::FnDef(did2, args2)) => {
|
||||
let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2);
|
||||
let mut values = self.cmp_fn_sig(sig1, &sig2);
|
||||
let mut values = self.cmp_fn_sig(&sig_tys1.with(*hdr1), &sig2);
|
||||
values
|
||||
.1
|
||||
.push_normal(format!(" {{{}}}", self.tcx.def_path_str_with_args(*did2, args2)));
|
||||
values
|
||||
}
|
||||
|
||||
(ty::FnPtr(sig1), ty::FnPtr(sig2)) => self.cmp_fn_sig(sig1, sig2),
|
||||
(ty::FnPtr(sig_tys1, hdr1), ty::FnPtr(sig_tys2, hdr2)) => {
|
||||
self.cmp_fn_sig(&sig_tys1.with(*hdr1), &sig_tys2.with(*hdr2))
|
||||
}
|
||||
|
||||
_ => {
|
||||
let mut strs = (DiagStyledString::new(), DiagStyledString::new());
|
||||
|
@ -441,9 +441,9 @@ impl<T> Trait<T> for X {
|
||||
}
|
||||
}
|
||||
}
|
||||
(ty::FnPtr(sig), ty::FnDef(def_id, _))
|
||||
| (ty::FnDef(def_id, _), ty::FnPtr(sig)) => {
|
||||
if tcx.fn_sig(def_id).skip_binder().safety() < sig.safety() {
|
||||
(ty::FnPtr(_, hdr), ty::FnDef(def_id, _))
|
||||
| (ty::FnDef(def_id, _), ty::FnPtr(_, hdr)) => {
|
||||
if tcx.fn_sig(def_id).skip_binder().safety() < hdr.safety {
|
||||
diag.note(
|
||||
"unsafe functions cannot be coerced into safe function pointers",
|
||||
);
|
||||
|
@ -383,8 +383,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
return;
|
||||
}
|
||||
match (&expected_inner.kind(), &found_inner.kind()) {
|
||||
(ty::FnPtr(sig), ty::FnDef(did, args)) => {
|
||||
let expected_sig = &(self.normalize_fn_sig)(*sig);
|
||||
(ty::FnPtr(sig_tys, hdr), ty::FnDef(did, args)) => {
|
||||
let sig = sig_tys.with(*hdr);
|
||||
let expected_sig = &(self.normalize_fn_sig)(sig);
|
||||
let found_sig =
|
||||
&(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args));
|
||||
|
||||
@ -402,11 +403,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
|
||||
(true, true) => {
|
||||
diag.subdiagnostic(FnItemsAreDistinct);
|
||||
FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig }
|
||||
FunctionPointerSuggestion::CastRef { span, fn_name, sig }
|
||||
}
|
||||
(false, false) => {
|
||||
diag.subdiagnostic(FnItemsAreDistinct);
|
||||
FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig }
|
||||
FunctionPointerSuggestion::Cast { span, fn_name, sig }
|
||||
}
|
||||
};
|
||||
diag.subdiagnostic(sugg);
|
||||
@ -449,10 +450,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
diag.subdiagnostic(sug);
|
||||
}
|
||||
(ty::FnDef(did, args), ty::FnPtr(sig)) => {
|
||||
(ty::FnDef(did, args), ty::FnPtr(sig_tys, hdr)) => {
|
||||
let expected_sig =
|
||||
&(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args));
|
||||
let found_sig = &(self.normalize_fn_sig)(*sig);
|
||||
let found_sig = &(self.normalize_fn_sig)(sig_tys.with(*hdr));
|
||||
|
||||
if !self.same_type_modulo_infer(*found_sig, *expected_sig) {
|
||||
return;
|
||||
|
@ -375,7 +375,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
let impl_candidates = self.find_similar_impl_candidates(leaf_trait_predicate);
|
||||
suggested = if let &[cand] = &impl_candidates[..] {
|
||||
let cand = cand.trait_ref;
|
||||
if let (ty::FnPtr(_), ty::FnDef(..)) =
|
||||
if let (ty::FnPtr(..), ty::FnDef(..)) =
|
||||
(cand.self_ty().kind(), main_trait_ref.self_ty().skip_binder().kind())
|
||||
{
|
||||
err.span_suggestion(
|
||||
@ -790,8 +790,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
// is unimplemented is because async closures don't implement `Fn`/`FnMut`
|
||||
// if they have captures.
|
||||
if let Some(by_ref_captures) = by_ref_captures
|
||||
&& let ty::FnPtr(sig) = by_ref_captures.kind()
|
||||
&& !sig.skip_binder().output().is_unit()
|
||||
&& let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
|
||||
&& !sig_tys.skip_binder().output().is_unit()
|
||||
{
|
||||
let mut err = self.dcx().create_err(AsyncClosureNotFn {
|
||||
span: self.tcx.def_span(closure_def_id),
|
||||
@ -1057,7 +1057,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
"`{ty}` is forbidden as the type of a const generic parameter",
|
||||
)
|
||||
}
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
@ -1836,10 +1836,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
if let &[cand] = &candidates[..] {
|
||||
let (desc, mention_castable) =
|
||||
match (cand.self_ty().kind(), trait_ref.self_ty().skip_binder().kind()) {
|
||||
(ty::FnPtr(_), ty::FnDef(..)) => {
|
||||
(ty::FnPtr(..), ty::FnDef(..)) => {
|
||||
(" implemented for fn pointer `", ", cast using `as`")
|
||||
}
|
||||
(ty::FnPtr(_), _) => (" implemented for fn pointer `", ""),
|
||||
(ty::FnPtr(..), _) => (" implemented for fn pointer `", ""),
|
||||
_ => (" implemented for `", ""),
|
||||
};
|
||||
err.highlighted_help(vec![
|
||||
|
@ -1077,10 +1077,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
let Some((def_id_or_name, output, inputs)) =
|
||||
(self.autoderef_steps)(found).into_iter().find_map(|(found, _)| {
|
||||
match *found.kind() {
|
||||
ty::FnPtr(fn_sig) => Some((
|
||||
ty::FnPtr(sig_tys, _) => Some((
|
||||
DefIdOrName::Name("function pointer"),
|
||||
fn_sig.output(),
|
||||
fn_sig.inputs(),
|
||||
sig_tys.output(),
|
||||
sig_tys.inputs(),
|
||||
)),
|
||||
ty::FnDef(def_id, _) => {
|
||||
let fn_sig = found.fn_sig(self.tcx);
|
||||
@ -1977,20 +1977,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = cause else {
|
||||
return;
|
||||
};
|
||||
let ty::FnPtr(expected) = expected.kind() else {
|
||||
let ty::FnPtr(sig_tys, hdr) = expected.kind() else {
|
||||
return;
|
||||
};
|
||||
let ty::FnPtr(found) = found.kind() else {
|
||||
let expected = sig_tys.with(*hdr);
|
||||
let ty::FnPtr(sig_tys, hdr) = found.kind() else {
|
||||
return;
|
||||
};
|
||||
let found = sig_tys.with(*hdr);
|
||||
let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) else {
|
||||
return;
|
||||
};
|
||||
let hir::ExprKind::Path(path) = arg.kind else {
|
||||
return;
|
||||
};
|
||||
let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(*expected).inputs();
|
||||
let found_inputs = self.tcx.instantiate_bound_regions_with_erased(*found).inputs();
|
||||
let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(expected).inputs();
|
||||
let found_inputs = self.tcx.instantiate_bound_regions_with_erased(found).inputs();
|
||||
let both_tys = expected_inputs.iter().copied().zip(found_inputs.iter().copied());
|
||||
|
||||
let arg_expr = |infcx: &InferCtxt<'tcx>, name, expected: Ty<'tcx>, found: Ty<'tcx>| {
|
||||
@ -4790,13 +4792,13 @@ fn hint_missing_borrow<'tcx>(
|
||||
}
|
||||
|
||||
let found_args = match found.kind() {
|
||||
ty::FnPtr(f) => infcx.enter_forall(*f, |f| f.inputs().iter()),
|
||||
ty::FnPtr(sig_tys, _) => infcx.enter_forall(*sig_tys, |sig_tys| sig_tys.inputs().iter()),
|
||||
kind => {
|
||||
span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
|
||||
}
|
||||
};
|
||||
let expected_args = match expected.kind() {
|
||||
ty::FnPtr(f) => infcx.enter_forall(*f, |f| f.inputs().iter()),
|
||||
ty::FnPtr(sig_tys, _) => infcx.enter_forall(*sig_tys, |sig_tys| sig_tys.inputs().iter()),
|
||||
kind => {
|
||||
span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", kind)
|
||||
}
|
||||
|
@ -1636,7 +1636,7 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||
.generics_of(def_id)
|
||||
.host_effect_index
|
||||
.map_or(tcx.consts.true_, |idx| args.const_at(idx)),
|
||||
ty::FnPtr(_) => tcx.consts.true_,
|
||||
ty::FnPtr(..) => tcx.consts.true_,
|
||||
_ => unreachable!("only expected FnPtr or FnDef in `confirm_fn_pointer_candidate`"),
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
| ty::Float(_)
|
||||
| ty::Never
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Char
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::RawPtr(_, _)
|
||||
@ -224,7 +224,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::CoroutineWitness(..) => {
|
||||
// these types never have a destructor
|
||||
}
|
||||
|
@ -468,8 +468,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates.vec.push(AsyncClosureCandidate);
|
||||
}
|
||||
// Provide an impl, but only for suitable `fn` pointers.
|
||||
ty::FnPtr(sig) => {
|
||||
if sig.is_fn_trait_compatible() {
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
if sig_tys.with(hdr).is_fn_trait_compatible() {
|
||||
candidates.vec.push(AsyncClosureCandidate);
|
||||
}
|
||||
}
|
||||
@ -535,8 +535,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates.ambiguous = true; // Could wind up being a fn() type.
|
||||
}
|
||||
// Provide an impl, but only for suitable `fn` pointers.
|
||||
ty::FnPtr(sig) => {
|
||||
if sig.is_fn_trait_compatible() {
|
||||
ty::FnPtr(sig_tys, hdr) => {
|
||||
if sig_tys.with(hdr).is_fn_trait_compatible() {
|
||||
candidates
|
||||
.vec
|
||||
.push(FnPointerCandidate { fn_host_effect: self.tcx().consts.true_ });
|
||||
@ -819,7 +819,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
@ -1207,7 +1207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::Foreign(_)
|
||||
| ty::Array(..)
|
||||
@ -1290,7 +1290,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::Pat(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
@ -1339,7 +1339,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
|
||||
|
||||
match self_ty.skip_binder().kind() {
|
||||
ty::FnPtr(_) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
|
||||
ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
@ -1398,7 +1398,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Never
|
||||
| ty::Foreign(_) => {}
|
||||
|
||||
|
@ -2113,7 +2113,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Char
|
||||
| ty::Ref(..)
|
||||
@ -2170,7 +2170,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
use self::BuiltinImplConditions::{Ambiguous, None, Where};
|
||||
|
||||
match *self_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
|
||||
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
|
||||
|
||||
ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
@ -2332,7 +2332,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
| ty::Bool
|
||||
| ty::Float(_)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Error(_)
|
||||
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||
| ty::Never
|
||||
|
@ -812,7 +812,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
||||
return upvars.visit_with(self);
|
||||
}
|
||||
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
// Let the visitor iterate into the argument/return
|
||||
// types appearing in the fn signature.
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ fn resolve_associated_item<'tcx>(
|
||||
if name == sym::clone {
|
||||
let self_ty = trait_ref.self_ty();
|
||||
match self_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => (),
|
||||
ty::FnDef(..) | ty::FnPtr(..) => (),
|
||||
ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Closure(..)
|
||||
|
@ -184,7 +184,7 @@ fn layout_of_uncached<'tcx>(
|
||||
ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
|
||||
ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
|
||||
ty::Float(fty) => scalar(Float(Float::from_float_ty(fty))),
|
||||
ty::FnPtr(_) => {
|
||||
ty::FnPtr(..) => {
|
||||
let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
|
||||
ptr.valid_range_mut().start = 1;
|
||||
tcx.mk_layout(LayoutS::scalar(cx, ptr))
|
||||
|
@ -86,6 +86,7 @@ macro_rules! impl_binder_encode_decode {
|
||||
#[cfg(feature = "nightly")]
|
||||
impl_binder_encode_decode! {
|
||||
ty::FnSig<I>,
|
||||
ty::FnSigTys<I>,
|
||||
ty::TraitPredicate<I>,
|
||||
ty::ExistentialPredicate<I>,
|
||||
ty::TraitRef<I>,
|
||||
@ -247,21 +248,6 @@ impl<I: Interner, T> Binder<I, T> {
|
||||
// `self.value` is equivalent to `self.skip_binder()`
|
||||
if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
|
||||
}
|
||||
|
||||
/// Splits the contents into two things that share the same binder
|
||||
/// level as the original, returning two distinct binders.
|
||||
///
|
||||
/// `f` should consider bound regions at depth 1 to be free, and
|
||||
/// anything it produces with bound regions at depth 1 will be
|
||||
/// bound in the resulting return values.
|
||||
pub fn split<U, V, F>(self, f: F) -> (Binder<I, U>, Binder<I, V>)
|
||||
where
|
||||
F: FnOnce(T) -> (U, V),
|
||||
{
|
||||
let Binder { value, bound_vars } = self;
|
||||
let (u, v) = f(value);
|
||||
(Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, T> Binder<I, Option<T>> {
|
||||
|
@ -135,7 +135,9 @@ pub fn simplify_type<I: Interner>(
|
||||
ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id)),
|
||||
ty::Never => Some(SimplifiedType::Never),
|
||||
ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())),
|
||||
ty::FnPtr(f) => Some(SimplifiedType::Function(f.skip_binder().inputs().len())),
|
||||
ty::FnPtr(sig_tys, _hdr) => {
|
||||
Some(SimplifiedType::Function(sig_tys.skip_binder().inputs().len()))
|
||||
}
|
||||
ty::Placeholder(..) => Some(SimplifiedType::Placeholder),
|
||||
ty::Param(_) => match treat_params {
|
||||
TreatParams::ForLookup => Some(SimplifiedType::Placeholder),
|
||||
@ -307,17 +309,14 @@ impl<I: Interner> DeepRejectCtxt<I> {
|
||||
obl_preds.principal_def_id() == impl_preds.principal_def_id()
|
||||
)
|
||||
}
|
||||
ty::FnPtr(obl_sig) => match k {
|
||||
ty::FnPtr(impl_sig) => {
|
||||
let ty::FnSig { inputs_and_output, c_variadic, safety, abi } =
|
||||
obl_sig.skip_binder();
|
||||
let impl_sig = impl_sig.skip_binder();
|
||||
ty::FnPtr(obl_sig_tys, obl_hdr) => match k {
|
||||
ty::FnPtr(impl_sig_tys, impl_hdr) => {
|
||||
let obl_sig_tys = obl_sig_tys.skip_binder().inputs_and_output;
|
||||
let impl_sig_tys = impl_sig_tys.skip_binder().inputs_and_output;
|
||||
|
||||
abi == impl_sig.abi
|
||||
&& c_variadic == impl_sig.c_variadic
|
||||
&& safety == impl_sig.safety
|
||||
&& inputs_and_output.len() == impl_sig.inputs_and_output.len()
|
||||
&& iter::zip(inputs_and_output.iter(), impl_sig.inputs_and_output.iter())
|
||||
obl_hdr == impl_hdr
|
||||
&& obl_sig_tys.len() == impl_sig_tys.len()
|
||||
&& iter::zip(obl_sig_tys.iter(), impl_sig_tys.iter())
|
||||
.all(|(obl, imp)| self.types_may_unify(obl, imp))
|
||||
}
|
||||
_ => false,
|
||||
|
@ -133,12 +133,12 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
||||
}
|
||||
|
||||
fn is_fn_ptr(self) -> bool {
|
||||
matches!(self.kind(), ty::FnPtr(_))
|
||||
matches!(self.kind(), ty::FnPtr(..))
|
||||
}
|
||||
|
||||
fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
|
||||
match self.kind() {
|
||||
ty::FnPtr(sig) => sig,
|
||||
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
|
||||
ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
|
||||
ty::Error(_) => {
|
||||
// ignore errors (#54954)
|
||||
@ -181,7 +181,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::CoroutineClosure(_, _)
|
||||
@ -203,7 +203,9 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
||||
pub trait Tys<I: Interner<Tys = Self>>:
|
||||
Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default
|
||||
{
|
||||
fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty);
|
||||
fn inputs(self) -> I::FnInputTys;
|
||||
|
||||
fn output(self) -> I::Ty;
|
||||
}
|
||||
|
||||
pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq + Relate<I> {
|
||||
|
@ -186,7 +186,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(_, _)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Tuple(_) => {
|
||||
ty.super_visit_with(self);
|
||||
|
@ -524,8 +524,8 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
|
||||
Ok(Ty::new_fn_def(cx, a_def_id, args))
|
||||
}
|
||||
|
||||
(ty::FnPtr(a_fty), ty::FnPtr(b_fty)) => {
|
||||
let fty = relation.relate(a_fty, b_fty)?;
|
||||
(ty::FnPtr(a_sig_tys, a_hdr), ty::FnPtr(b_sig_tys, b_hdr)) => {
|
||||
let fty = relation.relate(a_sig_tys.with(a_hdr), b_sig_tys.with(b_hdr))?;
|
||||
Ok(Ty::new_fn_ptr(cx, fty))
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,12 @@ pub enum TyKind<I: Interner> {
|
||||
/// fn foo() -> i32 { 1 }
|
||||
/// let bar: fn() -> i32 = foo;
|
||||
/// ```
|
||||
FnPtr(ty::Binder<I, FnSig<I>>),
|
||||
///
|
||||
/// These two fields are equivalent to a `ty::Binder<I, FnSig<I>>`. But by
|
||||
/// splitting that into two pieces, we get a more compact data layout that
|
||||
/// reduces the size of `TyKind` by 8 bytes. It is a very hot type, so it's
|
||||
/// worth the mild inconvenience.
|
||||
FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
|
||||
|
||||
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
|
||||
Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
|
||||
@ -288,7 +293,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
|
||||
RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
|
||||
Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
|
||||
FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
|
||||
FnPtr(s) => write!(f, "{s:?}"),
|
||||
FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
|
||||
Dynamic(p, r, repr) => match repr {
|
||||
DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
|
||||
DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
|
||||
@ -868,16 +873,12 @@ pub struct FnSig<I: Interner> {
|
||||
}
|
||||
|
||||
impl<I: Interner> FnSig<I> {
|
||||
pub fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty) {
|
||||
self.inputs_and_output.split_inputs_and_output()
|
||||
}
|
||||
|
||||
pub fn inputs(self) -> I::FnInputTys {
|
||||
self.split_inputs_and_output().0
|
||||
self.inputs_and_output.inputs()
|
||||
}
|
||||
|
||||
pub fn output(self) -> I::Ty {
|
||||
self.split_inputs_and_output().1
|
||||
self.inputs_and_output.output()
|
||||
}
|
||||
|
||||
pub fn is_fn_trait_compatible(self) -> bool {
|
||||
@ -922,6 +923,13 @@ impl<I: Interner> ty::Binder<I, FnSig<I>> {
|
||||
pub fn is_fn_trait_compatible(&self) -> bool {
|
||||
self.skip_binder().is_fn_trait_compatible()
|
||||
}
|
||||
|
||||
// Used to split a single value into the two fields in `TyKind::FnPtr`.
|
||||
pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
|
||||
let hdr =
|
||||
FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
|
||||
(self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||
@ -935,7 +943,7 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||
}
|
||||
|
||||
write!(f, "fn(")?;
|
||||
let (inputs, output) = sig.split_inputs_and_output();
|
||||
let inputs = sig.inputs();
|
||||
for (i, ty) in inputs.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
@ -951,9 +959,69 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||
}
|
||||
write!(f, ")")?;
|
||||
|
||||
let output = sig.output();
|
||||
match output.kind() {
|
||||
Tuple(list) if list.is_empty() => Ok(()),
|
||||
_ => write!(f, " -> {:?}", sig.output()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is just a `FnSig` without the `FnHeader` fields.
|
||||
#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnSigTys<I: Interner> {
|
||||
pub inputs_and_output: I::Tys,
|
||||
}
|
||||
|
||||
impl<I: Interner> FnSigTys<I> {
|
||||
pub fn inputs(self) -> I::FnInputTys {
|
||||
self.inputs_and_output.inputs()
|
||||
}
|
||||
|
||||
pub fn output(self) -> I::Ty {
|
||||
self.inputs_and_output.output()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
|
||||
// Used to combine the two fields in `TyKind::FnPtr` into a single value.
|
||||
pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
|
||||
self.map_bound(|sig_tys| FnSig {
|
||||
inputs_and_output: sig_tys.inputs_and_output,
|
||||
c_variadic: hdr.c_variadic,
|
||||
safety: hdr.safety,
|
||||
abi: hdr.abi,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
|
||||
self.map_bound(|sig_tys| sig_tys.inputs())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
|
||||
self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap())
|
||||
}
|
||||
|
||||
pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
|
||||
self.map_bound(|sig_tys| sig_tys.inputs_and_output)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn output(self) -> ty::Binder<I, I::Ty> {
|
||||
self.map_bound(|sig_tys| sig_tys.output())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnHeader<I: Interner> {
|
||||
pub c_variadic: bool,
|
||||
pub safety: I::Safety,
|
||||
pub abi: I::Abi,
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ impl<I: Interner> ClosureArgs<I> {
|
||||
/// Extracts the signature from the closure.
|
||||
pub fn sig(self) -> ty::Binder<I, ty::FnSig<I>> {
|
||||
match self.sig_as_fn_ptr_ty().kind() {
|
||||
ty::FnPtr(sig) => sig,
|
||||
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
|
||||
ty => panic!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {ty:?}"),
|
||||
}
|
||||
}
|
||||
@ -292,21 +292,23 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
|
||||
pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>> {
|
||||
let interior = self.coroutine_witness_ty();
|
||||
let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { panic!() };
|
||||
sig.map_bound(|sig| {
|
||||
let [resume_ty, tupled_inputs_ty] = *sig.inputs().as_slice() else {
|
||||
let ty::FnPtr(sig_tys, hdr) = self.signature_parts_ty().kind() else { panic!() };
|
||||
sig_tys.map_bound(|sig_tys| {
|
||||
let [resume_ty, tupled_inputs_ty] = *sig_tys.inputs().as_slice() else {
|
||||
panic!();
|
||||
};
|
||||
let [yield_ty, return_ty] = *sig.output().tuple_fields().as_slice() else { panic!() };
|
||||
let [yield_ty, return_ty] = *sig_tys.output().tuple_fields().as_slice() else {
|
||||
panic!()
|
||||
};
|
||||
CoroutineClosureSignature {
|
||||
interior,
|
||||
tupled_inputs_ty,
|
||||
resume_ty,
|
||||
yield_ty,
|
||||
return_ty,
|
||||
c_variadic: sig.c_variadic,
|
||||
safety: sig.safety,
|
||||
abi: sig.abi,
|
||||
c_variadic: hdr.c_variadic,
|
||||
safety: hdr.safety,
|
||||
abi: hdr.abi,
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -321,7 +323,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
||||
|
||||
pub fn has_self_borrows(&self) -> bool {
|
||||
match self.coroutine_captures_by_ref_ty().kind() {
|
||||
ty::FnPtr(sig) => sig
|
||||
ty::FnPtr(sig_tys, _) => sig_tys
|
||||
.skip_binder()
|
||||
.visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST })
|
||||
.is_break(),
|
||||
@ -460,11 +462,11 @@ impl<I: Interner> CoroutineClosureSignature<I> {
|
||||
) -> I::Ty {
|
||||
match kind {
|
||||
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
|
||||
let ty::FnPtr(sig) = coroutine_captures_by_ref_ty.kind() else {
|
||||
let ty::FnPtr(sig_tys, _) = coroutine_captures_by_ref_ty.kind() else {
|
||||
panic!();
|
||||
};
|
||||
let coroutine_captures_by_ref_ty =
|
||||
sig.output().skip_binder().fold_with(&mut FoldEscapingRegions {
|
||||
sig_tys.output().skip_binder().fold_with(&mut FoldEscapingRegions {
|
||||
interner: cx,
|
||||
region: env_region,
|
||||
debruijn: ty::INNERMOST,
|
||||
|
@ -2069,7 +2069,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
Some(ContainerTy::Ref(r)),
|
||||
)),
|
||||
},
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
// FIXME: should we merge the outer and inner binders somehow?
|
||||
let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
|
||||
let decl = clean_poly_fn_sig(cx, None, sig);
|
||||
|
@ -495,7 +495,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
ty::RawPtr(_, _) => Res::Primitive(RawPointer),
|
||||
ty::Ref(..) => Res::Primitive(Reference),
|
||||
ty::FnDef(..) => panic!("type alias to a function definition"),
|
||||
ty::FnPtr(_) => Res::Primitive(Fn),
|
||||
ty::FnPtr(..) => Res::Primitive(Fn),
|
||||
ty::Never => Res::Primitive(Never),
|
||||
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => {
|
||||
Res::from_def_id(self.cx.tcx, did)
|
||||
|
@ -15,7 +15,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
||||
}
|
||||
|
||||
match cast_from.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
|
||||
let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
|
||||
|
@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
||||
_ => { /* continue to checks */ },
|
||||
}
|
||||
|
||||
if let ty::FnDef(..) | ty::FnPtr(_) = cast_from.kind() {
|
||||
if let ty::FnDef(..) | ty::FnPtr(..) = cast_from.kind() {
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
|
||||
|
||||
|
@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
|
||||
_ => return,
|
||||
}
|
||||
match cast_from.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
|
||||
|
||||
|
@ -236,7 +236,7 @@ fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<'
|
||||
// We can't use `Ty::fn_sig` because it automatically performs args, this may result in FNs.
|
||||
match node_ty.kind() {
|
||||
ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).instantiate_identity()),
|
||||
ty::FnPtr(fn_sig) => Some(*fn_sig),
|
||||
ty::FnPtr(sig_tys, hdr) => Some(sig_tys.with(*hdr)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +872,7 @@ impl TyCoercionStability {
|
||||
| ty::Pat(..)
|
||||
| ty::Float(_)
|
||||
| ty::RawPtr(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Str
|
||||
| ty::Slice(..)
|
||||
| ty::Adt(..)
|
||||
|
@ -158,7 +158,7 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
|
||||
|
||||
cx.tcx.fn_sig(def).skip_binder().skip_binder()
|
||||
},
|
||||
ty::FnPtr(sig) => sig.skip_binder(),
|
||||
ty::FnPtr(sig_tys, hdr) => sig_tys.with(*hdr).skip_binder(),
|
||||
ty::Closure(_, subs) => cx
|
||||
.tcx
|
||||
.signature_unclosure(subs.as_closure().sig(), Safety::Safe)
|
||||
|
@ -58,7 +58,7 @@ fn try_get_caller_ty_name_and_method_name(
|
||||
fn is_map_to_option(cx: &LateContext<'_>, map_arg: &Expr<'_>) -> bool {
|
||||
let map_closure_ty = cx.typeck_results().expr_ty(map_arg);
|
||||
match map_closure_ty.kind() {
|
||||
ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(_) => {
|
||||
ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(..) => {
|
||||
let map_closure_sig = match map_closure_ty.kind() {
|
||||
ty::Closure(_, args) => args.as_closure().sig(),
|
||||
_ => map_closure_ty.fn_sig(cx.tcx),
|
||||
|
@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
|
||||
ExprKind::Call(func, _) => {
|
||||
let typ = self.cx.typeck_results().expr_ty(func);
|
||||
match typ.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
let sig = typ.fn_sig(self.cx.tcx);
|
||||
if self.cx.tcx.instantiate_bound_regions_with_erased(sig).output().kind() == &ty::Never {
|
||||
self.report_diverging_sub_expr(e);
|
||||
|
@ -130,7 +130,7 @@ fn collect_unsafe_exprs<'tcx>(
|
||||
ExprKind::Call(path_expr, _) => {
|
||||
let sig = match *cx.typeck_results().expr_ty(path_expr).kind() {
|
||||
ty::FnDef(id, _) => cx.tcx.fn_sig(id).skip_binder(),
|
||||
ty::FnPtr(sig) => sig,
|
||||
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
|
||||
_ => return Continue(Descend::Yes),
|
||||
};
|
||||
if sig.safety() == Safety::Unsafe {
|
||||
|
@ -79,7 +79,7 @@ fn check_arguments<'tcx>(
|
||||
fn_kind: &str,
|
||||
) {
|
||||
match type_definition.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
|
||||
for (argument, parameter) in iter::zip(arguments, parameters) {
|
||||
match parameter.kind() {
|
||||
|
@ -541,7 +541,7 @@ pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) {
|
||||
/// Returns `true` if the given type is an `unsafe` function.
|
||||
pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe,
|
||||
ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -721,7 +721,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
|
||||
cx.tcx.item_super_predicates(def_id).iter_instantiated(cx.tcx, args),
|
||||
cx.tcx.opt_parent(def_id),
|
||||
),
|
||||
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
|
||||
ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)),
|
||||
ty::Dynamic(bounds, _, _) => {
|
||||
let lang_items = cx.tcx.lang_items();
|
||||
match bounds.principal() {
|
||||
|
@ -441,7 +441,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
|
||||
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => {
|
||||
self.is_unsafe = true;
|
||||
},
|
||||
ty::FnPtr(sig) if sig.safety() == Safety::Unsafe => self.is_unsafe = true,
|
||||
ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => self.is_unsafe = true,
|
||||
_ => walk_expr(self, e),
|
||||
},
|
||||
ExprKind::Path(ref p)
|
||||
|
Loading…
Reference in New Issue
Block a user