@@ -26,6 +26,7 @@ use rustc::lint;
2626use rustc_errors:: DiagnosticBuilder ;
2727
2828use rustc:: hir:: def:: * ;
29+ use rustc:: hir:: def_id:: DefId ;
2930use rustc:: hir:: intravisit:: { self , Visitor , FnKind , NestedVisitorMap } ;
3031use rustc:: hir:: { self , Pat , PatKind } ;
3132
@@ -48,21 +49,59 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
4849
4950 let def_id = self . tcx . hir . local_def_id ( id) ;
5051
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) ;
5853 }
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.
5984}
6085
6186pub fn check_crate < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) {
6287 tcx. hir . krate ( ) . visit_all_item_likes ( & mut OuterVisitor { tcx : tcx } . as_deep_visitor ( ) ) ;
6388 tcx. sess . abort_if_errors ( ) ;
6489}
6590
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+
66105fn create_e0004 < ' a > ( sess : & ' a Session , sp : Span , error_message : String ) -> DiagnosticBuilder < ' a > {
67106 struct_span_err ! ( sess, sp, E0004 , "{}" , & error_message)
68107}
0 commit comments