mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Refactor FnDecl and FnSig flags into packed structs
This commit is contained in:
@@ -4578,7 +4578,6 @@ name = "rustc_query_impl"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"measureme",
|
||||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_hir",
|
||||
|
||||
@@ -131,6 +131,29 @@ pub const fn as_str(&self) -> &'static str {
|
||||
$($e_name::$variant $( { unwind: $uw } )* => $tok,)*
|
||||
}
|
||||
}
|
||||
// ALL_VARIANTS.iter().position(|v| v == self), but const
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
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 {
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
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 @@ fn get_resolution_id(&self, node_id: NodeId) -> Option<DefId> {
|
||||
// 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 @@ fn lower_delegation_decl(
|
||||
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 @@ fn lower_delegation_sig(
|
||||
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 @@ fn generate_delegation_error(
|
||||
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 };
|
||||
|
||||
@@ -762,9 +762,7 @@ pub(super) fn make_desugared_coroutine_expr(
|
||||
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| {
|
||||
|
||||
@@ -1831,7 +1831,7 @@ fn lower_fn_decl(
|
||||
// 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 @@ fn lower_fn_decl(
|
||||
},
|
||||
};
|
||||
|
||||
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 @@ fn lower_fn_decl(
|
||||
}
|
||||
_ => 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 { .. }`
|
||||
|
||||
@@ -493,7 +493,7 @@ pub(crate) fn report_mutability_error(
|
||||
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 @@ fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>) {
|
||||
&& 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 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
|
||||
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
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
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 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
|
||||
}
|
||||
|
||||
// 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(
|
||||
|
||||
@@ -103,9 +103,7 @@ pub(super) fn check_signature_annotation(&mut self) {
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1015,7 +1015,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
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 @@ fn check_call_inputs(
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#[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));
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
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 @@ fn codegen_llvm_intrinsic_call(
|
||||
}
|
||||
_ => 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));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -419,7 +419,7 @@ pub(crate) fn write_fn_ptr_type_info(
|
||||
sig: &FnSigTys<TyCtxt<'tcx>>,
|
||||
fn_header: &FnHeader<TyCtxt<'tcx>>,
|
||||
) -> 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 @@ pub(crate) fn write_fn_ptr_type_info(
|
||||
|
||||
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 @@ pub(crate) fn write_fn_ptr_type_info(
|
||||
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}"),
|
||||
}
|
||||
|
||||
@@ -542,7 +542,7 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResul
|
||||
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 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResul
|
||||
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!(
|
||||
|
||||
@@ -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 @@ pub fn opt_delegation_generics(&self) -> Option<&'hir DelegationGenerics> {
|
||||
|
||||
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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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 main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
|
||||
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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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::<Vec<String>>()
|
||||
.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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ fn get_lifetime_args_suggestions_from_param_names(
|
||||
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::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,9 @@
|
||||
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 @@ pub fn lower_fn_ty(
|
||||
|
||||
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, .. }) =
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2264,8 +2264,8 @@ fn print_fn(
|
||||
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 @@ fn print_fn(
|
||||
print_arg(s, Some(ty));
|
||||
s.end(ib);
|
||||
});
|
||||
if decl.c_variadic {
|
||||
if decl.c_variadic() {
|
||||
if !decl.inputs.is_empty() {
|
||||
self.word(", ");
|
||||
}
|
||||
|
||||
@@ -89,11 +89,11 @@ pub(crate) fn check_expr_call(
|
||||
|
||||
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 @@ fn try_overloaded_call_step(
|
||||
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 @@ fn confirm_builtin_call(
|
||||
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 @@ fn confirm_deferred_closure_call(
|
||||
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 @@ fn confirm_overloaded_call(
|
||||
method.sig.output(),
|
||||
expected,
|
||||
arg_exprs,
|
||||
method.sig.c_variadic,
|
||||
method.sig.c_variadic(),
|
||||
TupleArgumentsFlag::TupleArguments,
|
||||
Some(method.def_id),
|
||||
);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
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 @@ pub(crate) fn check_expr_closure(
|
||||
// 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 @@ pub(crate) fn check_expr_closure(
|
||||
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 @@ pub(crate) fn check_expr_closure(
|
||||
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 @@ fn extract_sig_from_projection(
|
||||
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 @@ fn extract_sig_from_projection_and_future_bound(
|
||||
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 @@ fn sig_of_closure_with_expectation(
|
||||
// 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 @@ fn sig_of_closure_with_expectation(
|
||||
// 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 @@ fn merge_supplied_sig_with_expectation(
|
||||
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 @@ fn supplied_sig_of_closure(
|
||||
},
|
||||
};
|
||||
|
||||
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 @@ fn error_sig_of_closure(
|
||||
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);
|
||||
|
||||
|
||||
@@ -944,7 +944,7 @@ fn coerce_from_fn_pointer(
|
||||
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 @@ fn coerce_from_fn_item(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'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 @@ fn coerce_closure_to_fn(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'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);
|
||||
|
||||
|
||||
@@ -1489,12 +1489,12 @@ fn check_expr_method_call(
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ pub(in super::super) fn check_argument_types(
|
||||
// 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 @@ fn get_hir_param_info(
|
||||
(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(),
|
||||
|
||||
@@ -4366,7 +4366,7 @@ fn suggest_traits_to_import(
|
||||
_ => 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) {
|
||||
|
||||
@@ -438,13 +438,7 @@ fn analyze_closure(
|
||||
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,
|
||||
)]),
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -816,7 +816,7 @@ impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'tcx> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -707,7 +707,7 @@ pub fn hir_id_to_string(self, id: HirId) -> String {
|
||||
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 @@ pub fn hir_id_to_string(self, id: HirId) -> String {
|
||||
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",
|
||||
},
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
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 @@ fn as_local(self) -> Option<LocalDefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::FSigKind<TyCtxt<'tcx>> 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<TyCtxt<'tcx>> for ExternAbi {
|
||||
fn abi(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn rust() -> Self {
|
||||
ExternAbi::Rust
|
||||
}
|
||||
@@ -92,6 +120,14 @@ fn rust() -> Self {
|
||||
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<TyCtxt<'tcx>> for hir::Safety {
|
||||
@@ -99,6 +135,10 @@ fn safe() -> Self {
|
||||
hir::Safety::Safe
|
||||
}
|
||||
|
||||
fn unsafe_mode() -> Self {
|
||||
hir::Safety::Unsafe
|
||||
}
|
||||
|
||||
fn is_safe(self) -> bool {
|
||||
self.is_safe()
|
||||
}
|
||||
@@ -1332,7 +1372,10 @@ pub fn adjust_target_feature_sig(
|
||||
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 @@ pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'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 @@ pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> P
|
||||
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,26 +2469,40 @@ pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
// 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<I, T>(
|
||||
self,
|
||||
inputs: I,
|
||||
output: I::Item,
|
||||
c_variadic: bool,
|
||||
safety: hir::Safety,
|
||||
abi: ExternAbi,
|
||||
) -> T::Output
|
||||
pub fn mk_fn_sig<I, T>(self, inputs: I, output: I::Item, fn_sig_kind: FnSigKind) -> T::Output
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: CollectAndApply<Ty<'tcx>, 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,
|
||||
fn_sig_kind,
|
||||
})
|
||||
}
|
||||
|
||||
/// `mk_fn_sig`, but with a Rust ABI, and no C-variadic argument.
|
||||
pub fn mk_fn_sig_rust_abi<I, T>(
|
||||
self,
|
||||
inputs: I,
|
||||
output: I::Item,
|
||||
safety: hir::Safety,
|
||||
) -> T::Output
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
|
||||
{
|
||||
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<I, T>(self, inputs: I, output: I::Item) -> T::Output
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
|
||||
{
|
||||
self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(true))
|
||||
}
|
||||
|
||||
pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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 @@ fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
|
||||
type AllocId = crate::mir::interpret::AllocId;
|
||||
type Pat = Pattern<'tcx>;
|
||||
type PatList = &'tcx List<Pattern<'tcx>>;
|
||||
type FSigKind = FnSigKind;
|
||||
type Safety = hir::Safety;
|
||||
type Abi = ExternAbi;
|
||||
type Const = ty::Const<'tcx>;
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
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,
|
||||
};
|
||||
|
||||
@@ -750,7 +750,7 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
|
||||
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 @@ macro_rules! define_print_and_forward_display {
|
||||
(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> {
|
||||
|
||||
@@ -198,6 +198,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
rustc_hir::Safety,
|
||||
rustc_middle::mir::ConstValue,
|
||||
rustc_type_ir::BoundConstness,
|
||||
rustc_type_ir::FnSigKind,
|
||||
rustc_type_ir::PredicatePolarity,
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
||||
pub type AliasTyKind<'tcx> = ir::AliasTyKind<TyCtxt<'tcx>>;
|
||||
pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
|
||||
pub type FnSigKind = ir::FnSigKind;
|
||||
pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>;
|
||||
pub type EarlyBinder<'tcx, T> = ir::EarlyBinder<TyCtxt<'tcx>, T>;
|
||||
pub type TypingMode<'tcx> = ir::TypingMode<TyCtxt<'tcx>>;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -131,12 +131,12 @@ fn check_tail_call(&mut self, call: &Expr<'_>, expr: &Expr<'_>) {
|
||||
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 @@ fn check_tail_call(&mut self, call: &Expr<'_>, expr: &Expr<'_>) {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,15 +184,15 @@ fn explicit_params(
|
||||
// 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
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 @@ fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) {
|
||||
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 @@ fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) {
|
||||
},
|
||||
),
|
||||
token_stream,
|
||||
false,
|
||||
Safety::Safe,
|
||||
ExternAbi::Rust,
|
||||
);
|
||||
|
||||
if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) {
|
||||
|
||||
@@ -204,7 +204,7 @@ fn check_fn(&mut self) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -308,11 +308,13 @@ fn internal<'tcx>(
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -252,6 +252,23 @@ fn stable<'cx>(
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ fn stable<'cx>(
|
||||
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 @@ fn stable<'cx>(
|
||||
.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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -134,7 +134,7 @@ fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -551,10 +551,10 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
|
||||
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 @@ fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
|
||||
for &ty in sig.inputs() {
|
||||
ty.print(p)?;
|
||||
}
|
||||
if sig.c_variadic {
|
||||
if sig.c_variadic() {
|
||||
p.push("v");
|
||||
}
|
||||
p.push("E");
|
||||
|
||||
@@ -783,12 +783,12 @@ fn cmp_fn_sig(
|
||||
// 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 @@ fn cmp_fn_sig(
|
||||
|
||||
// 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 @@ fn cmp_fn_sig(
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -523,7 +523,7 @@ fn foo(&self, x: T) -> T { 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",
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
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 @@ fn add_help_message_for_fn_trait(
|
||||
|
||||
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) {
|
||||
|
||||
@@ -2344,21 +2344,9 @@ pub(crate) fn build_fn_sig_ty<'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 @@ fn suggest_option_method_if_applicable<G: EmissionGuarantee>(
|
||||
&& 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())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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::<Result<_, _>>()?,
|
||||
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))
|
||||
}
|
||||
|
||||
|
||||
@@ -203,18 +203,51 @@ pub trait Tys<I: Interner<Tys = Self>>:
|
||||
fn output(self) -> I::Ty;
|
||||
}
|
||||
|
||||
pub trait FSigKind<I: Interner<FSigKind = Self>>: 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<I: Interner<Abi = Self>>: 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<I: Interner<Safety = Self>>: 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ fn mk_tracked<T: Debug + Clone>(
|
||||
+ Eq
|
||||
+ TypeVisitable<Self>
|
||||
+ SliceLike<Item = Self::Pat>;
|
||||
type FSigKind: FSigKind<Self>;
|
||||
type Safety: Safety<Self>;
|
||||
type Abi: Abi<Self>;
|
||||
|
||||
|
||||
@@ -154,19 +154,19 @@ fn relate<R: TypeRelation<I>>(
|
||||
) -> RelateResult<I, ty::FnSig<I>> {
|
||||
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 @@ fn relate<R: TypeRelation<I>>(
|
||||
});
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
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 @@ pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
|
||||
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<I: Interner> {
|
||||
|
||||
impl<I: Interner> Eq for TypeAndMut<I> {}
|
||||
|
||||
/// 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<I: Interner> Eq for TypeAndMut<I> {}
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnSig<I: Interner> {
|
||||
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<I: Interner> Eq for FnSig<I> {}
|
||||
@@ -791,8 +886,37 @@ pub fn output(self) -> I::Ty {
|
||||
}
|
||||
|
||||
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 @@ pub fn output(self) -> ty::Binder<I, I::Ty> {
|
||||
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 @@ pub fn is_fn_trait_compatible(&self) -> bool {
|
||||
|
||||
// Used to split a single value into the two fields in `TyKind::FnPtr`.
|
||||
pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
|
||||
let hdr =
|
||||
FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
|
||||
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 @@ pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
|
||||
impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||
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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
write!(f, "{ty:?}")?;
|
||||
}
|
||||
if *c_variadic {
|
||||
if fn_sig_kind.c_variadic() {
|
||||
if inputs.is_empty() {
|
||||
write!(f, "...")?;
|
||||
} else {
|
||||
@@ -968,9 +1095,7 @@ impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
|
||||
pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
|
||||
self.map_bound(|sig_tys| FnSig {
|
||||
inputs_and_output: sig_tys.inputs_and_output,
|
||||
c_variadic: hdr.c_variadic,
|
||||
safety: hdr.safety,
|
||||
abi: hdr.abi,
|
||||
fn_sig_kind: hdr.fn_sig_kind,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1002,9 +1127,27 @@ pub fn output(self) -> ty::Binder<I, I::Ty> {
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnHeader<I: Interner> {
|
||||
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<I: Interner> FnHeader<I> {
|
||||
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<I: Interner> Eq for FnHeader<I> {}
|
||||
|
||||
@@ -307,9 +307,7 @@ pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>
|
||||
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<I: Interner> {
|
||||
// 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<I: Interner> Eq for CoroutineClosureSignature<I> {}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -103,7 +103,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
|
||||
&& 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()
|
||||
|
||||
@@ -64,7 +64,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
@@ -205,7 +205,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'
|
||||
&& 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()
|
||||
|
||||
@@ -54,7 +54,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
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 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
|
||||
check_for_is_empty(
|
||||
cx,
|
||||
sig.span,
|
||||
sig.decl.implicit_self,
|
||||
sig.decl.implicit_self(),
|
||||
output,
|
||||
ty_id,
|
||||
name,
|
||||
|
||||
@@ -411,7 +411,7 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet<LocalDefI
|
||||
fn non_elidable_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>, 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 visit_lifetime(&mut self, lifetime: &Lifetime) -> Self::Result {
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -5062,7 +5062,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::Impl
|
||||
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 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -321,7 +321,7 @@ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
|
||||
}) => (
|
||||
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 @@ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
|
||||
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)
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -376,7 +376,7 @@ fn check_default_new<'tcx>(
|
||||
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.
|
||||
|
||||
@@ -257,9 +257,9 @@ fn eq_fn_decl(&mut self, left: &FnDecl<'_>, right: &FnDecl<'_>) -> bool {
|
||||
(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 @@ pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {
|
||||
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 {
|
||||
|
||||
@@ -437,7 +437,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {
|
||||
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)
|
||||
|
||||
@@ -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 @@
|
||||
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(
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
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 @@ fn call_function(
|
||||
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())?;
|
||||
|
||||
|
||||
@@ -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 @@ fn check_shim_sig<'a, const N: usize>(
|
||||
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())?;
|
||||
|
||||
|
||||
@@ -164,13 +164,7 @@ pub(super) fn infer_closure(
|
||||
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 @@ fn extract_sig_from_projection(
|
||||
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 @@ fn extract_sig_from_projection_and_future_bound(
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -2358,6 +2358,22 @@ pub fn mk_fn_sig<I>(
|
||||
abi,
|
||||
}
|
||||
}
|
||||
|
||||
/// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
|
||||
pub fn mk_fn_sig_safe_rust_abi<I>(self, inputs: I, output: Ty<'db>) -> FnSig<'db>
|
||||
where
|
||||
I: IntoIterator<Item = Ty<'db>>,
|
||||
{
|
||||
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 {
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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<issue_60925::llvm::Foo>::foo::h4b3099ec5dc5d306)
|
||||
error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::hba5ac046b858f549)
|
||||
--> $DIR/issue-60925.rs:21:9
|
||||
|
|
||||
LL | #[rustc_dump_symbol_name]
|
||||
|
||||
Reference in New Issue
Block a user