Skip to content

Commit dfaf6ac

Browse files
Represent async blocks as TyKind::Coroutine, not as opaques
1 parent 9061bd3 commit dfaf6ac

File tree

9 files changed

+94
-197
lines changed

9 files changed

+94
-197
lines changed

crates/hir-ty/src/display.rs

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use triomphe::Arc;
4848

4949
use crate::{
5050
CallableDefId, FnAbi, ImplTraitId, MemoryMap, TraitEnvironment, consteval,
51-
db::{HirDatabase, InternedClosure},
51+
db::{HirDatabase, InternedClosure, InternedCoroutine},
5252
generics::generics,
5353
layout::Layout,
5454
mir::pad16,
@@ -1389,33 +1389,6 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
13891389
SizedByDefault::Sized { anchor: krate },
13901390
)?;
13911391
}
1392-
ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => {
1393-
let future_trait =
1394-
LangItem::Future.resolve_trait(db, body.module(db).krate());
1395-
let output = future_trait.and_then(|t| {
1396-
t.trait_items(db)
1397-
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
1398-
});
1399-
write!(f, "impl ")?;
1400-
if let Some(t) = future_trait {
1401-
f.start_location_link(t.into());
1402-
}
1403-
write!(f, "Future")?;
1404-
if future_trait.is_some() {
1405-
f.end_location_link();
1406-
}
1407-
write!(f, "<")?;
1408-
if let Some(t) = output {
1409-
f.start_location_link(t.into());
1410-
}
1411-
write!(f, "Output")?;
1412-
if output.is_some() {
1413-
f.end_location_link();
1414-
}
1415-
write!(f, " = ")?;
1416-
alias_ty.args.type_at(0).hir_fmt(f)?;
1417-
write!(f, ">")?;
1418-
}
14191392
}
14201393
}
14211394
TyKind::Closure(id, substs) => {
@@ -1567,23 +1540,56 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
15671540
}
15681541
}
15691542
TyKind::Infer(..) => write!(f, "_")?,
1570-
TyKind::Coroutine(_, subst) => {
1571-
if f.display_kind.is_source_code() {
1572-
return Err(HirDisplayError::DisplaySourceCodeError(
1573-
DisplaySourceCodeError::Coroutine,
1574-
));
1575-
}
1543+
TyKind::Coroutine(coroutine_id, subst) => {
1544+
let InternedCoroutine(owner, expr_id) = coroutine_id.0.loc(db);
15761545
let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } =
15771546
subst.split_coroutine_args();
1578-
write!(f, "|")?;
1579-
resume_ty.hir_fmt(f)?;
1580-
write!(f, "|")?;
1547+
let body = db.body(owner);
1548+
match &body[expr_id] {
1549+
hir_def::hir::Expr::Async { .. } => {
1550+
let future_trait =
1551+
LangItem::Future.resolve_trait(db, owner.module(db).krate());
1552+
let output = future_trait.and_then(|t| {
1553+
t.trait_items(db)
1554+
.associated_type_by_name(&Name::new_symbol_root(sym::Output))
1555+
});
1556+
write!(f, "impl ")?;
1557+
if let Some(t) = future_trait {
1558+
f.start_location_link(t.into());
1559+
}
1560+
write!(f, "Future")?;
1561+
if future_trait.is_some() {
1562+
f.end_location_link();
1563+
}
1564+
write!(f, "<")?;
1565+
if let Some(t) = output {
1566+
f.start_location_link(t.into());
1567+
}
1568+
write!(f, "Output")?;
1569+
if output.is_some() {
1570+
f.end_location_link();
1571+
}
1572+
write!(f, " = ")?;
1573+
return_ty.hir_fmt(f)?;
1574+
write!(f, ">")?;
1575+
}
1576+
_ => {
1577+
if f.display_kind.is_source_code() {
1578+
return Err(HirDisplayError::DisplaySourceCodeError(
1579+
DisplaySourceCodeError::Coroutine,
1580+
));
1581+
}
1582+
write!(f, "|")?;
1583+
resume_ty.hir_fmt(f)?;
1584+
write!(f, "|")?;
15811585

1582-
write!(f, " yields ")?;
1583-
yield_ty.hir_fmt(f)?;
1586+
write!(f, " yields ")?;
1587+
yield_ty.hir_fmt(f)?;
15841588

1585-
write!(f, " -> ")?;
1586-
return_ty.hir_fmt(f)?;
1589+
write!(f, " -> ")?;
1590+
return_ty.hir_fmt(f)?;
1591+
}
1592+
}
15871593
}
15881594
TyKind::CoroutineWitness(..) => write!(f, "{{coroutine witness}}")?,
15891595
TyKind::Pat(_, _) => write!(f, "{{pat}}")?,

