diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-29 17:39:15 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-29 17:39:15 +0000 |
| commit | f6da603c7fe56c19a275dc7bab1f30fe1ad39707 (patch) | |
| tree | 222351c552f11aed7e8f18a5447fc9c15afa42e0 | |
| parent | 0438e2ceaa89959fe3a1b21e5311a17b08b6fc6d (diff) | |
| parent | 54d60fdee9a49e2081837cc6445c61dec0b303af (diff) | |
| download | rust-f6da603c7fe56c19a275dc7bab1f30fe1ad39707.tar.gz rust-f6da603c7fe56c19a275dc7bab1f30fe1ad39707.zip | |
Merge #9050
9050: hir_ty: use async ret type for inference inside async bodies r=flodiebold a=cynecx Fixes #9004. Co-authored-by: cynecx <me@cynecx.net>
| -rw-r--r-- | crates/hir_def/src/data.rs | 2 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree.rs | 1 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 8 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree/pretty.rs | 1 | ||||
| -rw-r--r-- | crates/hir_ty/src/infer.rs | 8 | ||||
| -rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 49 |
6 files changed, 65 insertions, 4 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index a04f73352bc..d2bb381be02 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -22,6 +22,7 @@ pub struct FunctionData { pub name: Name, pub params: Vec<Interned<TypeRef>>, pub ret_type: Interned<TypeRef>, + pub async_ret_type: Option<Interned<TypeRef>>, pub attrs: Attrs, pub visibility: RawVisibility, pub abi: Option<Interned<str>>, @@ -63,6 +64,7 @@ impl FunctionData { }) .collect(), ret_type: func.ret_type.clone(), + async_ret_type: func.async_ret_type.clone(), attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), visibility: item_tree[func.visibility].clone(), abi: func.abi.clone(), diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index c4d20c416b4..227337a8df1 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -580,6 +580,7 @@ pub struct Function { pub abi: Option<Interned<str>>, pub params: IdRange<Param>, pub ret_type: Interned<TypeRef>, + pub async_ret_type: Option<Interned<TypeRef>>, pub ast_id: FileAstId<ast::Fn>, pub(crate) flags: FnFlags, } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index b83adec46af..6208facd54e 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> { _ => TypeRef::unit(), }; - let ret_type = if func.async_token().is_some() { + let (ret_type, async_ret_type) = if func.async_token().is_some() { + let async_ret_type = ret_type.clone(); let future_impl = desugar_future_path(ret_type); let ty_bound = Interned::new(TypeBound::Path(future_impl)); - TypeRef::ImplTrait(vec![ty_bound]) + (TypeRef::ImplTrait(vec![ty_bound]), Some(async_ret_type)) } else { - ret_type + (ret_type, None) }; let abi = func.abi().map(lower_abi); @@ -395,6 +396,7 @@ impl<'a> Ctx<'a> { abi, params, ret_type: Interned::new(ret_type), + async_ret_type: async_ret_type.map(Interned::new), ast_id, flags, }; diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs index d1ee697cb5d..cc9944a22f8 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> { abi, params, ret_type, + async_ret_type: _, ast_id: _, flags, } = &self.tree[it]; diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 8cefd80f3ab..7a4268819b4 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -558,7 +558,13 @@ impl<'a> InferenceContext<'a> { self.infer_pat(*pat, &ty, BindingMode::default()); } - let return_ty = self.make_ty_with_mode(&data.ret_type, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT + let error_ty = &TypeRef::Error; + let return_ty = if data.is_async() { + data.async_ret_type.as_deref().unwrap_or(error_ty) + } else { + &*data.ret_type + }; + let return_ty = self.make_ty_with_mode(return_ty, ImplTraitLoweringMode::Disallowed); // FIXME implement RPIT self.return_ty = return_ty; } diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 6ad96bfe383..7c0ff2170fe 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 { "#]], ); } + +#[test] +fn infer_async_ret_type() { + check_types( + r#" +//- /main.rs crate:main deps:core + +enum Result<T, E> { + Ok(T), + Err(E), +} + +use Result::*; + + +struct Fooey; + +impl Fooey { + fn collect<B: Convert>(self) -> B { + B::new() + } +} + +trait Convert { + fn new() -> Self; +} +impl Convert for u32 { + fn new() -> Self { + 0 + } +} + +async fn get_accounts() -> Result<u32, ()> { + let ret = Fooey.collect(); + // ^ u32 + Ok(ret) +} + +//- /core.rs crate:core +#[prelude_import] use future::*; +mod future { + #[lang = "future_trait"] + trait Future { + type Output; + } +} +"#, + ); +} |
