88//! through, but errors for structured control flow in a `const` should be emitted here.
99
1010use rustc_attr as attr;
11- use rustc_data_structures:: stable_set:: FxHashSet ;
1211use rustc_errors:: struct_span_err;
1312use rustc_hir as hir;
1413use rustc_hir:: def_id:: LocalDefId ;
@@ -83,30 +82,39 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor<
8382 let _: Option < _ > = try {
8483 if let hir:: ItemKind :: Impl ( ref imp) = item. kind {
8584 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+ {
9095 if let ty:: AssocItem {
9196 kind : ty:: AssocKind :: Fn , ident, defaultness, ..
92- } = self . tcx . associated_item ( * did )
97+ } = trait_item
9398 {
9499 // we can ignore functions that do not have default bodies:
95100 // 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)
98105 {
99- to_implement . insert ( ident ) ;
106+ continue ;
100107 }
101- }
102- }
103108
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+ }
110118 }
111119
112120 // all nonconst trait functions (not marked with #[default_method_body_is_const])
@@ -118,7 +126,7 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor<
118126 item. span ,
119127 "const trait implementations may not use non-const default functions" ,
120128 )
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( "`, `" ) ) )
122130 . emit ( ) ;
123131 }
124132 }
0 commit comments