crates/hir-ty/src/infer.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,6 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
12431243
}
12441244
(self.db.type_alias_impl_traits(def), idx)
12451245
}
1246-
_ => unreachable!(),
12471246
};
12481247
let Some(impl_traits) = impl_traits else {
12491248
return ty;

crates/hir-ty/src/infer/expr.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use hir_expand::name::Name;
1818
use intern::sym;
1919
use rustc_ast_ir::Mutability;
2020
use rustc_type_ir::{
21-
AliasTyKind, InferTy, Interner,
21+
CoroutineArgs, CoroutineArgsParts, InferTy, Interner,
2222
inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _},
2323
};
2424
use syntax::ast::RangeOp;
@@ -29,6 +29,7 @@ use crate::{
2929
IncorrectGenericsLenKind, Rawness, TraitEnvironment,
3030
autoderef::overloaded_deref_ty,
3131
consteval,
32+
db::InternedCoroutine,
3233
generics::generics,
3334
infer::{
3435
AllowTwoPhase, BreakableKind,
@@ -43,7 +44,7 @@ use crate::{
4344
},
4445
method_resolution::{self, VisibleFromModule},
4546
next_solver::{
46-
AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, TraitRef, Ty, TyKind,
47+
Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, TraitRef, Ty, TyKind,
4748
TypeError,
4849
infer::{
4950
InferOk,
@@ -1132,18 +1133,26 @@ impl<'db> InferenceContext<'_, 'db> {
11321133
inner_ty: Ty<'db>,
11331134
tgt_expr: ExprId,
11341135
) -> Ty<'db> {
1135-
// Use the first type parameter as the output type of future.
1136-
// existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
1137-
let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, tgt_expr);
1138-
let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
1139-
Ty::new_alias(
1136+
let coroutine_id = InternedCoroutine(self.owner, tgt_expr);
1137+
let coroutine_id = self.db.intern_coroutine(coroutine_id).into();
1138+
let parent_args = GenericArgs::identity_for_item(self.interner(), self.generic_def.into());
1139+
Ty::new_coroutine(
11401140
self.interner(),
1141-
AliasTyKind::Opaque,
1142-
AliasTy::new(
1141+
coroutine_id,
1142+
CoroutineArgs::new(
11431143
self.interner(),
1144-
opaque_ty_id,
1145-
GenericArgs::new_from_iter(self.interner(), [inner_ty.into()]),
1146-
),
1144+
CoroutineArgsParts {
1145+
parent_args,
1146+
kind_ty: self.types.unit,
1147+
// rustc uses a special lang item type for the resume ty. I don't believe this can cause us problems.
1148+
resume_ty: self.types.unit,
1149+
yield_ty: self.types.unit,
1150+
return_ty: inner_ty,
1151+
// FIXME: Infer upvars.
1152+
tupled_upvars_ty: self.types.unit,
1153+
},
1154+
)
1155+
.args,
11471156
)
11481157
}
11491158

crates/hir-ty/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ mod variance;
5353

5454
use std::hash::Hash;
5555

56-
use hir_def::{CallableDefId, TypeOrConstParamId, hir::ExprId, type_ref::Rawness};
56+
use hir_def::{CallableDefId, TypeOrConstParamId, type_ref::Rawness};
5757
use hir_expand::name::Name;
5858
use indexmap::{IndexMap, map::Entry};
5959
use intern::{Symbol, sym};
@@ -334,7 +334,6 @@ impl FnAbi {
334334
pub enum ImplTraitId<'db> {
335335
ReturnTypeImplTrait(hir_def::FunctionId, next_solver::ImplTraitIdx<'db>),
336336
TypeAliasImplTrait(hir_def::TypeAliasId, next_solver::ImplTraitIdx<'db>),
337-
AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
338337
}
339338

340339
/// 'Canonicalizes' the `t` by replacing any errors with new variables. Also

crates/hir-ty/src/next_solver/generic_arg.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,6 @@ impl<'db> rustc_type_ir::inherent::GenericArgs<DbInterner<'db>> for GenericArgs<
446446
signature_parts_ty,
447447
tupled_upvars_ty,
448448
coroutine_captures_by_ref_ty,
449-
_coroutine_witness_ty,
450449
] => rustc_type_ir::CoroutineClosureArgsParts {
451450
parent_args: GenericArgs::new_from_iter(
452451
DbInterner::conjure(),

crates/hir-ty/src/next_solver/generics.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
33
use hir_def::{
44
ConstParamId, GenericDefId, GenericParamId, LifetimeParamId, TypeOrConstParamId, TypeParamId,
5-
hir::generics::{
6-
GenericParams, LocalTypeOrConstParamId, TypeOrConstParamData, TypeParamData,
7-
TypeParamProvenance,
8-
},
5+
hir::generics::{GenericParams, TypeOrConstParamData},
96
};
107

118
use crate::{db::HirDatabase, generics::parent_generic_def};
@@ -67,27 +64,6 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
6764
crate::ImplTraitId::TypeAliasImplTrait(type_alias_id, _) => {
6865
(Some(type_alias_id.into()), Vec::new())
6966
}
70-
crate::ImplTraitId::AsyncBlockTypeImplTrait(_def, _) => {
71-
let param = TypeOrConstParamData::TypeParamData(TypeParamData {
72-
name: None,
73-
default: None,
74-
provenance: TypeParamProvenance::TypeParamList,
75-
});
76-
// Yes, there is a parent but we don't include it in the generics
77-
// FIXME: It seems utterly sensitive to fake a generic param here.
78-
// Also, what a horrible mess!
79-
(
80-
None,
81-
vec![mk_ty(
82-
GenericDefId::FunctionId(salsa::plumbing::FromId::from_id(unsafe {
83-
salsa::Id::from_index(salsa::Id::MAX_U32 - 1)
84-
})),
85-
0,
86-
LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)),
87-
&param,
88-
)],
89-
)
90-
}
9167
}
9268
}
9369
_ => panic!("No generics for {def:?}"),

crates/hir-ty/src/next_solver/interner.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,8 +1884,7 @@ impl<'db> Interner for DbInterner<'db> {
18841884
let infer = self.db().infer(func.into());
18851885
EarlyBinder::bind(infer.type_of_rpit[idx])
18861886
}
1887-
crate::ImplTraitId::TypeAliasImplTrait(..)
1888-
| crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
1887+
crate::ImplTraitId::TypeAliasImplTrait(..) => {
18891888
// FIXME(next-solver)
18901889
EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed))
18911890
}

