From 9792179648abb7bf38a9e54191cfe5a25436b8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 19 Jun 2021 00:00:00 +0000 Subject: [PATCH] Add flag to configure `large_assignments` lint The `large_assignments` lints detects moves over specified limit. The limit is configured through `move_size_limit = "N"` attribute placed at the root of a crate. When attribute is absent, the lint is disabled. Make it possible to enable the lint without making any changes to the source code, through a new flag `-Zmove-size-limit=N`. For example, to detect moves exceeding 1023 bytes in a cargo crate, including all dependencies one could use: ``` $ env RUSTFLAGS=-Zmove-size-limit=1024 cargo build -vv ``` --- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_middle/src/middle/limits.rs | 7 +++- compiler/rustc_session/src/options.rs | 2 + .../src/compiler-flags/move-size-limit.md | 10 +++++ ...es.stderr => large_moves.attribute.stderr} | 8 ++-- .../ui/async-await/large_moves.option.stderr | 38 +++++++++++++++++++ src/test/ui/async-await/large_moves.rs | 4 +- 7 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/move-size-limit.md rename src/test/ui/async-await/{large_moves.stderr => large_moves.attribute.stderr} (88%) create mode 100644 src/test/ui/async-await/large_moves.option.stderr diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index b252409a92ada..76dc31d187678 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -720,6 +720,7 @@ fn test_debugging_options_tracking_hash() { tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_opt_level, Some(4)); + tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, Some(true)); tracked!(new_llvm_pass_manager, Some(true)); tracked!(no_generate_arange_section, true); diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index c4bfd0ebb2fde..7ea4902f4bc39 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -21,7 +21,12 @@ use std::num::IntErrorKind; pub fn provide(providers: &mut ty::query::Providers) { providers.limits = |tcx, ()| Limits { recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess), - move_size_limit: get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0), + move_size_limit: get_limit( + tcx.hir().krate_attrs(), + tcx.sess, + sym::move_size_limit, + tcx.sess.opts.debugging_opts.move_size_limit.unwrap_or(0), + ), type_length_limit: get_limit( tcx.hir().krate_attrs(), tcx.sess, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 4c40d0c367eca..4232d60481607 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1147,6 +1147,8 @@ options! { (default: no)"), mir_opt_level: Option = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), + move_size_limit: Option = (None, parse_opt_number, [TRACKED], + "the size at which the `large_assignments` lint starts to be emitted"), mutable_noalias: Option = (None, parse_opt_bool, [TRACKED], "emit noalias metadata for mutable references (default: yes for LLVM >= 12, otherwise no)"), new_llvm_pass_manager: Option = (None, parse_opt_bool, [TRACKED], diff --git a/src/doc/unstable-book/src/compiler-flags/move-size-limit.md b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md new file mode 100644 index 0000000000000..88f022af2ecf2 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md @@ -0,0 +1,10 @@ +# `move_size_limit` + +-------------------- + +The `-Zmove-size-limit=N` compiler flag enables `large_assignments` lints which +will warn when moving objects whose size exceeds `N` bytes. + +Lint warns only about moves in functions that participate in code generation. +Consequently it will be ineffective for compiler invocatation that emit +metadata only, i.e., `cargo check` like workflows. diff --git a/src/test/ui/async-await/large_moves.stderr b/src/test/ui/async-await/large_moves.attribute.stderr similarity index 88% rename from src/test/ui/async-await/large_moves.stderr rename to src/test/ui/async-await/large_moves.attribute.stderr index 8c47ec0ed9d38..39b7e7cb345bd 100644 --- a/src/test/ui/async-await/large_moves.stderr +++ b/src/test/ui/async-await/large_moves.attribute.stderr @@ -1,5 +1,5 @@ error: moving 10024 bytes - --> $DIR/large_moves.rs:10:13 + --> $DIR/large_moves.rs:12:13 | LL | let x = async { | _____________^ @@ -17,19 +17,19 @@ LL | #![deny(large_assignments)] | ^^^^^^^^^^^^^^^^^ error: moving 10024 bytes - --> $DIR/large_moves.rs:16:14 + --> $DIR/large_moves.rs:18:14 | LL | let z = (x, 42); | ^ value moved from here error: moving 10024 bytes - --> $DIR/large_moves.rs:16:13 + --> $DIR/large_moves.rs:18:13 | LL | let z = (x, 42); | ^^^^^^^ value moved from here error: moving 10024 bytes - --> $DIR/large_moves.rs:18:13 + --> $DIR/large_moves.rs:20:13 | LL | let a = z.0; | ^^^ value moved from here diff --git a/src/test/ui/async-await/large_moves.option.stderr b/src/test/ui/async-await/large_moves.option.stderr new file mode 100644 index 0000000000000..39b7e7cb345bd --- /dev/null +++ b/src/test/ui/async-await/large_moves.option.stderr @@ -0,0 +1,38 @@ +error: moving 10024 bytes + --> $DIR/large_moves.rs:12:13 + | +LL | let x = async { + | _____________^ +LL | | let y = [0; 9999]; +LL | | dbg!(y); +LL | | thing(&y).await; +LL | | dbg!(y); +LL | | }; + | |_____^ value moved from here + | +note: the lint level is defined here + --> $DIR/large_moves.rs:1:9 + | +LL | #![deny(large_assignments)] + | ^^^^^^^^^^^^^^^^^ + +error: moving 10024 bytes + --> $DIR/large_moves.rs:18:14 + | +LL | let z = (x, 42); + | ^ value moved from here + +error: moving 10024 bytes + --> $DIR/large_moves.rs:18:13 + | +LL | let z = (x, 42); + | ^^^^^^^ value moved from here + +error: moving 10024 bytes + --> $DIR/large_moves.rs:20:13 + | +LL | let a = z.0; + | ^^^ value moved from here + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/async-await/large_moves.rs b/src/test/ui/async-await/large_moves.rs index 4fac046beef62..18bb538a81eb1 100644 --- a/src/test/ui/async-await/large_moves.rs +++ b/src/test/ui/async-await/large_moves.rs @@ -1,8 +1,10 @@ #![deny(large_assignments)] #![feature(large_assignments)] -#![move_size_limit = "1000"] +#![cfg_attr(attribute, move_size_limit = "1000")] // build-fail // only-x86_64 +// revisions: attribute option +// [option]compile-flags: -Zmove-size-limit=1000 // edition:2018