diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 9c183c9332..a42d6bb337 100644 --- a/crates/hir-def/src/data.rs +++ b/crates/hir-def/src/data.rs @@ -19,7 +19,7 @@ use crate::{ macro_call_as_call_id, nameres::{ attr_resolution::ResolvedAttr, - diagnostics::DefDiagnostic, + diagnostics::{DefDiagnostic, DefDiagnostics}, proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, DefMap, MacroSubNs, }, @@ -240,7 +240,7 @@ impl TraitData { pub(crate) fn trait_data_with_diagnostics_query( db: &dyn DefDatabase, tr: TraitId, - ) -> (Arc, Arc<[DefDiagnostic]>) { + ) -> (Arc, DefDiagnostics) { let tr_loc @ ItemLoc { container: module_id, id: tree_id } = tr.lookup(db); let item_tree = tree_id.item_tree(db); let tr_def = &item_tree[tree_id.value]; @@ -274,7 +274,7 @@ impl TraitData { rustc_has_incoherent_inherent_impls, fundamental, }), - diagnostics.into(), + DefDiagnostics::new(diagnostics), ) } @@ -340,7 +340,7 @@ impl ImplData { pub(crate) fn impl_data_with_diagnostics_query( db: &dyn DefDatabase, id: ImplId, - ) -> (Arc, Arc<[DefDiagnostic]>) { + ) -> (Arc, DefDiagnostics) { let _p = profile::span("impl_data_with_diagnostics_query"); let ItemLoc { container: module_id, id: tree_id } = id.lookup(db); @@ -367,7 +367,7 @@ impl ImplData { is_unsafe, attribute_calls, }), - diagnostics.into(), + DefDiagnostics::new(diagnostics), ) } diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs index 942fafe329..6e302aea65 100644 --- a/crates/hir-def/src/data/adt.rs +++ b/crates/hir-def/src/data/adt.rs @@ -21,7 +21,7 @@ use crate::{ item_tree::{AttrOwner, Field, FieldAstId, Fields, ItemTree, ModItem, RawVisibilityId}, lang_item::LangItem, lower::LowerCtx, - nameres::diagnostics::DefDiagnostic, + nameres::diagnostics::{DefDiagnostic, DefDiagnostics}, src::HasChildSource, src::HasSource, trace::Trace, @@ -187,7 +187,7 @@ impl StructData { pub(crate) fn struct_data_with_diagnostics_query( db: &dyn DefDatabase, id: StructId, - ) -> (Arc, Arc<[DefDiagnostic]>) { + ) -> (Arc, DefDiagnostics) { let loc = id.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); @@ -232,7 +232,7 @@ impl StructData { visibility: item_tree[strukt.visibility].clone(), flags, }), - diagnostics.into(), + DefDiagnostics::new(diagnostics), ) } @@ -243,7 +243,7 @@ impl StructData { pub(crate) fn union_data_with_diagnostics_query( db: &dyn DefDatabase, id: UnionId, - ) -> (Arc, Arc<[DefDiagnostic]>) { + ) -> (Arc, DefDiagnostics) { let loc = id.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); @@ -278,7 +278,7 @@ impl StructData { visibility: item_tree[union.visibility].clone(), flags, }), - diagnostics.into(), + DefDiagnostics::new(diagnostics), ) } } @@ -332,14 +332,14 @@ impl EnumVariantData { pub(crate) fn enum_variant_data_with_diagnostics_query( db: &dyn DefDatabase, e: EnumVariantId, - ) -> (Arc, Option>>) { + ) -> (Arc, DefDiagnostics) { let loc = e.lookup(db); let krate = loc.container.krate; let item_tree = loc.id.item_tree(db); let cfg_options = db.crate_graph()[krate].cfg_options.clone(); let variant = &item_tree[loc.id.value]; - let (var_data, field_diagnostics) = lower_fields( + let (var_data, diagnostics) = lower_fields( db, krate, loc.id.file_id(), @@ -355,11 +355,7 @@ impl EnumVariantData { name: variant.name.clone(), variant_data: Arc::new(var_data), }), - if field_diagnostics.is_empty() { - None - } else { - Some(Arc::new(field_diagnostics.into_boxed_slice())) - }, + DefDiagnostics::new(diagnostics), ) } } diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index 2b1d0bca28..186a8cf2d9 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -19,7 +19,7 @@ use crate::{ import_map::ImportMap, item_tree::{AttrOwner, ItemTree}, lang_item::{self, LangItem, LangItemTarget, LangItems}, - nameres::{diagnostics::DefDiagnostic, DefMap}, + nameres::{diagnostics::DefDiagnostics, DefMap}, visibility::{self, Visibility}, AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, @@ -121,14 +121,13 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Arc; #[salsa::invoke(StructData::struct_data_with_diagnostics_query)] - fn struct_data_with_diagnostics(&self, id: StructId) - -> (Arc, Arc<[DefDiagnostic]>); + fn struct_data_with_diagnostics(&self, id: StructId) -> (Arc, DefDiagnostics); #[salsa::invoke(StructData::union_data_query)] fn union_data(&self, id: UnionId) -> Arc; #[salsa::invoke(StructData::union_data_with_diagnostics_query)] - fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc, Arc<[DefDiagnostic]>); + fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc, DefDiagnostics); #[salsa::invoke(EnumData::enum_data_query)] fn enum_data(&self, e: EnumId) -> Arc; @@ -140,19 +139,19 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast (Arc, Option>>); + ) -> (Arc, DefDiagnostics); #[salsa::invoke(ImplData::impl_data_query)] fn impl_data(&self, e: ImplId) -> Arc; #[salsa::invoke(ImplData::impl_data_with_diagnostics_query)] - fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, Arc<[DefDiagnostic]>); + fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); #[salsa::invoke(TraitData::trait_data_query)] fn trait_data(&self, e: TraitId) -> Arc; #[salsa::invoke(TraitData::trait_data_with_diagnostics_query)] - fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, Arc<[DefDiagnostic]>); + fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); #[salsa::invoke(TraitAliasData::trait_alias_query)] fn trait_alias_data(&self, e: TraitAliasId) -> Arc; diff --git a/crates/hir-def/src/nameres/diagnostics.rs b/crates/hir-def/src/nameres/diagnostics.rs index 9cffb3c9f3..0a3f7bf7ec 100644 --- a/crates/hir-def/src/nameres/diagnostics.rs +++ b/crates/hir-def/src/nameres/diagnostics.rs @@ -40,6 +40,23 @@ pub enum DefDiagnosticKind { MacroDefError { ast: AstId, message: String }, } +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct DefDiagnostics(Option>>); + +impl DefDiagnostics { + pub fn new(diagnostics: Vec) -> Self { + Self(if diagnostics.is_empty() { + None + } else { + Some(triomphe::Arc::new(diagnostics.into_boxed_slice())) + }) + } + + pub fn iter(&self) -> impl Iterator { + self.0.as_ref().into_iter().flat_map(|it| &***it) + } +} + #[derive(Debug, PartialEq, Eq)] pub struct DefDiagnostic { pub in_module: LocalModuleId, diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 69d8046524..749ca43fba 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -69,6 +69,7 @@ struct MirLowerCtx<'a> { drop_scopes: Vec, } +// FIXME: Make this smaller, its stored in database queries #[derive(Debug, Clone, PartialEq, Eq)] pub enum MirLowerError { ConstEvalError(Box, Box), diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 5e133bf5c7..246fc231b4 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -584,11 +584,8 @@ impl Module { Adt::Enum(e) => { for v in e.variants(db) { acc.extend(ModuleDef::Variant(v).diagnostics(db)); - if let Some(diags) = &db.enum_variant_data_with_diagnostics(v.id).1 - { - for diag in &***diags { - emit_def_diagnostic(db, acc, diag); - } + for diag in db.enum_variant_data_with_diagnostics(v.id).1.iter() { + emit_def_diagnostic(db, acc, diag); } } }