Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21977 from ChayimFriedman2/fill-fields-priv
fix: Disable the fix for missing-fields when the fields are private
| -rw-r--r-- | crates/hir/src/diagnostics.rs | 9 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/missing_fields.rs | 29 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/lib.rs | 6 |
3 files changed, 38 insertions, 6 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index 7f672a697c..555270bad8 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs @@ -282,7 +282,7 @@ pub struct MissingFields { pub file: HirFileId, pub field_list_parent: AstPtr<Either<ast::RecordExpr, ast::RecordPat>>, pub field_list_parent_path: Option<AstPtr<ast::Path>>, - pub missed_fields: Vec<Name>, + pub missed_fields: Vec<(Name, Field)>, } #[derive(Debug)] @@ -476,7 +476,12 @@ impl<'db> AnyDiagnostic<'db> { let variant_data = variant.fields(db); let missed_fields = missed_fields .into_iter() - .map(|idx| variant_data.fields()[idx].name.clone()) + .map(|idx| { + ( + variant_data.fields()[idx].name.clone(), + Field { parent: variant.into(), id: idx }, + ) + }) .collect(); let record = match record { diff --git a/crates/ide-diagnostics/src/handlers/missing_fields.rs b/crates/ide-diagnostics/src/handlers/missing_fields.rs index efbd266714..85368cc09f 100644 --- a/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -1,6 +1,6 @@ use either::Either; use hir::{ - AssocItem, FindPathConfig, HirDisplay, InFile, Type, + AssocItem, FindPathConfig, HasVisibility, HirDisplay, InFile, Type, db::{ExpandDatabase, HirDatabase}, sym, }; @@ -35,7 +35,7 @@ use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, fix}; // ``` pub(crate) fn missing_fields(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Diagnostic { let mut message = String::from("missing structure fields:\n"); - for field in &d.missed_fields { + for (field, _) in &d.missed_fields { format_to!(message, "- {}\n", field.display(ctx.sema.db, ctx.edition)); } @@ -57,7 +57,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass // `struct A(usize);` // `let a = A { 0: () }` // but it is uncommon usage and it should not be encouraged. - if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) { + if d.missed_fields.iter().any(|(name, _)| name.as_tuple_index().is_some()) { return None; } @@ -68,6 +68,12 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass let range = InFile::new(d.file, d.field_list_parent.text_range()) .original_node_file_range_rooted_opt(ctx.sema.db)?; + if let Some(current_module) = current_module + && d.missed_fields.iter().any(|(_, field)| !field.is_visible_from(ctx.db(), current_module)) + { + return None; + } + let build_text_edit = |new_syntax: &SyntaxNode, old_syntax| { let edit = { let old_range = ctx.sema.original_range_opt(old_syntax)?; @@ -254,7 +260,7 @@ fn get_default_constructor( #[cfg(test)] mod tests { - use crate::tests::{check_diagnostics, check_fix}; + use crate::tests::{check_diagnostics, check_fix, check_no_fix}; #[test] fn missing_record_pat_field_diagnostic() { @@ -960,4 +966,19 @@ fn f() -> A { "#, ); } + + #[test] + fn inaccessible_fields() { + check_no_fix( + r#" +mod foo { + pub struct Bar { baz: i32 } +} + +fn qux() { + foo::Bar {$0}; +} + "#, + ); + } } diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs index 519639db00..09c9f8eab0 100644 --- a/crates/ide-diagnostics/src/lib.rs +++ b/crates/ide-diagnostics/src/lib.rs @@ -285,6 +285,12 @@ struct DiagnosticsContext<'a> { is_nightly: bool, } +impl<'a> DiagnosticsContext<'a> { + fn db(&self) -> &'a RootDatabase { + self.sema.db + } +} + /// Request parser level diagnostics for the given [`FileId`]. pub fn syntax_diagnostics( db: &RootDatabase, |