Skip to content

Commit

Permalink
feat: Implement default-field-values
Browse files Browse the repository at this point in the history
  • Loading branch information
ShoyuVanilla committed Jan 27, 2025
1 parent 1711a19 commit d18afd3
Show file tree
Hide file tree
Showing 33 changed files with 647 additions and 31 deletions.
3 changes: 3 additions & 0 deletions src/tools/rust-analyzer/crates/hir-def/src/expr_store/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ impl Body {
src.map(|it| it.expr())
}
DefWithBodyId::InTypeConstId(c) => c.lookup(db).id.map(|_| c.source(db).expr()),
DefWithBodyId::FieldId(f) => {
f.record_field_source(db).map(|it| it.and_then(|it| it.expr()))
}
}
};
let module = def.module(db);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub(super) fn lower_body(
DefWithBodyId::ConstId(it) => db.attrs(it.into()),
DefWithBodyId::InTypeConstId(_) => Attrs::EMPTY,
DefWithBodyId::VariantId(it) => db.attrs(it.into()),
DefWithBodyId::FieldId(it) => db.attrs(it.into()),
}
.rust_analyzer_tool()
.any(|attr| *attr.path() == tool_path![skip]);
Expand Down Expand Up @@ -168,6 +169,7 @@ pub(super) fn lower_body(
Awaitable::No("constant")
}
DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"),
DefWithBodyId::FieldId(..) => Awaitable::No("field"),
}
},
);
Expand Down
27 changes: 27 additions & 0 deletions src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
Statement,
},
pretty::{print_generic_args, print_path, print_type_ref},
VariantId,
};

use super::*;
Expand Down Expand Up @@ -56,6 +57,32 @@ pub(super) fn print_body_hir(
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
)
}
DefWithBodyId::FieldId(it) => {
let parent_name: String = match it.parent {
VariantId::EnumVariantId(it) => {
let loc = it.lookup(db);
let enum_loc = loc.parent.lookup(db);
format!(
"{}::{}",
enum_loc.id.item_tree(db)[enum_loc.id.value]
.name
.display(db.upcast(), edition),
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
)
}
VariantId::StructId(it) => it
.lookup(db)
.id
.resolved(db, |it| it.name.display(db.upcast(), edition).to_string()),
VariantId::UnionId(it) => it
.lookup(db)
.id
.resolved(db, |it| it.name.display(db.upcast(), edition).to_string()),
};
let variant_data = it.parent.variant_data(db);
let field_name = &variant_data.fields()[it.local_id].name;
format!("field {}.{}", parent_name, field_name.display(db.upcast(), edition),)
}
};

let mut p = Printer {
Expand Down
59 changes: 58 additions & 1 deletion src/tools/rust-analyzer/crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub mod visibility;

use intern::Interned;
pub use rustc_abi as layout;
use src::HasSource;
use triomphe::Arc;

#[cfg(test)]
Expand All @@ -77,6 +78,7 @@ use hir_expand::{
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
db::ExpandDatabase,
eager::expand_eager_macro_input,
files::InFileWrapper,
impl_intern_lookup,
name::Name,
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
Expand Down Expand Up @@ -519,6 +521,41 @@ pub struct FieldId {
pub local_id: LocalFieldId,
}

impl FieldId {
pub fn record_field_source(
&self,
db: &dyn DefDatabase,
) -> InFileWrapper<HirFileId, Option<ast::RecordField>> {
let field_list = match self.parent {
crate::VariantId::EnumVariantId(it) => {
let s = it.lookup(db);
s.source(db).map(|it| {
it.field_list().and_then(|it| match it {
ast::FieldList::RecordFieldList(it) => Some(it),
_ => None,
})
})
}
crate::VariantId::StructId(it) => {
let s = it.lookup(db);
s.source(db).map(|it| {
it.field_list().and_then(|it| match it {
ast::FieldList::RecordFieldList(it) => Some(it),
_ => None,
})
})
}
crate::VariantId::UnionId(it) => {
let s = it.lookup(db);
s.source(db).map(|it| it.record_field_list())
}
};
field_list.map(|it| {
it.and_then(|it| it.fields().nth(self.local_id.into_raw().into_u32() as usize))
})
}
}

pub type LocalFieldId = Idx<data::adt::FieldData>;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -686,6 +723,7 @@ pub enum TypeOwnerId {
TypeAliasId(TypeAliasId),
ImplId(ImplId),
EnumVariantId(EnumVariantId),
FieldId(FieldId),
}

impl TypeOwnerId {
Expand All @@ -703,6 +741,11 @@ impl TypeOwnerId {
GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
}
TypeOwnerId::InTypeConstId(_) => return None,
TypeOwnerId::FieldId(it) => GenericDefId::AdtId(match it.parent {
VariantId::EnumVariantId(it) => AdtId::EnumId(it.lookup(db).parent),
VariantId::StructId(it) => it.into(),
VariantId::UnionId(it) => it.into(),
}),
})
}
}
Expand All @@ -717,7 +760,8 @@ impl_from!(
TraitAliasId,
TypeAliasId,
ImplId,
EnumVariantId
EnumVariantId,
FieldId
for TypeOwnerId
);

