@@ -13,6 +13,7 @@ use rustc_hir as hir;
13
13
use rustc_hir:: def_id:: LocalDefId ;
14
14
use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
15
15
use rustc_middle:: hir:: map:: Map ;
16
+ use rustc_middle:: ty;
16
17
use rustc_middle:: ty:: query:: Providers ;
17
18
use rustc_middle:: ty:: TyCtxt ;
18
19
use rustc_session:: parse:: feature_err;
@@ -59,12 +60,70 @@ impl NonConstExpr {
59
60
fn check_mod_const_bodies ( tcx : TyCtxt < ' _ > , module_def_id : LocalDefId ) {
60
61
let mut vis = CheckConstVisitor :: new ( tcx) ;
61
62
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
+ }
62
66
}
63
67
64
68
pub ( crate ) fn provide ( providers : & mut Providers ) {
65
69
* providers = Providers { check_mod_const_bodies, ..* providers } ;
66
70
}
67
71
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
+
68
127
#[ derive( Copy , Clone ) ]
69
128
struct CheckConstVisitor < ' tcx > {
70
129
tcx : TyCtxt < ' tcx > ,
0 commit comments