@@ -25,7 +25,7 @@ use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
25
25
use crate :: middle:: privacy:: AccessLevels ;
26
26
use crate :: rustc_serialize:: { Decoder , Decodable , Encoder , Encodable } ;
27
27
use crate :: session:: { config, early_error, Session } ;
28
- use crate :: ty:: { self , TyCtxt , Ty } ;
28
+ use crate :: ty:: { self , print :: Printer , subst :: Kind , TyCtxt , Ty } ;
29
29
use crate :: ty:: layout:: { LayoutError , LayoutOf , TyLayout } ;
30
30
use crate :: util:: nodemap:: FxHashMap ;
31
31
use crate :: util:: common:: time;
@@ -36,9 +36,10 @@ use syntax::edition;
36
36
use syntax_pos:: { MultiSpan , Span , symbol:: { LocalInternedString , Symbol } } ;
37
37
use errors:: DiagnosticBuilder ;
38
38
use crate :: hir;
39
- use crate :: hir:: def_id:: { DefId , LOCAL_CRATE } ;
39
+ use crate :: hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
40
40
use crate :: hir:: intravisit as hir_visit;
41
41
use crate :: hir:: intravisit:: Visitor ;
42
+ use crate :: hir:: map:: { definitions:: DisambiguatedDefPathData , DefPathData } ;
42
43
use syntax:: util:: lev_distance:: find_best_match_for_name;
43
44
use syntax:: visit as ast_visit;
44
45
@@ -752,6 +753,114 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
752
753
pub fn current_lint_root ( & self ) -> hir:: HirId {
753
754
self . last_node_with_lint_attrs
754
755
}
756
+
757
+ /// Check if a `DefId`'s path matches the given absolute type path usage.
758
+ // Uplifted from rust-lang/rust-clippy
759
+ pub fn match_path ( & self , def_id : DefId , path : & [ & str ] ) -> bool {
760
+ pub struct AbsolutePathPrinter < ' a , ' tcx > {
761
+ pub tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
762
+ }
763
+
764
+ impl < ' tcx > Printer < ' tcx , ' tcx > for AbsolutePathPrinter < ' _ , ' tcx > {
765
+ type Error = !;
766
+
767
+ type Path = Vec < LocalInternedString > ;
768
+ type Region = ( ) ;
769
+ type Type = ( ) ;
770
+ type DynExistential = ( ) ;
771
+
772
+ fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx , ' tcx > {
773
+ self . tcx
774
+ }
775
+
776
+ fn print_region ( self , _region : ty:: Region < ' _ > ) -> Result < Self :: Region , Self :: Error > {
777
+ Ok ( ( ) )
778
+ }
779
+
780
+ fn print_type ( self , _ty : Ty < ' tcx > ) -> Result < Self :: Type , Self :: Error > {
781
+ Ok ( ( ) )
782
+ }
783
+
784
+ fn print_dyn_existential (
785
+ self ,
786
+ _predicates : & ' tcx ty:: List < ty:: ExistentialPredicate < ' tcx > > ,
787
+ ) -> Result < Self :: DynExistential , Self :: Error > {
788
+ Ok ( ( ) )
789
+ }
790
+
791
+ fn path_crate ( self , cnum : CrateNum ) -> Result < Self :: Path , Self :: Error > {
792
+ Ok ( vec ! [ self . tcx. original_crate_name( cnum) . as_str( ) ] )
793
+ }
794
+
795
+ fn path_qualified (
796
+ self ,
797
+ self_ty : Ty < ' tcx > ,
798
+ trait_ref : Option < ty:: TraitRef < ' tcx > > ,
799
+ ) -> Result < Self :: Path , Self :: Error > {
800
+ if trait_ref. is_none ( ) {
801
+ if let ty:: Adt ( def, substs) = self_ty. sty {
802
+ return self . print_def_path ( def. did , substs) ;
803
+ }
804
+ }
805
+
806
+ // This shouldn't ever be needed, but just in case:
807
+ Ok ( vec ! [ match trait_ref {
808
+ Some ( trait_ref) => Symbol :: intern( & format!( "{:?}" , trait_ref) ) . as_str( ) ,
809
+ None => Symbol :: intern( & format!( "<{}>" , self_ty) ) . as_str( ) ,
810
+ } ] )
811
+ }
812
+
813
+ fn path_append_impl (
814
+ self ,
815
+ print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
816
+ _disambiguated_data : & DisambiguatedDefPathData ,
817
+ self_ty : Ty < ' tcx > ,
818
+ trait_ref : Option < ty:: TraitRef < ' tcx > > ,
819
+ ) -> Result < Self :: Path , Self :: Error > {
820
+ let mut path = print_prefix ( self ) ?;
821
+
822
+ // This shouldn't ever be needed, but just in case:
823
+ path. push ( match trait_ref {
824
+ Some ( trait_ref) => {
825
+ Symbol :: intern ( & format ! ( "<impl {} for {}>" , trait_ref, self_ty) ) . as_str ( )
826
+ } ,
827
+ None => Symbol :: intern ( & format ! ( "<impl {}>" , self_ty) ) . as_str ( ) ,
828
+ } ) ;
829
+
830
+ Ok ( path)
831
+ }
832
+
833
+ fn path_append (
834
+ self ,
835
+ print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
836
+ disambiguated_data : & DisambiguatedDefPathData ,
837
+ ) -> Result < Self :: Path , Self :: Error > {
838
+ let mut path = print_prefix ( self ) ?;
839
+
840
+ // Skip `::{{constructor}}` on tuple/unit structs.
841
+ match disambiguated_data. data {
842
+ DefPathData :: Ctor => return Ok ( path) ,
843
+ _ => { }
844
+ }
845
+
846
+ path. push ( disambiguated_data. data . as_interned_str ( ) . as_str ( ) ) ;
847
+ Ok ( path)
848
+ }
849
+
850
+ fn path_generic_args (
851
+ self ,
852
+ print_prefix : impl FnOnce ( Self ) -> Result < Self :: Path , Self :: Error > ,
853
+ _args : & [ Kind < ' tcx > ] ,
854
+ ) -> Result < Self :: Path , Self :: Error > {
855
+ print_prefix ( self )
856
+ }
857
+ }
858
+
859
+ let names = AbsolutePathPrinter { tcx : self . tcx } . print_def_path ( def_id, & [ ] ) . unwrap ( ) ;
860
+
861
+ names. len ( ) == path. len ( )
862
+ && names. into_iter ( ) . zip ( path. iter ( ) ) . all ( |( a, & b) | * a == * b)
863
+ }
755
864
}
756
865
757
866
impl < ' a , ' tcx > LayoutOf for LateContext < ' a , ' tcx > {
0 commit comments