@@ -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,20 +1878,26 @@ 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 ///
18831889 /// Takes `coroutine_kind` which can be acquired from the `CoroutineArgs::kind_ty`,
18841890 /// e.g. `args.as_coroutine().kind_ty()`.
18851891 fn ordinary_coroutine_layout (
18861892 self ,
1893+ ty : Ty < ' tcx > ,
18871894 def_id : DefId ,
18881895 coroutine_kind_ty : Ty < ' tcx > ,
1889- ) -> Option < & ' tcx CoroutineLayout < ' tcx > > {
1896+ ) -> Result < & ' tcx CoroutineLayout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
18901897 let mir = self . optimized_mir ( def_id) ;
18911898 // Regular coroutine
18921899 if coroutine_kind_ty. is_unit ( ) {
1893- mir. coroutine_layout_raw ( )
1900+ mir. coroutine_layout_raw ( ) . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty ) ) )
18941901 } else {
18951902 // If we have a `Coroutine` that comes from an coroutine-closure,
18961903 // then it may be a by-move or by-ref body.
@@ -1904,6 +1911,7 @@ impl<'tcx> TyCtxt<'tcx> {
19041911 // a by-ref coroutine.
19051912 if identity_kind_ty == coroutine_kind_ty {
19061913 mir. coroutine_layout_raw ( )
1914+ . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty) ) )
19071915 } else {
19081916 assert_matches ! ( coroutine_kind_ty. to_opt_closure_kind( ) , Some ( ClosureKind :: FnOnce ) ) ;
19091917 assert_matches ! (
@@ -1912,6 +1920,7 @@ impl<'tcx> TyCtxt<'tcx> {
19121920 ) ;
19131921 self . optimized_mir ( self . coroutine_by_move_body_def_id ( def_id) )
19141922 . coroutine_layout_raw ( )
1923+ . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty) ) )
19151924 }
19161925 }
19171926 }
@@ -1921,23 +1930,27 @@ impl<'tcx> TyCtxt<'tcx> {
19211930 /// Layout might be unavailable if the coroutine is tainted by errors.
19221931 fn async_drop_coroutine_layout (
19231932 self ,
1933+ ty : Ty < ' tcx > ,
19241934 def_id : DefId ,
19251935 args : GenericArgsRef < ' tcx > ,
1926- ) -> Option < & ' tcx CoroutineLayout < ' tcx > > {
1936+ ) -> Result < & ' tcx CoroutineLayout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
19271937 if args[ 0 ] . has_placeholders ( ) || args[ 0 ] . has_non_region_param ( ) {
1928- return None ;
1938+ return Err ( self . layout_error ( LayoutError :: TooGeneric ( ty ) ) ) ;
19291939 }
19301940 let instance = InstanceKind :: AsyncDropGlue ( def_id, Ty :: new_coroutine ( self , def_id, args) ) ;
1931- self . mir_shims ( instance) . coroutine_layout_raw ( )
1941+ self . mir_shims ( instance)
1942+ . coroutine_layout_raw ( )
1943+ . ok_or_else ( || self . layout_error ( LayoutError :: Unknown ( ty) ) )
19321944 }
19331945
19341946 /// Returns layout of a coroutine. Layout might be unavailable if the
19351947 /// coroutine is tainted by errors.
19361948 pub fn coroutine_layout (
19371949 self ,
1950+ ty : Ty < ' tcx > ,
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 {
1964- self . async_drop_coroutine_layout ( def_id, args)
1977+ self . async_drop_coroutine_layout ( ty , def_id, args)
19651978 }
19661979 } else {
1967- self . ordinary_coroutine_layout ( def_id, args. as_coroutine ( ) . kind_ty ( ) )
1980+ self . ordinary_coroutine_layout ( ty , def_id, args. as_coroutine ( ) . kind_ty ( ) )
19681981 }
19691982 }
19701983
0 commit comments