aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_arena/src/lib.rs10
-rw-r--r--crates/ra_cli/src/analysis_stats.rs11
-rw-r--r--crates/ra_hir/src/code_model.rs128
-rw-r--r--crates/ra_hir/src/code_model/src.rs37
-rw-r--r--crates/ra_hir/src/db.rs29
-rw-r--r--crates/ra_hir/src/from_id.rs41
-rw-r--r--crates/ra_hir/src/from_source.rs11
-rw-r--r--crates/ra_hir/src/impl_block.rs52
-rw-r--r--crates/ra_hir/src/lib.rs10
-rw-r--r--crates/ra_hir/src/source_binder.rs28
-rw-r--r--crates/ra_hir/src/ty.rs38
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs45
-rw-r--r--crates/ra_hir/src/ty/infer.rs13
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs26
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs87
-rw-r--r--crates/ra_hir/src/ty/infer/pat.rs9
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs2
-rw-r--r--crates/ra_hir/src/ty/lower.rs164
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs13
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs16
-rw-r--r--crates/ra_hir_def/src/adt.rs14
-rw-r--r--crates/ra_hir_def/src/body.rs3
-rw-r--r--crates/ra_hir_def/src/body/lower.rs3
-rw-r--r--crates/ra_hir_def/src/body/scope.rs2
-rw-r--r--crates/ra_hir_def/src/lib.rs23
-rw-r--r--crates/ra_hir_def/src/path.rs2
-rw-r--r--crates/ra_hir_def/src/per_ns.rs5
-rw-r--r--crates/ra_hir_def/src/resolver.rs18
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs59
-rw-r--r--crates/ra_hir_expand/src/name.rs1
-rw-r--r--crates/ra_ide_api/src/call_info.rs13
-rw-r--r--crates/ra_ide_api/src/change.rs2
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs2
-rw-r--r--crates/ra_ide_api/src/references/classify.rs10
34 files changed, 478 insertions, 449 deletions
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs
index 3ec8d3b60..fc0f7c12f 100644
--- a/crates/ra_arena/src/lib.rs
+++ b/crates/ra_arena/src/lib.rs
@@ -37,7 +37,7 @@ impl fmt::Display for RawId {
37} 37}
38 38
39#[derive(Clone, PartialEq, Eq)] 39#[derive(Clone, PartialEq, Eq)]
40pub struct Arena<ID: ArenaId, T> { 40pub struct Arena<ID, T> {
41 data: Vec<T>, 41 data: Vec<T>,
42 _ty: PhantomData<ID>, 42 _ty: PhantomData<ID>,
43} 43}
@@ -67,6 +67,12 @@ pub trait ArenaId {
67 fn into_raw(self) -> RawId; 67 fn into_raw(self) -> RawId;
68} 68}
69 69
70impl<ID, T> Arena<ID, T> {
71 pub const fn new() -> Arena<ID, T> {
72 Arena { data: Vec::new(), _ty: PhantomData }
73 }
74}
75
70impl<ID: ArenaId, T> Arena<ID, T> { 76impl<ID: ArenaId, T> Arena<ID, T> {
71 pub fn len(&self) -> usize { 77 pub fn len(&self) -> usize {
72 self.data.len() 78 self.data.len()
@@ -79,7 +85,7 @@ impl<ID: ArenaId, T> Arena<ID, T> {
79 self.data.push(value); 85 self.data.push(value);
80 ID::from_raw(id) 86 ID::from_raw(id)
81 } 87 }
82 pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator { 88 pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator + DoubleEndedIterator {
83 self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) 89 self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value))
84 } 90 }
85} 91}
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs
index 135de7ffb..c4eb28245 100644
--- a/crates/ra_cli/src/analysis_stats.rs
+++ b/crates/ra_cli/src/analysis_stats.rs
@@ -3,7 +3,7 @@
3use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; 3use std::{collections::HashSet, fmt::Write, path::Path, time::Instant};
4 4
5use ra_db::SourceDatabaseExt; 5use ra_db::SourceDatabaseExt;
6use ra_hir::{AssocItem, Crate, HasBodySource, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; 6use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk};
7use ra_syntax::AstNode; 7use ra_syntax::AstNode;
8 8
9use crate::{Result, Verbosity}; 9use crate::{Result, Verbosity};
@@ -128,15 +128,16 @@ pub fn run(
128 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { 128 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) {
129 num_type_mismatches += 1; 129 num_type_mismatches += 1;
130 if verbosity.is_verbose() { 130 if verbosity.is_verbose() {
131 let src = f.expr_source(db, expr_id); 131 let src = f.body_source_map(db).expr_syntax(expr_id);
132 if let Some(src) = src { 132 if let Some(src) = src {
133 // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly 133 // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly
134 let original_file = src.file_id.original_file(db); 134 let original_file = src.file_id.original_file(db);
135 let path = db.file_relative_path(original_file); 135 let path = db.file_relative_path(original_file);
136 let line_index = host.analysis().file_line_index(original_file).unwrap(); 136 let line_index = host.analysis().file_line_index(original_file).unwrap();
137 let text_range = src 137 let text_range = src.value.either(
138 .value 138 |it| it.syntax_node_ptr().range(),
139 .either(|it| it.syntax().text_range(), |it| it.syntax().text_range()); 139 |it| it.syntax_node_ptr().range(),
140 );
140 let (start, end) = ( 141 let (start, end) = (
141 line_index.line_col(text_range.start()), 142 line_index.line_col(text_range.start()),
142 line_index.line_col(text_range.end()), 143 line_index.line_col(text_range.end()),
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 9f06b147c..534f1f8e9 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -6,15 +6,14 @@ use std::sync::Arc;
6 6
7use hir_def::{ 7use hir_def::{
8 adt::VariantData, 8 adt::VariantData,
9 body::scope::ExprScopes,
10 builtin_type::BuiltinType, 9 builtin_type::BuiltinType,
11 docs::Documentation, 10 docs::Documentation,
12 per_ns::PerNs, 11 per_ns::PerNs,
13 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
14 type_ref::TypeRef, 13 type_ref::TypeRef,
15 AstItemDef, ConstId, ContainerId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, 14 AstItemDef, ConstId, ContainerId, EnumId, FunctionId, GenericDefId, HasModule, ImplId,
16 LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, 15 LocalEnumVariantId, LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId,
17 TraitId, TypeAliasId, UnionId, 16 StaticId, StructId, TraitId, TypeAliasId, UnionId,
18}; 17};
19use hir_expand::{ 18use hir_expand::{
20 diagnostics::DiagnosticSink, 19 diagnostics::DiagnosticSink,
@@ -28,7 +27,7 @@ use crate::{
28 db::{DefDatabase, HirDatabase}, 27 db::{DefDatabase, HirDatabase},
29 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, 28 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
30 ty::{InferenceResult, Namespace, TraitRef}, 29 ty::{InferenceResult, Namespace, TraitRef},
31 Either, HasSource, Name, Source, Ty, 30 Either, Name, Source, Ty,
32}; 31};
33 32
34/// hir::Crate describes a single crate. It's the main interface with which 33/// hir::Crate describes a single crate. It's the main interface with which
@@ -302,11 +301,11 @@ pub enum FieldSource {
302 301
303impl StructField { 302impl StructField {
304 pub fn name(&self, db: &impl HirDatabase) -> Name { 303 pub fn name(&self, db: &impl HirDatabase) -> Name {
305 self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() 304 self.parent.variant_data(db).fields()[self.id].name.clone()
306 } 305 }
307 306
308 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 307 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
309 db.type_for_field(*self) 308 db.field_types(self.parent.into())[self.id].clone()
310 } 309 }
311 310
312 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { 311 pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef {
@@ -336,8 +335,7 @@ impl Struct {
336 db.struct_data(self.id.into()) 335 db.struct_data(self.id.into())
337 .variant_data 336 .variant_data
338 .fields() 337 .fields()
339 .into_iter() 338 .iter()
340 .flat_map(|it| it.iter())
341 .map(|(id, _)| StructField { parent: self.into(), id }) 339 .map(|(id, _)| StructField { parent: self.into(), id })
342 .collect() 340 .collect()
343 } 341 }
@@ -346,8 +344,7 @@ impl Struct {
346 db.struct_data(self.id.into()) 344 db.struct_data(self.id.into())
347 .variant_data 345 .variant_data
348 .fields() 346 .fields()
349 .into_iter() 347 .iter()
350 .flat_map(|it| it.iter())
351 .find(|(_id, data)| data.name == *name) 348 .find(|(_id, data)| data.name == *name)
352 .map(|(id, _)| StructField { parent: self.into(), id }) 349 .map(|(id, _)| StructField { parent: self.into(), id })
353 } 350 }
@@ -444,8 +441,7 @@ impl EnumVariant {
444 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { 441 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
445 self.variant_data(db) 442 self.variant_data(db)
446 .fields() 443 .fields()
447 .into_iter() 444 .iter()
448 .flat_map(|it| it.iter())
449 .map(|(id, _)| StructField { parent: self.into(), id }) 445 .map(|(id, _)| StructField { parent: self.into(), id })
450 .collect() 446 .collect()
451 } 447 }
@@ -453,8 +449,7 @@ impl EnumVariant {
453 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 449 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
454 self.variant_data(db) 450 self.variant_data(db)
455 .fields() 451 .fields()
456 .into_iter() 452 .iter()
457 .flat_map(|it| it.iter())
458 .find(|(_id, data)| data.name == *name) 453 .find(|(_id, data)| data.name == *name)
459 .map(|(id, _)| StructField { parent: self.into(), id }) 454 .map(|(id, _)| StructField { parent: self.into(), id })
460 } 455 }
@@ -510,7 +505,7 @@ impl VariantDef {
510 } 505 }
511 } 506 }
512 507
513 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 508 pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
514 match self { 509 match self {
515 VariantDef::Struct(it) => it.field(db, name), 510 VariantDef::Struct(it) => it.field(db, name),
516 VariantDef::EnumVariant(it) => it.field(db, name), 511 VariantDef::EnumVariant(it) => it.field(db, name),
@@ -560,52 +555,6 @@ impl DefWithBody {
560 } 555 }
561} 556}
562 557
563pub trait HasBody: Copy {
564 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>;
565 fn body(self, db: &impl HirDatabase) -> Arc<Body>;
566 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>;
567 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>;
568}
569
570impl<T> HasBody for T
571where
572 T: Into<DefWithBody> + Copy + HasSource,
573{
574 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
575 db.infer(self.into())
576 }
577
578 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
579 self.into().body(db)
580 }
581
582 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
583 self.into().body_source_map(db)
584 }
585
586 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
587 self.into().expr_scopes(db)
588 }
589}
590
591impl HasBody for DefWithBody {
592 fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
593 db.infer(self)
594 }
595
596 fn body(self, db: &impl HirDatabase) -> Arc<Body> {
597 db.body(self.into())
598 }
599
600 fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
601 db.body_with_source_map(self.into()).1
602 }
603
604 fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
605 db.expr_scopes(self.into())
606 }
607}
608
609#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
610pub struct Function { 559pub struct Function {
611 pub(crate) id: FunctionId, 560 pub(crate) id: FunctionId,
@@ -632,7 +581,7 @@ impl Function {
632 db.function_data(self.id).params.clone() 581 db.function_data(self.id).params.clone()
633 } 582 }
634 583
635 pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 584 pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
636 db.body_with_source_map(self.id.into()).1 585 db.body_with_source_map(self.id.into()).1
637 } 586 }
638 587
@@ -948,16 +897,6 @@ impl_froms!(
948 Const 897 Const
949); 898);
950 899
951impl From<AssocItem> for GenericDef {
952 fn from(item: AssocItem) -> Self {
953 match item {
954 AssocItem::Function(f) => f.into(),
955 AssocItem::Const(c) => c.into(),
956 AssocItem::TypeAlias(t) => t.into(),
957 }
958 }
959}
960
961#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 900#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
962pub struct Local { 901pub struct Local {
963 pub(crate) parent: DefWithBody, 902 pub(crate) parent: DefWithBody,
@@ -966,7 +905,7 @@ pub struct Local {
966 905
967impl Local { 906impl Local {
968 pub fn name(self, db: &impl HirDatabase) -> Option<Name> { 907 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
969 let body = self.parent.body(db); 908 let body = db.body(self.parent.into());
970 match &body[self.pat_id] { 909 match &body[self.pat_id] {
971 Pat::Bind { name, .. } => Some(name.clone()), 910 Pat::Bind { name, .. } => Some(name.clone()),
972 _ => None, 911 _ => None,
@@ -978,7 +917,7 @@ impl Local {
978 } 917 }
979 918
980 pub fn is_mut(self, db: &impl HirDatabase) -> bool { 919 pub fn is_mut(self, db: &impl HirDatabase) -> bool {
981 let body = self.parent.body(db); 920 let body = db.body(self.parent.into());
982 match &body[self.pat_id] { 921 match &body[self.pat_id] {
983 Pat::Bind { mode, .. } => match mode { 922 Pat::Bind { mode, .. } => match mode {
984 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, 923 BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
@@ -1002,7 +941,7 @@ impl Local {
1002 } 941 }
1003 942
1004 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { 943 pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> {
1005 let source_map = self.parent.body_source_map(db); 944 let (_body, source_map) = db.body_with_source_map(self.parent.into());
1006 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... 945 let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
1007 let root = src.file_syntax(db); 946 let root = src.file_syntax(db);
1008 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) 947 src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root)))
@@ -1011,7 +950,7 @@ impl Local {
1011 950
1012#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 951#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1013pub struct GenericParam { 952pub struct GenericParam {
1014 pub(crate) parent: GenericDef, 953 pub(crate) parent: GenericDefId,
1015 pub(crate) idx: u32, 954 pub(crate) idx: u32,
1016} 955}
1017 956
@@ -1020,6 +959,41 @@ pub struct ImplBlock {
1020 pub(crate) id: ImplId, 959 pub(crate) id: ImplId,
1021} 960}
1022 961
962impl ImplBlock {
963 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
964 db.impl_data(self.id).target_trait.clone()
965 }
966
967 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
968 db.impl_data(self.id).target_type.clone()
969 }
970
971 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
972 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
973 }
974
975 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
976 let target_ty = self.target_ty(db);
977 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
978 }
979
980 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
981 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
982 }
983
984 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
985 db.impl_data(self.id).is_negative
986 }
987
988 pub fn module(&self, db: &impl DefDatabase) -> Module {
989 self.id.module(db).into()
990 }
991
992 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
993 Crate { crate_id: self.module(db).id.krate }
994 }
995}
996
1023/// For IDE only 997/// For IDE only
1024pub enum ScopeDef { 998pub enum ScopeDef {
1025 ModuleDef(ModuleDef), 999 ModuleDef(ModuleDef),
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index b9d21bdd7..a4e317c20 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -2,12 +2,11 @@
2 2
3use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId}; 3use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId};
4use hir_expand::either::Either; 4use hir_expand::either::Either;
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::ast;
6 6
7use crate::{ 7use crate::{
8 db::{DefDatabase, HirDatabase}, 8 db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef,
9 Const, Enum, EnumVariant, FieldSource, Function, HasBody, Import, MacroDef, Module, 9 Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
10 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
11}; 10};
12 11
13pub use hir_expand::Source; 12pub use hir_expand::Source;
@@ -109,6 +108,12 @@ impl HasSource for MacroDef {
109 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } 108 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) }
110 } 109 }
111} 110}
111impl HasSource for ImplBlock {
112 type Ast = ast::ImplBlock;
113 fn source(self, db: &impl DefDatabase) -> Source<ast::ImplBlock> {
114 self.id.source(db)
115 }
116}
112impl HasSource for Import { 117impl HasSource for Import {
113 type Ast = Either<ast::UseTree, ast::ExternCrateItem>; 118 type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
114 119
@@ -121,27 +126,3 @@ impl HasSource for Import {
121 src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root))) 126 src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root)))
122 } 127 }
123} 128}
124
125pub trait HasBodySource: HasBody + HasSource
126where
127 Self::Ast: AstNode,
128{
129 fn expr_source(
130 self,
131 db: &impl HirDatabase,
132 expr_id: crate::expr::ExprId,
133 ) -> Option<Source<Either<ast::Expr, ast::RecordField>>> {
134 let source_map = self.body_source_map(db);
135 let source_ptr = source_map.expr_syntax(expr_id)?;
136 let root = source_ptr.file_syntax(db);
137 let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root)));
138 Some(source)
139 }
140}
141
142impl<T> HasBodySource for T
143where
144 T: HasBody + HasSource,
145 T::Ast: AstNode,
146{
147}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index a9dab2d25..b034d4e44 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -2,6 +2,7 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use ra_arena::map::ArenaMap;
5use ra_db::salsa; 6use ra_db::salsa;
6 7
7use crate::{ 8use crate::{
@@ -11,15 +12,19 @@ use crate::{
11 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, 12 CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef,
12 TypeCtor, 13 TypeCtor,
13 }, 14 },
14 Crate, DefWithBody, GenericDef, ImplBlock, StructField, Trait, 15 Crate, DefWithBody, ImplBlock, Trait,
15}; 16};
16 17
17pub use hir_def::db::{ 18pub use hir_def::{
18 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, 19 db::{
19 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, 20 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery,
20 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, 21 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery,
21 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, 22 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase,
22 StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, 23 InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery,
24 RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery,
25 TypeAliasDataQuery,
26 },
27 GenericDefId, LocalStructFieldId, VariantId,
23}; 28};
24pub use hir_expand::db::{ 29pub use hir_expand::db::{
25 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 30 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
@@ -35,8 +40,8 @@ pub trait HirDatabase: DefDatabase {
35 #[salsa::invoke(crate::ty::type_for_def)] 40 #[salsa::invoke(crate::ty::type_for_def)]
36 fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; 41 fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty;
37 42
38 #[salsa::invoke(crate::ty::type_for_field)] 43 #[salsa::invoke(crate::ty::field_types_query)]
39 fn type_for_field(&self, field: StructField) -> Ty; 44 fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
40 45
41 #[salsa::invoke(crate::ty::callable_item_sig)] 46 #[salsa::invoke(crate::ty::callable_item_sig)]
42 fn callable_item_signature(&self, def: CallableDef) -> FnSig; 47 fn callable_item_signature(&self, def: CallableDef) -> FnSig;
@@ -44,15 +49,15 @@ pub trait HirDatabase: DefDatabase {
44 #[salsa::invoke(crate::ty::generic_predicates_for_param_query)] 49 #[salsa::invoke(crate::ty::generic_predicates_for_param_query)]
45 fn generic_predicates_for_param( 50 fn generic_predicates_for_param(
46 &self, 51 &self,
47 def: GenericDef, 52 def: GenericDefId,
48 param_idx: u32, 53 param_idx: u32,
49 ) -> Arc<[GenericPredicate]>; 54 ) -> Arc<[GenericPredicate]>;
50 55
51 #[salsa::invoke(crate::ty::generic_predicates_query)] 56 #[salsa::invoke(crate::ty::generic_predicates_query)]
52 fn generic_predicates(&self, def: GenericDef) -> Arc<[GenericPredicate]>; 57 fn generic_predicates(&self, def: GenericDefId) -> Arc<[GenericPredicate]>;
53 58
54 #[salsa::invoke(crate::ty::generic_defaults_query)] 59 #[salsa::invoke(crate::ty::generic_defaults_query)]
55 fn generic_defaults(&self, def: GenericDef) -> Substs; 60 fn generic_defaults(&self, def: GenericDefId) -> Substs;
56 61
57 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] 62 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
58 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 63 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs
index 529ac8251..619f6055e 100644
--- a/crates/ra_hir/src/from_id.rs
+++ b/crates/ra_hir/src/from_id.rs
@@ -9,9 +9,8 @@ use hir_def::{
9}; 9};
10 10
11use crate::{ 11use crate::{
12 ty::{CallableDef, TypableDef}, 12 ty::TypableDef, Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function,
13 Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, 13 GenericDef, ModuleDef, Static, StructField, TypeAlias, VariantDef,
14 ModuleDef, Static, StructField, TypeAlias, VariantDef,
15}; 14};
16 15
17impl From<ra_db::CrateId> for Crate { 16impl From<ra_db::CrateId> for Crate {
@@ -138,20 +137,6 @@ impl From<GenericDef> for GenericDefId {
138 } 137 }
139} 138}
140 139
141impl From<GenericDefId> for GenericDef {
142 fn from(def: GenericDefId) -> Self {
143 match def {
144 GenericDefId::FunctionId(it) => GenericDef::Function(it.into()),
145 GenericDefId::AdtId(it) => GenericDef::Adt(it.into()),
146 GenericDefId::TraitId(it) => GenericDef::Trait(it.into()),
147 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
148 GenericDefId::ImplId(it) => GenericDef::ImplBlock(it.into()),
149 GenericDefId::EnumVariantId(it) => GenericDef::EnumVariant(it.into()),
150 GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
151 }
152 }
153}
154
155impl From<AdtId> for TypableDef { 140impl From<AdtId> for TypableDef {
156 fn from(id: AdtId) -> Self { 141 fn from(id: AdtId) -> Self {
157 Adt::from(id).into() 142 Adt::from(id).into()
@@ -214,18 +199,6 @@ impl From<Adt> for GenericDefId {
214 } 199 }
215} 200}
216 201
217impl From<CallableDef> for GenericDefId {
218 fn from(def: CallableDef) -> Self {
219 match def {
220 CallableDef::Function(it) => it.id.into(),
221 CallableDef::Struct(it) => it.id.into(),
222 CallableDef::EnumVariant(it) => {
223 EnumVariantId { parent: it.parent.id, local_id: it.id }.into()
224 }
225 }
226 }
227}
228
229impl From<VariantDef> for VariantId { 202impl From<VariantDef> for VariantId {
230 fn from(def: VariantDef) -> Self { 203 fn from(def: VariantDef) -> Self {
231 match def { 204 match def {
@@ -257,3 +230,13 @@ impl From<AttrDef> for AttrDefId {
257 } 230 }
258 } 231 }
259} 232}
233
234impl From<AssocItem> for GenericDefId {
235 fn from(item: AssocItem) -> Self {
236 match item {
237 AssocItem::Function(f) => f.id.into(),
238 AssocItem::Const(c) => c.id.into(),
239 AssocItem::TypeAlias(t) => t.id.into(),
240 }
241 }
242}
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index f506bba70..1e7c22774 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -9,9 +9,9 @@ use ra_syntax::{
9 9
10use crate::{ 10use crate::{
11 db::{AstDatabase, DefDatabase, HirDatabase}, 11 db::{AstDatabase, DefDatabase, HirDatabase},
12 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, 12 AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock,
13 ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, 13 Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, StructField, Trait,
14 StructField, Trait, TypeAlias, Union, VariantDef, 14 TypeAlias, Union, VariantDef,
15}; 15};
16 16
17pub trait FromSource: Sized { 17pub trait FromSource: Sized {
@@ -200,8 +200,7 @@ impl FromSource for StructField {
200 variant_def 200 variant_def
201 .variant_data(db) 201 .variant_data(db)
202 .fields() 202 .fields()
203 .into_iter() 203 .iter()
204 .flat_map(|it| it.iter())
205 .map(|(id, _)| StructField { parent: variant_def, id }) 204 .map(|(id, _)| StructField { parent: variant_def, id })
206 .find(|f| f.source(db) == src) 205 .find(|f| f.source(db) == src)
207 } 206 }
@@ -221,7 +220,7 @@ impl Local {
221 }; 220 };
222 Some(res) 221 Some(res)
223 })?; 222 })?;
224 let source_map = parent.body_source_map(db); 223 let (_body, source_map) = db.body_with_source_map(parent.into());
225 let src = src.map(ast::Pat::from); 224 let src = src.map(ast::Pat::from);
226 let pat_id = source_map.node_pat(src.as_ref())?; 225 let pat_id = source_map.node_pat(src.as_ref())?;
227 Some(Local { parent, pat_id }) 226 Some(Local { parent, pat_id })
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
deleted file mode 100644
index 334eeebac..000000000
--- a/crates/ra_hir/src/impl_block.rs
+++ /dev/null
@@ -1,52 +0,0 @@
1//! FIXME: write short doc here
2
3use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef};
4use ra_syntax::ast;
5
6use crate::{
7 db::{AstDatabase, DefDatabase, HirDatabase},
8 ty::Ty,
9 AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef,
10};
11
12impl HasSource for ImplBlock {
13 type Ast = ast::ImplBlock;
14 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ImplBlock> {
15 self.id.source(db)
16 }
17}
18
19impl ImplBlock {
20 pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
21 db.impl_data(self.id).target_trait.clone()
22 }
23
24 pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef {
25 db.impl_data(self.id).target_type.clone()
26 }
27
28 pub fn target_ty(&self, db: &impl HirDatabase) -> Ty {
29 Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db))
30 }
31
32 pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
33 let target_ty = self.target_ty(db);
34 TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty))
35 }
36
37 pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> {
38 db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect()
39 }
40
41 pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
42 db.impl_data(self.id).is_negative
43 }
44
45 pub fn module(&self, db: &impl DefDatabase) -> Module {
46 self.id.module(db).into()
47 }
48
49 pub fn krate(&self, db: &impl DefDatabase) -> Crate {
50 Crate { crate_id: self.module(db).id.krate }
51 }
52}
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 8c589c728..843ce6a88 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -32,7 +32,6 @@ pub mod db;
32pub mod source_binder; 32pub mod source_binder;
33 33
34mod ty; 34mod ty;
35mod impl_block;
36mod expr; 35mod expr;
37pub mod diagnostics; 36pub mod diagnostics;
38mod util; 37mod util;
@@ -49,11 +48,10 @@ mod marks;
49 48
50pub use crate::{ 49pub use crate::{
51 code_model::{ 50 code_model::{
52 src::{HasBodySource, HasSource}, 51 src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency,
53 Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Docs, Enum, 52 DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam,
54 EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock, 53 HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef,
55 Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, 54 Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef,
56 StructField, Trait, TypeAlias, Union, VariantDef,
57 }, 55 },
58 expr::ExprScopes, 56 expr::ExprScopes,
59 from_source::FromSource, 57 from_source::FromSource,
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index cfc4bd326..cbfeca3ab 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -26,10 +26,12 @@ use ra_syntax::{
26use crate::{ 26use crate::{
27 db::HirDatabase, 27 db::HirDatabase,
28 expr::{BodySourceMap, ExprScopes, ScopeId}, 28 expr::{BodySourceMap, ExprScopes, ScopeId},
29 ty::method_resolution::{self, implements_trait}, 29 ty::{
30 method_resolution::{self, implements_trait},
31 TraitEnvironment,
32 },
30 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, 33 Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function,
31 GenericParam, HasBody, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, 34 GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias,
32 TypeAlias,
33}; 35};
34 36
35fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { 37fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> {
@@ -155,8 +157,8 @@ impl SourceAnalyzer {
155 ) -> SourceAnalyzer { 157 ) -> SourceAnalyzer {
156 let def_with_body = def_with_body_from_child_node(db, node); 158 let def_with_body = def_with_body_from_child_node(db, node);
157 if let Some(def) = def_with_body { 159 if let Some(def) = def_with_body {
158 let source_map = def.body_source_map(db); 160 let (_body, source_map) = db.body_with_source_map(def.into());
159 let scopes = def.expr_scopes(db); 161 let scopes = db.expr_scopes(def.into());
160 let scope = match offset { 162 let scope = match offset {
161 None => scope_for(&scopes, &source_map, node), 163 None => scope_for(&scopes, &source_map, node),
162 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), 164 Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
@@ -166,7 +168,7 @@ impl SourceAnalyzer {
166 resolver, 168 resolver,
167 body_owner: Some(def), 169 body_owner: Some(def),
168 body_source_map: Some(source_map), 170 body_source_map: Some(source_map),
169 infer: Some(def.infer(db)), 171 infer: Some(db.infer(def)),
170 scopes: Some(scopes), 172 scopes: Some(scopes),
171 file_id: node.file_id, 173 file_id: node.file_id,
172 } 174 }
@@ -216,6 +218,11 @@ impl SourceAnalyzer {
216 self.infer.as_ref()?.field_resolution(expr_id) 218 self.infer.as_ref()?.field_resolution(expr_id)
217 } 219 }
218 220
221 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
222 let expr_id = self.expr_id(&field.expr()?)?;
223 self.infer.as_ref()?.record_field_resolution(expr_id)
224 }
225
219 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { 226 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> {
220 let expr_id = self.expr_id(&record_lit.clone().into())?; 227 let expr_id = self.expr_id(&record_lit.clone().into())?;
221 self.infer.as_ref()?.variant_resolution_for_expr(expr_id) 228 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
@@ -244,7 +251,7 @@ impl SourceAnalyzer {
244 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { 251 let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty {
245 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 252 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
246 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { 253 TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam {
247 parent: self.resolver.generic_def().unwrap().into(), 254 parent: self.resolver.generic_def().unwrap(),
248 idx, 255 idx,
249 }), 256 }),
250 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { 257 TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
@@ -319,7 +326,7 @@ impl SourceAnalyzer {
319 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), 326 resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()),
320 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), 327 resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()),
321 resolver::ScopeDef::GenericParam(idx) => { 328 resolver::ScopeDef::GenericParam(idx) => {
322 let parent = self.resolver.generic_def().unwrap().into(); 329 let parent = self.resolver.generic_def().unwrap();
323 ScopeDef::GenericParam(GenericParam { parent, idx }) 330 ScopeDef::GenericParam(GenericParam { parent, idx })
324 } 331 }
325 resolver::ScopeDef::Local(pat_id) => { 332 resolver::ScopeDef::Local(pat_id) => {
@@ -404,7 +411,10 @@ impl SourceAnalyzer {
404 // There should be no inference vars in types passed here 411 // There should be no inference vars in types passed here
405 // FIXME check that? 412 // FIXME check that?
406 let canonical = crate::ty::Canonical { value: ty, num_vars: 0 }; 413 let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
407 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 414 let krate = self.resolver.krate();
415 let environment = TraitEnvironment::lower(db, &self.resolver);
416 let ty = crate::ty::InEnvironment { value: canonical, environment };
417 crate::ty::autoderef(db, krate, ty).map(|canonical| canonical.value)
408 } 418 }
409 419
410 /// Checks that particular type `ty` implements `std::future::Future`. 420 /// Checks that particular type `ty` implements `std::future::Future`.
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 309bd2727..8c045aaef 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -17,12 +17,12 @@ use std::ops::Deref;
17use std::sync::Arc; 17use std::sync::Arc;
18use std::{fmt, iter, mem}; 18use std::{fmt, iter, mem};
19 19
20use hir_def::{generics::GenericParams, AdtId}; 20use hir_def::{generics::GenericParams, AdtId, GenericDefId};
21use ra_db::{impl_intern_key, salsa}; 21use ra_db::{impl_intern_key, salsa};
22 22
23use crate::{ 23use crate::{
24 db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, 24 db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, IntTy,
25 GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, 25 Mutability, Name, Trait, TypeAlias, Uncertain,
26}; 26};
27use display::{HirDisplay, HirFormatter}; 27use display::{HirDisplay, HirFormatter};
28 28
@@ -30,8 +30,9 @@ pub(crate) use autoderef::autoderef;
30pub(crate) use infer::{infer_query, InferTy, InferenceResult}; 30pub(crate) use infer::{infer_query, InferTy, InferenceResult};
31pub use lower::CallableDef; 31pub use lower::CallableDef;
32pub(crate) use lower::{ 32pub(crate) use lower::{
33 callable_item_sig, generic_defaults_query, generic_predicates_for_param_query, 33 callable_item_sig, field_types_query, generic_defaults_query,
34 generic_predicates_query, type_for_def, type_for_field, Namespace, TypableDef, 34 generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace,
35 TypableDef,
35}; 36};
36pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 37pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
37 38
@@ -170,12 +171,12 @@ impl TypeCtor {
170 | TypeCtor::Tuple { .. } => None, 171 | TypeCtor::Tuple { .. } => None,
171 TypeCtor::Closure { def, .. } => def.krate(db), 172 TypeCtor::Closure { def, .. } => def.krate(db),
172 TypeCtor::Adt(adt) => adt.krate(db), 173 TypeCtor::Adt(adt) => adt.krate(db),
173 TypeCtor::FnDef(callable) => callable.krate(db), 174 TypeCtor::FnDef(callable) => Some(callable.krate(db).into()),
174 TypeCtor::AssociatedType(type_alias) => type_alias.krate(db), 175 TypeCtor::AssociatedType(type_alias) => type_alias.krate(db),
175 } 176 }
176 } 177 }
177 178
178 pub fn as_generic_def(self) -> Option<crate::GenericDef> { 179 pub fn as_generic_def(self) -> Option<GenericDefId> {
179 match self { 180 match self {
180 TypeCtor::Bool 181 TypeCtor::Bool
181 | TypeCtor::Char 182 | TypeCtor::Char
@@ -192,7 +193,7 @@ impl TypeCtor {
192 | TypeCtor::Closure { .. } => None, 193 | TypeCtor::Closure { .. } => None,
193 TypeCtor::Adt(adt) => Some(adt.into()), 194 TypeCtor::Adt(adt) => Some(adt.into()),
194 TypeCtor::FnDef(callable) => Some(callable.into()), 195 TypeCtor::FnDef(callable) => Some(callable.into()),
195 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()), 196 TypeCtor::AssociatedType(type_alias) => Some(type_alias.id.into()),
196 } 197 }
197 } 198 }
198} 199}
@@ -355,9 +356,9 @@ impl Substs {
355 ) 356 )
356 } 357 }
357 358
358 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDef>) -> SubstsBuilder { 359 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
359 let def = def.into(); 360 let def = def.into();
360 let params = db.generic_params(def.into()); 361 let params = db.generic_params(def);
361 let param_count = params.count_params_including_parent(); 362 let param_count = params.count_params_including_parent();
362 Substs::builder(param_count) 363 Substs::builder(param_count)
363 } 364 }
@@ -855,13 +856,20 @@ impl HirDisplay for ApplicationTy {
855 TypeCtor::FnDef(def) => { 856 TypeCtor::FnDef(def) => {
856 let sig = f.db.callable_item_signature(def); 857 let sig = f.db.callable_item_signature(def);
857 let name = match def { 858 let name = match def {
858 CallableDef::Function(ff) => ff.name(f.db), 859 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
859 CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing), 860 CallableDef::StructId(s) => {
860 CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing), 861 f.db.struct_data(s.0).name.clone().unwrap_or_else(Name::missing)
862 }
863 CallableDef::EnumVariantId(e) => {
864 let enum_data = f.db.enum_data(e.parent);
865 enum_data.variants[e.local_id].name.clone().unwrap_or_else(Name::missing)
866 }
861 }; 867 };
862 match def { 868 match def {
863 CallableDef::Function(_) => write!(f, "fn {}", name)?, 869 CallableDef::FunctionId(_) => write!(f, "fn {}", name)?,
864 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?, 870 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {
871 write!(f, "{}", name)?
872 }
865 } 873 }
866 if self.parameters.len() > 0 { 874 if self.parameters.len() > 0 {
867 write!(f, "<")?; 875 write!(f, "<")?;
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 41c99d227..44547197c 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -5,42 +5,49 @@
5 5
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; 8use hir_def::lang_item::LangItemTarget;
9use hir_expand::name; 9use hir_expand::name;
10use log::{info, warn}; 10use log::{info, warn};
11use ra_db::CrateId;
11 12
12use crate::{db::HirDatabase, Trait}; 13use crate::{db::HirDatabase, Trait};
13 14
14use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 15use super::{
16 traits::{InEnvironment, Solution},
17 Canonical, Substs, Ty, TypeWalk,
18};
15 19
16const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
17 21
18pub(crate) fn autoderef<'a>( 22pub(crate) fn autoderef<'a>(
19 db: &'a impl HirDatabase, 23 db: &'a impl HirDatabase,
20 resolver: &'a Resolver, 24 krate: Option<CrateId>,
21 ty: Canonical<Ty>, 25 ty: InEnvironment<Canonical<Ty>>,
22) -> impl Iterator<Item = Canonical<Ty>> + 'a { 26) -> impl Iterator<Item = Canonical<Ty>> + 'a {
23 successors(Some(ty), move |ty| deref(db, resolver, ty)).take(AUTODEREF_RECURSION_LIMIT) 27 let InEnvironment { value: ty, environment } = ty;
28 successors(Some(ty), move |ty| {
29 deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() })
30 })
31 .take(AUTODEREF_RECURSION_LIMIT)
24} 32}
25 33
26pub(crate) fn deref( 34pub(crate) fn deref(
27 db: &impl HirDatabase, 35 db: &impl HirDatabase,
28 resolver: &Resolver, 36 krate: CrateId,
29 ty: &Canonical<Ty>, 37 ty: InEnvironment<&Canonical<Ty>>,
30) -> Option<Canonical<Ty>> { 38) -> Option<Canonical<Ty>> {
31 if let Some(derefed) = ty.value.builtin_deref() { 39 if let Some(derefed) = ty.value.value.builtin_deref() {
32 Some(Canonical { value: derefed, num_vars: ty.num_vars }) 40 Some(Canonical { value: derefed, num_vars: ty.value.num_vars })
33 } else { 41 } else {
34 deref_by_trait(db, resolver, ty) 42 deref_by_trait(db, krate, ty)
35 } 43 }
36} 44}
37 45
38fn deref_by_trait( 46fn deref_by_trait(
39 db: &impl HirDatabase, 47 db: &impl HirDatabase,
40 resolver: &Resolver, 48 krate: CrateId,
41 ty: &Canonical<Ty>, 49 ty: InEnvironment<&Canonical<Ty>>,
42) -> Option<Canonical<Ty>> { 50) -> Option<Canonical<Ty>> {
43 let krate = resolver.krate()?;
44 let deref_trait = match db.lang_item(krate.into(), "deref".into())? { 51 let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
45 LangItemTarget::TraitId(t) => Trait::from(t), 52 LangItemTarget::TraitId(t) => Trait::from(t),
46 _ => return None, 53 _ => return None,
@@ -56,10 +63,8 @@ fn deref_by_trait(
56 63
57 // FIXME make the Canonical handling nicer 64 // FIXME make the Canonical handling nicer
58 65
59 let env = super::lower::trait_env(db, resolver);
60
61 let parameters = Substs::build_for_generics(&generic_params) 66 let parameters = Substs::build_for_generics(&generic_params)
62 .push(ty.value.clone().shift_bound_vars(1)) 67 .push(ty.value.value.clone().shift_bound_vars(1))
63 .build(); 68 .build();
64 69
65 let projection = super::traits::ProjectionPredicate { 70 let projection = super::traits::ProjectionPredicate {
@@ -69,9 +74,9 @@ fn deref_by_trait(
69 74
70 let obligation = super::Obligation::Projection(projection); 75 let obligation = super::Obligation::Projection(projection);
71 76
72 let in_env = super::traits::InEnvironment { value: obligation, environment: env }; 77 let in_env = InEnvironment { value: obligation, environment: ty.environment };
73 78
74 let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; 79 let canonical = super::Canonical { num_vars: 1 + ty.value.num_vars, value: in_env };
75 80
76 let solution = db.trait_solve(krate.into(), canonical)?; 81 let solution = db.trait_solve(krate.into(), canonical)?;
77 82
@@ -89,14 +94,14 @@ fn deref_by_trait(
89 // the case. 94 // the case.
90 for i in 1..vars.0.num_vars { 95 for i in 1..vars.0.num_vars {
91 if vars.0.value[i] != Ty::Bound((i - 1) as u32) { 96 if vars.0.value[i] != Ty::Bound((i - 1) as u32) {
92 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); 97 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
93 return None; 98 return None;
94 } 99 }
95 } 100 }
96 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) 101 Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars })
97 } 102 }
98 Solution::Ambig(_) => { 103 Solution::Ambig(_) => {
99 info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); 104 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
100 None 105 None
101 } 106 }
102 } 107 }
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 2e744e5ec..6fd00d457 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -34,7 +34,6 @@ use ra_prof::profile;
34use test_utils::tested_by; 34use test_utils::tested_by;
35 35
36use super::{ 36use super::{
37 lower,
38 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 37 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
39 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, 38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef,
40 TypeCtor, TypeWalk, Uncertain, 39 TypeCtor, TypeWalk, Uncertain,
@@ -44,8 +43,7 @@ use crate::{
44 db::HirDatabase, 43 db::HirDatabase,
45 expr::{BindingAnnotation, Body, ExprId, PatId}, 44 expr::{BindingAnnotation, Body, ExprId, PatId},
46 ty::infer::diagnostics::InferenceDiagnostic, 45 ty::infer::diagnostics::InferenceDiagnostic,
47 Adt, AssocItem, DefWithBody, FloatTy, Function, HasBody, IntTy, Path, StructField, Trait, 46 Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef,
48 VariantDef,
49}; 47};
50 48
51macro_rules! ty_app { 49macro_rules! ty_app {
@@ -126,6 +124,8 @@ pub struct InferenceResult {
126 method_resolutions: FxHashMap<ExprId, Function>, 124 method_resolutions: FxHashMap<ExprId, Function>,
127 /// For each field access expr, records the field it resolves to. 125 /// For each field access expr, records the field it resolves to.
128 field_resolutions: FxHashMap<ExprId, StructField>, 126 field_resolutions: FxHashMap<ExprId, StructField>,
127 /// For each field in record literal, records the field it resolves to.
128 record_field_resolutions: FxHashMap<ExprId, StructField>,
129 /// For each struct literal, records the variant it resolves to. 129 /// For each struct literal, records the variant it resolves to.
130 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, 130 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>,
131 /// For each associated item record what it resolves to 131 /// For each associated item record what it resolves to
@@ -143,6 +143,9 @@ impl InferenceResult {
143 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { 143 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
144 self.field_resolutions.get(&expr).copied() 144 self.field_resolutions.get(&expr).copied()
145 } 145 }
146 pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> {
147 self.record_field_resolutions.get(&expr).copied()
148 }
146 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { 149 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> {
147 self.variant_resolutions.get(&id.into()).copied() 150 self.variant_resolutions.get(&id.into()).copied()
148 } 151 }
@@ -212,11 +215,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
212 var_unification_table: InPlaceUnificationTable::new(), 215 var_unification_table: InPlaceUnificationTable::new(),
213 obligations: Vec::default(), 216 obligations: Vec::default(),
214 return_ty: Ty::Unknown, // set in collect_fn_signature 217 return_ty: Ty::Unknown, // set in collect_fn_signature
215 trait_env: lower::trait_env(db, &resolver), 218 trait_env: TraitEnvironment::lower(db, &resolver),
216 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), 219 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver),
217 db, 220 db,
218 owner, 221 owner,
219 body: owner.body(db), 222 body: db.body(owner.into()),
220 resolver, 223 resolver,
221 } 224 }
222 } 225 }
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs
index 4ea038d99..4b53bba73 100644
--- a/crates/ra_hir/src/ty/infer/coerce.rs
+++ b/crates/ra_hir/src/ty/infer/coerce.rs
@@ -14,7 +14,7 @@ use crate::{
14 Adt, Mutability, 14 Adt, Mutability,
15}; 15};
16 16
17use super::{InferTy, InferenceContext, TypeVarValue}; 17use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
18 18
19impl<'a, D: HirDatabase> InferenceContext<'a, D> { 19impl<'a, D: HirDatabase> InferenceContext<'a, D> {
20 /// Unify two types, but may coerce the first one to the second one 20 /// Unify two types, but may coerce the first one to the second one
@@ -245,14 +245,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
245 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), 245 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1),
246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), 246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2),
247 ) if struct1 == struct2 => { 247 ) if struct1 == struct2 => {
248 let fields = struct1.fields(self.db); 248 let field_tys = self.db.field_types(struct1.id.into());
249 let (last_field, prev_fields) = fields.split_last()?; 249 let struct_data = self.db.struct_data(struct1.id.0);
250
251 let mut fields = struct_data.variant_data.fields().iter();
252 let (last_field_id, _data) = fields.next_back()?;
250 253
251 // Get the generic parameter involved in the last field. 254 // Get the generic parameter involved in the last field.
252 let unsize_generic_index = { 255 let unsize_generic_index = {
253 let mut index = None; 256 let mut index = None;
254 let mut multiple_param = false; 257 let mut multiple_param = false;
255 last_field.ty(self.db).walk(&mut |ty| match ty { 258 field_tys[last_field_id].walk(&mut |ty| match ty {
256 &Ty::Param { idx, .. } => { 259 &Ty::Param { idx, .. } => {
257 if index.is_none() { 260 if index.is_none() {
258 index = Some(idx); 261 index = Some(idx);
@@ -271,8 +274,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
271 274
272 // Check other fields do not involve it. 275 // Check other fields do not involve it.
273 let mut multiple_used = false; 276 let mut multiple_used = false;
274 prev_fields.iter().for_each(|field| { 277 fields.for_each(|(field_id, _data)| {
275 field.ty(self.db).walk(&mut |ty| match ty { 278 field_tys[field_id].walk(&mut |ty| match ty {
276 &Ty::Param { idx, .. } if idx == unsize_generic_index => { 279 &Ty::Param { idx, .. } if idx == unsize_generic_index => {
277 multiple_used = true 280 multiple_used = true
278 } 281 }
@@ -317,9 +320,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
317 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); 320 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone());
318 let to_ty = self.resolve_ty_shallow(&to_ty); 321 let to_ty = self.resolve_ty_shallow(&to_ty);
319 // FIXME: Auto DerefMut 322 // FIXME: Auto DerefMut
320 for derefed_ty in 323 for derefed_ty in autoderef::autoderef(
321 autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) 324 self.db,
322 { 325 self.resolver.krate(),
326 InEnvironment {
327 value: canonicalized.value.clone(),
328 environment: self.trait_env.clone(),
329 },
330 ) {
323 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 331 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
324 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 332 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) {
325 // Stop when constructor matches. 333 // Stop when constructor matches.
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs
index 20a7e9352..1d6df2b7a 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -8,6 +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}; 12};
12use hir_expand::name; 13use hir_expand::name;
13 14
@@ -15,9 +16,9 @@ use crate::{
15 db::HirDatabase, 16 db::HirDatabase,
16 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 17 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
17 ty::{ 18 ty::{
18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, 19 autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy,
19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 20 Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty,
20 Uncertain, 21 TypeCtor, TypeWalk, Uncertain,
21 }, 22 },
22 Adt, Name, 23 Adt, Name,
23}; 24};
@@ -214,19 +215,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
214 self.unify(&ty, &expected.ty); 215 self.unify(&ty, &expected.ty);
215 216
216 let substs = ty.substs().unwrap_or_else(Substs::empty); 217 let substs = ty.substs().unwrap_or_else(Substs::empty);
218 let field_types =
219 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default();
217 for (field_idx, field) in fields.iter().enumerate() { 220 for (field_idx, field) in fields.iter().enumerate() {
218 let field_ty = def_id 221 let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) {
219 .and_then(|it| match it.field(self.db, &field.name) { 222 Some(field) => Some(field),
220 Some(field) => Some(field), 223 None => {
221 None => { 224 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
222 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 225 expr: tgt_expr,
223 expr: tgt_expr, 226 field: field_idx,
224 field: field_idx, 227 });
225 }); 228 None
226 None 229 }
227 } 230 });
228 }) 231 if let Some(field_def) = field_def {
229 .map_or(Ty::Unknown, |field| field.ty(self.db)) 232 self.result.record_field_resolutions.insert(field.expr, field_def);
233 }
234 let field_ty = field_def
235 .map_or(Ty::Unknown, |it| field_types[it.id].clone())
230 .subst(&substs); 236 .subst(&substs);
231 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 237 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
232 } 238 }
@@ -240,8 +246,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
240 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); 246 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty);
241 let ty = autoderef::autoderef( 247 let ty = autoderef::autoderef(
242 self.db, 248 self.db,
243 &self.resolver.clone(), 249 self.resolver.krate(),
244 canonicalized.value.clone(), 250 InEnvironment {
251 value: canonicalized.value.clone(),
252 environment: self.trait_env.clone(),
253 },
245 ) 254 )
246 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 255 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
247 Ty::Apply(a_ty) => match a_ty.ctor { 256 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -250,7 +259,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
250 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 259 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
251 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { 260 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| {
252 self.write_field_resolution(tgt_expr, field); 261 self.write_field_resolution(tgt_expr, field);
253 field.ty(self.db).subst(&a_ty.parameters) 262 self.db.field_types(s.id.into())[field.id]
263 .clone()
264 .subst(&a_ty.parameters)
254 }), 265 }),
255 _ => None, 266 _ => None,
256 }, 267 },
@@ -330,16 +341,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
330 Expr::UnaryOp { expr, op } => { 341 Expr::UnaryOp { expr, op } => {
331 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 342 let inner_ty = self.infer_expr(*expr, &Expectation::none());
332 match op { 343 match op {
333 UnaryOp::Deref => { 344 UnaryOp::Deref => match self.resolver.krate() {
334 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); 345 Some(krate) => {
335 if let Some(derefed_ty) = 346 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty);
336 autoderef::deref(self.db, &self.resolver, &canonicalized.value) 347 match autoderef::deref(
337 { 348 self.db,
338 canonicalized.decanonicalize_ty(derefed_ty.value) 349 krate,
339 } else { 350 InEnvironment {
340 Ty::Unknown 351 value: &canonicalized.value,
352 environment: self.trait_env.clone(),
353 },
354 ) {
355 Some(derefed_ty) => {
356 canonicalized.decanonicalize_ty(derefed_ty.value)
357 }
358 None => Ty::Unknown,
359 }
341 } 360 }
342 } 361 None => Ty::Unknown,
362 },
343 UnaryOp::Neg => { 363 UnaryOp::Neg => {
344 match &inner_ty { 364 match &inner_ty {
345 Ty::Apply(a_ty) => match a_ty.ctor { 365 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -641,18 +661,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
641 } 661 }
642 // add obligation for trait implementation, if this is a trait method 662 // add obligation for trait implementation, if this is a trait method
643 match def { 663 match def {
644 CallableDef::Function(f) => { 664 CallableDef::FunctionId(f) => {
645 if let Some(trait_) = f.parent_trait(self.db) { 665 if let ContainerId::TraitId(trait_) = f.lookup(self.db).container {
646 // construct a TraitDef 666 // construct a TraitDef
647 let substs = a_ty.parameters.prefix( 667 let substs = a_ty.parameters.prefix(
648 self.db 668 self.db
649 .generic_params(trait_.id.into()) 669 .generic_params(trait_.into())
650 .count_params_including_parent(), 670 .count_params_including_parent(),
651 ); 671 );
652 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 672 self.obligations.push(Obligation::Trait(TraitRef {
673 trait_: trait_.into(),
674 substs,
675 }));
653 } 676 }
654 } 677 }
655 CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} 678 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {}
656 } 679 }
657 } 680 }
658 } 681 }
diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs
index c125ddfbc..641d61e87 100644
--- a/crates/ra_hir/src/ty/infer/pat.rs
+++ b/crates/ra_hir/src/ty/infer/pat.rs
@@ -27,10 +27,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
27 27
28 let substs = ty.substs().unwrap_or_else(Substs::empty); 28 let substs = ty.substs().unwrap_or_else(Substs::empty);
29 29
30 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
30 for (i, &subpat) in subpats.iter().enumerate() { 31 for (i, &subpat) in subpats.iter().enumerate() {
31 let expected_ty = def 32 let expected_ty = def
32 .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) 33 .and_then(|d| d.field(self.db, &Name::new_tuple_field(i)))
33 .map_or(Ty::Unknown, |field| field.ty(self.db)) 34 .map_or(Ty::Unknown, |field| field_tys[field.id].clone())
34 .subst(&substs); 35 .subst(&substs);
35 let expected_ty = self.normalize_associated_types_in(expected_ty); 36 let expected_ty = self.normalize_associated_types_in(expected_ty);
36 self.infer_pat(subpat, &expected_ty, default_bm); 37 self.infer_pat(subpat, &expected_ty, default_bm);
@@ -56,10 +57,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
56 57
57 let substs = ty.substs().unwrap_or_else(Substs::empty); 58 let substs = ty.substs().unwrap_or_else(Substs::empty);
58 59
60 let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default();
59 for subpat in subpats { 61 for subpat in subpats {
60 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); 62 let matching_field = def.and_then(|it| it.field(self.db, &subpat.name));
61 let expected_ty = 63 let expected_ty = matching_field
62 matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); 64 .map_or(Ty::Unknown, |field| field_tys[field.id].clone())
65 .subst(&substs);
63 let expected_ty = self.normalize_associated_types_in(expected_ty); 66 let expected_ty = self.normalize_associated_types_in(expected_ty);
64 self.infer_pat(subpat.pat, &expected_ty, default_bm); 67 self.infer_pat(subpat.pat, &expected_ty, default_bm);
65 } 68 }
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs
index ee54d8217..6165eba4f 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -203,7 +203,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
203 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), 203 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()),
204 Container::Trait(t) => { 204 Container::Trait(t) => {
205 // we're picking this method 205 // we're picking this method
206 let trait_substs = Substs::build_for_def(self.db, t) 206 let trait_substs = Substs::build_for_def(self.db, t.id)
207 .push(ty.clone()) 207 .push(ty.clone())
208 .fill(std::iter::repeat_with(|| self.new_type_var())) 208 .fill(std::iter::repeat_with(|| self.new_type_var()))
209 .build(); 209 .build();
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index 2272510e8..27cfe00c1 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -14,12 +14,15 @@ use hir_def::{
14 path::{GenericArg, PathSegment}, 14 path::{GenericArg, PathSegment},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, GenericDefId, 17 AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId,
18 Lookup, StructId, VariantId,
18}; 19};
20use ra_arena::map::ArenaMap;
21use ra_db::CrateId;
19 22
20use super::{ 23use super::{
21 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 24 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef,
22 TypeWalk, 25 Ty, TypeCtor, TypeWalk,
23}; 26};
24use crate::{ 27use crate::{
25 db::HirDatabase, 28 db::HirDatabase,
@@ -28,8 +31,8 @@ use crate::{
28 Adt, 31 Adt,
29 }, 32 },
30 util::make_mut_slice, 33 util::make_mut_slice,
31 Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, 34 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait,
32 StructField, Trait, TypeAlias, Union, VariantDef, 35 TypeAlias, Union,
33}; 36};
34 37
35// FIXME: this is only really used in `type_for_def`, which contains a bunch of 38// FIXME: this is only really used in `type_for_def`, which contains a bunch of
@@ -260,8 +263,10 @@ impl Ty {
260 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); 263 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db));
261 for t in traits { 264 for t in traits {
262 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { 265 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) {
263 let substs = 266 let substs = Substs::build_for_def(db, t.id)
264 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 267 .push(self_ty.clone())
268 .fill_with_unknown()
269 .build();
265 // FIXME handle type parameters on the segment 270 // FIXME handle type parameters on the segment
266 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); 271 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
267 } 272 }
@@ -286,11 +291,11 @@ impl Ty {
286 segment: &PathSegment, 291 segment: &PathSegment,
287 resolved: TypableDef, 292 resolved: TypableDef,
288 ) -> Substs { 293 ) -> Substs {
289 let def_generic: Option<GenericDef> = match resolved { 294 let def_generic: Option<GenericDefId> = match resolved {
290 TypableDef::Function(func) => Some(func.into()), 295 TypableDef::Function(func) => Some(func.id.into()),
291 TypableDef::Adt(adt) => Some(adt.into()), 296 TypableDef::Adt(adt) => Some(adt.into()),
292 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), 297 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()),
293 TypableDef::TypeAlias(t) => Some(t.into()), 298 TypableDef::TypeAlias(t) => Some(t.id.into()),
294 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, 299 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
295 }; 300 };
296 substs_from_path_segment(db, resolver, segment, def_generic, false) 301 substs_from_path_segment(db, resolver, segment, def_generic, false)
@@ -337,7 +342,7 @@ pub(super) fn substs_from_path_segment(
337 db: &impl HirDatabase, 342 db: &impl HirDatabase,
338 resolver: &Resolver, 343 resolver: &Resolver,
339 segment: &PathSegment, 344 segment: &PathSegment,
340 def_generic: Option<GenericDef>, 345 def_generic: Option<GenericDefId>,
341 add_self_param: bool, 346 add_self_param: bool,
342) -> Substs { 347) -> Substs {
343 let mut substs = Vec::new(); 348 let mut substs = Vec::new();
@@ -375,7 +380,7 @@ pub(super) fn substs_from_path_segment(
375 380
376 // handle defaults 381 // handle defaults
377 if let Some(def_generic) = def_generic { 382 if let Some(def_generic) = def_generic {
378 let default_substs = db.generic_defaults(def_generic); 383 let default_substs = db.generic_defaults(def_generic.into());
379 assert_eq!(substs.len(), default_substs.len()); 384 assert_eq!(substs.len(), default_substs.len());
380 385
381 for (i, default_ty) in default_substs.iter().enumerate() { 386 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -438,7 +443,7 @@ impl TraitRef {
438 ) -> Substs { 443 ) -> Substs {
439 let has_self_param = 444 let has_self_param =
440 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 445 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
441 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 446 substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
442 } 447 }
443 448
444 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { 449 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
@@ -543,22 +548,29 @@ pub(crate) fn type_for_def(db: &impl HirDatabase, def: TypableDef, ns: Namespace
543/// Build the signature of a callable item (function, struct or enum variant). 548/// Build the signature of a callable item (function, struct or enum variant).
544pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { 549pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig {
545 match def { 550 match def {
546 CallableDef::Function(f) => fn_sig_for_fn(db, f), 551 CallableDef::FunctionId(f) => fn_sig_for_fn(db, f),
547 CallableDef::Struct(s) => fn_sig_for_struct_constructor(db, s), 552 CallableDef::StructId(s) => fn_sig_for_struct_constructor(db, s),
548 CallableDef::EnumVariant(e) => fn_sig_for_enum_variant_constructor(db, e), 553 CallableDef::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
549 } 554 }
550} 555}
551 556
552/// Build the type of a specific field of a struct or enum variant. 557/// Build the type of all specific fields of a struct or enum variant.
553pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 558pub(crate) fn field_types_query(
554 let parent_def = field.parent_def(db); 559 db: &impl HirDatabase,
555 let resolver = match parent_def { 560 variant_id: VariantId,
556 VariantDef::Struct(it) => it.id.resolver(db), 561) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
557 VariantDef::EnumVariant(it) => it.parent.id.resolver(db), 562 let (resolver, var_data) = match variant_id {
563 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()),
564 VariantId::EnumVariantId(it) => (
565 it.parent.resolver(db),
566 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(),
567 ),
558 }; 568 };
559 let var_data = parent_def.variant_data(db); 569 let mut res = ArenaMap::default();
560 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 570 for (field_id, field_data) in var_data.fields().iter() {
561 Ty::from_hir(db, &resolver, type_ref) 571 res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref))
572 }
573 Arc::new(res)
562} 574}
563 575
564/// This query exists only to be used when resolving short-hand associated types 576/// This query exists only to be used when resolving short-hand associated types
@@ -571,10 +583,10 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
571/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 583/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
572pub(crate) fn generic_predicates_for_param_query( 584pub(crate) fn generic_predicates_for_param_query(
573 db: &impl HirDatabase, 585 db: &impl HirDatabase,
574 def: GenericDef, 586 def: GenericDefId,
575 param_idx: u32, 587 param_idx: u32,
576) -> Arc<[GenericPredicate]> { 588) -> Arc<[GenericPredicate]> {
577 let resolver = GenericDefId::from(def).resolver(db); 589 let resolver = def.resolver(db);
578 resolver 590 resolver
579 .where_predicates_in_scope() 591 .where_predicates_in_scope()
580 // we have to filter out all other predicates *first*, before attempting to lower them 592 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -583,24 +595,23 @@ pub(crate) fn generic_predicates_for_param_query(
583 .collect() 595 .collect()
584} 596}
585 597
586pub(crate) fn trait_env( 598impl TraitEnvironment {
587 db: &impl HirDatabase, 599 pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
588 resolver: &Resolver, 600 let predicates = resolver
589) -> Arc<super::TraitEnvironment> { 601 .where_predicates_in_scope()
590 let predicates = resolver 602 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
591 .where_predicates_in_scope() 603 .collect::<Vec<_>>();
592 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
593 .collect::<Vec<_>>();
594 604
595 Arc::new(super::TraitEnvironment { predicates }) 605 Arc::new(TraitEnvironment { predicates })
606 }
596} 607}
597 608
598/// Resolve the where clause(s) of an item with generics. 609/// Resolve the where clause(s) of an item with generics.
599pub(crate) fn generic_predicates_query( 610pub(crate) fn generic_predicates_query(
600 db: &impl HirDatabase, 611 db: &impl HirDatabase,
601 def: GenericDef, 612 def: GenericDefId,
602) -> Arc<[GenericPredicate]> { 613) -> Arc<[GenericPredicate]> {
603 let resolver = GenericDefId::from(def).resolver(db); 614 let resolver = def.resolver(db);
604 resolver 615 resolver
605 .where_predicates_in_scope() 616 .where_predicates_in_scope()
606 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 617 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -608,8 +619,8 @@ pub(crate) fn generic_predicates_query(
608} 619}
609 620
610/// Resolve the default type params from generics 621/// Resolve the default type params from generics
611pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 622pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
612 let resolver = GenericDefId::from(def).resolver(db); 623 let resolver = def.resolver(db);
613 let generic_params = db.generic_params(def.into()); 624 let generic_params = db.generic_params(def.into());
614 625
615 let defaults = generic_params 626 let defaults = generic_params
@@ -621,9 +632,9 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
621 Substs(defaults) 632 Substs(defaults)
622} 633}
623 634
624fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 635fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig {
625 let data = db.function_data(def.id); 636 let data = db.function_data(def);
626 let resolver = def.id.resolver(db); 637 let resolver = def.resolver(db);
627 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 638 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
628 let ret = Ty::from_hir(db, &resolver, &data.ret_type); 639 let ret = Ty::from_hir(db, &resolver, &data.ret_type);
629 FnSig::from_params_and_return(params, ret) 640 FnSig::from_params_and_return(params, ret)
@@ -634,7 +645,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
634fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 645fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
635 let generics = db.generic_params(def.id.into()); 646 let generics = db.generic_params(def.id.into());
636 let substs = Substs::identity(&generics); 647 let substs = Substs::identity(&generics);
637 Ty::apply(TypeCtor::FnDef(def.into()), substs) 648 Ty::apply(TypeCtor::FnDef(def.id.into()), substs)
638} 649}
639 650
640/// Build the declared type of a const. 651/// Build the declared type of a const.
@@ -694,58 +705,53 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
694 } 705 }
695} 706}
696 707
697fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { 708fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig {
698 let struct_data = db.struct_data(def.id.into()); 709 let struct_data = db.struct_data(def.into());
699 let fields = match struct_data.variant_data.fields() { 710 let fields = struct_data.variant_data.fields();
700 Some(fields) => fields, 711 let resolver = def.resolver(db);
701 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
702 };
703 let resolver = def.id.resolver(db);
704 let params = fields 712 let params = fields
705 .iter() 713 .iter()
706 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 714 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
707 .collect::<Vec<_>>(); 715 .collect::<Vec<_>>();
708 let ret = type_for_adt(db, def); 716 let ret = type_for_adt(db, Struct::from(def));
709 FnSig::from_params_and_return(params, ret) 717 FnSig::from_params_and_return(params, ret)
710} 718}
711 719
712/// Build the type of a tuple struct constructor. 720/// Build the type of a tuple struct constructor.
713fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 721fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
714 let struct_data = db.struct_data(def.id.into()); 722 let struct_data = db.struct_data(def.id.into());
715 if struct_data.variant_data.fields().is_none() { 723 if struct_data.variant_data.is_unit() {
716 return type_for_adt(db, def); // Unit struct 724 return type_for_adt(db, def); // Unit struct
717 } 725 }
718 let generics = db.generic_params(def.id.into()); 726 let generics = db.generic_params(def.id.into());
719 let substs = Substs::identity(&generics); 727 let substs = Substs::identity(&generics);
720 Ty::apply(TypeCtor::FnDef(def.into()), substs) 728 Ty::apply(TypeCtor::FnDef(def.id.into()), substs)
721} 729}
722 730
723fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { 731fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> FnSig {
724 let var_data = def.variant_data(db); 732 let enum_data = db.enum_data(def.parent);
725 let fields = match var_data.fields() { 733 let var_data = &enum_data.variants[def.local_id];
726 Some(fields) => fields, 734 let fields = var_data.variant_data.fields();
727 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), 735 let resolver = def.parent.resolver(db);
728 };
729 let resolver = def.parent.id.resolver(db);
730 let params = fields 736 let params = fields
731 .iter() 737 .iter()
732 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 738 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
733 .collect::<Vec<_>>(); 739 .collect::<Vec<_>>();
734 let generics = db.generic_params(def.parent_enum(db).id.into()); 740 let generics = db.generic_params(def.parent.into());
735 let substs = Substs::identity(&generics); 741 let substs = Substs::identity(&generics);
736 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); 742 let ret = type_for_adt(db, Enum::from(def.parent)).subst(&substs);
737 FnSig::from_params_and_return(params, ret) 743 FnSig::from_params_and_return(params, ret)
738} 744}
739 745
740/// Build the type of a tuple enum variant constructor. 746/// Build the type of a tuple enum variant constructor.
741fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 747fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
742 let var_data = def.variant_data(db); 748 let var_data = def.variant_data(db);
743 if var_data.fields().is_none() { 749 if var_data.is_unit() {
744 return type_for_adt(db, def.parent_enum(db)); // Unit variant 750 return type_for_adt(db, def.parent_enum(db)); // Unit variant
745 } 751 }
746 let generics = db.generic_params(def.parent_enum(db).id.into()); 752 let generics = db.generic_params(def.parent_enum(db).id.into());
747 let substs = Substs::identity(&generics); 753 let substs = Substs::identity(&generics);
748 Ty::apply(TypeCtor::FnDef(def.into()), substs) 754 Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs)
749} 755}
750 756
751fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { 757fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty {
@@ -802,28 +808,28 @@ impl From<ModuleDef> for Option<TypableDef> {
802 808
803#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 809#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
804pub enum CallableDef { 810pub enum CallableDef {
805 Function(Function), 811 FunctionId(FunctionId),
806 Struct(Struct), 812 StructId(StructId),
807 EnumVariant(EnumVariant), 813 EnumVariantId(EnumVariantId),
808} 814}
809impl_froms!(CallableDef: Function, Struct, EnumVariant); 815impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId);
810 816
811impl CallableDef { 817impl CallableDef {
812 pub fn krate(self, db: &impl HirDatabase) -> Option<crate::Crate> { 818 pub fn krate(self, db: &impl HirDatabase) -> CrateId {
813 match self { 819 match self {
814 CallableDef::Function(f) => f.krate(db), 820 CallableDef::FunctionId(f) => f.lookup(db).module(db).krate,
815 CallableDef::Struct(s) => s.krate(db), 821 CallableDef::StructId(s) => s.0.module(db).krate,
816 CallableDef::EnumVariant(e) => e.parent_enum(db).krate(db), 822 CallableDef::EnumVariantId(e) => e.parent.module(db).krate,
817 } 823 }
818 } 824 }
819} 825}
820 826
821impl From<CallableDef> for GenericDef { 827impl From<CallableDef> for GenericDefId {
822 fn from(def: CallableDef) -> GenericDef { 828 fn from(def: CallableDef) -> GenericDefId {
823 match def { 829 match def {
824 CallableDef::Function(f) => f.into(), 830 CallableDef::FunctionId(f) => f.into(),
825 CallableDef::Struct(s) => s.into(), 831 CallableDef::StructId(s) => s.into(),
826 CallableDef::EnumVariant(e) => e.into(), 832 CallableDef::EnumVariantId(e) => e.into(),
827 } 833 }
828 } 834 }
829} 835}
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index caa5f5f74..c5ab690eb 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -15,7 +15,7 @@ use crate::{
15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, 15 AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait,
16}; 16};
17 17
18use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 18use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
19 19
20/// This is used as a key for indexing impls. 20/// This is used as a key for indexing impls.
21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 21#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -179,8 +179,9 @@ pub(crate) fn iterate_method_candidates<T>(
179 // Also note that when we've got a receiver like &S, even if the method we 179 // Also note that when we've got a receiver like &S, even if the method we
180 // find in the end takes &self, we still do the autoderef step (just as 180 // find in the end takes &self, we still do the autoderef step (just as
181 // rustc does an autoderef and then autoref again). 181 // rustc does an autoderef and then autoref again).
182 182 let environment = TraitEnvironment::lower(db, resolver);
183 for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { 183 let ty = InEnvironment { value: ty.clone(), environment };
184 for derefed_ty in autoderef::autoderef(db, resolver.krate(), ty) {
184 if let Some(result) = iterate_inherent_methods( 185 if let Some(result) = iterate_inherent_methods(
185 &derefed_ty, 186 &derefed_ty,
186 db, 187 db,
@@ -230,7 +231,7 @@ fn iterate_trait_method_candidates<T>(
230) -> Option<T> { 231) -> Option<T> {
231 let krate = resolver.krate()?; 232 let krate = resolver.krate()?;
232 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) 233 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
233 let env = lower::trait_env(db, resolver); 234 let env = TraitEnvironment::lower(db, resolver);
234 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope 235 // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope
235 let inherent_trait = ty.value.inherent_trait().into_iter(); 236 let inherent_trait = ty.value.inherent_trait().into_iter();
236 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 237 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
@@ -324,7 +325,7 @@ pub(crate) fn implements_trait(
324 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet 325 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
325 return true; 326 return true;
326 } 327 }
327 let env = lower::trait_env(db, resolver); 328 let env = TraitEnvironment::lower(db, resolver);
328 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 329 let goal = generic_implements_goal(db, env, trait_, ty.clone());
329 let solution = db.trait_solve(krate, goal); 330 let solution = db.trait_solve(krate, goal);
330 331
@@ -364,7 +365,7 @@ fn generic_implements_goal(
364 self_ty: Canonical<Ty>, 365 self_ty: Canonical<Ty>,
365) -> Canonical<InEnvironment<super::Obligation>> { 366) -> Canonical<InEnvironment<super::Obligation>> {
366 let num_vars = self_ty.num_vars; 367 let num_vars = self_ty.num_vars;
367 let substs = super::Substs::build_for_def(db, trait_) 368 let substs = super::Substs::build_for_def(db, trait_.id)
368 .push(self_ty.value) 369 .push(self_ty.value)
369 .fill_with_bound_vars(num_vars as u32) 370 .fill_with_bound_vars(num_vars as u32)
370 .build(); 371 .build();
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 9efdc53c4..0272dd9ae 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -9,7 +9,7 @@ use chalk_ir::{
9}; 9};
10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; 10use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
11 11
12use hir_def::lang_item::LangItemTarget; 12use hir_def::{lang_item::LangItemTarget, GenericDefId};
13use hir_expand::name; 13use hir_expand::name;
14 14
15use ra_db::salsa::{InternId, InternKey}; 15use ra_db::salsa::{InternId, InternKey};
@@ -19,7 +19,7 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 ty::display::HirDisplay, 20 ty::display::HirDisplay,
21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, 21 ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
22 Crate, GenericDef, HasBody, ImplBlock, Trait, TypeAlias, 22 Crate, ImplBlock, Trait, TypeAlias,
23}; 23};
24 24
25/// This represents a trait whose name we could not resolve. 25/// This represents a trait whose name we could not resolve.
@@ -402,7 +402,7 @@ fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
402 402
403fn convert_where_clauses( 403fn convert_where_clauses(
404 db: &impl HirDatabase, 404 db: &impl HirDatabase,
405 def: GenericDef, 405 def: GenericDefId,
406 substs: &Substs, 406 substs: &Substs,
407) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { 407) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> {
408 let generic_predicates = db.generic_predicates(def); 408 let generic_predicates = db.generic_predicates(def);
@@ -561,7 +561,7 @@ pub(crate) fn trait_datum_query(
561 marker: false, 561 marker: false,
562 fundamental: false, 562 fundamental: false,
563 }; 563 };
564 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); 564 let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars);
565 let associated_ty_ids = trait_ 565 let associated_ty_ids = trait_
566 .items(db) 566 .items(db)
567 .into_iter() 567 .into_iter()
@@ -643,7 +643,7 @@ fn impl_block_datum(
643 } else { 643 } else {
644 chalk_rust_ir::ImplType::External 644 chalk_rust_ir::ImplType::External
645 }; 645 };
646 let where_clauses = convert_where_clauses(db, impl_block.into(), &bound_vars); 646 let where_clauses = convert_where_clauses(db, impl_block.id.into(), &bound_vars);
647 let negative = impl_block.is_negative(db); 647 let negative = impl_block.is_negative(db);
648 debug!( 648 debug!(
649 "impl {:?}: {}{} where {:?}", 649 "impl {:?}: {}{} where {:?}",
@@ -715,7 +715,7 @@ fn closure_fn_trait_impl_datum(
715 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; 715 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
716 fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; 716 fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?;
717 717
718 let num_args: u16 = match &data.def.body(db)[data.expr] { 718 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
719 crate::expr::Expr::Lambda { args, .. } => args.len() as u16, 719 crate::expr::Expr::Lambda { args, .. } => args.len() as u16,
720 _ => { 720 _ => {
721 log::warn!("closure for closure type {:?} not found", data); 721 log::warn!("closure for closure type {:?} not found", data);
@@ -736,7 +736,7 @@ fn closure_fn_trait_impl_datum(
736 736
737 let trait_ref = TraitRef { 737 let trait_ref = TraitRef {
738 trait_, 738 trait_,
739 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), 739 substs: Substs::build_for_def(db, trait_.id).push(self_ty).push(arg_ty).build(),
740 }; 740 };
741 741
742 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db); 742 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()).to_chalk(db);
@@ -805,7 +805,7 @@ fn closure_fn_trait_output_assoc_ty_value(
805) -> Arc<AssociatedTyValue<ChalkIr>> { 805) -> Arc<AssociatedTyValue<ChalkIr>> {
806 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); 806 let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db);
807 807
808 let num_args: u16 = match &data.def.body(db)[data.expr] { 808 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
809 crate::expr::Expr::Lambda { args, .. } => args.len() as u16, 809 crate::expr::Expr::Lambda { args, .. } => args.len() as u16,
810 _ => { 810 _ => {
811 log::warn!("closure for closure type {:?} not found", data); 811 log::warn!("closure for closure type {:?} not found", data);
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index a43f553aa..c9f30923e 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -109,10 +109,18 @@ impl VariantData {
109 } 109 }
110 } 110 }
111 111
112 pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> { 112 pub fn fields(&self) -> &Arena<LocalStructFieldId, StructFieldData> {
113 const EMPTY: &Arena<LocalStructFieldId, StructFieldData> = &Arena::new();
113 match &self { 114 match &self {
114 VariantData::Record(fields) | VariantData::Tuple(fields) => Some(fields), 115 VariantData::Record(fields) | VariantData::Tuple(fields) => fields,
115 _ => None, 116 _ => EMPTY,
117 }
118 }
119
120 pub fn is_unit(&self) -> bool {
121 match self {
122 VariantData::Unit => true,
123 _ => false,
116 } 124 }
117 } 125 }
118} 126}
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 45a36d793..d77ccb272 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -1,4 +1,5 @@
1//! FIXME: write short doc here 1//! Defines `Body`: a lowered representation of bodies of functions, statics and
2//! consts.
2mod lower; 3mod lower;
3pub mod scope; 4pub mod scope;
4 5
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index f4640dfa4..331736cb2 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -1,4 +1,5 @@
1//! FIXME: write short doc here 1//! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr`
2//! representation.
2 3
3use hir_expand::{ 4use hir_expand::{
4 either::Either, 5 either::Either,
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 5240a59d5..625aa39dd 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -1,4 +1,4 @@
1//! FIXME: write short doc here 1//! Name resolution for expressions.
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use hir_expand::name::Name; 4use hir_expand::name::Name;
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f63c3dd64..8e8c2d749 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -192,12 +192,6 @@ pub struct LocalEnumVariantId(RawId);
192impl_arena_id!(LocalEnumVariantId); 192impl_arena_id!(LocalEnumVariantId);
193 193
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
195pub enum VariantId {
196 EnumVariantId(EnumVariantId),
197 StructId(StructId),
198}
199
200#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
201pub struct StructFieldId { 195pub struct StructFieldId {
202 pub parent: VariantId, 196 pub parent: VariantId,
203 pub local_id: LocalStructFieldId, 197 pub local_id: LocalStructFieldId,
@@ -437,6 +431,13 @@ impl_froms!(
437 ImplId 431 ImplId
438); 432);
439 433
434#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
435pub enum VariantId {
436 EnumVariantId(EnumVariantId),
437 StructId(StructId),
438}
439impl_froms!(VariantId: EnumVariantId, StructId);
440
440trait Intern { 441trait Intern {
441 type ID; 442 type ID;
442 fn intern(self, db: &impl db::DefDatabase) -> Self::ID; 443 fn intern(self, db: &impl db::DefDatabase) -> Self::ID;
@@ -481,6 +482,16 @@ impl HasModule for ConstLoc {
481 } 482 }
482} 483}
483 484
485impl HasModule for AdtId {
486 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
487 match self {
488 AdtId::StructId(it) => it.0.module(db),
489 AdtId::UnionId(it) => it.0.module(db),
490 AdtId::EnumId(it) => it.module(db),
491 }
492 }
493}
494
484impl HasModule for StaticLoc { 495impl HasModule for StaticLoc {
485 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 496 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId {
486 self.container 497 self.container
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 7b2723d57..0e606fd0e 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -195,7 +195,7 @@ impl Path {
195 } 195 }
196 196
197 /// Converts an `ast::NameRef` into a single-identifier `Path`. 197 /// Converts an `ast::NameRef` into a single-identifier `Path`.
198 pub fn from_name_ref(name_ref: &ast::NameRef) -> Path { 198 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path {
199 name_ref.as_name().into() 199 name_ref.as_name().into()
200 } 200 }
201 201
diff --git a/crates/ra_hir_def/src/per_ns.rs b/crates/ra_hir_def/src/per_ns.rs
index 06ef6c9fc..00e866bf9 100644
--- a/crates/ra_hir_def/src/per_ns.rs
+++ b/crates/ra_hir_def/src/per_ns.rs
@@ -1,4 +1,7 @@
1//! FIXME: write short doc here 1//! In rust, it is possible to have a value, a type and a macro with the same
2//! name without conflicts.
3//!
4//! `PerNs` (per namespace) captures this.
2 5
3use hir_expand::MacroDefId; 6use hir_expand::MacroDefId;
4 7
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index c24a9b165..95b3c926d 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -18,8 +18,8 @@ use crate::{
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
21 GenericDefId, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, 21 GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId,
22 TraitId, TypeAliasId, 22 StructId, TraitId, TypeAliasId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -29,20 +29,20 @@ pub struct Resolver {
29 29
30// FIXME how to store these best 30// FIXME how to store these best
31#[derive(Debug, Clone)] 31#[derive(Debug, Clone)]
32pub(crate) struct ModuleItemMap { 32struct ModuleItemMap {
33 crate_def_map: Arc<CrateDefMap>, 33 crate_def_map: Arc<CrateDefMap>,
34 module_id: LocalModuleId, 34 module_id: LocalModuleId,
35} 35}
36 36
37#[derive(Debug, Clone)] 37#[derive(Debug, Clone)]
38pub(crate) struct ExprScope { 38struct ExprScope {
39 owner: DefWithBodyId, 39 owner: DefWithBodyId,
40 expr_scopes: Arc<ExprScopes>, 40 expr_scopes: Arc<ExprScopes>,
41 scope_id: ScopeId, 41 scope_id: ScopeId,
42} 42}
43 43
44#[derive(Debug, Clone)] 44#[derive(Debug, Clone)]
45pub(crate) enum Scope { 45enum Scope {
46 /// All the items and imported names of a module 46 /// All the items and imported names of a module
47 ModuleScope(ModuleItemMap), 47 ModuleScope(ModuleItemMap),
48 /// Brings the generic parameters of an item into scope 48 /// Brings the generic parameters of an item into scope
@@ -503,13 +503,7 @@ impl HasResolver for TraitId {
503impl<T: Into<AdtId>> HasResolver for T { 503impl<T: Into<AdtId>> HasResolver for T {
504 fn resolver(self, db: &impl DefDatabase) -> Resolver { 504 fn resolver(self, db: &impl DefDatabase) -> Resolver {
505 let def = self.into(); 505 let def = self.into();
506 let module = match def { 506 def.module(db)
507 AdtId::StructId(it) => it.0.module(db),
508 AdtId::UnionId(it) => it.0.module(db),
509 AdtId::EnumId(it) => it.module(db),
510 };
511
512 module
513 .resolver(db) 507 .resolver(db)
514 .push_generic_params_scope(db, def.into()) 508 .push_generic_params_scope(db, def.into())
515 .push_scope(Scope::AdtScope(def)) 509 .push_scope(Scope::AdtScope(def))
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index c0e0436c0..d370dfb34 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -46,6 +46,7 @@ macro_rules! register_builtin {
46 46
47register_builtin! { 47register_builtin! {
48 (COLUMN_MACRO, Column) => column_expand, 48 (COLUMN_MACRO, Column) => column_expand,
49 (COMPILE_ERROR_MACRO, CompileError) => compile_error_expand,
49 (FILE_MACRO, File) => file_expand, 50 (FILE_MACRO, File) => file_expand,
50 (LINE_MACRO, Line) => line_expand, 51 (LINE_MACRO, Line) => line_expand,
51 (STRINGIFY_MACRO, Stringify) => stringify_expand 52 (STRINGIFY_MACRO, Stringify) => stringify_expand
@@ -57,16 +58,21 @@ fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize
57 let text = db.file_text(file_id); 58 let text = db.file_text(file_id);
58 let mut line_num = 1; 59 let mut line_num = 1;
59 60
61 let pos = pos.to_usize();
62 if pos > text.len() {
63 // FIXME: `pos` at the moment could be an offset inside the "wrong" file
64 // in this case, when we know it's wrong, we return a dummy value
65 return 0;
66 }
60 // Count line end 67 // Count line end
61 for (i, c) in text.chars().enumerate() { 68 for (i, c) in text.chars().enumerate() {
62 if i == pos.to_usize() { 69 if i == pos {
63 break; 70 break;
64 } 71 }
65 if c == '\n' { 72 if c == '\n' {
66 line_num += 1; 73 line_num += 1;
67 } 74 }
68 } 75 }
69
70 line_num 76 line_num
71} 77}
72 78
@@ -118,15 +124,21 @@ fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize
118 // FIXME: Use expansion info 124 // FIXME: Use expansion info
119 let file_id = file.original_file(db); 125 let file_id = file.original_file(db);
120 let text = db.file_text(file_id); 126 let text = db.file_text(file_id);
121 let mut col_num = 1;
122 127
123 for c in text[..pos.to_usize()].chars().rev() { 128 let pos = pos.to_usize();
129 if pos > text.len() {
130 // FIXME: `pos` at the moment could be an offset inside the "wrong" file
131 // in this case we return a dummy value so that we don't `panic!`
132 return 0;
133 }
134
135 let mut col_num = 1;
136 for c in text[..pos].chars().rev() {
124 if c == '\n' { 137 if c == '\n' {
125 break; 138 break;
126 } 139 }
127 col_num = col_num + 1; 140 col_num = col_num + 1;
128 } 141 }
129
130 col_num 142 col_num
131} 143}
132 144
@@ -172,6 +184,26 @@ fn file_expand(
172 Ok(expanded) 184 Ok(expanded)
173} 185}
174 186
187fn compile_error_expand(
188 _db: &dyn AstDatabase,
189 _id: MacroCallId,
190 tt: &tt::Subtree,
191) -> Result<tt::Subtree, mbe::ExpandError> {
192 if tt.count() == 1 {
193 match &tt.token_trees[0] {
194 tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => {
195 let s = it.text.as_str();
196 if s.contains(r#"""#) {
197 return Ok(quote! { loop { #it }});
198 }
199 }
200 _ => {}
201 };
202 }
203
204 Err(mbe::ExpandError::BindingError("Must be a string".into()))
205}
206
175#[cfg(test)] 207#[cfg(test)]
176mod tests { 208mod tests {
177 use super::*; 209 use super::*;
@@ -259,4 +291,21 @@ mod tests {
259 291
260 assert_eq!(expanded, "\"\""); 292 assert_eq!(expanded, "\"\"");
261 } 293 }
294
295 #[test]
296 fn test_compile_error_expand() {
297 let expanded = expand_builtin_macro(
298 r#"
299 #[rustc_builtin_macro]
300 macro_rules! compile_error {
301 ($msg:expr) => ({ /* compiler built-in */ });
302 ($msg:expr,) => ({ /* compiler built-in */ })
303 }
304 compile_error!("error!");
305"#,
306 BuiltinFnLikeExpander::CompileError,
307 );
308
309 assert_eq!(expanded, r#"loop{"error!"}"#);
310 }
262} 311}
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs
index eaea7a6a8..7824489d7 100644
--- a/crates/ra_hir_expand/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs
@@ -144,5 +144,6 @@ pub const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box");
144// Builtin Macros 144// Builtin Macros
145pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file"); 145pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file");
146pub const COLUMN_MACRO: Name = Name::new_inline_ascii(6, b"column"); 146pub const COLUMN_MACRO: Name = Name::new_inline_ascii(6, b"column");
147pub const COMPILE_ERROR_MACRO: Name = Name::new_inline_ascii(13, b"compile_error");
147pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line"); 148pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line");
148pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify"); 149pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify");
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs
index 7c367230e..9beceb29c 100644
--- a/crates/ra_ide_api/src/call_info.rs
+++ b/crates/ra_ide_api/src/call_info.rs
@@ -26,14 +26,17 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
26 ); 26 );
27 let (mut call_info, has_self) = match &calling_node { 27 let (mut call_info, has_self) = match &calling_node {
28 FnCallNode::CallExpr(expr) => { 28 FnCallNode::CallExpr(expr) => {
29 //FIXME: apply subst 29 //FIXME: don't poke into Ty
30 let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; 30 let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?;
31 match callable_def { 31 match callable_def {
32 hir::CallableDef::Function(it) => { 32 hir::CallableDef::FunctionId(it) => {
33 (CallInfo::with_fn(db, it), it.has_self_param(db)) 33 let fn_def = it.into();
34 (CallInfo::with_fn(db, fn_def), fn_def.has_self_param(db))
35 }
36 hir::CallableDef::StructId(it) => (CallInfo::with_struct(db, it.into())?, false),
37 hir::CallableDef::EnumVariantId(it) => {
38 (CallInfo::with_enum_variant(db, it.into())?, false)
34 } 39 }
35 hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false),
36 hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false),
37 } 40 }
38 } 41 }
39 FnCallNode::MethodCallExpr(expr) => { 42 FnCallNode::MethodCallExpr(expr) => {
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 8a05b287f..0f692460d 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -324,7 +324,7 @@ impl RootDatabase {
324 hir::db::ExprScopesQuery 324 hir::db::ExprScopesQuery
325 hir::db::InferQuery 325 hir::db::InferQuery
326 hir::db::TypeForDefQuery 326 hir::db::TypeForDefQuery
327 hir::db::TypeForFieldQuery 327 hir::db::FieldTypesQuery
328 hir::db::CallableItemSignatureQuery 328 hir::db::CallableItemSignatureQuery
329 hir::db::GenericPredicatesQuery 329 hir::db::GenericPredicatesQuery
330 hir::db::GenericDefaultsQuery 330 hir::db::GenericDefaultsQuery
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index bac3f7582..85b053a6e 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -292,7 +292,7 @@ fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool {
292} 292}
293 293
294fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { 294fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool {
295 let subst = db.generic_defaults(def); 295 let subst = db.generic_defaults(def.into());
296 subst.iter().any(|ty| ty == &Ty::Unknown) 296 subst.iter().any(|ty| ty == &Ty::Unknown)
297} 297}
298 298
diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs
index 4a4b030f8..cab06dea9 100644
--- a/crates/ra_ide_api/src/references/classify.rs
+++ b/crates/ra_ide_api/src/references/classify.rs
@@ -1,6 +1,6 @@
1//! Functions that are used to classify an element from its definition or reference. 1//! Functions that are used to classify an element from its definition or reference.
2 2
3use hir::{FromSource, Module, ModuleSource, Path, PathResolution, Source, SourceAnalyzer}; 3use hir::{FromSource, Module, ModuleSource, PathResolution, Source, SourceAnalyzer};
4use ra_prof::profile; 4use ra_prof::profile;
5use ra_syntax::{ast, match_ast, AstNode}; 5use ra_syntax::{ast, match_ast, AstNode};
6use test_utils::tested_by; 6use test_utils::tested_by;
@@ -140,12 +140,8 @@ pub(crate) fn classify_name_ref(
140 140
141 if let Some(record_field) = ast::RecordField::cast(parent.clone()) { 141 if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
142 tested_by!(goto_definition_works_for_record_fields); 142 tested_by!(goto_definition_works_for_record_fields);
143 if let Some(record_lit) = record_field.syntax().ancestors().find_map(ast::RecordLit::cast) { 143 if let Some(field_def) = analyzer.resolve_record_field(&record_field) {
144 let variant_def = analyzer.resolve_record_literal(&record_lit)?; 144 return Some(from_struct_field(db, field_def));
145 let hir_path = Path::from_name_ref(name_ref.value);
146 let hir_name = hir_path.as_ident()?;
147 let field = variant_def.field(db, hir_name)?;
148 return Some(from_struct_field(db, field));
149 } 145 }
150 } 146 }
151 147