@@ -24,7 +24,7 @@ use rustc_hir::{
24
24
use rustc_lint:: { EarlyContext , EarlyLintPass , LateContext , LateLintPass , LintContext } ;
25
25
use rustc_middle:: hir:: nested_filter;
26
26
use rustc_middle:: mir:: interpret:: { Allocation , ConstValue , GlobalAlloc } ;
27
- use rustc_middle:: ty:: { self , AssocKind , Ty } ;
27
+ use rustc_middle:: ty:: { self , AssocKind , DefIdTree , Ty } ;
28
28
use rustc_semver:: RustcVersion ;
29
29
use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass} ;
30
30
use rustc_span:: source_map:: Spanned ;
@@ -905,15 +905,32 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
905
905
return ;
906
906
} ;
907
907
908
+ let has_ctor = match cx. tcx. def_kind( def_id) {
909
+ DefKind :: Struct => {
910
+ let variant = cx. tcx. adt_def( def_id) . non_enum_variant( ) ;
911
+ variant. ctor_def_id. is_some( ) && variant. fields. iter( ) . all( |f| f. vis. is_public( ) )
912
+ }
913
+ DefKind :: Variant =>
914
+ cx. tcx. parent( def_id) . map_or( false , |adt_id| {
915
+ let variant = cx. tcx. adt_def( adt_id) . variant_with_id( def_id) ;
916
+ variant. ctor_def_id. is_some( ) && variant. fields. iter( ) . all( |f| f. vis. is_public( ) )
917
+ } ) ,
918
+ _ => false ,
919
+ } ;
920
+
908
921
let mut app = Applicability :: MachineApplicable ;
909
922
let cx_snip = snippet_with_applicability( cx, cx_arg. span, ".." , & mut app) ;
910
923
let def_snip = snippet_with_applicability( cx, def_arg. span, ".." , & mut app) ;
911
924
let sugg = match ( which_path, item) {
912
925
// match_def_path
926
+ ( 0 , Item :: DiagnosticItem ( item) ) if has_ctor =>
927
+ format!( "is_diagnostic_item_or_ctor({}, {}, sym::{})" , cx_snip, def_snip, item) ,
928
+ ( 0 , Item :: LangItem ( item) ) if has_ctor =>
929
+ format!( "is_lang_item_or_ctor({}, {}, LangItem::{})" , cx_snip, def_snip, item) ,
913
930
( 0 , Item :: DiagnosticItem ( item) ) =>
914
- format!( "is_diagnostic_item({}, {}, sym::{} )" , cx_snip, def_snip , item ) ,
931
+ format!( "{}.tcx. is_diagnostic_item(sym:: {}, {})" , cx_snip, item , def_snip ) ,
915
932
( 0 , Item :: LangItem ( item) ) =>
916
- format!( "is_lang_item({}, {}, LangItem::{})" , cx_snip, def_snip , item ) ,
933
+ format!( "{}.tcx.lang_items().require( LangItem::{}).ok() == Some({}) " , cx_snip, item , def_snip ) ,
917
934
// match_trait_method
918
935
( 1 , Item :: DiagnosticItem ( item) ) =>
919
936
format!( "is_trait_method({}, {}, sym::{})" , cx_snip, def_snip, item) ,
@@ -923,12 +940,24 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
923
940
( 2 , Item :: LangItem ( item) ) =>
924
941
format!( "is_type_lang_item({}, {}, LangItem::{})" , cx_snip, def_snip, item) ,
925
942
// is_expr_path_def_path
943
+ ( 3 , Item :: DiagnosticItem ( item) ) if has_ctor =>
944
+ format!(
945
+ "path_res({}, {}).opt_def_id()\
946
+ .map_or(false, |id| is_diagnostic_item_or_ctor({}, id, sym::{})",
947
+ cx_snip, def_snip, cx_snip, item,
948
+ ) ,
949
+ ( 3 , Item :: LangItem ( item) ) if has_ctor =>
950
+ format!(
951
+ "path_res({}, {}).opt_def_id()\
952
+ .map_or(false, |id| is_lang_item_or_ctor({}, id, LangItem::{})",
953
+ cx_snip, def_snip, cx_snip, item,
954
+ ) ,
926
955
( 3 , Item :: DiagnosticItem ( item) ) =>
927
956
format!( "is_expr_diagnostic_item({}, {}, sym::{})" , cx_snip, def_snip, item) ,
928
957
( 3 , Item :: LangItem ( item) ) =>
929
958
format!(
930
959
"path_res({}, {}).opt_def_id()\
931
- .map_or(false, |id| is_lang_item({}, id, LangItem::{}))",
960
+ .map_or(false, |id| {}.tcx.lang_items().require( LangItem::{}).ok() == Some(id ))",
932
961
cx_snip, def_snip, cx_snip, item,
933
962
) ,
934
963
_ => return ,
0 commit comments