mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-27 02:06:57 +00:00
feat: Implement default-field-values
This commit is contained in:
parent
35b55fd67f
commit
7de0b2e75a
33 changed files with 647 additions and 31 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
@ -168,6 +169,7 @@ pub(super) fn lower_body(
|
|||
Awaitable::No("constant")
|
||||
}
|
||||
DefWithBodyId::VariantId(..) => Awaitable::No("enum variant"),
|
||||
DefWithBodyId::FieldId(..) => Awaitable::No("field"),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::{
|
|||
Statement,
|
||||
},
|
||||
pretty::{print_generic_args, print_path, print_type_ref},
|
||||
VariantId,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ pub mod visibility;
|
|||
|
||||
use intern::Interned;
|
||||
pub use rustc_abi as layout;
|
||||
use src::HasSource;
|
||||
use triomphe::Arc;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -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},
|
||||
|
|
@ -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)]
|
||||
|
|
@ -686,6 +723,7 @@ pub enum TypeOwnerId {
|
|||
TypeAliasId(TypeAliasId),
|
||||
ImplId(ImplId),
|
||||
EnumVariantId(EnumVariantId),
|
||||
FieldId(FieldId),
|
||||
}
|
||||
|
||||
impl TypeOwnerId {
|
||||
|
|
@ -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(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -717,7 +760,8 @@ impl_from!(
|
|||
TraitAliasId,
|
||||
TypeAliasId,
|
||||
ImplId,
|
||||
EnumVariantId
|
||||
EnumVariantId,
|
||||
FieldId
|
||||
for TypeOwnerId
|
||||
);
|
||||
|
||||
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -885,6 +930,7 @@ pub enum DefWithBodyId {
|
|||
ConstId(ConstId),
|
||||
InTypeConstId(InTypeConstId),
|
||||
VariantId(EnumVariantId),
|
||||
FieldId(FieldId),
|
||||
}
|
||||
|
||||
impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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(), ..
|
||||
}
|
||||
}
|
||||
}"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue