compiler: Lower fn call arg spans down to MIR

To enable improved accuracy of diagnostics in upcoming commits.
This commit is contained in:
Martin Nordholts 2024-01-12 08:21:42 +01:00
parent 18e12dcf6b
commit f40f996562
6 changed files with 77 additions and 72 deletions

View File

@ -11,6 +11,7 @@
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::FnAbiOf;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_target::abi::call::{Conv, FnAbi}; use rustc_target::abi::call::{Conv, FnAbi};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -360,7 +361,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
source_info: mir::SourceInfo, source_info: mir::SourceInfo,
func: &Operand<'tcx>, func: &Operand<'tcx>,
args: &[Operand<'tcx>], args: &[Spanned<Operand<'tcx>>],
destination: Place<'tcx>, destination: Place<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
) { ) {
@ -415,7 +416,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let extra_args = &args[fn_sig.inputs().skip_binder().len()..]; let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
let extra_args = fx.tcx.mk_type_list_from_iter( let extra_args = fx.tcx.mk_type_list_from_iter(
extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))), extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.node.ty(fx.mir, fx.tcx))),
); );
let fn_abi = if let Some(instance) = instance { let fn_abi = if let Some(instance) = instance {
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args) RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
@ -440,10 +441,10 @@ pub(crate) fn codegen_terminator_call<'tcx>(
// Unpack arguments tuple for closures // Unpack arguments tuple for closures
let mut args = if fn_sig.abi() == Abi::RustCall { let mut args = if fn_sig.abi() == Abi::RustCall {
let (self_arg, pack_arg) = match args { let (self_arg, pack_arg) = match args {
[pack_arg] => (None, codegen_call_argument_operand(fx, pack_arg)), [pack_arg] => (None, codegen_call_argument_operand(fx, &pack_arg.node)),
[self_arg, pack_arg] => ( [self_arg, pack_arg] => (
Some(codegen_call_argument_operand(fx, self_arg)), Some(codegen_call_argument_operand(fx, &self_arg.node)),
codegen_call_argument_operand(fx, pack_arg), codegen_call_argument_operand(fx, &pack_arg.node),
), ),
_ => panic!("rust-call abi requires one or two arguments"), _ => panic!("rust-call abi requires one or two arguments"),
}; };
@ -463,7 +464,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
} }
args args
} else { } else {
args.iter().map(|arg| codegen_call_argument_operand(fx, arg)).collect::<Vec<_>>() args.iter().map(|arg| codegen_call_argument_operand(fx, &arg.node)).collect::<Vec<_>>()
}; };
// Pass the caller location for `#[track_caller]`. // Pass the caller location for `#[track_caller]`.

View File

@ -7,7 +7,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str, intrinsic: &str,
generic_args: GenericArgsRef<'tcx>, generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
span: Span, span: Span,

View File

@ -7,7 +7,7 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str, intrinsic: &str,
_args: GenericArgsRef<'tcx>, _args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
) { ) {

View File

@ -11,7 +11,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str, intrinsic: &str,
_args: GenericArgsRef<'tcx>, _args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
span: Span, span: Span,
@ -175,9 +175,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
[x, y, kind] => (x, y, kind), [x, y, kind] => (x, y, kind),
_ => bug!("wrong number of args for intrinsic {intrinsic}"), _ => bug!("wrong number of args for intrinsic {intrinsic}"),
}; };
let x = codegen_operand(fx, x); let x = codegen_operand(fx, &x.node);
let y = codegen_operand(fx, y); let y = codegen_operand(fx, &y.node);
let kind = match kind { let kind = match &kind.node {
Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0, Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0,
Operand::Copy(_) | Operand::Move(_) => unreachable!("{kind:?}"), Operand::Copy(_) | Operand::Move(_) => unreachable!("{kind:?}"),
}; };
@ -287,8 +287,8 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
[a, b] => (a, b), [a, b] => (a, b),
_ => bug!("wrong number of args for intrinsic {intrinsic}"), _ => bug!("wrong number of args for intrinsic {intrinsic}"),
}; };
let a = codegen_operand(fx, a); let a = codegen_operand(fx, &a.node);
let b = codegen_operand(fx, b); let b = codegen_operand(fx, &b.node);
// Based on the pseudocode at https://github.com/rust-lang/stdarch/blob/1cfbca8b38fd9b4282b2f054f61c6ca69fc7ce29/crates/core_arch/src/x86/avx2.rs#L2319-L2332 // Based on the pseudocode at https://github.com/rust-lang/stdarch/blob/1cfbca8b38fd9b4282b2f054f61c6ca69fc7ce29/crates/core_arch/src/x86/avx2.rs#L2319-L2332
let zero = fx.bcx.ins().iconst(types::I8, 0); let zero = fx.bcx.ins().iconst(types::I8, 0);
@ -325,9 +325,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
[a, b, imm8] => (a, b, imm8), [a, b, imm8] => (a, b, imm8),
_ => bug!("wrong number of args for intrinsic {intrinsic}"), _ => bug!("wrong number of args for intrinsic {intrinsic}"),
}; };
let a = codegen_operand(fx, a); let a = codegen_operand(fx, &a.node);
let b = codegen_operand(fx, b); let b = codegen_operand(fx, &b.node);
let imm8 = codegen_operand(fx, imm8).load_scalar(fx); let imm8 = codegen_operand(fx, &imm8.node).load_scalar(fx);
let a_low = a.value_typed_lane(fx, fx.tcx.types.u128, 0).load_scalar(fx); let a_low = a.value_typed_lane(fx, fx.tcx.types.u128, 0).load_scalar(fx);
let a_high = a.value_typed_lane(fx, fx.tcx.types.u128, 1).load_scalar(fx); let a_high = a.value_typed_lane(fx, fx.tcx.types.u128, 1).load_scalar(fx);
@ -956,14 +956,14 @@ fn select4(
let b = b.load_scalar(fx); let b = b.load_scalar(fx);
let lb = lb.load_scalar(fx); let lb = lb.load_scalar(fx);
let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[4]) let imm8 =
{ if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[4].node) {
imm8 imm8
} else { } else {
fx.tcx fx.tcx
.dcx() .dcx()
.span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant"); .span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant");
}; };
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
@ -1009,14 +1009,14 @@ fn select4(
let b = b.load_scalar(fx); let b = b.load_scalar(fx);
let lb = lb.load_scalar(fx); let lb = lb.load_scalar(fx);
let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[4]) let imm8 =
{ if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[4].node) {
imm8 imm8
} else { } else {
fx.tcx fx.tcx
.dcx() .dcx()
.span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant"); .span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant");
}; };
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
@ -1056,15 +1056,15 @@ fn select4(
let a = a.load_scalar(fx); let a = a.load_scalar(fx);
let b = b.load_scalar(fx); let b = b.load_scalar(fx);
let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[2]) let imm8 =
{ if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[2].node) {
imm8 imm8
} else { } else {
fx.tcx.dcx().span_fatal( fx.tcx.dcx().span_fatal(
span, span,
"Index argument for `_mm_clmulepi64_si128` is not a constant", "Index argument for `_mm_clmulepi64_si128` is not a constant",
); );
}; };
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));
@ -1093,15 +1093,15 @@ fn select4(
let a = a.load_scalar(fx); let a = a.load_scalar(fx);
let imm8 = if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1]) let imm8 =
{ if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1].node) {
imm8 imm8
} else { } else {
fx.tcx.dcx().span_fatal( fx.tcx.dcx().span_fatal(
span, span,
"Index argument for `_mm_aeskeygenassist_si128` is not a constant", "Index argument for `_mm_aeskeygenassist_si128` is not a constant",
); );
}; };
let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8));

View File

