Skip to content

Commit 19fad54

Browse files
committed
Auto merge of rust-lang#12625 - yue4u:fix/non-exhaustive-variant, r=Veykril
fix: completes non exhaustive variant within the defining crate close rust-lang#12624
2 parents 6fc5c3c + 472ae16 commit 19fad54

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

crates/hir/src/lib.rs

+18
Original file line numberDiff line numberDiff line change
@@ -3497,12 +3497,30 @@ impl HasCrate for AssocItem {
34973497
}
34983498
}
34993499

3500+
impl HasCrate for Struct {
3501+
fn krate(&self, db: &dyn HirDatabase) -> Crate {
3502+
self.module(db).krate()
3503+
}
3504+
}
3505+
3506+
impl HasCrate for Union {
3507+
fn krate(&self, db: &dyn HirDatabase) -> Crate {
3508+
self.module(db).krate()
3509+
}
3510+
}
3511+
35003512
impl HasCrate for Field {
35013513
fn krate(&self, db: &dyn HirDatabase) -> Crate {
35023514
self.parent_def(db).module(db).krate()
35033515
}
35043516
}
35053517

3518+
impl HasCrate for Variant {
3519+
fn krate(&self, db: &dyn HirDatabase) -> Crate {
3520+
self.module(db).krate()
3521+
}
3522+
}
3523+
35063524
impl HasCrate for Function {
35073525
fn krate(&self, db: &dyn HirDatabase) -> Crate {
35083526
self.module(db).krate()

crates/ide-completion/src/render/variant.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Code common to structs, unions, and enum variants.
22
33
use crate::context::CompletionContext;
4-
use hir::{db::HirDatabase, HasAttrs, HasVisibility, HirDisplay, StructKind};
4+
use hir::{db::HirDatabase, HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind};
55
use ide_db::SnippetCap;
66
use itertools::Itertools;
77
use syntax::SmolStr;
@@ -70,7 +70,7 @@ pub(crate) fn render_tuple_lit(
7070
pub(crate) fn visible_fields(
7171
ctx: &CompletionContext,
7272
fields: &[hir::Field],
73-
item: impl HasAttrs,
73+
item: impl HasAttrs + HasCrate + Copy,
7474
) -> Option<(Vec<hir::Field>, bool)> {
7575
let module = ctx.module;
7676
let n_fields = fields.len();
@@ -79,9 +79,10 @@ pub(crate) fn visible_fields(
7979
.filter(|field| field.is_visible_from(ctx.db, module))
8080
.copied()
8181
.collect::<Vec<_>>();
82-
83-
let fields_omitted =
84-
n_fields - fields.len() > 0 || item.attrs(ctx.db).by_key("non_exhaustive").exists();
82+
let has_invisible_field = n_fields - fields.len() > 0;
83+
let is_foreign_non_exhaustive = item.attrs(ctx.db).by_key("non_exhaustive").exists()
84+
&& item.krate(ctx.db) != module.krate();
85+
let fields_omitted = has_invisible_field || is_foreign_non_exhaustive;
8586
Some((fields, fields_omitted))
8687
}
8788

crates/ide-completion/src/tests/special.rs

+40
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,46 @@ impl Foo {
540540
);
541541
}
542542

543+
#[test]
544+
fn completes_non_exhaustive_variant_within_the_defining_crate() {
545+
check(
546+
r#"
547+
enum Foo {
548+
#[non_exhaustive]
549+
Bar,
550+
Baz,
551+
}
552+
553+
fn foo(self) {
554+
Foo::$0
555+
}
556+
"#,
557+
expect![[r#"
558+
ev Bar Bar
559+
ev Baz Baz
560+
"#]],
561+
);
562+
563+
check(
564+
r#"
565+
//- /main.rs crate:main deps:e
566+
fn foo(self) {
567+
e::Foo::$0
568+
}
569+
570+
//- /e.rs crate:e
571+
enum Foo {
572+
#[non_exhaustive]
573+
Bar,
574+
Baz,
575+
}
576+
"#,
577+
expect![[r#"
578+
ev Baz Baz
579+
"#]],
580+
);
581+
}
582+
543583
#[test]
544584
fn completes_primitive_assoc_const() {
545585
cov_mark::check!(completes_primitive_assoc_const);

0 commit comments

Comments
 (0)