@@ -25,7 +25,7 @@ use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
2525use crate :: middle:: privacy:: AccessLevels ;
2626use crate :: rustc_serialize:: { Decoder , Decodable , Encoder , Encodable } ;
2727use crate :: session:: { config, early_error, Session } ;
28- use crate :: ty:: { self , TyCtxt , Ty } ;
28+ use crate :: ty:: { self , print :: Printer , subst :: Kind , TyCtxt , Ty } ;
2929use crate :: ty:: layout:: { LayoutError , LayoutOf , TyLayout } ;
3030use crate :: util:: nodemap:: FxHashMap ;
3131use crate :: util:: common:: time;
@@ -36,9 +36,10 @@ use syntax::edition;
3636use syntax_pos:: { MultiSpan , Span , symbol:: { LocalInternedString , Symbol } } ;
3737use errors:: DiagnosticBuilder ;
3838use crate :: hir;
39- use crate :: hir:: def_id:: { DefId , LOCAL_CRATE } ;
39+ use crate :: hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
4040use crate :: hir:: intravisit as hir_visit;
4141use crate :: hir:: intravisit:: Visitor ;
42+ use crate :: hir:: map:: { definitions:: DisambiguatedDefPathData , DefPathData } ;
4243use syntax:: util:: lev_distance:: find_best_match_for_name;
4344use syntax:: visit as ast_visit;
4445
@@ -752,6 +753,114 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
752753 pub fn current_lint_root ( & self ) -> hir:: HirId {
753754 self . last_node_with_lint_attrs
754755 }
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+ }
755864}
756865
757866impl < ' a , ' tcx > LayoutOf for LateContext < ' a , ' tcx > {
0 commit comments