@@ -4,24 +4,49 @@ use rustc_errors::Applicability;
44use rustc_hir as hir;
55use rustc_hir:: ExprKind ;
66use rustc_lint:: LateContext ;
7- use rustc_middle:: ty:: TyS ;
7+ use rustc_middle:: ty:: { TyS , ImplContainer , TraitContainer } ;
8+ use rustc_span:: symbol:: Symbol ;
9+ use rustc_hir:: Expr ;
810
911use super :: OWNED_TO_OWNED ;
12+ use clippy_utils:: is_type_diagnostic_item;
13+
14+ // local for now while I'm massively debugging this
15+ fn match_diagnostic ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , diag_item : Symbol ) -> bool {
16+ let def_id = cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) . unwrap ( ) ;
17+ let associated = cx. tcx . opt_associated_item ( def_id) . and_then ( |associated_item| match associated_item. container {
18+ TraitContainer ( assoc_def_id) => Some ( assoc_def_id) ,
19+ ImplContainer ( assoc_def_id) => Some ( assoc_def_id) ,
20+ } ) ;
21+ if let Some ( assoc_def_id) = associated {
22+ // Except this doesn't work for std::path::Path::to_path_buf as this print returns;
23+ // got associated DefId(1:4405 ~ std[e437]::path::{impl#61}) for DefId(1:4413 ~ std[e437]::path::{impl#61}::to_path_buf) // kind : "std::path::Path"
24+ // obviously def_path_str realizes this is in std::path::Path, but the assoc_id is "std[e437]::path::{impl#61}"
25+ // how do I get from ::{impl#61} to ::Path (which has my diagnostic item)
26+ println ! ( "got associated {:?} for {:?} // kind : {:?}" , assoc_def_id, def_id, cx. tcx. def_path_str( assoc_def_id) ) ;
27+ println ! ( " --- {:?} {}" , cx. tcx. get_diagnostic_item( diag_item) , cx. tcx. get_diagnostic_item( diag_item) == Some ( assoc_def_id) ) ;
28+
29+ cx. tcx . is_diagnostic_item ( diag_item, assoc_def_id)
30+ } else {
31+ println ! ( "got associated NONE for {:?}" , def_id) ;
32+ false
33+ }
34+ }
1035
1136pub fn check (
1237 cx : & LateContext < ' _ > ,
1338 expr : & hir:: Expr < ' _ > ,
14- trait_path : Option < & [ & str ] > ,
15- expected_type_path : Option < & [ & str ] > ,
39+ trait_diagnostic : Symbol ,
40+ expected_type_diagnostic : Option < Symbol > ,
1641) {
1742 if_chain ! {
1843 if let ExprKind :: MethodCall ( method_path, _, [ arg] , _) = & expr. kind;
1944 let return_type = cx. typeck_results( ) . expr_ty( & expr) ;
2045 let input_type = cx. typeck_results( ) . expr_ty( arg) ;
2146 if let Some ( ty_name) = input_type. ty_adt_def( ) . map( |adt_def| cx. tcx. item_name( adt_def. did) ) ;
2247 if TyS :: same_type( return_type, input_type) ;
23- if trait_path . map_or ( true , |path| match_trait_method ( cx, expr, path ) ) &&
24- expected_type_path . map_or( true , |path| match_type ( cx, input_type, path ) ) ;
48+ if match_diagnostic ( cx, expr, trait_diagnostic ) &&
49+ expected_type_diagnostic . map_or( true , |diagnostic| is_type_diagnostic_item ( cx, input_type, diagnostic ) ) ;
2550 then {
2651 span_lint_and_sugg(
2752 cx, OWNED_TO_OWNED , method_path. ident. span,
0 commit comments