8
8
//! through, but errors for structured control flow in a `const` should be emitted here.
9
9
10
10
use rustc_attr as attr;
11
- use rustc_data_structures:: stable_set:: FxHashSet ;
12
11
use rustc_errors:: struct_span_err;
13
12
use rustc_hir as hir;
14
13
use rustc_hir:: def_id:: LocalDefId ;
@@ -83,30 +82,39 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor<
83
82
let _: Option < _ > = try {
84
83
if let hir:: ItemKind :: Impl ( ref imp) = item. kind {
85
84
if let hir:: Constness :: Const = imp. constness {
86
- let did = imp. of_trait . as_ref ( ) ?. trait_def_id ( ) ?;
87
- let mut to_implement = FxHashSet :: default ( ) ;
88
-
89
- for did in self . tcx . associated_item_def_ids ( did) {
85
+ let trait_def_id = imp. of_trait . as_ref ( ) ?. trait_def_id ( ) ?;
86
+ let ancestors = self
87
+ . tcx
88
+ . trait_def ( trait_def_id)
89
+ . ancestors ( self . tcx , item. def_id . to_def_id ( ) )
90
+ . ok ( ) ?;
91
+ let mut to_implement = Vec :: new ( ) ;
92
+
93
+ for trait_item in self . tcx . associated_items ( trait_def_id) . in_definition_order ( )
94
+ {
90
95
if let ty:: AssocItem {
91
96
kind : ty:: AssocKind :: Fn , ident, defaultness, ..
92
- } = self . tcx . associated_item ( * did )
97
+ } = trait_item
93
98
{
94
99
// we can ignore functions that do not have default bodies:
95
100
// if those are unimplemented it will be catched by typeck.
96
- if defaultness. has_value ( )
97
- && !self . tcx . has_attr ( * did, sym:: default_method_body_is_const)
101
+ if !defaultness. has_value ( )
102
+ || self
103
+ . tcx
104
+ . has_attr ( trait_item. def_id , sym:: default_method_body_is_const)
98
105
{
99
- to_implement . insert ( ident ) ;
106
+ continue ;
100
107
}
101
- }
102
- }
103
108
104
- for it in imp
105
- . items
106
- . iter ( )
107
- . filter ( |it| matches ! ( it. kind, hir:: AssocItemKind :: Fn { .. } ) )
108
- {
109
- to_implement. remove ( & it. ident ) ;
109
+ let is_implemented = ancestors
110
+ . leaf_def ( self . tcx , trait_item. ident , trait_item. kind )
111
+ . map ( |node_item| !node_item. defining_node . is_from_trait ( ) )
112
+ . unwrap_or ( false ) ;
113
+
114
+ if !is_implemented {
115
+ to_implement. push ( ident. to_string ( ) ) ;
116
+ }
117
+ }
110
118
}
111
119
112
120
// all nonconst trait functions (not marked with #[default_method_body_is_const])
@@ -118,7 +126,7 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor<
118
126
item. span ,
119
127
"const trait implementations may not use non-const default functions" ,
120
128
)
121
- . note ( & format ! ( "`{}` not implemented" , to_implement. into_iter ( ) . map ( |id| id . to_string ( ) ) . collect :: < Vec <_>> ( ) . join( "`, `" ) ) )
129
+ . note ( & format ! ( "`{}` not implemented" , to_implement. join( "`, `" ) ) )
122
130
. emit ( ) ;
123
131
}
124
132
}
0 commit comments