Skip to content

Commit

Permalink
Add flag to configure large_assignments lint
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
tmiasko committed Jul 6, 2021
1 parent d7901f3 commit 9792179
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 6 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_middle/src/middle/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,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],
Expand Down
10 changes: 10 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/move-size-limit.md
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: moving 10024 bytes
--> $DIR/large_moves.rs:10:13
--> $DIR/large_moves.rs:12:13
|
LL | let x = async {
| _____________^
Expand All @@ -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
Expand Down
38 changes: 38 additions & 0 deletions src/test/ui/async-await/large_moves.option.stderr
Original file line number Diff line number Diff line change
@@ -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

4 changes: 3 additions & 1 deletion src/test/ui/async-await/large_moves.rs
Original file line number Diff line number Diff line change
@@ -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

Expand Down

0 comments on commit 9792179

Please sign in to comment.