mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Merge #2409
2409: Id-ify Ty::Adt r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
6e36eadd26
11 changed files with 98 additions and 39 deletions
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()?;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in a new issue