diff --git a/Cargo.lock b/Cargo.lock index 6c9ac52d1c40c..e2033023f9d56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4578,7 +4578,6 @@ name = "rustc_query_impl" version = "0.0.0" dependencies = [ "measureme", - "rustc_abi", "rustc_data_structures", "rustc_errors", "rustc_hir", diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 9173245d8aa4e..95ba2ee3b78f8 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -131,6 +131,29 @@ macro_rules! abi_impls { $($e_name::$variant $( { unwind: $uw } )* => $tok,)* } } + // FIXME(FnSigKind): when PartialEq is stably const, use it instead + const fn internal_const_eq(&self, other: &Self) -> bool { + match (self, other) { + $( ( $e_name::$variant $( { unwind: $uw } )* , $e_name::$variant $( { unwind: $uw } )* ) => true,)* + _ => false, + } + } + // ALL_VARIANTS.iter().position(|v| v == self), but const + pub const fn as_packed(&self) -> u8 { + let mut index = 0; + while index < $e_name::ALL_VARIANTS.len() { + if self.internal_const_eq(&$e_name::ALL_VARIANTS[index]) { + return index as u8; + } + index += 1; + } + panic!("unreachable: invalid ExternAbi variant"); + } + pub const fn from_packed(index: u8) -> Self { + let index = index as usize; + assert!(index < $e_name::ALL_VARIANTS.len(), "invalid ExternAbi index"); + $e_name::ALL_VARIANTS[index] + } } impl ::core::str::FromStr for $e_name { diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index ee4a52fb3863e..01382a69f2ec0 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -46,9 +46,9 @@ use rustc_ast as ast; use rustc_ast::*; use rustc_data_structures::fx::FxHashSet; use rustc_errors::ErrorGuaranteed; -use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, FnDeclFlags}; use rustc_middle::span_bug; use rustc_middle::ty::Asyncness; use rustc_span::symbol::kw; @@ -271,7 +271,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // Function parameter count, including C variadic `...` if present. fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) { let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder(); - (sig.inputs().len() + usize::from(sig.c_variadic), sig.c_variadic) + (sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic()) } fn lower_delegation_decl( @@ -309,9 +309,9 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { self.arena.alloc(hir::FnDecl { inputs, output: hir::FnRetTy::Return(output), - c_variadic, - lifetime_elision_allowed: true, - implicit_self: hir::ImplicitSelfKind::None, + fn_decl_kind: FnDeclFlags::default() + .set_lifetime_elision_allowed(true) + .set_c_variadic(c_variadic), }) } @@ -331,11 +331,11 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { safety: if self.tcx.codegen_fn_attrs(sig_id).safe_target_features { hir::HeaderSafety::SafeTargetFeatures } else { - hir::HeaderSafety::Normal(sig.safety) + hir::HeaderSafety::Normal(sig.safety()) }, constness: self.tcx.constness(sig_id), asyncness, - abi: sig.abi, + abi: sig.abi(), }; hir::FnSig { decl, header, span } @@ -603,13 +603,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { span: Span, delegation: &Delegation, ) -> DelegationResults<'hir> { - let decl = self.arena.alloc(hir::FnDecl { - inputs: &[], - output: hir::FnRetTy::DefaultReturn(span), - c_variadic: false, - lifetime_elision_allowed: true, - implicit_self: hir::ImplicitSelfKind::None, - }); + let decl = self.arena.alloc(hir::FnDecl::dummy(span)); let header = self.generate_header_error(); let sig = hir::FnSig { decl, header, span }; diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index b6bc122051cbc..a042cde3e3690 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -762,9 +762,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { let fn_decl = self.arena.alloc(hir::FnDecl { inputs, output, - c_variadic: false, - implicit_self: hir::ImplicitSelfKind::None, - lifetime_elision_allowed: false, + fn_decl_kind: hir::FnDeclFlags::default(), }); let body = self.lower_body(move |this| { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6d9fe9870c42e..0aa20e7c61423 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1831,7 +1831,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // as they are not explicit in HIR/Ty function signatures. // (instead, the `c_variadic` flag is set to `true`) let mut inputs = &decl.inputs[..]; - if c_variadic { + if decl.c_variadic() { inputs = &inputs[..inputs.len() - 1]; } let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| { @@ -1894,12 +1894,8 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { }, }; - self.arena.alloc(hir::FnDecl { - inputs, - output, - c_variadic, - lifetime_elision_allowed: self.resolver.lifetime_elision_allowed(fn_node_id), - implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { + let fn_decl_kind = hir::FnDeclFlags::default() + .set_implicit_self(decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { let is_mutable_pat = matches!( arg.pat.kind, PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..) @@ -1921,8 +1917,11 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { } _ => hir::ImplicitSelfKind::None, } - }), - }) + })) + .set_lifetime_elision_allowed(self.resolver.lifetime_elision_allowed(fn_node_id)) + .set_c_variadic(c_variadic); + + self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind }) } // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }` diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index a0e53248c9047..954eb050a9d1e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -493,7 +493,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { for (_, node) in self.infcx.tcx.hir_parent_iter(upvar_hir_id) { if let Some(fn_decl) = node.fn_decl() { if !matches!( - fn_decl.implicit_self, + fn_decl.implicit_self(), hir::ImplicitSelfKind::RefImm | hir::ImplicitSelfKind::RefMut ) { err.span_suggestion_verbose( @@ -810,7 +810,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && let Some(ty) = sig.decl.inputs.get(local.index() - 1) && let hir::TyKind::Ref(_, mut_ty) = ty.kind && let hir::Mutability::Not = mut_ty.mutbl - && sig.decl.implicit_self.has_implicit_self() + && sig.decl.implicit_self().has_implicit_self() { Some(ty.span) } else { @@ -1147,7 +1147,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { arg_pos .and_then(|pos| { sig.decl.inputs.get( - pos + if sig.decl.implicit_self.has_implicit_self() { + pos + if sig.decl.implicit_self().has_implicit_self() { 1 } else { 0 diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index f6a20e41742bb..65ae1f86a00fe 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -15,7 +15,8 @@ use rustc_middle::bug; use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint}; use rustc_middle::ty::{ - self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, fold_regions, + self, FnSigKind, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, + fold_regions, }; use rustc_span::{Ident, Span, kw}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -1081,14 +1082,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } // Build a new closure where the return type is an owned value, instead of a ref. + let fn_sig_kind = + FnSigKind::default().set_safe(true).set_c_variadic(liberated_sig.c_variadic()); let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr( tcx, ty::Binder::dummy(tcx.mk_fn_sig( liberated_sig.inputs().iter().copied(), peeled_ty, - liberated_sig.c_variadic, - hir::Safety::Safe, - rustc_abi::ExternAbi::Rust, + fn_sig_kind, )), ); let closure_ty = Ty::new_closure( diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 39b3e525bc4c2..2e6a2962b8760 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -103,9 +103,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_provided_sig = self.tcx().mk_fn_sig( user_provided_sig.inputs().iter().copied(), output_ty, - user_provided_sig.c_variadic, - user_provided_sig.safety, - user_provided_sig.abi, + user_provided_sig.fn_sig_kind, ); } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0b7b4e01e7523..7cacbb1c06e66 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1015,7 +1015,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if let ty::FnDef(def_id, _) = *src_ty.kind() && let ty::FnPtr(_, target_hdr) = *ty.kind() && tcx.codegen_fn_attrs(def_id).safe_target_features - && target_hdr.safety.is_safe() + && target_hdr.safety().is_safe() && let Some(safe_sig) = tcx.adjust_target_feature_sig( def_id, src_sig, @@ -1971,7 +1971,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { term_location: Location, call_source: CallSource, ) { - if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) { + if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic()) + { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 9dc5012a602dc..67adbaf028eb9 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -870,20 +870,10 @@ pub(crate) fn assert_assignable<'tcx>( let from_sig = fx .tcx .normalize_erasing_late_bound_regions(fx.typing_env(), from_ty.fn_sig(fx.tcx)); - let FnSig { - inputs_and_output: types_from, - c_variadic: c_variadic_from, - safety: unsafety_from, - abi: abi_from, - } = from_sig; + let FnSig { inputs_and_output: types_from, fn_sig_kind: fn_sig_kind_from } = from_sig; let to_sig = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to_ty.fn_sig(fx.tcx)); - let FnSig { - inputs_and_output: types_to, - c_variadic: c_variadic_to, - safety: unsafety_to, - abi: abi_to, - } = to_sig; + let FnSig { inputs_and_output: types_to, fn_sig_kind: fn_sig_kind_to } = to_sig; let mut types_from = types_from.iter(); let mut types_to = types_to.iter(); loop { @@ -894,17 +884,7 @@ pub(crate) fn assert_assignable<'tcx>( } } assert_eq!( - c_variadic_from, c_variadic_to, - "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}", - from_sig, to_sig, fx, - ); - assert_eq!( - unsafety_from, unsafety_to, - "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}", - from_sig, to_sig, fx, - ); - assert_eq!( - abi_from, abi_to, + fn_sig_kind_from, fn_sig_kind_to, "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n\n{:#?}", from_sig, to_sig, fx, ); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 83ac627d27c54..2a7c88afe17dd 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -7,8 +7,6 @@ use std::iter; #[cfg(feature = "master")] use gccjit::Type; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; -#[cfg(feature = "master")] -use rustc_abi::ExternAbi; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; @@ -1483,32 +1481,26 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( // `unsafe fn(*mut i8) -> ()` let try_fn_ty = Ty::new_fn_ptr( tcx, - ty::Binder::dummy(tcx.mk_fn_sig( + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( iter::once(i8p), tcx.types.unit, - false, rustc_hir::Safety::Unsafe, - ExternAbi::Rust, )), ); // `unsafe fn(*mut i8, *mut i8) -> ()` let catch_fn_ty = Ty::new_fn_ptr( tcx, - ty::Binder::dummy(tcx.mk_fn_sig( + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( [i8p, i8p].iter().cloned(), tcx.types.unit, - false, rustc_hir::Safety::Unsafe, - ExternAbi::Rust, )), ); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` - let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig( + let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi( [try_fn_ty, i8p, catch_fn_ty], tcx.types.i32, - false, rustc_hir::Safety::Unsafe, - ExternAbi::Rust, )); let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen); cx.rust_try_fn.set(Some(rust_try)); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 0d3d682ece21f..2f9105bdde4b7 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -3,8 +3,7 @@ use std::ffi::c_uint; use std::{assert_matches, iter, ptr}; use rustc_abi::{ - Align, BackendRepr, ExternAbi, Float, HasDataLayout, NumScalableVectors, Primitive, Size, - WrappingRange, + Align, BackendRepr, Float, HasDataLayout, NumScalableVectors, Primitive, Size, WrappingRange, }; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; @@ -810,7 +809,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } _ => unreachable!(), }; - assert!(!fn_sig.c_variadic); + assert!(!fn_sig.c_variadic()); let ret_layout = self.layout_of(fn_sig.output()); let llreturn_ty = if ret_layout.is_zst() { @@ -1630,32 +1629,18 @@ fn get_rust_try_fn<'a, 'll, 'tcx>( // `unsafe fn(*mut i8) -> ()` let try_fn_ty = Ty::new_fn_ptr( tcx, - ty::Binder::dummy(tcx.mk_fn_sig( - [i8p], - tcx.types.unit, - false, - hir::Safety::Unsafe, - ExternAbi::Rust, - )), + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p], tcx.types.unit, hir::Safety::Unsafe)), ); // `unsafe fn(*mut i8, *mut i8) -> ()` let catch_fn_ty = Ty::new_fn_ptr( tcx, - ty::Binder::dummy(tcx.mk_fn_sig( - [i8p, i8p], - tcx.types.unit, - false, - hir::Safety::Unsafe, - ExternAbi::Rust, - )), + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi([i8p, i8p], tcx.types.unit, hir::Safety::Unsafe)), ); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` - let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig( + let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig_rust_abi( [try_fn_ty, i8p, catch_fn_ty], tcx.types.i32, - false, hir::Safety::Unsafe, - ExternAbi::Rust, )); let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen); cx.rust_try_fn.set(Some(rust_try)); diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index d207cdca4d4bb..17948e0a69e42 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -364,10 +364,10 @@ fn push_debuginfo_type_name<'tcx>( } output.push_str(" (*)("); } else { - output.push_str(sig.safety.prefix_str()); + output.push_str(sig.safety().prefix_str()); - if sig.abi != rustc_abi::ExternAbi::Rust { - let _ = write!(output, "extern {} ", sig.abi); + if sig.abi() != rustc_abi::ExternAbi::Rust { + let _ = write!(output, "extern {} ", sig.abi()); } output.push_str("fn("); @@ -381,7 +381,7 @@ fn push_debuginfo_type_name<'tcx>( pop_arg_separator(output); } - if sig.c_variadic { + if sig.c_variadic() { if !sig.inputs().is_empty() { output.push_str(", ..."); } else { diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index dffc66f731af0..7b63ab5bb02e8 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -419,7 +419,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { sig: &FnSigTys>, fn_header: &FnHeader>, ) -> InterpResult<'tcx> { - let FnHeader { safety, c_variadic, abi } = fn_header; + let FnHeader { fn_sig_kind } = fn_header; for (field_idx, field) in place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() @@ -428,9 +428,9 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { match field.name { sym::unsafety => { - self.write_scalar(Scalar::from_bool(safety.is_unsafe()), &field_place)?; + self.write_scalar(Scalar::from_bool(!fn_sig_kind.is_safe()), &field_place)?; } - sym::abi => match abi { + sym::abi => match fn_sig_kind.abi() { ExternAbi::C { .. } => { let (rust_variant, _rust_place) = self.downcast(&field_place, sym::ExternC)?; @@ -463,7 +463,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { self.write_type_id(output, &field_place)?; } sym::variadic => { - self.write_scalar(Scalar::from_bool(*c_variadic), &field_place)?; + self.write_scalar(Scalar::from_bool(fn_sig_kind.c_variadic()), &field_place)?; } other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 2dee1157e2a12..f9ab86e9888d7 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -542,7 +542,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let destination = self.eval_place(destination)?; self.init_fn_call( callee, - (fn_sig.abi, fn_abi), + (fn_sig.abi(), fn_abi), &args, with_caller_location, &destination, @@ -565,7 +565,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let EvaluatedCalleeAndArgs { callee, args, fn_sig, fn_abi, with_caller_location } = self.eval_callee_and_args(terminator, func, args, &mir::Place::return_place())?; - self.init_fn_tail_call(callee, (fn_sig.abi, fn_abi), &args, with_caller_location)?; + self.init_fn_tail_call( + callee, + (fn_sig.abi(), fn_abi), + &args, + with_caller_location, + )?; if self.frame_idx() != old_frame_idx { span_bug!( diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e4e6642981d1a..863cfe4ef1453 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3917,6 +3917,117 @@ pub struct Param<'hir> { pub span: Span, } +/// Contains the packed non-type fields of a function declaration. +// FIXME(splat): add the splatted argument index as a u16 +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Encodable, Decodable, HashStable_Generic)] +pub struct FnDeclFlags { + /// Holds the c_variadic and lifetime_elision_allowed bitflags, and 3 bits for the `ImplicitSelfKind`. + flags: u8, +} + +impl fmt::Debug for FnDeclFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut f = f.debug_tuple("FnDeclFlags"); + f.field(&format!("ImplicitSelfKind({:?})", self.implicit_self())); + + if self.lifetime_elision_allowed() { + f.field(&"LifetimeElisionAllowed"); + } else { + f.field(&"NoLifetimeElision"); + }; + + if self.c_variadic() { + f.field(&"CVariadic"); + }; + + f.finish() + } +} + +impl FnDeclFlags { + /// Mask for the implicit self kind. + const IMPLICIT_SELF_MASK: u8 = 0b111; + + /// Bitflag for a trailing C-style variadic argument. + const C_VARIADIC_FLAG: u8 = 1 << 3; + + /// Bitflag for lifetime elision. + const LIFETIME_ELISION_ALLOWED_FLAG: u8 = 1 << 4; + + /// Create a new FnDeclKind with no implicit self, no lifetime elision, and no C-style variadic argument. + /// To modify these flags, use the `set_*` methods, for readability. + // FIXME: use Default instead when that trait is const stable. + pub const fn default() -> Self { + Self { flags: 0 } + .set_implicit_self(ImplicitSelfKind::None) + .set_lifetime_elision_allowed(false) + .set_c_variadic(false) + } + + /// Set the implicit self kind. + #[must_use = "this method does not modify the receiver"] + pub const fn set_implicit_self(mut self, implicit_self: ImplicitSelfKind) -> Self { + self.flags &= !Self::IMPLICIT_SELF_MASK; + + match implicit_self { + ImplicitSelfKind::None => self.flags |= 0, + ImplicitSelfKind::Imm => self.flags |= 1, + ImplicitSelfKind::Mut => self.flags |= 2, + ImplicitSelfKind::RefImm => self.flags |= 3, + ImplicitSelfKind::RefMut => self.flags |= 4, + } + + self + } + + /// Set the C-style variadic argument flag. + #[must_use = "this method does not modify the receiver"] + pub const fn set_c_variadic(mut self, c_variadic: bool) -> Self { + if c_variadic { + self.flags |= Self::C_VARIADIC_FLAG; + } else { + self.flags &= !Self::C_VARIADIC_FLAG; + } + + self + } + + /// Set the lifetime elision allowed flag. + #[must_use = "this method does not modify the receiver"] + pub const fn set_lifetime_elision_allowed(mut self, allowed: bool) -> Self { + if allowed { + self.flags |= Self::LIFETIME_ELISION_ALLOWED_FLAG; + } else { + self.flags &= !Self::LIFETIME_ELISION_ALLOWED_FLAG; + } + + self + } + + /// Get the implicit self kind. + pub const fn implicit_self(self) -> ImplicitSelfKind { + match self.flags & Self::IMPLICIT_SELF_MASK { + 0 => ImplicitSelfKind::None, + 1 => ImplicitSelfKind::Imm, + 2 => ImplicitSelfKind::Mut, + 3 => ImplicitSelfKind::RefImm, + 4 => ImplicitSelfKind::RefMut, + _ => unreachable!(), + } + } + + /// Do the function arguments end with a C-style variadic argument? + pub const fn c_variadic(self) -> bool { + self.flags & Self::C_VARIADIC_FLAG != 0 + } + + /// Is lifetime elision allowed? + pub const fn lifetime_elision_allowed(self) -> bool { + self.flags & Self::LIFETIME_ELISION_ALLOWED_FLAG != 0 + } +} + /// Represents the header (not the body) of a function declaration. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnDecl<'hir> { @@ -3925,11 +4036,8 @@ pub struct FnDecl<'hir> { /// Additional argument data is stored in the function's [body](Body::params). pub inputs: &'hir [Ty<'hir>], pub output: FnRetTy<'hir>, - pub c_variadic: bool, - /// Does the function have an implicit self? - pub implicit_self: ImplicitSelfKind, - /// Is lifetime elision allowed. - pub lifetime_elision_allowed: bool, + /// The packed function declaration attributes. + pub fn_decl_kind: FnDeclFlags, } impl<'hir> FnDecl<'hir> { @@ -3952,6 +4060,26 @@ impl<'hir> FnDecl<'hir> { None } + + pub fn implicit_self(&self) -> ImplicitSelfKind { + self.fn_decl_kind.implicit_self() + } + + pub fn c_variadic(&self) -> bool { + self.fn_decl_kind.c_variadic() + } + + pub fn lifetime_elision_allowed(&self) -> bool { + self.fn_decl_kind.lifetime_elision_allowed() + } + + pub fn dummy(span: Span) -> Self { + Self { + inputs: &[], + output: FnRetTy::DefaultReturn(span), + fn_decl_kind: FnDeclFlags::default().set_lifetime_elision_allowed(true), + } + } } /// Represents what type of implicit self a function has, if any. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 99511189e9283..9f7c9af79b753 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1216,8 +1216,7 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>( visitor: &mut V, function_declaration: &'v FnDecl<'v>, ) -> V::Result { - let FnDecl { inputs, output, c_variadic: _, implicit_self: _, lifetime_elision_allowed: _ } = - function_declaration; + let FnDecl { inputs, output, fn_decl_kind: _ } = function_declaration; walk_list!(visitor, visit_ty_unambig, *inputs); visitor.visit_fn_ret_ty(output) } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 2dcd4ed24df4b..d825d1ab51686 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -91,7 +91,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi } pub fn check_custom_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, fn_sig: FnSig<'_>, fn_sig_span: Span) { - if fn_sig.abi == ExternAbi::Custom { + if fn_sig.abi() == ExternAbi::Custom { // Function definitions that use `extern "custom"` must be naked functions. if !find_attr!(tcx, def_id, Naked(_)) { tcx.dcx().emit_err(crate::errors::AbiCustomClothedFunction { diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 4c72f5a654e1d..16e95c96ab913 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -1,6 +1,5 @@ use std::ops::Not; -use rustc_abi::ExternAbi; use rustc_hir as hir; use rustc_hir::{Node, find_attr}; use rustc_infer::infer::TyCtxtInferExt; @@ -152,13 +151,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) -> Result<(), ErrorGuar expected_return_type = tcx.types.unit; } - let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig( - [], - expected_return_type, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )); + let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([], expected_return_type)); check_function_signature( tcx, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 58454cfc489c6..d952faa5edb74 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -1,6 +1,5 @@ //! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes. -use rustc_abi::ExternAbi; use rustc_errors::DiagMessage; use rustc_hir::{self as hir, LangItem}; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; @@ -636,20 +635,10 @@ pub(crate) fn check_intrinsic_type( sym::catch_unwind => { let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8); - let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( - [mut_u8], - tcx.types.unit, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )); - let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( - [mut_u8, mut_u8], - tcx.types.unit, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )); + let try_fn_ty = + ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([mut_u8], tcx.types.unit)); + let catch_fn_ty = + ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([mut_u8, mut_u8], tcx.types.unit)); ( 0, 0, @@ -817,7 +806,7 @@ pub(crate) fn check_intrinsic_type( return; } }; - let sig = tcx.mk_fn_sig(inputs, output, false, safety, ExternAbi::Rust); + let sig = tcx.mk_fn_sig_rust_abi(inputs, output, safety); let sig = ty::Binder::bind_with_vars(sig, bound_vars); equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, n_lts, n_cts, sig) } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 950696db44efb..cf182fb116cb1 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -478,7 +478,7 @@ fn fn_sig_suggestion<'tcx>( } }) }) - .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None })) + .chain(std::iter::once(if sig.c_variadic() { Some("...".to_string()) } else { None })) .flatten() .collect::>() .join(", "); @@ -506,7 +506,7 @@ fn fn_sig_suggestion<'tcx>( let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() }; - let safety = sig.safety.prefix_str(); + let safety = sig.safety().prefix_str(); let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates, assoc); // FIXME: this is not entirely correct, as the lifetimes from borrowed params will diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 460a9d776530e..4ab69f7a7b098 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1701,9 +1701,9 @@ fn check_fn_or_method<'tcx>( check_where_clauses(wfcx, def_id); - if sig.abi == ExternAbi::RustCall { + if sig.abi() == ExternAbi::RustCall { let span = tcx.def_span(def_id); - let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None; + let has_implicit_self = hir_decl.implicit_self() != hir::ImplicitSelfKind::None; let mut inputs = sig.inputs().iter().skip(if has_implicit_self { 1 } else { 0 }); // Check that the argument is a tuple and is sized if let Some(ty) = inputs.next() { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 91f6c1a08f152..00f26a5f06679 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1040,7 +1040,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn (Bound::Unbounded, Bound::Unbounded) => hir::Safety::Safe, _ => hir::Safety::Unsafe, }; - ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, safety, ExternAbi::Rust)) + ty::Binder::dummy(tcx.mk_fn_sig_rust_abi(inputs, ty, safety)) } Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { @@ -1233,9 +1233,7 @@ fn recover_infer_ret_ty<'tcx>( let fn_sig = tcx.mk_fn_sig( fn_sig.inputs().iter().copied(), recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)), - fn_sig.c_variadic, - fn_sig.safety, - fn_sig.abi, + fn_sig.fn_sig_kind, ); late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig) diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index e97830ccd23fa..3eb6767dd77df 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -530,7 +530,7 @@ fn check_constraints<'tcx>( })); }; - if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic { + if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic() { // See issue #127443 for explanation. emit("delegation to C-variadic functions is not allowed"); } diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 615c0a766a63f..5cd4ea2f9edd5 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -360,7 +360,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let in_ret = matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id); - if in_arg || (in_ret && fn_decl.lifetime_elision_allowed) { + if in_arg || (in_ret && fn_decl.lifetime_elision_allowed()) { return std::iter::repeat_n("'_".to_owned(), num_params_to_take) .collect::>() .join(", "); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index a1b169c6a1661..f4dca6371696e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -48,7 +48,7 @@ pub(crate) fn validate_cmse_abi<'tcx>( // An `extern "cmse-nonsecure-entry"` function cannot be c-variadic. We run // into https://github.com/rust-lang/rust/issues/132142 if we don't explicitly bail. - if decl.c_variadic { + if decl.c_variadic() { return; } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 706b56114d05e..bf3dc3b94275b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -38,8 +38,9 @@ use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ - self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput, Ty, TyCtxt, - TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, const_lit_matches_ty, fold_regions, + self, Const, FnSigKind, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput, + Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, const_lit_matches_ty, + fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; @@ -3578,7 +3579,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?output_ty); - let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi); + let fn_sig_kind = FnSigKind::default() + .set_abi(abi) + .set_safe(safety.is_safe()) + .set_c_variadic(decl.fn_decl_kind.c_variadic()); + let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, fn_sig_kind); let fn_ptr_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), span, .. }) = diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 937bcee01161e..0721bfcab519a 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -97,7 +97,7 @@ pub use crate::collect::suggest_impl_trait; use crate::hir_ty_lowering::HirTyLowerer; fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) { - if !decl.c_variadic { + if !decl.c_variadic() { // Not even a variadic function. return; } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 6f64d07b01d66..46aed3c5cd084 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2264,8 +2264,8 @@ impl<'a> State<'a> { assert!(arg_idents.is_empty() || body_id.is_none()); let mut i = 0; let mut print_arg = |s: &mut Self, ty: Option<&hir::Ty<'_>>| { - if i == 0 && decl.implicit_self.has_implicit_self() { - s.print_implicit_self(&decl.implicit_self); + if i == 0 && decl.implicit_self().has_implicit_self() { + s.print_implicit_self(&decl.implicit_self()); } else { if let Some(arg_ident) = arg_idents.get(i) { if let Some(arg_ident) = arg_ident { @@ -2289,7 +2289,7 @@ impl<'a> State<'a> { print_arg(s, Some(ty)); s.end(ib); }); - if decl.c_variadic { + if decl.c_variadic() { if !decl.inputs.is_empty() { self.word(", "); } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 3952d3889bb8f..848fb7118bbfe 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -89,11 +89,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *autoderef.final_ty().kind() { ty::FnDef(def_id, _) => { - let abi = self.tcx.fn_sig(def_id).skip_binder().skip_binder().abi; + let abi = self.tcx.fn_sig(def_id).skip_binder().skip_binder().abi(); self.check_call_abi(abi, call_expr.span); } ty::FnPtr(_, header) => { - self.check_call_abi(header.abi, call_expr.span); + self.check_call_abi(header.abi(), call_expr.span); } _ => { /* cannot have a non-rust abi */ } } @@ -275,9 +275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.coroutine_for_closure(def_id), tupled_upvars_ty, ), - coroutine_closure_sig.c_variadic, - coroutine_closure_sig.safety, - coroutine_closure_sig.abi, + coroutine_closure_sig.fn_sig_kind, ); let adjustments = self.adjust_steps(autoderef); self.record_deferred_call_resolution( @@ -595,12 +593,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output(), expected, arg_exprs, - fn_sig.c_variadic, + fn_sig.c_variadic(), TupleArgumentsFlag::DontTupleArguments, def_id, ); - if fn_sig.abi == rustc_abi::ExternAbi::RustCall { + if fn_sig.abi() == rustc_abi::ExternAbi::RustCall { let sp = arg_exprs.last().map_or(call_expr.span, |expr| expr.span); if let Some(ty) = fn_sig.inputs().last().copied() { self.register_bound( @@ -905,7 +903,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output(), expected, arg_exprs, - fn_sig.c_variadic, + fn_sig.c_variadic(), TupleArgumentsFlag::TupleArguments, Some(closure_def_id.to_def_id()), ); @@ -984,7 +982,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method.sig.output(), expected, arg_exprs, - method.sig.c_variadic, + method.sig.c_variadic(), TupleArgumentsFlag::TupleArguments, Some(method.def_id), ); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 612396858841f..25bba0def5c6e 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; -use rustc_abi::ExternAbi; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; @@ -55,7 +54,7 @@ pub(super) fn check_fn<'a, 'tcx>( // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). - let maybe_va_list = fn_sig.c_variadic.then(|| { + let maybe_va_list = fn_sig.c_variadic().then(|| { let span = body.params.last().unwrap().span; let va_list_did = tcx.require_lang_item(LangItem::VaList, span); let region = fcx.next_region_var(RegionVariableOrigin::Misc(span)); @@ -204,7 +203,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_> ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon), ]); let expected_sig = ty::Binder::bind_with_vars( - tcx.mk_fn_sig([panic_info_ref_ty], tcx.types.never, false, fn_sig.safety, ExternAbi::Rust), + tcx.mk_fn_sig_rust_abi([panic_info_ref_ty], tcx.types.never, fn_sig.safety()), bounds, ); @@ -225,12 +224,10 @@ fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id: let generics = tcx.generics_of(def_id); let fn_generic = generics.param_at(0, tcx); let generic_ty = Ty::new_param(tcx, fn_generic.index, fn_generic.name); - let main_fn_ty = Ty::new_fn_ptr( - tcx, - Binder::dummy(tcx.mk_fn_sig([], generic_ty, false, hir::Safety::Safe, ExternAbi::Rust)), - ); + let main_fn_ty = + Ty::new_fn_ptr(tcx, Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([], generic_ty))); - let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig( + let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig_rust_abi( [ main_fn_ty, tcx.types.isize, @@ -238,9 +235,7 @@ fn check_lang_start_fn<'tcx>(tcx: TyCtxt<'tcx>, fn_sig: ty::FnSig<'tcx>, def_id: tcx.types.u8, ], tcx.types.isize, - false, - fn_sig.safety, - ExternAbi::Rust, + fn_sig.safety(), )); let _ = check_function_signature( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 28bb9c5cd75b2..0597a60f9f8c5 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -13,7 +13,7 @@ use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::span_bug; use rustc_middle::ty::{ - self, ClosureKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + self, ClosureKind, FnSigKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_span::def_id::LocalDefId; @@ -85,13 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Tuple up the arguments and insert the resulting function type into // the `closures` table. let sig = bound_sig.map_bound(|sig| { - tcx.mk_fn_sig( - [Ty::new_tup(tcx, sig.inputs())], - sig.output(), - sig.c_variadic, - sig.safety, - sig.abi, - ) + tcx.mk_fn_sig([Ty::new_tup(tcx, sig.inputs())], sig.output(), sig.fn_sig_kind) }); debug!(?sig, ?expected_kind); @@ -231,9 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_tup_from_iter(tcx, sig.inputs().iter().copied()), ], Ty::new_tup(tcx, &[bound_yield_ty, bound_return_ty]), - sig.c_variadic, - sig.safety, - sig.abi, + sig.fn_sig_kind, ) }), ), @@ -273,9 +265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { liberated_sig = tcx.mk_fn_sig( liberated_sig.inputs().iter().copied(), coroutine_output_ty, - liberated_sig.c_variadic, - liberated_sig.safety, - liberated_sig.abi, + liberated_sig.fn_sig_kind, ); (Ty::new_coroutine_closure(tcx, expr_def_id.to_def_id(), closure_args.args), None) @@ -544,13 +534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ret_param_ty = projection.skip_binder().term.expect_type(); debug!(?ret_param_ty); - let sig = projection.rebind(self.tcx.mk_fn_sig( - input_tys, - ret_param_ty, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )); + let sig = projection.rebind(self.tcx.mk_fn_sig_safe_rust_abi(input_tys, ret_param_ty)); Some(ExpectedSig { cause_span, sig }) } @@ -630,13 +614,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let return_ty = return_ty.unwrap_or_else(|| self.next_ty_var(cause_span.unwrap_or(DUMMY_SP))); - let sig = projection.rebind(self.tcx.mk_fn_sig( - input_tys, - return_ty, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )); + let sig = projection.rebind(self.tcx.mk_fn_sig_safe_rust_abi(input_tys, return_ty)); Some(ExpectedSig { cause_span, sig }) } @@ -727,7 +705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Watch out for some surprises and just ignore the // expectation if things don't see to match up with what we // expect. - if expected_sig.sig.c_variadic() != decl.c_variadic { + if expected_sig.sig.c_variadic() != decl.c_variadic() { return self.sig_of_closure_no_expectation(expr_def_id, decl, closure_kind); } else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 { return self.sig_of_closure_with_mismatched_number_of_arguments( @@ -742,13 +720,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // in this binder we are creating. assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST)); let bound_sig = expected_sig.sig.map_bound(|sig| { - self.tcx.mk_fn_sig( - sig.inputs().iter().cloned(), - sig.output(), - sig.c_variadic, - hir::Safety::Safe, - ExternAbi::RustCall, - ) + let fn_sig_kind = FnSigKind::default() + .set_abi(ExternAbi::RustCall) + .set_safe(true) + .set_c_variadic(sig.c_variadic()); + self.tcx.mk_fn_sig(sig.inputs().iter().cloned(), sig.output(), fn_sig_kind) }); // `deduce_expectations_from_expected_type` introduces @@ -881,13 +857,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let inputs = supplied_sig.inputs().into_iter().map(|&ty| self.resolve_vars_if_possible(ty)); - expected_sigs.liberated_sig = self.tcx.mk_fn_sig( - inputs, - supplied_output_ty, - expected_sigs.liberated_sig.c_variadic, - hir::Safety::Safe, - ExternAbi::RustCall, - ); + let fn_sig_kind = FnSigKind::default() + .set_abi(ExternAbi::RustCall) + .set_safe(true) + .set_c_variadic(expected_sigs.liberated_sig.c_variadic()); + expected_sigs.liberated_sig = + self.tcx.mk_fn_sig(inputs, supplied_output_ty, fn_sig_kind); Ok(InferOk { value: expected_sigs, obligations: all_obligations }) }) @@ -957,14 +932,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, }; + let fn_sig_kind = FnSigKind::default() + .set_abi(ExternAbi::RustCall) + .set_safe(true) + .set_c_variadic(decl.c_variadic()); let result = ty::Binder::bind_with_vars( - self.tcx.mk_fn_sig( - supplied_arguments, - supplied_return, - decl.c_variadic, - hir::Safety::Safe, - ExternAbi::RustCall, - ), + self.tcx.mk_fn_sig(supplied_arguments, supplied_return, fn_sig_kind), bound_vars, ); @@ -1121,13 +1094,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lowerer.lower_ty(output); } - let result = ty::Binder::dummy(self.tcx.mk_fn_sig( - supplied_arguments, - err_ty, - decl.c_variadic, - hir::Safety::Safe, - ExternAbi::RustCall, - )); + let fn_sig_kind = FnSigKind::default() + .set_abi(ExternAbi::RustCall) + .set_safe(true) + .set_c_variadic(decl.c_variadic()); + let result = ty::Binder::dummy(self.tcx.mk_fn_sig(supplied_arguments, err_ty, fn_sig_kind)); debug!("supplied_sig_of_closure: result={:?}", result); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bfc677046e0f4..444e6f2e3c77d 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -944,7 +944,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { debug_assert!(self.shallow_resolve(b) == b); match b.kind() { - ty::FnPtr(_, b_hdr) if a_sig.safety().is_safe() && b_hdr.safety.is_unsafe() => { + ty::FnPtr(_, b_hdr) if a_sig.safety().is_safe() && b_hdr.safety().is_unsafe() => { let a = self.tcx.safe_to_unsafe_fn_ty(a_sig); let adjust = Adjust::Pointer(PointerCoercion::UnsafeFnPointer); self.unify_and(a, b, [], adjust, ForceLeakCheck::Yes) @@ -960,13 +960,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match b.kind() { ty::FnPtr(_, b_hdr) => { - let a_sig = self.sig_for_fn_def_coercion(a, Some(b_hdr.safety))?; + let a_sig = self.sig_for_fn_def_coercion(a, Some(b_hdr.safety()))?; let InferOk { value: a_sig, mut obligations } = self.at(&self.cause, self.param_env).normalize(a_sig); let a = Ty::new_fn_ptr(self.tcx, a_sig); - let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety)); + let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety())); let InferOk { value, obligations: o2 } = self.unify_and(a, b, [], adjust, ForceLeakCheck::Yes)?; @@ -985,9 +985,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match b.kind() { ty::FnPtr(_, hdr) => { - let safety = hdr.safety; + let safety = hdr.safety(); let terr = TypeError::Sorts(ty::error::ExpectedFound::new(a, b)); - let closure_sig = self.sig_for_closure_coercion(a, Some(hdr.safety), terr)?; + let closure_sig = self.sig_for_closure_coercion(a, Some(hdr.safety()), terr)?; let pointer_ty = Ty::new_fn_ptr(self.tcx, closure_sig); debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e21cadcf3ffe6..d558c982f380d 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1489,12 +1489,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method.sig.output(), expected, args, - method.sig.c_variadic, + method.sig.c_variadic(), TupleArgumentsFlag::DontTupleArguments, Some(method.def_id), ); - self.check_call_abi(method.sig.abi, expr.span); + self.check_call_abi(method.sig.abi(), expr.span); method.sig.output() } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bb31bcbf70f1b..ba619449defc9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -183,6 +183,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The expressions for each provided argument provided_args: &'tcx [hir::Expr<'tcx>], // Whether the function is variadic, for example when imported from C + // FIXME(splat): maybe change this to FnSigKind? c_variadic: bool, // Whether the arguments have been bundled in a tuple (ex: closures) tuple_arguments: TupleArgumentsFlag, @@ -1793,14 +1794,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (Some(_), Some(_)) | (None, None) => unreachable!(), (Some(body), None) => { let params = self.tcx.hir_body(body).params; - let params = - params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?; + let params = params + .get(is_method as usize..params.len() - sig.decl.c_variadic() as usize)?; debug_assert_eq!(params.len(), fn_inputs.len()); Some((fn_inputs.zip(params.iter().map(FnParam::Param)).collect(), generics)) } (None, Some(params)) => { - let params = - params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?; + let params = params + .get(is_method as usize..params.len() - sig.decl.c_variadic() as usize)?; debug_assert_eq!(params.len(), fn_inputs.len()); Some(( fn_inputs.zip(params.iter().map(|&ident| FnParam::Ident(ident))).collect(), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3fcc3f03f7aa5..c9329fef4ed80 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -4366,7 +4366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => false, }; - if !fn_sig.decl.implicit_self.has_implicit_self() + if !fn_sig.decl.implicit_self().has_implicit_self() && self_first_arg { if let Some(ty) = fn_sig.decl.inputs.get(0) { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index df02974d2fb2d..c35492a8042ff 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -438,13 +438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let coroutine_captures_by_ref_ty = Ty::new_fn_ptr( self.tcx, ty::Binder::bind_with_vars( - self.tcx.mk_fn_sig( - [], - tupled_upvars_ty_for_borrow, - false, - hir::Safety::Safe, - rustc_abi::ExternAbi::Rust, - ), + self.tcx.mk_fn_sig_safe_rust_abi([], tupled_upvars_ty_for_borrow), self.tcx.mk_bound_variable_kinds(&[ty::BoundVariableKind::Region( ty::BoundRegionKind::ClosureEnv, )]), diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 9bc04db5e790b..8d48b72a12213 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -329,8 +329,8 @@ fn structurally_same_type_impl<'tcx>( let a_sig = tcx.instantiate_bound_regions_with_erased(a_poly_sig); let b_sig = tcx.instantiate_bound_regions_with_erased(b_poly_sig); - (a_sig.abi, a_sig.safety, a_sig.c_variadic) - == (b_sig.abi, b_sig.safety, b_sig.c_variadic) + (a_sig.abi(), a_sig.safety(), a_sig.c_variadic()) + == (b_sig.abi(), b_sig.safety(), b_sig.c_variadic()) && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| { structurally_same_type_impl(seen_types, tcx, typing_env, *a, *b) }) diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 38f2fbb07ed3e..c0f341f25b380 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -816,7 +816,7 @@ impl<'tcx> ImproperCTypesLint { fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if let ty::FnPtr(_, hdr) = ty.kind() - && !hdr.abi.is_rustic_abi() + && !hdr.abi().is_rustic_abi() { self.tys.push(ty); } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 20aa0a809006f..68357212bebe8 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -707,7 +707,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::ImplItem(ii) => { let kind = match ii.kind { ImplItemKind::Const(..) => "associated constant", - ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self() { ImplicitSelfKind::None => "associated function", _ => "method", }, @@ -718,7 +718,7 @@ impl<'tcx> TyCtxt<'tcx> { Node::TraitItem(ti) => { let kind = match ti.kind { TraitItemKind::Const(..) => "associated constant", - TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self() { ImplicitSelfKind::None => "associated function", _ => "trait method", }, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b908a6c6e8439..e3f6a67531470 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -47,7 +47,9 @@ use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_type_ir::TyKind::*; pub use rustc_type_ir::lift::Lift; -use rustc_type_ir::{CollectAndApply, TypeFlags, WithCachedTypeInfo, elaborate, search_graph}; +use rustc_type_ir::{ + CollectAndApply, FnSigKind, TypeFlags, WithCachedTypeInfo, elaborate, search_graph, +}; use tracing::{debug, instrument}; use crate::arena::Arena; @@ -84,7 +86,33 @@ impl<'tcx> rustc_type_ir::inherent::DefId> for DefId { } } +impl<'tcx> rustc_type_ir::inherent::FSigKind> for FnSigKind { + fn fn_sig_kind(self) -> Self { + self + } + + fn new(abi: ExternAbi, safety: hir::Safety, c_variadic: bool) -> Self { + FnSigKind::default().set_abi(abi).set_safe(safety.is_safe()).set_c_variadic(c_variadic) + } + + fn abi(self) -> ExternAbi { + self.abi() + } + + fn safety(self) -> hir::Safety { + if self.is_safe() { hir::Safety::Safe } else { hir::Safety::Unsafe } + } + + fn c_variadic(self) -> bool { + self.c_variadic() + } +} + impl<'tcx> rustc_type_ir::inherent::Abi> for ExternAbi { + fn abi(self) -> Self { + self + } + fn rust() -> Self { ExternAbi::Rust } @@ -92,6 +120,14 @@ impl<'tcx> rustc_type_ir::inherent::Abi> for ExternAbi { fn is_rust(self) -> bool { matches!(self, ExternAbi::Rust) } + + fn pack_abi(self) -> u8 { + self.as_packed() + } + + fn unpack_abi(abi_index: u8) -> Self { + Self::from_packed(abi_index) + } } impl<'tcx> rustc_type_ir::inherent::Safety> for hir::Safety { @@ -99,6 +135,10 @@ impl<'tcx> rustc_type_ir::inherent::Safety> for hir::Safety { hir::Safety::Safe } + fn unsafe_mode() -> Self { + hir::Safety::Unsafe + } + fn is_safe(self) -> bool { self.is_safe() } @@ -1332,7 +1372,10 @@ impl<'tcx> TyCtxt<'tcx> { let fun_features = &self.codegen_fn_attrs(fun_def).target_features; let caller_features = &self.body_codegen_attrs(caller).target_features; if self.is_target_feature_call_safe(&fun_features, &caller_features) { - return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig })); + return Some(fun_sig.map_bound(|sig| ty::FnSig { + fn_sig_kind: fun_sig.fn_sig_kind().set_safe(true), + ..sig + })); } None } @@ -2096,7 +2139,10 @@ impl<'tcx> TyCtxt<'tcx> { /// unsafe. pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> { assert!(sig.safety().is_safe()); - Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig })) + Ty::new_fn_ptr( + self, + sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig }), + ) } /// Given a `fn` sig, returns an equivalent `unsafe fn` sig; @@ -2104,7 +2150,7 @@ impl<'tcx> TyCtxt<'tcx> { /// unsafe. pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> { assert!(sig.safety().is_safe()); - sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }) + sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig }) } /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name` @@ -2146,7 +2192,11 @@ impl<'tcx> TyCtxt<'tcx> { ty::Tuple(params) => *params, _ => bug!(), }; - self.mk_fn_sig(params, s.output(), s.c_variadic, safety, ExternAbi::Rust) + self.mk_fn_sig( + params, + s.output(), + s.fn_sig_kind.set_safe(safety.is_safe()).set_abi(ExternAbi::Rust), + ) }) } @@ -2419,24 +2469,38 @@ impl<'tcx> TyCtxt<'tcx> { // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice // variant, because of the need to combine `inputs` and `output`. This // explains the lack of `_from_iter` suffix. - pub fn mk_fn_sig( + pub fn mk_fn_sig(self, inputs: I, output: I::Item, fn_sig_kind: FnSigKind) -> T::Output + where + I: IntoIterator, + T: CollectAndApply, ty::FnSig<'tcx>>, + { + T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { + inputs_and_output: self.mk_type_list(xs), + fn_sig_kind, + }) + } + + /// `mk_fn_sig`, but with a Rust ABI, and no C-variadic argument. + pub fn mk_fn_sig_rust_abi( self, inputs: I, output: I::Item, - c_variadic: bool, safety: hir::Safety, - abi: ExternAbi, ) -> T::Output where I: IntoIterator, T: CollectAndApply, ty::FnSig<'tcx>>, { - T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { - inputs_and_output: self.mk_type_list(xs), - c_variadic, - safety, - abi, - }) + self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(safety.is_safe())) + } + + /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument. + pub fn mk_fn_sig_safe_rust_abi(self, inputs: I, output: I::Item) -> T::Output + where + I: IntoIterator, + T: CollectAndApply, ty::FnSig<'tcx>>, + { + self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(true)) } pub fn mk_poly_existential_predicates_from_iter(self, iter: I) -> T::Output diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 9913261b14d95..61e9b6106a1ac 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -10,7 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; -use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, search_graph}; +use rustc_type_ir::{CollectAndApply, FnSigKind, Interner, TypeFoldable, search_graph}; use crate::dep_graph::{DepKind, DepNodeIndex}; use crate::infer::canonical::CanonicalVarKinds; @@ -90,6 +90,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type AllocId = crate::mir::interpret::AllocId; type Pat = Pattern<'tcx>; type PatList = &'tcx List>; + type FSigKind = FnSigKind; type Safety = hir::Safety; type Abi = ExternAbi; type Const = ty::Const<'tcx>; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0915cc48015c3..0aa683e1ce148 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -104,7 +104,7 @@ pub use self::region::{ pub use self::sty::{ AliasTy, AliasTyKind, Article, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder, FnSig, - InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PlaceholderConst, + FnSigKind, InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PlaceholderConst, PlaceholderRegion, PlaceholderType, PolyFnSig, TyKind, TypeAndMut, TypingMode, TypingModeEqWrapper, UpvarArgs, }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1262974325a1f..535547153a143 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -750,7 +750,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { if self.tcx().codegen_fn_attrs(def_id).safe_target_features { write!(self, "#[target_features] ")?; sig = sig.map_bound(|mut sig| { - sig.safety = hir::Safety::Safe; + sig.fn_sig_kind = sig.fn_sig_kind.set_safe(true); sig }); } @@ -3131,14 +3131,14 @@ define_print! { (self, p): ty::FnSig<'tcx> { - write!(p, "{}", self.safety.prefix_str())?; + write!(p, "{}", self.safety().prefix_str())?; - if self.abi != ExternAbi::Rust { - write!(p, "extern {} ", self.abi)?; + if self.abi() != ExternAbi::Rust { + write!(p, "extern {} ", self.abi())?; } write!(p, "fn")?; - p.pretty_print_fn_sig(self.inputs(), self.c_variadic, self.output())?; + p.pretty_print_fn_sig(self.inputs(), self.c_variadic(), self.output())?; } ty::TraitRef<'tcx> { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 29b784e837954..f6d5d226683b3 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -198,6 +198,7 @@ TrivialLiftImpls! { rustc_hir::Safety, rustc_middle::mir::ConstValue, rustc_type_ir::BoundConstness, + rustc_type_ir::FnSigKind, rustc_type_ir::PredicatePolarity, // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 9164f7b57e648..151c8ffd7991b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -37,6 +37,7 @@ pub type TypeAndMut<'tcx> = ir::TypeAndMut>; pub type AliasTy<'tcx> = ir::AliasTy>; pub type AliasTyKind<'tcx> = ir::AliasTyKind>; pub type FnSig<'tcx> = ir::FnSig>; +pub type FnSigKind = ir::FnSigKind; pub type Binder<'tcx, T> = ir::Binder, T>; pub type EarlyBinder<'tcx, T> = ir::EarlyBinder, T>; pub type TypingMode<'tcx> = ir::TypingMode>; diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 01c1e2e79b501..8914ff71bcb29 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -470,7 +470,7 @@ fn construct_fn<'tcx>( .output .span(); - let mut abi = fn_sig.abi; + let mut abi = fn_sig.abi(); if let DefKind::Closure = tcx.def_kind(fn_def) { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b8547e288027a..0dca1eb062d4d 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -131,12 +131,12 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { let callee_sig = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, ty.fn_sig(self.tcx)); - if caller_sig.abi != callee_sig.abi { - self.report_abi_mismatch(expr.span, caller_sig.abi, callee_sig.abi); + if caller_sig.abi() != callee_sig.abi() { + self.report_abi_mismatch(expr.span, caller_sig.abi(), callee_sig.abi()); } - if !callee_sig.abi.supports_guaranteed_tail_call() { - self.report_unsupported_abi(expr.span, callee_sig.abi); + if !callee_sig.abi().supports_guaranteed_tail_call() { + self.report_unsupported_abi(expr.span, callee_sig.abi()); } // FIXME(explicit_tail_calls): this currently fails for cases where opaques are used. @@ -180,11 +180,11 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { } } - if caller_sig.c_variadic { + if caller_sig.c_variadic() { self.report_c_variadic_caller(expr.span); } - if callee_sig.c_variadic { + if callee_sig.c_variadic() { self.report_c_variadic_callee(expr.span); } } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index f22ff92c01782..a1c39950254b4 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -184,15 +184,15 @@ impl<'tcx> ThirBuildCx<'tcx> { // Make sure that inferred closure args have no type span .and_then(|ty| if param.pat.span != ty.span { Some(ty.span) } else { None }); - let self_kind = if index == 0 && fn_decl.implicit_self.has_implicit_self() { - Some(fn_decl.implicit_self) + let self_kind = if index == 0 && fn_decl.implicit_self().has_implicit_self() { + Some(fn_decl.implicit_self()) } else { None }; // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). - let ty = if fn_decl.c_variadic && index == fn_decl.inputs.len() { + let ty = if fn_decl.c_variadic() && index == fn_decl.inputs.len() { let va_list_did = self.tcx.require_lang_item(LangItem::VaList, param.span); self.tcx diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4fd0629befecf..cee637272e090 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -1020,7 +1020,7 @@ fn build_call_shim<'tcx>( let mut body = new_body(MirSource::from_instance(instance), blocks, local_decls, sig.inputs().len(), span); - if let ExternAbi::RustCall = sig.abi { + if let ExternAbi::RustCall = sig.abi() { body.spread_arg = Some(Local::new(sig.inputs().len())); } @@ -1171,9 +1171,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( args.as_coroutine_closure().tupled_upvars_ty(), args.as_coroutine_closure().coroutine_captures_by_ref_ty(), ), - sig.c_variadic, - sig.safety, - sig.abi, + sig.fn_sig_kind, ) }); let sig = tcx.liberate_late_bound_regions(coroutine_closure_def_id, poly_sig); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index a0f1260cd986d..ee08c09c130f6 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -1,6 +1,6 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Safety}; +use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource}; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{ BasicBlock, BasicBlockData, Body, Local, LocalDecl, MirSource, Operand, Place, Rvalue, @@ -67,13 +67,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let resume_adt = tcx.adt_def(tcx.require_lang_item(LangItem::ResumeTy, DUMMY_SP)); let resume_ty = Ty::new_adt(tcx, resume_adt, ty::List::empty()); - let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig( - [ty, resume_ty], - tcx.types.unit, - false, - Safety::Safe, - ExternAbi::Rust, - )); + let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi([ty, resume_ty], tcx.types.unit)); let sig = tcx.instantiate_bound_regions_with_erased(fn_sig); assert!(!drop_ty.is_coroutine()); @@ -310,13 +304,7 @@ fn build_adrop_for_adrop_shim<'tcx>( let pin_adt_ref = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, span)); let env_ty = Ty::new_adt(tcx, pin_adt_ref, tcx.mk_args(&[proxy_ref.into()])); // sig = `fn (Pin<&mut proxy_ty>, &mut Context) -> Poll<()>` - let sig = tcx.mk_fn_sig( - [env_ty, Ty::new_task_context(tcx)], - ret_ty, - false, - hir::Safety::Safe, - ExternAbi::Rust, - ); + let sig = tcx.mk_fn_sig_safe_rust_abi([env_ty, Ty::new_task_context(tcx)], ret_ty); // This function will be called with pinned proxy coroutine layout. // We need to extract `Arg0.0` to get proxy layout, and then get `.0` // further to receive impl coroutine (may be needed) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6ee8db1703b8e..a5dd15563233c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -25,7 +25,7 @@ use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ self as hir, Attribute, CRATE_HIR_ID, Constness, FnSig, ForeignItem, GenericParamKind, HirId, - Item, ItemKind, MethodKind, Node, ParamName, Safety, Target, TraitItem, find_attr, + Item, ItemKind, MethodKind, Node, ParamName, Target, TraitItem, find_attr, }; use rustc_macros::Diagnostic; use rustc_middle::hir::nested_filter; @@ -1671,7 +1671,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; } - let expected_sig = tcx.mk_fn_sig( + let expected_sig = tcx.mk_fn_sig_safe_rust_abi( std::iter::repeat_n( token_stream, match kind { @@ -1680,9 +1680,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }, ), token_stream, - false, - Safety::Safe, - ExternAbi::Rust, ); if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) { diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index 7f80de9da41f4..9c5f285dea02f 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -204,7 +204,7 @@ impl<'tcx, 'a> ExportableItemsChecker<'tcx, 'a> { } let sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); - if !matches!(sig.abi, ExternAbi::C { .. }) { + if !matches!(sig.abi(), ExternAbi::C { .. }) { self.tcx.dcx().emit_err(UnexportableItem::FnAbi(span)); return; } diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs index b8533dcaa8d67..4f3e9f94c599b 100644 --- a/compiler/rustc_public/src/unstable/convert/internal.rs +++ b/compiler/rustc_public/src/unstable/convert/internal.rs @@ -308,11 +308,13 @@ impl RustcInternal for FnSig { tables: &mut Tables<'_, BridgeTys>, tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { + let fn_sig_kind = rustc_ty::FnSigKind::default() + .set_abi(self.abi.internal(tables, tcx)) + .set_safe(self.safety == Safety::Safe) + .set_c_variadic(self.c_variadic); tcx.lift(rustc_ty::FnSig { inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)), - c_variadic: self.c_variadic, - safety: self.safety.internal(tables, tcx), - abi: self.abi.internal(tables, tcx), + fn_sig_kind, }) .unwrap() } diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 57115467366c2..9a9576d47efd2 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -252,6 +252,23 @@ where } } +// This internal type isn't publicly exposed, because it is an implementation detail. +// But it's a public field of FnSig (which has a public mirror type), so allow conversions. +impl<'tcx> Stable<'tcx> for ty::FnSigKind { + type T = (bool /*c_variadic*/, crate::mir::Safety, crate::ty::Abi); + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + cx: &CompilerCtxt<'cx, BridgeTys>, + ) -> Self::T { + ( + self.c_variadic(), + if self.is_safe() { crate::mir::Safety::Safe } else { crate::mir::Safety::Unsafe }, + self.abi().stable(tables, cx), + ) + } +} + impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { type T = crate::ty::FnSig; fn stable<'cx>( @@ -260,6 +277,7 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { cx: &CompilerCtxt<'cx, BridgeTys>, ) -> Self::T { use crate::ty::FnSig; + let (c_variadic, safety, abi) = self.fn_sig_kind.stable(tables, cx); FnSig { inputs_and_output: self @@ -267,9 +285,9 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { .iter() .map(|ty| ty.stable(tables, cx)) .collect(), - c_variadic: self.c_variadic, - safety: self.safety.stable(tables, cx), - abi: self.abi.stable(tables, cx), + c_variadic, + safety, + abi, } } } diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 02d3b0110cb8c..ec1d8dab74519 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start measureme = "12.0.1" -rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_query_impl/src/handle_cycle_error.rs b/compiler/rustc_query_impl/src/handle_cycle_error.rs index e02e4a92d0a2c..79e7788cafe81 100644 --- a/compiler/rustc_query_impl/src/handle_cycle_error.rs +++ b/compiler/rustc_query_impl/src/handle_cycle_error.rs @@ -43,13 +43,9 @@ pub(crate) fn fn_sig<'tcx>( unreachable!() }; - ty::EarlyBinder::bind(ty::Binder::dummy(tcx.mk_fn_sig( - std::iter::repeat_n(err, arity), - err, - false, - rustc_hir::Safety::Safe, - rustc_abi::ExternAbi::Rust, - ))) + ty::EarlyBinder::bind(ty::Binder::dummy( + tcx.mk_fn_sig_safe_rust_abi(std::iter::repeat_n(err, arity), err), + )) } pub(crate) fn check_representability<'tcx>( diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 26979c24bdb68..1071928441080 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -183,7 +183,7 @@ fn encode_fnsig<'tcx>( let mut encode_ty_options = EncodeTyOptions::from_bits(options.bits()) .unwrap_or_else(|| bug!("encode_fnsig: invalid option(s) `{:?}`", options.bits())); - match fn_sig.abi { + match fn_sig.abi() { ExternAbi::C { .. } => { encode_ty_options.insert(EncodeTyOptions::GENERALIZE_REPR_C); } @@ -207,10 +207,10 @@ fn encode_fnsig<'tcx>( s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options)); } - if fn_sig.c_variadic { + if fn_sig.c_variadic() { s.push('z'); } - } else if fn_sig.c_variadic { + } else if fn_sig.c_variadic() { s.push('z'); } else { // Empty parameter lists, whether declared as () or conventionally as (void), are diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 89ee4743a6f43..70b63bfcf64eb 100644 --- a/compiler/rustc_symbol_mangling/src/export.rs +++ b/compiler/rustc_symbol_mangling/src/export.rs @@ -134,7 +134,7 @@ impl<'tcx> AbiHashStable<'tcx> for ty::FnSig<'tcx> { for ty in self.inputs_and_output { ty.abi_hash(tcx, hasher); } - self.safety.is_safe().abi_hash(tcx, hasher); + self.safety().is_safe().abi_hash(tcx, hasher); } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index fa839eb845586..1656944f1cca3 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -551,10 +551,10 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { let sig = sig_tys.with(hdr); self.push("F"); self.wrap_binder(&sig, |p, sig| { - if sig.safety.is_unsafe() { + if sig.safety().is_unsafe() { p.push("U"); } - match sig.abi { + match sig.abi() { ExternAbi::Rust => {} ExternAbi::C { unwind: false } => p.push("KC"), abi => { @@ -570,7 +570,7 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { for &ty in sig.inputs() { ty.print(p)?; } - if sig.c_variadic { + if sig.c_variadic() { p.push("v"); } p.push("E"); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 19a6c5dfe5ee6..df2cd480caa11 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -783,12 +783,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // unsafe extern "C" for<'a> fn(&'a T) -> &'a T // ^^^^^^ let safety = |fn_def, sig: ty::FnSig<'_>| match fn_def { - None => sig.safety.prefix_str(), + None => sig.safety().prefix_str(), Some((did, _)) => { if self.tcx.codegen_fn_attrs(did).safe_target_features { "#[target_features] " } else { - sig.safety.prefix_str() + sig.safety().prefix_str() } } }; @@ -799,11 +799,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // unsafe extern "C" for<'a> fn(&'a T) -> &'a T // ^^^^^^^^^^ - if sig1.abi != ExternAbi::Rust { - values.0.push(format!("extern {} ", sig1.abi), sig1.abi != sig2.abi); + if sig1.abi() != ExternAbi::Rust { + values.0.push(format!("extern {} ", sig1.abi()), sig1.abi() != sig2.abi()); } - if sig2.abi != ExternAbi::Rust { - values.1.push(format!("extern {} ", sig2.abi), sig1.abi != sig2.abi); + if sig2.abi() != ExternAbi::Rust { + values.1.push(format!("extern {} ", sig2.abi()), sig1.abi() != sig2.abi()); } // unsafe extern "C" for<'a> fn(&'a T) -> &'a T @@ -843,17 +843,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - if sig1.c_variadic { + if sig1.c_variadic() { if len1 > 0 { values.0.push_normal(", "); } - values.0.push("...", !sig2.c_variadic); + values.0.push("...", !sig2.c_variadic()); } - if sig2.c_variadic { + if sig2.c_variadic() { if len2 > 0 { values.1.push_normal(", "); } - values.1.push("...", !sig1.c_variadic); + values.1.push("...", !sig1.c_variadic()); } // unsafe extern "C" for<'a> fn(&'a T) -> &'a T diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index 5f2aab38c31c8..252735bbf56b7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -71,7 +71,7 @@ pub fn find_param_with_region<'tcx>( let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); body.params .iter() - .take(if fn_sig.c_variadic { + .take(if fn_sig.c_variadic() { fn_sig.inputs().len() } else { assert_eq!(fn_sig.inputs().len(), body.params.len()); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index fb1d25999116d..b34eb2037d013 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -523,7 +523,7 @@ impl Trait for X { } (ty::FnPtr(_, hdr), ty::FnDef(def_id, _)) | (ty::FnDef(def_id, _), ty::FnPtr(_, hdr)) => { - if tcx.fn_sig(def_id).skip_binder().safety() < hdr.safety { + if tcx.fn_sig(def_id).skip_binder().safety() < hdr.safety() { if !tcx.codegen_fn_attrs(def_id).safe_target_features { diag.note( "unsafe functions cannot be coerced into safe function pointers", diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 04c9edc25d172..9ba92cfa2bdf9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -4,7 +4,6 @@ use std::borrow::Cow; use std::collections::hash_set; use std::path::PathBuf; -use rustc_abi::ExternAbi; use rustc_ast::ast::LitKind; use rustc_ast::{LitIntType, TraitObjectSyntax}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -3203,23 +3202,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let given_ty = Ty::new_fn_ptr( self.tcx, - params.rebind(self.tcx.mk_fn_sig( - given, - self.tcx.types.unit, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )), + params.rebind(self.tcx.mk_fn_sig_safe_rust_abi(given, self.tcx.types.unit)), ); let expected_ty = Ty::new_fn_ptr( self.tcx, - trait_pred.rebind(self.tcx.mk_fn_sig( - expected, - self.tcx.types.unit, - false, - hir::Safety::Safe, - ExternAbi::Rust, - )), + trait_pred.rebind(self.tcx.mk_fn_sig_safe_rust_abi(expected, self.tcx.types.unit)), ); if !self.same_type_modulo_infer(given_ty, expected_ty) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 9a9238f5c7994..5a5d8af4ce144 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2344,21 +2344,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let inputs = trait_ref.args.type_at(1); let sig = match inputs.kind() { ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id) => { - infcx.tcx.mk_fn_sig( - *inputs, - infcx.next_ty_var(DUMMY_SP), - false, - hir::Safety::Safe, - ExternAbi::Rust, - ) + infcx.tcx.mk_fn_sig_safe_rust_abi(*inputs, infcx.next_ty_var(DUMMY_SP)) } - _ => infcx.tcx.mk_fn_sig( - [inputs], - infcx.next_ty_var(DUMMY_SP), - false, - hir::Safety::Safe, - ExternAbi::Rust, - ), + _ => infcx.tcx.mk_fn_sig_safe_rust_abi([inputs], infcx.next_ty_var(DUMMY_SP)), }; Ty::new_fn_ptr(infcx.tcx, ty::Binder::dummy(sig)) @@ -4669,11 +4657,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let [self_ty, found_ty] = trait_ref.args.as_slice() && let Some(fn_ty) = self_ty.as_type().filter(|ty| ty.is_fn()) && let fn_sig @ ty::FnSig { - abi: ExternAbi::Rust, - c_variadic: false, - safety: hir::Safety::Safe, .. } = fn_ty.fn_sig(tcx).skip_binder() + && fn_sig.abi() == ExternAbi::Rust + && !fn_sig.c_variadic() + && fn_sig.safety() == hir::Safety::Safe // Extract first param of fn sig with peeled refs, e.g. `fn(&T)` -> `T` && let Some(&ty::Ref(_, target_ty, needs_mut)) = fn_sig.inputs().first().map(|t| t.kind()) diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 1ca0aa3bab199..254760c1d5f0d 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -465,7 +465,7 @@ fn virtual_call_violations_for_method<'tcx>( if let Some(error) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) { errors.push(error); } - if sig.skip_binder().c_variadic { + if sig.skip_binder().c_variadic() { errors.push(MethodViolation::CVariadic); } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 72d3ba9629f4d..a318d59612792 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1655,13 +1655,8 @@ fn confirm_closure_candidate<'cx, 'tcx>( tupled_upvars_ty, ) }; - tcx.mk_fn_sig( - [sig.tupled_inputs_ty], - output_ty, - sig.c_variadic, - sig.safety, - sig.abi, - ) + + tcx.mk_fn_sig([sig.tupled_inputs_ty], output_ty, sig.fn_sig_kind) }) } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 5008794bcb191..addaee51c268b 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -39,13 +39,7 @@ fn fn_sig_for_fn_abi<'tcx>( typing_env: ty::TypingEnv<'tcx>, ) -> ty::FnSig<'tcx> { if let InstanceKind::ThreadLocalShim(..) = instance.def { - return tcx.mk_fn_sig( - [], - tcx.thread_local_ptr_ty(instance.def_id()), - false, - hir::Safety::Safe, - rustc_abi::ExternAbi::Rust, - ); + return tcx.mk_fn_sig_safe_rust_abi([], tcx.thread_local_ptr_ty(instance.def_id())); } let ty = instance.ty(tcx, typing_env); @@ -74,9 +68,7 @@ fn fn_sig_for_fn_abi<'tcx>( tcx.mk_fn_sig( iter::once(env_ty).chain(sig.inputs().iter().cloned()), sig.output(), - sig.c_variadic, - sig.safety, - sig.abi, + sig.fn_sig_kind, ) } ty::CoroutineClosure(def_id, args) => { @@ -119,9 +111,7 @@ fn fn_sig_for_fn_abi<'tcx>( args.as_coroutine_closure().tupled_upvars_ty(), args.as_coroutine_closure().coroutine_captures_by_ref_ty(), ), - sig.c_variadic, - sig.safety, - sig.abi, + sig.fn_sig_kind, ) } ty::Coroutine(did, args) => { @@ -224,22 +214,10 @@ fn fn_sig_for_fn_abi<'tcx>( }; if let Some(resume_ty) = resume_ty { - tcx.mk_fn_sig( - [env_ty, resume_ty], - ret_ty, - false, - hir::Safety::Safe, - rustc_abi::ExternAbi::Rust, - ) + tcx.mk_fn_sig_safe_rust_abi([env_ty, resume_ty], ret_ty) } else { // `Iterator::next` doesn't have a `resume` argument. - tcx.mk_fn_sig( - [env_ty], - ret_ty, - false, - hir::Safety::Safe, - rustc_abi::ExternAbi::Rust, - ) + tcx.mk_fn_sig_safe_rust_abi([env_ty], ret_ty) } } _ => bug!("unexpected type {:?} in Instance::fn_sig", ty), @@ -334,7 +312,7 @@ fn fn_abi_of_instance_raw<'tcx>( // If the function's body can be used to deduce parameter attributes, then adjust such // "no deduced attrs" ABI; otherwise, return that ABI unadjusted. params.determined_fn_def_id.map_or(fn_abi, |fn_def_id| { - fn_abi_adjust_for_deduced_attrs(¶ms.layout_cx, fn_abi, params.sig.abi, fn_def_id) + fn_abi_adjust_for_deduced_attrs(¶ms.layout_cx, fn_abi, params.sig.abi(), fn_def_id) }) }) } @@ -567,11 +545,11 @@ fn fn_abi_new_uncached<'tcx>( let tcx = cx.tcx(); let abi_map = AbiMap::from_target(&tcx.sess.target); - let conv = abi_map.canonize_abi(sig.abi, sig.c_variadic).unwrap(); + let conv = abi_map.canonize_abi(sig.abi(), sig.c_variadic()).unwrap(); let mut inputs = sig.inputs(); - let extra_args = if sig.abi == ExternAbi::RustCall { - assert!(!sig.c_variadic && extra_args.is_empty()); + let extra_args = if sig.abi() == ExternAbi::RustCall { + assert!(!sig.c_variadic() && extra_args.is_empty()); if let Some(input) = sig.inputs().last() && let ty::Tuple(tupled_arguments) = input.kind() @@ -585,7 +563,7 @@ fn fn_abi_new_uncached<'tcx>( ); } } else { - assert!(sig.c_variadic || extra_args.is_empty()); + assert!(sig.c_variadic() || extra_args.is_empty()); extra_args }; @@ -638,7 +616,7 @@ fn fn_abi_new_uncached<'tcx>( .enumerate() .map(|(i, ty)| arg_of(ty, Some(i))) .collect::>()?, - c_variadic: sig.c_variadic, + c_variadic: sig.c_variadic(), fixed_count: inputs.len() as u32, conv, // FIXME return false for tls shim @@ -646,12 +624,12 @@ fn fn_abi_new_uncached<'tcx>( tcx, // Since `#[rustc_nounwind]` can change unwinding, we cannot infer unwinding by `fn_def_id` for a virtual call. determined_fn_def_id, - sig.abi, + sig.abi(), ), }; - fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi); + fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi()); debug!("fn_abi_new_uncached = {:?}", fn_abi); - fn_abi_sanity_check(cx, &fn_abi, sig.abi); + fn_abi_sanity_check(cx, &fn_abi, sig.abi()); Ok(tcx.arena.alloc(fn_abi)) } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index e5ca3d2db0dcc..cf94dc4298958 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -203,18 +203,51 @@ pub trait Tys>: fn output(self) -> I::Ty; } +pub trait FSigKind>: Copy + Debug + Hash + Eq { + /// The identity function. + fn fn_sig_kind(self) -> Self; + + /// Create a new FnSigKind with the given ABI, safety, and C-style variadic flag. + fn new(abi: I::Abi, safety: I::Safety, c_variadic: bool) -> Self; + + /// Returns the ABI. + fn abi(self) -> I::Abi; + + /// Returns the safety mode. + fn safety(self) -> I::Safety; + + /// Do the function arguments end with a C-style variadic argument? + fn c_variadic(self) -> bool; +} + pub trait Abi>: Copy + Debug + Hash + Eq { - fn rust() -> Self; + /// The identity function. + fn abi(self) -> Self; + + /// The ABI `extern "Rust"`. + fn rust() -> I::Abi; /// Whether this ABI is `extern "Rust"`. fn is_rust(self) -> bool; + + /// Pack the ABI into a small dense integer, so it can be stored as packed `FnSigKind` flags. + fn pack_abi(self) -> u8; + + /// Unpack the ABI from packed `FnSigKind` flags. + fn unpack_abi(abi_index: u8) -> Self; } pub trait Safety>: Copy + Debug + Hash + Eq { + /// The `safe` safety mode. fn safe() -> Self; + /// The `unsafe` safety mode. + fn unsafe_mode() -> Self; + + /// Is the safety mode `Safe`? fn is_safe(self) -> bool; + /// The string prefix for this safety mode. fn prefix_str(self) -> &'static str; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index baae3f2ebe363..f71f7c7c1ab38 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -145,6 +145,7 @@ pub trait Interner: + Eq + TypeVisitable + SliceLike; + type FSigKind: FSigKind; type Safety: Safety; type Abi: Abi; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 61095a00d0414..23d447e8e606b 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -154,19 +154,19 @@ impl Relate for ty::FnSig { ) -> RelateResult> { let cx = relation.cx(); - if a.c_variadic != b.c_variadic { + if a.c_variadic() != b.c_variadic() { return Err(TypeError::VariadicMismatch(ExpectedFound::new( - a.c_variadic, - b.c_variadic, + a.c_variadic(), + b.c_variadic(), ))); } - if a.safety != b.safety { - return Err(TypeError::SafetyMismatch(ExpectedFound::new(a.safety, b.safety))); + if a.safety() != b.safety() { + return Err(TypeError::SafetyMismatch(ExpectedFound::new(a.safety(), b.safety()))); } - if a.abi != b.abi { - return Err(TypeError::AbiMismatch(ExpectedFound::new(a.abi, b.abi))); + if a.abi() != b.abi() { + return Err(TypeError::AbiMismatch(ExpectedFound::new(a.abi(), b.abi()))); }; let a_inputs = a.inputs(); @@ -202,9 +202,7 @@ impl Relate for ty::FnSig { }); Ok(ty::FnSig { inputs_and_output: cx.mk_type_list_from_iter(inputs_and_output)?, - c_variadic: a.c_variadic, - safety: a.safety, - abi: a.abi, + fn_sig_kind: a.fn_sig_kind, }) } } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 9c57d04159cc8..eed44442b77ae 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -2,6 +2,7 @@ use std::fmt; use std::ops::Deref; use derive_where::derive_where; +use rustc_abi::ExternAbi; use rustc_ast_ir::Mutability; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -308,12 +309,7 @@ impl TyKind { ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args), ty::Error(_) => { // ignore errors (#54954) - ty::Binder::dummy(ty::FnSig { - inputs_and_output: Default::default(), - c_variadic: false, - safety: I::Safety::safe(), - abi: I::Abi::rust(), - }) + ty::Binder::dummy(ty::FnSig::dummy()) } ty::Closure(..) => panic!( "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`", @@ -762,6 +758,109 @@ pub struct TypeAndMut { impl Eq for TypeAndMut {} +/// Contains the packed non-type fields of a function signature. +// FIXME(splat): add the splatted argument index as a u16 +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr( + feature = "nightly", + derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) +)] +pub struct FnSigKind { + /// Holds the c_variadic and safety bitflags, and 6 bits for the `ExternAbi` variant and unwind + /// flag. + flags: u8, +} + +impl fmt::Debug for FnSigKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut f = f.debug_tuple("FnSigKind"); + + if self.is_safe() { + f.field(&"Safe"); + } else { + f.field(&"Unsafe"); + } + + f.field(&self.abi()); + + if self.c_variadic() { + f.field(&"CVariadic"); + }; + + f.finish() + } +} + +impl FnSigKind { + /// Mask for the `ExternAbi` variant, including the unwind flag. + const EXTERN_ABI_MASK: u8 = 0b111111; + + /// Bitflag for `Safety::Safe`. The default is `Unsafe`. + const SAFE_FLAG: u8 = 1 << 6; + + /// Bitflag for a trailing C-style variadic argument. + const C_VARIADIC_FLAG: u8 = 1 << 7; + + /// Create a new FnSigKind with the "Rust" ABI, "Unsafe" safety, and no C-style variadic argument. + /// To modify these flags, use the `set_*` methods, for readability. + // FIXME: use Default instead when that trait is const stable. + pub const fn default() -> Self { + Self { flags: 0 }.set_abi(ExternAbi::Rust).set_safe(false).set_c_variadic(false) + } + + /// Set the ABI, including the unwind flag. + #[must_use = "this method does not modify the receiver"] + pub const fn set_abi(mut self, abi: ExternAbi) -> Self { + let abi_index = abi.as_packed(); + assert!(abi_index <= Self::EXTERN_ABI_MASK); + + self.flags &= !Self::EXTERN_ABI_MASK; + self.flags |= abi_index; + + self + } + + /// Set the safety flag, `true` is `Safe`. + #[must_use = "this method does not modify the receiver"] + pub const fn set_safe(mut self, is_safe: bool) -> Self { + if is_safe { + self.flags |= Self::SAFE_FLAG; + } else { + self.flags &= !Self::SAFE_FLAG; + } + + self + } + + /// Set the C-style variadic argument flag. + #[must_use = "this method does not modify the receiver"] + pub const fn set_c_variadic(mut self, c_variadic: bool) -> Self { + if c_variadic { + self.flags |= Self::C_VARIADIC_FLAG; + } else { + self.flags &= !Self::C_VARIADIC_FLAG; + } + + self + } + + /// Get the ABI, including the unwind flag. + pub const fn abi(self) -> ExternAbi { + let abi_index = self.flags & Self::EXTERN_ABI_MASK; + ExternAbi::from_packed(abi_index) + } + + /// Get the safety flag. + pub const fn is_safe(self) -> bool { + self.flags & Self::SAFE_FLAG != 0 + } + + /// Do the function arguments end with a C-style variadic argument? + pub const fn c_variadic(self) -> bool { + self.flags & Self::C_VARIADIC_FLAG != 0 + } +} + #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] #[cfg_attr( feature = "nightly", @@ -770,13 +869,9 @@ impl Eq for TypeAndMut {} #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnSig { pub inputs_and_output: I::Tys, - pub c_variadic: bool, #[type_visitable(ignore)] #[type_foldable(identity)] - pub safety: I::Safety, - #[type_visitable(ignore)] - #[type_foldable(identity)] - pub abi: I::Abi, + pub fn_sig_kind: I::FSigKind, } impl Eq for FnSig {} @@ -791,8 +886,37 @@ impl FnSig { } pub fn is_fn_trait_compatible(self) -> bool { - let FnSig { safety, abi, c_variadic, .. } = self; - !c_variadic && safety.is_safe() && abi.is_rust() + !self.c_variadic() && self.safety().is_safe() && self.abi().is_rust() + } + + pub fn set_safe(self, is_safe: bool) -> Self { + Self { + fn_sig_kind: I::FSigKind::new( + self.abi(), + if is_safe { I::Safety::safe() } else { I::Safety::unsafe_mode() }, + self.c_variadic(), + ), + ..self + } + } + + pub fn safety(self) -> I::Safety { + self.fn_sig_kind.safety() + } + + pub fn abi(self) -> I::Abi { + self.fn_sig_kind.abi() + } + + pub fn c_variadic(self) -> bool { + self.fn_sig_kind.c_variadic() + } + + pub fn dummy() -> Self { + Self { + inputs_and_output: Default::default(), + fn_sig_kind: I::FSigKind::new(I::Abi::rust(), I::Safety::safe(), false), + } } } @@ -817,16 +941,20 @@ impl ty::Binder> { self.map_bound(|fn_sig| fn_sig.output()) } + pub fn fn_sig_kind(self) -> I::FSigKind { + self.skip_binder().fn_sig_kind + } + pub fn c_variadic(self) -> bool { - self.skip_binder().c_variadic + self.skip_binder().c_variadic() } pub fn safety(self) -> I::Safety { - self.skip_binder().safety + self.skip_binder().safety() } pub fn abi(self) -> I::Abi { - self.skip_binder().abi + self.skip_binder().abi() } pub fn is_fn_trait_compatible(&self) -> bool { @@ -835,8 +963,7 @@ impl ty::Binder> { // Used to split a single value into the two fields in `TyKind::FnPtr`. pub fn split(self) -> (ty::Binder>, FnHeader) { - let hdr = - FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() }; + let hdr = FnHeader { fn_sig_kind: self.fn_sig_kind() }; (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr) } } @@ -844,11 +971,11 @@ impl ty::Binder> { impl fmt::Debug for FnSig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let sig = self; - let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig; + let FnSig { inputs_and_output: _, fn_sig_kind } = sig; - write!(f, "{}", safety.prefix_str())?; - if !abi.is_rust() { - write!(f, "extern \"{abi:?}\" ")?; + write!(f, "{}", fn_sig_kind.safety().prefix_str())?; + if !fn_sig_kind.abi().is_rust() { + write!(f, "extern \"{:?}\" ", fn_sig_kind.abi())?; } write!(f, "fn(")?; @@ -859,7 +986,7 @@ impl fmt::Debug for FnSig { } write!(f, "{ty:?}")?; } - if *c_variadic { + if fn_sig_kind.c_variadic() { if inputs.is_empty() { write!(f, "...")?; } else { @@ -968,9 +1095,7 @@ impl ty::Binder> { pub fn with(self, hdr: FnHeader) -> ty::Binder> { self.map_bound(|sig_tys| FnSig { inputs_and_output: sig_tys.inputs_and_output, - c_variadic: hdr.c_variadic, - safety: hdr.safety, - abi: hdr.abi, + fn_sig_kind: hdr.fn_sig_kind, }) } @@ -1002,9 +1127,27 @@ impl ty::Binder> { )] #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnHeader { - pub c_variadic: bool, - pub safety: I::Safety, - pub abi: I::Abi, + #[type_visitable(ignore)] + #[type_foldable(identity)] + pub fn_sig_kind: I::FSigKind, +} + +impl FnHeader { + pub fn c_variadic(self) -> bool { + self.fn_sig_kind.c_variadic() + } + + pub fn safety(self) -> I::Safety { + self.fn_sig_kind.safety() + } + + pub fn abi(self) -> I::Abi { + self.fn_sig_kind.abi() + } + + pub fn dummy() -> Self { + Self { fn_sig_kind: I::FSigKind::new(I::Abi::rust(), I::Safety::safe(), false) } + } } impl Eq for FnHeader {} diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index e8f94c8e7cc92..1ad5ed45e8b10 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -307,9 +307,7 @@ impl CoroutineClosureArgs { resume_ty, yield_ty, return_ty, - c_variadic: hdr.c_variadic, - safety: hdr.safety, - abi: hdr.abi, + fn_sig_kind: hdr.fn_sig_kind, } }) } @@ -366,16 +364,10 @@ pub struct CoroutineClosureSignature { // Like the `fn_sig_as_fn_ptr_ty` of a regular closure, these types // never actually differ. But we save them rather than recreating them // from scratch just for good measure. - /// Always false - pub c_variadic: bool, - /// Always `Normal` (safe) + /// Always safe, RustCall, non-c-variadic #[type_visitable(ignore)] #[type_foldable(identity)] - pub safety: I::Safety, - /// Always `RustCall` - #[type_visitable(ignore)] - #[type_foldable(identity)] - pub abi: I::Abi, + pub fn_sig_kind: I::FSigKind, } impl Eq for CoroutineClosureSignature {} diff --git a/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs b/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs index ce427d54b3552..7ce0e31750bfd 100644 --- a/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs +++ b/library/stdarch/crates/stdarch-gen-arm/src/intrinsic.rs @@ -550,7 +550,7 @@ impl LLVMLink { /// Alters all the unsigned types from the signature. This is required where /// a signed and unsigned variant require the same binding to an exposed - /// LLVM instrinsic. + /// LLVM intrinsic. pub fn sanitise_uints(&mut self) { let transform = |tk: &mut TypeKind| { if let Some(BaseType::Sized(BaseTypeKind::UInt, size)) = tk.base_type() { @@ -1139,7 +1139,7 @@ impl Intrinsic { } else { /* If we do not need to reorder anything then immediately add * the expressions from the big_endian_expressions and - * concatinate the compose vector */ + * concatenate the compose vector */ variant.big_endian_compose.extend(big_endian_expressions); variant .big_endian_compose @@ -1157,11 +1157,11 @@ impl Intrinsic { /* If we do not create a shuffle call we do not need modify the * return value and append to the big endian ast array. A bit confusing - * as in code we are making the final call before caputuring the return + * as in code we are making the final call before capturing the return * value of the intrinsic that has been called.*/ let ret_val_name = "ret_val".to_string(); if let Some(simd_shuffle_call) = create_shuffle_call(&ret_val_name, return_type) { - /* There is a possibility that the funcion arguments did not + /* There is a possibility that the function arguments did not * require big endian treatment, thus we need to now add the * original function body before appending the return value.*/ if variant.big_endian_compose.is_empty() { @@ -1695,8 +1695,8 @@ enum Endianness { NA, } -/// Based on the endianess will create the appropriate intrinsic, or simply -/// create the desired intrinsic without any endianess +/// Based on the endianness will create the appropriate intrinsic, or simply +/// create the desired intrinsic without any endianness fn create_tokens(intrinsic: &Intrinsic, endianness: Endianness, tokens: &mut TokenStream) { let signature = &intrinsic.signature; let fn_name = signature.fn_name().to_string(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5fa5c7b0519ac..832b7a5093cff 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1172,7 +1172,7 @@ fn clean_fn_decl_with_params<'tcx>( { output = output.sugared_async_return_type(); } - FnDecl { inputs: params, output, c_variadic: decl.c_variadic } + FnDecl { inputs: params, output, c_variadic: decl.c_variadic() } } fn clean_poly_fn_sig<'tcx>( @@ -1210,7 +1210,7 @@ fn clean_poly_fn_sig<'tcx>( }) .collect(); - FnDecl { inputs: params, output, c_variadic: sig.skip_binder().c_variadic } + FnDecl { inputs: params, output, c_variadic: sig.skip_binder().c_variadic() } } fn clean_trait_ref<'tcx>(trait_ref: &hir::TraitRef<'tcx>, cx: &mut DocContext<'tcx>) -> Path { diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index 7f0f0a0245f4c..dae0c8439ea82 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -306,9 +306,16 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { cur_f = Some(field); } }, - ItemKind::Trait(_constness, is_auto, _safety, _impl_restriction, _ident, _generics, _generic_bounds, item_ref) - if self.enable_ordering_for_trait && *is_auto == IsAuto::No => - { + ItemKind::Trait( + _constness, + is_auto, + _safety, + _impl_restriction, + _ident, + _generics, + _generic_bounds, + item_ref, + ) if self.enable_ordering_for_trait && *is_auto == IsAuto::No => { let mut cur_t: Option<(TraitItemId, Ident)> = None; for &item in *item_ref { diff --git a/src/tools/clippy/clippy_lints/src/derive/derive_partial_eq_without_eq.rs b/src/tools/clippy/clippy_lints/src/derive/derive_partial_eq_without_eq.rs index 22943cd9ee5e2..3782c1dab3557 100644 --- a/src/tools/clippy/clippy_lints/src/derive/derive_partial_eq_without_eq.rs +++ b/src/tools/clippy/clippy_lints/src/derive/derive_partial_eq_without_eq.rs @@ -85,8 +85,5 @@ fn typing_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> .upcast(tcx) }), ))); - ty::TypingEnv::new( - param_env, - ty::TypingMode::non_body_analysis(), - ) + ty::TypingEnv::new(param_env, ty::TypingMode::non_body_analysis()) } diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 3562200cbd929..229af104799d1 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -4,7 +4,6 @@ use clippy_utils::res::{MaybeDef, MaybeResPath}; use clippy_utils::source::{snippet_opt, snippet_with_applicability}; use clippy_utils::usage::{local_used_after_expr, local_used_in}; use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate}; -use rustc_abi::ExternAbi; use rustc_errors::Applicability; use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind, find_attr}; use rustc_infer::infer::TyCtxtInferExt; @@ -173,7 +172,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx && let output = typeck.expr_ty(body.value) && let ty::Tuple(tys) = *subs.type_at(1).kind() { - cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, ExternAbi::Rust) + cx.tcx.mk_fn_sig_safe_rust_abi(tys, output) } else { return; } @@ -318,7 +317,7 @@ fn check_inputs( } fn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool { - call_sig.safety.is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig) + call_sig.safety().is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig) } /// This walks through both signatures and checks for any time a late-bound region is expected by an diff --git a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs index fa63876410f01..215039952ca5a 100644 --- a/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs +++ b/src/tools/clippy/clippy_lints/src/functions/misnamed_getters.rs @@ -23,7 +23,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: let name = ident.name.as_str(); - let name = match decl.implicit_self { + let name = match decl.implicit_self() { ImplicitSelfKind::RefMut => { let Some(name) = name.strip_suffix("_mut") else { return; diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index c6b0e7c54c06f..e49dee4164b88 100644 --- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -59,7 +59,7 @@ fn check_raw_ptr<'tcx>( }, hir::ExprKind::MethodCall(_, recv, args, _) => { let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap(); - if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety.is_unsafe() { + if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety().is_unsafe() { check_arg(cx, &raw_ptrs, recv); for arg in args { check_arg(cx, &raw_ptrs, arg); diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs index 22082646eb316..afe2a1033ceeb 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs @@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString { && header.abi == ExternAbi::Rust && impl_item.ident.name == sym::to_string && let decl = signature.decl - && decl.implicit_self.has_implicit_self() + && decl.implicit_self().has_implicit_self() && decl.inputs.len() == 1 && impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })) && !impl_item.span.from_expansion() diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs index 753360906d666..73e4a856c0468 100644 --- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator { } fn check_sig(cx: &LateContext<'_>, name: Symbol, sig: &FnSig<'_>, fn_id: LocalDefId) { - if sig.decl.implicit_self.has_implicit_self() { + if sig.decl.implicit_self().has_implicit_self() { let ret_ty = cx .tcx .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(fn_id).instantiate_identity().output()); diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 4e56f9c8472de..369037dad94fc 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -205,7 +205,7 @@ impl {self_ty_without_ref} {{ && let FnRetTy::Return(ret) = sig.decl.output && is_nameable_in_impl_trait(ret) && cx.tcx.generics_of(item_did).is_own_empty() - && sig.decl.implicit_self == expected_implicit_self + && sig.decl.implicit_self() == expected_implicit_self && sig.decl.inputs.len() == 1 && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id()) && imp.of_trait.is_none() diff --git a/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs b/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs index 60dbd6cd3570f..de6ccf56ab2a2 100644 --- a/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if item.ident.name == sym::len && let ImplItemKind::Fn(sig, _) = &item.kind - && sig.decl.implicit_self.has_implicit_self() + && sig.decl.implicit_self().has_implicit_self() && sig.decl.inputs.len() == 1 && cx.effective_visibilities.is_exported(item.owner_id.def_id) && matches!(sig.decl.output, FnRetTy::Return(_)) @@ -79,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty { check_for_is_empty( cx, sig.span, - sig.decl.implicit_self, + sig.decl.implicit_self(), output, ty_id, name, diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index 0bb4992cf6bb4..ea99b523f09b0 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -411,7 +411,7 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option, msrv: Msrv) -> bool { if let Some(ident) = ident && ident.name == kw::SelfLower - && !func.implicit_self.has_implicit_self() + && !func.implicit_self().has_implicit_self() && let Some(self_ty) = func.inputs.first() && !msrv.meets(cx, msrvs::EXPLICIT_SELF_TYPE_ELISION) { @@ -697,7 +697,7 @@ fn is_candidate_for_elision(fd: &FnDecl<'_>) -> bool { } } - if fd.lifetime_elision_allowed + if fd.lifetime_elision_allowed() && let Return(ret_ty) = fd.output && walk_unambig_ty(&mut V, ret_ty).is_break() { diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index b39aec6e521ce..3d456c8e77918 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -5062,7 +5062,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let first_arg_ty_opt = method_sig.inputs().iter().next().copied(); should_implement_trait::check_impl_item(cx, impl_item, self_ty, implements_trait, first_arg_ty_opt, sig); - if sig.decl.implicit_self.has_implicit_self() + if sig.decl.implicit_self().has_implicit_self() && !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)) && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir_body(id)).next() @@ -5089,7 +5089,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } if let TraitItemKind::Fn(ref sig, _) = item.kind { - if sig.decl.implicit_self.has_implicit_self() + if sig.decl.implicit_self().has_implicit_self() && let Some(first_arg_hir_ty) = sig.decl.inputs.first() && let Some(&first_arg_ty) = cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 6c45964da0dab..f1625b1a4c6e0 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { }) => ( owner_id.to_def_id(), FnKind::TraitFn, - usize::from(sig.decl.implicit_self.has_implicit_self()), + usize::from(sig.decl.implicit_self().has_implicit_self()), ), Node::ImplItem(&ImplItem { kind: ImplItemKind::Fn(ref sig, _), @@ -339,7 +339,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { FnKind::ImplTraitFn( std::ptr::from_ref(cx.tcx.erase_and_anonymize_regions(trait_ref.args)) as usize ), - usize::from(sig.decl.implicit_self.has_implicit_self()), + usize::from(sig.decl.implicit_self().has_implicit_self()), ) } else { (owner_id.to_def_id(), FnKind::Fn, 0) diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs index 78f5167fa5436..8c892b7085b7c 100644 --- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs +++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs @@ -70,7 +70,7 @@ declare_lint_pass!(ReturnSelfNotMustUse => [RETURN_SELF_NOT_MUST_USE]); fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, span: Span, owner_id: OwnerId) { if !span.in_external_macro(cx.sess().source_map()) // If it comes from an external macro, better ignore it. - && decl.implicit_self.has_implicit_self() + && decl.implicit_self().has_implicit_self() // We only show this warning for public exported methods. && cx.effective_visibilities.is_exported(fn_def) // We don't want to emit this lint if the `#[must_use]` attribute is already there. diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index 534ba3a50c6b4..e32cf944536bf 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -44,7 +44,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { match impl_item.kind { ImplItemKind::Fn(ref sig, _) => { - if sig.decl.implicit_self.has_implicit_self() { + if sig.decl.implicit_self().has_implicit_self() { return; } }, diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 297f4c2df040d..3df16bf71ce7e 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -376,7 +376,7 @@ impl UnconditionalRecursion { method_def_id: LocalDefId, ) { // We're only interested into static methods. - if decl.implicit_self.has_implicit_self() { + if decl.implicit_self().has_implicit_self() { return; } // We don't check trait implementations. diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index a4d8fd20e4d3f..4d9ddb388f3cb 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -257,9 +257,9 @@ impl HirEqInterExpr<'_, '_, '_> { (FnRetTy::Return(l_ty), FnRetTy::Return(r_ty)) => self.eq_ty(l_ty, r_ty), _ => false, }) - && left.c_variadic == right.c_variadic - && left.implicit_self == right.implicit_self - && left.lifetime_elision_allowed == right.lifetime_elision_allowed + && left.c_variadic() == right.c_variadic() + && left.implicit_self() == right.implicit_self() + && left.lifetime_elision_allowed() == right.lifetime_elision_allowed() } fn eq_generics(&mut self, left: &Generics<'_>, right: &Generics<'_>) -> bool { @@ -1571,7 +1571,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_ty(ty); }, } - fn_ptr.decl.c_variadic.hash(&mut self.s); + fn_ptr.decl.c_variadic().hash(&mut self.s); }, TyKind::Tup(ty_list) => { for ty in *ty_list { diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 6ac979d595f49..28449a75a8fc5 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -437,7 +437,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().is_unsafe() => { ControlFlow::Break(()) }, - ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()), + ty::FnPtr(_, hdr) if hdr.safety().is_unsafe() => ControlFlow::Break(()), _ => walk_expr(self, e), }, ExprKind::Path(ref p) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index bb52bde6fe7b2..273ac90068b01 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -7,7 +7,6 @@ )] // The rustc crates we need -extern crate rustc_abi; extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_driver; @@ -47,7 +46,6 @@ use miri::{ BacktraceStyle, BorrowTrackerMethod, GenmcConfig, GenmcCtx, MiriConfig, MiriEntryFnType, ProvenanceMode, TreeBorrowsParams, ValidationMode, run_genmc_mode, }; -use rustc_abi::ExternAbi; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::sync::{self, DynSync}; use rustc_driver::Compilation; @@ -98,12 +96,9 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) { let start_def_id = id.expect_local(); let start_span = tcx.def_span(start_def_id); - let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig( + let expected_sig = ty::Binder::dummy(tcx.mk_fn_sig_safe_rust_abi( [tcx.types.isize, Ty::new_imm_ptr(tcx, Ty::new_imm_ptr(tcx, tcx.types.u8))], tcx.types.isize, - false, - hir::Safety::Safe, - ExternAbi::Rust, )); let correct_func_sig = check_function_signature( diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index a40ad4b55317f..2a6520ffc2ba5 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -6,14 +6,13 @@ use std::{cmp, iter}; use rand::RngCore; use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants}; use rustc_data_structures::fx::{FxBuildHasher, FxHashSet}; -use rustc_hir::Safety; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefId, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::ty::layout::{LayoutOf, MaybeResult, TyAndLayout}; -use rustc_middle::ty::{self, IntTy, Ty, TyCtxt, UintTy}; +use rustc_middle::ty::{self, FnSigKind, IntTy, Ty, TyCtxt, UintTy}; use rustc_session::config::CrateType; use rustc_span::{Span, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; @@ -408,9 +407,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let sig = this.tcx.mk_fn_sig( args.iter().map(|a| a.layout.ty), dest.layout.ty, - /*c_variadic*/ false, - Safety::Safe, - caller_abi, + FnSigKind::default().set_abi(caller_abi).set_safe(true), ); let caller_fn_abi = this.fn_abi_of_fn_ptr(ty::Binder::dummy(sig), ty::List::empty())?; diff --git a/src/tools/miri/src/shims/sig.rs b/src/tools/miri/src/shims/sig.rs index 43b913edbebf5..ddfde35f47c4d 100644 --- a/src/tools/miri/src/shims/sig.rs +++ b/src/tools/miri/src/shims/sig.rs @@ -1,8 +1,7 @@ //! Everything related to checking the signature of shim invocations. use rustc_abi::{CanonAbi, ExternAbi}; -use rustc_hir::Safety; -use rustc_middle::ty::{Binder, FnSig, Ty}; +use rustc_middle::ty::{Binder, FnSig, FnSigKind, Ty}; use rustc_span::Symbol; use rustc_target::callconv::FnAbi; @@ -275,10 +274,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { inputs_and_output.push(shim_sig.ret); let fn_sig_binder = Binder::dummy(FnSig { inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output), - c_variadic: false, - // This does not matter for the ABI. - safety: Safety::Safe, - abi: shim_sig.abi, + // Safety does not matter for the ABI. + fn_sig_kind: FnSigKind::default().set_abi(shim_sig.abi).set_safe(true), }); let callee_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs index ce99016470c14..b868f0234209e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/closure.rs @@ -164,13 +164,7 @@ impl<'db> InferenceContext<'_, 'db> { let coroutine_captures_by_ref_ty = Ty::new_fn_ptr( interner, Binder::bind_with_vars( - interner.mk_fn_sig( - [], - self.types.types.unit, - false, - Safety::Safe, - FnAbi::Rust, - ), + interner.mk_fn_sig_safe_rust_abi([], self.types.types.unit), self.types.coroutine_captures_by_ref_bound_var_kinds, ), ); @@ -484,13 +478,8 @@ impl<'db> InferenceContext<'_, 'db> { let ret_param_ty = projection.skip_binder().term.expect_type(); debug!(?ret_param_ty); - let sig = projection.rebind(self.interner().mk_fn_sig( - input_tys, - ret_param_ty, - false, - Safety::Safe, - FnAbi::Rust, - )); + let sig = + projection.rebind(self.interner().mk_fn_sig_safe_rust_abi(input_tys, ret_param_ty)); Some(sig) } @@ -572,13 +561,8 @@ impl<'db> InferenceContext<'_, 'db> { // that does not misuse a `FnSig` type, but that can be done separately. let return_ty = return_ty.unwrap_or_else(|| self.table.next_ty_var()); - let sig = projection.rebind(self.interner().mk_fn_sig( - input_tys, - return_ty, - false, - Safety::Safe, - FnAbi::Rust, - )); + let sig = + projection.rebind(self.interner().mk_fn_sig_safe_rust_abi(input_tys, return_ty)); Some(sig) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs index 622648bc8d52b..5d7ad84e1fe2c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/interner.rs @@ -2358,6 +2358,22 @@ impl<'db> DbInterner<'db> { abi, } } + + /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument. + pub fn mk_fn_sig_safe_rust_abi(self, inputs: I, output: Ty<'db>) -> FnSig<'db> + where + I: IntoIterator>, + { + FnSig { + inputs_and_output: Tys::new_from_iter( + self, + inputs.into_iter().chain(std::iter::once(output)), + ), + c_variadic: false, + safety: Safety::Safe, + abi: FnAbi::Rust, + } + } } fn predicates_of(db: &dyn HirDatabase, def_id: SolverDefId) -> &GenericPredicates { diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr index 8594a62fc9488..8309b8f957a7a 100644 --- a/tests/ui/symbol-names/basic.legacy.stderr +++ b/tests/ui/symbol-names/basic.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN5basic4main17h1dddcfd03744167fE) +error: symbol-name(_ZN5basic4main17h947b7a9ed2b2bf56E) --> $DIR/basic.rs:8:1 | LL | #[rustc_dump_symbol_name] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: demangling(basic::main::h1dddcfd03744167f) +error: demangling(basic::main::h947b7a9ed2b2bf56) --> $DIR/basic.rs:8:1 | LL | #[rustc_dump_symbol_name] diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr index aebdaf111fc84..359bafdff4692 100644 --- a/tests/ui/symbol-names/issue-60925.legacy.stderr +++ b/tests/ui/symbol-names/issue-60925.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h4b3099ec5dc5d306E) +error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17hba5ac046b858f549E) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_dump_symbol_name] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: demangling(issue_60925::foo::Foo::foo::h4b3099ec5dc5d306) +error: demangling(issue_60925::foo::Foo::foo::hba5ac046b858f549) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_dump_symbol_name]