Expand All @@ -730,6 +774,7 @@ impl From<DefWithBodyId> for TypeOwnerId {
DefWithBodyId::ConstId(it) => it.into(),
DefWithBodyId::InTypeConstId(it) => it.into(),
DefWithBodyId::VariantId(it) => it.into(),
DefWithBodyId::FieldId(it) => it.into(),
}
}
}
Expand Down Expand Up @@ -885,6 +930,7 @@ pub enum DefWithBodyId {
ConstId(ConstId),
InTypeConstId(InTypeConstId),
VariantId(EnumVariantId),
FieldId(FieldId),
}

impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
Expand All @@ -905,6 +951,7 @@ impl DefWithBodyId {
// FIXME: stable rust doesn't allow generics in constants, but we should
// use `TypeOwnerId::as_generic_def_id` when it does.
DefWithBodyId::InTypeConstId(_) => None,
DefWithBodyId::FieldId(_) => None,
}
}
}
Expand Down Expand Up @@ -1332,6 +1379,11 @@ impl HasModule for TypeOwnerId {
TypeOwnerId::ImplId(it) => it.module(db),
TypeOwnerId::EnumVariantId(it) => it.module(db),
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
TypeOwnerId::FieldId(it) => match it.parent {
VariantId::EnumVariantId(it) => it.module(db),
VariantId::StructId(it) => it.module(db),
VariantId::UnionId(it) => it.module(db),
},
}
}
}
Expand All @@ -1344,6 +1396,11 @@ impl HasModule for DefWithBodyId {
DefWithBodyId::ConstId(it) => it.module(db),
DefWithBodyId::VariantId(it) => it.module(db),
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
DefWithBodyId::FieldId(it) => match it.parent {
VariantId::EnumVariantId(it) => it.module(db),
VariantId::StructId(it) => it.module(db),
VariantId::UnionId(it) => it.module(db),
},
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,20 @@ enum Bar {
#[default]
Bar,
}
#[derive(Default)]
struct Baz {
field1: i32 = 2,
field2: bool = { false },
}
#[derive(Default)]
enum Qux {
#[default]
Foo {
field1: i32,
field2: bool = true,
field3: (),
}
}
"#,
expect![[r#"
#[derive(Default)]
Expand All @@ -224,6 +238,20 @@ enum Bar {
#[default]
Bar,
}
#[derive(Default)]
struct Baz {
field1: i32 = 2,
field2: bool = { false },
}
#[derive(Default)]
enum Qux {
#[default]
Foo {
field1: i32,
field2: bool = true,
field3: (),
}
}
impl <> $crate::default::Default for Foo< > where {
fn default() -> Self {
Expand All @@ -236,6 +264,20 @@ impl <> $crate::default::Default for Bar< > where {
fn default() -> Self {
Bar::Bar
}
}
impl <> $crate::default::Default for Baz< > where {
fn default() -> Self {
Baz {
..
}
}
}
impl <> $crate::default::Default for Qux< > where {
fn default() -> Self {
Qux::Foo {
field1: $crate::default::Default::default(), field3: $crate::default::Default::default(), ..
}
}
}"#]],
);
}
Expand Down
10 changes: 10 additions & 0 deletions src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,11 @@ impl HasResolver for TypeOwnerId {
TypeOwnerId::TypeAliasId(it) => it.resolver(db),
TypeOwnerId::ImplId(it) => it.resolver(db),
TypeOwnerId::EnumVariantId(it) => it.resolver(db),
TypeOwnerId::FieldId(it) => match it.parent {
VariantId::EnumVariantId(it) => it.resolver(db),
VariantId::StructId(it) => it.resolver(db),
VariantId::UnionId(it) => it.resolver(db),
},
}
}
}
Expand All @@ -1239,6 +1244,11 @@ impl HasResolver for DefWithBodyId {
DefWithBodyId::StaticId(s) => s.resolver(db),
DefWithBodyId::VariantId(v) => v.resolver(db),
DefWithBodyId::InTypeConstId(c) => c.lookup(db).owner.resolver(db),
DefWithBodyId::FieldId(f) => match f.parent {
VariantId::EnumVariantId(it) => it.resolver(db),
VariantId::StructId(it) => it.resolver(db),
VariantId::UnionId(it) => it.resolver(db),
},
}
}
}
Expand Down
Loading

0 comments on commit d18afd3

Please sign in to comment.