From a443b5033c2e95ee58bf086f7093ddc610d4f78f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Nov 2019 14:29:12 +0300 Subject: Id-ify Ty::Adt --- crates/ra_hir/src/code_model.rs | 54 +++++++++++++++++----- crates/ra_hir/src/expr.rs | 4 +- crates/ra_hir/src/from_id.rs | 17 +++++++ crates/ra_hir/src/ty.rs | 12 ++--- crates/ra_hir/src/ty/infer.rs | 4 +- crates/ra_hir/src/ty/infer/coerce.rs | 12 ++--- crates/ra_hir/src/ty/infer/expr.rs | 21 +++++---- crates/ra_hir/src/ty/lower.rs | 2 +- crates/ra_hir/src/ty/method_resolution.rs | 6 ++- crates/ra_hir_def/src/adt.rs | 4 ++ .../ra_ide_api/src/references/name_definition.rs | 1 + 11 files changed, 98 insertions(+), 39 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a7bba85e1..bb1596bed 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -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 { + 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 { + 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 { + 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 { 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 { 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 { 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 { diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 43fedde7a..adb9805ab 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -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, diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 619f6055e..38daa5e59 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -199,11 +199,22 @@ impl From for GenericDefId { } } +impl From 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 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 for StructFieldId { } } +impl From for StructField { + fn from(def: StructFieldId) -> Self { + StructField { parent: def.parent.into(), id: def.local_id } + } +} + impl From for AttrDefId { fn from(def: AttrDef) -> Self { match def { diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 388530f31..bd03055b9 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -58,7 +58,7 @@ pub enum TypeCtor { Float(Uncertain), /// 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)?; diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 6fd00d457..fce45321d 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -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 { + fn resolve_boxed_box(&self) -> Option { let path = known::std_boxed_box(); let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; - Some(Adt::Struct(struct_.into())) + Some(struct_.into()) } } diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index bb9a2e427..5ed4470af 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -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: Unsize>, if the last field of Foo has type Bar ( - 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()?; diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 316cdc880..3d0895dc6 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -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| { - self.write_field_resolution(tgt_expr, field); - self.db.field_types(s.id.into())[field.id] - .clone() - .subst(&a_ty.parameters) - }), + 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.into())[field.id] + .clone() + .subst(&a_ty.parameters) + }) + } // FIXME: - TypeCtor::Adt(Adt::Union(_)) => None, + TypeCtor::Adt(AdtId::UnionId(_)) => None, _ => None, }, _ => None, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index d7d4bb0d6..485871e69 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -762,7 +762,7 @@ fn type_for_adt(db: &impl HirDatabase, adt: impl Into) -> 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 { diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index c5ab690eb..7f0ff2e8c 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -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 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 { diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 0091bfbc3..0cf418d30 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -129,6 +129,10 @@ impl VariantData { } } + pub fn field(&self, name: &Name) -> Option { + 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, diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs index aca23f79e..cf12db066 100644 --- a/crates/ra_ide_api/src/references/name_definition.rs +++ b/crates/ra_ide_api/src/references/name_definition.rs @@ -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 } -- cgit v1.2.3