@@ -26,6 +26,7 @@ use rustc::lint;
26
26
use rustc_errors:: DiagnosticBuilder ;
27
27
28
28
use rustc:: hir:: def:: * ;
29
+ use rustc:: hir:: def_id:: DefId ;
29
30
use rustc:: hir:: intravisit:: { self , Visitor , FnKind , NestedVisitorMap } ;
30
31
use rustc:: hir:: { self , Pat , PatKind } ;
31
32
@@ -48,21 +49,59 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
48
49
49
50
let def_id = self . tcx . hir . local_def_id ( id) ;
50
51
51
- MatchVisitor {
52
- tcx : self . tcx ,
53
- tables : self . tcx . body_tables ( b) ,
54
- region_scope_tree : & self . tcx . region_scope_tree ( def_id) ,
55
- param_env : self . tcx . param_env ( def_id) ,
56
- identity_substs : Substs :: identity_for_item ( self . tcx , def_id) ,
57
- } . visit_body ( self . tcx . hir . body ( b) ) ;
52
+ check_body ( self . tcx , def_id, b) ;
58
53
}
54
+
55
+ fn visit_item ( & mut self , item : & ' tcx hir:: Item ) {
56
+ intravisit:: walk_item ( self , item) ;
57
+ match item. node {
58
+ hir:: ItemStatic ( .., body_id) | hir:: ItemConst ( .., body_id) => {
59
+ let def_id = self . tcx . hir . local_def_id ( item. id ) ;
60
+ check_body ( self . tcx , def_id, body_id) ;
61
+ }
62
+ _ => ( ) ,
63
+ }
64
+ }
65
+
66
+ fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem ) {
67
+ intravisit:: walk_impl_item ( self , ii) ;
68
+ if let hir:: ImplItemKind :: Const ( _, body_id) = ii. node {
69
+ let def_id = self . tcx . hir . local_def_id ( ii. id ) ;
70
+ check_body ( self . tcx , def_id, body_id) ;
71
+ }
72
+ }
73
+
74
+ fn visit_trait_item ( & mut self , ti : & ' tcx hir:: TraitItem ) {
75
+ intravisit:: walk_trait_item ( self , ti) ;
76
+ if let hir:: TraitItemKind :: Const ( _, Some ( body_id) ) = ti. node {
77
+ let def_id = self . tcx . hir . local_def_id ( ti. id ) ;
78
+ check_body ( self . tcx , def_id, body_id) ;
79
+ }
80
+ }
81
+
82
+ // Enum variants and types (e.g. `[T; { .. }]`) may have bodies too,
83
+ // but they are const-evaluated during typeck.
59
84
}
60
85
61
86
pub fn check_crate < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
62
87
tcx. hir . krate ( ) . visit_all_item_likes ( & mut OuterVisitor { tcx : tcx } . as_deep_visitor ( ) ) ;
63
88
tcx. sess . abort_if_errors ( ) ;
64
89
}
65
90
91
+ pub ( crate ) fn check_body < ' a , ' tcx > (
92
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
93
+ def_id : DefId ,
94
+ body_id : hir:: BodyId ,
95
+ ) {
96
+ MatchVisitor {
97
+ tcx,
98
+ tables : tcx. body_tables ( body_id) ,
99
+ region_scope_tree : & tcx. region_scope_tree ( def_id) ,
100
+ param_env : tcx. param_env ( def_id) ,
101
+ identity_substs : Substs :: identity_for_item ( tcx, def_id) ,
102
+ } . visit_body ( tcx. hir . body ( body_id) ) ;
103
+ }
104
+
66
105
fn create_e0004 < ' a > ( sess : & ' a Session , sp : Span , error_message : String ) -> DiagnosticBuilder < ' a > {
67
106
struct_span_err ! ( sess, sp, E0004 , "{}" , & error_message)
68
107
}
0 commit comments