Skip to content

Commit 067b4a3

Browse files
authored
Merge pull request #18645 from Veykril/push-yruoyrvrsntw
fix: Non-exhaustive structs may be empty
2 parents d824871 + 55a7ee8 commit 067b4a3

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,6 @@ impl<'db> PatCx for MatchCheckCtx<'db> {
383383
} else {
384384
let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap();
385385

386-
// Whether we must not match the fields of this variant exhaustively.
387-
let is_non_exhaustive =
388-
LazyCell::new(|| self.is_foreign_non_exhaustive(adt));
389386
let visibilities = LazyCell::new(|| self.db.field_visibilities(variant));
390387

391388
self.list_variant_fields(ty, variant)
@@ -396,8 +393,7 @@ impl<'db> PatCx for MatchCheckCtx<'db> {
396393
.is_visible_from(self.db.upcast(), self.module)
397394
};
398395
let is_uninhabited = self.is_uninhabited(&ty);
399-
let private_uninhabited =
400-
is_uninhabited && (!is_visible() || *is_non_exhaustive);
396+
let private_uninhabited = is_uninhabited && !is_visible();
401397
(ty, PrivateUninhabitedField(private_uninhabited))
402398
})
403399
.collect()

crates/hir-ty/src/inhabitedness.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use chalk_ir::{
55
visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
66
DebruijnIndex,
77
};
8-
use hir_def::{visibility::Visibility, AdtId, EnumVariantId, HasModule, ModuleId, VariantId};
9-
use intern::sym;
8+
use hir_def::{visibility::Visibility, AdtId, EnumVariantId, ModuleId, VariantId};
109
use rustc_hash::FxHashSet;
1110

1211
use crate::{
@@ -118,11 +117,6 @@ impl UninhabitedFrom<'_> {
118117
variant: VariantId,
119118
subst: &Substitution,
120119
) -> ControlFlow<VisiblyUninhabited> {
121-
let is_local = variant.krate(self.db.upcast()) == self.target_mod.krate();
122-
if !is_local && self.db.attrs(variant.into()).by_key(&sym::non_exhaustive).exists() {
123-
return CONTINUE_OPAQUELY_INHABITED;
124-
}
125-
126120
let variant_data = self.db.variant_data(variant);
127121
let fields = variant_data.fields();
128122
if fields.is_empty() {

crates/ide-diagnostics/src/handlers/missing_match_arms.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,25 @@ fn test(x: Option<lib::PrivatelyUninhabited>) {
11141114
}
11151115
}
11161116

1117+
#[test]
1118+
fn non_exhaustive_may_be_empty() {
1119+
check_diagnostics_no_bails(
1120+
r"
1121+
//- /main.rs crate:main deps:dep
1122+
// In a different crate
1123+
fn empty_match_on_empty_struct<T>(x: dep::UninhabitedStruct) -> T {
1124+
match x {}
1125+
}
1126+
//- /dep.rs crate:dep
1127+
#[non_exhaustive]
1128+
pub struct UninhabitedStruct {
1129+
pub never: !,
1130+
// other fields
1131+
}
1132+
",
1133+
);
1134+
}
1135+
11171136
mod false_negatives {
11181137
//! The implementation of match checking here is a work in progress. As we roll this out, we
11191138
//! prefer false negatives to false positives (ideally there would be no false positives). This

0 commit comments

Comments
 (0)