mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-02 21:04:18 +00:00
feat: complete raw, const keyword
This commit is contained in:
parent
7d337c7f35
commit
9809143562
6 changed files with 144 additions and 8 deletions
|
|
@ -581,10 +581,7 @@ impl ExprCollector<'_> {
|
|||
let mutability = if raw_tok {
|
||||
if e.mut_token().is_some() {
|
||||
Mutability::Mut
|
||||
} else if e.const_token().is_some() {
|
||||
Mutability::Shared
|
||||
} else {
|
||||
never!("parser only remaps to raw_token() if matching mutability token follows");
|
||||
Mutability::Shared
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -69,8 +69,25 @@ pub(crate) fn complete_expr_path(
|
|||
..
|
||||
} = expr_ctx;
|
||||
|
||||
let wants_mut_token =
|
||||
ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false);
|
||||
let has_raw_token =
|
||||
ref_expr_parent.as_ref().map(|it| it.raw_token().is_some()).unwrap_or(false);
|
||||
let has_const_token =
|
||||
ref_expr_parent.as_ref().map(|it| it.const_token().is_some()).unwrap_or(false);
|
||||
let has_mut_token =
|
||||
ref_expr_parent.as_ref().map(|it| it.mut_token().is_some()).unwrap_or(false);
|
||||
|
||||
let wants_raw_token = ref_expr_parent.is_some() && !has_raw_token;
|
||||
let wants_const_token =
|
||||
ref_expr_parent.is_some() && has_raw_token && !has_const_token && !has_mut_token;
|
||||
let wants_mut_token = if ref_expr_parent.is_some() {
|
||||
if has_raw_token {
|
||||
!has_const_token && !has_mut_token
|
||||
} else {
|
||||
!has_mut_token
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let scope_def_applicable = |def| match def {
|
||||
ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) | ScopeDef::Label(_) => false,
|
||||
|
|
@ -354,6 +371,12 @@ pub(crate) fn complete_expr_path(
|
|||
add_keyword("else if", "else if $1 {\n $0\n}");
|
||||
}
|
||||
|
||||
if wants_raw_token {
|
||||
add_keyword("raw", "raw ");
|
||||
}
|
||||
if wants_const_token {
|
||||
add_keyword("const", "const ");
|
||||
}
|
||||
if wants_mut_token {
|
||||
add_keyword("mut", "mut ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ fn baz() {
|
|||
kw loop
|
||||
kw match
|
||||
kw mut
|
||||
kw raw
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
|
|
@ -436,6 +437,94 @@ fn completes_in_let_initializer() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_after_ref_expr() {
|
||||
check(
|
||||
r#"fn main() { let _ = &$0 }"#,
|
||||
expect![[r#"
|
||||
fn main() fn()
|
||||
bt u32 u32
|
||||
kw crate::
|
||||
kw false
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw loop
|
||||
kw match
|
||||
kw mut
|
||||
kw raw
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
kw unsafe
|
||||
kw while
|
||||
kw while let
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"fn main() { let _ = &raw $0 }"#,
|
||||
expect![[r#"
|
||||
fn main() fn()
|
||||
bt u32 u32
|
||||
kw const
|
||||
kw crate::
|
||||
kw false
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw loop
|
||||
kw match
|
||||
kw mut
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
kw unsafe
|
||||
kw while
|
||||
kw while let
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"fn main() { let _ = &raw const $0 }"#,
|
||||
expect![[r#"
|
||||
fn main() fn()
|
||||
bt u32 u32
|
||||
kw crate::
|
||||
kw false
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw loop
|
||||
kw match
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
kw unsafe
|
||||
kw while
|
||||
kw while let
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"fn main() { let _ = &raw mut $0 }"#,
|
||||
expect![[r#"
|
||||
fn main() fn()
|
||||
bt u32 u32
|
||||
kw crate::
|
||||
kw false
|
||||
kw for
|
||||
kw if
|
||||
kw if let
|
||||
kw loop
|
||||
kw match
|
||||
kw return
|
||||
kw self::
|
||||
kw true
|
||||
kw unsafe
|
||||
kw while
|
||||
kw while let
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_initializer_field_expr() {
|
||||
check(
|
||||
|
|
|
|||
|
|
@ -339,13 +339,20 @@ fn lhs(p: &mut Parser<'_>, r: Restrictions) -> Option<(CompletedMarker, BlockLik
|
|||
// // raw reference operator
|
||||
// let _ = &raw mut foo;
|
||||
// let _ = &raw const foo;
|
||||
// let _ = &raw foo;
|
||||
// }
|
||||
T![&] => {
|
||||
m = p.start();
|
||||
p.bump(T![&]);
|
||||
if p.at_contextual_kw(T![raw]) && [T![mut], T![const]].contains(&p.nth(1)) {
|
||||
p.bump_remap(T![raw]);
|
||||
p.bump_any();
|
||||
if p.at_contextual_kw(T![raw]) {
|
||||
if [T![mut], T![const]].contains(&p.nth(1)) {
|
||||
p.bump_remap(T![raw]);
|
||||
p.bump_any();
|
||||
} else if p.nth_at(1, SyntaxKind::IDENT) {
|
||||
// we treat raw as keyword in this case
|
||||
// &raw foo;
|
||||
p.bump_remap(T![raw]);
|
||||
}
|
||||
} else {
|
||||
p.eat(T![mut]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,25 @@ SOURCE_FILE
|
|||
NAME_REF
|
||||
IDENT "foo"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n "
|
||||
LET_STMT
|
||||
LET_KW "let"
|
||||
WHITESPACE " "
|
||||
WILDCARD_PAT
|
||||
UNDERSCORE "_"
|
||||
WHITESPACE " "
|
||||
EQ "="
|
||||
WHITESPACE " "
|
||||
REF_EXPR
|
||||
AMP "&"
|
||||
RAW_KW "raw"
|
||||
WHITESPACE " "
|
||||
PATH_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "foo"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n"
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ fn foo() {
|
|||
// raw reference operator
|
||||
let _ = &raw mut foo;
|
||||
let _ = &raw const foo;
|
||||
let _ = &raw foo;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue