Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 27723cbc16..5b35b0168a 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -415,6 +415,28 @@ impl ModuleDef { def.diagnostics(db, &mut acc); } + let vd: Option<(VariantDef, Arc<VariantData>)> = match self { + ModuleDef::Adt(Adt::Struct(it)) => { + Some((it.into(), db.struct_data(it.id).variant_data.clone())) + } + ModuleDef::Adt(Adt::Union(it)) => { + Some((it.into(), db.union_data(it.id).variant_data.clone())) + } + ModuleDef::Variant(it) => { + Some((it.into(), db.enum_variant_data(it.id).variant_data.clone())) + } + _ => None, + }; + if let Some((parent, vd)) = vd { + for (id, fd) in vd.fields().iter() { + if !fd.has_default { + continue; + } + let def: DefWithBody = DefWithBody::Field(Field { parent, id }); + def.diagnostics(db, &mut acc, style_lints); + } + } + acc } @@ -1226,6 +1248,12 @@ impl HasVisibility for Module { } } +impl From<&Field> for DefWithBodyId { + fn from(&f: &Field) -> Self { + DefWithBodyId::FieldId(f.into()) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Field { pub(crate) parent: VariantDef, @@ -1291,6 +1319,10 @@ impl AstNode for FieldSource { } impl Field { + pub fn module(self, db: &dyn HirDatabase) -> Module { + self.parent.module(db) + } + pub fn name(&self, db: &dyn HirDatabase) -> Name { self.parent.variant_data(db).fields()[self.id].name.clone() } @@ -1353,6 +1385,14 @@ impl Field { pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef { self.parent } + + pub fn default_value_source( + &self, + db: &dyn HirDatabase, + ) -> Option<InFileWrapper<HirFileId, ast::Expr>> { + let id: hir_def::FieldId = (*self).into(); + id.record_field_source(db.upcast()).map(|it| it.and_then(|it| it.expr())).transpose() + } } impl HasVisibility for Field { @@ -1789,8 +1829,9 @@ pub enum DefWithBody { Const(Const), Variant(Variant), InTypeConst(InTypeConst), + Field(Field), } -impl_from!(Function, Const, Static, Variant, InTypeConst for DefWithBody); +impl_from!(Function, Const, Static, Variant, InTypeConst, Field for DefWithBody); impl DefWithBody { pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -1800,6 +1841,7 @@ impl DefWithBody { DefWithBody::Static(s) => s.module(db), DefWithBody::Variant(v) => v.module(db), DefWithBody::InTypeConst(c) => c.module(db), + DefWithBody::Field(f) => f.module(db), } } @@ -1810,6 +1852,7 @@ impl DefWithBody { DefWithBody::Const(c) => c.name(db), DefWithBody::Variant(v) => Some(v.name(db)), DefWithBody::InTypeConst(_) => None, + DefWithBody::Field(f) => Some(f.name(db)), } } @@ -1825,6 +1868,7 @@ impl DefWithBody { &DefWithBodyId::from(it.id).resolver(db.upcast()), TyKind::Error.intern(Interner), ), + DefWithBody::Field(it) => it.ty(db), } } @@ -1835,6 +1879,7 @@ impl DefWithBody { DefWithBody::Const(it) => it.id.into(), DefWithBody::Variant(it) => it.into(), DefWithBody::InTypeConst(it) => it.id.into(), + DefWithBody::Field(it) => it.into(), } } @@ -1880,6 +1925,23 @@ impl DefWithBody { item_tree_source_maps.konst(konst.value) } DefWithBody::Variant(_) | DefWithBody::InTypeConst(_) => &TypesSourceMap::EMPTY, + DefWithBody::Field(field) => match field.parent { + VariantDef::Struct(strukt) => { + let strukt = strukt.id.lookup(db.upcast()).id; + item_tree_source_maps = strukt.item_tree_with_source_map(db.upcast()).1; + item_tree_source_maps.strukt(strukt.value).item() + } + VariantDef::Union(union) => { + let union = union.id.lookup(db.upcast()).id; + item_tree_source_maps = union.item_tree_with_source_map(db.upcast()).1; + item_tree_source_maps.union(union.value).item() + } + VariantDef::Variant(variant) => { + let variant = variant.id.lookup(db.upcast()).id; + item_tree_source_maps = variant.item_tree_with_source_map(db.upcast()).1; + item_tree_source_maps.variant(variant.value) + } + }, }; for (_, def_map) in body.blocks(db.upcast()) { @@ -2111,8 +2173,8 @@ impl DefWithBody { DefWithBody::Static(it) => it.into(), DefWithBody::Const(it) => it.into(), DefWithBody::Variant(it) => it.into(), - // FIXME: don't ignore diagnostics for in type const - DefWithBody::InTypeConst(_) => return, + // FIXME: don't ignore diagnostics for in type const and default field value exprs + DefWithBody::InTypeConst(_) | DefWithBody::Field(_) => return, }; for diag in hir_ty::diagnostics::incorrect_case(db, def.into()) { acc.push(diag.into()) @@ -3237,7 +3299,10 @@ impl AsAssocItem for DefWithBody { match self { DefWithBody::Function(it) => it.as_assoc_item(db), DefWithBody::Const(it) => it.as_assoc_item(db), - DefWithBody::Static(_) | DefWithBody::Variant(_) | DefWithBody::InTypeConst(_) => None, + DefWithBody::Static(_) + | DefWithBody::Variant(_) + | DefWithBody::InTypeConst(_) + | DefWithBody::Field(_) => None, } } } |