@@ -38,7 +38,8 @@ use rustc_apfloat::{
3838use rustc_ast_ir:: FloatTy ;
3939use rustc_hash:: FxHashSet ;
4040use rustc_type_ir:: {
41- AliasTyKind , BoundVarIndexKind , CoroutineArgsParts , RegionKind , Upcast ,
41+ AliasTyKind , BoundVarIndexKind , CoroutineArgsParts , CoroutineClosureArgsParts , RegionKind ,
42+ Upcast ,
4243 inherent:: { AdtDef , GenericArgs as _, IntoKind , SliceLike , Term as _, Ty as _, Tys as _} ,
4344} ;
4445use smallvec:: SmallVec ;
@@ -48,7 +49,7 @@ use triomphe::Arc;
4849
4950use crate :: {
5051 CallableDefId , FnAbi , ImplTraitId , MemoryMap , TraitEnvironment , consteval,
51- db:: { HirDatabase , InternedClosure } ,
52+ db:: { HirDatabase , InternedClosure , InternedCoroutine } ,
5253 generics:: generics,
5354 layout:: Layout ,
5455 mir:: pad16,
@@ -1389,33 +1390,6 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
13891390 SizedByDefault :: Sized { anchor : krate } ,
13901391 ) ?;
13911392 }
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- }
14191393 }
14201394 }
14211395 TyKind :: Closure ( id, substs) => {
@@ -1471,14 +1445,83 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
14711445 }
14721446 if f. closure_style == ClosureStyle :: RANotation || !sig. output ( ) . is_unit ( ) {
14731447 write ! ( f, " -> " ) ?;
1474- // FIXME: We display `AsyncFn` as `-> impl Future`, but this is hard to fix because
1475- // we don't have a trait environment here, required to normalize `<Ret as Future>::Output`.
14761448 sig. output ( ) . hir_fmt ( f) ?;
14771449 }
14781450 } else {
14791451 write ! ( f, "{{closure}}" ) ?;
14801452 }
14811453 }
1454+ TyKind :: CoroutineClosure ( id, args) => {
1455+ let id = id. 0 ;
1456+ if f. display_kind . is_source_code ( ) {
1457+ if !f. display_kind . allows_opaque ( ) {
1458+ return Err ( HirDisplayError :: DisplaySourceCodeError (
1459+ DisplaySourceCodeError :: OpaqueType ,
1460+ ) ) ;
1461+ } else if f. closure_style != ClosureStyle :: ImplFn {
1462+ never ! ( "Only `impl Fn` is valid for displaying closures in source code" ) ;
1463+ }
1464+ }
1465+ match f. closure_style {
1466+ ClosureStyle :: Hide => return write ! ( f, "{TYPE_HINT_TRUNCATION}" ) ,
1467+ ClosureStyle :: ClosureWithId => {
1468+ return write ! (
1469+ f,
1470+ "{{async closure#{:?}}}" ,
1471+ salsa:: plumbing:: AsId :: as_id( & id) . index( )
1472+ ) ;
1473+ }
1474+ ClosureStyle :: ClosureWithSubst => {
1475+ write ! (
1476+ f,
1477+ "{{async closure#{:?}}}" ,
1478+ salsa:: plumbing:: AsId :: as_id( & id) . index( )
1479+ ) ?;
1480+ return hir_fmt_generics ( f, args. as_slice ( ) , None , None ) ;
1481+ }
1482+ _ => ( ) ,
1483+ }
1484+ let CoroutineClosureArgsParts { closure_kind_ty, signature_parts_ty, .. } =
1485+ args. split_coroutine_closure_args ( ) ;
1486+ let kind = closure_kind_ty. to_opt_closure_kind ( ) . unwrap ( ) ;
1487+ let kind = match kind {
1488+ rustc_type_ir:: ClosureKind :: Fn => "AsyncFn" ,
1489+ rustc_type_ir:: ClosureKind :: FnMut => "AsyncFnMut" ,
1490+ rustc_type_ir:: ClosureKind :: FnOnce => "AsyncFnOnce" ,
1491+ } ;
1492+ let TyKind :: FnPtr ( coroutine_sig, _) = signature_parts_ty. kind ( ) else {
1493+ unreachable ! ( "invalid coroutine closure signature" ) ;
1494+ } ;
1495+ let coroutine_sig = coroutine_sig. skip_binder ( ) ;
1496+ let coroutine_inputs = coroutine_sig. inputs ( ) ;
1497+ let TyKind :: Tuple ( coroutine_inputs) = coroutine_inputs. as_slice ( ) [ 1 ] . kind ( ) else {
1498+ unreachable ! ( "invalid coroutine closure signature" ) ;
1499+ } ;
1500+ let TyKind :: Tuple ( coroutine_output) = coroutine_sig. output ( ) . kind ( ) else {
1501+ unreachable ! ( "invalid coroutine closure signature" ) ;
1502+ } ;
1503+ let coroutine_output = coroutine_output. as_slice ( ) [ 1 ] ;
1504+ match f. closure_style {
1505+ ClosureStyle :: ImplFn => write ! ( f, "impl {kind}(" ) ?,
1506+ ClosureStyle :: RANotation => write ! ( f, "async |" ) ?,
1507+ _ => unreachable ! ( ) ,
1508+ }
1509+ if coroutine_inputs. is_empty ( ) {
1510+ } else if f. should_truncate ( ) {
1511+ write ! ( f, "{TYPE_HINT_TRUNCATION}" ) ?;
1512+ } else {
1513+ f. write_joined ( coroutine_inputs, ", " ) ?;
1514+ } ;
1515+ match f. closure_style {
1516+ ClosureStyle :: ImplFn => write ! ( f, ")" ) ?,
1517+ ClosureStyle :: RANotation => write ! ( f, "|" ) ?,
1518+ _ => unreachable ! ( ) ,
1519+ }
1520+ if f. closure_style == ClosureStyle :: RANotation || !coroutine_output. is_unit ( ) {
1521+ write ! ( f, " -> " ) ?;
1522+ coroutine_output. hir_fmt ( f) ?;
1523+ }
1524+ }
14821525 TyKind :: Placeholder ( _) => write ! ( f, "{{placeholder}}" ) ?,
14831526 TyKind :: Param ( param) => {
14841527 // FIXME: We should not access `param.id`, it should be removed, and we should know the
@@ -1567,28 +1610,69 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
15671610 }
15681611 }
15691612 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- }
1613+ TyKind :: Coroutine ( coroutine_id, subst) => {
1614+ let InternedCoroutine ( owner, expr_id) = coroutine_id. 0 . loc ( db) ;
15761615 let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } =
15771616 subst. split_coroutine_args ( ) ;
1578- write ! ( f, "|" ) ?;
1579- resume_ty. hir_fmt ( f) ?;
1580- write ! ( f, "|" ) ?;
1617+ let body = db. body ( owner) ;
1618+ let expr = & body[ expr_id] ;
1619+ match expr {
1620+ hir_def:: hir:: Expr :: Closure {
1621+ closure_kind : hir_def:: hir:: ClosureKind :: Async ,
1622+ ..
1623+ }
1624+ | hir_def:: hir:: Expr :: Async { .. } => {
1625+ let future_trait =
1626+ LangItem :: Future . resolve_trait ( db, owner. module ( db) . krate ( ) ) ;
1627+ let output = future_trait. and_then ( |t| {
1628+ t. trait_items ( db)
1629+ . associated_type_by_name ( & Name :: new_symbol_root ( sym:: Output ) )
1630+ } ) ;
1631+ write ! ( f, "impl " ) ?;
1632+ if let Some ( t) = future_trait {
1633+ f. start_location_link ( t. into ( ) ) ;
1634+ }
1635+ write ! ( f, "Future" ) ?;
1636+ if future_trait. is_some ( ) {
1637+ f. end_location_link ( ) ;
1638+ }
1639+ write ! ( f, "<" ) ?;
1640+ if let Some ( t) = output {
1641+ f. start_location_link ( t. into ( ) ) ;
1642+ }
1643+ write ! ( f, "Output" ) ?;
1644+ if output. is_some ( ) {
1645+ f. end_location_link ( ) ;
1646+ }
1647+ write ! ( f, " = " ) ?;
1648+ return_ty. hir_fmt ( f) ?;
1649+ write ! ( f, ">" ) ?;
1650+ }
1651+ hir_def:: hir:: Expr :: Closure {
1652+ closure_kind : hir_def:: hir:: ClosureKind :: Coroutine ( ..) ,
1653+ ..
1654+ } => {
1655+ if f. display_kind . is_source_code ( ) {
1656+ return Err ( HirDisplayError :: DisplaySourceCodeError (
1657+ DisplaySourceCodeError :: Coroutine ,
1658+ ) ) ;
1659+ }
1660+ write ! ( f, "|" ) ?;
1661+ resume_ty. hir_fmt ( f) ?;
1662+ write ! ( f, "|" ) ?;
15811663
1582- write ! ( f, " yields " ) ?;
1583- yield_ty. hir_fmt ( f) ?;
1664+ write ! ( f, " yields " ) ?;
1665+ yield_ty. hir_fmt ( f) ?;
15841666
1585- write ! ( f, " -> " ) ?;
1586- return_ty. hir_fmt ( f) ?;
1667+ write ! ( f, " -> " ) ?;
1668+ return_ty. hir_fmt ( f) ?;
1669+ }
1670+ _ => panic ! ( "invalid expr for coroutine: {expr:?}" ) ,
1671+ }
15871672 }
15881673 TyKind :: CoroutineWitness ( ..) => write ! ( f, "{{coroutine witness}}" ) ?,
15891674 TyKind :: Pat ( _, _) => write ! ( f, "{{pat}}" ) ?,
15901675 TyKind :: UnsafeBinder ( _) => write ! ( f, "{{unsafe binder}}" ) ?,
1591- TyKind :: CoroutineClosure ( _, _) => write ! ( f, "{{coroutine closure}}" ) ?,
15921676 TyKind :: Alias ( _, _) => write ! ( f, "{{alias}}" ) ?,
15931677 }
15941678 Ok ( ( ) )
0 commit comments