Auto merge of #116520 - Enselic:large-copy-into-fn, r=oli-obk

large_assignments: Lint on specific large args passed to functions

Requires lowering function call arg spans down to MIR, which is done in the second commit.

Part of #83518

Also see
* https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/arg.20Spans.20for.20TerminatorKind.3A.3ACall.3F
* https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/move_size_limit.20lint

r? `@oli-obk` (E-mentor)
This commit is contained in:
bors 2024-01-16 19:33:14 +00:00
commit 92f2e0aa62
52 changed files with 379 additions and 210 deletions

View file

@ -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,