Unnamed repository; edit this file 'description' to name the repository.
Simplify
Lukas Wirth 2023-03-15
parent af175dd · commit 3bf07a5
-rw-r--r--crates/hir-def/src/body/pretty.rs27
-rw-r--r--crates/hir-ty/src/infer/expr.rs65
-rw-r--r--crates/hir-ty/src/tests/traits.rs31
3 files changed, 52 insertions, 71 deletions
diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs
index de3d995c9a..5a9b825a25 100644
--- a/crates/hir-def/src/body/pretty.rs
+++ b/crates/hir-def/src/body/pretty.rs
@@ -360,8 +360,14 @@ impl<'a> Printer<'a> {
w!(self, "]");
}
Expr::Closure { args, arg_types, ret_type, body, closure_kind } => {
- if let ClosureKind::Generator(Movability::Static) = closure_kind {
- w!(self, "static ");
+ match closure_kind {
+ ClosureKind::Generator(Movability::Static) => {
+ w!(self, "static ");
+ }
+ ClosureKind::Async => {
+ w!(self, "async ");
+ }
+ _ => (),
}
w!(self, "|");
for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
@@ -375,20 +381,9 @@ impl<'a> Printer<'a> {
}
}
w!(self, "|");
- match (ret_type, closure_kind) {
- (Some(ret_ty), ClosureKind::Async) => {
- w!(self, " -> impl Future<Output = ");
- self.print_type_ref(ret_ty);
- w!(self, ">");
- }
- (Some(ret_ty), _) => {
- w!(self, " -> ");
- self.print_type_ref(ret_ty);
- }
- (None, ClosureKind::Async) => {
- w!(self, " -> impl Future<Output = {{unknown}}>");
- }
- (None, _) => {}
+ if let Some(ret_ty) = ret_type {
+ w!(self, " -> ");
+ self.print_type_ref(ret_ty);
}
self.whitespace();
self.print_expr(*body);
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 8113b0bd53..ee186673ee 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -275,7 +275,23 @@ impl<'a> InferenceContext<'a> {
Some(type_ref) => self.make_ty(type_ref),
None => self.table.new_type_var(),
};
- sig_tys.push(ret_ty.clone());
+ if let ClosureKind::Async = closure_kind {
+ // Use the first type parameter as the output type of future.
+ // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
+ let impl_trait_id =
+ crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
+ let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
+ sig_tys.push(
+ TyKind::OpaqueType(
+ opaque_ty_id,
+ Substitution::from1(Interner, ret_ty.clone()),
+ )
+ .intern(Interner),
+ );
+ } else {
+ sig_tys.push(ret_ty.clone());
+ }
+
let sig_ty = TyKind::Function(FnPointer {
num_binders: 0,
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
@@ -286,7 +302,7 @@ impl<'a> InferenceContext<'a> {
})
.intern(Interner);
- let (closure_id, ty, resume_yield_tys) = match closure_kind {
+ let (ty, resume_yield_tys) = match closure_kind {
ClosureKind::Generator(_) => {
// FIXME: report error when there are more than 1 parameter.
let resume_ty = match sig_tys.first() {
@@ -306,9 +322,9 @@ impl<'a> InferenceContext<'a> {
let generator_id = self.db.intern_generator((self.owner, tgt_expr)).into();
let generator_ty = TyKind::Generator(generator_id, subst).intern(Interner);
- (None, generator_ty, Some((resume_ty, yield_ty)))
+ (generator_ty, Some((resume_ty, yield_ty)))
}
- ClosureKind::Async | ClosureKind::Closure => {
+ ClosureKind::Closure | ClosureKind::Async => {
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
let closure_ty = TyKind::Closure(
closure_id,
@@ -316,7 +332,7 @@ impl<'a> InferenceContext<'a> {
)
.intern(Interner);
- (Some(closure_id), closure_ty, None)
+ (closure_ty, None)
}
};
@@ -338,47 +354,16 @@ impl<'a> InferenceContext<'a> {
let prev_resume_yield_tys =
mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
- let (breaks, ()) =
- self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
- this.infer_return(*body);
- });
-
- let inner_ty = if matches!(closure_kind, ClosureKind::Async) {
- // Use the first type parameter as the output type of future.
- // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
- let impl_trait_id =
- crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
- let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
- TyKind::OpaqueType(opaque_ty_id, Substitution::from1(Interner, ret_ty.clone()))
- .intern(Interner)
- } else {
- ret_ty.clone()
- };
+ self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
+ this.infer_return(*body);
+ });
self.diverges = prev_diverges;
self.return_ty = prev_ret_ty;
self.return_coercion = prev_ret_coercion;
self.resume_yield_tys = prev_resume_yield_tys;
- sig_tys.pop();
- sig_tys.push(inner_ty);
-
- let sig_ty = TyKind::Function(FnPointer {
- num_binders: 0,
- sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
- substitution: FnSubst(
- Substitution::from_iter(Interner, sig_tys.clone()).shifted_in(Interner),
- ),
- })
- .intern(Interner);
-
- match closure_id {
- Some(closure_id) => {
- TyKind::Closure(closure_id, Substitution::from1(Interner, sig_ty.clone()))
- .intern(Interner)
- }
- None => ty,
- }
+ ty
}
Expr::Call { callee, args, .. } => {
let callee_ty = self.infer_expr(*callee, &Expectation::none());
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 4e9b1611fb..da76d7fd83 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -533,29 +533,30 @@ fn tuple_struct_with_fn() {
r#"
struct S(fn(u32) -> u64);
fn test() -> u64 {
- let a = S(|i| 2*i);
+ let a = S(|i| 2*i as u64);
let b = a.0(4);
a.0(2)
}"#,
expect![[r#"
- 43..101 '{ ...0(2) }': u64
+ 43..108 '{ ...0(2) }': u64
53..54 'a': S
57..58 'S': S(fn(u32) -> u64) -> S
- 57..67 'S(|i| 2*i)': S
- 59..66 '|i| 2*i': |u32| -> u64
+ 57..74 'S(|i| ...s u64)': S
+ 59..73 '|i| 2*i as u64': |u32| -> u64
60..61 'i': u32
- 63..64 '2': u32
- 63..66 '2*i': u32
+ 63..64 '2': u64
+ 63..73 '2*i as u64': u64
65..66 'i': u32
- 77..78 'b': u64
- 81..82 'a': S
- 81..84 'a.0': fn(u32) -> u64
- 81..87 'a.0(4)': u64
- 85..86 '4': u32
- 93..94 'a': S
- 93..96 'a.0': fn(u32) -> u64
- 93..99 'a.0(2)': u64
- 97..98 '2': u32
+ 65..73 'i as u64': u64
+ 84..85 'b': u64
+ 88..89 'a': S
+ 88..91 'a.0': fn(u32) -> u64
+ 88..94 'a.0(4)': u64
+ 92..93 '4': u32
+ 100..101 'a': S
+ 100..103 'a.0': fn(u32) -> u64
+ 100..106 'a.0(2)': u64
+ 104..105 '2': u32
"#]],
);
}