Auto merge of #88499 - eddyb:layout-off, r=nagisa
Provide `layout_of` automatically (given tcx + param_env + error handling). After #88337, there's no longer any uses of `LayoutOf` within `rustc_target` itself, so I realized I could move the trait to `rustc_middle::ty::layout` and redesign it a bit. This is similar to #88338 (and supersedes it), but at no ergonomic loss, since there's no funky `C: LayoutOf<Ty = Ty>` -> `Ty: TyAbiInterface<C>` generic `impl` chain, and each `LayoutOf` still corresponds to one `impl` (of `LayoutOfHelpers`) for the specific context. After this PR, this is what's needed to get `trait LayoutOf` (with the `layout_of` method) implemented on some context type: * `TyCtxt`, via `HasTyCtxt` * `ParamEnv`, via `HasParamEnv` * a way to transform `LayoutError`s into the desired error type * an error type of `!` can be paired with having `cx.layout_of(...)` return `TyAndLayout` *without* `Result<...>` around it, such as used by codegen * this is done through a new `LayoutOfHelpers` trait (and so is specifying the type of `cx.layout_of(...)`) When going through this path (and not bypassing it with a manual `impl` of `LayoutOf`), the end result is that only the error case can be customized, the query itself and the success paths are guaranteed to be uniform. (**EDIT**: just noticed that because of the supertrait relationship, you cannot actually implement `LayoutOf` yourself, the blanket `impl` fully covers all possible context types that could ever implement it) Part of the motivation for this shape of API is that I've been working on querifying `FnAbi::of_*`, and what I want/need to introduce for that looks a lot like the setup in this PR - in particular, it's harder to express the `FnAbi` methods in `rustc_target`, since they're much more tied to `rustc` concepts. r? `@nagisa` cc `@oli-obk` `@bjorn3`
This commit is contained in:
commit
e2750baf53
51 changed files with 253 additions and 218 deletions
|
@ -3,10 +3,11 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_hir::ItemKind;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, TyAndLayout};
|
||||
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout};
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_target::abi::{HasDataLayout, LayoutOf, TargetDataLayout};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
|
||||
|
||||
pub fn test_layout(tcx: TyCtxt<'_>) {
|
||||
if tcx.features().rustc_attrs {
|
||||
|
@ -113,12 +114,16 @@ struct UnwrapLayoutCx<'tcx> {
|
|||
param_env: ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl LayoutOf<'tcx> for UnwrapLayoutCx<'tcx> {
|
||||
type Ty = Ty<'tcx>;
|
||||
type TyAndLayout = TyAndLayout<'tcx>;
|
||||
impl LayoutOfHelpers<'tcx> for UnwrapLayoutCx<'tcx> {
|
||||
type LayoutOfResult = TyAndLayout<'tcx>;
|
||||
|
||||
fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
|
||||
self.tcx.layout_of(self.param_env.and(ty)).unwrap()
|
||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
||||
span_bug!(
|
||||
span,
|
||||
"`#[rustc_layout(..)]` test resulted in `layout_of({}) = Err({})`",
|
||||
ty,
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue