aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-29 18:39:15 +0100
committerGitHub <[email protected]>2021-05-29 18:39:15 +0100
commitf6da603c7fe56c19a275dc7bab1f30fe1ad39707 (patch)
tree222351c552f11aed7e8f18a5447fc9c15afa42e0
parent0438e2ceaa89959fe3a1b21e5311a17b08b6fc6d (diff)
parent54d60fdee9a49e2081837cc6445c61dec0b303af (diff)
Merge #9050
9050: hir_ty: use async ret type for inference inside async bodies r=flodiebold a=cynecx Fixes #9004. Co-authored-by: cynecx <[email protected]>
-rw-r--r--crates/hir_def/src/data.rs2
-rw-r--r--crates/hir_def/src/item_tree.rs1
-rw-r--r--crates/hir_def/src/item_tree/lower.rs8
-rw-r--r--crates/hir_def/src/item_tree/pretty.rs1
-rw-r--r--crates/hir_ty/src/infer.rs8
-rw-r--r--crates/hir_ty/src/tests/traits.rs49
6 files changed, 65 insertions, 4 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index a04f73352..d2bb381be 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -22,6 +22,7 @@ pub struct FunctionData {
22 pub name: Name, 22 pub name: Name,
23 pub params: Vec<Interned<TypeRef>>, 23 pub params: Vec<Interned<TypeRef>>,
24 pub ret_type: Interned<TypeRef>, 24 pub ret_type: Interned<TypeRef>,
25 pub async_ret_type: Option<Interned<TypeRef>>,
25 pub attrs: Attrs, 26 pub attrs: Attrs,
26 pub visibility: RawVisibility, 27 pub visibility: RawVisibility,
27 pub abi: Option<Interned<str>>, 28 pub abi: Option<Interned<str>>,
@@ -63,6 +64,7 @@ impl FunctionData {
63 }) 64 })
64 .collect(), 65 .collect(),
65 ret_type: func.ret_type.clone(), 66 ret_type: func.ret_type.clone(),
67 async_ret_type: func.async_ret_type.clone(),
66 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), 68 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
67 visibility: item_tree[func.visibility].clone(), 69 visibility: item_tree[func.visibility].clone(),
68 abi: func.abi.clone(), 70 abi: func.abi.clone(),
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index c4d20c416..227337a8d 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -580,6 +580,7 @@ pub struct Function {
580 pub abi: Option<Interned<str>>, 580 pub abi: Option<Interned<str>>,
581 pub params: IdRange<Param>, 581 pub params: IdRange<Param>,
582 pub ret_type: Interned<TypeRef>, 582 pub ret_type: Interned<TypeRef>,
583 pub async_ret_type: Option<Interned<TypeRef>>,
583 pub ast_id: FileAstId<ast::Fn>, 584 pub ast_id: FileAstId<ast::Fn>,
584 pub(crate) flags: FnFlags, 585 pub(crate) flags: FnFlags,
585} 586}
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index b83adec46..6208facd5 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -356,12 +356,13 @@ impl<'a> Ctx<'a> {
356 _ => TypeRef::unit(), 356 _ => TypeRef::unit(),
357 }; 357 };
358 358
359 let ret_type = if func.async_token().is_some() { 359 let (ret_type, async_ret_type) = if func.async_token().is_some() {
360 let async_ret_type = ret_type.clone();
360 let future_impl = desugar_future_path(ret_type); 361 let future_impl = desugar_future_path(ret_type);
361 let ty_bound = Interned::new(TypeBound::Path(future_impl)); 362 let ty_bound = Interned::new(TypeBound::Path(future_impl));
362 TypeRef::ImplTrait(vec![ty_bound]) 363 (TypeRef::ImplTrait(vec![ty_bound]), Some(async_ret_type))
363 } else { 364 } else {
364 ret_type 365 (ret_type, None)
365 }; 366 };
366 367
367 let abi = func.abi().map(lower_abi); 368 let abi = func.abi().map(lower_abi);
@@ -395,6 +396,7 @@ impl<'a> Ctx<'a> {
395 abi, 396 abi,
396 params, 397 params,
397 ret_type: Interned::new(ret_type), 398 ret_type: Interned::new(ret_type),
399 async_ret_type: async_ret_type.map(Interned::new),
398 ast_id, 400 ast_id,
399 flags, 401 flags,
400 }; 402 };
diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs
index d1ee697cb..cc9944a22 100644
--- a/crates/hir_def/src/item_tree/pretty.rs
+++ b/crates/hir_def/src/item_tree/pretty.rs
@@ -235,6 +235,7 @@ impl<'a> Printer<'a> {
235 abi, 235 abi,
236 params, 236 params,
237 ret_type, 237 ret_type,
238 async_ret_type: _,
238 ast_id: _, 239 ast_id: _,
239 flags, 240 flags,
240 } = &self.tree[it]; 241 } = &self.tree[it];
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 8cefd80f3..7a4268819 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -558,7 +558,13 @@ impl<'a> InferenceContext<'a> {
558 558
559 self.infer_pat(*pat, &ty, BindingMode::default()); 559 self.infer_pat(*pat, &ty, BindingMode::default());
560 } 560 }
561 let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT 561 let error_ty = &TypeRef::Error;
562 let return_ty = if data.is_async() {
563 data.async_ret_type.as_deref().unwrap_or(error_ty)
564 } else {
565 &*data.ret_type
566 };
567 let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT
562 self.return_ty = return_ty; 568 self.return_ty = return_ty;
563 } 569 }
564 570
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 6ad96bfe3..7c0ff2170 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -3660,3 +3660,52 @@ impl foo::Foo for u32 {
3660 "#]], 3660 "#]],
3661 ); 3661 );
3662} 3662}
3663
3664#[test]
3665fn infer_async_ret_type() {
3666 check_types(
3667 r#"
3668//- /main.rs crate:main deps:core
3669
3670enum Result<T, E> {
3671 Ok(T),
3672 Err(E),
3673}
3674
3675use Result::*;
3676
3677
3678struct Fooey;
3679
3680impl Fooey {
3681 fn collect<B: Convert>(self) -> B {
3682 B::new()
3683 }
3684}
3685
3686trait Convert {
3687 fn new() -> Self;
3688}
3689impl Convert for u32 {
3690 fn new() -> Self {
3691 0
3692 }
3693}
3694
3695async fn get_accounts() -> Result<u32, ()> {
3696 let ret = Fooey.collect();
3697 // ^ u32
3698 Ok(ret)
3699}
3700
3701//- /core.rs crate:core
3702#[prelude_import] use future::*;
3703mod future {
3704 #[lang = "future_trait"]
3705 trait Future {
3706 type Output;
3707 }
3708}
3709"#,
3710 );
3711}