forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#120773 - Enselic:copy-vs-move, r=oli-obk large_assignments: Allow moves into functions Moves into functions are typically implemented with pointer passing rather than memcpy's at the llvm-ir level, so allow moves into functions. Part of the "Differentiate between Operand::Move and Operand::Copy" step of rust-lang#83518. r? `@oli-obk` (who I think is still E-mentor?)
- Loading branch information
Showing
9 changed files
with
147 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#![deny(large_assignments)] | ||
#![feature(large_assignments)] | ||
#![move_size_limit = "1000"] | ||
// build-fail | ||
// only-64bit | ||
|
||
// edition:2018 | ||
// compile-flags: -Zmir-opt-level=1 | ||
|
||
use std::{sync::Arc, rc::Rc}; | ||
|
||
fn main() { | ||
let data = [0; 9999]; | ||
|
||
// Looking at --emit mir, we can see that all parameters below are passed by | ||
// copy. But it requires at least mir-opt-level=1. | ||
let _ = Arc::new(data); // OK! | ||
let _ = Box::new(data); // OK! | ||
let _ = Rc::new(data); // OK! | ||
|
||
// Looking at --emit llvm-ir, we can see that a memcpy is involved in the | ||
// parameter passing. So we want the lint to trigger here. | ||
let _ = NotBox::new(data); //~ ERROR large_assignments | ||
} | ||
|
||
struct NotBox { | ||
data: [u8; 9999], | ||
} | ||
|
||
impl NotBox { | ||
fn new(data: [u8; 9999]) -> Self { | ||
// Looking at --emit llvm-ir, we can see that a memcpy is involved. | ||
// So we want the lint to trigger here. | ||
Self { //~ ERROR large_assignments | ||
data, | ||
} | ||
} | ||
} |
16 changes: 9 additions & 7 deletions
16
...rge_assignments/box_rc_arc_allowed.stderr → ...e_assignments/copy_into_box_rc_arc.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#![deny(large_assignments)] | ||
#![feature(large_assignments)] | ||
#![move_size_limit = "1000"] | ||
// build-fail | ||
// only-64bit | ||
|
||
// edition:2018 | ||
// compile-flags: -Zmir-opt-level=0 | ||
|
||
use std::{sync::Arc, rc::Rc}; | ||
|
||
fn main() { | ||
// Looking at --emit mir, we can see that all parameters below are passed | ||
// by move. | ||
let _ = Arc::new([0; 9999]); // OK! | ||
let _ = Box::new([0; 9999]); // OK! | ||
let _ = Rc::new([0; 9999]); // OK! | ||
|
||
// Looking at --emit llvm-ir, we can see that no memcpy is involved in the | ||
// parameter passing. Instead, a pointer is passed. This is typically what | ||
// we get when moving parameter into functions. So we don't want the lint to | ||
// trigger here. | ||
let _ = NotBox::new([0; 9999]); // OK (compare with copy_into_box_rc_arc.rs) | ||
} | ||
|
||
struct NotBox { | ||
data: [u8; 9999], | ||
} | ||
|
||
impl NotBox { | ||
fn new(data: [u8; 9999]) -> Self { | ||
Self { | ||
// Looking at --emit llvm-ir, we can see that a memcpy is involved. | ||
// So we want the lint to trigger here. | ||
data, //~ ERROR large_assignments | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
error: moving 9999 bytes | ||
--> $DIR/move_into_box_rc_arc.rs:35:13 | ||
| | ||
LL | data, | ||
| ^^^^ value moved from here | ||
| | ||
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` | ||
note: the lint level is defined here | ||
--> $DIR/move_into_box_rc_arc.rs:1:9 | ||
| | ||
LL | #![deny(large_assignments)] | ||
| ^^^^^^^^^^^^^^^^^ | ||
|
||
error: aborting due to 1 previous error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// build-fail | ||
|
||
#![feature(large_assignments)] | ||
#![move_size_limit = "1000"] | ||
#![deny(large_assignments)] | ||
#![allow(unused)] | ||
|
||
// Note: This type does not implement Copy. | ||
struct Data([u8; 9999]); | ||
|
||
fn main() { | ||
// Looking at llvm-ir output, we can see a memcpy'd into Data, so we want | ||
// the lint to trigger here. | ||
let data = Data([100; 9999]); //~ ERROR large_assignments | ||
|
||
// Looking at llvm-ir output, we can see that there is no memcpy involved in | ||
// this function call. Instead, just a pointer is passed to the function. So | ||
// the lint shall not trigger here. | ||
take_data(data); | ||
} | ||
|
||
fn take_data(data: Data) {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
error: moving 9999 bytes | ||
--> $DIR/move_into_fn.rs:14:16 | ||
| | ||
LL | let data = Data([100; 9999]); | ||
| ^^^^^^^^^^^^^^^^^ value moved from here | ||
| | ||
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` | ||
note: the lint level is defined here | ||
--> $DIR/move_into_fn.rs:5:9 | ||
| | ||
LL | #![deny(large_assignments)] | ||
| ^^^^^^^^^^^^^^^^^ | ||
|
||
error: aborting due to 1 previous error | ||
|