@@ -2095,35 +2095,74 @@ pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>;
20952095
20962096/// Trait for contexts that can compute layouts of types.
20972097pub trait LayoutOf < ' tcx > : HasDataLayout + HasTyCtxt < ' tcx > + HasParamEnv < ' tcx > {
2098+ /// The `TyAndLayout`-wrapping type (or `TyAndLayout` itself), which will be
2099+ /// returned from `layout_of` (see also `handle_layout_err`).
20982100 type LayoutOfResult : MaybeResult < TyAndLayout < ' tcx > > ;
20992101
2100- fn layout_of ( & self , ty : Ty < ' tcx > ) -> Self :: LayoutOfResult ;
2102+ /// `Span` to use for `tcx.at(span)`, from `layout_of`.
2103+ // FIXME(eddyb) perhaps make this mandatory to get contexts to track it better?
2104+ #[ inline]
2105+ fn layout_tcx_at_span ( & self ) -> Span {
2106+ DUMMY_SP
2107+ }
2108+
2109+ /// Helper used for `layout_of`, to adapt `tcx.layout_of(...)` into a
2110+ /// `Self::LayoutOfResult` (which does not need to be a `Result<...>`).
2111+ ///
2112+ /// Most `impl`s, which propagate `LayoutError`s, should simply return `err`,
2113+ /// but this hook allows e.g. codegen to return only `TyAndLayout` from its
2114+ /// `cx.layout_of(...)`, without any `Result<...>` around it to deal with
2115+ /// (and any `LayoutError`s are turned into fatal errors or ICEs).
2116+ fn handle_layout_err (
2117+ & self ,
2118+ err : LayoutError < ' tcx > ,
2119+ span : Span ,
2120+ ty : Ty < ' tcx > ,
2121+ ) -> <Self :: LayoutOfResult as MaybeResult < TyAndLayout < ' tcx > > >:: Error ;
2122+
2123+ /// Computes the layout of a type. Note that this implicitly
2124+ /// executes in "reveal all" mode, and will normalize the input type.
2125+ #[ inline]
2126+ fn layout_of ( & self , ty : Ty < ' tcx > ) -> Self :: LayoutOfResult {
2127+ self . spanned_layout_of ( ty, DUMMY_SP )
2128+ }
2129+
2130+ /// Computes the layout of a type, at `span`. Note that this implicitly
2131+ /// executes in "reveal all" mode, and will normalize the input type.
21012132 // FIXME(eddyb) avoid passing information like this, and instead add more
21022133 // `TyCtxt::at`-like APIs to be able to do e.g. `cx.at(span).layout_of(ty)`.
2103- fn spanned_layout_of ( & self , ty : Ty < ' tcx > , _span : Span ) -> Self :: LayoutOfResult {
2104- self . layout_of ( ty)
2134+ #[ inline]
2135+ fn spanned_layout_of ( & self , ty : Ty < ' tcx > , span : Span ) -> Self :: LayoutOfResult {
2136+ let span = if !span. is_dummy ( ) { span } else { self . layout_tcx_at_span ( ) } ;
2137+ MaybeResult :: from (
2138+ self . tcx ( )
2139+ . at ( span)
2140+ . layout_of ( self . param_env ( ) . and ( ty) )
2141+ . map_err ( |err| self . handle_layout_err ( err, span, ty) ) ,
2142+ )
21052143 }
21062144}
21072145
21082146impl LayoutOf < ' tcx > for LayoutCx < ' tcx , TyCtxt < ' tcx > > {
21092147 type LayoutOfResult = Result < TyAndLayout < ' tcx > , LayoutError < ' tcx > > ;
21102148
2111- /// Computes the layout of a type. Note that this implicitly
2112- /// executes in "reveal all" mode, and will normalize the input type.
21132149 #[ inline]
2114- fn layout_of ( & self , ty : Ty < ' tcx > ) -> Self :: LayoutOfResult {
2115- self . tcx . layout_of ( self . param_env . and ( ty ) )
2150+ fn handle_layout_err ( & self , err : LayoutError < ' tcx > , _ : Span , _ : Ty < ' tcx > ) -> LayoutError < ' tcx > {
2151+ err
21162152 }
21172153}
21182154
21192155impl LayoutOf < ' tcx > for LayoutCx < ' tcx , ty:: query:: TyCtxtAt < ' tcx > > {
21202156 type LayoutOfResult = Result < TyAndLayout < ' tcx > , LayoutError < ' tcx > > ;
21212157
2122- /// Computes the layout of a type. Note that this implicitly
2123- /// executes in "reveal all" mode, and will normalize the input type.
21242158 #[ inline]
2125- fn layout_of ( & self , ty : Ty < ' tcx > ) -> Self :: LayoutOfResult {
2126- self . tcx . layout_of ( self . param_env . and ( ty) )
2159+ fn layout_tcx_at_span ( & self ) -> Span {
2160+ self . tcx . span
2161+ }
2162+
2163+ #[ inline]
2164+ fn handle_layout_err ( & self , err : LayoutError < ' tcx > , _: Span , _: Ty < ' tcx > ) -> LayoutError < ' tcx > {
2165+ err
21272166 }
21282167}
21292168
0 commit comments