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,
resolver::{HasResolver, TypeNs},
type_ref::{Mutability, TypeRef},
AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule,
ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId,
StaticId, StructId, TraitId, TypeAliasId, UnionId,
AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
};
use hir_expand::{
diagnostics::DiagnosticSink,
@ -383,6 +383,28 @@ impl Union {
pub fn ty(self, db: &impl HirDatabase) -> Ty {
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)]
@ -501,14 +523,16 @@ impl Adt {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum VariantDef {
Struct(Struct),
Union(Union),
EnumVariant(EnumVariant),
}
impl_froms!(VariantDef: Struct, EnumVariant);
impl_froms!(VariantDef: Struct, Union, EnumVariant);
impl VariantDef {
pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
match self {
VariantDef::Struct(it) => it.fields(db),
VariantDef::Union(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> {
match self {
VariantDef::Struct(it) => it.field(db, name),
VariantDef::Union(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 {
match self {
VariantDef::Struct(it) => it.module(db),
VariantDef::Union(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> {
match self {
VariantDef::Struct(it) => it.variant_data(db),
VariantDef::Union(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)> {
let mut res = Vec::new();
if let Ty::Apply(a_ty) = &self.ty.value {
match a_ty.ctor {
ty::TypeCtor::Adt(Adt::Struct(s)) => {
for field in s.fields(db) {
let ty = field.ty(db).subst(&a_ty.parameters);
res.push((field, self.derived(ty)));
}
ty::TypeCtor::Adt(AdtId::StructId(s)) => {
let var_def = s.into();
return db
.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> {

View file

@ -2,7 +2,7 @@
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 ra_syntax::ast;
use ra_syntax::AstPtr;
@ -127,7 +127,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
_ => 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 {
Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
_ => 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 {
fn from(def: VariantDef) -> Self {
match def {
VariantDef::Struct(it) => VariantId::StructId(it.id),
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 {
fn from(def: AttrDef) -> Self {
match def {

View file

@ -58,7 +58,7 @@ pub enum TypeCtor {
Float(Uncertain<FloatTy>),
/// Structures, enumerations and unions.
Adt(Adt),
Adt(AdtId),
/// The pointee of a string slice. Written as `str`.
Str,
@ -174,7 +174,7 @@ impl TypeCtor {
| TypeCtor::Tuple { .. } => None,
// Closure's krate is irrelevant for coherence I would think?
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::AssociatedType(type_alias) => {
Some(type_alias.lookup(db).module(db).krate.into())
@ -598,7 +598,7 @@ impl Ty {
pub fn as_adt(&self) -> Option<(Adt, &Substs)> {
match self {
Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
Some((*adt_def, parameters))
Some(((*adt_def).into(), parameters))
}
_ => None,
}
@ -889,9 +889,9 @@ impl HirDisplay for ApplicationTy {
}
TypeCtor::Adt(def_id) => {
let name = match def_id {
Adt::Struct(s) => s.name(f.db),
Adt::Union(u) => u.name(f.db),
Adt::Enum(e) => e.name(f.db),
AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
}
.unwrap_or_else(Name::missing);
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)
}
fn resolve_boxed_box(&self) -> Option<Adt> {
fn resolve_boxed_box(&self) -> Option<AdtId> {
let path = known::std_boxed_box();
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
use hir_def::{lang_item::LangItemTarget, resolver::Resolver};
use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId};
use rustc_hash::FxHashMap;
use test_utils::tested_by;
use crate::{
db::HirDatabase,
ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
Adt, Mutability,
Mutability,
};
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
// - 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(Adt::Struct(struct2)), st2),
ty_app!(TypeCtor::Adt(AdtId::StructId(struct1)), st1),
ty_app!(TypeCtor::Adt(AdtId::StructId(struct2)), st2),
) if struct1 == struct2 => {
let field_tys = self.db.field_types(struct1.id.into());
let struct_data = self.db.struct_data(struct1.id);
let field_tys = self.db.field_types((*struct1).into());
let struct_data = self.db.struct_data(*struct1);
let mut fields = struct_data.variant_data.fields().iter();
let (last_field_id, _data) = fields.next_back()?;

View file

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

View file

@ -5,7 +5,7 @@
use std::sync::Arc;
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 crate::{
@ -102,7 +102,9 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV
let lang_item_targets = match ty {
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::Char => lang_item_crate!("char"),
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 {
match self {
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 visibility = match parent {
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(),
};
NameDefinition { kind, container, visibility }