mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Auto merge of #17513 - roife:fix-issue-17500, r=Veykril
fix: completions after async kw fix #17500 ### Changes 1. fix completions after async kw 2. fix completions for `async` kw in trait
This commit is contained in:
		
						commit
						b6422dcaf1
					
				@ -82,17 +82,30 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
 | 
				
			|||||||
    let no_vis_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
 | 
					    let no_vis_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
 | 
				
			||||||
    let in_block = kind.is_none();
 | 
					    let in_block = kind.is_none();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let missing_qualifiers = [
 | 
				
			||||||
 | 
					        ctx.qualifier_ctx.unsafe_tok.is_none().then_some(("unsafe", "unsafe $0")),
 | 
				
			||||||
 | 
					        ctx.qualifier_ctx.async_tok.is_none().then_some(("async", "async $0")),
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if !in_trait_impl {
 | 
					    if !in_trait_impl {
 | 
				
			||||||
        if ctx.qualifier_ctx.unsafe_tok.is_some() {
 | 
					        // handle qualifier tokens
 | 
				
			||||||
 | 
					        if missing_qualifiers.iter().any(Option::is_none) {
 | 
				
			||||||
 | 
					            // only complete missing qualifiers
 | 
				
			||||||
 | 
					            missing_qualifiers.iter().filter_map(|x| *x).for_each(|(kw, snippet)| {
 | 
				
			||||||
 | 
					                add_keyword(kw, snippet);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if in_item_list || in_assoc_non_trait_impl {
 | 
					            if in_item_list || in_assoc_non_trait_impl {
 | 
				
			||||||
                add_keyword("fn", "fn $1($2) {\n    $0\n}");
 | 
					                add_keyword("fn", "fn $1($2) {\n    $0\n}");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if in_item_list {
 | 
					
 | 
				
			||||||
 | 
					            if ctx.qualifier_ctx.unsafe_tok.is_some() && in_item_list {
 | 
				
			||||||
                add_keyword("trait", "trait $1 {\n    $0\n}");
 | 
					                add_keyword("trait", "trait $1 {\n    $0\n}");
 | 
				
			||||||
                if no_vis_qualifiers {
 | 
					                if no_vis_qualifiers {
 | 
				
			||||||
                    add_keyword("impl", "impl $1 {\n    $0\n}");
 | 
					                    add_keyword("impl", "impl $1 {\n    $0\n}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -100,7 +113,6 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
 | 
				
			|||||||
            add_keyword("enum", "enum $1 {\n    $0\n}");
 | 
					            add_keyword("enum", "enum $1 {\n    $0\n}");
 | 
				
			||||||
            add_keyword("mod", "mod $0");
 | 
					            add_keyword("mod", "mod $0");
 | 
				
			||||||
            add_keyword("static", "static $0");
 | 
					            add_keyword("static", "static $0");
 | 
				
			||||||
            add_keyword("async", "async $0");
 | 
					 | 
				
			||||||
            add_keyword("struct", "struct $0");
 | 
					            add_keyword("struct", "struct $0");
 | 
				
			||||||
            add_keyword("trait", "trait $1 {\n    $0\n}");
 | 
					            add_keyword("trait", "trait $1 {\n    $0\n}");
 | 
				
			||||||
            add_keyword("union", "union $1 {\n    $0\n}");
 | 
					            add_keyword("union", "union $1 {\n    $0\n}");
 | 
				
			||||||
@ -129,6 +141,7 @@ fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option
 | 
				
			|||||||
            add_keyword("fn", "fn $1($2) {\n    $0\n}");
 | 
					            add_keyword("fn", "fn $1($2) {\n    $0\n}");
 | 
				
			||||||
            add_keyword("unsafe", "unsafe $0");
 | 
					            add_keyword("unsafe", "unsafe $0");
 | 
				
			||||||
            add_keyword("const", "const $0");
 | 
					            add_keyword("const", "const $0");
 | 
				
			||||||
 | 
					            add_keyword("async", "async $0");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -57,6 +57,7 @@ mod tests {
 | 
				
			|||||||
        check(
 | 
					        check(
 | 
				
			||||||
            r"fn my_fn() { unsafe $0 }",
 | 
					            r"fn my_fn() { unsafe $0 }",
 | 
				
			||||||
            expect![[r#"
 | 
					            expect![[r#"
 | 
				
			||||||
 | 
					                kw async
 | 
				
			||||||
                kw fn
 | 
					                kw fn
 | 
				
			||||||
                kw impl
 | 
					                kw impl
 | 
				
			||||||
                kw trait
 | 
					                kw trait
 | 
				
			||||||
 | 
				
			|||||||
@ -46,13 +46,15 @@ pub(crate) enum Visible {
 | 
				
			|||||||
/// Existing qualifiers for the thing we are currently completing.
 | 
					/// Existing qualifiers for the thing we are currently completing.
 | 
				
			||||||
#[derive(Debug, Default)]
 | 
					#[derive(Debug, Default)]
 | 
				
			||||||
pub(crate) struct QualifierCtx {
 | 
					pub(crate) struct QualifierCtx {
 | 
				
			||||||
 | 
					    // TODO: Add try_tok and default_tok
 | 
				
			||||||
 | 
					    pub(crate) async_tok: Option<SyntaxToken>,
 | 
				
			||||||
    pub(crate) unsafe_tok: Option<SyntaxToken>,
 | 
					    pub(crate) unsafe_tok: Option<SyntaxToken>,
 | 
				
			||||||
    pub(crate) vis_node: Option<ast::Visibility>,
 | 
					    pub(crate) vis_node: Option<ast::Visibility>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl QualifierCtx {
 | 
					impl QualifierCtx {
 | 
				
			||||||
    pub(crate) fn none(&self) -> bool {
 | 
					    pub(crate) fn none(&self) -> bool {
 | 
				
			||||||
        self.unsafe_tok.is_none() && self.vis_node.is_none()
 | 
					        self.async_tok.is_none() && self.unsafe_tok.is_none() && self.vis_node.is_none()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1287,10 +1287,15 @@ fn classify_name_ref(
 | 
				
			|||||||
                syntax::algo::non_trivia_sibling(top.clone().into(), syntax::Direction::Prev)
 | 
					                syntax::algo::non_trivia_sibling(top.clone().into(), syntax::Direction::Prev)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if error_node.kind() == SyntaxKind::ERROR {
 | 
					                if error_node.kind() == SyntaxKind::ERROR {
 | 
				
			||||||
                    qualifier_ctx.unsafe_tok = error_node
 | 
					                    for token in
 | 
				
			||||||
                        .children_with_tokens()
 | 
					                        error_node.children_with_tokens().filter_map(NodeOrToken::into_token)
 | 
				
			||||||
                        .filter_map(NodeOrToken::into_token)
 | 
					                    {
 | 
				
			||||||
                        .find(|it| it.kind() == T![unsafe]);
 | 
					                        match token.kind() {
 | 
				
			||||||
 | 
					                            SyntaxKind::UNSAFE_KW => qualifier_ctx.unsafe_tok = Some(token),
 | 
				
			||||||
 | 
					                            SyntaxKind::ASYNC_KW => qualifier_ctx.async_tok = Some(token),
 | 
				
			||||||
 | 
					                            _ => {}
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    qualifier_ctx.vis_node = error_node.children().find_map(ast::Visibility::cast);
 | 
					                    qualifier_ctx.vis_node = error_node.children().find_map(ast::Visibility::cast);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -123,6 +123,7 @@ fn after_unsafe_token() {
 | 
				
			|||||||
    check(
 | 
					    check(
 | 
				
			||||||
        r#"unsafe $0"#,
 | 
					        r#"unsafe $0"#,
 | 
				
			||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
            kw impl
 | 
					            kw impl
 | 
				
			||||||
            kw trait
 | 
					            kw trait
 | 
				
			||||||
@ -130,6 +131,17 @@ fn after_unsafe_token() {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn after_async_token() {
 | 
				
			||||||
 | 
					    check(
 | 
				
			||||||
 | 
					        r#"async $0"#,
 | 
				
			||||||
 | 
					        expect![[r#"
 | 
				
			||||||
 | 
					            kw fn
 | 
				
			||||||
 | 
					            kw unsafe
 | 
				
			||||||
 | 
					        "#]],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn after_visibility() {
 | 
					fn after_visibility() {
 | 
				
			||||||
    check(
 | 
					    check(
 | 
				
			||||||
@ -157,6 +169,7 @@ fn after_visibility_unsafe() {
 | 
				
			|||||||
    check(
 | 
					    check(
 | 
				
			||||||
        r#"pub unsafe $0"#,
 | 
					        r#"pub unsafe $0"#,
 | 
				
			||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
            kw trait
 | 
					            kw trait
 | 
				
			||||||
        "#]],
 | 
					        "#]],
 | 
				
			||||||
@ -170,6 +183,7 @@ fn in_impl_assoc_item_list() {
 | 
				
			|||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
            ma makro!(…)  macro_rules! makro
 | 
					            ma makro!(…)  macro_rules! makro
 | 
				
			||||||
            md module
 | 
					            md module
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw const
 | 
					            kw const
 | 
				
			||||||
            kw crate::
 | 
					            kw crate::
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
@ -189,6 +203,7 @@ fn in_impl_assoc_item_list_after_attr() {
 | 
				
			|||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
            ma makro!(…)  macro_rules! makro
 | 
					            ma makro!(…)  macro_rules! makro
 | 
				
			||||||
            md module
 | 
					            md module
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw const
 | 
					            kw const
 | 
				
			||||||
            kw crate::
 | 
					            kw crate::
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
@ -208,6 +223,7 @@ fn in_trait_assoc_item_list() {
 | 
				
			|||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
            ma makro!(…) macro_rules! makro
 | 
					            ma makro!(…) macro_rules! makro
 | 
				
			||||||
            md module
 | 
					            md module
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw const
 | 
					            kw const
 | 
				
			||||||
            kw crate::
 | 
					            kw crate::
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
@ -225,6 +241,7 @@ fn in_trait_assoc_fn_missing_body() {
 | 
				
			|||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
            ma makro!(…) macro_rules! makro
 | 
					            ma makro!(…) macro_rules! makro
 | 
				
			||||||
            md module
 | 
					            md module
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw const
 | 
					            kw const
 | 
				
			||||||
            kw crate::
 | 
					            kw crate::
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
@ -242,6 +259,7 @@ fn in_trait_assoc_const_missing_body() {
 | 
				
			|||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
            ma makro!(…) macro_rules! makro
 | 
					            ma makro!(…) macro_rules! makro
 | 
				
			||||||
            md module
 | 
					            md module
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw const
 | 
					            kw const
 | 
				
			||||||
            kw crate::
 | 
					            kw crate::
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
@ -259,6 +277,7 @@ fn in_trait_assoc_type_aliases_missing_ty() {
 | 
				
			|||||||
        expect![[r#"
 | 
					        expect![[r#"
 | 
				
			||||||
            ma makro!(…) macro_rules! makro
 | 
					            ma makro!(…) macro_rules! makro
 | 
				
			||||||
            md module
 | 
					            md module
 | 
				
			||||||
 | 
					            kw async
 | 
				
			||||||
            kw const
 | 
					            kw const
 | 
				
			||||||
            kw crate::
 | 
					            kw crate::
 | 
				
			||||||
            kw fn
 | 
					            kw fn
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user