@@ -2,11 +2,13 @@ use rustc_ast::Attribute;
2
2
use rustc_hir:: def:: DefKind ;
3
3
use rustc_hir:: def_id:: LocalDefId ;
4
4
use 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 } ;
6
6
use rustc_span:: source_map:: Spanned ;
7
7
use rustc_span:: symbol:: sym;
8
8
use rustc_span:: Span ;
9
9
use rustc_target:: abi:: { HasDataLayout , TargetDataLayout } ;
10
+ use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
11
+ use rustc_trait_selection:: { infer:: TyCtxtInferExt , traits} ;
10
12
11
13
use crate :: errors:: {
12
14
LayoutAbi , LayoutAlign , LayoutHomogeneousAggregate , LayoutInvalidAttribute , LayoutOf ,
@@ -40,9 +42,39 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
40
42
}
41
43
}
42
44
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
+
43
71
fn dump_layout_of ( tcx : TyCtxt < ' _ > , item_def_id : LocalDefId , attr : & Attribute ) {
44
72
let param_env = tcx. param_env ( item_def_id) ;
45
73
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
+ }
46
78
match tcx. layout_of ( param_env. and ( ty) ) {
47
79
Ok ( ty_layout) => {
48
80
// 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) {
51
83
for meta_item in meta_items {
52
84
match meta_item. name_or_empty ( ) {
53
85
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) } ) ;
58
87
}
59
88
60
89
sym:: align => {
61
90
tcx. sess . emit_err ( LayoutAlign {
62
- span : tcx . def_span ( item_def_id . to_def_id ( ) ) ,
91
+ span,
63
92
align : format ! ( "{:?}" , ty_layout. align) ,
64
93
} ) ;
65
94
}
66
95
67
96
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) } ) ;
72
99
}
73
100
74
101
sym:: homogeneous_aggregate => {
75
102
tcx. sess . emit_err ( LayoutHomogeneousAggregate {
76
- span : tcx . def_span ( item_def_id . to_def_id ( ) ) ,
103
+ span,
77
104
homogeneous_aggregate : format ! (
78
105
"{:?}" ,
79
106
ty_layout. homogeneous_aggregate( & UnwrapLayoutCx { tcx, param_env } )
@@ -90,11 +117,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
90
117
)
91
118
) ;
92
119
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 } ) ;
98
121
}
99
122
100
123
name => {
@@ -105,11 +128,7 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
105
128
}
106
129
107
130
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 } ) ;
113
132
}
114
133
}
115
134
}
0 commit comments