summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_passes/src/layout_test.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /compiler/rustc_passes/src/layout_test.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_passes/src/layout_test.rs')
-rw-r--r--compiler/rustc_passes/src/layout_test.rs97
1 files changed, 64 insertions, 33 deletions
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index a7a8af864..e195f9ab6 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -2,33 +2,76 @@ use rustc_ast::Attribute;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout};
-use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
+use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
+use rustc_trait_selection::{infer::TyCtxtInferExt, traits};
-use crate::errors::{Abi, Align, HomogeneousAggregate, LayoutOf, Size, UnrecognizedField};
+use crate::errors::{
+ LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
+ LayoutSize, UnrecognizedField,
+};
pub fn test_layout(tcx: TyCtxt<'_>) {
- if tcx.features().rustc_attrs {
+ if !tcx.features().rustc_attrs {
// if the `rustc_attrs` feature is not enabled, don't bother testing layout
- for id in tcx.hir().items() {
- if matches!(
- tcx.def_kind(id.owner_id),
- DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union
- ) {
- for attr in tcx.get_attrs(id.owner_id, sym::rustc_layout) {
- dump_layout_of(tcx, id.owner_id.def_id, attr);
+ return;
+ }
+ for id in tcx.hir_crate_items(()).definitions() {
+ for attr in tcx.get_attrs(id, sym::rustc_layout) {
+ match tcx.def_kind(id) {
+ DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union => {
+ dump_layout_of(tcx, id, attr);
+ }
+ _ => {
+ tcx.sess.emit_err(LayoutInvalidAttribute { span: tcx.def_span(id) });
}
}
}
}
}
+pub fn ensure_wf<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ param_env: ParamEnv<'tcx>,
+ ty: Ty<'tcx>,
+ def_id: LocalDefId,
+ span: Span,
+) -> bool {
+ let pred = ty::ClauseKind::WellFormed(ty.into());
+ let obligation = traits::Obligation::new(
+ tcx,
+ traits::ObligationCause::new(
+ span,
+ def_id,
+ traits::ObligationCauseCode::WellFormed(Some(traits::WellFormedLoc::Ty(def_id))),
+ ),
+ param_env,
+ pred,
+ );
+ let infcx = tcx.infer_ctxt().build();
+ let ocx = traits::ObligationCtxt::new(&infcx);
+ ocx.register_obligation(obligation);
+ let errors = ocx.select_all_or_error();
+ if !errors.is_empty() {
+ infcx.err_ctxt().report_fulfillment_errors(&errors);
+ false
+ } else {
+ // looks WF!
+ true
+ }
+}
+
fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
let param_env = tcx.param_env(item_def_id);
let ty = tcx.type_of(item_def_id).instantiate_identity();
+ let span = tcx.def_span(item_def_id.to_def_id());
+ if !ensure_wf(tcx, param_env, ty, item_def_id, span) {
+ return;
+ }
match tcx.layout_of(param_env.and(ty)) {
Ok(ty_layout) => {
// Check out the `#[rustc_layout(..)]` attribute to tell what to dump.
@@ -37,29 +80,24 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
for meta_item in meta_items {
match meta_item.name_or_empty() {
sym::abi => {
- tcx.sess.emit_err(Abi {
- span: tcx.def_span(item_def_id.to_def_id()),
- abi: format!("{:?}", ty_layout.abi),
- });
+ tcx.sess.emit_err(LayoutAbi { span, abi: format!("{:?}", ty_layout.abi) });
}
sym::align => {
- tcx.sess.emit_err(Align {
- span: tcx.def_span(item_def_id.to_def_id()),
+ tcx.sess.emit_err(LayoutAlign {
+ span,
align: format!("{:?}", ty_layout.align),
});
}
sym::size => {
- tcx.sess.emit_err(Size {
- span: tcx.def_span(item_def_id.to_def_id()),
- size: format!("{:?}", ty_layout.size),
- });
+ tcx.sess
+ .emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) });
}
sym::homogeneous_aggregate => {
- tcx.sess.emit_err(HomogeneousAggregate {
- span: tcx.def_span(item_def_id.to_def_id()),
+ tcx.sess.emit_err(LayoutHomogeneousAggregate {
+ span,
homogeneous_aggregate: format!(
"{:?}",
ty_layout.homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env })
@@ -69,18 +107,15 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
sym::debug => {
let normalized_ty = format!(
- "{:?}",
+ "{}",
tcx.normalize_erasing_regions(
param_env.with_reveal_all_normalized(tcx),
ty,
)
);
+ // FIXME: using the `Debug` impl here isn't ideal.
let ty_layout = format!("{:#?}", *ty_layout);
- tcx.sess.emit_err(LayoutOf {
- span: tcx.def_span(item_def_id.to_def_id()),
- normalized_ty,
- ty_layout,
- });
+ tcx.sess.emit_err(LayoutOf { span, normalized_ty, ty_layout });
}
name => {
@@ -91,11 +126,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
}
Err(layout_error) => {
- tcx.sess.emit_fatal(Spanned {
- node: layout_error.into_diagnostic(),
-
- span: tcx.def_span(item_def_id.to_def_id()),
- });
+ tcx.sess.emit_fatal(Spanned { node: layout_error.into_diagnostic(), span });
}
}
}