diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 101 |
1 files changed, 33 insertions, 68 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 2c296987c..f8c00a7b4 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -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 | CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, | 22 | ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, |
23 | TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, | 23 | TypeCtor, TypeWalk, Uncertain, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | 26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; |
@@ -95,21 +95,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
95 | Expr::For { iterable, body, pat } => { | 95 | Expr::For { iterable, body, pat } => { |
96 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 96 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
97 | 97 | ||
98 | let pat_ty = match self.resolve_into_iter_item() { | 98 | let pat_ty = |
99 | Some(into_iter_item_alias) => { | 99 | self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); |
100 | let pat_ty = self.table.new_type_var(); | ||
101 | let projection = ProjectionPredicate { | ||
102 | ty: pat_ty.clone(), | ||
103 | projection_ty: ProjectionTy { | ||
104 | associated_ty: into_iter_item_alias, | ||
105 | parameters: Substs::single(iterable_ty), | ||
106 | }, | ||
107 | }; | ||
108 | self.obligations.push(Obligation::Projection(projection)); | ||
109 | self.resolve_ty_as_possible(pat_ty) | ||
110 | } | ||
111 | None => Ty::Unknown, | ||
112 | }; | ||
113 | 100 | ||
114 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); | 101 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); |
115 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 102 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
@@ -284,40 +271,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
284 | } | 271 | } |
285 | Expr::Await { expr } => { | 272 | Expr::Await { expr } => { |
286 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 273 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
287 | let ty = match self.resolve_future_future_output() { | 274 | let ty = |
288 | Some(future_future_output_alias) => { | 275 | self.resolve_associated_type(inner_ty, self.resolve_future_future_output()); |
289 | let ty = self.table.new_type_var(); | ||
290 | let projection = ProjectionPredicate { | ||
291 | ty: ty.clone(), | ||
292 | projection_ty: ProjectionTy { | ||
293 | associated_ty: future_future_output_alias, | ||
294 | parameters: Substs::single(inner_ty), | ||
295 | }, | ||
296 | }; | ||
297 | self.obligations.push(Obligation::Projection(projection)); | ||
298 | self.resolve_ty_as_possible(ty) | ||
299 | } | ||
300 | None => Ty::Unknown, | ||
301 | }; | ||
302 | ty | 276 | ty |
303 | } | 277 | } |
304 | Expr::Try { expr } => { | 278 | Expr::Try { expr } => { |
305 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 279 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
306 | let ty = match self.resolve_ops_try_ok() { | 280 | let ty = self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()); |
307 | Some(ops_try_ok_alias) => { | ||
308 | let ty = self.table.new_type_var(); | ||
309 | let projection = ProjectionPredicate { | ||
310 | ty: ty.clone(), | ||
311 | projection_ty: ProjectionTy { | ||
312 | associated_ty: ops_try_ok_alias, | ||
313 | parameters: Substs::single(inner_ty), | ||
314 | }, | ||
315 | }; | ||
316 | self.obligations.push(Obligation::Projection(projection)); | ||
317 | self.resolve_ty_as_possible(ty) | ||
318 | } | ||
319 | None => Ty::Unknown, | ||
320 | }; | ||
321 | ty | 281 | ty |
322 | } | 282 | } |
323 | Expr::Cast { expr, type_ref } => { | 283 | Expr::Cast { expr, type_ref } => { |
@@ -372,31 +332,36 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
372 | }, | 332 | }, |
373 | UnaryOp::Neg => { | 333 | UnaryOp::Neg => { |
374 | match &inner_ty { | 334 | match &inner_ty { |
375 | Ty::Apply(a_ty) => match a_ty.ctor { | 335 | // Fast path for builtins |
376 | TypeCtor::Int(Uncertain::Unknown) | 336 | Ty::Apply(ApplicationTy { |
377 | | TypeCtor::Int(Uncertain::Known(IntTy { | 337 | ctor: |
378 | signedness: Signedness::Signed, | 338 | TypeCtor::Int(Uncertain::Known(IntTy { |
379 | .. | 339 | signedness: Signedness::Signed, |
380 | })) | 340 | .. |
381 | | TypeCtor::Float(..) => inner_ty, | 341 | })), |
382 | _ => Ty::Unknown, | 342 | .. |
383 | }, | 343 | }) |
384 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { | 344 | | Ty::Apply(ApplicationTy { |
385 | inner_ty | 345 | ctor: TypeCtor::Int(Uncertain::Unknown), |
386 | } | 346 | .. |
387 | // FIXME: resolve ops::Neg trait | 347 | }) |
388 | _ => Ty::Unknown, | 348 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) |
349 | | Ty::Infer(InferTy::IntVar(..)) | ||
350 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | ||
351 | // Otherwise we resolve via the std::ops::Neg trait | ||
352 | _ => self | ||
353 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | ||
389 | } | 354 | } |
390 | } | 355 | } |
391 | UnaryOp::Not => { | 356 | UnaryOp::Not => { |
392 | match &inner_ty { | 357 | match &inner_ty { |
393 | Ty::Apply(a_ty) => match a_ty.ctor { | 358 | // Fast path for builtins |
394 | TypeCtor::Bool | TypeCtor::Int(_) => inner_ty, | 359 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) |
395 | _ => Ty::Unknown, | 360 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) |
396 | }, | 361 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
397 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 362 | // Otherwise we resolve via the std::ops::Not trait |
398 | // FIXME: resolve ops::Not trait for inner_ty | 363 | _ => self |
399 | _ => Ty::Unknown, | 364 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
400 | } | 365 | } |
401 | } | 366 | } |
402 | } | 367 | } |