Skip to content

Commit 0275b6f

Browse files
committed
compiler: Lower fn call arg spans down to MIR
To enable improved accuracy of diagnostics in upcoming commits.
1 parent 57ef889 commit 0275b6f

File tree

37 files changed

+178
-93
lines changed

37 files changed

+178
-93
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_middle::util::CallKind;
2323
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
2424
use rustc_span::def_id::LocalDefId;
2525
use rustc_span::hygiene::DesugaringKind;
26+
use rustc_span::source_map::Spanned;
2627
use rustc_span::symbol::{kw, sym, Ident};
2728
use rustc_span::{BytePos, Span, Symbol};
2829
use rustc_trait_selection::infer::InferCtxtExt;
@@ -1247,7 +1248,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12471248
return None;
12481249
};
12491250
debug!("checking call args for uses of inner_param: {:?}", args);
1250-
args.contains(&Operand::Move(inner_param)).then_some((loc, term))
1251+
args.iter()
1252+
.map(|a| &a.node)
1253+
.any(|a| a == &Operand::Move(inner_param))
1254+
.then_some((loc, term))
12511255
})
12521256
else {
12531257
debug!("no uses of inner_param found as a by-move call arg");
@@ -3172,7 +3176,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
31723176
assigned_to, args
31733177
);
31743178
for operand in args {
3175-
let (Operand::Copy(assigned_from) | Operand::Move(assigned_from)) = operand
3179+
let Spanned {
3180+
node: Operand::Copy(assigned_from) | Operand::Move(assigned_from),
3181+
..
3182+
} = operand
31763183
else {
31773184
continue;
31783185
};

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
635635
);
636636
// Check if one of the arguments to this function is the target place.
637637
let found_target = args.iter().any(|arg| {
638-
if let Operand::Move(place) = arg {
638+
if let Operand::Move(place) = arg.node {
639639
if let Some(potential) = place.as_local() {
640640
potential == target
641641
} else {

compiler/rustc_borrowck/src/diagnostics/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
2222
use rustc_middle::util::{call_kind, CallDesugaringKind};
2323
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult};
2424
use rustc_span::def_id::LocalDefId;
25+
use rustc_span::source_map::Spanned;
2526
use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
2627
use rustc_target::abi::{FieldIdx, VariantIdx};
2728
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -110,9 +111,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
110111
debug!("add_moved_or_invoked_closure_note: id={:?}", id);
111112
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
112113
let closure = match args.first() {
113-
Some(Operand::Copy(place) | Operand::Move(place))
114-
if target == place.local_or_deref_local() =>
115-
{
114+
Some(Spanned {
115+
node: Operand::Copy(place) | Operand::Move(place), ..
116+
}) if target == place.local_or_deref_local() => {
116117
place.local_or_deref_local().unwrap()
117118
}
118119
_ => return false,

compiler/rustc_borrowck/src/invalidation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
133133
} => {
134134
self.consume_operand(location, func);
135135
for arg in args {
136-
self.consume_operand(location, arg);
136+
self.consume_operand(location, &arg.node);
137137
}
138138
self.mutate_place(location, *destination, Deep);
139139
}

compiler/rustc_borrowck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
715715
} => {
716716
self.consume_operand(loc, (func, span), flow_state);
717717
for arg in args {
718-
self.consume_operand(loc, (arg, span), flow_state);
718+
self.consume_operand(loc, (&arg.node, arg.span), flow_state);
719719
}
720720
self.mutate_place(loc, (*destination, span), Deep, flow_state);
721721
}

compiler/rustc_borrowck/src/type_check/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_middle::ty::{
3838
};
3939
use rustc_middle::ty::{GenericArgsRef, UserArgs};
4040
use rustc_span::def_id::CRATE_DEF_ID;
41+
use rustc_span::source_map::Spanned;
4142
use rustc_span::symbol::sym;
4243
use rustc_span::{Span, DUMMY_SP};
4344
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
@@ -1372,7 +1373,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13721373
TerminatorKind::Call { func, args, destination, call_source, target, .. } => {
13731374
self.check_operand(func, term_location);
13741375
for arg in args {
1375-
self.check_operand(arg, term_location);
1376+
self.check_operand(&arg.node, term_location);
13761377
}
13771378

13781379
let func_ty = func.ty(body, tcx);
@@ -1571,7 +1572,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15711572
term: &Terminator<'tcx>,
15721573
func: &Operand<'tcx>,
15731574
sig: &ty::FnSig<'tcx>,
1574-
args: &[Operand<'tcx>],
1575+
args: &[Spanned<Operand<'tcx>>],
15751576
term_location: Location,
15761577
call_source: CallSource,
15771578
) {
@@ -1584,7 +1585,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15841585
if self.tcx().is_intrinsic(def_id) {
15851586
match self.tcx().item_name(def_id) {
15861587
sym::simd_shuffle => {
1587-
if !matches!(args[2], Operand::Constant(_)) {
1588+
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
15881589
self.tcx()
15891590
.sess
15901591
.emit_err(SimdShuffleLastConst { span: term.source_info.span });
@@ -1597,7 +1598,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15971598
debug!(?func_ty);
15981599

15991600
for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() {
1600-
let op_arg_ty = op_arg.ty(body, self.tcx());
1601+
let op_arg_ty = op_arg.node.ty(body, self.tcx());
16011602

16021603
let op_arg_ty = self.normalize(op_arg_ty, term_location);
16031604
let category = if call_source.from_hir_call() {

compiler/rustc_codegen_ssa/src/mir/block.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1717
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
1818
use rustc_middle::ty::{self, Instance, Ty};
1919
use rustc_session::config::OptLevel;
20-
use rustc_span::source_map::Span;
20+
use rustc_span::source_map::{Span, Spanned};
2121
use rustc_span::{sym, Symbol};
2222
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
2323
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
@@ -743,7 +743,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
743743
bx: &mut Bx,
744744
terminator: &mir::Terminator<'tcx>,
745745
func: &mir::Operand<'tcx>,
746-
args: &[mir::Operand<'tcx>],
746+
args: &[Spanned<mir::Operand<'tcx>>],
747747
destination: mir::Place<'tcx>,
748748
target: Option<mir::BasicBlock>,
749749
unwind: mir::UnwindAction,
@@ -794,7 +794,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
794794

795795
let extra_args = &args[sig.inputs().skip_binder().len()..];
796796
let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| {
797-
let op_ty = op_arg.ty(self.mir, bx.tcx());
797+
let op_ty = op_arg.node.ty(self.mir, bx.tcx());
798798
self.monomorphize(op_ty)
799799
}));
800800

@@ -864,7 +864,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
864864
// checked by const-qualification, which also
865865
// promotes any complex rvalues to constants.
866866
if i == 2 && intrinsic == sym::simd_shuffle {
867-
if let mir::Operand::Constant(constant) = arg {
867+
if let Spanned { node: mir::Operand::Constant(constant), .. } = arg {
868868
let (llval, ty) = self.simd_shuffle_indices(&bx, constant);
869869
return OperandRef {
870870
val: Immediate(llval),
@@ -875,7 +875,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
875875
}
876876
}
877877

878-
self.codegen_operand(bx, arg)
878+
self.codegen_operand(bx, &arg.node)
879879
})
880880
.collect();
881881

@@ -911,7 +911,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
911911

912912
let mut copied_constant_arguments = vec![];
913913
'make_args: for (i, arg) in first_args.iter().enumerate() {
914-
let mut op = self.codegen_operand(bx, arg);
914+
let mut op = self.codegen_operand(bx, &arg.node);
915915

916916
if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
917917
match op.val {
@@ -989,7 +989,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
989989

990990
// The callee needs to own the argument memory if we pass it
991991
// by-ref, so make a local copy of non-immediate constants.
992-
match (arg, op.val) {
992+
match (&arg.node, op.val) {
993993
(&mir::Operand::Copy(_), Ref(_, None, _))
994994
| (&mir::Operand::Constant(_), Ref(_, None, _)) => {
995995
let tmp = PlaceRef::alloca(bx, op.layout);
@@ -1004,7 +1004,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10041004
self.codegen_argument(bx, op, &mut llargs, &fn_abi.args[i]);
10051005
}
10061006
let num_untupled = untuple.map(|tup| {
1007-
self.codegen_arguments_untupled(bx, tup, &mut llargs, &fn_abi.args[first_args.len()..])
1007+
self.codegen_arguments_untupled(
1008+
bx,
1009+
&tup.node,
1010+
&mut llargs,
1011+
&fn_abi.args[first_args.len()..],
1012+
)
10081013
});
10091014

10101015
let needs_location =

compiler/rustc_const_eval/src/interpret/terminator.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::{
1010
AdtDef, Instance, Ty,
1111
},
1212
};
13-
use rustc_span::sym;
13+
use rustc_span::{source_map::Spanned, sym};
1414
use rustc_target::abi::{self, FieldIdx};
1515
use rustc_target::abi::{
1616
call::{ArgAbi, FnAbi, PassMode},
@@ -243,13 +243,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
243243
/// Evaluate the arguments of a function call
244244
pub(super) fn eval_fn_call_arguments(
245245
&self,
246-
ops: &[mir::Operand<'tcx>],
246+
ops: &[Spanned<mir::Operand<'tcx>>],
247247
) -> InterpResult<'tcx, Vec<FnArg<'tcx, M::Provenance>>> {
248248
ops.iter()
249249
.map(|op| {
250-
Ok(match op {
250+
Ok(match &op.node {
251251
mir::Operand::Move(place) => FnArg::InPlace(self.eval_place(*place)?),
252-
_ => FnArg::Copy(self.eval_operand(op, None)?),
252+
_ => FnArg::Copy(self.eval_operand(&op.node, None)?),
253253
})
254254
})
255255
.collect()

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -893,15 +893,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
893893

894894
// const-eval of the `begin_panic` fn assumes the argument is `&str`
895895
if Some(callee) == tcx.lang_items().begin_panic_fn() {
896-
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
896+
match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
897897
ty::Ref(_, ty, _) if ty.is_str() => return,
898898
_ => self.check_op(ops::PanicNonStr),
899899
}
900900
}
901901

902902
// const-eval of `#[rustc_const_panic_str]` functions assumes the argument is `&&str`
903903
if tcx.has_attr(callee, sym::rustc_const_panic_str) {
904-
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
904+
match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
905905
ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
906906
{
907907
return;

compiler/rustc_const_eval/src/transform/promote_consts.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt};
2121
use rustc_span::Span;
2222

2323
use rustc_index::{Idx, IndexSlice, IndexVec};
24+
use rustc_span::source_map::Spanned;
2425

2526
use std::cell::Cell;
2627
use std::{cmp, iter, mem};
@@ -638,7 +639,7 @@ impl<'tcx> Validator<'_, 'tcx> {
638639
fn validate_call(
639640
&mut self,
640641
callee: &Operand<'tcx>,
641-
args: &[Operand<'tcx>],
642+
args: &[Spanned<Operand<'tcx>>],
642643
) -> Result<(), Unpromotable> {
643644
let fn_ty = callee.ty(self.body, self.tcx);
644645

@@ -668,7 +669,7 @@ impl<'tcx> Validator<'_, 'tcx> {
668669

669670
self.validate_operand(callee)?;
670671
for arg in args {
671-
self.validate_operand(arg)?;
672+
self.validate_operand(&arg.node)?;
672673
}
673674

674675
Ok(())
@@ -804,7 +805,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
804805
} => {
805806
self.visit_operand(&mut func, loc);
806807
for arg in &mut args {
807-
self.visit_operand(arg, loc);
808+
self.visit_operand(&mut arg.node, loc);
808809
}
809810

810811
let last = self.promoted.basic_blocks.last_index().unwrap();

compiler/rustc_const_eval/src/transform/validate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
442442
}
443443
let mut has_duplicates = false;
444444
for arg in args {
445-
if let Operand::Move(place) = arg {
445+
if let Operand::Move(place) = &arg.node {
446446
has_duplicates |= !self.place_cache.insert(place.as_ref());
447447
if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() {
448448
// This is bad! The callee will expect the memory to be aligned.

compiler/rustc_middle/src/mir/syntax.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_hir::def_id::DefId;
1717
use rustc_hir::{self as hir};
1818
use rustc_hir::{self, GeneratorKind};
1919
use rustc_index::IndexVec;
20+
use rustc_span::source_map::Spanned;
2021
use rustc_target::abi::{FieldIdx, VariantIdx};
2122

2223
use rustc_ast::Mutability;
@@ -670,7 +671,9 @@ pub enum TerminatorKind<'tcx> {
670671
/// These are owned by the callee, which is free to modify them.
671672
/// This allows the memory occupied by "by-value" arguments to be
672673
/// reused across function calls without duplicating the contents.
673-
args: Vec<Operand<'tcx>>,
674+
/// The span for each arg is also included
675+
/// (e.g. `a` and `b` in `x.foo(a, b)`).
676+
args: Vec<Spanned<Operand<'tcx>>>,
674677
/// Where the returned value will be written
675678
destination: Place<'tcx>,
676679
/// Where to go after this call returns. If none, the call necessarily diverges.

compiler/rustc_middle/src/mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ macro_rules! make_mir_visitor {
526526
} => {
527527
self.visit_operand(func, location);
528528
for arg in args {
529-
self.visit_operand(arg, location);
529+
self.visit_operand(&$($mutability)? arg.node, location);
530530
}
531531
self.visit_place(
532532
destination,

compiler/rustc_middle/src/ty/structural_impls.rs

+20
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
99
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
1010
use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
1111
use rustc_hir::def::Namespace;
12+
use rustc_span::source_map::Spanned;
1213
use rustc_target::abi::TyAndLayout;
1314
use rustc_type_ir::{ConstKind, DebugWithInfcx, InferCtxtLike, OptWithInfcx};
1415

@@ -897,3 +898,22 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
897898
visitor.visit_ty(self.ty)
898899
}
899900
}
901+
902+
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>> + Debug + Clone> TypeVisitable<TyCtxt<'tcx>>
903+
for Spanned<T>
904+
{
905+
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
906+
self.node.visit_with(visitor)
907+
}
908+
}
909+
910+
impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Debug + Clone> TypeFoldable<TyCtxt<'tcx>>
911+
for Spanned<T>
912+
{
913+
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
914+
self,
915+
folder: &mut F,
916+
) -> Result<Self, F::Error> {
917+
Ok(Spanned { node: self.node.try_fold_with(folder)?, span: self.span })
918+
}
919+
}

compiler/rustc_middle/src/util/find_self_call.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::mir::*;
22
use crate::ty::GenericArgsRef;
33
use crate::ty::{self, TyCtxt};
44
use rustc_span::def_id::DefId;
5+
use rustc_span::source_map::Spanned;
56

67
/// Checks if the specified `local` is used as the `self` parameter of a method call
78
/// in the provided `BasicBlock`. If it is, then the `DefId` of the called method is
@@ -23,7 +24,13 @@ pub fn find_self_call<'tcx>(
2324
tcx.opt_associated_item(def_id)
2425
{
2526
debug!("find_self_call: args={:?}", fn_args);
26-
if let [Operand::Move(self_place) | Operand::Copy(self_place), ..] = **args {
27+
if let [
28+
Spanned {
29+
node: Operand::Move(self_place) | Operand::Copy(self_place), ..
30+
},
31+
..,
32+
] = **args
33+
{
2734
if self_place.as_local() == Some(local) {
2835
return Some((def_id, fn_args));
2936
}

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_middle::mir::interpret::Scalar;
22
use rustc_middle::mir::tcx::PlaceTy;
33
use rustc_middle::ty::cast::mir_cast_kind;
44
use rustc_middle::{mir::*, thir::*, ty};
5+
use rustc_span::source_map::Spanned;
56
use rustc_span::Span;
67
use rustc_target::abi::{FieldIdx, VariantIdx};
78

@@ -119,7 +120,10 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
119120
let fun = self.parse_operand(*fun)?;
120121
let args = args
121122
.iter()
122-
.map(|arg| self.parse_operand(*arg))
123+
.map(|arg| match self.parse_operand(*arg) {
124+
Ok(node) => Ok(Spanned { node, span: self.thir.exprs[*arg].span }),
125+
Err(e) => Err(e),
126+
})
123127
.collect::<PResult<Vec<_>>>()?;
124128
Ok(TerminatorKind::Call {
125129
func: fun,

0 commit comments

Comments
 (0)