2409: Id-ify Ty::Adt r=matklad a=matklad



Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2019-11-26 11:32:09 +00:00 committed by GitHub
commit 6e36eadd26
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 98 additions and 39 deletions

View file

@ -11,9 +11,9 @@ use hir_def::{
per_ns::PerNs, per_ns::PerNs,
resolver::{HasResolver, TypeNs}, resolver::{HasResolver, TypeNs},
type_ref::{Mutability, TypeRef}, type_ref::{Mutability, TypeRef},
AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
StaticId, StructId, TraitId, TypeAliasId, UnionId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
}; };
use hir_expand::{ use hir_expand::{
diagnostics::DiagnosticSink, diagnostics::DiagnosticSink,
@ -383,6 +383,28 @@ impl Union {
pub fn ty(self, db: &impl HirDatabase) -> Ty { pub fn ty(self, db: &impl HirDatabase) -> Ty {
db.type_for_def(self.into(), Namespace::Types) db.type_for_def(self.into(), Namespace::Types)
} }
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
db.union_data(self.id)
.variant_data
.fields()
.iter()
.map(|(id, _)| StructField { parent: self.into(), id })
.collect()
}
pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
db.union_data(self.id)
.variant_data
.fields()
.iter()
.find(|(_id, data)| data.name == *name)
.map(|(id, _)| StructField { parent: self.into(), id })
}
fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
db.union_data(self.id).variant_data.clone()
}
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -501,14 +523,16 @@ impl Adt {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum VariantDef { pub enum VariantDef {
Struct(Struct), Struct(Struct),
Union(Union),
EnumVariant(EnumVariant), EnumVariant(EnumVariant),
} }
impl_froms!(VariantDef: Struct, EnumVariant); impl_froms!(VariantDef: Struct, Union, EnumVariant);
impl VariantDef { impl VariantDef {
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
match self { match self {
VariantDef::Struct(it) => it.fields(db), VariantDef::Struct(it) => it.fields(db),
VariantDef::Union(it) => it.fields(db),
VariantDef::EnumVariant(it) => it.fields(db), VariantDef::EnumVariant(it) => it.fields(db),
} }
} }
@ -516,6 +540,7 @@ impl VariantDef {
pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
match self { match self {
VariantDef::Struct(it) => it.field(db, name), VariantDef::Struct(it) => it.field(db, name),
VariantDef::Union(it) => it.field(db, name),
VariantDef::EnumVariant(it) => it.field(db, name), VariantDef::EnumVariant(it) => it.field(db, name),
} }
} }
@ -523,6 +548,7 @@ impl VariantDef {
pub fn module(self, db: &impl HirDatabase) -> Module { pub fn module(self, db: &impl HirDatabase) -> Module {
match self { match self {
VariantDef::Struct(it) => it.module(db), VariantDef::Struct(it) => it.module(db),
VariantDef::Union(it) => it.module(db),
VariantDef::EnumVariant(it) => it.module(db), VariantDef::EnumVariant(it) => it.module(db),
} }
} }
@ -530,6 +556,7 @@ impl VariantDef {
pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
match self { match self {
VariantDef::Struct(it) => it.variant_data(db), VariantDef::Struct(it) => it.variant_data(db),
VariantDef::Union(it) => it.variant_data(db),
VariantDef::EnumVariant(it) => it.variant_data(db), VariantDef::EnumVariant(it) => it.variant_data(db),
} }
} }
@ -1056,19 +1083,24 @@ impl Type {
} }
pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> {
let mut res = Vec::new();
if let Ty::Apply(a_ty) = &self.ty.value { if let Ty::Apply(a_ty) = &self.ty.value {
match a_ty.ctor { match a_ty.ctor {
ty::TypeCtor::Adt(Adt::Struct(s)) => { ty::TypeCtor::Adt(AdtId::StructId(s)) => {
for field in s.fields(db) { let var_def = s.into();
let ty = field.ty(db).subst(&a_ty.parameters); return db
res.push((field, self.derived(ty))); .field_types(var_def)
} .iter()
.map(|(local_id, ty)| {
let def = StructField { parent: var_def.into(), id: local_id };
let ty = ty.clone().subst(&a_ty.parameters);
(def, self.derived(ty))
})
.collect();
} }
_ => {} _ => {}
} }
}; };
res Vec::new()
} }
pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> { pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> {

View file

@ -2,7 +2,7 @@
use std::sync::Arc; use std::sync::Arc;
use hir_def::{path::known, resolver::HasResolver}; use hir_def::{path::known, resolver::HasResolver, AdtId};
use hir_expand::diagnostics::DiagnosticSink; use hir_expand::diagnostics::DiagnosticSink;
use ra_syntax::ast; use ra_syntax::ast;
use ra_syntax::AstPtr; use ra_syntax::AstPtr;
@ -127,7 +127,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
_ => return, _ => return,
}; };
let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); let std_result_ctor = TypeCtor::Adt(AdtId::EnumId(std_result_enum));
let params = match &mismatch.expected { let params = match &mismatch.expected {
Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
_ => return, _ => return,

View file

@ -199,11 +199,22 @@ impl From<Adt> for GenericDefId {
} }
} }
impl From<VariantId> for VariantDef {
fn from(def: VariantId) -> Self {
match def {
VariantId::StructId(it) => VariantDef::Struct(it.into()),
VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()),
VariantId::UnionId(it) => VariantDef::Union(it.into()),
}
}
}
impl From<VariantDef> for VariantId { impl From<VariantDef> for VariantId {
fn from(def: VariantDef) -> Self { fn from(def: VariantDef) -> Self {
match def { match def {
VariantDef::Struct(it) => VariantId::StructId(it.id), VariantDef::Struct(it) => VariantId::StructId(it.id),
VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()),
VariantDef::Union(it) => VariantId::UnionId(it.id),
} }
} }
} }
@ -214,6 +225,12 @@ impl From<StructField> for StructFieldId {
} }
} }
impl From<StructFieldId> for StructField {
fn from(def: StructFieldId) -> Self {
StructField { parent: def.parent.into(), id: def.local_id }
}
}
impl From<AttrDef> for AttrDefId { impl From<AttrDef> for AttrDefId {
fn from(def: AttrDef) -> Self { fn from(def: AttrDef) -> Self {
match def { match def {

View file

@ -58,7 +58,7 @@ pub enum TypeCtor {
Float(Uncertain<FloatTy>), Float(Uncertain<FloatTy>),
/// Structures, enumerations and unions. /// Structures, enumerations and unions.
Adt(Adt), Adt(AdtId),
/// The pointee of a string slice. Written as `str`. /// The pointee of a string slice. Written as `str`.
Str, Str,
@ -174,7 +174,7 @@ impl TypeCtor {
| TypeCtor::Tuple { .. } => None, | TypeCtor::Tuple { .. } => None,
// Closure's krate is irrelevant for coherence I would think? // Closure's krate is irrelevant for coherence I would think?
TypeCtor::Closure { .. } => None, TypeCtor::Closure { .. } => None,
TypeCtor::Adt(adt) => adt.krate(db), TypeCtor::Adt(adt) => Some(adt.module(db).krate.into()),
TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), TypeCtor::FnDef(callable) => Some(callable.krate(db).into()),
TypeCtor::AssociatedType(type_alias) => { TypeCtor::AssociatedType(type_alias) => {
Some(type_alias.lookup(db).module(db).krate.into()) Some(type_alias.lookup(db).module(db).krate.into())
@ -598,7 +598,7 @@ impl Ty {
pub fn as_adt(&self) -> Option<(Adt, &Substs)> { pub fn as_adt(&self) -> Option<(Adt, &Substs)> {
match self { match self {
Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
Some((*adt_def, parameters)) Some(((*adt_def).into(), parameters))
} }
_ => None, _ => None,
} }
@ -889,9 +889,9 @@ impl HirDisplay for ApplicationTy {
} }
TypeCtor::Adt(def_id) => { TypeCtor::Adt(def_id) => {
let name = match def_id { let name = match def_id {
Adt::Struct(s) => s.name(f.db), AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
Adt::Union(u) => u.name(f.db), AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
Adt::Enum(e) => e.name(f.db), AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
} }
.unwrap_or_else(Name::missing); .unwrap_or_else(Name::missing);
write!(f, "{}", name)?; write!(f, "{}", name)?;

View file

@ -598,10 +598,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE)
} }
fn resolve_boxed_box(&self) -> Option<Adt> { fn resolve_boxed_box(&self) -> Option<AdtId> {
let path = known::std_boxed_box(); let path = known::std_boxed_box();
let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
Some(Adt::Struct(struct_.into())) Some(struct_.into())
} }
} }

View file

@ -4,14 +4,14 @@
//! //!
//! See: https://doc.rust-lang.org/nomicon/coercions.html //! See: https://doc.rust-lang.org/nomicon/coercions.html
use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use test_utils::tested_by; use test_utils::tested_by;
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
Adt, Mutability, Mutability,
}; };
use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
@ -242,11 +242,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
// - T is not part of the type of any other fields // - T is not part of the type of any other fields
// - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T> // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T>
( (
ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), ty_app!(TypeCtor::Adt(AdtId::StructId(struct1)), st1),
ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), ty_app!(TypeCtor::Adt(AdtId::StructId(struct2)), st2),
) if struct1 == struct2 => { ) if struct1 == struct2 => {
let field_tys = self.db.field_types(struct1.id.into()); let field_tys = self.db.field_types((*struct1).into());
let struct_data = self.db.struct_data(struct1.id); let struct_data = self.db.struct_data(*struct1);
let mut fields = struct_data.variant_data.fields().iter(); let mut fields = struct_data.variant_data.fields().iter();
let (last_field_id, _data) = fields.next_back()?; let (last_field_id, _data) = fields.next_back()?;

View file

@ -8,7 +8,7 @@ use hir_def::{
generics::GenericParams, generics::GenericParams,
path::{GenericArg, GenericArgs}, path::{GenericArg, GenericArgs},
resolver::resolver_for_expr, resolver::resolver_for_expr,
ContainerId, Lookup, AdtId, ContainerId, Lookup, StructFieldId,
}; };
use hir_expand::name; use hir_expand::name;
@ -20,7 +20,7 @@ use crate::{
Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty,
TypeCtor, TypeWalk, Uncertain, TypeCtor, TypeWalk, Uncertain,
}, },
Adt, Name, Name,
}; };
use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@ -259,14 +259,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
TypeCtor::Tuple { .. } => name TypeCtor::Tuple { .. } => name
.as_tuple_index() .as_tuple_index()
.and_then(|idx| a_ty.parameters.0.get(idx).cloned()), .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { TypeCtor::Adt(AdtId::StructId(s)) => {
self.write_field_resolution(tgt_expr, field); self.db.struct_data(s).variant_data.field(name).map(|local_id| {
self.db.field_types(s.id.into())[field.id] let field = StructFieldId { parent: s.into(), local_id }.into();
.clone() self.write_field_resolution(tgt_expr, field);
.subst(&a_ty.parameters) self.db.field_types(s.into())[field.id]
}), .clone()
.subst(&a_ty.parameters)
})
}
// FIXME: // FIXME:
TypeCtor::Adt(Adt::Union(_)) => None, TypeCtor::Adt(AdtId::UnionId(_)) => None,
_ => None, _ => None,
}, },
_ => None, _ => None,

