diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/autoderef.rs | 45 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/coerce.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 87 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/pat.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 164 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 16 |
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 | ||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | use hir_expand::name; | 9 | use hir_expand::name; |
10 | use log::{info, warn}; | 10 | use log::{info, warn}; |
11 | use ra_db::CrateId; | ||
11 | 12 | ||
12 | use crate::{db::HirDatabase, Trait}; | 13 | use crate::{db::HirDatabase, Trait}; |
13 | 14 | ||
14 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; | 15 | use super::{ |
16 | traits::{InEnvironment, Solution}, | ||
17 | Canonical, Substs, Ty, TypeWalk, | ||
18 | }; | ||
15 | 19 | ||
16 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
17 | 21 | ||
18 | pub(crate) fn autoderef<'a>( | 22 | pub(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 | ||
26 | pub(crate) fn deref( | 34 | pub(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 | ||
38 | fn deref_by_trait( | 46 | fn 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; | |||
34 | use test_utils::tested_by; | 34 | use test_utils::tested_by; |
35 | 35 | ||
36 | use super::{ | 36 | use 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 | ||
51 | macro_rules! ty_app { | 49 | macro_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 | ||
17 | use super::{InferTy, InferenceContext, TypeVarValue}; | 17 | use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; |
18 | 18 | ||
19 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 19 | impl<'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 | }; |
12 | use hir_expand::name; | 13 | use 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 | }; |
20 | use ra_arena::map::ArenaMap; | ||
21 | use ra_db::CrateId; | ||
19 | 22 | ||
20 | use super::{ | 23 | use 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 | }; |
24 | use crate::{ | 27 | use 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). |
544 | pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSig { | 549 | pub(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. |
553 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 558 | pub(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<()>`. |
572 | pub(crate) fn generic_predicates_for_param_query( | 584 | pub(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 | ||
586 | pub(crate) fn trait_env( | 598 | impl 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. |
599 | pub(crate) fn generic_predicates_query( | 610 | pub(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 |
611 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { | 622 | pub(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 | ||
624 | fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { | 635 | fn 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 { | |||
634 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 645 | fn 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 | ||
697 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | 708 | fn 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. |
713 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 721 | fn 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 | ||
723 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { | 731 | fn 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. |
741 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 747 | fn 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 | ||
751 | fn type_for_adt(db: &impl HirDatabase, adt: impl Into<Adt>) -> Ty { | 757 | fn 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)] |
804 | pub enum CallableDef { | 810 | pub enum CallableDef { |
805 | Function(Function), | 811 | FunctionId(FunctionId), |
806 | Struct(Struct), | 812 | StructId(StructId), |
807 | EnumVariant(EnumVariant), | 813 | EnumVariantId(EnumVariantId), |
808 | } | 814 | } |
809 | impl_froms!(CallableDef: Function, Struct, EnumVariant); | 815 | impl_froms!(CallableDef: FunctionId, StructId, EnumVariantId); |
810 | 816 | ||
811 | impl CallableDef { | 817 | impl 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 | ||
821 | impl From<CallableDef> for GenericDef { | 827 | impl 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 | ||
18 | use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 18 | use 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 | }; |
10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; | 10 | use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum}; |
11 | 11 | ||
12 | use hir_def::lang_item::LangItemTarget; | 12 | use hir_def::{lang_item::LangItemTarget, GenericDefId}; |
13 | use hir_expand::name; | 13 | use hir_expand::name; |
14 | 14 | ||
15 | use ra_db::salsa::{InternId, InternKey}; | 15 | use 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 | ||
403 | fn convert_where_clauses( | 403 | fn 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); |