Merge #9390
9390: fix: Improve type bound completions r=Veykril a=Veykril Closes #9389 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
1deb1d3209
@ -33,7 +33,7 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
|
|||||||
if !ctx.config.enable_self_on_the_fly {
|
if !ctx.config.enable_self_on_the_fly {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !ctx.is_trivial_path() || ctx.is_path_disallowed() {
|
if !ctx.is_trivial_path() || ctx.is_path_disallowed() || !ctx.expects_expression() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx.scope.process_all_names(&mut |name, def| {
|
ctx.scope.process_all_names(&mut |name, def| {
|
||||||
|
@ -36,6 +36,20 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches!(&ctx.completion_location, Some(ImmediateLocation::TypeBound)) {
|
||||||
|
ctx.scope.process_all_names(&mut |name, res| {
|
||||||
|
let add_resolution = match res {
|
||||||
|
ScopeDef::MacroDef(mac) => mac.is_fn_like(),
|
||||||
|
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 !ctx.expects_type() {
|
||||||
if let Some(hir::Adt::Enum(e)) =
|
if let Some(hir::Adt::Enum(e)) =
|
||||||
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
|
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
|
||||||
|
@ -36,6 +36,7 @@ pub(crate) enum ImmediateLocation {
|
|||||||
IdentPat,
|
IdentPat,
|
||||||
BlockExpr,
|
BlockExpr,
|
||||||
ItemList,
|
ItemList,
|
||||||
|
TypeBound,
|
||||||
// Fake file ast node
|
// Fake file ast node
|
||||||
Attribute(ast::Attr),
|
Attribute(ast::Attr),
|
||||||
// Fake file ast node
|
// Fake file ast node
|
||||||
@ -154,6 +155,13 @@ pub(crate) fn determine_location(
|
|||||||
ast::NameLike::Lifetime(lt) => lt.syntax().clone(),
|
ast::NameLike::Lifetime(lt) => lt.syntax().clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match_ast! {
|
||||||
|
match node {
|
||||||
|
ast::TypeBoundList(_it) => return Some(ImmediateLocation::TypeBound),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let parent = match node.parent() {
|
let parent = match node.parent() {
|
||||||
Some(parent) => match ast::MacroCall::cast(parent.clone()) {
|
Some(parent) => match ast::MacroCall::cast(parent.clone()) {
|
||||||
// When a path is being typed in an (Assoc)ItemList the parser will always emit a macro_call.
|
// When a path is being typed in an (Assoc)ItemList the parser will always emit a macro_call.
|
||||||
@ -195,6 +203,8 @@ pub(crate) fn determine_location(
|
|||||||
},
|
},
|
||||||
ast::TupleField(_it) => ImmediateLocation::TupleField,
|
ast::TupleField(_it) => ImmediateLocation::TupleField,
|
||||||
ast::TupleFieldList(_it) => ImmediateLocation::TupleField,
|
ast::TupleFieldList(_it) => ImmediateLocation::TupleField,
|
||||||
|
ast::TypeBound(_it) => ImmediateLocation::TypeBound,
|
||||||
|
ast::TypeBoundList(_it) => ImmediateLocation::TypeBound,
|
||||||
ast::AssocItemList(it) => match it.syntax().parent().map(|it| it.kind()) {
|
ast::AssocItemList(it) => match it.syntax().parent().map(|it| it.kind()) {
|
||||||
Some(IMPL) => ImmediateLocation::Impl,
|
Some(IMPL) => ImmediateLocation::Impl,
|
||||||
Some(TRAIT) => ImmediateLocation::Trait,
|
Some(TRAIT) => ImmediateLocation::Trait,
|
||||||
|
@ -9,6 +9,7 @@ mod use_tree;
|
|||||||
mod items;
|
mod items;
|
||||||
mod pattern;
|
mod pattern;
|
||||||
mod type_pos;
|
mod type_pos;
|
||||||
|
mod predicate;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
@ -28,6 +29,24 @@ use test_utils::assert_eq_text;
|
|||||||
|
|
||||||
use crate::{item::CompletionKind, CompletionConfig, CompletionItem};
|
use crate::{item::CompletionKind, CompletionConfig, CompletionItem};
|
||||||
|
|
||||||
|
/// Lots of basic item definitions
|
||||||
|
const BASE_FIXTURE: &str = r#"
|
||||||
|
enum Enum { TupleV(u32), RecordV { field: u32 }, UnitV }
|
||||||
|
use self::Enum::TupleV;
|
||||||
|
mod module {}
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
static STATIC: Unit = Unit;
|
||||||
|
const CONST: Unit = Unit;
|
||||||
|
struct Record { field: u32 }
|
||||||
|
struct Tuple(u32);
|
||||||
|
struct Unit;
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! makro {}
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
pub macro Clone {}
|
||||||
|
"#;
|
||||||
|
|
||||||
pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
|
pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
|
||||||
enable_postfix_completions: true,
|
enable_postfix_completions: true,
|
||||||
enable_imports_on_the_fly: true,
|
enable_imports_on_the_fly: true,
|
||||||
|
@ -1,19 +1,9 @@
|
|||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
|
||||||
use crate::tests::completion_list;
|
use crate::tests::{completion_list, BASE_FIXTURE};
|
||||||
|
|
||||||
fn check(ra_fixture: &str, expect: Expect) {
|
fn check(ra_fixture: &str, expect: Expect) {
|
||||||
let base = r#"#[rustc_builtin_macro]
|
let actual = completion_list(&format!("{}{}", BASE_FIXTURE, ra_fixture));
|
||||||
pub macro Clone {}
|
|
||||||
enum Enum { Variant }
|
|
||||||
struct Struct {}
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! foo {}
|
|
||||||
mod bar {}
|
|
||||||
const CONST: () = ();
|
|
||||||
trait Trait {}
|
|
||||||
"#;
|
|
||||||
let actual = completion_list(&format!("{}{}", base, ra_fixture));
|
|
||||||
expect.assert_eq(&actual)
|
expect.assert_eq(&actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +30,7 @@ fn in_mod_item_list() {
|
|||||||
sn tmod (Test module)
|
sn tmod (Test module)
|
||||||
sn tfn (Test function)
|
sn tfn (Test function)
|
||||||
sn macro_rules
|
sn macro_rules
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -68,9 +58,9 @@ fn in_source_file_item_list() {
|
|||||||
sn tmod (Test module)
|
sn tmod (Test module)
|
||||||
sn tfn (Test function)
|
sn tfn (Test function)
|
||||||
sn macro_rules
|
sn macro_rules
|
||||||
md bar
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
md module
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -122,8 +112,8 @@ fn in_qualified_path() {
|
|||||||
kw enum
|
kw enum
|
||||||
kw struct
|
kw struct
|
||||||
kw union
|
kw union
|
||||||
md bar
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
md module
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -184,9 +174,9 @@ fn in_impl_assoc_item_list() {
|
|||||||
kw fn
|
kw fn
|
||||||
kw const
|
kw const
|
||||||
kw type
|
kw type
|
||||||
md bar
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
md module
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -215,9 +205,9 @@ fn in_trait_assoc_item_list() {
|
|||||||
kw fn
|
kw fn
|
||||||
kw const
|
kw const
|
||||||
kw type
|
kw type
|
||||||
md bar
|
md module
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"##]],
|
"##]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,10 @@
|
|||||||
//! in [crate::completions::mod_].
|
//! in [crate::completions::mod_].
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
|
||||||
use crate::tests::completion_list;
|
use crate::tests::{completion_list, BASE_FIXTURE};
|
||||||
|
|
||||||
fn check(ra_fixture: &str, expect: Expect) {
|
fn check(ra_fixture: &str, expect: Expect) {
|
||||||
let base = r#"#[rustc_builtin_macro]
|
let actual = completion_list(&format!("{}{}", BASE_FIXTURE, ra_fixture));
|
||||||
pub macro Clone {}
|
|
||||||
enum Enum { Variant }
|
|
||||||
struct Struct {}
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! foo {}
|
|
||||||
mod bar {}
|
|
||||||
const CONST: () = ();
|
|
||||||
trait Trait {}
|
|
||||||
"#;
|
|
||||||
let actual = completion_list(&format!("{}{}", base, ra_fixture));
|
|
||||||
expect.assert_eq(&actual)
|
expect.assert_eq(&actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,10 +20,12 @@ impl Tra$0
|
|||||||
expect![[r##"
|
expect![[r##"
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
st Struct
|
st Record
|
||||||
md bar
|
st Tuple
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
bt u32
|
bt u32
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
@ -48,10 +40,12 @@ impl Trait for Str$0
|
|||||||
expect![[r##"
|
expect![[r##"
|
||||||
tt Trait
|
tt Trait
|
||||||
en Enum
|
en Enum
|
||||||
st Struct
|
st Record
|
||||||
md bar
|
st Tuple
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
ma foo!(…) #[macro_export] macro_rules! foo
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
bt u32
|
bt u32
|
||||||
"##]],
|
"##]],
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Completions tests for pattern position.
|
//! Completions tests for pattern position.
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
|
||||||
use crate::tests::completion_list;
|
use crate::tests::{completion_list, BASE_FIXTURE};
|
||||||
|
|
||||||
fn check(ra_fixture: &str, expect: Expect) {
|
fn check(ra_fixture: &str, expect: Expect) {
|
||||||
let actual = completion_list(ra_fixture);
|
let actual = completion_list(ra_fixture);
|
||||||
@ -9,19 +9,7 @@ fn check(ra_fixture: &str, expect: Expect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_with(ra_fixture: &str, expect: Expect) {
|
fn check_with(ra_fixture: &str, expect: Expect) {
|
||||||
let base = r#"
|
let actual = completion_list(&format!("{}\n{}", BASE_FIXTURE, ra_fixture));
|
||||||
enum Enum { TupleV(u32), RecordV { field: u32 }, UnitV }
|
|
||||||
use self::Enum::TupleV;
|
|
||||||
mod module {}
|
|
||||||
|
|
||||||
static STATIC: Unit = Unit;
|
|
||||||
const CONST: Unit = Unit;
|
|
||||||
struct Record { field: u32 }
|
|
||||||
struct Tuple(u32);
|
|
||||||
struct Unit
|
|
||||||
macro_rules! makro {}
|
|
||||||
"#;
|
|
||||||
let actual = completion_list(&format!("{}\n{}", base, ra_fixture));
|
|
||||||
expect.assert_eq(&actual)
|
expect.assert_eq(&actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,20 +109,21 @@ fn foo() {
|
|||||||
if let a$0
|
if let a$0
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r##"
|
||||||
kw mut
|
kw mut
|
||||||
|
en Enum
|
||||||
bn Record Record { field$1 }$0
|
bn Record Record { field$1 }$0
|
||||||
st Record
|
st Record
|
||||||
en Enum
|
|
||||||
bn Tuple Tuple($1)$0
|
bn Tuple Tuple($1)$0
|
||||||
st Tuple
|
st Tuple
|
||||||
md module
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
bn TupleV TupleV($1)$0
|
bn TupleV TupleV($1)$0
|
||||||
ev TupleV
|
ev TupleV
|
||||||
st Unit
|
|
||||||
ct CONST
|
ct CONST
|
||||||
ma makro!(…) macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"#]],
|
"##]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,15 +135,16 @@ fn foo() {
|
|||||||
let a$0
|
let a$0
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r##"
|
||||||
kw mut
|
kw mut
|
||||||
bn Record Record { field$1 }$0
|
bn Record Record { field$1 }$0
|
||||||
st Record
|
st Record
|
||||||
bn Tuple Tuple($1)$0
|
bn Tuple Tuple($1)$0
|
||||||
st Tuple
|
st Tuple
|
||||||
st Unit
|
st Unit
|
||||||
ma makro!(…) macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"#]],
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
"##]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,15 +155,16 @@ fn in_param() {
|
|||||||
fn foo(a$0) {
|
fn foo(a$0) {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r##"
|
||||||
kw mut
|
kw mut
|
||||||
bn Record Record { field$1 }: Record$0
|
bn Record Record { field$1 }: Record$0
|
||||||
st Record
|
st Record
|
||||||
bn Tuple Tuple($1): Tuple$0
|
bn Tuple Tuple($1): Tuple$0
|
||||||
st Tuple
|
st Tuple
|
||||||
st Unit
|
st Unit
|
||||||
ma makro!(…) macro_rules! makro
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
"#]],
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
"##]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
122
crates/ide_completion/src/tests/predicate.rs
Normal file
122
crates/ide_completion/src/tests/predicate.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//! Completion tests for predicates and bounds.
|
||||||
|
use expect_test::{expect, Expect};
|
||||||
|
|
||||||
|
use crate::tests::{completion_list, BASE_FIXTURE};
|
||||||
|
|
||||||
|
fn check(ra_fixture: &str, expect: Expect) {
|
||||||
|
let actual = completion_list(&format!("{}\n{}", BASE_FIXTURE, ra_fixture));
|
||||||
|
expect.assert_eq(&actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn predicate_start() {
|
||||||
|
// FIXME: `for` kw
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<'lt, T, const C: usize> where $0 {}
|
||||||
|
"#,
|
||||||
|
expect![[r##"
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Foo<…>
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
bt u32
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bound_for_type_pred() {
|
||||||
|
// FIXME: only show traits, macros and modules
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<'lt, T, const C: usize> where T: $0 {}
|
||||||
|
"#,
|
||||||
|
expect![[r##"
|
||||||
|
tt Trait
|
||||||
|
md module
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bound_for_lifetime_pred() {
|
||||||
|
// FIXME: should only show lifetimes here
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
|
||||||
|
"#,
|
||||||
|
expect![[r##"
|
||||||
|
tt Trait
|
||||||
|
md module
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bound_for_for_pred() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
|
||||||
|
"#,
|
||||||
|
expect![[r##"
|
||||||
|
tt Trait
|
||||||
|
md module
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn param_list_for_for_pred() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
|
||||||
|
"#,
|
||||||
|
expect![[r##"
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
md module
|
||||||
|
st Foo<…>
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
bt u32
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pred_on_fn_in_impl() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
impl Record {
|
||||||
|
fn method(self) where $0 {}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r##"
|
||||||
|
sp Self
|
||||||
|
tt Trait
|
||||||
|
en Enum
|
||||||
|
st Record
|
||||||
|
st Tuple
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
md module
|
||||||
|
st Unit
|
||||||
|
ma makro!(…) #[macro_export] macro_rules! makro
|
||||||
|
bt u32
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
//! Completions tests for use trees.
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
|
||||||
use crate::tests::completion_list;
|
use crate::tests::completion_list;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user