@@ -19,7 +19,7 @@ use session::Session;
1919use lint;
2020use middle:: cstore:: LOCAL_CRATE ;
2121use hir:: def:: Def ;
22- use hir:: def_id:: { CRATE_DEF_INDEX , DefId } ;
22+ use hir:: def_id:: { CRATE_DEF_INDEX , DefId , DefIndex } ;
2323use ty:: { self , TyCtxt } ;
2424use middle:: privacy:: AccessLevels ;
2525use syntax:: parse:: token:: InternedString ;
@@ -61,12 +61,46 @@ enum AnnotationKind {
6161 Container ,
6262}
6363
64+ /// An entry in the `depr_map`.
65+ #[ derive( Clone ) ]
66+ pub struct DeprecationEntry {
67+ /// The metadata of the attribute associated with this entry.
68+ pub attr : Deprecation ,
69+ /// The def id where the attr was originally attached. `None` for non-local
70+ /// `DefId`'s.
71+ origin : Option < DefIndex > ,
72+ }
73+
74+ impl DeprecationEntry {
75+ fn local ( attr : Deprecation , id : DefId ) -> DeprecationEntry {
76+ assert ! ( id. is_local( ) ) ;
77+ DeprecationEntry {
78+ attr : attr,
79+ origin : Some ( id. index ) ,
80+ }
81+ }
82+
83+ fn external ( attr : Deprecation ) -> DeprecationEntry {
84+ DeprecationEntry {
85+ attr : attr,
86+ origin : None ,
87+ }
88+ }
89+
90+ pub fn same_origin ( & self , other : & DeprecationEntry ) -> bool {
91+ match ( self . origin , other. origin ) {
92+ ( Some ( o1) , Some ( o2) ) => o1 == o2,
93+ _ => false
94+ }
95+ }
96+ }
97+
6498/// A stability index, giving the stability level for items and methods.
6599pub struct Index < ' tcx > {
66100 /// This is mostly a cache, except the stabilities of local items
67101 /// are filled by the annotator.
68102 stab_map : DefIdMap < Option < & ' tcx Stability > > ,
69- depr_map : DefIdMap < Option < Deprecation > > ,
103+ depr_map : DefIdMap < Option < DeprecationEntry > > ,
70104
71105 /// Maps for each crate whether it is part of the staged API.
72106 staged_api : FnvHashMap < ast:: CrateNum , bool >
@@ -77,7 +111,7 @@ struct Annotator<'a, 'tcx: 'a> {
77111 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
78112 index : & ' a mut Index < ' tcx > ,
79113 parent_stab : Option < & ' tcx Stability > ,
80- parent_depr : Option < Deprecation > ,
114+ parent_depr : Option < DeprecationEntry > ,
81115 access_levels : & ' a AccessLevels ,
82116 in_trait_impl : bool ,
83117}
@@ -184,14 +218,15 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
184218
185219 // `Deprecation` is just two pointers, no need to intern it
186220 let def_id = self . tcx . map . local_def_id ( id) ;
187- self . index . depr_map . insert ( def_id, Some ( depr. clone ( ) ) ) ;
221+ let depr_entry = Some ( DeprecationEntry :: local ( depr, def_id) ) ;
222+ self . index . depr_map . insert ( def_id, depr_entry. clone ( ) ) ;
188223
189- let orig_parent_depr = replace ( & mut self . parent_depr , Some ( depr ) ) ;
224+ let orig_parent_depr = replace ( & mut self . parent_depr , depr_entry ) ;
190225 visit_children ( self ) ;
191226 self . parent_depr = orig_parent_depr;
192- } else if let Some ( depr ) = self . parent_depr . clone ( ) {
227+ } else if let parent_depr @ Some ( _ ) = self . parent_depr . clone ( ) {
193228 let def_id = self . tcx . map . local_def_id ( id) ;
194- self . index . depr_map . insert ( def_id, Some ( depr ) ) ;
229+ self . index . depr_map . insert ( def_id, parent_depr ) ;
195230 visit_children ( self ) ;
196231 } else {
197232 visit_children ( self ) ;
@@ -351,7 +386,7 @@ struct Checker<'a, 'tcx: 'a> {
351386
352387impl < ' a , ' tcx > Checker < ' a , ' tcx > {
353388 fn check ( & mut self , id : DefId , span : Span ,
354- stab : & Option < & Stability > , _depr : & Option < Deprecation > ) {
389+ stab : & Option < & Stability > , _depr : & Option < DeprecationEntry > ) {
355390 if !is_staged_api ( self . tcx , id) {
356391 return ;
357392 }
@@ -476,7 +511,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
476511 warn_about_defns : bool ,
477512 cb : & mut FnMut ( DefId , Span ,
478513 & Option < & Stability > ,
479- & Option < Deprecation > ) ) {
514+ & Option < DeprecationEntry > ) ) {
480515 match item. node {
481516 hir:: ItemExternCrate ( _) => {
482517 // compiler-generated `extern crate` items have a dummy span.
@@ -515,7 +550,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
515550pub fn check_expr < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , e : & hir:: Expr ,
516551 cb : & mut FnMut ( DefId , Span ,
517552 & Option < & Stability > ,
518- & Option < Deprecation > ) ) {
553+ & Option < DeprecationEntry > ) ) {
519554 let span;
520555 let id = match e. node {
521556 hir:: ExprMethodCall ( i, _, _) => {
@@ -579,7 +614,7 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
579614 path : & hir:: Path , id : ast:: NodeId ,
580615 cb : & mut FnMut ( DefId , Span ,
581616 & Option < & Stability > ,
582- & Option < Deprecation > ) ) {
617+ & Option < DeprecationEntry > ) ) {
583618 // Paths in import prefixes may have no resolution.
584619 match tcx. expect_def_or_none ( id) {
585620 Some ( Def :: PrimTy ( ..) ) => { }
@@ -595,7 +630,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
595630 item : & hir:: PathListItem ,
596631 cb : & mut FnMut ( DefId , Span ,
597632 & Option < & Stability > ,
598- & Option < Deprecation > ) ) {
633+ & Option < DeprecationEntry > ) ) {
599634 match tcx. expect_def ( item. node . id ( ) ) {
600635 Def :: PrimTy ( ..) => { }
601636 def => {
@@ -607,7 +642,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
607642pub fn check_pat < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , pat : & hir:: Pat ,
608643 cb : & mut FnMut ( DefId , Span ,
609644 & Option < & Stability > ,
610- & Option < Deprecation > ) ) {
645+ & Option < DeprecationEntry > ) ) {
611646 debug ! ( "check_pat(pat = {:?})" , pat) ;
612647 if is_internal ( tcx, pat. span ) { return ; }
613648
@@ -638,7 +673,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
638673 id : DefId , span : Span ,
639674 cb : & mut FnMut ( DefId , Span ,
640675 & Option < & Stability > ,
641- & Option < Deprecation > ) ) {
676+ & Option < DeprecationEntry > ) ) {
642677 if is_internal ( tcx, span) {
643678 debug ! ( "maybe_do_stability_check: \
644679 skipping span={:?} since it is internal", span) ;
@@ -647,7 +682,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
647682 let ( stability, deprecation) = if is_staged_api ( tcx, id) {
648683 ( tcx. lookup_stability ( id) , None )
649684 } else {
650- ( None , tcx. lookup_deprecation ( id) )
685+ ( None , tcx. lookup_deprecation_entry ( id) )
651686 } ;
652687 debug ! ( "maybe_do_stability_check: \
653688 inspecting id={:?} span={:?} of stability={:?}", id, span, stability) ;
@@ -685,6 +720,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
685720 }
686721
687722 pub fn lookup_deprecation ( self , id : DefId ) -> Option < Deprecation > {
723+ self . lookup_deprecation_entry ( id) . map ( |depr| depr. attr )
724+ }
725+
726+ pub fn lookup_deprecation_entry ( self , id : DefId ) -> Option < DeprecationEntry > {
688727 if let Some ( depr) = self . stability . borrow ( ) . depr_map . get ( & id) {
689728 return depr. clone ( ) ;
690729 }
@@ -703,12 +742,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
703742 }
704743 }
705744
706- fn lookup_deprecation_uncached ( self , id : DefId ) -> Option < Deprecation > {
745+ fn lookup_deprecation_uncached ( self , id : DefId ) -> Option < DeprecationEntry > {
707746 debug ! ( "lookup(id={:?})" , id) ;
708747 if id. is_local ( ) {
709748 None // The stability cache is filled partially lazily
710749 } else {
711- self . sess . cstore . deprecation ( id)
750+ self . sess . cstore . deprecation ( id) . map ( DeprecationEntry :: external )
712751 }
713752 }
714753}
0 commit comments