mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
Compute closure captures
This commit is contained in:
parent
51d5862caf
commit
59b6f2d9f2
42 changed files with 2537 additions and 433 deletions
|
@ -225,7 +225,7 @@ fn main() {
|
|||
*iter*
|
||||
|
||||
```rust
|
||||
let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>>
|
||||
let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, impl Fn(&mut u32, &u32, &mut u32) -> Option<u32>, u32>>
|
||||
```
|
||||
"#]],
|
||||
);
|
||||
|
|
|
@ -5,7 +5,8 @@ use std::{
|
|||
|
||||
use either::Either;
|
||||
use hir::{
|
||||
known, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef, ModuleDefId, Semantics,
|
||||
known, ClosureStyle, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef,
|
||||
ModuleDefId, Semantics,
|
||||
};
|
||||
use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
|
||||
use itertools::Itertools;
|
||||
|
@ -45,6 +46,7 @@ pub struct InlayHintsConfig {
|
|||
pub param_names_for_lifetime_elision_hints: bool,
|
||||
pub hide_named_constructor_hints: bool,
|
||||
pub hide_closure_initialization_hints: bool,
|
||||
pub closure_style: ClosureStyle,
|
||||
pub max_length: Option<usize>,
|
||||
pub closing_brace_hints_min_lines: Option<usize>,
|
||||
}
|
||||
|
@ -291,6 +293,7 @@ fn label_of_ty(
|
|||
mut max_length: Option<usize>,
|
||||
ty: hir::Type,
|
||||
label_builder: &mut InlayHintLabelBuilder<'_>,
|
||||
config: &InlayHintsConfig,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
let iter_item_type = hint_iterator(sema, famous_defs, &ty);
|
||||
match iter_item_type {
|
||||
|
@ -321,11 +324,14 @@ fn label_of_ty(
|
|||
label_builder.write_str(LABEL_ITEM)?;
|
||||
label_builder.end_location_link();
|
||||
label_builder.write_str(LABEL_MIDDLE2)?;
|
||||
rec(sema, famous_defs, max_length, ty, label_builder)?;
|
||||
rec(sema, famous_defs, max_length, ty, label_builder, config)?;
|
||||
label_builder.write_str(LABEL_END)?;
|
||||
Ok(())
|
||||
}
|
||||
None => ty.display_truncated(sema.db, max_length).write_to(label_builder),
|
||||
None => ty
|
||||
.display_truncated(sema.db, max_length)
|
||||
.with_closure_style(config.closure_style)
|
||||
.write_to(label_builder),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,7 +341,7 @@ fn label_of_ty(
|
|||
location: None,
|
||||
result: InlayHintLabel::default(),
|
||||
};
|
||||
let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder);
|
||||
let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder, config);
|
||||
let r = label_builder.finish();
|
||||
Some(r)
|
||||
}
|
||||
|
@ -481,6 +487,7 @@ fn closure_has_block_body(closure: &ast::ClosureExpr) -> bool {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::Expect;
|
||||
use hir::ClosureStyle;
|
||||
use itertools::Itertools;
|
||||
use test_utils::extract_annotations;
|
||||
|
||||
|
@ -504,6 +511,7 @@ mod tests {
|
|||
binding_mode_hints: false,
|
||||
hide_named_constructor_hints: false,
|
||||
hide_closure_initialization_hints: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
param_names_for_lifetime_elision_hints: false,
|
||||
max_length: None,
|
||||
closing_brace_hints_min_lines: None,
|
||||
|
|
|
@ -176,6 +176,7 @@ fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::IdentPat, pat_ty: &hir
|
|||
mod tests {
|
||||
// This module also contains tests for super::closure_ret
|
||||
|
||||
use hir::ClosureStyle;
|
||||
use syntax::{TextRange, TextSize};
|
||||
use test_utils::extract_annotations;
|
||||
|
||||
|
@ -235,7 +236,7 @@ fn main() {
|
|||
let zz_ref = &zz;
|
||||
//^^^^^^ &Test<i32>
|
||||
let test = || zz;
|
||||
//^^^^ || -> Test<i32>
|
||||
//^^^^ impl FnOnce() -> Test<i32>
|
||||
}"#,
|
||||
);
|
||||
}
|
||||
|
@ -753,7 +754,7 @@ fn main() {
|
|||
let func = times2;
|
||||
// ^^^^ fn times2(i32) -> i32
|
||||
let closure = |x: i32| x * 2;
|
||||
// ^^^^^^^ |i32| -> i32
|
||||
// ^^^^^^^ impl Fn(i32) -> i32
|
||||
}
|
||||
|
||||
fn fallible() -> ControlFlow<()> {
|
||||
|
@ -821,7 +822,7 @@ fn main() {
|
|||
//^^^^^^^^^ i32
|
||||
|
||||
let multiply =
|
||||
//^^^^^^^^ |i32, i32| -> i32
|
||||
//^^^^^^^^ impl Fn(i32, i32) -> i32
|
||||
| a, b| a * b
|
||||
//^ i32 ^ i32
|
||||
|
||||
|
@ -830,10 +831,10 @@ fn main() {
|
|||
let _: i32 = multiply(1, 2);
|
||||
//^ a ^ b
|
||||
let multiply_ref = &multiply;
|
||||
//^^^^^^^^^^^^ &|i32, i32| -> i32
|
||||
//^^^^^^^^^^^^ &impl Fn(i32, i32) -> i32
|
||||
|
||||
let return_42 = || 42;
|
||||
//^^^^^^^^^ || -> i32
|
||||
//^^^^^^^^^ impl Fn() -> i32
|
||||
|| { 42 };
|
||||
//^^ i32
|
||||
}"#,
|
||||
|
@ -857,6 +858,94 @@ fn main() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn closure_style() {
|
||||
check_with_config(
|
||||
InlayHintsConfig { type_hints: true, ..DISABLED_CONFIG },
|
||||
r#"
|
||||
//- minicore: fn
|
||||
fn main() {
|
||||
let x = || 2;
|
||||
//^ impl Fn() -> i32
|
||||
let y = |t: i32| x() + t;
|
||||
//^ impl Fn(i32) -> i32
|
||||
let mut t = 5;
|
||||
//^ i32
|
||||
let z = |k: i32| { t += k; };
|
||||
//^ impl FnMut(i32)
|
||||
let p = (y, z);
|
||||
//^ (impl Fn(i32) -> i32, impl FnMut(i32))
|
||||
}
|
||||
"#,
|
||||
);
|
||||
check_with_config(
|
||||
InlayHintsConfig {
|
||||
type_hints: true,
|
||||
closure_style: ClosureStyle::RANotation,
|
||||
..DISABLED_CONFIG
|
||||
},
|
||||
r#"
|
||||
//- minicore: fn
|
||||
fn main() {
|
||||
let x = || 2;
|
||||
//^ || -> i32
|
||||
let y = |t: i32| x() + t;
|
||||
//^ |i32| -> i32
|
||||
let mut t = 5;
|
||||
//^ i32
|
||||
let z = |k: i32| { t += k; };
|
||||
//^ |i32| -> ()
|
||||
let p = (y, z);
|
||||
//^ (|i32| -> i32, |i32| -> ())
|
||||
}
|
||||
"#,
|
||||
);
|
||||
check_with_config(
|
||||
InlayHintsConfig {
|
||||
type_hints: true,
|
||||
closure_style: ClosureStyle::ClosureWithId,
|
||||
..DISABLED_CONFIG
|
||||
},
|
||||
r#"
|
||||
//- minicore: fn
|
||||
fn main() {
|
||||
let x = || 2;
|
||||
//^ {closure#0}
|
||||
let y = |t: i32| x() + t;
|
||||
//^ {closure#1}
|
||||
let mut t = 5;
|
||||
//^ i32
|
||||
let z = |k: i32| { t += k; };
|
||||
//^ {closure#2}
|
||||
let p = (y, z);
|
||||
//^ ({closure#1}, {closure#2})
|
||||
}
|
||||
"#,
|
||||
);
|
||||
check_with_config(
|
||||
InlayHintsConfig {
|
||||
type_hints: true,
|
||||
closure_style: ClosureStyle::Hide,
|
||||
..DISABLED_CONFIG
|
||||
},
|
||||
r#"
|
||||
//- minicore: fn
|
||||
fn main() {
|
||||
let x = || 2;
|
||||
//^ …
|
||||
let y = |t: i32| x() + t;
|
||||
//^ …
|
||||
let mut t = 5;
|
||||
//^ i32
|
||||
let z = |k: i32| { t += k; };
|
||||
//^ …
|
||||
let p = (y, z);
|
||||
//^ (…, …)
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skip_closure_type_hints() {
|
||||
check_with_config(
|
||||
|
@ -871,13 +960,13 @@ fn main() {
|
|||
let multiple_2 = |x: i32| { x * 2 };
|
||||
|
||||
let multiple_2 = |x: i32| x * 2;
|
||||
// ^^^^^^^^^^ |i32| -> i32
|
||||
// ^^^^^^^^^^ impl Fn(i32) -> i32
|
||||
|
||||
let (not) = (|x: bool| { !x });
|
||||
// ^^^ |bool| -> bool
|
||||
// ^^^ impl Fn(bool) -> bool
|
||||
|
||||
let (is_zero, _b) = (|x: usize| { x == 0 }, false);
|
||||
// ^^^^^^^ |usize| -> bool
|
||||
// ^^^^^^^ impl Fn(usize) -> bool
|
||||
// ^^ bool
|
||||
|
||||
let plus_one = |x| { x + 1 };
|
||||
|
|
|
@ -1227,6 +1227,24 @@ fn main() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn call_info_for_fn_def_over_reference() {
|
||||
check(
|
||||
r#"
|
||||
struct S;
|
||||
fn foo(s: S) -> i32 { 92 }
|
||||
fn main() {
|
||||
let bar = &&&&&foo;
|
||||
bar($0);
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
fn foo(s: S) -> i32
|
||||
^^^^
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn call_info_for_fn_ptr() {
|
||||
check(
|
||||
|
|
|
@ -118,6 +118,7 @@ impl StaticIndex<'_> {
|
|||
adjustment_hints_hide_outside_unsafe: false,
|
||||
hide_named_constructor_hints: false,
|
||||
hide_closure_initialization_hints: false,
|
||||
closure_style: hir::ClosureStyle::ImplFn,
|
||||
param_names_for_lifetime_elision_hints: false,
|
||||
binding_mode_hints: false,
|
||||
max_length: Some(25),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue