compiler: Lower fn call arg spans down to MIR
To enable improved accuracy of diagnostics in upcoming commits.
This commit is contained in:
parent
924ea05103
commit
16ba56c242
47 changed files with 221 additions and 170 deletions
|
@ -675,9 +675,9 @@ fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local
|
|||
let terminator = bb_data.terminator.take().unwrap();
|
||||
if let TerminatorKind::Call { mut args, destination, target, .. } = terminator.kind {
|
||||
let arg = args.pop().unwrap();
|
||||
let local = arg.place().unwrap().local;
|
||||
let local = arg.node.place().unwrap().local;
|
||||
|
||||
let arg = Rvalue::Use(arg);
|
||||
let arg = Rvalue::Use(arg.node);
|
||||
let assign = Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((destination, arg))),
|
||||
|
@ -1865,7 +1865,7 @@ impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> {
|
|||
self.check_assigned_place(*destination, |this| {
|
||||
this.visit_operand(func, location);
|
||||
for arg in args {
|
||||
this.visit_operand(arg, location);
|
||||
this.visit_operand(&arg.node, location);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
live.seek_to_block_end(bb);
|
||||
let mut state = live.get().clone();
|
||||
|
||||
for (index, arg) in args.iter().enumerate().rev() {
|
||||
for (index, arg) in args.iter().map(|a| &a.node).enumerate().rev() {
|
||||
if let Operand::Copy(place) = *arg
|
||||
&& !place.is_indirect()
|
||||
// Do not skip the transformation if the local is in debuginfo, as we do
|
||||
|
@ -119,7 +119,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
let TerminatorKind::Call { ref mut args, .. } = bbs[block].terminator_mut().kind else {
|
||||
bug!()
|
||||
};
|
||||
let arg = &mut args[argument_index];
|
||||
let arg = &mut args[argument_index].node;
|
||||
let Operand::Copy(place) = *arg else { bug!() };
|
||||
*arg = Operand::Move(place);
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
|
|||
|
||||
if let TerminatorKind::Call { ref args, .. } = terminator.kind {
|
||||
for arg in args {
|
||||
if let Operand::Move(place) = *arg {
|
||||
if let Operand::Move(place) = arg.node {
|
||||
let local = place.local;
|
||||
if place.is_indirect()
|
||||
|| local == RETURN_PLACE
|
||||
|
|
|
@ -609,7 +609,7 @@ impl WriteInfo {
|
|||
self.add_place(*destination);
|
||||
self.add_operand(func);
|
||||
for arg in args {
|
||||
self.add_operand(arg);
|
||||
self.add_operand(&arg.node);
|
||||
}
|
||||
}
|
||||
TerminatorKind::InlineAsm { operands, .. } => {
|
||||
|
|
|
@ -4,6 +4,7 @@ use rustc_middle::mir::visit::Visitor;
|
|||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt};
|
||||
use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{symbol::sym, Span};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
|
@ -43,7 +44,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
|
|||
if let ty::FnDef(def_id, args_ref) = *func_ty.kind() {
|
||||
// Handle calls to `transmute`
|
||||
if self.tcx.is_diagnostic_item(sym::transmute, def_id) {
|
||||
let arg_ty = args[0].ty(self.body, self.tcx);
|
||||
let arg_ty = args[0].node.ty(self.body, self.tcx);
|
||||
for inner_ty in arg_ty.walk().filter_map(|arg| arg.as_type()) {
|
||||
if let Some((fn_id, fn_args)) = FunctionItemRefChecker::is_fn_ref(inner_ty)
|
||||
{
|
||||
|
@ -67,7 +68,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
|
|||
&self,
|
||||
def_id: DefId,
|
||||
args_ref: GenericArgsRef<'tcx>,
|
||||
args: &[Operand<'tcx>],
|
||||
args: &[Spanned<Operand<'tcx>>],
|
||||
source_info: SourceInfo,
|
||||
) {
|
||||
let param_env = self.tcx.param_env(def_id);
|
||||
|
@ -134,8 +135,8 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
|
|||
.unwrap_or(None)
|
||||
}
|
||||
|
||||
fn nth_arg_span(&self, args: &[Operand<'tcx>], n: usize) -> Span {
|
||||
match &args[n] {
|
||||
fn nth_arg_span(&self, args: &[Spanned<Operand<'tcx>>], n: usize) -> Span {
|
||||
match &args[n].node {
|
||||
Operand::Copy(place) | Operand::Move(place) => {
|
||||
self.body.local_decls[place.local].source_info.span
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use rustc_middle::mir::*;
|
|||
use rustc_middle::ty::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
|
||||
use rustc_session::config::OptLevel;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
|
@ -172,7 +173,7 @@ impl<'tcx> Inliner<'tcx> {
|
|||
let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() };
|
||||
let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty;
|
||||
for arg in args {
|
||||
if !arg.ty(&caller_body.local_decls, self.tcx).is_sized(self.tcx, self.param_env) {
|
||||
if !arg.node.ty(&caller_body.local_decls, self.tcx).is_sized(self.tcx, self.param_env) {
|
||||
// We do not allow inlining functions with unsized params. Inlining these functions
|
||||
// could create unsized locals, which are unsound and being phased out.
|
||||
return Err("Call has unsized argument");
|
||||
|
@ -238,9 +239,9 @@ impl<'tcx> Inliner<'tcx> {
|
|||
};
|
||||
|
||||
let self_arg_ty =
|
||||
self_arg.map(|self_arg| self_arg.ty(&caller_body.local_decls, self.tcx));
|
||||
self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, self.tcx));
|
||||
|
||||
let arg_tuple_ty = arg_tuple.ty(&caller_body.local_decls, self.tcx);
|
||||
let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, self.tcx);
|
||||
let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
|
||||
bug!("Closure arguments are not passed as a tuple");
|
||||
};
|
||||
|
@ -263,7 +264,7 @@ impl<'tcx> Inliner<'tcx> {
|
|||
} else {
|
||||
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
|
||||
let input_type = callee_body.local_decls[input].ty;
|
||||
let arg_ty = arg.ty(&caller_body.local_decls, self.tcx);
|
||||
let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
|
||||
if !util::relate_types(
|
||||
self.tcx,
|
||||
self.param_env,
|
||||
|
@ -694,7 +695,7 @@ impl<'tcx> Inliner<'tcx> {
|
|||
|
||||
fn make_call_args(
|
||||
&self,
|
||||
args: Vec<Operand<'tcx>>,
|
||||
args: Vec<Spanned<Operand<'tcx>>>,
|
||||
callsite: &CallSite<'tcx>,
|
||||
caller_body: &mut Body<'tcx>,
|
||||
callee_body: &Body<'tcx>,
|
||||
|
@ -728,13 +729,13 @@ impl<'tcx> Inliner<'tcx> {
|
|||
if callsite.fn_sig.abi() == Abi::RustCall && callee_body.spread_arg.is_none() {
|
||||
let mut args = args.into_iter();
|
||||
let self_ = self.create_temp_if_necessary(
|
||||
args.next().unwrap(),
|
||||
args.next().unwrap().node,
|
||||
callsite,
|
||||
caller_body,
|
||||
return_block,
|
||||
);
|
||||
let tuple = self.create_temp_if_necessary(
|
||||
args.next().unwrap(),
|
||||
args.next().unwrap().node,
|
||||
callsite,
|
||||
caller_body,
|
||||
return_block,
|
||||
|
@ -761,7 +762,7 @@ impl<'tcx> Inliner<'tcx> {
|
|||
closure_ref_arg.chain(tuple_tmp_args).collect()
|
||||
} else {
|
||||
args.into_iter()
|
||||
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body, return_block))
|
||||
.map(|a| self.create_temp_if_necessary(a.node, callsite, caller_body, return_block))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
|
||||
// These types are easily available from locals, so check that before
|
||||
// doing DefId lookups to figure out what we're actually calling.
|
||||
let arg_ty = args[0].ty(self.local_decls, self.tcx);
|
||||
let arg_ty = args[0].node.ty(self.local_decls, self.tcx);
|
||||
|
||||
let ty::Ref(_region, inner_ty, Mutability::Not) = *arg_ty.kind() else { return };
|
||||
|
||||
|
@ -238,7 +238,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
|
|||
return;
|
||||
}
|
||||
|
||||
let Some(arg_place) = args.pop().unwrap().place() else { return };
|
||||
let Some(arg_place) = args.pop().unwrap().node.place() else { return };
|
||||
|
||||
statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
|
|
|
@ -41,7 +41,7 @@ use rustc_middle::mir::{
|
|||
};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::sym;
|
||||
use rustc_span::{source_map::Spanned, sym, DUMMY_SP};
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
#[macro_use]
|
||||
|
@ -170,13 +170,13 @@ fn remap_mir_for_const_eval_select<'tcx>(
|
|||
{
|
||||
let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
|
||||
std::mem::take(args).try_into().unwrap();
|
||||
let ty = tupled_args.ty(&body.local_decls, tcx);
|
||||
let ty = tupled_args.node.ty(&body.local_decls, tcx);
|
||||
let fields = ty.tuple_fields();
|
||||
let num_args = fields.len();
|
||||
let func =
|
||||
if context == hir::Constness::Const { called_in_const } else { called_at_rt };
|
||||
let (method, place): (fn(Place<'tcx>) -> Operand<'tcx>, Place<'tcx>) =
|
||||
match tupled_args {
|
||||
match tupled_args.node {
|
||||
Operand::Constant(_) => {
|
||||
// there is no good way of extracting a tuple arg from a constant (const generic stuff)
|
||||
// so we just create a temporary and deconstruct that.
|
||||
|
@ -185,7 +185,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
|
|||
source_info: SourceInfo::outermost(fn_span),
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
local.into(),
|
||||
Rvalue::Use(tupled_args.clone()),
|
||||
Rvalue::Use(tupled_args.node.clone()),
|
||||
))),
|
||||
});
|
||||
(Operand::Move, local.into())
|
||||
|
@ -200,11 +200,11 @@ fn remap_mir_for_const_eval_select<'tcx>(
|
|||
place_elems.push(ProjectionElem::Field(x.into(), fields[x]));
|
||||
let projection = tcx.mk_place_elems(&place_elems);
|
||||
let place = Place { local: place.local, projection };
|
||||
method(place)
|
||||
Spanned { node: method(place), span: DUMMY_SP }
|
||||
})
|
||||
.collect();
|
||||
terminator.kind = TerminatorKind::Call {
|
||||
func,
|
||||
func: func.node,
|
||||
args: arguments,
|
||||
destination,
|
||||
target,
|
||||
|
|
|
@ -131,7 +131,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Lint<'a, 'tcx> {
|
|||
self.places.insert(destination.as_ref());
|
||||
let mut has_duplicates = false;
|
||||
for arg in args {
|
||||
if let Operand::Move(place) = arg {
|
||||
if let Operand::Move(place) = &arg.node {
|
||||
has_duplicates |= !self.places.insert(place.as_ref());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,9 +45,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
kind: StatementKind::Intrinsic(Box::new(
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(
|
||||
rustc_middle::mir::CopyNonOverlapping {
|
||||
src: args.next().unwrap(),
|
||||
dst: args.next().unwrap(),
|
||||
count: args.next().unwrap(),
|
||||
src: args.next().unwrap().node,
|
||||
dst: args.next().unwrap().node,
|
||||
count: args.next().unwrap().node,
|
||||
},
|
||||
),
|
||||
)),
|
||||
|
@ -66,7 +66,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Intrinsic(Box::new(
|
||||
NonDivergingIntrinsic::Assume(args.next().unwrap()),
|
||||
NonDivergingIntrinsic::Assume(args.next().unwrap().node),
|
||||
)),
|
||||
});
|
||||
assert_eq!(
|
||||
|
@ -112,7 +112,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs, rhs))),
|
||||
Rvalue::BinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
|
@ -136,7 +136,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::CheckedBinaryOp(bin_op, Box::new((lhs, rhs))),
|
||||
Rvalue::CheckedBinaryOp(bin_op, Box::new((lhs.node, rhs.node))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
|
@ -164,7 +164,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
let [arg] = args.as_slice() else {
|
||||
span_bug!(terminator.source_info.span, "Wrong number of arguments");
|
||||
};
|
||||
let derefed_place = if let Some(place) = arg.place()
|
||||
let derefed_place = if let Some(place) = arg.node.place()
|
||||
&& let Some(local) = place.as_local()
|
||||
{
|
||||
tcx.mk_place_deref(local.into())
|
||||
|
@ -200,7 +200,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
"Wrong number of arguments for write_via_move intrinsic",
|
||||
);
|
||||
};
|
||||
let derefed_place = if let Some(place) = ptr.place()
|
||||
let derefed_place = if let Some(place) = ptr.node.place()
|
||||
&& let Some(local) = place.as_local()
|
||||
{
|
||||
tcx.mk_place_deref(local.into())
|
||||
|
@ -214,13 +214,13 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
derefed_place,
|
||||
Rvalue::Use(val),
|
||||
Rvalue::Use(val.node),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
}
|
||||
sym::discriminant_value => {
|
||||
if let (Some(target), Some(arg)) = (*target, args[0].place()) {
|
||||
if let (Some(target), Some(arg)) = (*target, args[0].node.place()) {
|
||||
let arg = tcx.mk_place_deref(arg);
|
||||
block.statements.push(Statement {
|
||||
source_info: terminator.source_info,
|
||||
|
@ -244,7 +244,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, delta))),
|
||||
Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr.node, delta.node))),
|
||||
))),
|
||||
});
|
||||
terminator.kind = TerminatorKind::Goto { target };
|
||||
|
@ -265,7 +265,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
|||
source_info: terminator.source_info,
|
||||
kind: StatementKind::Assign(Box::new((
|
||||
*destination,
|
||||
Rvalue::Cast(CastKind::Transmute, arg, dst_ty),
|
||||
Rvalue::Cast(CastKind::Transmute, arg.node, dst_ty),
|
||||
))),
|
||||
});
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ fn lower_slice_len_call<'tcx>(
|
|||
} = &terminator.kind
|
||||
// some heuristics for fast rejection
|
||||
&& let [arg] = &args[..]
|
||||
&& let Some(arg) = arg.place()
|
||||
&& let Some(arg) = arg.node.place()
|
||||
&& let ty::FnDef(fn_def_id, _) = func.ty(local_decls, tcx).kind()
|
||||
&& *fn_def_id == slice_len_fn_item_def_id
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@ use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
|
|||
use rustc_span::Span;
|
||||
|
||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::cell::Cell;
|
||||
|
@ -565,7 +566,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
fn validate_call(
|
||||
&mut self,
|
||||
callee: &Operand<'tcx>,
|
||||
args: &[Operand<'tcx>],
|
||||
args: &[Spanned<Operand<'tcx>>],
|
||||
) -> Result<(), Unpromotable> {
|
||||
let fn_ty = callee.ty(self.body, self.tcx);
|
||||
|
||||
|
@ -595,7 +596,7 @@ impl<'tcx> Validator<'_, 'tcx> {
|
|||
|
||||
self.validate_operand(callee)?;
|
||||
for arg in args {
|
||||
self.validate_operand(arg)?;
|
||||
self.validate_operand(&arg.node)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -731,7 +732,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
} => {
|
||||
self.visit_operand(&mut func, loc);
|
||||
for arg in &mut args {
|
||||
self.visit_operand(arg, loc);
|
||||
self.visit_operand(&mut arg.node, loc);
|
||||
}
|
||||
|
||||
let last = self.promoted.basic_blocks.last_index().unwrap();
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
|
|||
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{source_map::Spanned, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use std::fmt;
|
||||
|
@ -526,7 +526,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
|
|||
vec![statement],
|
||||
TerminatorKind::Call {
|
||||
func,
|
||||
args: vec![Operand::Move(ref_loc)],
|
||||
args: vec![Spanned { node: Operand::Move(ref_loc), span: DUMMY_SP }],
|
||||
destination: dest,
|
||||
target: Some(next),
|
||||
unwind: UnwindAction::Cleanup(cleanup),
|
||||
|
@ -811,6 +811,7 @@ fn build_call_shim<'tcx>(
|
|||
};
|
||||
|
||||
// BB #0
|
||||
let args = args.into_iter().map(|a| Spanned { node: a, span: DUMMY_SP }).collect::<Vec<_>>();
|
||||
block(
|
||||
&mut blocks,
|
||||
statements,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue