diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-12-09 13:26:47 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-09 13:26:47 +0000 |
| commit | 244b1fd34e8ee7f0acf185167302fbe7f9ec398b (patch) | |
| tree | c67e001362ce0d0f69803cff43b97689cbb1fb4d | |
| parent | 641bca6d6244e9b8a2aa76a55f8e00c4a70fe4b7 (diff) | |
| parent | 67c92878630657777039954b060d3410e5ef3d46 (diff) | |
| download | rust-244b1fd34e8ee7f0acf185167302fbe7f9ec398b.tar.gz rust-244b1fd34e8ee7f0acf185167302fbe7f9ec398b.zip | |
Merge pull request #18645 from Veykril/push-yruoyrvrsntw
fix: Non-exhaustive structs may be empty
3 files changed, 21 insertions, 12 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 58de19ba81e..5452f5c680d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -383,9 +383,6 @@ impl<'db> PatCx for MatchCheckCtx<'db> { } else { let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap(); - // Whether we must not match the fields of this variant exhaustively. - let is_non_exhaustive = - LazyCell::new(|| self.is_foreign_non_exhaustive(adt)); let visibilities = LazyCell::new(|| self.db.field_visibilities(variant)); self.list_variant_fields(ty, variant) @@ -396,8 +393,7 @@ impl<'db> PatCx for MatchCheckCtx<'db> { .is_visible_from(self.db.upcast(), self.module) }; let is_uninhabited = self.is_uninhabited(&ty); - let private_uninhabited = - is_uninhabited && (!is_visible() || *is_non_exhaustive); + let private_uninhabited = is_uninhabited && !is_visible(); (ty, PrivateUninhabitedField(private_uninhabited)) }) .collect() diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs index c0a781b17ee..56b549436c7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/inhabitedness.rs @@ -5,8 +5,7 @@ use chalk_ir::{ visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, DebruijnIndex, }; -use hir_def::{visibility::Visibility, AdtId, EnumVariantId, HasModule, ModuleId, VariantId}; -use intern::sym; +use hir_def::{visibility::Visibility, AdtId, EnumVariantId, ModuleId, VariantId}; use rustc_hash::FxHashSet; use crate::{ @@ -118,11 +117,6 @@ impl UninhabitedFrom<'_> { variant: VariantId, subst: &Substitution, ) -> ControlFlow<VisiblyUninhabited> { - let is_local = variant.krate(self.db.upcast()) == self.target_mod.krate(); - if !is_local && self.db.attrs(variant.into()).by_key(&sym::non_exhaustive).exists() { - return CONTINUE_OPAQUELY_INHABITED; - } - let variant_data = self.db.variant_data(variant); let fields = variant_data.fields(); if fields.is_empty() { diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs index f39738f2fb8..08e6e7dced9 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_match_arms.rs @@ -1114,6 +1114,25 @@ fn test(x: Option<lib::PrivatelyUninhabited>) { } } + #[test] + fn non_exhaustive_may_be_empty() { + check_diagnostics_no_bails( + r" +//- /main.rs crate:main deps:dep +// In a different crate +fn empty_match_on_empty_struct<T>(x: dep::UninhabitedStruct) -> T { + match x {} +} +//- /dep.rs crate:dep +#[non_exhaustive] +pub struct UninhabitedStruct { + pub never: !, + // other fields +} +", + ); + } + mod false_negatives { //! The implementation of match checking here is a work in progress. As we roll this out, we //! prefer false negatives to false positives (ideally there would be no false positives). This |
