@@ -2,11 +2,13 @@ use rustc_ast::Attribute;
22use rustc_hir:: def:: DefKind ;
33use rustc_hir:: def_id:: LocalDefId ;
44use rustc_middle:: ty:: layout:: { HasParamEnv , HasTyCtxt , LayoutError , LayoutOfHelpers , TyAndLayout } ;
5- use rustc_middle:: ty:: { ParamEnv , Ty , TyCtxt } ;
5+ use rustc_middle:: ty:: { self , ParamEnv , Ty , TyCtxt } ;
66use rustc_span:: source_map:: Spanned ;
77use rustc_span:: symbol:: sym;
88use rustc_span:: Span ;
99use rustc_target:: abi:: { HasDataLayout , TargetDataLayout } ;
10+ use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
11+ use rustc_trait_selection:: { infer:: TyCtxtInferExt , traits} ;
1012
1113use crate :: errors:: {
1214 LayoutAbi , LayoutAlign , LayoutHomogeneousAggregate , LayoutInvalidAttribute , LayoutOf ,
@@ -40,9 +42,39 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
4042 }
4143}
4244
45+ pub fn ensure_wf < ' tcx > (
46+ tcx : TyCtxt < ' tcx > ,
47+ param_env : ParamEnv < ' tcx > ,
48+ ty : Ty < ' tcx > ,
49+ span : Span ,
50+ ) -> bool {
51+ let pred = ty:: ClauseKind :: WellFormed ( ty. into ( ) ) ;
52+ let obligation = traits:: Obligation :: new (
53+ tcx,
54+ traits:: ObligationCause :: dummy_with_span ( span) ,
55+ param_env,
56+ pred,
57+ ) ;
58+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
59+ let ocx = traits:: ObligationCtxt :: new ( & infcx) ;
60+ ocx. register_obligation ( obligation) ;
61+ let errors = ocx. select_all_or_error ( ) ;
62+ if !errors. is_empty ( ) {
63+ infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) ;
64+ false
65+ } else {
66+ // looks WF!
67+ true
68+ }
69+ }
70+
4371fn dump_layout_of ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId , attr : & Attribute ) {
4472 let param_env = tcx. param_env ( item_def_id) ;
4573 let ty = tcx. type_of ( item_def_id) . instantiate_identity ( ) ;
74+ let span = tcx. def_span ( item_def_id. to_def_id ( ) ) ;
75+ if !ensure_wf ( tcx, param_env, ty, span) {
76+ return ;
77+ }
4678 match tcx. layout_of ( param_env. and ( ty) ) {
4779 Ok ( ty_layout) => {
4880 // 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) {
5183 for meta_item in meta_items {
5284 match meta_item. name_or_empty ( ) {
5385 sym:: abi => {
54- tcx. sess . emit_err ( LayoutAbi {
55- span : tcx. def_span ( item_def_id. to_def_id ( ) ) ,
56- abi : format ! ( "{:?}" , ty_layout. abi) ,
57- } ) ;
86+ tcx. sess . emit_err ( LayoutAbi { span, abi : format ! ( "{:?}" , ty_layout. abi) } ) ;
5887 }
5988
6089 sym:: align => {
6190 tcx. sess . emit_err ( LayoutAlign {
62- span : tcx . def_span ( item_def_id . to_def_id ( ) ) ,
91+ span,
6392 align : format ! ( "{:?}" , ty_layout. align) ,
6493 } ) ;
6594 }
6695
6796 sym:: size => {
68- tcx. sess . emit_err ( LayoutSize {
69- span : tcx. def_span ( item_def_id. to_def_id ( ) ) ,
70- size : format ! ( "{:?}" , ty_layout. size) ,
71- } ) ;
97+ tcx. sess
98+ . emit_err ( LayoutSize { span, size : format ! ( "{:?}" , ty_layout. size) } ) ;
7299 }
73100
74101 sym:: homogeneous_aggregate => {
75102 tcx. sess . emit_err ( LayoutHomogeneousAggregate {
76- span : tcx . def_span ( item_def_id . to_def_id ( ) ) ,
103+ span,
77104 homogeneous_aggregate : format ! (
78105 "{:?}" ,
79106 ty_layout. homogeneous_aggregate( & UnwrapLayoutCx { tcx, param_env } )
@@ -90,11 +117,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
90117 )
91118 ) ;
92119 let ty_layout = format ! ( "{:#?}" , * ty_layout) ;
93- tcx. sess . emit_err ( LayoutOf {
94- span : tcx. def_span ( item_def_id. to_def_id ( ) ) ,
95- normalized_ty,
96- ty_layout,
97- } ) ;
120+ tcx. sess . emit_err ( LayoutOf { span, normalized_ty, ty_layout } ) ;
98121 }
99122
100123 name => {
@@ -105,11 +128,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
105128 }
106129
107130 Err ( layout_error) => {
108- tcx. sess . emit_fatal ( Spanned {
109- node : layout_error. into_diagnostic ( ) ,
110-
111- span : tcx. def_span ( item_def_id. to_def_id ( ) ) ,
112- } ) ;
131+ tcx. sess . emit_fatal ( Spanned { node : layout_error. into_diagnostic ( ) , span } ) ;
113132 }
114133 }
115134}
0 commit comments