aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs52
-rw-r--r--crates/ra_hir/src/ty/infer.rs32
-rw-r--r--crates/ra_hir/src/ty/infer/coerce.rs33
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs81
-rw-r--r--crates/ra_hir/src/ty/infer/pat.rs9
-rw-r--r--crates/ra_hir/src/ty/infer/path.rs5
-rw-r--r--crates/ra_hir/src/ty/lower.rs150
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs68
-rw-r--r--crates/ra_hir/src/ty/tests.rs40
-rw-r--r--crates/ra_hir/src/ty/traits.rs11
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs48
11 files changed, 315 insertions, 214 deletions
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 5d8518041..44547197c 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -5,48 +5,56 @@
5 5
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::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 super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 13use crate::{db::HirDatabase, Trait};
13use crate::{db::HirDatabase, generics::HasGenericParams}; 14
15use super::{
16 traits::{InEnvironment, Solution},
17 Canonical, Substs, Ty, TypeWalk,
18};
14 19
15const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
16 21
17pub(crate) fn autoderef<'a>( 22pub(crate) fn autoderef<'a>(
18 db: &'a impl HirDatabase, 23 db: &'a impl HirDatabase,
19 resolver: &'a Resolver, 24 krate: Option<CrateId>,
20 ty: Canonical<Ty>, 25 ty: InEnvironment<Canonical<Ty>>,
21) -> impl Iterator<Item = Canonical<Ty>> + 'a { 26) -> impl Iterator<Item = Canonical<Ty>> + 'a {
22 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)
23} 32}
24 33
25pub(crate) fn deref( 34pub(crate) fn deref(
26 db: &impl HirDatabase, 35 db: &impl HirDatabase,
27 resolver: &Resolver, 36 krate: CrateId,
28 ty: &Canonical<Ty>, 37 ty: InEnvironment<&Canonical<Ty>>,
29) -> Option<Canonical<Ty>> { 38) -> Option<Canonical<Ty>> {
30 if let Some(derefed) = ty.value.builtin_deref() { 39 if let Some(derefed) = ty.value.value.builtin_deref() {
31 Some(Canonical { value: derefed, num_vars: ty.num_vars }) 40 Some(Canonical { value: derefed, num_vars: ty.value.num_vars })
32 } else { 41 } else {
33 deref_by_trait(db, resolver, ty) 42 deref_by_trait(db, krate, ty)
34 } 43 }
35} 44}
36 45
37fn deref_by_trait( 46fn deref_by_trait(
38 db: &impl HirDatabase, 47 db: &impl HirDatabase,
39 resolver: &Resolver, 48 krate: CrateId,
40 ty: &Canonical<Ty>, 49 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 50) -> Option<Canonical<Ty>> {
42 let krate = resolver.krate()?;
43 let deref_trait = match db.lang_item(krate.into(), "deref".into())? { 51 let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
44 crate::lang_item::LangItemTarget::Trait(t) => t, 52 LangItemTarget::TraitId(t) => Trait::from(t),
45 _ => return None, 53 _ => return None,
46 }; 54 };
47 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; 55 let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;
48 56
49 let generic_params = target.generic_params(db); 57 let generic_params = db.generic_params(target.id.into());
50 if generic_params.count_params_including_parent() != 1 { 58 if generic_params.count_params_including_parent() != 1 {
51 // the Target type + Deref trait should only have one generic parameter, 59 // the Target type + Deref trait should only have one generic parameter,
52 // namely Deref's Self type 60 // namely Deref's Self type
@@ -55,10 +63,8 @@ fn deref_by_trait(
55 63
56 // FIXME make the Canonical handling nicer 64 // FIXME make the Canonical handling nicer
57 65
58 let env = super::lower::trait_env(db, resolver);
59
60 let parameters = Substs::build_for_generics(&generic_params) 66 let parameters = Substs::build_for_generics(&generic_params)
61 .push(ty.value.clone().shift_bound_vars(1)) 67 .push(ty.value.value.clone().shift_bound_vars(1))
62 .build(); 68 .build();
63 69
64 let projection = super::traits::ProjectionPredicate { 70 let projection = super::traits::ProjectionPredicate {
@@ -68,9 +74,9 @@ fn deref_by_trait(
68 74
69 let obligation = super::Obligation::Projection(projection); 75 let obligation = super::Obligation::Projection(projection);
70 76
71 let in_env = super::traits::InEnvironment { value: obligation, environment: env }; 77 let in_env = InEnvironment { value: obligation, environment: ty.environment };
72 78
73 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 };
74 80
75 let solution = db.trait_solve(krate.into(), canonical)?; 81 let solution = db.trait_solve(krate.into(), canonical)?;
76 82
@@ -88,14 +94,14 @@ fn deref_by_trait(
88 // the case. 94 // the case.
89 for i in 1..vars.0.num_vars { 95 for i in 1..vars.0.num_vars {
90 if vars.0.value[i] != Ty::Bound((i - 1) as u32) { 96 if vars.0.value[i] != Ty::Bound((i - 1) as u32) {
91 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); 97 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
92 return None; 98 return None;
93 } 99 }
94 } 100 }
95 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 })
96 } 102 }
97 Solution::Ambig(_) => { 103 Solution::Ambig(_) => {
98 info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); 104 info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
99 None 105 None
100 } 106 }
101 } 107 }
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 69b13baef..6fd00d457 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -22,6 +22,7 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
22use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use hir_def::{
25 data::{ConstData, FunctionData},
25 path::known, 26 path::known,
26 resolver::{HasResolver, Resolver, TypeNs}, 27 resolver::{HasResolver, Resolver, TypeNs},
27 type_ref::{Mutability, TypeRef}, 28 type_ref::{Mutability, TypeRef},
@@ -33,7 +34,6 @@ use ra_prof::profile;
33use test_utils::tested_by; 34use test_utils::tested_by;
34 35
35use super::{ 36use super::{
36 lower,
37 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 37 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef, 38 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypableDef,
39 TypeCtor, TypeWalk, Uncertain, 39 TypeCtor, TypeWalk, Uncertain,
@@ -43,8 +43,7 @@ use crate::{
43 db::HirDatabase, 43 db::HirDatabase,
44 expr::{BindingAnnotation, Body, ExprId, PatId}, 44 expr::{BindingAnnotation, Body, ExprId, PatId},
45 ty::infer::diagnostics::InferenceDiagnostic, 45 ty::infer::diagnostics::InferenceDiagnostic,
46 Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, 46 Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef,
47 StructField, Trait, VariantDef,
48}; 47};
49 48
50macro_rules! ty_app { 49macro_rules! ty_app {
@@ -68,10 +67,10 @@ pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResu
68 let resolver = DefWithBodyId::from(def).resolver(db); 67 let resolver = DefWithBodyId::from(def).resolver(db);
69 let mut ctx = InferenceContext::new(db, def, resolver); 68 let mut ctx = InferenceContext::new(db, def, resolver);
70 69
71 match def { 70 match &def {
72 DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)), 71 DefWithBody::Const(c) => ctx.collect_const(&db.const_data(c.id)),
73 DefWithBody::Function(ref f) => ctx.collect_fn(&f.data(db)), 72 DefWithBody::Function(f) => ctx.collect_fn(&db.function_data(f.id)),
74 DefWithBody::Static(ref s) => ctx.collect_const(&s.data(db)), 73 DefWithBody::Static(s) => ctx.collect_const(&db.static_data(s.id)),
75 } 74 }
76 75
77 ctx.infer_body(); 76 ctx.infer_body();
@@ -125,6 +124,8 @@ pub struct InferenceResult {
125 method_resolutions: FxHashMap<ExprId, Function>, 124 method_resolutions: FxHashMap<ExprId, Function>,
126 /// For each field access expr, records the field it resolves to. 125 /// For each field access expr, records the field it resolves to.
127 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>,
128 /// For each struct literal, records the variant it resolves to. 129 /// For each struct literal, records the variant it resolves to.
129 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, 130 variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>,
130 /// For each associated item record what it resolves to 131 /// For each associated item record what it resolves to
@@ -142,6 +143,9 @@ impl InferenceResult {
142 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { 143 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
143 self.field_resolutions.get(&expr).copied() 144 self.field_resolutions.get(&expr).copied()
144 } 145 }
146 pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> {
147 self.record_field_resolutions.get(&expr).copied()
148 }
145 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { 149 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> {
146 self.variant_resolutions.get(&id.into()).copied() 150 self.variant_resolutions.get(&id.into()).copied()
147 } 151 }
@@ -211,11 +215,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
211 var_unification_table: InPlaceUnificationTable::new(), 215 var_unification_table: InPlaceUnificationTable::new(),
212 obligations: Vec::default(), 216 obligations: Vec::default(),
213 return_ty: Ty::Unknown, // set in collect_fn_signature 217 return_ty: Ty::Unknown, // set in collect_fn_signature
214 trait_env: lower::trait_env(db, &resolver), 218 trait_env: TraitEnvironment::lower(db, &resolver),
215 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), 219 coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver),
216 db, 220 db,
217 owner, 221 owner,
218 body: owner.body(db), 222 body: db.body(owner.into()),
219 resolver, 223 resolver,
220 } 224 }
221 } 225 }
@@ -559,21 +563,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
559 } 563 }
560 564
561 fn collect_const(&mut self, data: &ConstData) { 565 fn collect_const(&mut self, data: &ConstData) {
562 self.return_ty = self.make_ty(data.type_ref()); 566 self.return_ty = self.make_ty(&data.type_ref);
563 } 567 }
564 568
565 fn collect_fn(&mut self, data: &FnData) { 569 fn collect_fn(&mut self, data: &FunctionData) {
566 let body = Arc::clone(&self.body); // avoid borrow checker problem 570 let body = Arc::clone(&self.body); // avoid borrow checker problem
567 for (type_ref, pat) in data.params().iter().zip(body.params()) { 571 for (type_ref, pat) in data.params.iter().zip(body.params.iter()) {
568 let ty = self.make_ty(type_ref); 572 let ty = self.make_ty(type_ref);
569 573
570 self.infer_pat(*pat, &ty, BindingMode::default()); 574 self.infer_pat(*pat, &ty, BindingMode::default());
571 } 575 }
572 self.return_ty = self.make_ty(data.ret_type()); 576 self.return_ty = self.make_ty(&data.ret_type);
573 } 577 }
574 578
575 fn infer_body(&mut self) { 579 fn infer_body(&mut self) {
576 self.infer_expr(self.body.body_expr(), &Expectation::has_type(self.return_ty.clone())); 580 self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
577 } 581 }
578 582
579 fn resolve_into_iter_item(&self) -> Option<TypeAlias> { 583 fn resolve_into_iter_item(&self) -> Option<TypeAlias> {
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs
index 0772b9df5..4b53bba73 100644
--- a/crates/ra_hir/src/ty/infer/coerce.rs
+++ b/crates/ra_hir/src/ty/infer/coerce.rs
@@ -4,18 +4,17 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::resolver::Resolver; 7use hir_def::{lang_item::LangItemTarget, resolver::Resolver};
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9use test_utils::tested_by; 9use test_utils::tested_by;
10 10
11use crate::{ 11use crate::{
12 db::HirDatabase, 12 db::HirDatabase,
13 lang_item::LangItemTarget,
14 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, 13 ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk},
15 Adt, Mutability, 14 Adt, Mutability,
16}; 15};
17 16
18use super::{InferTy, InferenceContext, TypeVarValue}; 17use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue};
19 18
20impl<'a, D: HirDatabase> InferenceContext<'a, D> { 19impl<'a, D: HirDatabase> InferenceContext<'a, D> {
21 /// 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
@@ -50,7 +49,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
50 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { 49 ) -> FxHashMap<(TypeCtor, TypeCtor), usize> {
51 let krate = resolver.krate().unwrap(); 50 let krate = resolver.krate().unwrap();
52 let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { 51 let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) {
53 Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate.into(), trait_), 52 Some(LangItemTarget::TraitId(trait_)) => {
53 db.impls_for_trait(krate.into(), trait_.into())
54 }
54 _ => return FxHashMap::default(), 55 _ => return FxHashMap::default(),
55 }; 56 };
56 57
@@ -244,14 +245,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
244 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), 245 ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1),
245 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), 246 ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2),
246 ) if struct1 == struct2 => { 247 ) if struct1 == struct2 => {
247 let fields = struct1.fields(self.db); 248 let field_tys = self.db.field_types(struct1.id.into());
248 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()?;
249 253
250 // Get the generic parameter involved in the last field. 254 // Get the generic parameter involved in the last field.
251 let unsize_generic_index = { 255 let unsize_generic_index = {
252 let mut index = None; 256 let mut index = None;
253 let mut multiple_param = false; 257 let mut multiple_param = false;
254 last_field.ty(self.db).walk(&mut |ty| match ty { 258 field_tys[last_field_id].walk(&mut |ty| match ty {
255 &Ty::Param { idx, .. } => { 259 &Ty::Param { idx, .. } => {
256 if index.is_none() { 260 if index.is_none() {
257 index = Some(idx); 261 index = Some(idx);
@@ -270,8 +274,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
270 274
271 // Check other fields do not involve it. 275 // Check other fields do not involve it.
272 let mut multiple_used = false; 276 let mut multiple_used = false;
273 prev_fields.iter().for_each(|field| { 277 fields.for_each(|(field_id, _data)| {
274 field.ty(self.db).walk(&mut |ty| match ty { 278 field_tys[field_id].walk(&mut |ty| match ty {
275 &Ty::Param { idx, .. } if idx == unsize_generic_index => { 279 &Ty::Param { idx, .. } if idx == unsize_generic_index => {
276 multiple_used = true 280 multiple_used = true
277 } 281 }
@@ -316,9 +320,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
316 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); 320 let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone());
317 let to_ty = self.resolve_ty_shallow(&to_ty); 321 let to_ty = self.resolve_ty_shallow(&to_ty);
318 // FIXME: Auto DerefMut 322 // FIXME: Auto DerefMut
319 for derefed_ty in 323 for derefed_ty in autoderef::autoderef(
320 autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) 324 self.db,
321 { 325 self.resolver.krate(),
326 InEnvironment {
327 value: canonicalized.value.clone(),
328 environment: self.trait_env.clone(),
329 },
330 ) {
322 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 331 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
323 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 332 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) {
324 // 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 ac570075f..194e55819 100644
--- a/crates/ra_hir/src/ty/infer/expr.rs
+++ b/crates/ra_hir/src/ty/infer/expr.rs
@@ -5,6 +5,7 @@ use std::sync::Arc;
5 5
6use hir_def::{ 6use hir_def::{
7 builtin_type::Signedness, 7 builtin_type::Signedness,
8 generics::GenericParams,
8 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
9 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
10}; 11};
@@ -13,11 +14,10 @@ use hir_expand::name;
13use crate::{ 14use crate::{
14 db::HirDatabase, 15 db::HirDatabase,
15 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 16 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
16 generics::{GenericParams, HasGenericParams},
17 ty::{ 17 ty::{
18 autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, 18 autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy,
19 Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, 19 Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty,
20 Uncertain, 20 TypeCtor, TypeWalk, Uncertain,
21 }, 21 },
22 Adt, Name, 22 Adt, Name,
23}; 23};
@@ -214,19 +214,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
214 self.unify(&ty, &expected.ty); 214 self.unify(&ty, &expected.ty);
215 215
216 let substs = ty.substs().unwrap_or_else(Substs::empty); 216 let substs = ty.substs().unwrap_or_else(Substs::empty);
217 let field_types =
218 def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default();
217 for (field_idx, field) in fields.iter().enumerate() { 219 for (field_idx, field) in fields.iter().enumerate() {
218 let field_ty = def_id 220 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) { 221 Some(field) => Some(field),
220 Some(field) => Some(field), 222 None => {
221 None => { 223 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
222 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 224 expr: tgt_expr,
223 expr: tgt_expr, 225 field: field_idx,
224 field: field_idx, 226 });
225 }); 227 None
226 None 228 }
227 } 229 });
228 }) 230 if let Some(field_def) = field_def {
229 .map_or(Ty::Unknown, |field| field.ty(self.db)) 231 self.result.record_field_resolutions.insert(field.expr, field_def);
232 }
233 let field_ty = field_def
234 .map_or(Ty::Unknown, |it| field_types[it.id].clone())
230 .subst(&substs); 235 .subst(&substs);
231 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 236 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
232 } 237 }
@@ -240,8 +245,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
240 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); 245 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty);
241 let ty = autoderef::autoderef( 246 let ty = autoderef::autoderef(
242 self.db, 247 self.db,
243 &self.resolver.clone(), 248 self.resolver.krate(),
244 canonicalized.value.clone(), 249 InEnvironment {
250 value: canonicalized.value.clone(),
251 environment: self.trait_env.clone(),
252 },
245 ) 253 )
246 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 254 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
247 Ty::Apply(a_ty) => match a_ty.ctor { 255 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -250,7 +258,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
250 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 258 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()),
251 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { 259 TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| {
252 self.write_field_resolution(tgt_expr, field); 260 self.write_field_resolution(tgt_expr, field);
253 field.ty(self.db).subst(&a_ty.parameters) 261 self.db.field_types(s.id.into())[field.id]
262 .clone()
263 .subst(&a_ty.parameters)
254 }), 264 }),
255 _ => None, 265 _ => None,
256 }, 266 },
@@ -330,16 +340,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
330 Expr::UnaryOp { expr, op } => { 340 Expr::UnaryOp { expr, op } => {
331 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 341 let inner_ty = self.infer_expr(*expr, &Expectation::none());
332 match op { 342 match op {
333 UnaryOp::Deref => { 343 UnaryOp::Deref => match self.resolver.krate() {
334 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); 344 Some(krate) => {
335 if let Some(derefed_ty) = 345 let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty);
336 autoderef::deref(self.db, &self.resolver, &canonicalized.value) 346 match autoderef::deref(
337 { 347 self.db,
338 canonicalized.decanonicalize_ty(derefed_ty.value) 348 krate,
339 } else { 349 InEnvironment {
340 Ty::Unknown 350 value: &canonicalized.value,
351 environment: self.trait_env.clone(),
352 },
353 ) {
354 Some(derefed_ty) => {
355 canonicalized.decanonicalize_ty(derefed_ty.value)
356 }
357 None => Ty::Unknown,
358 }
341 } 359 }
342 } 360 None => Ty::Unknown,
361 },
343 UnaryOp::Neg => { 362 UnaryOp::Neg => {
344 match &inner_ty { 363 match &inner_ty {
345 Ty::Apply(a_ty) => match a_ty.ctor { 364 Ty::Apply(a_ty) => match a_ty.ctor {
@@ -534,7 +553,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
534 ( 553 (
535 ty, 554 ty,
536 self.db.type_for_def(func.into(), Namespace::Values), 555 self.db.type_for_def(func.into(), Namespace::Values),
537 Some(func.generic_params(self.db)), 556 Some(self.db.generic_params(func.id.into())),
538 ) 557 )
539 } 558 }
540 None => (receiver_ty, Ty::Unknown, None), 559 None => (receiver_ty, Ty::Unknown, None),
@@ -645,7 +664,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
645 if let Some(trait_) = f.parent_trait(self.db) { 664 if let Some(trait_) = f.parent_trait(self.db) {
646 // construct a TraitDef 665 // construct a TraitDef
647 let substs = a_ty.parameters.prefix( 666 let substs = a_ty.parameters.prefix(
648 trait_.generic_params(self.db).count_params_including_parent(), 667 self.db
668 .generic_params(trait_.id.into())
669 .count_params_including_parent(),
649 ); 670 );
650 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 671 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
651 } 672 }
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 70136e514..6165eba4f 100644
--- a/crates/ra_hir/src/ty/infer/path.rs
+++ b/crates/ra_hir/src/ty/infer/path.rs
@@ -7,7 +7,6 @@ use hir_def::{
7 7
8use crate::{ 8use crate::{
9 db::HirDatabase, 9 db::HirDatabase,
10 generics::HasGenericParams,
11 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, 10 ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk},
12 AssocItem, Container, Function, Name, Path, 11 AssocItem, Container, Function, Name, Path,
13}; 12};
@@ -204,7 +203,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
204 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()), 203 Container::ImplBlock(_) => self.find_self_types(&def, ty.clone()),
205 Container::Trait(t) => { 204 Container::Trait(t) => {
206 // we're picking this method 205 // we're picking this method
207 let trait_substs = Substs::build_for_def(self.db, t) 206 let trait_substs = Substs::build_for_def(self.db, t.id)
208 .push(ty.clone()) 207 .push(ty.clone())
209 .fill(std::iter::repeat_with(|| self.new_type_var())) 208 .fill(std::iter::repeat_with(|| self.new_type_var()))
210 .build(); 209 .build();
@@ -230,7 +229,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
230 if let ValueNs::FunctionId(func) = def { 229 if let ValueNs::FunctionId(func) = def {
231 let func = Function::from(*func); 230 let func = Function::from(*func);
232 // We only do the infer if parent has generic params 231 // We only do the infer if parent has generic params
233 let gen = func.generic_params(self.db); 232 let gen = self.db.generic_params(func.id.into());
234 if gen.count_parent_params() == 0 { 233 if gen.count_parent_params() == 0 {
235 return None; 234 return None;
236 } 235 }
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs
index c6ad0811b..1ceafd9b1 100644
--- a/crates/ra_hir/src/ty/lower.rs
+++ b/crates/ra_hir/src/ty/lower.rs
@@ -10,27 +10,27 @@ use std::sync::Arc;
10 10
11use hir_def::{ 11use hir_def::{
12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, 12 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
13 generics::WherePredicate,
13 path::{GenericArg, PathSegment}, 14 path::{GenericArg, PathSegment},
14 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
15 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
16 GenericDefId, 17 AdtId, EnumVariantId, GenericDefId, LocalStructFieldId, VariantId,
17}; 18};
19use ra_arena::map::ArenaMap;
18 20
19use super::{ 21use super::{
20 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 22 FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef,
21 TypeWalk, 23 Ty, TypeCtor, TypeWalk,
22}; 24};
23use crate::{ 25use crate::{
24 db::HirDatabase, 26 db::HirDatabase,
25 generics::HasGenericParams,
26 generics::{GenericDef, WherePredicate},
27 ty::{ 27 ty::{
28 primitive::{FloatTy, IntTy, Uncertain}, 28 primitive::{FloatTy, IntTy, Uncertain},
29 Adt, 29 Adt,
30 }, 30 },
31 util::make_mut_slice, 31 util::make_mut_slice,
32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField, 32 Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait,
33 Trait, TypeAlias, Union, VariantDef, 33 TypeAlias, Union,
34}; 34};
35 35
36// FIXME: this is only really used in `type_for_def`, which contains a bunch of 36// FIXME: this is only really used in `type_for_def`, which contains a bunch of
@@ -261,8 +261,10 @@ impl Ty {
261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); 261 let traits = traits_from_env.flat_map(|t| t.all_super_traits(db));
262 for t in traits { 262 for t in traits {
263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { 263 if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) {
264 let substs = 264 let substs = Substs::build_for_def(db, t.id)
265 Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); 265 .push(self_ty.clone())
266 .fill_with_unknown()
267 .build();
266 // FIXME handle type parameters on the segment 268 // FIXME handle type parameters on the segment
267 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); 269 return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
268 } 270 }
@@ -287,11 +289,11 @@ impl Ty {
287 segment: &PathSegment, 289 segment: &PathSegment,
288 resolved: TypableDef, 290 resolved: TypableDef,
289 ) -> Substs { 291 ) -> Substs {
290 let def_generic: Option<GenericDef> = match resolved { 292 let def_generic: Option<GenericDefId> = match resolved {
291 TypableDef::Function(func) => Some(func.into()), 293 TypableDef::Function(func) => Some(func.id.into()),
292 TypableDef::Adt(adt) => Some(adt.into()), 294 TypableDef::Adt(adt) => Some(adt.into()),
293 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).into()), 295 TypableDef::EnumVariant(var) => Some(var.parent_enum(db).id.into()),
294 TypableDef::TypeAlias(t) => Some(t.into()), 296 TypableDef::TypeAlias(t) => Some(t.id.into()),
295 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None, 297 TypableDef::Const(_) | TypableDef::Static(_) | TypableDef::BuiltinType(_) => None,
296 }; 298 };
297 substs_from_path_segment(db, resolver, segment, def_generic, false) 299 substs_from_path_segment(db, resolver, segment, def_generic, false)
@@ -338,11 +340,11 @@ pub(super) fn substs_from_path_segment(
338 db: &impl HirDatabase, 340 db: &impl HirDatabase,
339 resolver: &Resolver, 341 resolver: &Resolver,
340 segment: &PathSegment, 342 segment: &PathSegment,
341 def_generic: Option<GenericDef>, 343 def_generic: Option<GenericDefId>,
342 add_self_param: bool, 344 add_self_param: bool,
343) -> Substs { 345) -> Substs {
344 let mut substs = Vec::new(); 346 let mut substs = Vec::new();
345 let def_generics = def_generic.map(|def| def.generic_params(db)); 347 let def_generics = def_generic.map(|def| db.generic_params(def.into()));
346 348
347 let (parent_param_count, param_count) = 349 let (parent_param_count, param_count) =
348 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); 350 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len()));
@@ -376,7 +378,7 @@ pub(super) fn substs_from_path_segment(
376 378
377 // handle defaults 379 // handle defaults
378 if let Some(def_generic) = def_generic { 380 if let Some(def_generic) = def_generic {
379 let default_substs = db.generic_defaults(def_generic); 381 let default_substs = db.generic_defaults(def_generic.into());
380 assert_eq!(substs.len(), default_substs.len()); 382 assert_eq!(substs.len(), default_substs.len());
381 383
382 for (i, default_ty) in default_substs.iter().enumerate() { 384 for (i, default_ty) in default_substs.iter().enumerate() {
@@ -439,11 +441,11 @@ impl TraitRef {
439 ) -> Substs { 441 ) -> Substs {
440 let has_self_param = 442 let has_self_param =
441 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); 443 segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false);
442 substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) 444 substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
443 } 445 }
444 446
445 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { 447 pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
446 let substs = Substs::identity(&trait_.generic_params(db)); 448 let substs = Substs::identity(&db.generic_params(trait_.id.into()));
447 TraitRef { trait_, substs } 449 TraitRef { trait_, substs }
448 } 450 }
449 451
@@ -550,16 +552,23 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi
550 } 552 }
551} 553}
552 554
553/// Build the type of a specific field of a struct or enum variant. 555/// Build the type of all specific fields of a struct or enum variant.
554pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { 556pub(crate) fn field_types_query(
555 let parent_def = field.parent_def(db); 557 db: &impl HirDatabase,
556 let resolver = match parent_def { 558 variant_id: VariantId,
557 VariantDef::Struct(it) => it.id.resolver(db), 559) -> Arc<ArenaMap<LocalStructFieldId, Ty>> {
558 VariantDef::EnumVariant(it) => it.parent.id.resolver(db), 560 let (resolver, var_data) = match variant_id {
561 VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()),
562 VariantId::EnumVariantId(it) => (
563 it.parent.resolver(db),
564 db.enum_data(it.parent).variants[it.local_id].variant_data.clone(),
565 ),
559 }; 566 };
560 let var_data = parent_def.variant_data(db); 567 let mut res = ArenaMap::default();
561 let type_ref = &var_data.fields().unwrap()[field.id].type_ref; 568 for (field_id, field_data) in var_data.fields().iter() {
562 Ty::from_hir(db, &resolver, type_ref) 569 res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref))
570 }
571 Arc::new(res)
563} 572}
564 573
565/// This query exists only to be used when resolving short-hand associated types 574/// This query exists only to be used when resolving short-hand associated types
@@ -572,10 +581,10 @@ pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty {
572/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 581/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
573pub(crate) fn generic_predicates_for_param_query( 582pub(crate) fn generic_predicates_for_param_query(
574 db: &impl HirDatabase, 583 db: &impl HirDatabase,
575 def: GenericDef, 584 def: GenericDefId,
576 param_idx: u32, 585 param_idx: u32,
577) -> Arc<[GenericPredicate]> { 586) -> Arc<[GenericPredicate]> {
578 let resolver = GenericDefId::from(def).resolver(db); 587 let resolver = def.resolver(db);
579 resolver 588 resolver
580 .where_predicates_in_scope() 589 .where_predicates_in_scope()
581 // we have to filter out all other predicates *first*, before attempting to lower them 590 // we have to filter out all other predicates *first*, before attempting to lower them
@@ -584,24 +593,23 @@ pub(crate) fn generic_predicates_for_param_query(
584 .collect() 593 .collect()
585} 594}
586 595
587pub(crate) fn trait_env( 596impl TraitEnvironment {
588 db: &impl HirDatabase, 597 pub(crate) fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
589 resolver: &Resolver, 598 let predicates = resolver
590) -> Arc<super::TraitEnvironment> { 599 .where_predicates_in_scope()
591 let predicates = resolver 600 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
592 .where_predicates_in_scope() 601 .collect::<Vec<_>>();
593 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
594 .collect::<Vec<_>>();
595 602
596 Arc::new(super::TraitEnvironment { predicates }) 603 Arc::new(TraitEnvironment { predicates })
604 }
597} 605}
598 606
599/// Resolve the where clause(s) of an item with generics. 607/// Resolve the where clause(s) of an item with generics.
600pub(crate) fn generic_predicates_query( 608pub(crate) fn generic_predicates_query(
601 db: &impl HirDatabase, 609 db: &impl HirDatabase,
602 def: GenericDef, 610 def: GenericDefId,
603) -> Arc<[GenericPredicate]> { 611) -> Arc<[GenericPredicate]> {
604 let resolver = GenericDefId::from(def).resolver(db); 612 let resolver = def.resolver(db);
605 resolver 613 resolver
606 .where_predicates_in_scope() 614 .where_predicates_in_scope()
607 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) 615 .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred))
@@ -609,9 +617,9 @@ pub(crate) fn generic_predicates_query(
609} 617}
610 618
611/// Resolve the default type params from generics 619/// Resolve the default type params from generics
612pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { 620pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs {
613 let resolver = GenericDefId::from(def).resolver(db); 621 let resolver = def.resolver(db);
614 let generic_params = def.generic_params(db); 622 let generic_params = db.generic_params(def.into());
615 623
616 let defaults = generic_params 624 let defaults = generic_params
617 .params_including_parent() 625 .params_including_parent()
@@ -623,35 +631,35 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
623} 631}
624 632
625fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { 633fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
626 let data = def.data(db); 634 let data = db.function_data(def.id);
627 let resolver = def.id.resolver(db); 635 let resolver = def.id.resolver(db);
628 let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); 636 let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
629 let ret = Ty::from_hir(db, &resolver, data.ret_type()); 637 let ret = Ty::from_hir(db, &resolver, &data.ret_type);
630 FnSig::from_params_and_return(params, ret) 638 FnSig::from_params_and_return(params, ret)
631} 639}
632 640
633/// Build the declared type of a function. This should not need to look at the 641/// Build the declared type of a function. This should not need to look at the
634/// function body. 642/// function body.
635fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { 643fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
636 let generics = def.generic_params(db); 644 let generics = db.generic_params(def.id.into());
637 let substs = Substs::identity(&generics); 645 let substs = Substs::identity(&generics);
638 Ty::apply(TypeCtor::FnDef(def.into()), substs) 646 Ty::apply(TypeCtor::FnDef(def.into()), substs)
639} 647}
640 648
641/// Build the declared type of a const. 649/// Build the declared type of a const.
642fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { 650fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty {
643 let data = def.data(db); 651 let data = db.const_data(def.id);
644 let resolver = def.id.resolver(db); 652 let resolver = def.id.resolver(db);
645 653
646 Ty::from_hir(db, &resolver, data.type_ref()) 654 Ty::from_hir(db, &resolver, &data.type_ref)
647} 655}
648 656
649/// Build the declared type of a static. 657/// Build the declared type of a static.
650fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { 658fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty {
651 let data = def.data(db); 659 let data = db.static_data(def.id);
652 let resolver = def.id.resolver(db); 660 let resolver = def.id.resolver(db);
653 661
654 Ty::from_hir(db, &resolver, data.type_ref()) 662 Ty::from_hir(db, &resolver, &data.type_ref)
655} 663}
656 664
657/// Build the declared type of a static. 665/// Build the declared type of a static.
@@ -697,10 +705,7 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
697 705
698fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { 706fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
699 let struct_data = db.struct_data(def.id.into()); 707 let struct_data = db.struct_data(def.id.into());
700 let fields = match struct_data.variant_data.fields() { 708 let fields = struct_data.variant_data.fields();
701 Some(fields) => fields,
702 None => panic!("fn_sig_for_struct_constructor called on unit struct"),
703 };
704 let resolver = def.id.resolver(db); 709 let resolver = def.id.resolver(db);
705 let params = fields 710 let params = fields
706 .iter() 711 .iter()
@@ -713,26 +718,23 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig {
713/// Build the type of a tuple struct constructor. 718/// Build the type of a tuple struct constructor.
714fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { 719fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
715 let struct_data = db.struct_data(def.id.into()); 720 let struct_data = db.struct_data(def.id.into());
716 if struct_data.variant_data.fields().is_none() { 721 if struct_data.variant_data.is_unit() {
717 return type_for_adt(db, def); // Unit struct 722 return type_for_adt(db, def); // Unit struct
718 } 723 }
719 let generics = def.generic_params(db); 724 let generics = db.generic_params(def.id.into());
720 let substs = Substs::identity(&generics); 725 let substs = Substs::identity(&generics);
721 Ty::apply(TypeCtor::FnDef(def.into()), substs) 726 Ty::apply(TypeCtor::FnDef(def.into()), substs)
722} 727}
723 728
724fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { 729fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig {
725 let var_data = def.variant_data(db); 730 let var_data = def.variant_data(db);
726 let fields = match var_data.fields() { 731 let fields = var_data.fields();
727 Some(fields) => fields,
728 None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"),
729 };
730 let resolver = def.parent.id.resolver(db); 732 let resolver = def.parent.id.resolver(db);
731 let params = fields 733 let params = fields
732 .iter() 734 .iter()
733 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) 735 .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
734 .collect::<Vec<_>>(); 736 .collect::<Vec<_>>();
735 let generics = def.parent_enum(db).generic_params(db); 737 let generics = db.generic_params(def.parent_enum(db).id.into());
736 let substs = Substs::identity(&generics); 738 let substs = Substs::identity(&generics);
737 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); 739 let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs);
738 FnSig::from_params_and_return(params, ret) 740 FnSig::from_params_and_return(params, ret)
@@ -741,21 +743,23 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant)
741/// Build the type of a tuple enum variant constructor. 743/// Build the type of a tuple enum variant constructor.
742fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { 744fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty {
743 let var_data = def.variant_data(db); 745 let var_data = def.variant_data(db);
744 if var_data.fields().is_none() { 746 if var_data.is_unit() {
745 return type_for_adt(db, def.parent_enum(db)); // Unit variant 747 return type_for_adt(db, def.parent_enum(db)); // Unit variant
746 } 748 }
747 let generics = def.parent_enum(db).generic_params(db); 749 let generics = db.generic_params(def.parent_enum(db).id.into());
748 let substs = Substs::identity(&generics); 750 let substs = Substs::identity(&generics);
749 Ty::apply(TypeCtor::FnDef(def.into()), substs) 751 Ty::apply(TypeCtor::FnDef(def.into()), substs)
750} 752}
751 753
752fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt> + HasGenericParams) -> Ty { 754fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty {
753 let generics = adt.generic_params(db); 755 let adt = adt.into();
754 Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) 756 let adt_id: AdtId = adt.into();
757 let generics = db.generic_params(adt_id.into());
758 Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics))
755} 759}
756 760
757fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { 761fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
758 let generics = t.generic_params(db); 762 let generics = db.generic_params(t.id.into());
759 let resolver = t.id.resolver(db); 763 let resolver = t.id.resolver(db);
760 let type_ref = t.type_ref(db); 764 let type_ref = t.type_ref(db);
761 let substs = Substs::identity(&generics); 765 let substs = Substs::identity(&generics);
@@ -817,12 +821,12 @@ impl CallableDef {
817 } 821 }
818} 822}
819 823
820impl From<CallableDef> for GenericDef { 824impl From<CallableDef> for GenericDefId {
821 fn from(def: CallableDef) -> GenericDef { 825 fn from(def: CallableDef) -> GenericDefId {
822 match def { 826 match def {
823 CallableDef::Function(f) => f.into(), 827 CallableDef::Function(f) => f.id.into(),
824 CallableDef::Struct(s) => s.into(), 828 CallableDef::Struct(s) => s.id.into(),
825 CallableDef::EnumVariant(e) => e.into(), 829 CallableDef::EnumVariant(e) => EnumVariantId::from(e).into(),
826 } 830 }
827 } 831 }
828} 832}
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 64adb814d..c5ab690eb 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -5,7 +5,7 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::resolver::Resolver; 8use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef};
9use rustc_hash::FxHashMap; 9use rustc_hash::FxHashMap;
10 10
11use crate::{ 11use crate::{
@@ -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)]
@@ -91,34 +91,43 @@ fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayV
91 // Types like slice can have inherent impls in several crates, (core and alloc). 91 // Types like slice can have inherent impls in several crates, (core and alloc).
92 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 92 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
93 macro_rules! lang_item_crate { 93 macro_rules! lang_item_crate {
94 ($db:expr, $cur_crate:expr, $($name:expr),+ $(,)?) => {{ 94 ($($name:expr),+ $(,)?) => {{
95 let mut v = ArrayVec::<[Crate; 2]>::new(); 95 let mut v = ArrayVec::<[LangItemTarget; 2]>::new();
96 $( 96 $(
97 v.extend($db.lang_item($cur_crate, $name.into()).and_then(|item| item.krate($db))); 97 v.extend(db.lang_item(cur_crate.crate_id, $name.into()));
98 )+ 98 )+
99 Some(v) 99 v
100 }}; 100 }};
101 } 101 }
102 102
103 match ty { 103 let lang_item_targets = match ty {
104 Ty::Apply(a_ty) => match a_ty.ctor { 104 Ty::Apply(a_ty) => match a_ty.ctor {
105 TypeCtor::Adt(def_id) => Some(std::iter::once(def_id.krate(db)?).collect()), 105 TypeCtor::Adt(def_id) => return Some(std::iter::once(def_id.krate(db)?).collect()),
106 TypeCtor::Bool => lang_item_crate!(db, cur_crate, "bool"), 106 TypeCtor::Bool => lang_item_crate!("bool"),
107 TypeCtor::Char => lang_item_crate!(db, cur_crate, "char"), 107 TypeCtor::Char => lang_item_crate!("char"),
108 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { 108 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {
109 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 109 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
110 FloatBitness::X32 => lang_item_crate!(db, cur_crate, "f32", "f32_runtime"), 110 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
111 FloatBitness::X64 => lang_item_crate!(db, cur_crate, "f64", "f64_runtime"), 111 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
112 }, 112 },
113 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(db, cur_crate, i.ty_to_string()), 113 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
114 TypeCtor::Str => lang_item_crate!(db, cur_crate, "str_alloc", "str"), 114 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
115 TypeCtor::Slice => lang_item_crate!(db, cur_crate, "slice_alloc", "slice"), 115 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
116 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!(db, cur_crate, "const_ptr"), 116 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
117 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!(db, cur_crate, "mut_ptr"), 117 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
118 _ => None, 118 _ => return None,
119 }, 119 },
120 _ => None, 120 _ => return None,
121 } 121 };
122 let res = lang_item_targets
123 .into_iter()
124 .filter_map(|it| match it {
125 LangItemTarget::ImplBlockId(it) => Some(it),
126 _ => None,
127 })
128 .map(|it| it.module(db).krate.into())
129 .collect();
130 Some(res)
122} 131}
123 132
124/// Look up the method with the given name, returning the actual autoderefed 133/// Look up the method with the given name, returning the actual autoderefed
@@ -170,8 +179,9 @@ pub(crate) fn iterate_method_candidates<T>(
170 // 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
171 // 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
172 // rustc does an autoderef and then autoref again). 181 // rustc does an autoderef and then autoref again).
173 182 let environment = TraitEnvironment::lower(db, resolver);
174 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) {
175 if let Some(result) = iterate_inherent_methods( 185 if let Some(result) = iterate_inherent_methods(
176 &derefed_ty, 186 &derefed_ty,
177 db, 187 db,
@@ -221,7 +231,7 @@ fn iterate_trait_method_candidates<T>(
221) -> Option<T> { 231) -> Option<T> {
222 let krate = resolver.krate()?; 232 let krate = resolver.krate()?;
223 // 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)
224 let env = lower::trait_env(db, resolver); 234 let env = TraitEnvironment::lower(db, resolver);
225 // 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
226 let inherent_trait = ty.value.inherent_trait().into_iter(); 236 let inherent_trait = ty.value.inherent_trait().into_iter();
227 // 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
@@ -233,7 +243,7 @@ fn iterate_trait_method_candidates<T>(
233 .chain(traits_from_env) 243 .chain(traits_from_env)
234 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); 244 .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
235 'traits: for t in traits { 245 'traits: for t in traits {
236 let data = t.trait_data(db); 246 let data = db.trait_data(t.id);
237 247
238 // we'll be lazy about checking whether the type implements the 248 // we'll be lazy about checking whether the type implements the
239 // trait, but if we find out it doesn't, we'll skip the rest of the 249 // trait, but if we find out it doesn't, we'll skip the rest of the
@@ -291,9 +301,9 @@ fn is_valid_candidate(
291) -> bool { 301) -> bool {
292 match item { 302 match item {
293 AssocItem::Function(m) => { 303 AssocItem::Function(m) => {
294 let data = m.data(db); 304 let data = db.function_data(m.id);
295 name.map_or(true, |name| data.name() == name) 305 name.map_or(true, |name| data.name == *name)
296 && (data.has_self_param() || mode == LookupMode::Path) 306 && (data.has_self_param || mode == LookupMode::Path)
297 } 307 }
298 AssocItem::Const(c) => { 308 AssocItem::Const(c) => {
299 name.map_or(true, |name| Some(name) == c.name(db).as_ref()) 309 name.map_or(true, |name| Some(name) == c.name(db).as_ref())
@@ -315,7 +325,7 @@ pub(crate) fn implements_trait(
315 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet 325 // anyway, but currently Chalk doesn't implement `dyn/impl Trait` yet
316 return true; 326 return true;
317 } 327 }
318 let env = lower::trait_env(db, resolver); 328 let env = TraitEnvironment::lower(db, resolver);
319 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 329 let goal = generic_implements_goal(db, env, trait_, ty.clone());
320 let solution = db.trait_solve(krate, goal); 330 let solution = db.trait_solve(krate, goal);
321 331
@@ -355,7 +365,7 @@ fn generic_implements_goal(
355 self_ty: Canonical<Ty>, 365 self_ty: Canonical<Ty>,
356) -> Canonical<InEnvironment<super::Obligation>> { 366) -> Canonical<InEnvironment<super::Obligation>> {
357 let num_vars = self_ty.num_vars; 367 let num_vars = self_ty.num_vars;
358 let substs = super::Substs::build_for_def(db, trait_) 368 let substs = super::Substs::build_for_def(db, trait_.id)
359 .push(self_ty.value) 369 .push(self_ty.value)
360 .fill_with_bound_vars(num_vars as u32) 370 .fill_with_bound_vars(num_vars as u32)
361 .build(); 371 .build();
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 74c12a0a2..3209c66bd 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2550,8 +2550,6 @@ fn test() {
2550 [233; 246) 'GLOBAL_STATIC': u32 2550 [233; 246) 'GLOBAL_STATIC': u32
2551 [256; 257) 'w': u32 2551 [256; 257) 'w': u32
2552 [260; 277) 'GLOBAL...IC_MUT': u32 2552 [260; 277) 'GLOBAL...IC_MUT': u32
2553 [118; 120) '99': u32
2554 [161; 163) '99': u32
2555 "### 2553 "###
2556 ); 2554 );
2557} 2555}
@@ -4857,3 +4855,41 @@ fn main() {
4857 "### 4855 "###
4858 ); 4856 );
4859} 4857}
4858
4859#[test]
4860fn infer_builtin_macros_file() {
4861 assert_snapshot!(
4862 infer(r#"
4863#[rustc_builtin_macro]
4864macro_rules! file {() => {}}
4865
4866fn main() {
4867 let x = file!();
4868}
4869"#),
4870 @r###"
4871 ![0; 2) '""': &str
4872 [64; 88) '{ ...!(); }': ()
4873 [74; 75) 'x': &str
4874 "###
4875 );
4876}
4877
4878#[test]
4879fn infer_builtin_macros_column() {
4880 assert_snapshot!(
4881 infer(r#"
4882#[rustc_builtin_macro]
4883macro_rules! column {() => {}}
4884
4885fn main() {
4886 let x = column!();
4887}
4888"#),
4889 @r###"
4890 ![0; 2) '13': i32
4891 [66; 92) '{ ...!(); }': ()
4892 [76; 77) 'x': i32
4893 "###
4894 );
4895}
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index 45f725438..268fa09e4 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex};
3 3
4use chalk_ir::{cast::Cast, family::ChalkIr}; 4use chalk_ir::{cast::Cast, family::ChalkIr};
5use log::debug; 5use log::debug;
6use ra_db::salsa; 6use ra_db::{impl_intern_key, salsa};
7use ra_prof::profile; 7use ra_prof::profile;
8use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
9 9
@@ -304,6 +304,10 @@ pub enum Impl {
304 /// Closure types implement the Fn traits synthetically. 304 /// Closure types implement the Fn traits synthetically.
305 ClosureFnTraitImpl(ClosureFnTraitImplData), 305 ClosureFnTraitImpl(ClosureFnTraitImplData),
306} 306}
307/// This exists just for Chalk, because our ImplIds are only unique per module.
308#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
309pub struct GlobalImplId(salsa::InternId);
310impl_intern_key!(GlobalImplId);
307 311
308/// An associated type value. Usually this comes from a `type` declaration 312/// An associated type value. Usually this comes from a `type` declaration
309/// inside an impl block, but for built-in impls we have to synthesize it. 313/// inside an impl block, but for built-in impls we have to synthesize it.
@@ -315,3 +319,8 @@ pub enum AssocTyValue {
315 /// The output type of the Fn trait implementation. 319 /// The output type of the Fn trait implementation.
316 ClosureFnTraitImplOutput(ClosureFnTraitImplData), 320 ClosureFnTraitImplOutput(ClosureFnTraitImplData),
317} 321}
322/// This exists just for Chalk, because it needs a unique ID for each associated
323/// type value in an impl (even synthetic ones).
324#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
325pub struct AssocTyValueId(salsa::InternId);
326impl_intern_key!(AssocTyValueId);
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index 9bf93981a..0272dd9ae 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -9,6 +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, GenericDefId};
12use hir_expand::name; 13use hir_expand::name;
13 14
14use ra_db::salsa::{InternId, InternKey}; 15use ra_db::salsa::{InternId, InternKey};
@@ -16,10 +17,9 @@ use ra_db::salsa::{InternId, InternKey};
16use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; 17use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
17use crate::{ 18use crate::{
18 db::HirDatabase, 19 db::HirDatabase,
19 generics::{GenericDef, HasGenericParams},
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, 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);
@@ -509,7 +509,7 @@ pub(crate) fn associated_ty_data_query(
509 Some(crate::Container::Trait(t)) => t, 509 Some(crate::Container::Trait(t)) => t,
510 _ => panic!("associated type not in trait"), 510 _ => panic!("associated type not in trait"),
511 }; 511 };
512 let generic_params = type_alias.generic_params(db); 512 let generic_params = db.generic_params(type_alias.id.into());
513 let bound_data = chalk_rust_ir::AssociatedTyDatumBound { 513 let bound_data = chalk_rust_ir::AssociatedTyDatumBound {
514 // FIXME add bounds and where clauses 514 // FIXME add bounds and where clauses
515 bounds: vec![], 515 bounds: vec![],
@@ -550,7 +550,7 @@ pub(crate) fn trait_datum_query(
550 } 550 }
551 let trait_: Trait = from_chalk(db, trait_id); 551 let trait_: Trait = from_chalk(db, trait_id);
552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); 552 debug!("trait {:?} = {:?}", trait_id, trait_.name(db));
553 let generic_params = trait_.generic_params(db); 553 let generic_params = db.generic_params(trait_.id.into());
554 let bound_vars = Substs::bound_vars(&generic_params); 554 let bound_vars = Substs::bound_vars(&generic_params);
555 let flags = chalk_rust_ir::TraitFlags { 555 let flags = chalk_rust_ir::TraitFlags {
556 auto: trait_.is_auto(db), 556 auto: trait_.is_auto(db),
@@ -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()
@@ -594,7 +594,7 @@ pub(crate) fn struct_datum_query(
594 let where_clauses = type_ctor 594 let where_clauses = type_ctor
595 .as_generic_def() 595 .as_generic_def()
596 .map(|generic_def| { 596 .map(|generic_def| {
597 let generic_params = generic_def.generic_params(db); 597 let generic_params = db.generic_params(generic_def.into());
598 let bound_vars = Substs::bound_vars(&generic_params); 598 let bound_vars = Substs::bound_vars(&generic_params);
599 convert_where_clauses(db, generic_def, &bound_vars) 599 convert_where_clauses(db, generic_def, &bound_vars)
600 }) 600 })
@@ -634,7 +634,7 @@ fn impl_block_datum(
634 impl_id: ImplId, 634 impl_id: ImplId,
635 impl_block: ImplBlock, 635 impl_block: ImplBlock,
636) -> Option<Arc<ImplDatum<ChalkIr>>> { 636) -> Option<Arc<ImplDatum<ChalkIr>>> {
637 let generic_params = impl_block.generic_params(db); 637 let generic_params = db.generic_params(impl_block.id.into());
638 let bound_vars = Substs::bound_vars(&generic_params); 638 let bound_vars = Substs::bound_vars(&generic_params);
639 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); 639 let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars);
640 let trait_ = trait_ref.trait_; 640 let trait_ = trait_ref.trait_;
@@ -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);
@@ -786,7 +786,7 @@ fn type_alias_associated_ty_value(
786 let assoc_ty = trait_ 786 let assoc_ty = trait_
787 .associated_type_by_name(db, &type_alias.name(db)) 787 .associated_type_by_name(db, &type_alias.name(db))
788 .expect("assoc ty value should not exist"); // validated when building the impl data as well 788 .expect("assoc ty value should not exist"); // validated when building the impl data as well
789 let generic_params = impl_block.generic_params(db); 789 let generic_params = db.generic_params(impl_block.id.into());
790 let bound_vars = Substs::bound_vars(&generic_params); 790 let bound_vars = Substs::bound_vars(&generic_params);
791 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); 791 let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars);
792 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 792 let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.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);
@@ -833,9 +833,9 @@ fn closure_fn_trait_output_assoc_ty_value(
833} 833}
834 834
835fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> { 835fn get_fn_trait(db: &impl HirDatabase, krate: Crate, fn_trait: super::FnTrait) -> Option<Trait> {
836 let target = db.lang_item(krate, fn_trait.lang_item_name().into())?; 836 let target = db.lang_item(krate.crate_id, fn_trait.lang_item_name().into())?;
837 match target { 837 match target {
838 crate::lang_item::LangItemTarget::Trait(t) => Some(t), 838 LangItemTarget::TraitId(t) => Some(t.into()),
839 _ => None, 839 _ => None,
840 } 840 }
841} 841}
@@ -847,38 +847,38 @@ fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
847 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() } 847 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
848} 848}
849 849
850impl From<chalk_ir::StructId> for crate::ids::TypeCtorId { 850impl From<chalk_ir::StructId> for crate::ty::TypeCtorId {
851 fn from(struct_id: chalk_ir::StructId) -> Self { 851 fn from(struct_id: chalk_ir::StructId) -> Self {
852 id_from_chalk(struct_id.0) 852 id_from_chalk(struct_id.0)
853 } 853 }
854} 854}
855 855
856impl From<crate::ids::TypeCtorId> for chalk_ir::StructId { 856impl From<crate::ty::TypeCtorId> for chalk_ir::StructId {
857 fn from(type_ctor_id: crate::ids::TypeCtorId) -> Self { 857 fn from(type_ctor_id: crate::ty::TypeCtorId) -> Self {
858 chalk_ir::StructId(id_to_chalk(type_ctor_id)) 858 chalk_ir::StructId(id_to_chalk(type_ctor_id))
859 } 859 }
860} 860}
861 861
862impl From<chalk_ir::ImplId> for crate::ids::GlobalImplId { 862impl From<chalk_ir::ImplId> for crate::ty::traits::GlobalImplId {
863 fn from(impl_id: chalk_ir::ImplId) -> Self { 863 fn from(impl_id: chalk_ir::ImplId) -> Self {
864 id_from_chalk(impl_id.0) 864 id_from_chalk(impl_id.0)
865 } 865 }
866} 866}
867 867
868impl From<crate::ids::GlobalImplId> for chalk_ir::ImplId { 868impl From<crate::ty::traits::GlobalImplId> for chalk_ir::ImplId {
869 fn from(impl_id: crate::ids::GlobalImplId) -> Self { 869 fn from(impl_id: crate::ty::traits::GlobalImplId) -> Self {
870 chalk_ir::ImplId(id_to_chalk(impl_id)) 870 chalk_ir::ImplId(id_to_chalk(impl_id))
871 } 871 }
872} 872}
873 873
874impl From<chalk_rust_ir::AssociatedTyValueId> for crate::ids::AssocTyValueId { 874impl From<chalk_rust_ir::AssociatedTyValueId> for crate::ty::traits::AssocTyValueId {
875 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self { 875 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self {
876 id_from_chalk(id.0) 876 id_from_chalk(id.0)
877 } 877 }
878} 878}
879 879
880impl From<crate::ids::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId { 880impl From<crate::ty::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId {
881 fn from(assoc_ty_value_id: crate::ids::AssocTyValueId) -> Self { 881 fn from(assoc_ty_value_id: crate::ty::traits::AssocTyValueId) -> Self {
882 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id)) 882 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id))
883 } 883 }
884} 884}