mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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.
This commit is contained in:
parent
8640998869
commit
c4717cc9d1
@ -3989,7 +3989,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig(
|
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
|
||||||
self.mir_def_id(),
|
self.mir_def_id(),
|
||||||
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
|
||||||
),
|
),
|
||||||
|
@ -1644,7 +1644,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
|||||||
| ty::Pat(_, _)
|
| ty::Pat(_, _)
|
||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(_, _)
|
| ty::Closure(_, _)
|
||||||
| ty::CoroutineClosure(_, _)
|
| ty::CoroutineClosure(_, _)
|
||||||
@ -1689,7 +1689,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
|
@ -1364,7 +1364,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
debug!("func_ty.kind: {:?}", func_ty.kind());
|
debug!("func_ty.kind: {:?}", func_ty.kind());
|
||||||
|
|
||||||
let sig = match 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);
|
span_mirbug!(self, term, "call to non-function {:?}", func_ty);
|
||||||
return;
|
return;
|
||||||
@ -2420,7 +2420,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
let ty_left = left.ty(body, tcx);
|
let ty_left = left.ty(body, tcx);
|
||||||
match ty_left.kind() {
|
match ty_left.kind() {
|
||||||
// Types with regions are comparable if they have a common super-type.
|
// 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 ty_right = right.ty(body, tcx);
|
||||||
let common_ty = self.infcx.next_ty_var(body.source_info(location).span);
|
let common_ty = self.infcx.next_ty_var(body.source_info(location).span);
|
||||||
self.sub_types(
|
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::F64 => types::F64,
|
||||||
FloatTy::F128 => unimplemented!("f16_f128"),
|
FloatTy::F128 => unimplemented!("f16_f128"),
|
||||||
},
|
},
|
||||||
ty::FnPtr(_) => pointer_ty(tcx),
|
ty::FnPtr(..) => pointer_ty(tcx),
|
||||||
ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
|
ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => {
|
||||||
if has_ptr_meta(tcx, *pointee_ty) {
|
if has_ptr_meta(tcx, *pointee_ty) {
|
||||||
return None;
|
return None;
|
||||||
|
@ -872,7 +872,7 @@ pub(crate) fn assert_assignable<'tcx>(
|
|||||||
(ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => {
|
(ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => {
|
||||||
assert_assignable(fx, *a, *b, limit - 1);
|
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(
|
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||||
ParamEnv::reveal_all(),
|
ParamEnv::reveal_all(),
|
||||||
from_ty.fn_sig(fx.tcx),
|
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
|
// NOTE: we cannot remove this match like in the LLVM codegen because the call
|
||||||
// to fn_ptr_backend_type handle the on-stack attribute.
|
// to fn_ptr_backend_type handle the on-stack attribute.
|
||||||
// TODO(antoyo): find a less hackish way to hande the on-stack attribute.
|
// TODO(antoyo): find a less hackish way to hande the on-stack attribute.
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => cx
|
||||||
cx.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig, ty::List::empty()))
|
.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),
|
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
|
||||||
};
|
};
|
||||||
cx.scalar_types.borrow_mut().insert(self.ty, ty);
|
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)
|
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::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
|
||||||
ty::CoroutineClosure(..) => 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),
|
ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
|
||||||
|
@ -331,7 +331,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
output.push(')');
|
output.push(')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
// We've encountered a weird 'recursive type'
|
// We've encountered a weird 'recursive type'
|
||||||
// Currently, the only way to generate such a type
|
// Currently, the only way to generate such a type
|
||||||
// is by using 'impl trait':
|
// is by using 'impl trait':
|
||||||
|
@ -846,7 +846,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
ty::FnPtr(_) => (None, Some(callee.immediate())),
|
ty::FnPtr(..) => (None, Some(callee.immediate())),
|
||||||
_ => bug!("{} is not callable", callee.layout.ty),
|
_ => bug!("{} is not callable", callee.layout.ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ struct LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
|||||||
impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
match t.kind() {
|
match t.kind() {
|
||||||
ty::FnPtr(_) => {}
|
ty::FnPtr(..) => {}
|
||||||
ty::Ref(_, _, hir::Mutability::Mut) => {
|
ty::Ref(_, _, hir::Mutability::Mut) => {
|
||||||
self.checker.check_op(ops::mut_ref::MutRef(self.kind));
|
self.checker.check_op(ops::mut_ref::MutRef(self.kind));
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
@ -725,7 +725,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||||||
let (mut callee, mut fn_args) = match *fn_ty.kind() {
|
let (mut callee, mut fn_args) = match *fn_ty.kind() {
|
||||||
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||||
|
|
||||||
ty::FnPtr(_) => {
|
ty::FnPtr(..) => {
|
||||||
self.check_op(ops::FnCallIndirect);
|
self.check_op(ops::FnCallIndirect);
|
||||||
return;
|
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
|
// Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to
|
||||||
// agree with runtime equality tests.
|
// agree with runtime equality tests.
|
||||||
ty::FnPtr(_) => Err(ValTreeCreationError::NonSupportedType(ty)),
|
ty::FnPtr(..) => Err(ValTreeCreationError::NonSupportedType(ty)),
|
||||||
|
|
||||||
ty::Ref(_, _, _) => {
|
ty::Ref(_, _, _) => {
|
||||||
let derefd_place = ecx.deref_pointer(place)?;
|
let derefd_place = ecx.deref_pointer(place)?;
|
||||||
@ -353,7 +353,7 @@ pub fn valtree_to_const_value<'tcx>(
|
|||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
| ty::Coroutine(..)
|
| ty::Coroutine(..)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Str
|
| ty::Str
|
||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
|
| 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) => {
|
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
|
||||||
let src = self.read_immediate(src)?;
|
let src = self.read_immediate(src)?;
|
||||||
match cast_ty.kind() {
|
match cast_ty.kind() {
|
||||||
ty::FnPtr(_) => {
|
ty::FnPtr(..) => {
|
||||||
// No change to value
|
// No change to value
|
||||||
self.write_immediate(*src, dest)?;
|
self.write_immediate(*src, dest)?;
|
||||||
}
|
}
|
||||||
@ -230,7 +230,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
src: &ImmTy<'tcx, M::Provenance>,
|
src: &ImmTy<'tcx, M::Provenance>,
|
||||||
cast_to: TyAndLayout<'tcx>,
|
cast_to: TyAndLayout<'tcx>,
|
||||||
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
|
) -> 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());
|
assert!(cast_to.ty.is_integral());
|
||||||
|
|
||||||
let scalar = src.to_scalar();
|
let scalar = src.to_scalar();
|
||||||
|
@ -79,7 +79,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(_, _)
|
| ty::Closure(_, _)
|
||||||
| ty::CoroutineClosure(_, _)
|
| ty::CoroutineClosure(_, _)
|
||||||
|
@ -483,7 +483,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Ref(..)
|
| 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));
|
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() {
|
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_ptr = self.read_pointer(&func)?;
|
||||||
let fn_val = self.get_ptr_fn(fn_ptr)?;
|
let fn_val = self.get_ptr_fn(fn_ptr)?;
|
||||||
(fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false)
|
(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))?;
|
self.check_safe_pointer(value, PointerKind::Ref(*mutbl))?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
ty::FnPtr(_sig) => {
|
ty::FnPtr(..) => {
|
||||||
let value = self.read_scalar(value, ExpectedKind::FnPtr)?;
|
let value = self.read_scalar(value, ExpectedKind::FnPtr)?;
|
||||||
|
|
||||||
// If we check references recursively, also check that this points to a function.
|
// 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::Slice(_)
|
||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Tuple(_)
|
| ty::Tuple(_)
|
||||||
| ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
|
| ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
|
||||||
|
@ -66,7 +66,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||||||
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
|
ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
|
||||||
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
|
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
|
||||||
ty::Float(FloatTy::F128) => Some(InlineAsmType::F128),
|
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::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
|
||||||
ty::Adt(adt, args) if adt.repr().simd() => {
|
ty::Adt(adt, args) if adt.repr().simd() => {
|
||||||
let fields = &adt.non_enum_variant().fields;
|
let fields = &adt.non_enum_variant().fields;
|
||||||
|
@ -951,7 +951,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||||||
} else {
|
} else {
|
||||||
let mut diag = match ty.kind() {
|
let mut diag = match ty.kind() {
|
||||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => return Ok(()),
|
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,
|
hir_ty.span,
|
||||||
"using function pointers as const generic parameters is forbidden",
|
"using function pointers as const generic parameters is forbidden",
|
||||||
),
|
),
|
||||||
|
@ -172,7 +172,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Tuple(..) => self.check_primitive_impl(id, self_ty),
|
| ty::Tuple(..) => self.check_primitive_impl(id, self_ty),
|
||||||
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => {
|
ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => {
|
||||||
Err(self.tcx.dcx().emit_err(errors::InherentNominal { span: item_span }))
|
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);
|
self.add_constraint(current, data.index, variance);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => {
|
||||||
self.add_constraints_from_sig(current, sig, variance);
|
self.add_constraints_from_sig(current, sig_tys.with(hdr), variance);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Error(_) => {
|
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.
|
// If the callee is a bare function or a closure, then we're all set.
|
||||||
match *adjusted_ty.kind() {
|
match *adjusted_ty.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
let adjustments = self.adjust_steps(autoderef);
|
let adjustments = self.adjust_steps(autoderef);
|
||||||
self.apply_adjustments(callee_expr, adjustments);
|
self.apply_adjustments(callee_expr, adjustments);
|
||||||
return Some(CallStep::Builtin(adjusted_ty));
|
return Some(CallStep::Builtin(adjusted_ty));
|
||||||
@ -467,7 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
(fn_sig, Some(def_id))
|
(fn_sig, Some(def_id))
|
||||||
}
|
}
|
||||||
// FIXME(effects): these arms should error because we can't enforce them
|
// 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 {
|
for arg in arg_exprs {
|
||||||
self.check_expr(arg);
|
self.check_expr(arg);
|
||||||
|
@ -336,9 +336,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|obl| (obl.predicate, obl.cause.span)),
|
.map(|obl| (obl.predicate, obl.cause.span)),
|
||||||
),
|
),
|
||||||
ty::FnPtr(sig) => match closure_kind {
|
ty::FnPtr(sig_tys, hdr) => match closure_kind {
|
||||||
hir::ClosureKind::Closure => {
|
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))
|
(Some(expected_sig), Some(ty::ClosureKind::Fn))
|
||||||
}
|
}
|
||||||
hir::ClosureKind::Coroutine(_) | hir::ClosureKind::CoroutineClosure(_) => {
|
hir::ClosureKind::Coroutine(_) | hir::ClosureKind::CoroutineClosure(_) => {
|
||||||
|
@ -225,10 +225,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
// items to drop the unsafe qualifier.
|
// items to drop the unsafe qualifier.
|
||||||
self.coerce_from_fn_item(a, b)
|
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
|
// We permit coercion of fn pointers to drop the
|
||||||
// unsafe qualifier.
|
// 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) => {
|
ty::Closure(closure_def_id_a, args_a) => {
|
||||||
// Non-capturing closures are coercible to
|
// Non-capturing closures are coercible to
|
||||||
@ -788,9 +788,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
self.commit_if_ok(|snapshot| {
|
self.commit_if_ok(|snapshot| {
|
||||||
let outer_universe = self.infcx.universe();
|
let outer_universe = self.infcx.universe();
|
||||||
|
|
||||||
let result = if let ty::FnPtr(fn_ty_b) = b.kind()
|
let result = if let ty::FnPtr(_, hdr_b) = b.kind()
|
||||||
&& let (hir::Safety::Safe, hir::Safety::Unsafe) =
|
&& let (hir::Safety::Safe, hir::Safety::Unsafe) = (fn_ty_a.safety(), hdr_b.safety)
|
||||||
(fn_ty_a.safety(), fn_ty_b.safety())
|
|
||||||
{
|
{
|
||||||
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
|
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
|
||||||
self.unify_and(unsafe_a, b, to_unsafe)
|
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);
|
debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
|
||||||
|
|
||||||
match b.kind() {
|
match b.kind() {
|
||||||
ty::FnPtr(b_sig) => {
|
ty::FnPtr(_, b_hdr) => {
|
||||||
let a_sig = a.fn_sig(self.tcx);
|
let a_sig = a.fn_sig(self.tcx);
|
||||||
if let ty::FnDef(def_id, _) = *a.kind() {
|
if let ty::FnDef(def_id, _) = *a.kind() {
|
||||||
// Intrinsics are not coercible to function pointers
|
// 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).
|
// 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()
|
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
|
||||||
{
|
{
|
||||||
return Err(TypeError::TargetFeatureCast(def_id));
|
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,
|
// 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.
|
// so we check `upvars_mentioned` for root variables being captured.
|
||||||
ty::FnPtr(fn_ty)
|
ty::FnPtr(_, hdr)
|
||||||
if self
|
if self
|
||||||
.tcx
|
.tcx
|
||||||
.upvars_mentioned(closure_def_id_a.expect_local())
|
.upvars_mentioned(closure_def_id_a.expect_local())
|
||||||
@ -923,7 +922,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
// or
|
// or
|
||||||
// `unsafe fn(arg0,arg1,...) -> _`
|
// `unsafe fn(arg0,arg1,...) -> _`
|
||||||
let closure_sig = args_a.as_closure().sig();
|
let closure_sig = args_a.as_closure().sig();
|
||||||
let safety = fn_ty.safety();
|
let safety = hdr.safety;
|
||||||
let pointer_ty =
|
let pointer_ty =
|
||||||
Ty::new_fn_ptr(self.tcx, self.tcx.signature_unclosure(closure_sig, safety));
|
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);
|
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty);
|
||||||
|
@ -1527,7 +1527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
ty::Int(_) | ty::Uint(_) => Some(ty),
|
ty::Int(_) | ty::Uint(_) => Some(ty),
|
||||||
ty::Char => Some(tcx.types.u8),
|
ty::Char => Some(tcx.types.u8),
|
||||||
ty::RawPtr(..) => Some(tcx.types.usize),
|
ty::RawPtr(..) => Some(tcx.types.usize),
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
|
ty::FnDef(..) | ty::FnPtr(..) => Some(tcx.types.usize),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
opt_ty.unwrap_or_else(|| self.next_int_var())
|
opt_ty.unwrap_or_else(|| self.next_int_var())
|
||||||
|
@ -604,7 +604,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
found: Ty<'tcx>,
|
found: Ty<'tcx>,
|
||||||
) -> bool {
|
) -> 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) {
|
if let Some(upvars) = self.tcx.upvars_mentioned(*def_id) {
|
||||||
// Report upto four upvars being captured to reduce the amount error messages
|
// Report upto four upvars being captured to reduce the amount error messages
|
||||||
// reported back to the user.
|
// 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`,
|
// Not all of these (e.g., unsafe fns) implement `FnOnce`,
|
||||||
// so we look for these beforehand.
|
// so we look for these beforehand.
|
||||||
// FIXME(async_closures): These don't impl `FnOnce` by default.
|
// 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`.
|
// If it's not a simple function, look for things which implement `FnOnce`.
|
||||||
_ => {
|
_ => {
|
||||||
let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
|
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::RawPtr(..)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(..)
|
| ty::Dynamic(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Tuple(..)
|
| ty::Tuple(..)
|
||||||
|
@ -1025,7 +1025,7 @@ fn ty_is_known_nonnull<'tcx>(
|
|||||||
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
|
let ty = tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty);
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::FnPtr(_) => true,
|
ty::FnPtr(..) => true,
|
||||||
ty::Ref(..) => true,
|
ty::Ref(..) => true,
|
||||||
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
|
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
|
||||||
ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => {
|
ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => {
|
||||||
@ -1476,7 +1476,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
|
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()) {
|
if self.is_internal_abi(sig.abi()) {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
ty,
|
ty,
|
||||||
@ -1712,8 +1713,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
type Result = ControlFlow<Ty<'tcx>>;
|
type Result = ControlFlow<Ty<'tcx>>;
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||||
if let ty::FnPtr(sig) = ty.kind()
|
if let ty::FnPtr(_, hdr) = ty.kind()
|
||||||
&& !self.visitor.is_internal_abi(sig.abi())
|
&& !self.visitor.is_internal_abi(hdr.abi)
|
||||||
{
|
{
|
||||||
self.tys.push(ty);
|
self.tys.push(ty);
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
|
@ -130,7 +130,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
||||||
_ => "fn item".into(),
|
_ => "fn item".into(),
|
||||||
},
|
},
|
||||||
ty::FnPtr(_) => "fn pointer".into(),
|
ty::FnPtr(..) => "fn pointer".into(),
|
||||||
ty::Dynamic(inner, ..) if let Some(principal) = inner.principal() => {
|
ty::Dynamic(inner, ..) if let Some(principal) = inner.principal() => {
|
||||||
format!("`dyn {}`", tcx.def_path_str(principal.def_id())).into()
|
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(),
|
DefKind::Ctor(CtorOf::Variant, _) => "enum constructor".into(),
|
||||||
_ => "fn item".into(),
|
_ => "fn item".into(),
|
||||||
},
|
},
|
||||||
ty::FnPtr(_) => "fn pointer".into(),
|
ty::FnPtr(..) => "fn pointer".into(),
|
||||||
ty::Dynamic(..) => "trait object".into(),
|
ty::Dynamic(..) => "trait object".into(),
|
||||||
ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(),
|
ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(),
|
||||||
ty::Coroutine(def_id, ..) => {
|
ty::Coroutine(def_id, ..) => {
|
||||||
|
@ -250,9 +250,9 @@ impl FlagComputation {
|
|||||||
self.add_args(args);
|
self.add_args(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
&ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {
|
&ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| {
|
||||||
computation.add_tys(fn_sig.inputs());
|
computation.add_tys(sig_tys.inputs());
|
||||||
computation.add_ty(fn_sig.output());
|
computation.add_ty(sig_tys.output());
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -801,7 +801,7 @@ where
|
|||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
| ty::Uint(_)
|
| ty::Uint(_)
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
@ -986,7 +986,8 @@ where
|
|||||||
safe: None,
|
safe: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
|
ty::FnPtr(sig_tys, hdr) if offset.bytes() == 0 => {
|
||||||
|
let fn_sig = sig_tys.with(hdr);
|
||||||
tcx.layout_of(param_env.and(Ty::new_fn_ptr(tcx, fn_sig))).ok().map(|layout| {
|
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 }
|
PointeeInfo { size: layout.size, align: layout.align.abi, safe: None }
|
||||||
})
|
})
|
||||||
|
@ -2149,6 +2149,6 @@ mod size_asserts {
|
|||||||
use super::*;
|
use super::*;
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
static_assert_size!(PredicateKind<'_>, 32);
|
static_assert_size!(PredicateKind<'_>, 32);
|
||||||
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 56);
|
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ fn characteristic_def_id_of_type_cached<'a>(
|
|||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
| ty::Uint(_)
|
| ty::Uint(_)
|
||||||
| ty::Str
|
| ty::Str
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Alias(..)
|
| ty::Alias(..)
|
||||||
| ty::Placeholder(..)
|
| ty::Placeholder(..)
|
||||||
| ty::Param(_)
|
| ty::Param(_)
|
||||||
|
@ -696,7 +696,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
p!(print(sig), " {{", print_value_path(def_id, args), "}}");
|
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) => {
|
ty::Infer(infer_ty) => {
|
||||||
if self.should_print_verbose() {
|
if self.should_print_verbose() {
|
||||||
p!(write("{:?}", ty.kind()));
|
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"
|
// 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).
|
// printing above (which also has to handle pointers to all sorts of things).
|
||||||
if let Some(GlobalAlloc::Function { instance, .. }) =
|
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()))
|
p!(write("{:?}", char::try_from(int).unwrap()))
|
||||||
}
|
}
|
||||||
// Pointer types
|
// 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);
|
let data = int.to_bits(self.tcx().data_layout.pointer_size);
|
||||||
self.typed_value(
|
self.typed_value(
|
||||||
|this| {
|
|this| {
|
||||||
|
@ -374,7 +374,7 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||||||
),
|
),
|
||||||
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
|
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::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, ty, mutbl) => {
|
||||||
ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, 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::Tuple(ts) => ts.visit_with(visitor),
|
||||||
ty::FnDef(_, args) => args.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, _) => {
|
ty::Ref(r, ty, _) => {
|
||||||
try_visit!(r.visit_with(visitor));
|
try_visit!(r.visit_with(visitor));
|
||||||
ty.visit_with(visitor)
|
ty.visit_with(visitor)
|
||||||
|
@ -658,7 +658,8 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
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]
|
#[inline]
|
||||||
@ -1182,7 +1183,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| Float(_)
|
| Float(_)
|
||||||
| Uint(_)
|
| Uint(_)
|
||||||
| FnDef(..)
|
| FnDef(..)
|
||||||
| FnPtr(_)
|
| FnPtr(..)
|
||||||
| RawPtr(_, _)
|
| RawPtr(_, _)
|
||||||
| Infer(IntVar(_) | FloatVar(_))
|
| Infer(IntVar(_) | FloatVar(_))
|
||||||
)
|
)
|
||||||
@ -1333,7 +1334,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
|
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
|
FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
|
||||||
FnPtr(f) => *f,
|
FnPtr(sig_tys, hdr) => sig_tys.with(*hdr),
|
||||||
Error(_) => {
|
Error(_) => {
|
||||||
// ignore errors (#54954)
|
// ignore errors (#54954)
|
||||||
Binder::dummy(ty::FnSig {
|
Binder::dummy(ty::FnSig {
|
||||||
@ -1352,12 +1353,12 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_fn(self) -> bool {
|
pub fn is_fn(self) -> bool {
|
||||||
matches!(self.kind(), FnDef(..) | FnPtr(_))
|
matches!(self.kind(), FnDef(..) | FnPtr(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_fn_ptr(self) -> bool {
|
pub fn is_fn_ptr(self) -> bool {
|
||||||
matches!(self.kind(), FnPtr(_))
|
matches!(self.kind(), FnPtr(..))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -1599,7 +1600,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
@ -1791,7 +1792,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
@ -1941,7 +1942,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| RawPtr(_, _)
|
| RawPtr(_, _)
|
||||||
| Ref(_, _, _)
|
| Ref(_, _, _)
|
||||||
| FnDef(_, _)
|
| FnDef(_, _)
|
||||||
| FnPtr(_)
|
| FnPtr(..)
|
||||||
| Dynamic(_, _, _)
|
| Dynamic(_, _, _)
|
||||||
| Closure(_, _)
|
| Closure(_, _)
|
||||||
| CoroutineClosure(_, _)
|
| CoroutineClosure(_, _)
|
||||||
@ -1972,6 +1973,6 @@ mod size_asserts {
|
|||||||
use super::*;
|
use super::*;
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
static_assert_size!(ty::RegionKind<'_>, 24);
|
static_assert_size!(ty::RegionKind<'_>, 24);
|
||||||
static_assert_size!(ty::TyKind<'_>, 32);
|
static_assert_size!(ty::TyKind<'_>, 24);
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
}
|
}
|
||||||
|
@ -1282,7 +1282,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::Error(_)
|
| ty::Error(_)
|
||||||
| ty::FnPtr(_) => true,
|
| ty::FnPtr(..) => true,
|
||||||
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_freeze),
|
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_freeze),
|
||||||
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_freeze(),
|
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_freeze(),
|
||||||
ty::Adt(..)
|
ty::Adt(..)
|
||||||
@ -1322,7 +1322,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::Error(_)
|
| ty::Error(_)
|
||||||
| ty::FnPtr(_) => true,
|
| ty::FnPtr(..) => true,
|
||||||
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_unpin),
|
ty::Tuple(fields) => fields.iter().all(Self::is_trivially_unpin),
|
||||||
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_unpin(),
|
ty::Pat(ty, _) | ty::Slice(ty) | ty::Array(ty, _) => ty.is_trivially_unpin(),
|
||||||
ty::Adt(..)
|
ty::Adt(..)
|
||||||
@ -1361,7 +1361,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Infer(ty::FreshIntTy(_))
|
| ty::Infer(ty::FreshIntTy(_))
|
||||||
| ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop,
|
| ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop,
|
||||||
|
|
||||||
@ -1544,7 +1544,7 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
ty::Pat(..) | ty::Ref(..) | ty::Array(..) | ty::Slice(_) | ty::Tuple(..) => true,
|
ty::Pat(..) | ty::Ref(..) | ty::Array(..) | ty::Slice(_) | ty::Tuple(..) => true,
|
||||||
|
|
||||||
// Raw pointers use bitwise comparison.
|
// Raw pointers use bitwise comparison.
|
||||||
ty::RawPtr(_, _) | ty::FnPtr(_) => true,
|
ty::RawPtr(_, _) | ty::FnPtr(..) => true,
|
||||||
|
|
||||||
// Floating point numbers are not `Eq`.
|
// Floating point numbers are not `Eq`.
|
||||||
ty::Float(_) => false,
|
ty::Float(_) => false,
|
||||||
@ -1675,7 +1675,7 @@ pub fn needs_drop_components_with_async<'tcx>(
|
|||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
@ -1742,7 +1742,7 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Foreign(_) => true,
|
| ty::Foreign(_) => true,
|
||||||
|
|
||||||
|
@ -189,9 +189,12 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
|||||||
stack.extend(args.iter().rev());
|
stack.extend(args.iter().rev());
|
||||||
}
|
}
|
||||||
ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
|
ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => {
|
||||||
stack.push(sig.skip_binder().output().into());
|
let fn_sig = sig_tys.with(hdr);
|
||||||
stack.extend(sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()));
|
stack.push(fn_sig.skip_binder().output().into());
|
||||||
|
stack.extend(
|
||||||
|
fn_sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GenericArgKind::Lifetime(_) => {}
|
GenericArgKind::Lifetime(_) => {}
|
||||||
|
@ -158,7 +158,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
|||||||
| ty::Pat(_, _)
|
| ty::Pat(_, _)
|
||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
@ -201,7 +201,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
|
@ -64,7 +64,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
|
|||||||
let ty = func.ty(body, tcx);
|
let ty = func.ty(body, tcx);
|
||||||
let sig = ty.fn_sig(tcx);
|
let sig = ty.fn_sig(tcx);
|
||||||
let fn_def_id = match ty.kind() {
|
let fn_def_id = match ty.kind() {
|
||||||
ty::FnPtr(_) => None,
|
ty::FnPtr(..) => None,
|
||||||
&ty::FnDef(def_id, _) => Some(def_id),
|
&ty::FnDef(def_id, _) => Some(def_id),
|
||||||
_ => span_bug!(span, "invalid callee of type {:?}", ty),
|
_ => 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() {
|
let fn_def_id = match ty.kind() {
|
||||||
ty::FnPtr(_) => None,
|
ty::FnPtr(..) => None,
|
||||||
&ty::FnDef(def_id, _) => {
|
&ty::FnDef(def_id, _) => {
|
||||||
// Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust ABI).
|
// 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.
|
// 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)));
|
let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
|
||||||
|
|
||||||
match self_ty.kind() {
|
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::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()),
|
||||||
ty::CoroutineClosure(_, args) => {
|
ty::CoroutineClosure(_, args) => {
|
||||||
builder.tuple_like_shim(dest, src, args.as_coroutine_closure().upvar_tys())
|
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::Ref(_, _, _)
|
||||||
| ty::Pat(_, _)
|
| ty::Pat(_, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
|
@ -334,7 +334,7 @@ where
|
|||||||
| ty::Str
|
| ty::Str
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::Pat(..)
|
| ty::Pat(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Array(..)
|
| ty::Array(..)
|
||||||
| ty::Slice(..)
|
| ty::Slice(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
|
@ -533,7 +533,7 @@ where
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(..)
|
| ty::Dynamic(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
@ -620,7 +620,7 @@ where
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Alias(..)
|
| ty::Alias(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
|
@ -31,7 +31,7 @@ where
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Error(_)
|
| ty::Error(_)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Char => Ok(vec![]),
|
| ty::Char => Ok(vec![]),
|
||||||
@ -117,7 +117,7 @@ where
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
@ -178,7 +178,7 @@ where
|
|||||||
{
|
{
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
// impl Copy/Clone for FnDef, FnPtr
|
// 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
|
// Implementations are provided in core
|
||||||
ty::Uint(_)
|
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.
|
// 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() {
|
if sig.is_fn_trait_compatible() {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
sig.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
|
sig.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
|
||||||
|
@ -1145,7 +1145,7 @@ where
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
| ty::Coroutine(_, _)
|
| 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 {
|
for meta_item in meta_items {
|
||||||
match meta_item.name_or_empty() {
|
match meta_item.name_or_empty() {
|
||||||
sym::debug => {
|
sym::debug => {
|
||||||
let ty::FnPtr(sig) = ty.kind() else {
|
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
meta_item.span(),
|
meta_item.span(),
|
||||||
"`#[rustc_abi(debug)]` on a type alias requires function pointer type"
|
"`#[rustc_abi(debug)]` on a type alias requires function pointer type"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
let abi = unwrap_fn_abi(
|
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,
|
tcx,
|
||||||
item_def_id,
|
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"
|
"`#[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!(
|
span_bug!(
|
||||||
meta_item.span(),
|
meta_item.span(),
|
||||||
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
|
"`#[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(
|
let abi1 = unwrap_fn_abi(
|
||||||
tcx.fn_abi_of_fn_ptr(
|
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,
|
tcx,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
);
|
);
|
||||||
let ty::FnPtr(sig2) = field2.kind() else {
|
let ty::FnPtr(sig_tys2, hdr2) = field2.kind() else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
meta_item.span(),
|
meta_item.span(),
|
||||||
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
|
"`#[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(
|
let abi2 = unwrap_fn_abi(
|
||||||
tcx.fn_abi_of_fn_ptr(
|
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,
|
tcx,
|
||||||
item_def_id,
|
item_def_id,
|
||||||
|
@ -414,7 +414,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||||||
| ty::Foreign(_)
|
| ty::Foreign(_)
|
||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Pat(_, _)
|
| ty::Pat(_, _)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
|
@ -607,10 +607,15 @@ pub fn encode_ty<'tcx>(
|
|||||||
typeid.push_str(&s);
|
typeid.push_str(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FnPtr(fn_sig) => {
|
ty::FnPtr(sig_tys, hdr) => {
|
||||||
// PF<return-type><parameter-type1..parameter-typeN>E
|
// PF<return-type><parameter-type1..parameter-typeN>E
|
||||||
let mut s = String::from("P");
|
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);
|
compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
|
||||||
typeid.push_str(&s);
|
typeid.push_str(&s);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,10 @@ impl RustcInternal for RigidTy {
|
|||||||
RigidTy::FnDef(def, args) => {
|
RigidTy::FnDef(def, args) => {
|
||||||
rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx))
|
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) => {
|
RigidTy::Closure(def, args) => {
|
||||||
rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx))
|
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) => {
|
ty::FnDef(def_id, generic_args) => {
|
||||||
TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
|
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) => {
|
ty::Dynamic(existential_predicates, region, dyn_kind) => {
|
||||||
TyKind::RigidTy(RigidTy::Dynamic(
|
TyKind::RigidTy(RigidTy::Dynamic(
|
||||||
existential_predicates
|
existential_predicates
|
||||||
|
@ -427,7 +427,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
|||||||
self.print_def_path(def_id, &[])?;
|
self.print_def_path(def_id, &[])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => {
|
||||||
|
let sig = sig_tys.with(hdr);
|
||||||
self.push("F");
|
self.push("F");
|
||||||
self.in_binder(&sig, |cx, sig| {
|
self.in_binder(&sig, |cx, sig| {
|
||||||
if sig.safety == hir::Safety::Unsafe {
|
if sig.safety == hir::Safety::Unsafe {
|
||||||
|
@ -1087,9 +1087,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
values
|
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 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!(
|
values.0.push_highlighted(format!(
|
||||||
" {{{}}}",
|
" {{{}}}",
|
||||||
self.tcx.def_path_str_with_args(*did1, args1)
|
self.tcx.def_path_str_with_args(*did1, args1)
|
||||||
@ -1097,16 +1097,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
values
|
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 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
|
values
|
||||||
.1
|
.1
|
||||||
.push_normal(format!(" {{{}}}", self.tcx.def_path_str_with_args(*did2, args2)));
|
.push_normal(format!(" {{{}}}", self.tcx.def_path_str_with_args(*did2, args2)));
|
||||||
values
|
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());
|
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::FnPtr(_, hdr), ty::FnDef(def_id, _))
|
||||||
| (ty::FnDef(def_id, _), ty::FnPtr(sig)) => {
|
| (ty::FnDef(def_id, _), ty::FnPtr(_, hdr)) => {
|
||||||
if tcx.fn_sig(def_id).skip_binder().safety() < sig.safety() {
|
if tcx.fn_sig(def_id).skip_binder().safety() < hdr.safety {
|
||||||
diag.note(
|
diag.note(
|
||||||
"unsafe functions cannot be coerced into safe function pointers",
|
"unsafe functions cannot be coerced into safe function pointers",
|
||||||
);
|
);
|
||||||
|
@ -383,8 +383,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match (&expected_inner.kind(), &found_inner.kind()) {
|
match (&expected_inner.kind(), &found_inner.kind()) {
|
||||||
(ty::FnPtr(sig), ty::FnDef(did, args)) => {
|
(ty::FnPtr(sig_tys, hdr), ty::FnDef(did, args)) => {
|
||||||
let expected_sig = &(self.normalize_fn_sig)(*sig);
|
let sig = sig_tys.with(*hdr);
|
||||||
|
let expected_sig = &(self.normalize_fn_sig)(sig);
|
||||||
let found_sig =
|
let found_sig =
|
||||||
&(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args));
|
&(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 },
|
(false, true) => FunctionPointerSuggestion::RemoveRef { span, fn_name },
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
diag.subdiagnostic(FnItemsAreDistinct);
|
diag.subdiagnostic(FnItemsAreDistinct);
|
||||||
FunctionPointerSuggestion::CastRef { span, fn_name, sig: *sig }
|
FunctionPointerSuggestion::CastRef { span, fn_name, sig }
|
||||||
}
|
}
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
diag.subdiagnostic(FnItemsAreDistinct);
|
diag.subdiagnostic(FnItemsAreDistinct);
|
||||||
FunctionPointerSuggestion::Cast { span, fn_name, sig: *sig }
|
FunctionPointerSuggestion::Cast { span, fn_name, sig }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
diag.subdiagnostic(sugg);
|
diag.subdiagnostic(sugg);
|
||||||
@ -449,10 +450,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
|
|
||||||
diag.subdiagnostic(sug);
|
diag.subdiagnostic(sug);
|
||||||
}
|
}
|
||||||
(ty::FnDef(did, args), ty::FnPtr(sig)) => {
|
(ty::FnDef(did, args), ty::FnPtr(sig_tys, hdr)) => {
|
||||||
let expected_sig =
|
let expected_sig =
|
||||||
&(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args));
|
&(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) {
|
if !self.same_type_modulo_infer(*found_sig, *expected_sig) {
|
||||||
return;
|
return;
|
||||||
|
@ -375,7 +375,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
let impl_candidates = self.find_similar_impl_candidates(leaf_trait_predicate);
|
let impl_candidates = self.find_similar_impl_candidates(leaf_trait_predicate);
|
||||||
suggested = if let &[cand] = &impl_candidates[..] {
|
suggested = if let &[cand] = &impl_candidates[..] {
|
||||||
let cand = cand.trait_ref;
|
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())
|
(cand.self_ty().kind(), main_trait_ref.self_ty().skip_binder().kind())
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
@ -793,8 +793,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
// is unimplemented is because async closures don't implement `Fn`/`FnMut`
|
// is unimplemented is because async closures don't implement `Fn`/`FnMut`
|
||||||
// if they have captures.
|
// if they have captures.
|
||||||
if let Some(by_ref_captures) = by_ref_captures
|
if let Some(by_ref_captures) = by_ref_captures
|
||||||
&& let ty::FnPtr(sig) = by_ref_captures.kind()
|
&& let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
|
||||||
&& !sig.skip_binder().output().is_unit()
|
&& !sig_tys.skip_binder().output().is_unit()
|
||||||
{
|
{
|
||||||
let mut err = self.dcx().create_err(AsyncClosureNotFn {
|
let mut err = self.dcx().create_err(AsyncClosureNotFn {
|
||||||
span: self.tcx.def_span(closure_def_id),
|
span: self.tcx.def_span(closure_def_id),
|
||||||
@ -1061,7 +1061,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
"`{ty}` is forbidden as the type of a const generic parameter",
|
"`{ty}` is forbidden as the type of a const generic parameter",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::FnPtr(_) => {
|
ty::FnPtr(..) => {
|
||||||
struct_span_code_err!(
|
struct_span_code_err!(
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
span,
|
span,
|
||||||
@ -1844,10 +1844,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
if let &[cand] = &candidates[..] {
|
if let &[cand] = &candidates[..] {
|
||||||
let (desc, mention_castable) =
|
let (desc, mention_castable) =
|
||||||
match (cand.self_ty().kind(), trait_ref.self_ty().skip_binder().kind()) {
|
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`")
|
(" implemented for fn pointer `", ", cast using `as`")
|
||||||
}
|
}
|
||||||
(ty::FnPtr(_), _) => (" implemented for fn pointer `", ""),
|
(ty::FnPtr(..), _) => (" implemented for fn pointer `", ""),
|
||||||
_ => (" implemented for `", ""),
|
_ => (" implemented for `", ""),
|
||||||
};
|
};
|
||||||
err.highlighted_help(vec![
|
err.highlighted_help(vec![
|
||||||
|
@ -1077,10 +1077,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
let Some((def_id_or_name, output, inputs)) =
|
let Some((def_id_or_name, output, inputs)) =
|
||||||
(self.autoderef_steps)(found).into_iter().find_map(|(found, _)| {
|
(self.autoderef_steps)(found).into_iter().find_map(|(found, _)| {
|
||||||
match *found.kind() {
|
match *found.kind() {
|
||||||
ty::FnPtr(fn_sig) => Some((
|
ty::FnPtr(sig_tys, _) => Some((
|
||||||
DefIdOrName::Name("function pointer"),
|
DefIdOrName::Name("function pointer"),
|
||||||
fn_sig.output(),
|
sig_tys.output(),
|
||||||
fn_sig.inputs(),
|
sig_tys.inputs(),
|
||||||
)),
|
)),
|
||||||
ty::FnDef(def_id, _) => {
|
ty::FnDef(def_id, _) => {
|
||||||
let fn_sig = found.fn_sig(self.tcx);
|
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 {
|
let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = cause else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let ty::FnPtr(expected) = expected.kind() else {
|
let ty::FnPtr(sig_tys, hdr) = expected.kind() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let ty::FnPtr(found) = found.kind() else {
|
let expected = sig_tys.with(*hdr);
|
||||||
|
let ty::FnPtr(sig_tys, hdr) = found.kind() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
let found = sig_tys.with(*hdr);
|
||||||
let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) else {
|
let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let hir::ExprKind::Path(path) = arg.kind else {
|
let hir::ExprKind::Path(path) = arg.kind else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let expected_inputs = self.tcx.instantiate_bound_regions_with_erased(*expected).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 found_inputs = self.tcx.instantiate_bound_regions_with_erased(found).inputs();
|
||||||
let both_tys = expected_inputs.iter().copied().zip(found_inputs.iter().copied());
|
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>| {
|
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() {
|
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 => {
|
kind => {
|
||||||
span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
|
span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let expected_args = match expected.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 => {
|
kind => {
|
||||||
span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", 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)
|
.generics_of(def_id)
|
||||||
.host_effect_index
|
.host_effect_index
|
||||||
.map_or(tcx.consts.true_, |idx| args.const_at(idx)),
|
.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`"),
|
_ => 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::Float(_)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
@ -224,7 +224,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
|||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::CoroutineWitness(..) => {
|
| ty::CoroutineWitness(..) => {
|
||||||
// these types never have a destructor
|
// these types never have a destructor
|
||||||
}
|
}
|
||||||
|
@ -468,8 +468,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
candidates.vec.push(AsyncClosureCandidate);
|
candidates.vec.push(AsyncClosureCandidate);
|
||||||
}
|
}
|
||||||
// Provide an impl, but only for suitable `fn` pointers.
|
// Provide an impl, but only for suitable `fn` pointers.
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => {
|
||||||
if sig.is_fn_trait_compatible() {
|
if sig_tys.with(hdr).is_fn_trait_compatible() {
|
||||||
candidates.vec.push(AsyncClosureCandidate);
|
candidates.vec.push(AsyncClosureCandidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,8 +535,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
candidates.ambiguous = true; // Could wind up being a fn() type.
|
candidates.ambiguous = true; // Could wind up being a fn() type.
|
||||||
}
|
}
|
||||||
// Provide an impl, but only for suitable `fn` pointers.
|
// Provide an impl, but only for suitable `fn` pointers.
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig_tys, hdr) => {
|
||||||
if sig.is_fn_trait_compatible() {
|
if sig_tys.with(hdr).is_fn_trait_compatible() {
|
||||||
candidates
|
candidates
|
||||||
.vec
|
.vec
|
||||||
.push(FnPointerCandidate { fn_host_effect: self.tcx().consts.true_ });
|
.push(FnPointerCandidate { fn_host_effect: self.tcx().consts.true_ });
|
||||||
@ -819,7 +819,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
| ty::Coroutine(..)
|
| ty::Coroutine(..)
|
||||||
@ -1207,7 +1207,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Foreign(_)
|
| ty::Foreign(_)
|
||||||
| ty::Array(..)
|
| ty::Array(..)
|
||||||
@ -1290,7 +1290,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::Pat(_, _)
|
| ty::Pat(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::CoroutineClosure(..)
|
| ty::CoroutineClosure(..)
|
||||||
@ -1339,7 +1339,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
|
let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
|
||||||
|
|
||||||
match self_ty.skip_binder().kind() {
|
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::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
|
@ -1398,7 +1398,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Foreign(_) => {}
|
| ty::Foreign(_) => {}
|
||||||
|
|
||||||
|
@ -2114,7 +2114,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
@ -2171,7 +2171,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||||||
use self::BuiltinImplConditions::{Ambiguous, None, Where};
|
use self::BuiltinImplConditions::{Ambiguous, None, Where};
|
||||||
|
|
||||||
match *self_ty.kind() {
|
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::Uint(_)
|
||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
@ -2333,7 +2333,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Error(_)
|
| ty::Error(_)
|
||||||
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||||
| ty::Never
|
| ty::Never
|
||||||
|
@ -812,7 +812,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||||||
return upvars.visit_with(self);
|
return upvars.visit_with(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FnPtr(_) => {
|
ty::FnPtr(..) => {
|
||||||
// Let the visitor iterate into the argument/return
|
// Let the visitor iterate into the argument/return
|
||||||
// types appearing in the fn signature.
|
// types appearing in the fn signature.
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ fn resolve_associated_item<'tcx>(
|
|||||||
if name == sym::clone {
|
if name == sym::clone {
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.self_ty();
|
||||||
match self_ty.kind() {
|
match self_ty.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => (),
|
ty::FnDef(..) | ty::FnPtr(..) => (),
|
||||||
ty::Coroutine(..)
|
ty::Coroutine(..)
|
||||||
| ty::CoroutineWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
|
@ -184,7 +184,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
|
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::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
|
||||||
ty::Float(fty) => scalar(Float(Float::from_float_ty(fty))),
|
ty::Float(fty) => scalar(Float(Float::from_float_ty(fty))),
|
||||||
ty::FnPtr(_) => {
|
ty::FnPtr(..) => {
|
||||||
let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
|
let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
|
||||||
ptr.valid_range_mut().start = 1;
|
ptr.valid_range_mut().start = 1;
|
||||||
tcx.mk_layout(LayoutS::scalar(cx, ptr))
|
tcx.mk_layout(LayoutS::scalar(cx, ptr))
|
||||||
|
@ -86,6 +86,7 @@ macro_rules! impl_binder_encode_decode {
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
impl_binder_encode_decode! {
|
impl_binder_encode_decode! {
|
||||||
ty::FnSig<I>,
|
ty::FnSig<I>,
|
||||||
|
ty::FnSigTys<I>,
|
||||||
ty::TraitPredicate<I>,
|
ty::TraitPredicate<I>,
|
||||||
ty::ExistentialPredicate<I>,
|
ty::ExistentialPredicate<I>,
|
||||||
ty::TraitRef<I>,
|
ty::TraitRef<I>,
|
||||||
|
@ -135,7 +135,9 @@ pub fn simplify_type<I: Interner>(
|
|||||||
ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id)),
|
ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id)),
|
||||||
ty::Never => Some(SimplifiedType::Never),
|
ty::Never => Some(SimplifiedType::Never),
|
||||||
ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())),
|
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::Placeholder(..) => Some(SimplifiedType::Placeholder),
|
||||||
ty::Param(_) => match treat_params {
|
ty::Param(_) => match treat_params {
|
||||||
TreatParams::ForLookup => Some(SimplifiedType::Placeholder),
|
TreatParams::ForLookup => Some(SimplifiedType::Placeholder),
|
||||||
@ -307,17 +309,14 @@ impl<I: Interner> DeepRejectCtxt<I> {
|
|||||||
obl_preds.principal_def_id() == impl_preds.principal_def_id()
|
obl_preds.principal_def_id() == impl_preds.principal_def_id()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::FnPtr(obl_sig) => match k {
|
ty::FnPtr(obl_sig_tys, obl_hdr) => match k {
|
||||||
ty::FnPtr(impl_sig) => {
|
ty::FnPtr(impl_sig_tys, impl_hdr) => {
|
||||||
let ty::FnSig { inputs_and_output, c_variadic, safety, abi } =
|
let obl_sig_tys = obl_sig_tys.skip_binder().0;
|
||||||
obl_sig.skip_binder();
|
let impl_sig_tys = impl_sig_tys.skip_binder().0;
|
||||||
let impl_sig = impl_sig.skip_binder();
|
|
||||||
|
|
||||||
abi == impl_sig.abi
|
obl_hdr == impl_hdr
|
||||||
&& c_variadic == impl_sig.c_variadic
|
&& obl_sig_tys.len() == impl_sig_tys.len()
|
||||||
&& safety == impl_sig.safety
|
&& iter::zip(obl_sig_tys.iter(), impl_sig_tys.iter())
|
||||||
&& inputs_and_output.len() == impl_sig.inputs_and_output.len()
|
|
||||||
&& iter::zip(inputs_and_output.iter(), impl_sig.inputs_and_output.iter())
|
|
||||||
.all(|(obl, imp)| self.types_may_unify(obl, imp))
|
.all(|(obl, imp)| self.types_may_unify(obl, imp))
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -133,12 +133,12 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_fn_ptr(self) -> bool {
|
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>> {
|
fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
|
||||||
match self.kind() {
|
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::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
|
||||||
ty::Error(_) => {
|
ty::Error(_) => {
|
||||||
// ignore errors (#54954)
|
// ignore errors (#54954)
|
||||||
@ -181,7 +181,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnDef(_, _)
|
| ty::FnDef(_, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(_, _)
|
| ty::Closure(_, _)
|
||||||
| ty::CoroutineClosure(_, _)
|
| ty::CoroutineClosure(_, _)
|
||||||
|
@ -186,7 +186,7 @@ impl<I: Interner> TypeVisitor<I> for OutlivesCollector<'_, I> {
|
|||||||
| ty::Slice(_)
|
| ty::Slice(_)
|
||||||
| ty::RawPtr(_, _)
|
| ty::RawPtr(_, _)
|
||||||
| ty::Ref(_, _, _)
|
| ty::Ref(_, _, _)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Tuple(_) => {
|
| ty::Tuple(_) => {
|
||||||
ty.super_visit_with(self);
|
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))
|
Ok(Ty::new_fn_def(cx, a_def_id, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::FnPtr(a_fty), ty::FnPtr(b_fty)) => {
|
(ty::FnPtr(a_sig_tys, a_hdr), ty::FnPtr(b_sig_tys, b_hdr)) => {
|
||||||
let fty = relation.relate(a_fty, b_fty)?;
|
let fty = relation.relate(a_sig_tys.with(a_hdr), b_sig_tys.with(b_hdr))?;
|
||||||
Ok(Ty::new_fn_ptr(cx, fty))
|
Ok(Ty::new_fn_ptr(cx, fty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,12 @@ pub enum TyKind<I: Interner> {
|
|||||||
/// fn foo() -> i32 { 1 }
|
/// fn foo() -> i32 { 1 }
|
||||||
/// let bar: fn() -> i32 = foo;
|
/// 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`.
|
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
|
||||||
Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
|
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),
|
RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
|
||||||
Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
|
Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
|
||||||
FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
|
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 {
|
Dynamic(p, r, repr) => match repr {
|
||||||
DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
|
DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
|
||||||
DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
|
DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
|
||||||
@ -918,6 +923,13 @@ impl<I: Interner> ty::Binder<I, FnSig<I>> {
|
|||||||
pub fn is_fn_trait_compatible(&self) -> bool {
|
pub fn is_fn_trait_compatible(&self) -> bool {
|
||||||
self.skip_binder().is_fn_trait_compatible()
|
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(sig.inputs_and_output)), hdr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Interner> fmt::Debug for FnSig<I> {
|
impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||||
@ -954,3 +966,60 @@ impl<I: Interner> fmt::Debug for FnSig<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 I::Tys);
|
||||||
|
|
||||||
|
impl<I: Interner> FnSigTys<I> {
|
||||||
|
pub fn inputs(self) -> I::FnInputTys {
|
||||||
|
self.0.inputs()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(self) -> I::Ty {
|
||||||
|
self.0.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.0,
|
||||||
|
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.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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.
|
/// Extracts the signature from the closure.
|
||||||
pub fn sig(self) -> ty::Binder<I, ty::FnSig<I>> {
|
pub fn sig(self) -> ty::Binder<I, ty::FnSig<I>> {
|
||||||
match self.sig_as_fn_ptr_ty().kind() {
|
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:?}"),
|
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>> {
|
pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>> {
|
||||||
let interior = self.coroutine_witness_ty();
|
let interior = self.coroutine_witness_ty();
|
||||||
let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { panic!() };
|
let ty::FnPtr(sig_tys, hdr) = self.signature_parts_ty().kind() else { panic!() };
|
||||||
sig.map_bound(|sig| {
|
sig_tys.map_bound(|sig_tys| {
|
||||||
let [resume_ty, tupled_inputs_ty] = *sig.inputs().as_slice() else {
|
let [resume_ty, tupled_inputs_ty] = *sig_tys.inputs().as_slice() else {
|
||||||
panic!();
|
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 {
|
CoroutineClosureSignature {
|
||||||
interior,
|
interior,
|
||||||
tupled_inputs_ty,
|
tupled_inputs_ty,
|
||||||
resume_ty,
|
resume_ty,
|
||||||
yield_ty,
|
yield_ty,
|
||||||
return_ty,
|
return_ty,
|
||||||
c_variadic: sig.c_variadic,
|
c_variadic: hdr.c_variadic,
|
||||||
safety: sig.safety,
|
safety: hdr.safety,
|
||||||
abi: sig.abi,
|
abi: hdr.abi,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -321,7 +323,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
|
|||||||
|
|
||||||
pub fn has_self_borrows(&self) -> bool {
|
pub fn has_self_borrows(&self) -> bool {
|
||||||
match self.coroutine_captures_by_ref_ty().kind() {
|
match self.coroutine_captures_by_ref_ty().kind() {
|
||||||
ty::FnPtr(sig) => sig
|
ty::FnPtr(sig_tys, _) => sig_tys
|
||||||
.skip_binder()
|
.skip_binder()
|
||||||
.visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST })
|
.visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST })
|
||||||
.is_break(),
|
.is_break(),
|
||||||
@ -460,11 +462,11 @@ impl<I: Interner> CoroutineClosureSignature<I> {
|
|||||||
) -> I::Ty {
|
) -> I::Ty {
|
||||||
match kind {
|
match kind {
|
||||||
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => {
|
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!();
|
panic!();
|
||||||
};
|
};
|
||||||
let coroutine_captures_by_ref_ty =
|
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,
|
interner: cx,
|
||||||
region: env_region,
|
region: env_region,
|
||||||
debruijn: ty::INNERMOST,
|
debruijn: ty::INNERMOST,
|
||||||
|
@ -2069,7 +2069,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
|||||||
Some(ContainerTy::Ref(r)),
|
Some(ContainerTy::Ref(r)),
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
// FIXME: should we merge the outer and inner binders somehow?
|
// FIXME: should we merge the outer and inner binders somehow?
|
||||||
let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
|
let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
|
||||||
let decl = clean_poly_fn_sig(cx, None, sig);
|
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::RawPtr(_, _) => Res::Primitive(RawPointer),
|
||||||
ty::Ref(..) => Res::Primitive(Reference),
|
ty::Ref(..) => Res::Primitive(Reference),
|
||||||
ty::FnDef(..) => panic!("type alias to a function definition"),
|
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::Never => Res::Primitive(Never),
|
||||||
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => {
|
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) | ty::Foreign(did) => {
|
||||||
Res::from_def_id(self.cx.tcx, 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() {
|
match cast_from.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
let mut applicability = Applicability::MaybeIncorrect;
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
|
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);
|
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 */ },
|
_ => { /* 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 mut applicability = Applicability::MaybeIncorrect;
|
||||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
|
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,
|
_ => return,
|
||||||
}
|
}
|
||||||
match cast_from.kind() {
|
match cast_from.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
let mut applicability = Applicability::MaybeIncorrect;
|
let mut applicability = Applicability::MaybeIncorrect;
|
||||||
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
|
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.
|
// We can't use `Ty::fn_sig` because it automatically performs args, this may result in FNs.
|
||||||
match node_ty.kind() {
|
match node_ty.kind() {
|
||||||
ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).instantiate_identity()),
|
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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -872,7 +872,7 @@ impl TyCoercionStability {
|
|||||||
| ty::Pat(..)
|
| ty::Pat(..)
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(..)
|
||||||
| ty::Str
|
| ty::Str
|
||||||
| ty::Slice(..)
|
| ty::Slice(..)
|
||||||
| ty::Adt(..)
|
| 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()
|
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
|
ty::Closure(_, subs) => cx
|
||||||
.tcx
|
.tcx
|
||||||
.signature_unclosure(subs.as_closure().sig(), Safety::Safe)
|
.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 {
|
fn is_map_to_option(cx: &LateContext<'_>, map_arg: &Expr<'_>) -> bool {
|
||||||
let map_closure_ty = cx.typeck_results().expr_ty(map_arg);
|
let map_closure_ty = cx.typeck_results().expr_ty(map_arg);
|
||||||
match map_closure_ty.kind() {
|
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() {
|
let map_closure_sig = match map_closure_ty.kind() {
|
||||||
ty::Closure(_, args) => args.as_closure().sig(),
|
ty::Closure(_, args) => args.as_closure().sig(),
|
||||||
_ => map_closure_ty.fn_sig(cx.tcx),
|
_ => map_closure_ty.fn_sig(cx.tcx),
|
||||||
|
@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
|
|||||||
ExprKind::Call(func, _) => {
|
ExprKind::Call(func, _) => {
|
||||||
let typ = self.cx.typeck_results().expr_ty(func);
|
let typ = self.cx.typeck_results().expr_ty(func);
|
||||||
match typ.kind() {
|
match typ.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
let sig = typ.fn_sig(self.cx.tcx);
|
let sig = typ.fn_sig(self.cx.tcx);
|
||||||
if self.cx.tcx.instantiate_bound_regions_with_erased(sig).output().kind() == &ty::Never {
|
if self.cx.tcx.instantiate_bound_regions_with_erased(sig).output().kind() == &ty::Never {
|
||||||
self.report_diverging_sub_expr(e);
|
self.report_diverging_sub_expr(e);
|
||||||
|
@ -130,7 +130,7 @@ fn collect_unsafe_exprs<'tcx>(
|
|||||||
ExprKind::Call(path_expr, _) => {
|
ExprKind::Call(path_expr, _) => {
|
||||||
let sig = match *cx.typeck_results().expr_ty(path_expr).kind() {
|
let sig = match *cx.typeck_results().expr_ty(path_expr).kind() {
|
||||||
ty::FnDef(id, _) => cx.tcx.fn_sig(id).skip_binder(),
|
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),
|
_ => return Continue(Descend::Yes),
|
||||||
};
|
};
|
||||||
if sig.safety() == Safety::Unsafe {
|
if sig.safety() == Safety::Unsafe {
|
||||||
|
@ -79,7 +79,7 @@ fn check_arguments<'tcx>(
|
|||||||
fn_kind: &str,
|
fn_kind: &str,
|
||||||
) {
|
) {
|
||||||
match type_definition.kind() {
|
match type_definition.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||||
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
|
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
|
||||||
for (argument, parameter) in iter::zip(arguments, parameters) {
|
for (argument, parameter) in iter::zip(arguments, parameters) {
|
||||||
match parameter.kind() {
|
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.
|
/// Returns `true` if the given type is an `unsafe` function.
|
||||||
pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
match ty.kind() {
|
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,
|
_ => 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.item_super_predicates(def_id).iter_instantiated(cx.tcx, args),
|
||||||
cx.tcx.opt_parent(def_id),
|
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, _, _) => {
|
ty::Dynamic(bounds, _, _) => {
|
||||||
let lang_items = cx.tcx.lang_items();
|
let lang_items = cx.tcx.lang_items();
|
||||||
match bounds.principal() {
|
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 => {
|
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => {
|
||||||
self.is_unsafe = true;
|
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),
|
_ => walk_expr(self, e),
|
||||||
},
|
},
|
||||||
ExprKind::Path(ref p)
|
ExprKind::Path(ref p)
|
||||||
|
Loading…
Reference in New Issue
Block a user