Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22385 from ChayimFriedman2/import-variant
fix: Autoimport enum variants
| -rw-r--r-- | crates/hir-def/src/import_map.rs | 36 | ||||
| -rw-r--r-- | crates/hir/src/symbols.rs | 2 | ||||
| -rw-r--r-- | crates/ide-assists/src/handlers/auto_import.rs | 56 | ||||
| -rw-r--r-- | crates/ide-completion/src/render.rs | 2 | ||||
| -rw-r--r-- | crates/ide-completion/src/tests/expression.rs | 1 | ||||
| -rw-r--r-- | crates/ide-db/src/test_data/test_symbol_index_collection.txt | 4 |
6 files changed, 95 insertions, 6 deletions
diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index ba077b1b2e..f8be211bf9 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -12,7 +12,7 @@ use span::Edition; use stdx::format_to; use crate::{ - AssocItemId, AttrDefId, Complete, FxIndexMap, ModuleDefId, ModuleId, TraitId, + AdtId, AssocItemId, AttrDefId, Complete, EnumId, FxIndexMap, ModuleDefId, ModuleId, TraitId, attrs::AttrFlags, db::DefDatabase, item_scope::{ImportOrExternCrate, ItemInNs}, @@ -208,7 +208,8 @@ impl ImportMap { complete: do_not_complete, }; - if let Some(ModuleDefId::TraitId(tr)) = item.as_module_def_id() { + let module_def = item.as_module_def_id(); + if let Some(ModuleDefId::TraitId(tr)) = module_def { Self::collect_trait_assoc_items( db, &mut map, @@ -216,6 +217,8 @@ impl ImportMap { matches!(item, ItemInNs::Types(_)), &import_info, ); + } else if let Some(ModuleDefId::AdtId(AdtId::EnumId(enum_))) = module_def { + Self::collect_enum_variants(db, &mut map, enum_, &import_info); } let (infos, _) = @@ -224,7 +227,7 @@ impl ImportMap { infos.push(import_info); // If we've just added a module, descend into it. - if let Some(ModuleDefId::ModuleId(mod_id)) = item.as_module_def_id() { + if let Some(ModuleDefId::ModuleId(mod_id)) = module_def { worklist.push(mod_id); } } @@ -234,6 +237,33 @@ impl ImportMap { map } + fn collect_enum_variants( + db: &dyn DefDatabase, + map: &mut ImportMapIndex, + enum_: EnumId, + enum_import_info: &ImportInfo, + ) { + let _p = tracing::info_span!("collect_enum_variants").entered(); + for (variant_name, &(variant, _)) in &enum_.enum_variants(db).variants { + let attr_id = variant.into(); + let attrs = AttrFlags::query(db, attr_id); + let do_not_complete = Complete::extract(false, attrs); + let variant_info = ImportInfo { + container: enum_import_info.container, + name: variant_name.clone(), + is_doc_hidden: attrs.contains(AttrFlags::IS_DOC_HIDDEN), + is_unstable: attrs.contains(AttrFlags::IS_UNSTABLE), + complete: do_not_complete, + }; + + let (infos, _) = map + .entry(ItemInNs::Types(variant.into())) + .or_insert_with(|| (SmallVec::new(), IsTraitAssocItem::No)); + infos.reserve_exact(1); + infos.push(variant_info); + } + } + fn collect_trait_assoc_items( db: &dyn DefDatabase, map: &mut ImportMapIndex, diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs index a00c3219b2..c4040c1c00 100644 --- a/crates/hir/src/symbols.rs +++ b/crates/hir/src/symbols.rs @@ -191,7 +191,7 @@ impl<'a> SymbolCollector<'a> { this.with_container_name(Some(enum_name), |this| { let variants = id.enum_variants(this.db); for (variant_name, (variant_id, _)) in &variants.variants { - this.push_decl(*variant_id, variant_name, true, None); + this.push_decl(*variant_id, variant_name, false, None); } }); } diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs index ac0bae7cd9..d6e459d044 100644 --- a/crates/ide-assists/src/handlers/auto_import.rs +++ b/crates/ide-assists/src/handlers/auto_import.rs @@ -2037,4 +2037,60 @@ fn baz() { "Import `foo::Ext` without `as _`", ); } + + #[test] + fn local_enum_variant() { + check_assist( + auto_import, + r#" +mod foo { + pub enum ControlFlow { + Continue, + } +} + +fn main() { + Continue$0; +} + "#, + r#" +use foo::ControlFlow::Continue; + +mod foo { + pub enum ControlFlow { + Continue, + } +} + +fn main() { + Continue; +} + "#, + ); + } + + #[test] + fn foreign_enum_variant() { + check_assist( + auto_import, + r#" +//- /foo.rs crate:foo +pub enum ControlFlow { + Continue, +} + +//- /main.rs crate:main deps:foo +fn main() { + Continue$0; +} + "#, + r#" +use foo::ControlFlow::Continue; + +fn main() { + Continue; +} + "#, + ); + } } diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 575c869093..bc71c1da2b 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -1067,6 +1067,8 @@ fn main() { "#, expect![[r#" ev dep::test_mod_b::Enum::Variant dep::test_mod_b::Enum::Variant [type_could_unify] + ev Variant Variant [type_could_unify+requires_import] + ev Variant Variant [requires_import] ex dep::test_mod_b::Enum::Variant [type_could_unify] md dep:: [] fn main() fn() [] diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs index e2baf42848..b5465ee87a 100644 --- a/crates/ide-completion/src/tests/expression.rs +++ b/crates/ide-completion/src/tests/expression.rs @@ -1055,6 +1055,7 @@ fn brr() { fn brr() fn() st YoloVariant YoloVariant st YoloVariant {…} YoloVariant { f: usize } + ev Yolo(…) (use HH::Yolo) Yolo(YoloVariant) bt u32 u32 kw const kw crate:: diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 1b20a574bd..a84f75cb4e 100644 --- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -38,7 +38,7 @@ "Enum", ), is_alias: false, - is_assoc: true, + is_assoc: false, is_import: false, do_not_complete: Yes, _marker: PhantomData<&()>, @@ -110,7 +110,7 @@ "Enum", ), is_alias: false, - is_assoc: true, + is_assoc: false, is_import: false, do_not_complete: Yes, _marker: PhantomData<&()>, |