@@ -13,7 +13,6 @@ use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
13
13
use rustc_feature:: { ACCEPTED_LANG_FEATURES , EnabledLangFeature , EnabledLibFeature } ;
14
14
use rustc_hir:: def:: { DefKind , Res } ;
15
15
use rustc_hir:: def_id:: { CRATE_DEF_ID , LOCAL_CRATE , LocalDefId , LocalModDefId } ;
16
- use rustc_hir:: hir_id:: CRATE_HIR_ID ;
17
16
use rustc_hir:: intravisit:: { self , Visitor , VisitorExt } ;
18
17
use rustc_hir:: { self as hir, AmbigArg , FieldDef , Item , ItemKind , TraitRef , Ty , TyKind , Variant } ;
19
18
use rustc_middle:: hir:: nested_filter;
@@ -410,7 +409,7 @@ struct MissingStabilityAnnotations<'tcx> {
410
409
411
410
impl < ' tcx > MissingStabilityAnnotations < ' tcx > {
412
411
#[ instrument( level = "trace" , skip( self ) ) ]
413
- fn check_compatible_stability ( & self , def_id : LocalDefId , item_sp : Span ) {
412
+ fn check_compatible_stability ( & self , def_id : LocalDefId ) {
414
413
if !self . tcx . features ( ) . staged_api ( ) {
415
414
return ;
416
415
}
@@ -440,6 +439,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
440
439
|| ( kind == AnnotationKind :: Container && stab. level . is_stable ( ) && depr. is_some ( ) )
441
440
{
442
441
if let Some ( span) = find_attr_span ! ( Stability ) {
442
+ let item_sp = self . tcx . def_span ( def_id) ;
443
443
self . tcx . dcx ( ) . emit_err ( errors:: UselessStability { span, item_sp } ) ;
444
444
}
445
445
}
@@ -451,6 +451,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
451
451
&& let attrs:: StabilityLevel :: Stable { since : stab_since, .. } = stab. level
452
452
&& let Some ( span) = find_attr_span ! ( Stability )
453
453
{
454
+ let item_sp = self . tcx . def_span ( def_id) ;
454
455
match stab_since {
455
456
StableSince :: Current => {
456
457
self . tcx
@@ -477,6 +478,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
477
478
&& ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| f. name == feature) . is_some ( )
478
479
&& let Some ( span) = find_attr_span ! ( Stability )
479
480
{
481
+ let item_sp = self . tcx . def_span ( def_id) ;
480
482
self . tcx
481
483
. dcx ( )
482
484
. emit_err ( errors:: UnstableAttrForAlreadyStableFeature { span, item_sp } ) ;
@@ -513,6 +515,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
513
515
&& let Some ( const_span) = find_attr_span ! ( ConstStability )
514
516
&& ACCEPTED_LANG_FEATURES . iter ( ) . find ( |f| f. name == feature) . is_some ( )
515
517
{
518
+ let item_sp = self . tcx . def_span ( def_id) ;
516
519
self . tcx . dcx ( ) . emit_err ( errors:: UnstableAttrForAlreadyStableFeature {
517
520
span : const_span,
518
521
item_sp,
@@ -529,19 +532,20 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
529
532
}
530
533
531
534
#[ instrument( level = "debug" , skip( self ) ) ]
532
- fn check_missing_stability ( & self , def_id : LocalDefId , span : Span ) {
535
+ fn check_missing_stability ( & self , def_id : LocalDefId ) {
533
536
let stab = self . tcx . lookup_stability ( def_id) ;
534
537
self . tcx . ensure_ok ( ) . lookup_const_stability ( def_id) ;
535
538
if !self . tcx . sess . is_test_crate ( )
536
539
&& stab. is_none ( )
537
540
&& self . effective_visibilities . is_reachable ( def_id)
538
541
{
539
542
let descr = self . tcx . def_descr ( def_id. to_def_id ( ) ) ;
543
+ let span = self . tcx . def_span ( def_id) ;
540
544
self . tcx . dcx ( ) . emit_err ( errors:: MissingStabilityAttr { span, descr } ) ;
541
545
}
542
546
}
543
547
544
- fn check_missing_const_stability ( & self , def_id : LocalDefId , span : Span ) {
548
+ fn check_missing_const_stability ( & self , def_id : LocalDefId ) {
545
549
let is_const = self . tcx . is_const_fn ( def_id. to_def_id ( ) )
546
550
|| ( self . tcx . def_kind ( def_id. to_def_id ( ) ) == DefKind :: Trait
547
551
&& self . tcx . is_const_trait ( def_id. to_def_id ( ) ) ) ;
@@ -551,6 +555,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
551
555
&& self . effective_visibilities . is_reachable ( def_id)
552
556
&& self . tcx . lookup_const_stability ( def_id) . is_none ( )
553
557
{
558
+ let span = self . tcx . def_span ( def_id) ;
554
559
let descr = self . tcx . def_descr ( def_id. to_def_id ( ) ) ;
555
560
self . tcx . dcx ( ) . emit_err ( errors:: MissingConstStabAttr { span, descr } ) ;
556
561
}
@@ -565,7 +570,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
565
570
}
566
571
567
572
fn visit_item ( & mut self , i : & ' tcx Item < ' tcx > ) {
568
- self . check_compatible_stability ( i. owner_id . def_id , i . span ) ;
573
+ self . check_compatible_stability ( i. owner_id . def_id ) ;
569
574
570
575
// Inherent impls and foreign modules serve only as containers for other items,
571
576
// they don't have their own stability. They still can be annotated as unstable
@@ -576,54 +581,54 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
576
581
hir:: ItemKind :: Impl ( hir:: Impl { of_trait: None , .. } )
577
582
| hir:: ItemKind :: ForeignMod { .. }
578
583
) {
579
- self . check_missing_stability ( i. owner_id . def_id , i . span ) ;
584
+ self . check_missing_stability ( i. owner_id . def_id ) ;
580
585
}
581
586
582
587
// Ensure stable `const fn` have a const stability attribute.
583
- self . check_missing_const_stability ( i. owner_id . def_id , i . span ) ;
588
+ self . check_missing_const_stability ( i. owner_id . def_id ) ;
584
589
585
590
intravisit:: walk_item ( self , i)
586
591
}
587
592
588
593
fn visit_trait_item ( & mut self , ti : & ' tcx hir:: TraitItem < ' tcx > ) {
589
- self . check_compatible_stability ( ti. owner_id . def_id , ti . span ) ;
590
- self . check_missing_stability ( ti. owner_id . def_id , ti . span ) ;
594
+ self . check_compatible_stability ( ti. owner_id . def_id ) ;
595
+ self . check_missing_stability ( ti. owner_id . def_id ) ;
591
596
intravisit:: walk_trait_item ( self , ti) ;
592
597
}
593
598
594
599
fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem < ' tcx > ) {
595
- self . check_compatible_stability ( ii. owner_id . def_id , ii . span ) ;
600
+ self . check_compatible_stability ( ii. owner_id . def_id ) ;
596
601
let impl_def_id = self . tcx . hir_get_parent_item ( ii. hir_id ( ) ) ;
597
602
if self . tcx . impl_trait_ref ( impl_def_id) . is_none ( ) {
598
- self . check_missing_stability ( ii. owner_id . def_id , ii . span ) ;
599
- self . check_missing_const_stability ( ii. owner_id . def_id , ii . span ) ;
603
+ self . check_missing_stability ( ii. owner_id . def_id ) ;
604
+ self . check_missing_const_stability ( ii. owner_id . def_id ) ;
600
605
}
601
606
intravisit:: walk_impl_item ( self , ii) ;
602
607
}
603
608
604
609
fn visit_variant ( & mut self , var : & ' tcx Variant < ' tcx > ) {
605
- self . check_compatible_stability ( var. def_id , var . span ) ;
606
- self . check_missing_stability ( var. def_id , var . span ) ;
610
+ self . check_compatible_stability ( var. def_id ) ;
611
+ self . check_missing_stability ( var. def_id ) ;
607
612
if let Some ( ctor_def_id) = var. data . ctor_def_id ( ) {
608
- self . check_missing_stability ( ctor_def_id, var . span ) ;
613
+ self . check_missing_stability ( ctor_def_id) ;
609
614
}
610
615
intravisit:: walk_variant ( self , var) ;
611
616
}
612
617
613
618
fn visit_field_def ( & mut self , s : & ' tcx FieldDef < ' tcx > ) {
614
- self . check_compatible_stability ( s. def_id , s . span ) ;
615
- self . check_missing_stability ( s. def_id , s . span ) ;
619
+ self . check_compatible_stability ( s. def_id ) ;
620
+ self . check_missing_stability ( s. def_id ) ;
616
621
intravisit:: walk_field_def ( self , s) ;
617
622
}
618
623
619
624
fn visit_foreign_item ( & mut self , i : & ' tcx hir:: ForeignItem < ' tcx > ) {
620
- self . check_compatible_stability ( i. owner_id . def_id , i . span ) ;
621
- self . check_missing_stability ( i. owner_id . def_id , i . span ) ;
625
+ self . check_compatible_stability ( i. owner_id . def_id ) ;
626
+ self . check_missing_stability ( i. owner_id . def_id ) ;
622
627
intravisit:: walk_foreign_item ( self , i) ;
623
628
}
624
629
625
630
fn visit_generic_param ( & mut self , p : & ' tcx hir:: GenericParam < ' tcx > ) {
626
- self . check_compatible_stability ( p. def_id , p . span ) ;
631
+ self . check_compatible_stability ( p. def_id ) ;
627
632
// Note that we don't need to `check_missing_stability` for default generic parameters,
628
633
// as we assume that any default generic parameters without attributes are automatically
629
634
// stable (assuming they have not inherited instability from their parent).
@@ -642,6 +647,21 @@ fn stability_implications(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> UnordMap<S
642
647
/// features and possibly prints errors.
643
648
fn check_mod_unstable_api_usage ( tcx : TyCtxt < ' _ > , module_def_id : LocalModDefId ) {
644
649
tcx. hir_visit_item_likes_in_module ( module_def_id, & mut Checker { tcx } ) ;
650
+
651
+ let is_staged_api =
652
+ tcx. sess . opts . unstable_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ( ) ;
653
+ if is_staged_api {
654
+ let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
655
+ let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities } ;
656
+ if module_def_id. is_top_level_module ( ) {
657
+ missing. check_missing_stability ( CRATE_DEF_ID ) ;
658
+ }
659
+ tcx. hir_visit_item_likes_in_module ( module_def_id, & mut missing) ;
660
+ }
661
+
662
+ if module_def_id. is_top_level_module ( ) {
663
+ check_unused_or_stable_features ( tcx)
664
+ }
645
665
}
646
666
647
667
pub ( crate ) fn provide ( providers : & mut Providers ) {
@@ -992,16 +1012,9 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
992
1012
/// Given the list of enabled features that were not language features (i.e., that
993
1013
/// were expected to be library features), and the list of features used from
994
1014
/// libraries, identify activated features that don't exist and error about them.
1015
+ // This is `pub` for rustdoc. rustc should call it through `check_mod_unstable_api_usage`.
995
1016
pub fn check_unused_or_stable_features ( tcx : TyCtxt < ' _ > ) {
996
- let is_staged_api =
997
- tcx. sess . opts . unstable_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ( ) ;
998
- if is_staged_api {
999
- let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
1000
- let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities } ;
1001
- missing. check_missing_stability ( CRATE_DEF_ID , tcx. hir_span ( CRATE_HIR_ID ) ) ;
1002
- tcx. hir_walk_toplevel_module ( & mut missing) ;
1003
- tcx. hir_visit_all_item_likes_in_crate ( & mut missing) ;
1004
- }
1017
+ let _prof_timer = tcx. sess . timer ( "unused_lib_feature_checking" ) ;
1005
1018
1006
1019
let enabled_lang_features = tcx. features ( ) . enabled_lang_features ( ) ;
1007
1020
let mut lang_features = UnordSet :: default ( ) ;
0 commit comments