@@ -13,6 +13,7 @@ use rustc_hir as hir;
1313use rustc_hir:: def_id:: LocalDefId ;
1414use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
1515use rustc_middle:: hir:: map:: Map ;
16+ use rustc_middle:: ty;
1617use rustc_middle:: ty:: query:: Providers ;
1718use rustc_middle:: ty:: TyCtxt ;
1819use rustc_session:: parse:: feature_err;
@@ -59,12 +60,70 @@ impl NonConstExpr {
5960fn check_mod_const_bodies ( tcx : TyCtxt < ' _ > , module_def_id : LocalDefId ) {
6061 let mut vis = CheckConstVisitor :: new ( tcx) ;
6162 tcx. hir ( ) . visit_item_likes_in_module ( module_def_id, & mut vis. as_deep_visitor ( ) ) ;
63+ if tcx. features ( ) . enabled ( sym:: const_trait_impl) {
64+ tcx. hir ( ) . visit_item_likes_in_module ( module_def_id, & mut CheckConstTraitVisitor :: new ( tcx) ) ;
65+ }
6266}
6367
6468pub ( crate ) fn provide ( providers : & mut Providers ) {
6569 * providers = Providers { check_mod_const_bodies, ..* providers } ;
6670}
6771
72+ struct CheckConstTraitVisitor < ' tcx > {
73+ tcx : TyCtxt < ' tcx > ,
74+ }
75+
76+ impl < ' tcx > CheckConstTraitVisitor < ' tcx > {
77+ fn new ( tcx : TyCtxt < ' tcx > ) -> Self {
78+ CheckConstTraitVisitor { tcx }
79+ }
80+ }
81+
82+ impl < ' tcx > hir:: itemlikevisit:: ItemLikeVisitor < ' tcx > for CheckConstTraitVisitor < ' tcx > {
83+ fn visit_item ( & mut self , item : & ' hir hir:: Item < ' hir > ) {
84+ let _: Option < _ > = try {
85+ if let hir:: ItemKind :: Impl ( ref imp) = item. kind {
86+ if let hir:: Constness :: Const = imp. constness {
87+ let did = imp. of_trait . as_ref ( ) ?. trait_def_id ( ) ?;
88+ let trait_fn_cnt = self
89+ . tcx
90+ . associated_item_def_ids ( did)
91+ . iter ( )
92+ . filter ( |did| {
93+ matches ! (
94+ self . tcx. associated_item( * * did) ,
95+ ty:: AssocItem { kind: ty:: AssocKind :: Fn , .. }
96+ )
97+ } )
98+ . count ( ) ;
99+
100+ let impl_fn_cnt = imp
101+ . items
102+ . iter ( )
103+ . filter ( |it| matches ! ( it. kind, hir:: AssocItemKind :: Fn { .. } ) )
104+ . count ( ) ;
105+
106+ if trait_fn_cnt != impl_fn_cnt {
107+ self . tcx
108+ . sess
109+ . struct_span_err (
110+ item. span ,
111+ "const trait implementations may not use default functions" ,
112+ )
113+ . emit ( ) ;
114+ }
115+ }
116+ }
117+ } ;
118+ }
119+
120+ fn visit_trait_item ( & mut self , _: & ' hir hir:: TraitItem < ' hir > ) { }
121+
122+ fn visit_impl_item ( & mut self , _: & ' hir hir:: ImplItem < ' hir > ) { }
123+
124+ fn visit_foreign_item ( & mut self , _: & ' hir hir:: ForeignItem < ' hir > ) { }
125+ }
126+
68127#[ derive( Copy , Clone ) ]
69128struct CheckConstVisitor < ' tcx > {
70129 tcx : TyCtxt < ' tcx > ,
0 commit comments