mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Compute closure captures
This commit is contained in:
parent
51d5862caf
commit
59b6f2d9f2
42 changed files with 2537 additions and 433 deletions
|
@ -11,6 +11,8 @@ use crate::{db::HirDatabase, test_db::TestDB, Interner, Substitution};
|
|||
|
||||
use super::layout_of_ty;
|
||||
|
||||
mod closure;
|
||||
|
||||
fn current_machine_data_layout() -> String {
|
||||
project_model::target_data_layout::get(None, None, &HashMap::default()).unwrap()
|
||||
}
|
||||
|
@ -81,8 +83,8 @@ fn check_size_and_align(ra_fixture: &str, minicore: &str, size: u64, align: u64)
|
|||
#[track_caller]
|
||||
fn check_size_and_align_expr(ra_fixture: &str, minicore: &str, size: u64, align: u64) {
|
||||
let l = eval_expr(ra_fixture, minicore).unwrap();
|
||||
assert_eq!(l.size.bytes(), size);
|
||||
assert_eq!(l.align.abi.bytes(), align);
|
||||
assert_eq!(l.size.bytes(), size, "size mismatch");
|
||||
assert_eq!(l.align.abi.bytes(), align, "align mismatch");
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
|
@ -118,13 +120,31 @@ macro_rules! size_and_align {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! size_and_align_expr {
|
||||
(minicore: $($x:tt),*; stmts: [$($s:tt)*] $($t:tt)*) => {
|
||||
{
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused_must_use)]
|
||||
#[allow(path_statements)]
|
||||
{
|
||||
$($s)*
|
||||
let val = { $($t)* };
|
||||
$crate::layout::tests::check_size_and_align_expr(
|
||||
&format!("{{ {} let val = {{ {} }}; val }}", stringify!($($s)*), stringify!($($t)*)),
|
||||
&format!("//- minicore: {}\n", stringify!($($x),*)),
|
||||
::std::mem::size_of_val(&val) as u64,
|
||||
::std::mem::align_of_val(&val) as u64,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
($($t:tt)*) => {
|
||||
{
|
||||
#[allow(dead_code)]
|
||||
{
|
||||
let val = { $($t)* };
|
||||
check_size_and_align_expr(
|
||||
$crate::layout::tests::check_size_and_align_expr(
|
||||
stringify!($($t)*),
|
||||
"",
|
||||
::std::mem::size_of_val(&val) as u64,
|
||||
|
|
175
crates/hir-ty/src/layout/tests/closure.rs
Normal file
175
crates/hir-ty/src/layout/tests/closure.rs
Normal file
|
@ -0,0 +1,175 @@
|
|||
use crate::size_and_align_expr;
|
||||
|
||||
#[test]
|
||||
fn zero_capture_simple() {
|
||||
size_and_align_expr! {
|
||||
|x: i32| x + 2
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn move_simple() {
|
||||
size_and_align_expr! {
|
||||
minicore: copy;
|
||||
stmts: []
|
||||
let y: i32 = 5;
|
||||
move |x: i32| {
|
||||
x + y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ref_simple() {
|
||||
size_and_align_expr! {
|
||||
minicore: copy;
|
||||
stmts: [
|
||||
let y: i32 = 5;
|
||||
]
|
||||
|x: i32| {
|
||||
x + y
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
minicore: copy;
|
||||
stmts: [
|
||||
let mut y: i32 = 5;
|
||||
]
|
||||
|x: i32| {
|
||||
y = y + x;
|
||||
y
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
minicore: copy;
|
||||
stmts: [
|
||||
struct X(i32, i64);
|
||||
let x: X = X(2, 6);
|
||||
]
|
||||
|| {
|
||||
x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ref_then_mut_then_move() {
|
||||
size_and_align_expr! {
|
||||
minicore: copy;
|
||||
stmts: [
|
||||
struct X(i32, i64);
|
||||
let mut x: X = X(2, 6);
|
||||
]
|
||||
|| {
|
||||
&x;
|
||||
&mut x;
|
||||
x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_closures() {
|
||||
size_and_align_expr! {
|
||||
|| {
|
||||
|| {
|
||||
|| {
|
||||
let x = 2;
|
||||
move || {
|
||||
move || {
|
||||
x
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capture_specific_fields() {
|
||||
size_and_align_expr! {
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y: X = X(2, 5, (7, 3));
|
||||
move |x: i64| {
|
||||
y.0 + x + (y.2 .0 as i64)
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y: X = X(2, 5, (7, 3));
|
||||
move |x: i64| {
|
||||
let _ = &y;
|
||||
y.0 + x + (y.2 .0 as i64)
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
minicore: copy;
|
||||
stmts: [
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y: X = X(2, 5, (7, 3));
|
||||
]
|
||||
let y = &y;
|
||||
move |x: i64| {
|
||||
y.0 + x + (y.2 .0 as i64)
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y: X = X(2, 5, (7, 3));
|
||||
move |x: i64| {
|
||||
let X(a, _, (b, _)) = y;
|
||||
a + x + (b as i64)
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y = &&X(2, 5, (7, 3));
|
||||
move |x: i64| {
|
||||
let X(a, _, (b, _)) = y;
|
||||
*a + x + (*b as i64)
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y: X = X(2, 5, (7, 3));
|
||||
move |x: i64| {
|
||||
match y {
|
||||
X(a, _, (b, _)) => a + x + (b as i64),
|
||||
}
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
struct X(i64, i32, (u8, i128));
|
||||
let y: X = X(2, 5, (7, 3));
|
||||
move |x: i64| {
|
||||
let X(a @ 2, _, (b, _)) = y else { return 5 };
|
||||
a + x + (b as i64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ellipsis_pattern() {
|
||||
size_and_align_expr! {
|
||||
struct X(i8, u16, i32, u64, i128, u8);
|
||||
let y: X = X(1, 2, 3, 4, 5, 6);
|
||||
move |_: i64| {
|
||||
let X(_a, .., _b, _c) = y;
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
struct X { a: i32, b: u8, c: i128}
|
||||
let y: X = X { a: 1, b: 2, c: 3 };
|
||||
move |_: i64| {
|
||||
let X { a, b, .. } = y;
|
||||
_ = (a, b);
|
||||
}
|
||||
}
|
||||
size_and_align_expr! {
|
||||
let y: (&&&(i8, u16, i32, u64, i128, u8), u16, i32, u64, i128, u8) = (&&&(1, 2, 3, 4, 5, 6), 2, 3, 4, 5, 6);
|
||||
move |_: i64| {
|
||||
let ((_a, .., _b, _c), .., _e, _f) = y;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue