2393: Simplify ADT fields r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-11-24 19:45:08 +00:00 committed by GitHub
commit f16cff3cad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 26 deletions

View file

@ -37,7 +37,7 @@ impl fmt::Display for RawId {
} }
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
pub struct Arena<ID: ArenaId, T> { pub struct Arena<ID, T> {
data: Vec<T>, data: Vec<T>,
_ty: PhantomData<ID>, _ty: PhantomData<ID>,
} }
@ -67,6 +67,12 @@ pub trait ArenaId {
fn into_raw(self) -> RawId; fn into_raw(self) -> RawId;
} }
impl<ID, T> Arena<ID, T> {
pub const fn new() -> Arena<ID, T> {
Arena { data: Vec::new(), _ty: PhantomData }
}
}
impl<ID: ArenaId, T> Arena<ID, T> { impl<ID: ArenaId, T> Arena<ID, T> {
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.data.len() self.data.len()

View file

@ -301,7 +301,7 @@ pub enum FieldSource {
impl StructField { impl StructField {
pub fn name(&self, db: &impl HirDatabase) -> Name { pub fn name(&self, db: &impl HirDatabase) -> Name {
self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() self.parent.variant_data(db).fields()[self.id].name.clone()
} }
pub fn ty(&self, db: &impl HirDatabase) -> Ty { pub fn ty(&self, db: &impl HirDatabase) -> Ty {
@ -335,8 +335,7 @@ impl Struct {
db.struct_data(self.id.into()) db.struct_data(self.id.into())
.variant_data .variant_data
.fields() .fields()
.into_iter() .iter()
.flat_map(|it| it.iter())
.map(|(id, _)| StructField { parent: self.into(), id }) .map(|(id, _)| StructField { parent: self.into(), id })
.collect() .collect()
} }
@ -345,8 +344,7 @@ impl Struct {
db.struct_data(self.id.into()) db.struct_data(self.id.into())
.variant_data .variant_data
.fields() .fields()
.into_iter() .iter()
.flat_map(|it| it.iter())
.find(|(_id, data)| data.name == *name) .find(|(_id, data)| data.name == *name)
.map(|(id, _)| StructField { parent: self.into(), id }) .map(|(id, _)| StructField { parent: self.into(), id })
} }
@ -443,8 +441,7 @@ impl EnumVariant {
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
self.variant_data(db) self.variant_data(db)
.fields() .fields()
.into_iter() .iter()
.flat_map(|it| it.iter())
.map(|(id, _)| StructField { parent: self.into(), id }) .map(|(id, _)| StructField { parent: self.into(), id })
.collect() .collect()
} }
@ -452,8 +449,7 @@ impl EnumVariant {
pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
self.variant_data(db) self.variant_data(db)
.fields() .fields()
.into_iter() .iter()
.flat_map(|it| it.iter())
.find(|(_id, data)| data.name == *name) .find(|(_id, data)| data.name == *name)
.map(|(id, _)| StructField { parent: self.into(), id }) .map(|(id, _)| StructField { parent: self.into(), id })
} }

View file

@ -200,8 +200,7 @@ impl FromSource for StructField {
variant_def variant_def
.variant_data(db) .variant_data(db)
.fields() .fields()
.into_iter() .iter()
.flat_map(|it| it.iter())
.map(|(id, _)| StructField { parent: variant_def, id }) .map(|(id, _)| StructField { parent: variant_def, id })
.find(|f| f.source(db) == src) .find(|f| f.source(db) == src)
} }

View file

@ -557,7 +557,7 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
VariantDef::EnumVariant(it) => it.parent.id.resolver(db), VariantDef::EnumVariant(it) => it.parent.id.resolver(db),
}; };
let var_data = parent_def.variant_data(db); let var_data = parent_def.variant_data(db);
let type_ref = &var_data.fields().unwrap()[field.id].type_ref; let type_ref = &var_data.fields()[field.id].type_ref;
Ty::from_hir(db, &resolver, type_ref) Ty::from_hir(db, &resolver, type_ref)
} }
@ -696,10 +696,7 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
let struct_data = db.struct_data(def.id.into()); let struct_data = db.struct_data(def.id.into());
let fields = match struct_data.variant_data.fields() { let fields = struct_data.variant_data.fields();
Some(fields) => fields,
None => panic!("fn_sig_for_struct_constructor called on unit struct"),
};
let resolver = def.id.resolver(db); let resolver = def.id.resolver(db);
let params = fields let params = fields
.iter() .iter()
@ -712,7 +709,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
/// Build the type of a tuple struct constructor. /// Build the type of a tuple struct constructor.
fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
let struct_data = db.struct_data(def.id.into()); let struct_data = db.struct_data(def.id.into());
if struct_data.variant_data.fields().is_none() { if struct_data.variant_data.is_unit() {
return type_for_adt(db, def); // Unit struct return type_for_adt(db, def); // Unit struct
} }
let generics = db.generic_params(def.id.into()); let generics = db.generic_params(def.id.into());
@ -722,10 +719,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
let var_data = def.variant_data(db); let var_data = def.variant_data(db);
let fields = match var_data.fields() { let fields = var_data.fields();
Some(fields) => fields,
None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
};
let resolver = def.parent.id.resolver(db); let resolver = def.parent.id.resolver(db);
let params = fields let params = fields
.iter() .iter()
@ -740,7 +734,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
/// Build the type of a tuple enum variant constructor. /// Build the type of a tuple enum variant constructor.
fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
let var_data = def.variant_data(db); let var_data = def.variant_data(db);
if var_data.fields().is_none() { if var_data.is_unit() {
return type_for_adt(db, def.parent_enum(db)); // Unit variant return type_for_adt(db, def.parent_enum(db)); // Unit variant
} }
let generics = db.generic_params(def.parent_enum(db).id.into()); let generics = db.generic_params(def.parent_enum(db).id.into());

View file

@ -109,10 +109,18 @@ impl VariantData {
} }
} }
pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> { pub fn fields(&self) -> &Arena<LocalStructFieldId, StructFieldData> {
const EMPTY: &Arena<LocalStructFieldId, StructFieldData> = &Arena::new();
match &self { match &self {
VariantData::Record(fields) | VariantData::Tuple(fields) => Some(fields), VariantData::Record(fields) | VariantData::Tuple(fields) => fields,
_ => None, _ => EMPTY,
}
}
pub fn is_unit(&self) -> bool {
match self {
VariantData::Unit => true,
_ => false,
} }
} }
} }