Auto merge of #12164 - Veykril:completion-rev, r=Veykril

internal: Remove `unqualified_path` completions module

cc https://github.com/rust-lang/rust-analyzer/issues/12144
This commit is contained in:
bors 2022-05-05 13:51:22 +00:00
commit 7dfd1cb572
14 changed files with 464 additions and 421 deletions

View file

@ -2,6 +2,7 @@
pub(crate) mod attribute;
pub(crate) mod dot;
pub(crate) mod expr;
pub(crate) mod extern_abi;
pub(crate) mod flyimport;
pub(crate) mod fn_param;
@ -16,7 +17,7 @@ pub(crate) mod qualified_path;
pub(crate) mod record;
pub(crate) mod snippet;
pub(crate) mod trait_impl;
pub(crate) mod unqualified_path;
pub(crate) mod r#type;
pub(crate) mod use_;
pub(crate) mod vis;

View file

@ -0,0 +1,49 @@
//! Completion of names from the current scope in expression position.
use hir::ScopeDef;
use crate::{
context::{PathCompletionCtx, PathKind, PathQualifierCtx},
CompletionContext, Completions,
};
pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_expr_path");
if ctx.is_path_disallowed() {
return;
}
let (&is_absolute_path, qualifier) = match &ctx.path_context {
Some(PathCompletionCtx {
kind: Some(PathKind::Expr), is_absolute_path, qualifier, ..
}) => (is_absolute_path, qualifier),
_ => return,
};
match qualifier {
Some(PathQualifierCtx { .. }) => return,
None if is_absolute_path => acc.add_crate_roots(ctx),
None => {
acc.add_nameref_keywords_with_colon(ctx);
if let Some(hir::Adt::Enum(e)) =
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
{
super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
acc.add_qualified_enum_variant(ctx, variant, path)
});
}
ctx.process_all_names(&mut |name, def| {
use hir::{GenericParam::*, ModuleDef::*};
let add_resolution = match def {
ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
// Don't suggest attribute macros and derives.
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
_ => true,
};
if add_resolution {
acc.add_resolution(ctx, name, def);
}
});
}
}
}

View file

@ -7,7 +7,7 @@ use crate::{
};
pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_unqualified_path");
let _p = profile::span("complete_item_list");
if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}

View file

@ -0,0 +1,90 @@
//! Completion of names from the current scope in type position.
use hir::ScopeDef;
use syntax::{ast, AstNode};
use crate::{
context::{PathCompletionCtx, PathKind, PathQualifierCtx},
patterns::ImmediateLocation,
CompletionContext, Completions,
};
pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_type_path");
if ctx.is_path_disallowed() {
return;
}
let (&is_absolute_path, qualifier) = match &ctx.path_context {
Some(PathCompletionCtx {
kind: Some(PathKind::Type), is_absolute_path, qualifier, ..
}) => (is_absolute_path, qualifier),
_ => return,
};
match qualifier {
Some(PathQualifierCtx { .. }) => return,
None if is_absolute_path => acc.add_crate_roots(ctx),
None => {
acc.add_nameref_keywords_with_colon(ctx);
if let Some(ImmediateLocation::TypeBound) = &ctx.completion_location {
ctx.process_all_names(&mut |name, res| {
let add_resolution = match res {
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
ScopeDef::ModuleDef(
hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_),
) => true,
_ => false,
};
if add_resolution {
acc.add_resolution(ctx, name, res);
}
});
return;
}
if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast)
{
if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
ctx.sema.resolve_path(&path_seg.parent_path())
{
trait_.items(ctx.sema.db).into_iter().for_each(|it| {
if let hir::AssocItem::TypeAlias(alias) = it {
acc.add_type_alias_with_eq(ctx, alias)
}
});
}
}
}
ctx.process_all_names(&mut |name, def| {
use hir::{GenericParam::*, ModuleDef::*};
let add_resolution = match def {
ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
// no values in type places
ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_))
| ScopeDef::Local(_) => false,
// unless its a constant in a generic arg list position
ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => {
ctx.expects_generic_arg()
}
ScopeDef::ImplSelfType(_) => {
!ctx.previous_token_is(syntax::T![impl])
&& !ctx.previous_token_is(syntax::T![for])
}
// Don't suggest attribute macros and derives.
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
// Type things are fine
ScopeDef::ModuleDef(
BuiltinType(_) | Adt(_) | Module(_) | Trait(_) | TypeAlias(_),
)
| ScopeDef::AdtSelfType(_)
| ScopeDef::Unknown
| ScopeDef::GenericParam(TypeParam(_)) => true,
};
if add_resolution {
acc.add_resolution(ctx, name, def);
}
});
}
}
}

View file

@ -1,289 +0,0 @@
//! Completion of names from the current scope, e.g. locals and imported items.
use hir::ScopeDef;
use syntax::{ast, AstNode};
use crate::{
context::{PathCompletionCtx, PathKind},
patterns::ImmediateLocation,
CompletionContext, Completions,
};
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_unqualified_path");
if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
match &ctx.path_context {
Some(PathCompletionCtx {
is_absolute_path: false,
qualifier: None,
kind: None | Some(PathKind::Expr | PathKind::Type),
..
}) => (),
_ => return,
}
acc.add_nameref_keywords(ctx);
match &ctx.completion_location {
Some(ImmediateLocation::TypeBound) => {
ctx.process_all_names(&mut |name, res| {
let add_resolution = match res {
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
ScopeDef::ModuleDef(hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_)) => {
true
}
_ => false,
};
if add_resolution {
acc.add_resolution(ctx, name, res);
}
});
return;
}
_ => (),
}
if !ctx.expects_type() {
if let Some(hir::Adt::Enum(e)) =
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
{
super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
acc.add_qualified_enum_variant(ctx, variant, path)
});
}
}
if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast) {
if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
ctx.sema.resolve_path(&path_seg.parent_path())
{
trait_.items(ctx.sema.db).into_iter().for_each(|it| {
if let hir::AssocItem::TypeAlias(alias) = it {
acc.add_type_alias_with_eq(ctx, alias)
}
});
}
}
}
ctx.process_all_names(&mut |name, res| {
let add_resolution = match res {
ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) | ScopeDef::Label(_) => {
cov_mark::hit!(unqualified_skip_lifetime_completion);
return;
}
ScopeDef::ImplSelfType(_) => {
!ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for])
}
// Don't suggest attribute macros and derives.
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
// no values in type places
ScopeDef::ModuleDef(
hir::ModuleDef::Function(_)
| hir::ModuleDef::Variant(_)
| hir::ModuleDef::Static(_),
)
| ScopeDef::Local(_) => !ctx.expects_type(),
// unless its a constant in a generic arg list position
ScopeDef::ModuleDef(hir::ModuleDef::Const(_))
| ScopeDef::GenericParam(hir::GenericParam::ConstParam(_)) => {
!ctx.expects_type() || ctx.expects_generic_arg()
}
_ => true,
};
if add_resolution {
acc.add_resolution(ctx, name, res);
}
});
}
#[cfg(test)]
mod tests {
use expect_test::{expect, Expect};
use crate::tests::{check_edit, completion_list_no_kw};
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list_no_kw(ra_fixture);
expect.assert_eq(&actual)
}
#[test]
fn completes_if_prefix_is_keyword() {
check_edit(
"wherewolf",
r#"
fn main() {
let wherewolf = 92;
drop(where$0)
}
"#,
r#"
fn main() {
let wherewolf = 92;
drop(wherewolf)
}
"#,
)
}
/// Regression test for issue #6091.
#[test]
fn correctly_completes_module_items_prefixed_with_underscore() {
check_edit(
"_alpha",
r#"
fn main() {
_$0
}
fn _alpha() {}
"#,
r#"
fn main() {
_alpha()$0
}
fn _alpha() {}
"#,
)
}
#[test]
fn completes_prelude() {
check(
r#"
//- /main.rs crate:main deps:std
fn foo() { let x: $0 }
//- /std/lib.rs crate:std
pub mod prelude {
pub mod rust_2018 {
pub struct Option;
}
}
"#,
expect![[r#"
md std
st Option
bt u32
"#]],
);
}
#[test]
fn completes_prelude_macros() {
check(
r#"
//- /main.rs crate:main deps:std
fn f() {$0}
//- /std/lib.rs crate:std
pub mod prelude {
pub mod rust_2018 {
pub use crate::concat;
}
}
mod macros {
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat { }
}
"#,
expect![[r#"
fn f() fn()
ma concat!() macro_rules! concat
md std
bt u32
"#]],
);
}
#[test]
fn completes_std_prelude_if_core_is_defined() {
check(
r#"
//- /main.rs crate:main deps:core,std
fn foo() { let x: $0 }
//- /core/lib.rs crate:core
pub mod prelude {
pub mod rust_2018 {
pub struct Option;
}
}
//- /std/lib.rs crate:std deps:core
pub mod prelude {
pub mod rust_2018 {
pub struct String;
}
}
"#,
expect![[r#"
md core
md std
st String
bt u32
"#]],
);
}
#[test]
fn respects_doc_hidden() {
check(
r#"
//- /lib.rs crate:lib deps:std
fn f() {
format_$0
}
//- /std.rs crate:std
#[doc(hidden)]
#[macro_export]
macro_rules! format_args_nl {
() => {}
}
pub mod prelude {
pub mod rust_2018 {}
}
"#,
expect![[r#"
fn f() fn()
md std
bt u32
"#]],
);
}
#[test]
fn respects_doc_hidden_in_assoc_item_list() {
check(
r#"
//- /lib.rs crate:lib deps:std
struct S;
impl S {
format_$0
}
//- /std.rs crate:std
#[doc(hidden)]
#[macro_export]
macro_rules! format_args_nl {
() => {}
}
pub mod prelude {
pub mod rust_2018 {}
}
"#,
expect![[r#"
md std
"#]],
);
}
}

View file

@ -71,6 +71,10 @@ pub(crate) struct PathCompletionCtx {
pub(super) is_absolute_path: bool,
/// The qualifier of the current path if it exists.
pub(super) qualifier: Option<PathQualifierCtx>,
#[allow(dead_code)]
// FIXME: use this
/// The parent of the path we are completing.
pub(super) parent: Option<ast::Path>,
pub(super) kind: Option<PathKind>,
/// Whether the path segment has type args or not.
pub(super) has_type_args: bool,
@ -949,13 +953,14 @@ impl<'a> CompletionContext<'a> {
let mut path_ctx = PathCompletionCtx {
has_call_parens: false,
has_macro_bang: false,
is_absolute_path: false,
qualifier: None,
parent: path.parent_path(),
kind: None,
has_type_args: false,
can_be_stmt: false,
in_loop_body: false,
has_macro_bang: false,
kind: None,
};
let mut pat_ctx = None;
path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());

View file

@ -144,34 +144,38 @@ pub fn completions(
config: &CompletionConfig,
position: FilePosition,
) -> Option<Completions> {
let ctx = CompletionContext::new(db, position, config)?;
let ctx = &CompletionContext::new(db, position, config)?;
let mut acc = Completions::default();
completions::attribute::complete_attribute(&mut acc, &ctx);
completions::attribute::complete_derive(&mut acc, &ctx);
completions::attribute::complete_known_attribute_input(&mut acc, &ctx);
completions::dot::complete_dot(&mut acc, &ctx);
completions::extern_abi::complete_extern_abi(&mut acc, &ctx);
completions::flyimport::import_on_the_fly(&mut acc, &ctx);
completions::fn_param::complete_fn_param(&mut acc, &ctx);
completions::format_string::format_string(&mut acc, &ctx);
completions::item_list::complete_item_list(&mut acc, &ctx);
completions::inferred_type(&mut acc, &ctx);
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
completions::lifetime::complete_label(&mut acc, &ctx);
completions::lifetime::complete_lifetime(&mut acc, &ctx);
completions::mod_::complete_mod(&mut acc, &ctx);
completions::pattern::complete_pattern(&mut acc, &ctx);
completions::postfix::complete_postfix(&mut acc, &ctx);
completions::qualified_path::complete_qualified_path(&mut acc, &ctx);
completions::record::complete_record_literal(&mut acc, &ctx);
completions::record::complete_record(&mut acc, &ctx);
completions::snippet::complete_expr_snippet(&mut acc, &ctx);
completions::snippet::complete_item_snippet(&mut acc, &ctx);
completions::trait_impl::complete_trait_impl(&mut acc, &ctx);
completions::unqualified_path::complete_unqualified_path(&mut acc, &ctx);
completions::use_::complete_use_tree(&mut acc, &ctx);
completions::vis::complete_vis(&mut acc, &ctx);
{
let acc = &mut acc;
completions::attribute::complete_attribute(acc, ctx);
completions::attribute::complete_derive(acc, ctx);
completions::attribute::complete_known_attribute_input(acc, ctx);
completions::dot::complete_dot(acc, ctx);
completions::expr::complete_expr_path(acc, ctx);
completions::extern_abi::complete_extern_abi(acc, ctx);
completions::flyimport::import_on_the_fly(acc, ctx);
completions::fn_param::complete_fn_param(acc, ctx);
completions::format_string::format_string(acc, ctx);
completions::item_list::complete_item_list(acc, ctx);
completions::inferred_type(acc, ctx);
completions::keyword::complete_expr_keyword(acc, ctx);
completions::lifetime::complete_label(acc, ctx);
completions::lifetime::complete_lifetime(acc, ctx);
completions::mod_::complete_mod(acc, ctx);
completions::pattern::complete_pattern(acc, ctx);
completions::postfix::complete_postfix(acc, ctx);
completions::qualified_path::complete_qualified_path(acc, ctx);
completions::record::complete_record_literal(acc, ctx);
completions::record::complete_record(acc, ctx);
completions::snippet::complete_expr_snippet(acc, ctx);
completions::snippet::complete_item_snippet(acc, ctx);
completions::trait_impl::complete_trait_impl(acc, ctx);
completions::r#type::complete_type_path(acc, ctx);
completions::use_::complete_use_tree(acc, ctx);
completions::vis::complete_vis(acc, ctx);
}
Some(acc)
}

View file

@ -10,6 +10,7 @@
mod attribute;
mod expression;
mod flyimport;
mod fn_param;
mod item_list;
mod item;
@ -17,10 +18,10 @@ mod pattern;
mod predicate;
mod proc_macros;
mod record;
mod special;
mod type_pos;
mod use_tree;
mod visibility;
mod flyimport;
use std::mem;

View file

@ -48,7 +48,7 @@ fn baz() {
un Union
ev TupleV() TupleV(u32)
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -57,8 +57,8 @@ fn baz() {
kw match
kw mut
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -91,7 +91,7 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
lc param1 i32
lc param2 i32
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -99,8 +99,8 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -111,7 +111,6 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
#[test]
fn completes_all_the_things_in_fn_body() {
cov_mark::check!(unqualified_skip_lifetime_completion);
check(
r#"
use non_existant::Unresolved;
@ -146,7 +145,7 @@ impl Unit {
ev TupleV() TupleV(u32)
bt u32
kw const
kw crate
kw crate::
kw enum
kw extern
kw false
@ -160,10 +159,10 @@ impl Unit {
kw match
kw mod
kw return
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw true
kw type
@ -224,7 +223,7 @@ fn complete_in_block() {
fn foo() fn()
bt u32
kw const
kw crate
kw crate::
kw enum
kw extern
kw false
@ -238,10 +237,10 @@ fn complete_in_block() {
kw match
kw mod
kw return
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw true
kw type
@ -270,7 +269,7 @@ fn complete_after_if_expr() {
fn foo() fn()
bt u32
kw const
kw crate
kw crate::
kw else
kw else if
kw enum
@ -286,10 +285,10 @@ fn complete_after_if_expr() {
kw match
kw mod
kw return
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw true
kw type
@ -318,7 +317,7 @@ fn complete_in_match_arm() {
expect![[r#"
fn foo() fn()
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -326,8 +325,8 @@ fn complete_in_match_arm() {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -346,7 +345,7 @@ fn completes_in_loop_ctx() {
kw break
kw const
kw continue
kw crate
kw crate::
kw enum
kw extern
kw false
@ -360,10 +359,10 @@ fn completes_in_loop_ctx() {
kw match
kw mod
kw return
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw true
kw type
@ -386,7 +385,7 @@ fn completes_in_let_initializer() {
expect![[r#"
fn main() fn()
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -394,8 +393,8 @@ fn completes_in_let_initializer() {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -421,7 +420,7 @@ fn foo() {
fn foo() fn()
st Foo
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -429,8 +428,8 @@ fn foo() {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -457,7 +456,7 @@ fn foo() {
fn foo() fn()
lc bar i32
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -465,8 +464,8 @@ fn foo() {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -489,7 +488,7 @@ fn quux(x: i32) {
lc x i32
ma m!() macro_rules! m
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -497,8 +496,8 @@ fn quux(x: i32) {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while
@ -517,7 +516,7 @@ fn quux(x: i32) {
lc x i32
ma m!() macro_rules! m
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -525,8 +524,8 @@ fn quux(x: i32) {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while

View file

@ -27,9 +27,9 @@ impl Tra$0
tt Trait
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
)
}
@ -50,9 +50,9 @@ impl Trait for Str$0
tt Trait
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
)
}

View file

@ -26,9 +26,9 @@ struct Foo<'lt, T, const C: usize> where $0 {}
tt Trait
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -43,9 +43,9 @@ struct Foo<'lt, T, const C: usize> where T: $0 {}
ma makro!() macro_rules! makro
md module
tt Trait
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -62,9 +62,9 @@ struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
ma makro!() macro_rules! makro
md module
tt Trait
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -79,9 +79,9 @@ struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
ma makro!() macro_rules! makro
md module
tt Trait
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -103,9 +103,9 @@ struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
tt Trait
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -129,9 +129,9 @@ impl Record {
tt Trait
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}

View file

@ -167,7 +167,7 @@ fn main() {
tt Default
tt Sized
bt u32
kw crate
kw crate::
kw false
kw for
kw if
@ -175,8 +175,8 @@ fn main() {
kw loop
kw match
kw return
kw self
kw super
kw self::
kw super::
kw true
kw unsafe
kw while

View file

@ -0,0 +1,183 @@
use expect_test::{expect, Expect};
use crate::tests::{check_edit, completion_list_no_kw};
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list_no_kw(ra_fixture);
expect.assert_eq(&actual)
}
#[test]
fn completes_if_prefix_is_keyword() {
check_edit(
"wherewolf",
r#"
fn main() {
let wherewolf = 92;
drop(where$0)
}
"#,
r#"
fn main() {
let wherewolf = 92;
drop(wherewolf)
}
"#,
)
}
/// Regression test for issue #6091.
#[test]
fn correctly_completes_module_items_prefixed_with_underscore() {
check_edit(
"_alpha",
r#"
fn main() {
_$0
}
fn _alpha() {}
"#,
r#"
fn main() {
_alpha()$0
}
fn _alpha() {}
"#,
)
}
#[test]
fn completes_prelude() {
check(
r#"
//- /main.rs crate:main deps:std
fn foo() { let x: $0 }
//- /std/lib.rs crate:std
pub mod prelude {
pub mod rust_2018 {
pub struct Option;
}
}
"#,
expect![[r#"
md std
st Option
bt u32
"#]],
);
}
#[test]
fn completes_prelude_macros() {
check(
r#"
//- /main.rs crate:main deps:std
fn f() {$0}
//- /std/lib.rs crate:std
pub mod prelude {
pub mod rust_2018 {
pub use crate::concat;
}
}
mod macros {
#[rustc_builtin_macro]
#[macro_export]
macro_rules! concat { }
}
"#,
expect![[r#"
fn f() fn()
ma concat!() macro_rules! concat
md std
bt u32
"#]],
);
}
#[test]
fn completes_std_prelude_if_core_is_defined() {
check(
r#"
//- /main.rs crate:main deps:core,std
fn foo() { let x: $0 }
//- /core/lib.rs crate:core
pub mod prelude {
pub mod rust_2018 {
pub struct Option;
}
}
//- /std/lib.rs crate:std deps:core
pub mod prelude {
pub mod rust_2018 {
pub struct String;
}
}
"#,
expect![[r#"
md core
md std
st String
bt u32
"#]],
);
}
#[test]
fn respects_doc_hidden() {
check(
r#"
//- /lib.rs crate:lib deps:std
fn f() {
format_$0
}
//- /std.rs crate:std
#[doc(hidden)]
#[macro_export]
macro_rules! format_args_nl {
() => {}
}
pub mod prelude {
pub mod rust_2018 {}
}
"#,
expect![[r#"
fn f() fn()
md std
bt u32
"#]],
);
}
#[test]
fn respects_doc_hidden_in_assoc_item_list() {
check(
r#"
//- /lib.rs crate:lib deps:std
struct S;
impl S {
format_$0
}
//- /std.rs crate:std
#[doc(hidden)]
#[macro_export]
macro_rules! format_args_nl {
() => {}
}
pub mod prelude {
pub mod rust_2018 {}
}
"#,
expect![[r#"
md std
"#]],
);
}

View file

@ -29,9 +29,9 @@ struct Foo<'lt, T, const C: usize> {
tp T
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
)
}
@ -55,12 +55,12 @@ struct Foo<'lt, T, const C: usize>(f$0);
tp T
un Union
bt u32
kw crate
kw crate::
kw pub
kw pub(crate)
kw pub(super)
kw self
kw super
kw self::
kw super::
"#]],
)
}
@ -82,9 +82,9 @@ fn x<'lt, T, const C: usize>() -> $0
tp T
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -108,9 +108,9 @@ const FOO: $0 = Foo(2);
un Union
bt u32
it Foo<i32>
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -135,9 +135,9 @@ fn f2() {
un Union
bt u32
it i32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -164,9 +164,9 @@ fn f2() {
un Union
bt u32
it u64
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -190,9 +190,9 @@ fn f2(x: u64) -> $0 {
un Union
bt u32
it u64
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -217,9 +217,9 @@ fn f2(x: $0) {
un Union
bt u32
it i32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -252,9 +252,9 @@ fn foo<'lt, T, const C: usize>() {
un Union
bt u32
it a::Foo<a::Foo<i32>>
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -282,9 +282,9 @@ fn foo<'lt, T, const C: usize>() {
un Union
bt u32
it Foo<i32>
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
}
@ -309,9 +309,9 @@ fn foo<'lt, T, const C: usize>() {
tp T
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
check(
@ -359,9 +359,9 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
tp T
un Union
bt u32
kw crate
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
check(