@@ -120,6 +120,7 @@ use crate::ty;
120120use crate :: ty:: codec:: { TyDecoder , TyEncoder } ;
121121pub use crate :: ty:: diagnostics:: * ;
122122use crate :: ty:: fast_reject:: SimplifiedType ;
123+ use crate :: ty:: layout:: LayoutError ;
123124use crate :: ty:: util:: Discr ;
124125use crate :: ty:: walk:: TypeWalker ;
125126
@@ -1877,6 +1878,11 @@ impl<'tcx> TyCtxt<'tcx> {
18771878 self . def_kind ( trait_def_id) == DefKind :: TraitAlias
18781879 }
18791880
1881+ /// Arena-alloc of LayoutError for coroutine layout
1882+ fn layout_error ( self , err : LayoutError < ' tcx > ) -> & ' tcx LayoutError < ' tcx > {
1883+ self . arena . alloc ( err)
1884+ }
1885+
18801886 /// Returns layout of a non-async-drop coroutine. Layout might be unavailable if the
18811887 /// coroutine is tainted by errors.
18821888 ///
@@ -1885,12 +1891,14 @@ impl<'tcx> TyCtxt<'tcx> {
18851891 fn ordinary_coroutine_layout (
18861892 self ,
18871893 def_id : DefId ,
1888- coroutine_kind_ty : Ty < ' tcx > ,
1889- ) -> Option < & ' tcx CoroutineLayout < ' tcx > > {
1894+ args : GenericArgsRef < ' tcx > ,
1895+ ) -> Result < & ' tcx CoroutineLayout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
1896+ let coroutine_kind_ty = args. as_coroutine ( ) . kind_ty ( ) ;
18901897 let mir = self . optimized_mir ( def_id) ;
1898+ let ty = || Ty :: new_coroutine ( self , def_id, args) ;
18911899 // Regular coroutine
18921900 if coroutine_kind_ty. is_unit ( ) {
1893- mir. coroutine_layout_raw ( )
1901+ mir. coroutine_layout_raw ( ) . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty ( ) ) ) )
18941902 } else {
18951903 // If we have a `Coroutine` that comes from an coroutine-closure,
18961904 // then it may be a by-move or by-ref body.
@@ -1904,6 +1912,7 @@ impl<'tcx> TyCtxt<'tcx> {
19041912 // a by-ref coroutine.
19051913 if identity_kind_ty == coroutine_kind_ty {
19061914 mir. coroutine_layout_raw ( )
1915+ . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty ( ) ) ) )
19071916 } else {
19081917 assert_matches ! ( coroutine_kind_ty. to_opt_closure_kind( ) , Some ( ClosureKind :: FnOnce ) ) ;
19091918 assert_matches ! (
@@ -1912,6 +1921,7 @@ impl<'tcx> TyCtxt<'tcx> {
19121921 ) ;
19131922 self . optimized_mir ( self . coroutine_by_move_body_def_id ( def_id) )
19141923 . coroutine_layout_raw ( )
1924+ . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty ( ) ) ) )
19151925 }
19161926 }
19171927 }
@@ -1923,12 +1933,15 @@ impl<'tcx> TyCtxt<'tcx> {
19231933 self ,
19241934 def_id : DefId ,
19251935 args : GenericArgsRef < ' tcx > ,
1926- ) -> Option < & ' tcx CoroutineLayout < ' tcx > > {
1936+ ) -> Result < & ' tcx CoroutineLayout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
1937+ let ty = || Ty :: new_coroutine ( self , def_id, args) ;
19271938 if args[ 0 ] . has_placeholders ( ) || args[ 0 ] . has_non_region_param ( ) {
1928- return None ;
1939+ return Err ( self . layout_error ( LayoutError :: TooGeneric ( ty ( ) ) ) ) ;
19291940 }
19301941 let instance = InstanceKind :: AsyncDropGlue ( def_id, Ty :: new_coroutine ( self , def_id, args) ) ;
1931- self . mir_shims ( instance) . coroutine_layout_raw ( )
1942+ self . mir_shims ( instance)
1943+ . coroutine_layout_raw ( )
1944+ . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty ( ) ) ) )
19321945 }
19331946
19341947 /// Returns layout of a coroutine. Layout might be unavailable if the
@@ -1937,7 +1950,7 @@ impl<'tcx> TyCtxt<'tcx> {
19371950 self ,
19381951 def_id : DefId ,
19391952 args : GenericArgsRef < ' tcx > ,
1940- ) -> Option < & ' tcx CoroutineLayout < ' tcx > > {
1953+ ) -> Result < & ' tcx CoroutineLayout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
19411954 if self . is_async_drop_in_place_coroutine ( def_id) {
19421955 // layout of `async_drop_in_place<T>::{closure}` in case,
19431956 // when T is a coroutine, contains this internal coroutine's ptr in upvars
@@ -1959,12 +1972,12 @@ impl<'tcx> TyCtxt<'tcx> {
19591972 variant_source_info,
19601973 storage_conflicts : BitMatrix :: new ( 0 , 0 ) ,
19611974 } ;
1962- return Some ( self . arena . alloc ( proxy_layout) ) ;
1975+ return Ok ( self . arena . alloc ( proxy_layout) ) ;
19631976 } else {
19641977 self . async_drop_coroutine_layout ( def_id, args)
19651978 }
19661979 } else {
1967- self . ordinary_coroutine_layout ( def_id, args. as_coroutine ( ) . kind_ty ( ) )
1980+ self . ordinary_coroutine_layout ( def_id, args)
19681981 }
19691982 }
19701983
0 commit comments