aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/coerce.rs18
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs34
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs19
-rw-r--r--crates/ra_hir_ty/src/infer/path.rs60
4 files changed, 64 insertions, 67 deletions
diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs
index 83c0c2c3f..f68a1439f 100644
--- a/crates/ra_hir_ty/src/infer/coerce.rs
+++ b/crates/ra_hir_ty/src/infer/coerce.rs
@@ -57,8 +57,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
57 let trait_ref = db.impl_trait(impl_id)?; 57 let trait_ref = db.impl_trait(impl_id)?;
58 58
59 // `CoerseUnsized` has one generic parameter for the target type. 59 // `CoerseUnsized` has one generic parameter for the target type.
60 let cur_from_ty = trait_ref.substs.0.get(0)?; 60 let cur_from_ty = trait_ref.value.substs.0.get(0)?;
61 let cur_to_ty = trait_ref.substs.0.get(1)?; 61 let cur_to_ty = trait_ref.value.substs.0.get(1)?;
62 62
63 match (&cur_from_ty, cur_to_ty) { 63 match (&cur_from_ty, cur_to_ty) {
64 (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => { 64 (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => {
@@ -66,9 +66,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
66 // This works for smart-pointer-like coercion, which covers all impls from std. 66 // This works for smart-pointer-like coercion, which covers all impls from std.
67 st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| { 67 st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| {
68 match (ty1, ty2) { 68 match (ty1, ty2) {
69 (Ty::Param { idx: p1, .. }, Ty::Param { idx: p2, .. }) 69 (Ty::Bound(idx1), Ty::Bound(idx2)) if idx1 != idx2 => {
70 if p1 != p2 =>
71 {
72 Some(((*ctor1, *ctor2), i)) 70 Some(((*ctor1, *ctor2), i))
73 } 71 }
74 _ => None, 72 _ => None,
@@ -256,8 +254,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
256 let unsize_generic_index = { 254 let unsize_generic_index = {
257 let mut index = None; 255 let mut index = None;
258 let mut multiple_param = false; 256 let mut multiple_param = false;
259 field_tys[last_field_id].walk(&mut |ty| match ty { 257 field_tys[last_field_id].value.walk(&mut |ty| match ty {
260 &Ty::Param { idx, .. } => { 258 &Ty::Bound(idx) => {
261 if index.is_none() { 259 if index.is_none() {
262 index = Some(idx); 260 index = Some(idx);
263 } else if Some(idx) != index { 261 } else if Some(idx) != index {
@@ -276,10 +274,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
276 // Check other fields do not involve it. 274 // Check other fields do not involve it.
277 let mut multiple_used = false; 275 let mut multiple_used = false;
278 fields.for_each(|(field_id, _data)| { 276 fields.for_each(|(field_id, _data)| {
279 field_tys[field_id].walk(&mut |ty| match ty { 277 field_tys[field_id].value.walk(&mut |ty| match ty {
280 &Ty::Param { idx, .. } if idx == unsize_generic_index => { 278 &Ty::Bound(idx) if idx == unsize_generic_index => multiple_used = true,
281 multiple_used = true
282 }
283 _ => {} 279 _ => {}
284 }) 280 })
285 }); 281 });
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 31259a01d..39d8bc0ca 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -10,7 +10,7 @@ use hir_def::{
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 AdtId, AssocContainerId, Lookup, StructFieldId, 11 AdtId, AssocContainerId, Lookup, StructFieldId,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::Name;
14use ra_syntax::ast::RangeOp; 14use ra_syntax::ast::RangeOp;
15 15
16use crate::{ 16use crate::{
@@ -19,8 +19,8 @@ use crate::{
19 method_resolution, op, 19 method_resolution, op,
20 traits::InEnvironment, 20 traits::InEnvironment,
21 utils::{generics, variant_data, Generics}, 21 utils::{generics, variant_data, Generics},
22 ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, 22 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef,
23 TypeCtor, TypeWalk, Uncertain, 23 Ty, TypeCtor, Uncertain,
24}; 24};
25 25
26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -165,12 +165,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
165 Expr::Match { expr, arms } => { 165 Expr::Match { expr, arms } => {
166 let input_ty = self.infer_expr(*expr, &Expectation::none()); 166 let input_ty = self.infer_expr(*expr, &Expectation::none());
167 167
168 let mut result_ty = self.table.new_maybe_never_type_var(); 168 let mut result_ty = if arms.len() == 0 {
169 Ty::simple(TypeCtor::Never)
170 } else {
171 self.table.new_type_var()
172 };
169 173
170 for arm in arms { 174 for arm in arms {
171 for &pat in &arm.pats { 175 let _pat_ty = self.infer_pat(arm.pat, &input_ty, BindingMode::default());
172 let _pat_ty = self.infer_pat(pat, &input_ty, BindingMode::default());
173 }
174 if let Some(guard_expr) = arm.guard { 176 if let Some(guard_expr) = arm.guard {
175 self.infer_expr( 177 self.infer_expr(
176 guard_expr, 178 guard_expr,
@@ -236,8 +238,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
236 self.result.record_field_resolutions.insert(field.expr, field_def); 238 self.result.record_field_resolutions.insert(field.expr, field_def);
237 } 239 }
238 let field_ty = field_def 240 let field_ty = field_def
239 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone()) 241 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs));
240 .subst(&substs);
241 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 242 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
242 } 243 }
243 if let Some(expr) = spread { 244 if let Some(expr) = spread {
@@ -588,10 +589,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
588 self.write_method_resolution(tgt_expr, func); 589 self.write_method_resolution(tgt_expr, func);
589 (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into()))) 590 (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into())))
590 } 591 }
591 None => (receiver_ty, Ty::Unknown, None), 592 None => (receiver_ty, Binders::new(0, Ty::Unknown), None),
592 }; 593 };
593 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 594 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
594 let method_ty = method_ty.apply_substs(substs); 595 let method_ty = method_ty.subst(&substs);
595 let method_ty = self.insert_type_vars(method_ty); 596 let method_ty = self.insert_type_vars(method_ty);
596 self.register_obligations_for_call(&method_ty); 597 self.register_obligations_for_call(&method_ty);
597 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 598 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -635,7 +636,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
635 continue; 636 continue;
636 } 637 }
637 638
638 let param_ty = self.insert_vars_for_impl_trait(param_ty);
639 let param_ty = self.normalize_associated_types_in(param_ty); 639 let param_ty = self.normalize_associated_types_in(param_ty);
640 self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone())); 640 self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone()));
641 } 641 }
@@ -648,13 +648,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
648 generic_args: Option<&GenericArgs>, 648 generic_args: Option<&GenericArgs>,
649 receiver_ty: &Ty, 649 receiver_ty: &Ty,
650 ) -> Substs { 650 ) -> Substs {
651 let (total_len, _parent_len, child_len) = 651 let (parent_params, self_params, type_params, impl_trait_params) =
652 def_generics.as_ref().map_or((0, 0, 0), |g| g.len_split()); 652 def_generics.as_ref().map_or((0, 0, 0, 0), |g| g.provenance_split());
653 assert_eq!(self_params, 0); // method shouldn't have another Self param
654 let total_len = parent_params + type_params + impl_trait_params;
653 let mut substs = Vec::with_capacity(total_len); 655 let mut substs = Vec::with_capacity(total_len);
654 // Parent arguments are unknown, except for the receiver type 656 // Parent arguments are unknown, except for the receiver type
655 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 657 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) {
656 for (_id, param) in parent_generics { 658 for (_id, param) in parent_generics {
657 if param.name == name![Self] { 659 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
658 substs.push(receiver_ty.clone()); 660 substs.push(receiver_ty.clone());
659 } else { 661 } else {
660 substs.push(Ty::Unknown); 662 substs.push(Ty::Unknown);
@@ -664,7 +666,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
664 // handle provided type arguments 666 // handle provided type arguments
665 if let Some(generic_args) = generic_args { 667 if let Some(generic_args) = generic_args {
666 // if args are provided, it should be all of them, but we can't rely on that 668 // if args are provided, it should be all of them, but we can't rely on that
667 for arg in generic_args.args.iter().take(child_len) { 669 for arg in generic_args.args.iter().take(type_params) {
668 match arg { 670 match arg {
669 GenericArg::Type(type_ref) => { 671 GenericArg::Type(type_ref) => {
670 let ty = self.make_ty(type_ref); 672 let ty = self.make_ty(type_ref);
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index a14662884..a5dfdf6c4 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -12,7 +12,7 @@ use hir_expand::name::Name;
12use test_utils::tested_by; 12use test_utils::tested_by;
13 13
14use super::{BindingMode, InferenceContext}; 14use super::{BindingMode, InferenceContext};
15use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}; 15use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor};
16 16
17impl<'a, D: HirDatabase> InferenceContext<'a, D> { 17impl<'a, D: HirDatabase> InferenceContext<'a, D> {
18 fn infer_tuple_struct_pat( 18 fn infer_tuple_struct_pat(
@@ -34,8 +34,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
34 let expected_ty = var_data 34 let expected_ty = var_data
35 .as_ref() 35 .as_ref()
36 .and_then(|d| d.field(&Name::new_tuple_field(i))) 36 .and_then(|d| d.field(&Name::new_tuple_field(i)))
37 .map_or(Ty::Unknown, |field| field_tys[field].clone()) 37 .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs));
38 .subst(&substs);
39 let expected_ty = self.normalize_associated_types_in(expected_ty); 38 let expected_ty = self.normalize_associated_types_in(expected_ty);
40 self.infer_pat(subpat, &expected_ty, default_bm); 39 self.infer_pat(subpat, &expected_ty, default_bm);
41 } 40 }
@@ -65,7 +64,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
65 for subpat in subpats { 64 for subpat in subpats {
66 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); 65 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
67 let expected_ty = 66 let expected_ty =
68 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs); 67 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs));
69 let expected_ty = self.normalize_associated_types_in(expected_ty); 68 let expected_ty = self.normalize_associated_types_in(expected_ty);
70 self.infer_pat(subpat.pat, &expected_ty, default_bm); 69 self.infer_pat(subpat.pat, &expected_ty, default_bm);
71 } 70 }
@@ -83,6 +82,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
83 82
84 let is_non_ref_pat = match &body[pat] { 83 let is_non_ref_pat = match &body[pat] {
85 Pat::Tuple(..) 84 Pat::Tuple(..)
85 | Pat::Or(..)
86 | Pat::TupleStruct { .. } 86 | Pat::TupleStruct { .. }
87 | Pat::Record { .. } 87 | Pat::Record { .. }
88 | Pat::Range { .. } 88 | Pat::Range { .. }
@@ -127,6 +127,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
127 127
128 Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys)) 128 Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys))
129 } 129 }
130 Pat::Or(ref pats) => {
131 if let Some((first_pat, rest)) = pats.split_first() {
132 let ty = self.infer_pat(*first_pat, expected, default_bm);
133 for pat in rest {
134 self.infer_pat(*pat, expected, default_bm);
135 }
136 ty
137 } else {
138 Ty::Unknown
139 }
140 }
130 Pat::Ref { pat, mutability } => { 141 Pat::Ref { pat, mutability } => {
131 let expectation = match expected.as_reference() { 142 let expectation = match expected.as_reference() {
132 Some((inner_ty, exp_mut)) => { 143 Some((inner_ty, exp_mut)) => {
diff --git a/crates/ra_hir_ty/src/infer/path.rs b/crates/ra_hir_ty/src/infer/path.rs
index 2c1d4831d..686ce7a21 100644
--- a/crates/ra_hir_ty/src/infer/path.rs
+++ b/crates/ra_hir_ty/src/infer/path.rs
@@ -9,9 +9,9 @@ use hir_def::{
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId}; 12use crate::{db::HirDatabase, method_resolution, Substs, Ty, ValueTyDefId};
13 13
14use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef}; 14use super::{ExprOrPatId, InferenceContext, TraitRef};
15 15
16impl<'a, D: HirDatabase> InferenceContext<'a, D> { 16impl<'a, D: HirDatabase> InferenceContext<'a, D> {
17 pub(super) fn infer_path( 17 pub(super) fn infer_path(
@@ -39,7 +39,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
39 } 39 }
40 let ty = self.make_ty(type_ref); 40 let ty = self.make_ty(type_ref);
41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); 41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
42 let ty = Ty::from_type_relative_path(self.db, resolver, ty, remaining_segments_for_ty); 42 let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver);
43 let ty = Ty::from_type_relative_path(&ctx, ty, remaining_segments_for_ty);
43 self.resolve_ty_assoc_item( 44 self.resolve_ty_assoc_item(
44 ty, 45 ty,
45 &path.segments().last().expect("path had at least one segment").name, 46 &path.segments().last().expect("path had at least one segment").name,
@@ -69,12 +70,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
69 ValueNs::EnumVariantId(it) => it.into(), 70 ValueNs::EnumVariantId(it) => it.into(),
70 }; 71 };
71 72
72 let mut ty = self.db.value_ty(typable); 73 let ty = self.db.value_ty(typable);
73 if let Some(self_subst) = self_subst { 74 // self_subst is just for the parent
74 ty = ty.subst(&self_subst); 75 let parent_substs = self_subst.unwrap_or_else(Substs::empty);
75 } 76 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
76 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 77 let substs = Ty::substs_from_path(&ctx, path, typable);
77 let ty = ty.subst(&substs); 78 let full_substs = Substs::builder(substs.len())
79 .use_parent_substs(&parent_substs)
80 .fill(substs.0[parent_substs.len()..].iter().cloned())
81 .build();
82 let ty = ty.subst(&full_substs);
78 Some(ty) 83 Some(ty)
79 } 84 }
80 85
@@ -98,13 +103,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
98 (TypeNs::TraitId(trait_), true) => { 103 (TypeNs::TraitId(trait_), true) => {
99 let segment = 104 let segment =
100 remaining_segments.last().expect("there should be at least one segment here"); 105 remaining_segments.last().expect("there should be at least one segment here");
101 let trait_ref = TraitRef::from_resolved_path( 106 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 self.db, 107 let trait_ref =
103 &self.resolver, 108 TraitRef::from_resolved_path(&ctx, trait_.into(), resolved_segment, None);
104 trait_.into(),
105 resolved_segment,
106 None,
107 );
108 self.resolve_trait_assoc_item(trait_ref, segment, id) 109 self.resolve_trait_assoc_item(trait_ref, segment, id)
109 } 110 }
110 (def, _) => { 111 (def, _) => {
@@ -114,9 +115,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
114 // as Iterator>::Item::default`) 115 // as Iterator>::Item::default`)
115 let remaining_segments_for_ty = 116 let remaining_segments_for_ty =
116 remaining_segments.take(remaining_segments.len() - 1); 117 remaining_segments.take(remaining_segments.len() - 1);
118 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
117 let ty = Ty::from_partly_resolved_hir_path( 119 let ty = Ty::from_partly_resolved_hir_path(
118 self.db, 120 &ctx,
119 &self.resolver,
120 def, 121 def,
121 resolved_segment, 122 resolved_segment,
122 remaining_segments_for_ty, 123 remaining_segments_for_ty,
@@ -173,13 +174,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
173 AssocItemId::ConstId(c) => ValueNs::ConstId(c), 174 AssocItemId::ConstId(c) => ValueNs::ConstId(c),
174 AssocItemId::TypeAliasId(_) => unreachable!(), 175 AssocItemId::TypeAliasId(_) => unreachable!(),
175 }; 176 };
176 let substs = Substs::build_for_def(self.db, item)
177 .use_parent_substs(&trait_ref.substs)
178 .fill_with_params()
179 .build();
180 177
181 self.write_assoc_resolution(id, item); 178 self.write_assoc_resolution(id, item);
182 Some((def, Some(substs))) 179 Some((def, Some(trait_ref.substs)))
183 } 180 }
184 181
185 fn resolve_ty_assoc_item( 182 fn resolve_ty_assoc_item(
@@ -193,14 +190,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
193 } 190 }
194 191
195 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone()); 192 let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone());
196 let env = TraitEnvironment::lower(self.db, &self.resolver);
197 let krate = self.resolver.krate()?; 193 let krate = self.resolver.krate()?;
198 let traits_in_scope = self.resolver.traits_in_scope(self.db); 194 let traits_in_scope = self.resolver.traits_in_scope(self.db);
199 195
200 method_resolution::iterate_method_candidates( 196 method_resolution::iterate_method_candidates(
201 &canonical_ty.value, 197 &canonical_ty.value,
202 self.db, 198 self.db,
203 env, 199 self.trait_env.clone(),
204 krate, 200 krate,
205 &traits_in_scope, 201 &traits_in_scope,
206 Some(name), 202 Some(name),
@@ -219,12 +215,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
219 .fill(iter::repeat_with(|| self.table.new_type_var())) 215 .fill(iter::repeat_with(|| self.table.new_type_var()))
220 .build(); 216 .build();
221 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 217 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs);
222 let substs = Substs::build_for_def(self.db, item)
223 .use_parent_substs(&impl_substs)
224 .fill_with_params()
225 .build();
226 self.unify(&impl_self_ty, &ty); 218 self.unify(&impl_self_ty, &ty);
227 Some(substs) 219 Some(impl_substs)
228 } 220 }
229 AssocContainerId::TraitId(trait_) => { 221 AssocContainerId::TraitId(trait_) => {
230 // we're picking this method 222 // we're picking this method
@@ -232,15 +224,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
232 .push(ty.clone()) 224 .push(ty.clone())
233 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 225 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
234 .build(); 226 .build();
235 let substs = Substs::build_for_def(self.db, item)
236 .use_parent_substs(&trait_substs)
237 .fill_with_params()
238 .build();
239 self.obligations.push(super::Obligation::Trait(TraitRef { 227 self.obligations.push(super::Obligation::Trait(TraitRef {
240 trait_, 228 trait_,
241 substs: trait_substs, 229 substs: trait_substs.clone(),
242 })); 230 }));
243 Some(substs) 231 Some(trait_substs)
244 } 232 }
245 AssocContainerId::ContainerId(_) => None, 233 AssocContainerId::ContainerId(_) => None,
246 }; 234 };