@@ -19,7 +19,7 @@ use session::Session;
19
19
use lint;
20
20
use middle:: cstore:: LOCAL_CRATE ;
21
21
use hir:: def:: Def ;
22
- use hir:: def_id:: { CRATE_DEF_INDEX , DefId } ;
22
+ use hir:: def_id:: { CRATE_DEF_INDEX , DefId , DefIndex } ;
23
23
use ty:: { self , TyCtxt } ;
24
24
use middle:: privacy:: AccessLevels ;
25
25
use syntax:: parse:: token:: InternedString ;
@@ -61,12 +61,46 @@ enum AnnotationKind {
61
61
Container ,
62
62
}
63
63
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
+
64
98
/// A stability index, giving the stability level for items and methods.
65
99
pub struct Index < ' tcx > {
66
100
/// This is mostly a cache, except the stabilities of local items
67
101
/// are filled by the annotator.
68
102
stab_map : DefIdMap < Option < & ' tcx Stability > > ,
69
- depr_map : DefIdMap < Option < Deprecation > > ,
103
+ depr_map : DefIdMap < Option < DeprecationEntry > > ,
70
104
71
105
/// Maps for each crate whether it is part of the staged API.
72
106
staged_api : FnvHashMap < ast:: CrateNum , bool >
@@ -77,7 +111,7 @@ struct Annotator<'a, 'tcx: 'a> {
77
111
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
78
112
index : & ' a mut Index < ' tcx > ,
79
113
parent_stab : Option < & ' tcx Stability > ,
80
- parent_depr : Option < Deprecation > ,
114
+ parent_depr : Option < DeprecationEntry > ,
81
115
access_levels : & ' a AccessLevels ,
82
116
in_trait_impl : bool ,
83
117
}
@@ -184,14 +218,15 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
184
218
185
219
// `Deprecation` is just two pointers, no need to intern it
186
220
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 ( ) ) ;
188
223
189
- let orig_parent_depr = replace ( & mut self . parent_depr , Some ( depr ) ) ;
224
+ let orig_parent_depr = replace ( & mut self . parent_depr , depr_entry ) ;
190
225
visit_children ( self ) ;
191
226
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 ( ) {
193
228
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 ) ;
195
230
visit_children ( self ) ;
196
231
} else {
197
232
visit_children ( self ) ;
@@ -351,7 +386,7 @@ struct Checker<'a, 'tcx: 'a> {
351
386
352
387
impl < ' a , ' tcx > Checker < ' a , ' tcx > {
353
388
fn check ( & mut self , id : DefId , span : Span ,
354
- stab : & Option < & Stability > , _depr : & Option < Deprecation > ) {
389
+ stab : & Option < & Stability > , _depr : & Option < DeprecationEntry > ) {
355
390
if !is_staged_api ( self . tcx , id) {
356
391
return ;
357
392
}
@@ -476,7 +511,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
476
511
warn_about_defns : bool ,
477
512
cb : & mut FnMut ( DefId , Span ,
478
513
& Option < & Stability > ,
479
- & Option < Deprecation > ) ) {
514
+ & Option < DeprecationEntry > ) ) {
480
515
match item. node {
481
516
hir:: ItemExternCrate ( _) => {
482
517
// compiler-generated `extern crate` items have a dummy span.
@@ -515,7 +550,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
515
550
pub fn check_expr < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , e : & hir:: Expr ,
516
551
cb : & mut FnMut ( DefId , Span ,
517
552
& Option < & Stability > ,
518
- & Option < Deprecation > ) ) {
553
+ & Option < DeprecationEntry > ) ) {
519
554
let span;
520
555
let id = match e. node {
521
556
hir:: ExprMethodCall ( i, _, _) => {
@@ -579,7 +614,7 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
579
614
path : & hir:: Path , id : ast:: NodeId ,
580
615
cb : & mut FnMut ( DefId , Span ,
581
616
& Option < & Stability > ,
582
- & Option < Deprecation > ) ) {
617
+ & Option < DeprecationEntry > ) ) {
583
618
// Paths in import prefixes may have no resolution.
584
619
match tcx. expect_def_or_none ( id) {
585
620
Some ( Def :: PrimTy ( ..) ) => { }
@@ -595,7 +630,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
595
630
item : & hir:: PathListItem ,
596
631
cb : & mut FnMut ( DefId , Span ,
597
632
& Option < & Stability > ,
598
- & Option < Deprecation > ) ) {
633
+ & Option < DeprecationEntry > ) ) {
599
634
match tcx. expect_def ( item. node . id ( ) ) {
600
635
Def :: PrimTy ( ..) => { }
601
636
def => {
@@ -607,7 +642,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
607
642
pub fn check_pat < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , pat : & hir:: Pat ,
608
643
cb : & mut FnMut ( DefId , Span ,
609
644
& Option < & Stability > ,
610
- & Option < Deprecation > ) ) {
645
+ & Option < DeprecationEntry > ) ) {
611
646
debug ! ( "check_pat(pat = {:?})" , pat) ;
612
647
if is_internal ( tcx, pat. span ) { return ; }
613
648
@@ -638,7 +673,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
638
673
id : DefId , span : Span ,
639
674
cb : & mut FnMut ( DefId , Span ,
640
675
& Option < & Stability > ,
641
- & Option < Deprecation > ) ) {
676
+ & Option < DeprecationEntry > ) ) {
642
677
if is_internal ( tcx, span) {
643
678
debug ! ( "maybe_do_stability_check: \
644
679
skipping span={:?} since it is internal", span) ;
@@ -647,7 +682,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
647
682
let ( stability, deprecation) = if is_staged_api ( tcx, id) {
648
683
( tcx. lookup_stability ( id) , None )
649
684
} else {
650
- ( None , tcx. lookup_deprecation ( id) )
685
+ ( None , tcx. lookup_deprecation_entry ( id) )
651
686
} ;
652
687
debug ! ( "maybe_do_stability_check: \
653
688
inspecting id={:?} span={:?} of stability={:?}", id, span, stability) ;
@@ -685,6 +720,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
685
720
}
686
721
687
722
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 > {
688
727
if let Some ( depr) = self . stability . borrow ( ) . depr_map . get ( & id) {
689
728
return depr. clone ( ) ;
690
729
}
@@ -703,12 +742,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
703
742
}
704
743
}
705
744
706
- fn lookup_deprecation_uncached ( self , id : DefId ) -> Option < Deprecation > {
745
+ fn lookup_deprecation_uncached ( self , id : DefId ) -> Option < DeprecationEntry > {
707
746
debug ! ( "lookup(id={:?})" , id) ;
708
747
if id. is_local ( ) {
709
748
None // The stability cache is filled partially lazily
710
749
} else {
711
- self . sess . cstore . deprecation ( id)
750
+ self . sess . cstore . deprecation ( id) . map ( DeprecationEntry :: external )
712
751
}
713
752
}
714
753
}
0 commit comments