@@ -527,17 +527,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
527
527
528
528
/// Evaluates the stability of an item.
529
529
///
530
- /// Returns `None` if the item is stable, or unstable but the corresponding `#![feature]` has
531
- /// been provided. Returns the tuple `Some((feature, reason, issue))` of the offending unstable
532
- /// feature otherwise.
533
- pub fn eval_stability ( self , def_id : DefId , id : NodeId , span : Span ) -> EvalResult {
530
+ /// Returns `EvalResult::Allow` if the item is stable, or unstable but the corresponding
531
+ /// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending
532
+ /// unstable feature otherwise.
533
+ ///
534
+ /// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
535
+ /// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
536
+ /// `id`.
537
+ pub fn eval_stability ( self , def_id : DefId , id : Option < NodeId > , span : Span ) -> EvalResult {
534
538
if span. allows_unstable ( ) {
535
539
debug ! ( "stability: \
536
540
skipping span={:?} since it is internal", span) ;
537
541
return EvalResult :: Allow ;
538
542
}
539
543
540
- let lint_deprecated = |def_id : DefId , note : Option < Symbol > | {
544
+ let lint_deprecated = |def_id : DefId , id : NodeId , note : Option < Symbol > | {
541
545
let path = self . item_path_str ( def_id) ;
542
546
543
547
let msg = if let Some ( note) = note {
@@ -547,22 +551,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
547
551
} ;
548
552
549
553
self . lint_node ( lint:: builtin:: DEPRECATED , id, span, & msg) ;
554
+ if id == ast:: DUMMY_NODE_ID {
555
+ span_bug ! ( span, "emitted a deprecated lint with dummy node id: {:?}" , def_id) ;
556
+ }
550
557
} ;
551
558
552
559
// Deprecated attributes apply in-crate and cross-crate.
553
- if let Some ( depr_entry) = self . lookup_deprecation_entry ( def_id) {
554
- let skip = if id == ast:: DUMMY_NODE_ID {
555
- true
556
- } else {
560
+ if let Some ( id) = id {
561
+ if let Some ( depr_entry) = self . lookup_deprecation_entry ( def_id) {
557
562
let parent_def_id = self . hir . local_def_id ( self . hir . get_parent ( id) ) ;
558
- self . lookup_deprecation_entry ( parent_def_id) . map_or ( false , |parent_depr| {
559
- parent_depr. same_origin ( & depr_entry)
560
- } )
563
+ let skip = self . lookup_deprecation_entry ( parent_def_id)
564
+ . map_or ( false , |parent_depr| parent_depr. same_origin ( & depr_entry) ) ;
565
+ if !skip {
566
+ lint_deprecated ( def_id, id, depr_entry. attr . note ) ;
567
+ }
561
568
} ;
562
-
563
- if !skip {
564
- lint_deprecated ( def_id, depr_entry. attr . note ) ;
565
- }
566
569
}
567
570
568
571
let is_staged_api = self . lookup_stability ( DefId {
@@ -579,8 +582,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
579
582
580
583
if let Some ( & Stability { rustc_depr : Some ( attr:: RustcDeprecation { reason, .. } ) , ..} )
581
584
= stability {
582
- if id != ast :: DUMMY_NODE_ID {
583
- lint_deprecated ( def_id, Some ( reason) ) ;
585
+ if let Some ( id ) = id {
586
+ lint_deprecated ( def_id, id , Some ( reason) ) ;
584
587
}
585
588
}
586
589
@@ -629,7 +632,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
629
632
}
630
633
}
631
634
632
- pub fn check_stability ( self , def_id : DefId , id : NodeId , span : Span ) {
635
+ /// Checks if an item is stable or error out.
636
+ ///
637
+ /// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
638
+ /// exist, emits an error.
639
+ ///
640
+ /// Additionally, this function will also check if the item is deprecated. If so, and `id` is
641
+ /// not `None`, a deprecated lint attached to `id` will be emitted.
642
+ pub fn check_stability ( self , def_id : DefId , id : Option < NodeId > , span : Span ) {
633
643
match self . eval_stability ( def_id, id, span) {
634
644
EvalResult :: Allow => { }
635
645
EvalResult :: Deny { feature, reason, issue } => {
@@ -687,7 +697,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
687
697
None => return ,
688
698
} ;
689
699
let def_id = DefId { krate : cnum, index : CRATE_DEF_INDEX } ;
690
- self . tcx . check_stability ( def_id, item. id , item. span ) ;
700
+ self . tcx . check_stability ( def_id, Some ( item. id ) , item. span ) ;
691
701
}
692
702
693
703
// For implementations of traits, check the stability of each item
@@ -700,8 +710,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
700
710
let trait_item_def_id = self . tcx . associated_items ( trait_did)
701
711
. find ( |item| item. name == impl_item. name ) . map ( |item| item. def_id ) ;
702
712
if let Some ( def_id) = trait_item_def_id {
703
- // Pass `DUMMY_NODE_ID ` to skip deprecation warnings.
704
- self . tcx . check_stability ( def_id, ast :: DUMMY_NODE_ID , impl_item. span ) ;
713
+ // Pass `None ` to skip deprecation warnings.
714
+ self . tcx . check_stability ( def_id, None , impl_item. span ) ;
705
715
}
706
716
}
707
717
}
@@ -737,7 +747,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
737
747
match path. def {
738
748
Def :: Local ( ..) | Def :: Upvar ( ..) |
739
749
Def :: PrimTy ( ..) | Def :: SelfTy ( ..) | Def :: Err => { }
740
- _ => self . tcx . check_stability ( path. def . def_id ( ) , id , path. span )
750
+ _ => self . tcx . check_stability ( path. def . def_id ( ) , Some ( id ) , path. span )
741
751
}
742
752
intravisit:: walk_path ( self , path)
743
753
}
0 commit comments