2021-07-23 09:37:19 -05:00
|
|
|
//! Completion tests for expressions.
|
|
|
|
use expect_test::{expect, Expect};
|
|
|
|
|
|
|
|
use crate::tests::{completion_list, BASE_ITEMS_FIXTURE};
|
|
|
|
|
|
|
|
fn check(ra_fixture: &str, expect: Expect) {
|
|
|
|
let actual = completion_list(&format!("{}{}", BASE_ITEMS_FIXTURE, ra_fixture));
|
|
|
|
expect.assert_eq(&actual)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_empty(ra_fixture: &str, expect: Expect) {
|
|
|
|
let actual = completion_list(ra_fixture);
|
|
|
|
expect.assert_eq(&actual);
|
|
|
|
}
|
|
|
|
|
2021-08-03 17:46:50 -05:00
|
|
|
#[test]
|
|
|
|
fn complete_literal_struct_with_a_private_field() {
|
|
|
|
// `FooDesc.bar` is private, the completion should not be triggered.
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
mod _69latrick {
|
|
|
|
pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, bar: bool }
|
|
|
|
pub fn create_foo(foo_desc: &FooDesc) -> () { () }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn baz() {
|
|
|
|
use _69latrick::*;
|
|
|
|
|
|
|
|
let foo = create_foo(&$0);
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
// This should not contain `FooDesc {…}`.
|
2022-03-10 15:21:58 -06:00
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
ct CONST
|
2021-08-03 17:46:50 -05:00
|
|
|
en Enum
|
|
|
|
fn baz() fn()
|
2022-05-05 03:49:43 -05:00
|
|
|
fn create_foo(…) fn(&FooDesc)
|
2021-08-03 17:46:50 -05:00
|
|
|
fn function() fn()
|
2022-05-05 03:49:43 -05:00
|
|
|
ma makro!(…) macro_rules! makro
|
|
|
|
md _69latrick
|
|
|
|
md module
|
2021-08-03 17:46:50 -05:00
|
|
|
sc STATIC
|
2022-05-05 03:49:43 -05:00
|
|
|
st FooDesc
|
|
|
|
st Record
|
|
|
|
st Tuple
|
|
|
|
st Unit
|
|
|
|
tt Trait
|
2021-08-03 17:46:50 -05:00
|
|
|
un Union
|
Complete enum variants identically to structures.
In particular:
- unit variants now display in the menu as "Variant", complete to "Variant", and display a detail of "Variant" (was "()")
- tuple variants now display in the menu as "Variant(…)", complete to "Variant(${1:()})$0" (was "Variant($0)"), and display a detail of "Variant(type)" (was "(type)")
- record variants now display in the menu as "Variant {…}", complete to "Variant { x: ${1:()} }$0" (was "Variant"), and display a detail of "Variant { x: type }" (was "{x: type}")
This behavior is identical to that of struct completions. In addition, tuple variants no longer set triggers_call_info, as to my understanding it's unnecessary now that we're emitting placeholders.
Tests have been updated to match, and the render::enum_variant::tests::inserts_parens_for_tuple_enums test has been removed entirely as it's covered by other tests (render::enum_detail_includes_{record, tuple}_fields, render::enum_detail_just_name_for_unit, render::pattern::enum_qualified).
2022-03-11 20:26:01 -06:00
|
|
|
ev TupleV(…) TupleV(u32)
|
2022-05-05 03:49:43 -05:00
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw loop
|
|
|
|
kw match
|
|
|
|
kw mut
|
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2022-03-10 15:21:58 -06:00
|
|
|
"#]],
|
2021-08-03 17:46:50 -05:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-07-23 09:37:19 -05:00
|
|
|
#[test]
|
|
|
|
fn completes_various_bindings() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
fn func(param0 @ (param1, param2): (i32, i32)) {
|
|
|
|
let letlocal = 92;
|
|
|
|
if let ifletlocal = 100 {
|
|
|
|
match 0 {
|
|
|
|
matcharm => 1 + $0,
|
|
|
|
otherwise => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let letlocal2 = 44;
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn func(…) fn((i32, i32))
|
2021-07-23 09:37:19 -05:00
|
|
|
lc ifletlocal i32
|
|
|
|
lc letlocal i32
|
2022-05-05 03:49:43 -05:00
|
|
|
lc matcharm i32
|
2021-07-23 09:37:19 -05:00
|
|
|
lc param0 (i32, i32)
|
|
|
|
lc param1 i32
|
|
|
|
lc param2 i32
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw loop
|
|
|
|
kw match
|
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-07-23 09:37:19 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-27 09:24:42 -05:00
|
|
|
fn completes_all_the_things_in_fn_body() {
|
2021-07-23 09:37:19 -05:00
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
use non_existant::Unresolved;
|
|
|
|
mod qualified { pub enum Enum { Variant } }
|
|
|
|
|
|
|
|
impl Unit {
|
|
|
|
fn foo<'lifetime, TypeParam, const CONST_PARAM: usize>(self) {
|
|
|
|
fn local_func() {}
|
|
|
|
$0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
2021-07-23 10:02:39 -05:00
|
|
|
// `self` is in here twice, once as the module, once as the local
|
2022-03-10 15:21:58 -06:00
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
ct CONST
|
|
|
|
cp CONST_PARAM
|
|
|
|
en Enum
|
|
|
|
fn function() fn()
|
|
|
|
fn local_func() fn()
|
|
|
|
lc self Unit
|
|
|
|
ma makro!(…) macro_rules! makro
|
|
|
|
md module
|
|
|
|
md qualified
|
|
|
|
sp Self
|
|
|
|
sc STATIC
|
|
|
|
st Record
|
|
|
|
st Tuple
|
|
|
|
st Unit
|
|
|
|
tt Trait
|
|
|
|
tp TypeParam
|
|
|
|
un Union
|
|
|
|
ev TupleV(…) TupleV(u32)
|
|
|
|
bt u32
|
2021-07-23 09:37:19 -05:00
|
|
|
kw const
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw enum
|
2021-07-23 09:37:19 -05:00
|
|
|
kw extern
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw fn
|
|
|
|
kw for
|
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw impl
|
|
|
|
kw let
|
|
|
|
kw loop
|
|
|
|
kw match
|
2021-07-23 09:37:19 -05:00
|
|
|
kw mod
|
2022-05-05 03:49:43 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw static
|
2022-04-14 11:39:27 -05:00
|
|
|
kw struct
|
2022-05-05 08:49:03 -05:00
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw trait
|
|
|
|
kw true
|
|
|
|
kw type
|
2022-04-14 11:39:27 -05:00
|
|
|
kw union
|
2022-05-05 03:49:43 -05:00
|
|
|
kw unsafe
|
|
|
|
kw use
|
2021-07-23 09:37:19 -05:00
|
|
|
kw while
|
|
|
|
kw while let
|
2022-05-05 03:49:43 -05:00
|
|
|
me self.foo() fn(self)
|
|
|
|
sn macro_rules
|
2021-07-23 09:37:19 -05:00
|
|
|
sn pd
|
|
|
|
sn ppd
|
|
|
|
?? Unresolved
|
2022-03-10 15:21:58 -06:00
|
|
|
"#]],
|
2021-07-23 09:37:19 -05:00
|
|
|
);
|
2021-07-23 10:02:39 -05:00
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
use non_existant::Unresolved;
|
|
|
|
mod qualified { pub enum Enum { Variant } }
|
|
|
|
|
|
|
|
impl Unit {
|
|
|
|
fn foo<'lifetime, TypeParam, const CONST_PARAM: usize>(self) {
|
|
|
|
fn local_func() {}
|
|
|
|
self::$0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
2022-03-10 15:21:58 -06:00
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
ct CONST
|
2021-07-23 10:02:39 -05:00
|
|
|
en Enum
|
2022-05-05 03:49:43 -05:00
|
|
|
fn function() fn()
|
|
|
|
ma makro!(…) macro_rules! makro
|
2021-07-23 10:02:39 -05:00
|
|
|
md module
|
|
|
|
md qualified
|
|
|
|
sc STATIC
|
2022-05-05 03:49:43 -05:00
|
|
|
st Record
|
|
|
|
st Tuple
|
|
|
|
st Unit
|
|
|
|
tt Trait
|
2021-07-23 10:02:39 -05:00
|
|
|
un Union
|
Complete enum variants identically to structures.
In particular:
- unit variants now display in the menu as "Variant", complete to "Variant", and display a detail of "Variant" (was "()")
- tuple variants now display in the menu as "Variant(…)", complete to "Variant(${1:()})$0" (was "Variant($0)"), and display a detail of "Variant(type)" (was "(type)")
- record variants now display in the menu as "Variant {…}", complete to "Variant { x: ${1:()} }$0" (was "Variant"), and display a detail of "Variant { x: type }" (was "{x: type}")
This behavior is identical to that of struct completions. In addition, tuple variants no longer set triggers_call_info, as to my understanding it's unnecessary now that we're emitting placeholders.
Tests have been updated to match, and the render::enum_variant::tests::inserts_parens_for_tuple_enums test has been removed entirely as it's covered by other tests (render::enum_detail_includes_{record, tuple}_fields, render::enum_detail_just_name_for_unit, render::pattern::enum_qualified).
2022-03-11 20:26:01 -06:00
|
|
|
ev TupleV(…) TupleV(u32)
|
2022-05-05 03:49:43 -05:00
|
|
|
?? Unresolved
|
2022-03-10 15:21:58 -06:00
|
|
|
"#]],
|
2021-07-23 10:02:39 -05:00
|
|
|
);
|
2021-07-23 09:37:19 -05:00
|
|
|
}
|
|
|
|
|
2021-10-27 09:24:42 -05:00
|
|
|
#[test]
|
|
|
|
fn complete_in_block() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if true {
|
|
|
|
$0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn foo() fn()
|
|
|
|
bt u32
|
2021-10-27 09:24:42 -05:00
|
|
|
kw const
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw enum
|
2021-10-27 09:24:42 -05:00
|
|
|
kw extern
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw fn
|
|
|
|
kw for
|
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw impl
|
|
|
|
kw let
|
|
|
|
kw loop
|
|
|
|
kw match
|
2021-10-27 09:24:42 -05:00
|
|
|
kw mod
|
2022-05-05 03:49:43 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw static
|
2022-04-14 11:39:27 -05:00
|
|
|
kw struct
|
2022-05-05 08:49:03 -05:00
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw trait
|
|
|
|
kw true
|
|
|
|
kw type
|
2022-04-14 11:39:27 -05:00
|
|
|
kw union
|
2022-05-05 03:49:43 -05:00
|
|
|
kw unsafe
|
|
|
|
kw use
|
2021-10-27 09:24:42 -05:00
|
|
|
kw while
|
|
|
|
kw while let
|
2022-05-05 03:49:43 -05:00
|
|
|
sn macro_rules
|
2021-10-27 09:24:42 -05:00
|
|
|
sn pd
|
|
|
|
sn ppd
|
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn complete_after_if_expr() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
if true {}
|
|
|
|
$0
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn foo() fn()
|
|
|
|
bt u32
|
2021-10-27 09:24:42 -05:00
|
|
|
kw const
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw else
|
|
|
|
kw else if
|
|
|
|
kw enum
|
2021-10-27 09:24:42 -05:00
|
|
|
kw extern
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw fn
|
|
|
|
kw for
|
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw impl
|
|
|
|
kw let
|
|
|
|
kw loop
|
|
|
|
kw match
|
2021-10-27 09:24:42 -05:00
|
|
|
kw mod
|
2022-05-05 03:49:43 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw static
|
2022-04-14 11:39:27 -05:00
|
|
|
kw struct
|
2022-05-05 08:49:03 -05:00
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw trait
|
|
|
|
kw true
|
|
|
|
kw type
|
2022-04-14 11:39:27 -05:00
|
|
|
kw union
|
2022-05-05 03:49:43 -05:00
|
|
|
kw unsafe
|
|
|
|
kw use
|
2021-10-27 09:24:42 -05:00
|
|
|
kw while
|
|
|
|
kw while let
|
2022-05-05 03:49:43 -05:00
|
|
|
sn macro_rules
|
2021-10-27 09:24:42 -05:00
|
|
|
sn pd
|
|
|
|
sn ppd
|
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn complete_in_match_arm() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
match () {
|
|
|
|
() => $0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn foo() fn()
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
2021-10-27 09:24:42 -05:00
|
|
|
kw if
|
|
|
|
kw if let
|
2022-05-05 03:49:43 -05:00
|
|
|
kw loop
|
|
|
|
kw match
|
2021-10-27 09:24:42 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-10-27 09:24:42 -05:00
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn completes_in_loop_ctx() {
|
|
|
|
check_empty(
|
|
|
|
r"fn my() { loop { $0 } }",
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn my() fn()
|
|
|
|
bt u32
|
|
|
|
kw break
|
2021-10-27 09:24:42 -05:00
|
|
|
kw const
|
2022-05-05 03:49:43 -05:00
|
|
|
kw continue
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw enum
|
2021-10-27 09:24:42 -05:00
|
|
|
kw extern
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw fn
|
|
|
|
kw for
|
|
|
|
kw if
|
|
|
|
kw if let
|
|
|
|
kw impl
|
|
|
|
kw let
|
|
|
|
kw loop
|
|
|
|
kw match
|
2021-10-27 09:24:42 -05:00
|
|
|
kw mod
|
2022-05-05 03:49:43 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw static
|
2022-04-14 11:39:27 -05:00
|
|
|
kw struct
|
2022-05-05 08:49:03 -05:00
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw trait
|
|
|
|
kw true
|
|
|
|
kw type
|
2022-04-14 11:39:27 -05:00
|
|
|
kw union
|
2022-05-05 03:49:43 -05:00
|
|
|
kw unsafe
|
|
|
|
kw use
|
2021-10-27 09:24:42 -05:00
|
|
|
kw while
|
|
|
|
kw while let
|
2022-05-05 03:49:43 -05:00
|
|
|
sn macro_rules
|
2021-10-27 09:24:42 -05:00
|
|
|
sn pd
|
|
|
|
sn ppd
|
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn completes_in_let_initializer() {
|
|
|
|
check_empty(
|
|
|
|
r#"fn main() { let _ = $0 }"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn main() fn()
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
2021-10-27 09:24:42 -05:00
|
|
|
kw if
|
|
|
|
kw if let
|
2022-05-05 03:49:43 -05:00
|
|
|
kw loop
|
|
|
|
kw match
|
2021-10-27 09:24:42 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-10-27 09:24:42 -05:00
|
|
|
"#]],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn struct_initializer_field_expr() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
struct Foo {
|
|
|
|
pub f: i32,
|
|
|
|
}
|
|
|
|
fn foo() {
|
|
|
|
Foo {
|
|
|
|
f: $0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn foo() fn()
|
|
|
|
st Foo
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
2021-10-27 09:24:42 -05:00
|
|
|
kw if
|
|
|
|
kw if let
|
2022-05-05 03:49:43 -05:00
|
|
|
kw loop
|
|
|
|
kw match
|
2021-10-27 09:24:42 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-10-27 09:24:42 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-07-23 09:37:19 -05:00
|
|
|
#[test]
|
|
|
|
fn shadowing_shows_single_completion() {
|
2021-08-03 09:36:06 -05:00
|
|
|
cov_mark::check!(shadowing_shows_single_completion);
|
|
|
|
|
2021-07-23 09:37:19 -05:00
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
fn foo() {
|
|
|
|
let bar = 92;
|
|
|
|
{
|
|
|
|
let bar = 62;
|
|
|
|
drop($0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn foo() fn()
|
|
|
|
lc bar i32
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
2021-07-23 09:37:19 -05:00
|
|
|
kw if
|
|
|
|
kw if let
|
2022-05-05 03:49:43 -05:00
|
|
|
kw loop
|
|
|
|
kw match
|
2021-07-23 09:37:19 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-07-23 09:37:19 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn in_macro_expr_frag() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
macro_rules! m { ($e:expr) => { $e } }
|
|
|
|
fn quux(x: i32) {
|
|
|
|
m!($0);
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn quux(…) fn(i32)
|
|
|
|
lc x i32
|
|
|
|
ma m!(…) macro_rules! m
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
2021-07-23 09:37:19 -05:00
|
|
|
kw if
|
|
|
|
kw if let
|
2022-05-05 03:49:43 -05:00
|
|
|
kw loop
|
|
|
|
kw match
|
2021-07-23 09:37:19 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-07-23 09:37:19 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
check_empty(
|
|
|
|
r"
|
|
|
|
macro_rules! m { ($e:expr) => { $e } }
|
|
|
|
fn quux(x: i32) {
|
|
|
|
m!(x$0);
|
|
|
|
}
|
|
|
|
",
|
|
|
|
expect![[r#"
|
2022-05-05 03:49:43 -05:00
|
|
|
fn quux(…) fn(i32)
|
|
|
|
lc x i32
|
|
|
|
ma m!(…) macro_rules! m
|
|
|
|
bt u32
|
2022-05-05 08:49:03 -05:00
|
|
|
kw crate::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw false
|
|
|
|
kw for
|
2021-07-23 09:37:19 -05:00
|
|
|
kw if
|
|
|
|
kw if let
|
2022-05-05 03:49:43 -05:00
|
|
|
kw loop
|
|
|
|
kw match
|
2021-07-23 09:37:19 -05:00
|
|
|
kw return
|
2022-05-05 08:49:03 -05:00
|
|
|
kw self::
|
|
|
|
kw super::
|
2022-05-05 03:49:43 -05:00
|
|
|
kw true
|
|
|
|
kw unsafe
|
|
|
|
kw while
|
|
|
|
kw while let
|
2021-07-23 09:37:19 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
macro_rules! m { ($e:expr) => { $e } }
|
|
|
|
fn quux(x: i32) {
|
|
|
|
let y = 92;
|
|
|
|
m!(x$0
|
|
|
|
}
|
|
|
|
"#,
|
fix: avoid pathological macro expansions
Today, rust-analyzer (and rustc, and bat, and IntelliJ) fail badly on
some kinds of maliciously constructed code, like a deep sequence of
nested parenthesis.
"Who writes 100k nested parenthesis" you'd ask?
Well, in a language with macros, a run-away macro expansion might do
that (see the added tests)! Such expansion can be broad, rather than
deep, so it bypasses recursion check at the macro-expansion layer, but
triggers deep recursion in parser.
In the ideal world, the parser would just handle deeply nested structs
gracefully. We'll get there some day, but at the moment, let's try to be
simple, and just avoid expanding macros with unbalanced parenthesis in
the first place.
closes #9358
2021-08-09 08:06:49 -05:00
|
|
|
expect![[r#""#]],
|
2021-07-23 09:37:19 -05:00
|
|
|
);
|
|
|
|
}
|
2021-07-23 10:02:39 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn enum_qualified() {
|
|
|
|
check(
|
|
|
|
r#"
|
|
|
|
impl Enum {
|
|
|
|
type AssocType = ();
|
|
|
|
const ASSOC_CONST: () = ();
|
|
|
|
fn assoc_fn() {}
|
|
|
|
}
|
|
|
|
fn func() {
|
|
|
|
Enum::$0
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2021-12-21 09:34:55 -06:00
|
|
|
ct ASSOC_CONST const ASSOC_CONST: ()
|
2021-07-23 10:02:39 -05:00
|
|
|
fn assoc_fn() fn()
|
2021-12-21 09:36:04 -06:00
|
|
|
ta AssocType type AssocType = ()
|
2022-05-05 03:49:43 -05:00
|
|
|
ev RecordV {…} RecordV { field: u32 }
|
|
|
|
ev TupleV(…) TupleV(u32)
|
|
|
|
ev UnitV UnitV
|
2021-07-23 10:02:39 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2022-03-21 15:45:29 -05:00
|
|
|
|
2022-03-26 12:46:49 -05:00
|
|
|
#[test]
|
|
|
|
fn ty_qualified_no_drop() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
//- minicore: drop
|
|
|
|
struct Foo;
|
|
|
|
impl Drop for Foo {
|
|
|
|
fn drop(&mut self) {}
|
|
|
|
}
|
|
|
|
fn func() {
|
|
|
|
Foo::$0
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#""#]],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-03-21 15:45:29 -05:00
|
|
|
#[test]
|
|
|
|
fn with_parens() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
enum Enum {
|
|
|
|
Variant()
|
|
|
|
}
|
|
|
|
impl Enum {
|
|
|
|
fn variant() -> Self { Enum::Variant() }
|
|
|
|
}
|
|
|
|
fn func() {
|
|
|
|
Enum::$0()
|
|
|
|
}
|
|
|
|
"#,
|
|
|
|
expect![[r#"
|
2022-06-05 11:34:01 -05:00
|
|
|
fn variant fn() -> Enum
|
|
|
|
ev Variant Variant
|
2022-03-21 15:45:29 -05:00
|
|
|
"#]],
|
|
|
|
);
|
|
|
|
}
|
2022-04-12 10:40:31 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn detail_impl_trait_in_return_position() {
|
|
|
|
check_empty(
|
|
|
|
r"
|
|
|
|
//- minicore: sized
|
|
|
|
trait Trait<T> {}
|
|
|
|
fn foo<U>() -> impl Trait<U> {}
|
|
|
|
fn main() {
|
|
|
|
self::$0
|
|
|
|
}
|
|
|
|
",
|
2022-05-05 03:49:43 -05:00
|
|
|
expect![[r#"
|
2022-04-12 10:40:31 -05:00
|
|
|
fn foo() fn() -> impl Trait<U>
|
2022-05-05 03:49:43 -05:00
|
|
|
fn main() fn()
|
|
|
|
tt Trait
|
|
|
|
"#]],
|
2022-04-12 10:40:31 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn detail_async_fn() {
|
|
|
|
check_empty(
|
|
|
|
r#"
|
|
|
|
//- minicore: future, sized
|
|
|
|
trait Trait<T> {}
|
|
|
|
async fn foo() -> u8 {}
|
2022-04-14 07:44:17 -05:00
|
|
|
async fn bar<U>() -> impl Trait<U> {}
|
2022-04-12 10:40:31 -05:00
|
|
|
fn main() {
|
|
|
|
self::$0
|
|
|
|
}
|
|
|
|
"#,
|
2022-05-05 03:49:43 -05:00
|
|
|
expect![[r#"
|
2022-04-14 07:44:17 -05:00
|
|
|
fn bar() async fn() -> impl Trait<U>
|
|
|
|
fn foo() async fn() -> u8
|
2022-05-05 03:49:43 -05:00
|
|
|
fn main() fn()
|
|
|
|
tt Trait
|
|
|
|
"#]],
|
2022-04-12 10:40:31 -05:00
|
|
|
);
|
|
|
|
}
|
2022-04-16 09:18:42 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn detail_impl_trait_in_argument_position() {
|
|
|
|
check_empty(
|
|
|
|
r"
|
|
|
|
//- minicore: sized
|
|
|
|
trait Trait<T> {}
|
|
|
|
struct Foo;
|
|
|
|
impl Foo {
|
|
|
|
fn bar<U>(_: impl Trait<U>) {}
|
|
|
|
}
|
|
|
|
fn main() {
|
|
|
|
Foo::$0
|
|
|
|
}
|
|
|
|
",
|
|
|
|
expect![[r"
|
|
|
|
fn bar(…) fn(impl Trait<U>)
|
|
|
|
"]],
|
|
|
|
);
|
|
|
|
}
|