aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model.rs54
-rw-r--r--crates/ra_hir/src/expr.rs4
-rw-r--r--crates/ra_hir/src/from_id.rs17
-rw-r--r--crates/ra_hir/src/ty.rs12
-rw-r--r--crates/ra_hir/src/ty/infer.rs4
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs12
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs21
-rw-r--r--crates/ra_hir/src/ty/lower.rs2
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs6
9 files changed, 93 insertions, 39 deletions
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::{
11 per_ns::PerNs, 11 per_ns::PerNs,
12 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
13 type_ref::{Mutability, TypeRef}, 13 type_ref::{Mutability, TypeRef},
14 AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, 14 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, FunctionId, GenericDefId,
15 ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, 15 HasModule, ImplId, LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId,
16 StaticId, StructId, TraitId, TypeAliasId, UnionId, 16 Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
17}; 17};
18use hir_expand::{ 18use hir_expand::{
19 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -383,6 +383,28 @@ impl Union {
383 pub fn ty(self, db: &impl HirDatabase) -> Ty { 383 pub fn ty(self, db: &impl HirDatabase) -> Ty {
384 db.type_for_def(self.into(), Namespace::Types) 384 db.type_for_def(self.into(), Namespace::Types)
385 } 385 }
386
387 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
388 db.union_data(self.id)
389 .variant_data
390 .fields()
391 .iter()
392 .map(|(id, _)| StructField { parent: self.into(), id })
393 .collect()
394 }
395
396 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
397 db.union_data(self.id)
398 .variant_data
399 .fields()
400 .iter()
401 .find(|(_id, data)| data.name == *name)
402 .map(|(id, _)| StructField { parent: self.into(), id })
403 }
404
405 fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
406 db.union_data(self.id).variant_data.clone()
407 }
386} 408}
387 409
388#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 410#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -501,14 +523,16 @@ impl Adt {
501#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 523#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
502pub enum VariantDef { 524pub enum VariantDef {
503 Struct(Struct), 525 Struct(Struct),
526 Union(Union),
504 EnumVariant(EnumVariant), 527 EnumVariant(EnumVariant),
505} 528}
506impl_froms!(VariantDef: Struct, EnumVariant); 529impl_froms!(VariantDef: Struct, Union, EnumVariant);
507 530
508impl VariantDef { 531impl VariantDef {
509 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 532 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
510 match self { 533 match self {
511 VariantDef::Struct(it) => it.fields(db), 534 VariantDef::Struct(it) => it.fields(db),
535 VariantDef::Union(it) => it.fields(db),
512 VariantDef::EnumVariant(it) => it.fields(db), 536 VariantDef::EnumVariant(it) => it.fields(db),
513 } 537 }
514 } 538 }
@@ -516,6 +540,7 @@ impl VariantDef {
516 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 540 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
517 match self { 541 match self {
518 VariantDef::Struct(it) => it.field(db, name), 542 VariantDef::Struct(it) => it.field(db, name),
543 VariantDef::Union(it) => it.field(db, name),
519 VariantDef::EnumVariant(it) => it.field(db, name), 544 VariantDef::EnumVariant(it) => it.field(db, name),
520 } 545 }
521 } 546 }
@@ -523,6 +548,7 @@ impl VariantDef {
523 pub fn module(self, db: &impl HirDatabase) -> Module { 548 pub fn module(self, db: &impl HirDatabase) -> Module {
524 match self { 549 match self {
525 VariantDef::Struct(it) => it.module(db), 550 VariantDef::Struct(it) => it.module(db),
551 VariantDef::Union(it) => it.module(db),
526 VariantDef::EnumVariant(it) => it.module(db), 552 VariantDef::EnumVariant(it) => it.module(db),
527 } 553 }
528 } 554 }
@@ -530,6 +556,7 @@ impl VariantDef {
530 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 556 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
531 match self { 557 match self {
532 VariantDef::Struct(it) => it.variant_data(db), 558 VariantDef::Struct(it) => it.variant_data(db),
559 VariantDef::Union(it) => it.variant_data(db),
533 VariantDef::EnumVariant(it) => it.variant_data(db), 560 VariantDef::EnumVariant(it) => it.variant_data(db),
534 } 561 }
535 } 562 }
@@ -1056,19 +1083,24 @@ impl Type {
1056 } 1083 }
1057 1084
1058 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> { 1085 pub fn fields(&self, db: &impl HirDatabase) -> Vec<(StructField, Type)> {
1059 let mut res = Vec::new();
1060 if let Ty::Apply(a_ty) = &self.ty.value { 1086 if let Ty::Apply(a_ty) = &self.ty.value {
1061 match a_ty.ctor { 1087 match a_ty.ctor {
1062 ty::TypeCtor::Adt(Adt::Struct(s)) => { 1088 ty::TypeCtor::Adt(AdtId::StructId(s)) => {
1063 for field in s.fields(db) { 1089 let var_def = s.into();
1064 let ty = field.ty(db).subst(&a_ty.parameters); 1090 return db
1065 res.push((field, self.derived(ty))); 1091 .field_types(var_def)
1066 } 1092 .iter()
1093 .map(|(local_id, ty)| {
1094 let def = StructField { parent: var_def.into(), id: local_id };
1095 let ty = ty.clone().subst(&a_ty.parameters);
1096 (def, self.derived(ty))
1097 })
1098 .collect();
1067 } 1099 }
1068 _ => {} 1100 _ => {}
1069 } 1101 }
1070 }; 1102 };
1071 res 1103 Vec::new()
1072 } 1104 }
1073 1105
1074 pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> { 1106 pub fn tuple_fields(&self, _db: &impl HirDatabase) -> Vec<Type> {
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 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{path::known, resolver::HasResolver}; 5use hir_def::{path::known, resolver::HasResolver, AdtId};
6use hir_expand::diagnostics::DiagnosticSink; 6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::ast; 7use ra_syntax::ast;
8use ra_syntax::AstPtr; 8use ra_syntax::AstPtr;
@@ -127,7 +127,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
127 _ => return, 127 _ => return,
128 }; 128 };
129 129
130 let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); 130 let std_result_ctor = TypeCtor::Adt(AdtId::EnumId(std_result_enum));
131 let params = match &mismatch.expected { 131 let params = match &mismatch.expected {
132 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, 132 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
133 _ => return, 133 _ => 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<Adt> for GenericDefId {
199 } 199 }
200} 200}
201 201
202impl From<VariantId> for VariantDef {
203 fn from(def: VariantId) -> Self {
204 match def {
205 VariantId::StructId(it) => VariantDef::Struct(it.into()),
206 VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()),
207 VariantId::UnionId(it) => VariantDef::Union(it.into()),
208 }
209 }
210}
211
202impl From<VariantDef> for VariantId { 212impl From<VariantDef> for VariantId {
203 fn from(def: VariantDef) -> Self { 213 fn from(def: VariantDef) -> Self {
204 match def { 214 match def {
205 VariantDef::Struct(it) => VariantId::StructId(it.id), 215 VariantDef::Struct(it) => VariantId::StructId(it.id),
206 VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()), 216 VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()),
217 VariantDef::Union(it) => VariantId::UnionId(it.id),
207 } 218 }
208 } 219 }
209} 220}
@@ -214,6 +225,12 @@ impl From<StructField> for StructFieldId {
214 } 225 }
215} 226}
216 227
228impl From<StructFieldId> for StructField {
229 fn from(def: StructFieldId) -> Self {
230 StructField { parent: def.parent.into(), id: def.local_id }
231 }
232}
233
217impl From<AttrDef> for AttrDefId { 234impl From<AttrDef> for AttrDefId {
218 fn from(def: AttrDef) -> Self { 235 fn from(def: AttrDef) -> Self {
219 match def { 236 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 {
58 Float(Uncertain<FloatTy>), 58 Float(Uncertain<FloatTy>),
59 59
60 /// Structures, enumerations and unions. 60 /// Structures, enumerations and unions.
61 Adt(Adt), 61 Adt(AdtId),
62 62
63 /// The pointee of a string slice. Written as `str`. 63 /// The pointee of a string slice. Written as `str`.
64 Str, 64 Str,
@@ -174,7 +174,7 @@ impl TypeCtor {
174 | TypeCtor::Tuple { .. } => None, 174 | TypeCtor::Tuple { .. } => None,
175 // Closure's krate is irrelevant for coherence I would think? 175 // Closure's krate is irrelevant for coherence I would think?
176 TypeCtor::Closure { .. } => None, 176 TypeCtor::Closure { .. } => None,
177 TypeCtor::Adt(adt) => adt.krate(db), 177 TypeCtor::Adt(adt) => Some(adt.module(db).krate.into()),
178 TypeCtor::FnDef(callable) => Some(callable.krate(db).into()), 178 TypeCtor::FnDef(callable) => Some(callable.krate(db).into()),
179 TypeCtor::AssociatedType(type_alias) => { 179 TypeCtor::AssociatedType(type_alias) => {
180 Some(type_alias.lookup(db).module(db).krate.into()) 180 Some(type_alias.lookup(db).module(db).krate.into())
@@ -598,7 +598,7 @@ impl Ty {
598 pub fn as_adt(&self) -> Option<(Adt, &Substs)> { 598 pub fn as_adt(&self) -> Option<(Adt, &Substs)> {
599 match self { 599 match self {
600 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 600 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
601 Some((*adt_def, parameters)) 601 Some(((*adt_def).into(), parameters))
602 } 602 }
603 _ => None, 603 _ => None,
604 } 604 }
@@ -889,9 +889,9 @@ impl HirDisplay for ApplicationTy {
889 } 889 }
890 TypeCtor::Adt(def_id) => { 890 TypeCtor::Adt(def_id) => {
891 let name = match def_id { 891 let name = match def_id {
892 Adt::Struct(s) => s.name(f.db), 892 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
893 Adt::Union(u) => u.name(f.db), 893 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
894 Adt::Enum(e) => e.name(f.db), 894 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
895 } 895 }
896 .unwrap_or_else(Name::missing); 896 .unwrap_or_else(Name::missing);
897 write!(f, "{}", name)?; 897 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> {
598 trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) 598 trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE)
599 } 599 }
600 600
601 fn resolve_boxed_box(&self) -> Option<Adt> { 601 fn resolve_boxed_box(&self) -> Option<AdtId> {
602 let path = known::std_boxed_box(); 602 let path = known::std_boxed_box();
603 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 603 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
604 Some(Adt::Struct(struct_.into())) 604 Some(struct_.into())
605 } 605 }
606} 606}
607 607
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 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; 7use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AdtId};
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{ 11use crate::{
12 db::HirDatabase, 12 db::HirDatabase,
13 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, 13 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
14 Adt, Mutability, 14 Mutability,
15}; 15};
16 16
17use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; 17use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
@@ -242,11 +242,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
242 // - T is not part of the type of any other fields 242 // - T is not part of the type of any other fields
243 // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T> 243 // - Bar<T>: Unsize<Bar<U>>, if the last field of Foo has type Bar<T>
244 ( 244 (
245 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), 245 ty_app!(TypeCtor::Adt(AdtId::StructId(struct1)), st1),
246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), 246 ty_app!(TypeCtor::Adt(AdtId::StructId(struct2)), st2),
247 ) if struct1 == struct2 => { 247 ) if struct1 == struct2 => {
248 let field_tys = self.db.field_types(struct1.id.into()); 248 let field_tys = self.db.field_types((*struct1).into());
249 let struct_data = self.db.struct_data(struct1.id); 249 let struct_data = self.db.struct_data(*struct1);
250 250
251 let mut fields = struct_data.variant_data.fields().iter(); 251 let mut fields = struct_data.variant_data.fields().iter();
252 let (last_field_id, _data) = fields.next_back()?; 252 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::{
8 generics::GenericParams, 8 generics::GenericParams,
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 ContainerId, Lookup, 11 AdtId, ContainerId, Lookup, StructFieldId,
12}; 12};
13use hir_expand::name; 13use hir_expand::name;
14 14
@@ -20,7 +20,7 @@ use crate::{
20 Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, 20 Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty,
21 TypeCtor, TypeWalk, Uncertain, 21 TypeCtor, TypeWalk, Uncertain,
22 }, 22 },
23 Adt, Name, 23 Name,
24}; 24};
25 25
26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -259,14 +259,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
259 TypeCtor::Tuple { .. } => name 259 TypeCtor::Tuple { .. } => name
260 .as_tuple_index() 260 .as_tuple_index()
261 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 261 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
262 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { 262 TypeCtor::Adt(AdtId::StructId(s)) => {
263 self.write_field_resolution(tgt_expr, field); 263 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
264 self.db.field_types(s.id.into())[field.id] 264 let field = StructFieldId { parent: s.into(), local_id }.into();
265 .clone() 265 self.write_field_resolution(tgt_expr, field);
266 .subst(&a_ty.parameters) 266 self.db.field_types(s.into())[field.id]
267 }), 267 .clone()
268 .subst(&a_ty.parameters)
269 })
270 }
268 // FIXME: 271 // FIXME:
269 TypeCtor::Adt(Adt::Union(_)) => None, 272 TypeCtor::Adt(AdtId::UnionId(_)) => None,
270 _ => None, 273 _ => None,
271 }, 274 },
272 _ => None, 275 _ => 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<Adt>) -> Ty {
762 let adt = adt.into(); 762 let adt = adt.into();
763 let adt_id: AdtId = adt.into(); 763 let adt_id: AdtId = adt.into();
764 let generics = db.generic_params(adt_id.into()); 764 let generics = db.generic_params(adt_id.into());
765 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) 765 Ty::apply(TypeCtor::Adt(adt_id), Substs::identity(&generics))
766} 766}
767 767
768fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 768fn 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 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef}; 8use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule};
9use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
10 10
11use crate::{ 11use crate::{
@@ -102,7 +102,9 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV
102 102
103 let lang_item_targets = match ty { 103 let lang_item_targets = match ty {
104 Ty::Apply(a_ty) => match a_ty.ctor { 104 Ty::Apply(a_ty) => match a_ty.ctor {
105 TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()), 105 TypeCtor::Adt(def_id) => {
106 return Some(std::iter::once(def_id.module(db).krate.into()).collect())
107 }
106 TypeCtor::Bool => lang_item_crate!("bool"), 108 TypeCtor::Bool => lang_item_crate!("bool"),
107 TypeCtor::Char => lang_item_crate!("char"), 109 TypeCtor::Char => lang_item_crate!("char"),
108 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { 110 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {