11use crate :: utils:: { is_entrypoint_fn, span_lint} ;
2+ use if_chain:: if_chain;
23use rustc:: hir;
34use rustc:: hir:: intravisit:: FnKind ;
45use rustc:: hir:: { Body , Constness , FnDecl , HirId } ;
5- use rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
6+ use rustc:: lint:: { in_external_macro , LateContext , LateLintPass , LintArray , LintPass } ;
67use rustc:: { declare_tool_lint, lint_array} ;
78use rustc_mir:: transform:: qualify_min_const_fn:: is_min_const_fn;
89use syntax_pos:: Span ;
@@ -82,7 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
8283 ) {
8384 let def_id = cx. tcx . hir ( ) . local_def_id_from_hir_id ( hir_id) ;
8485
85- if is_entrypoint_fn ( cx, def_id) {
86+ if in_external_macro ( cx . tcx . sess , span ) || is_entrypoint_fn ( cx, def_id) {
8687 return ;
8788 }
8889
@@ -95,7 +96,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
9596 }
9697 } ,
9798 FnKind :: Method ( _, sig, ..) => {
98- if already_const ( sig. header ) {
99+ if is_trait_method ( cx , hir_id ) || already_const ( sig. header ) {
99100 return ;
100101 }
101102 } ,
@@ -114,6 +115,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
114115 }
115116}
116117
118+ fn is_trait_method ( cx : & LateContext < ' _ , ' _ > , hir_id : HirId ) -> bool {
119+ // Get the implemented trait for the current function
120+ let parent_impl = cx. tcx . hir ( ) . get_parent_item ( hir_id) ;
121+ if_chain ! {
122+ if parent_impl != hir:: CRATE_HIR_ID ;
123+ if let hir:: Node :: Item ( item) = cx. tcx. hir( ) . get_by_hir_id( parent_impl) ;
124+ if let hir:: ItemKind :: Impl ( _, _, _, _, Some ( _trait_ref) , _, _) = & item. node;
125+ then { return true ; }
126+ }
127+ false
128+ }
129+
117130// We don't have to lint on something that's already `const`
118131fn already_const ( header : hir:: FnHeader ) -> bool {
119132 header. constness == Constness :: Const
0 commit comments