From 0edb5b4a501a66baa7db8ececf46135e6246f4de Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 24 Dec 2019 19:45:28 +0800 Subject: Implement infer await from async func --- crates/ra_hir_ty/src/infer.rs | 17 +++++++++-- crates/ra_hir_ty/src/tests/traits.rs | 57 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index e97b81473..08c220cfe 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs @@ -37,8 +37,8 @@ use test_utils::tested_by; use super::{ primitive::{FloatTy, IntTy}, traits::{Guidance, Obligation, ProjectionPredicate, Solution}, - ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, - TypeWalk, Uncertain, + ApplicationTy, GenericPredicate, InEnvironment, ProjectionTy, Substs, TraitEnvironment, + TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, }; use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; @@ -379,6 +379,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { ) -> Ty { match assoc_ty { Some(res_assoc_ty) => { + // Fast path: Check if inner_ty is is `impl Trait` and contained input TypeAlias id + if let Ty::Opaque(ref predicates) = inner_ty { + for p in predicates.iter() { + if let GenericPredicate::Projection(projection) = p { + if projection.projection_ty.associated_ty == res_assoc_ty + && projection.ty != Ty::Unknown + { + return projection.ty.clone(); + } + } + } + } + let ty = self.table.new_type_var(); let builder = Substs::build_for_def(self.db, res_assoc_ty) .push(inner_ty) diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 76e2198b6..08d1bf044 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -37,6 +37,63 @@ mod future { assert_eq!("u64", type_at_pos(&db, pos)); } +#[test] +fn infer_async() { + let (db, pos) = TestDB::with_position( + r#" +//- /main.rs crate:main deps:std + +async fn foo() -> u64 { + 128 +} + +fn test() { + let r = foo(); + let v = r.await; + v<|>; +} + +//- /std.rs crate:std +#[prelude_import] use future::*; +mod future { + trait Future { + type Output; + } +} + +"#, + ); + assert_eq!("u64", type_at_pos(&db, pos)); +} + +#[test] +fn infer_desugar_async() { + let (db, pos) = TestDB::with_position( + r#" +//- /main.rs crate:main deps:std + +async fn foo() -> u64 { + 128 +} + +fn test() { + let r = foo(); + r<|>; +} + +//- /std.rs crate:std +#[prelude_import] use future::*; +mod future { + trait Future { + type Output; + } +} + +"#, + ); + assert_eq!("impl Future", type_at_pos(&db, pos)); +} + #[test] fn infer_try() { let (db, pos) = TestDB::with_position( -- cgit v1.2.3