Skip to content

Commit f6da603

Browse files
bors[bot]cynecx
andauthored
9050: hir_ty: use async ret type for inference inside async bodies r=flodiebold a=cynecx Fixes rust-lang#9004. Co-authored-by: cynecx <me@cynecx.net>
2 parents 0438e2c + 54d60fd commit f6da603

File tree

6 files changed

+65
-4
lines changed

6 files changed

+65
-4
lines changed

crates/hir_def/src/data.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct FunctionData {
2222
pub name: Name,
2323
pub params: Vec<Interned<TypeRef>>,
2424
pub ret_type: Interned<TypeRef>,
25+
pub async_ret_type: Option<Interned<TypeRef>>,
2526
pub attrs: Attrs,
2627
pub visibility: RawVisibility,
2728
pub abi: Option<Interned<str>>,
@@ -63,6 +64,7 @@ impl FunctionData {
6364
})
6465
.collect(),
6566
ret_type: func.ret_type.clone(),
67+
async_ret_type: func.async_ret_type.clone(),
6668
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
6769
visibility: item_tree[func.visibility].clone(),
6870
abi: func.abi.clone(),

crates/hir_def/src/item_tree.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ pub struct Function {
580580
pub abi: Option<Interned<str>>,
581581
pub params: IdRange<Param>,
582582
pub ret_type: Interned<TypeRef>,
583+
pub async_ret_type: Option<Interned<TypeRef>>,
583584
pub ast_id: FileAstId<ast::Fn>,
584585
pub(crate) flags: FnFlags,
585586
}

crates/hir_def/src/item_tree/lower.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,13 @@ impl<'a> Ctx<'a> {
356356
_ => TypeRef::unit(),
357357
};
358358

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();
360361
let future_impl = desugar_future_path(ret_type);
361362
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))
363364
} else {
364-
ret_type
365+
(ret_type, None)
365366
};
366367

367368
let abi = func.abi().map(lower_abi);
@@ -395,6 +396,7 @@ impl<'a> Ctx<'a> {
395396
abi,
396397
params,
397398
ret_type: Interned::new(ret_type),
399+
async_ret_type: async_ret_type.map(Interned::new),
398400
ast_id,
399401
flags,
400402
};

crates/hir_def/src/item_tree/pretty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ impl<'a> Printer<'a> {
235235
abi,
236236
params,
237237
ret_type,
238+
async_ret_type: _,
238239
ast_id: _,
239240
flags,
240241
} = &self.tree[it];

crates/hir_ty/src/infer.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,13 @@ impl<'a> InferenceContext<'a> {
558558

559559
self.infer_pat(*pat, &ty, BindingMode::default());
560560
}
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
562568
self.return_ty = return_ty;
563569
}
564570

crates/hir_ty/src/tests/traits.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,3 +3660,52 @@ impl foo::Foo for u32 {
36603660
"#]],
36613661
);
36623662
}
3663+
3664+
#[test]
3665+
fn infer_async_ret_type() {
3666+
check_types(
3667+
r#"
3668+
//- /main.rs crate:main deps:core
3669+
3670+
enum Result<T, E> {
3671+
Ok(T),
3672+
Err(E),
3673+
}
3674+
3675+
use Result::*;
3676+
3677+
3678+
struct Fooey;
3679+
3680+
impl Fooey {
3681+
fn collect<B: Convert>(self) -> B {
3682+
B::new()
3683+
}
3684+
}
3685+
3686+
trait Convert {
3687+
fn new() -> Self;
3688+
}
3689+
impl Convert for u32 {
3690+
fn new() -> Self {
3691+
0
3692+
}
3693+
}
3694+
3695+
async 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::*;
3703+
mod future {
3704+
#[lang = "future_trait"]
3705+
trait Future {
3706+
type Output;
3707+
}
3708+
}
3709+
"#,
3710+
);
3711+
}

0 commit comments

Comments
 (0)