crates/hir-ty/src/next_solver/ty.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_type_ir::{
2626

2727
use crate::{
2828
ImplTraitId,
29-
db::HirDatabase,
29+
db::{HirDatabase, InternedCoroutine},
3030
next_solver::{
3131
AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
3232
CoroutineIdWrapper, FnSig, GenericArg, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper,
@@ -546,23 +546,6 @@ impl<'db> Ty<'db> {
546546
.collect()
547547
})
548548
}
549-
ImplTraitId::AsyncBlockTypeImplTrait(def, _) => {
550-
let krate = def.module(db).krate();
551-
if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
552-
// This is only used by type walking.
553-
// Parameters will be walked outside, and projection predicate is not used.
554-
// So just provide the Future trait.
555-
let impl_bound = TraitRef::new(
556-
interner,
557-
future_trait.into(),
558-
GenericArgs::new_from_iter(interner, []),
559-
)
560-
.upcast(interner);
561-
Some(vec![impl_bound])
562-
} else {
563-
None
564-
}
565-
}
566549
}
567550
}
568551
TyKind::Param(param) => {
@@ -592,6 +575,24 @@ impl<'db> Ty<'db> {
592575
_ => None,
593576
}
594577
}
578+
TyKind::Coroutine(coroutine_id, _args) => {
579+
let InternedCoroutine(owner, _) = coroutine_id.0.loc(db);
580+
let krate = owner.module(db).krate();
581+
if let Some(future_trait) = LangItem::Future.resolve_trait(db, krate) {
582+
// This is only used by type walking.
583+
// Parameters will be walked outside, and projection predicate is not used.
584+
// So just provide the Future trait.
585+
let impl_bound = TraitRef::new(
586+
interner,
587+
future_trait.into(),
588+
GenericArgs::new_from_iter(interner, []),
589+
)
590+
.upcast(interner);
591+
Some(vec![impl_bound])
592+
} else {
593+
None
594+
}
595+
}
595596
_ => None,
596597
}
597598
}

0 commit comments

Comments
 (0)