about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-07-27 19:52:40 +0900
committerGitHub <noreply@github.com>2021-07-27 19:52:40 +0900
commit99a6474bc45c66823972da3e4e23dc4cf47dd79a (patch)
treed06fe78bdab65bcb4b127f2c75cdb6cdfbfe15e8
parent998cfe5aad7c21eb19a4bca50f05a13354706970 (diff)
parent9792179648abb7bf38a9e54191cfe5a25436b8fb (diff)
downloadrust-99a6474bc45c66823972da3e4e23dc4cf47dd79a.tar.gz
rust-99a6474bc45c66823972da3e4e23dc4cf47dd79a.zip
Rollup merge of #86450 - tmiasko:move-size-limit, r=pnkfelix
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
```

Lint tracking issue #83518.
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs7
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/move-size-limit.md10
-rw-r--r--src/test/ui/async-await/large_moves.attribute.stderr (renamed from src/test/ui/async-await/large_moves.stderr)8
-rw-r--r--src/test/ui/async-await/large_moves.option.stderr38
-rw-r--r--src/test/ui/async-await/large_moves.rs4
7 files changed, 64 insertions, 6 deletions
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index b1e4e3ba395..de0d5fb0097 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -735,6 +735,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 c4bfd0ebb2f..7ea4902f4bc 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 9fbe4c05ef9..0805d2f0e14 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1148,6 +1148,8 @@ options! {
         (default: no)"),
     mir_opt_level: Option<usize> = (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<usize> = (None, parse_opt_number, [TRACKED],
+        "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: yes for LLVM >= 12, otherwise no)"),
     new_llvm_pass_manager: Option<bool> = (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 00000000000..88f022af2ec
--- /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
index 8c47ec0ed9d..39b7e7cb345 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 00000000000..39b7e7cb345
--- /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 4fac046beef..18bb538a81e 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