@ -5,7 +5,7 @@ macro_rules! intrinsic_args {
($fx:expr, $args:expr => ($($arg:tt),*); $intrinsic:expr) => { ($fx:expr, $args:expr => ($($arg:tt),*); $intrinsic:expr) => {
#[allow(unused_parens)] #[allow(unused_parens)]
let ($($arg),*) = if let [$($arg),*] = $args { let ($($arg),*) = if let [$($arg),*] = $args {
($(codegen_operand($fx, $arg)),*) ($(codegen_operand($fx, &($arg).node)),*)
} else { } else {
$crate::intrinsics::bug_on_incorrect_arg_count($intrinsic); $crate::intrinsics::bug_on_incorrect_arg_count($intrinsic);
}; };
@ -22,6 +22,7 @@ macro_rules! intrinsic_args {
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement}; use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::GenericArgsRef;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
pub(crate) use self::llvm::codegen_llvm_intrinsic_call; pub(crate) use self::llvm::codegen_llvm_intrinsic_call;
@ -263,7 +264,7 @@ fn bool_to_zero_or_max_uint<'tcx>(
pub(crate) fn codegen_intrinsic_call<'tcx>( pub(crate) fn codegen_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
instance: Instance<'tcx>, instance: Instance<'tcx>,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
destination: CPlace<'tcx>, destination: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
source_info: mir::SourceInfo, source_info: mir::SourceInfo,
@ -301,7 +302,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
fn codegen_float_intrinsic_call<'tcx>( fn codegen_float_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: Symbol, intrinsic: Symbol,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
) -> bool { ) -> bool {
let (name, arg_count, ty, clif_ty) = match intrinsic { let (name, arg_count, ty, clif_ty) = match intrinsic {
@ -353,18 +354,21 @@ fn codegen_float_intrinsic_call<'tcx>(
let (a, b, c); let (a, b, c);
let args = match args { let args = match args {
[x] => { [x] => {
a = [codegen_operand(fx, x).load_scalar(fx)]; a = [codegen_operand(fx, &x.node).load_scalar(fx)];
&a as &[_] &a as &[_]
} }
[x, y] => { [x, y] => {
b = [codegen_operand(fx, x).load_scalar(fx), codegen_operand(fx, y).load_scalar(fx)]; b = [
codegen_operand(fx, &x.node).load_scalar(fx),
codegen_operand(fx, &y.node).load_scalar(fx),
];
&b &b
} }
[x, y, z] => { [x, y, z] => {
c = [ c = [
codegen_operand(fx, x).load_scalar(fx), codegen_operand(fx, &x.node).load_scalar(fx),
codegen_operand(fx, y).load_scalar(fx), codegen_operand(fx, &y.node).load_scalar(fx),
codegen_operand(fx, z).load_scalar(fx), codegen_operand(fx, &z.node).load_scalar(fx),
]; ];
&c &c
} }
@ -422,7 +426,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
instance: Instance<'tcx>, instance: Instance<'tcx>,
intrinsic: Symbol, intrinsic: Symbol,
generic_args: GenericArgsRef<'tcx>, generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
destination: Option<BasicBlock>, destination: Option<BasicBlock>,
source_info: mir::SourceInfo, source_info: mir::SourceInfo,

View File

@ -21,7 +21,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: Symbol, intrinsic: Symbol,
generic_args: GenericArgsRef<'tcx>, generic_args: GenericArgsRef<'tcx>,
args: &[mir::Operand<'tcx>], args: &[Spanned<mir::Operand<'tcx>>],
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
target: BasicBlock, target: BasicBlock,
span: Span, span: Span,
@ -121,8 +121,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let [x, y] = args else { let [x, y] = args else {
bug!("wrong number of args for intrinsic {intrinsic}"); bug!("wrong number of args for intrinsic {intrinsic}");
}; };
let x = codegen_operand(fx, x); let x = codegen_operand(fx, &x.node);
let y = codegen_operand(fx, y); let y = codegen_operand(fx, &y.node);
if !x.layout().ty.is_simd() { if !x.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty); report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty);
@ -172,8 +172,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
bug!("wrong number of args for intrinsic {intrinsic}"); bug!("wrong number of args for intrinsic {intrinsic}");
} }
}; };
let x = codegen_operand(fx, x); let x = codegen_operand(fx, &x.node);
let y = codegen_operand(fx, y); let y = codegen_operand(fx, &y.node);
if !x.layout().ty.is_simd() { if !x.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty); report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty);
@ -182,7 +182,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
// Make sure this is actually an array, since typeck only checks the length-suffixed // Make sure this is actually an array, since typeck only checks the length-suffixed
// version of this intrinsic. // version of this intrinsic.
let idx_ty = fx.monomorphize(idx.ty(fx.mir, fx.tcx)); let idx_ty = fx.monomorphize(idx.node.ty(fx.mir, fx.tcx));
let n: u16 = match idx_ty.kind() { let n: u16 = match idx_ty.kind() {
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => len
.try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all()) .try_eval_target_usize(fx.tcx, ty::ParamEnv::reveal_all())
@ -215,7 +215,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let indexes = { let indexes = {
use rustc_middle::mir::interpret::*; use rustc_middle::mir::interpret::*;
let idx_const = match idx { let idx_const = match &idx.node {
Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0, Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0,
Operand::Copy(_) | Operand::Move(_) => unreachable!("{idx:?}"), Operand::Copy(_) | Operand::Move(_) => unreachable!("{idx:?}"),
}; };
@ -269,12 +269,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
bug!("wrong number of args for intrinsic {intrinsic}"); bug!("wrong number of args for intrinsic {intrinsic}");
} }
}; };
let base = codegen_operand(fx, base); let base = codegen_operand(fx, &base.node);
let val = codegen_operand(fx, val); let val = codegen_operand(fx, &val.node);
// FIXME validate // FIXME validate
let idx_const = if let Some(idx_const) = let idx_const = if let Some(idx_const) =
crate::constant::mir_operand_get_const_val(fx, idx) crate::constant::mir_operand_get_const_val(fx, &idx.node)
{ {
idx_const idx_const
} else { } else {
@ -304,7 +304,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
bug!("wrong number of args for intrinsic {intrinsic}"); bug!("wrong number of args for intrinsic {intrinsic}");
} }
}; };
let v = codegen_operand(fx, v); let v = codegen_operand(fx, &v.node);
if !v.layout().ty.is_simd() { if !v.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, v.layout().ty); report_simd_type_validation_error(fx, intrinsic, span, v.layout().ty);
@ -312,7 +312,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
} }
let idx_const = if let Some(idx_const) = let idx_const = if let Some(idx_const) =
crate::constant::mir_operand_get_const_val(fx, idx) crate::constant::mir_operand_get_const_val(fx, &idx.node)
{ {
idx_const idx_const
} else { } else {