diff options
Diffstat (limited to 'compiler/rustc_passes/src/layout_test.rs')
| -rw-r--r-- | compiler/rustc_passes/src/layout_test.rs | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index f3c12e0746d..6dacac150d3 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -2,11 +2,13 @@ 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::{ LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf, @@ -40,9 +42,39 @@ pub fn test_layout(tcx: TyCtxt<'_>) { } } +pub fn ensure_wf<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ty: Ty<'tcx>, + span: Span, +) -> bool { + let pred = ty::ClauseKind::WellFormed(ty.into()); + let obligation = traits::Obligation::new( + tcx, + traits::ObligationCause::dummy_with_span(span), + 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, span) { + return; + } match tcx.layout_of(param_env.and(ty)) { Ok(ty_layout) => { // Check out the `#[rustc_layout(..)]` attribute to tell what to dump. @@ -51,29 +83,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(LayoutAbi { - 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(LayoutAlign { - span: tcx.def_span(item_def_id.to_def_id()), + span, align: format!("{:?}", ty_layout.align), }); } sym::size => { - tcx.sess.emit_err(LayoutSize { - 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(LayoutHomogeneousAggregate { - span: tcx.def_span(item_def_id.to_def_id()), + span, homogeneous_aggregate: format!( "{:?}", ty_layout.homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env }) @@ -90,11 +117,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { ) ); 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 => { @@ -105,11 +128,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 }); } } } |