View file

@ -762,7 +762,7 @@ fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty {
let adt = adt.into(); let adt = adt.into();
let adt_id: AdtId = adt.into(); let adt_id: AdtId = adt.into();
let generics = db.generic_params(adt_id.into()); let generics = db.generic_params(adt_id.into());
Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics))
} }
fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {

View file

@ -5,7 +5,7 @@
use std::sync::Arc; use std::sync::Arc;
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef}; use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::{ use crate::{
@ -102,7 +102,9 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV
let lang_item_targets = match ty { let lang_item_targets = match ty {
Ty::Apply(a_ty) => match a_ty.ctor { Ty::Apply(a_ty) => match a_ty.ctor {
TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()), TypeCtor::Adt(def_id) => {
return Some(std::iter::once(def_id.module(db).krate.into()).collect())
}
TypeCtor::Bool => lang_item_crate!("bool"), TypeCtor::Bool => lang_item_crate!("bool"),
TypeCtor::Char => lang_item_crate!("char"), TypeCtor::Char => lang_item_crate!("char"),
TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {

View file

@ -129,6 +129,10 @@ impl VariantData {
} }
} }
pub fn field(&self, name: &Name) -> Option<LocalStructFieldId> {
self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None })
}
pub fn is_unit(&self) -> bool { pub fn is_unit(&self) -> bool {
match self { match self {
VariantData::Unit => true, VariantData::Unit => true,

View file

@ -46,6 +46,7 @@ pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDe
let container = parent.module(db); let container = parent.module(db);
let visibility = match parent { let visibility = match parent {
VariantDef::Struct(s) => s.source(db).value.visibility(), VariantDef::Struct(s) => s.source(db).value.visibility(),
VariantDef::Union(e) => e.source(db).value.visibility(),
VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(), VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(),
}; };
NameDefinition { kind, container, visibility } NameDefinition { kind, container, visibility }