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.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
9 files changed, 212 insertions, 163 deletions
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);