@@ -13,7 +13,6 @@ use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
13
13
use rustc_feature:: { 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;
@@ -411,7 +410,7 @@ struct MissingStabilityAnnotations<'tcx> {
411
410
impl < ' tcx > MissingStabilityAnnotations < ' tcx > {
412
411
/// Verify that deprecation and stability attributes make sense with one another.
413
412
#[ instrument( level = "trace" , skip( self ) ) ]
414
- fn check_compatible_stability ( & self , def_id : LocalDefId , item_sp : Span ) {
413
+ fn check_compatible_stability ( & self , def_id : LocalDefId ) {
415
414
if !self . tcx . features ( ) . staged_api ( ) {
416
415
return ;
417
416
}
@@ -441,6 +440,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
441
440
|| ( kind == AnnotationKind :: Container && stab. level . is_stable ( ) && depr. is_some ( ) )
442
441
{
443
442
if let Some ( span) = find_attr_span ! ( Stability ) {
443
+ let item_sp = self . tcx . def_span ( def_id) ;
444
444
self . tcx . dcx ( ) . emit_err ( errors:: UselessStability { span, item_sp } ) ;
445
445
}
446
446
}
@@ -452,6 +452,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
452
452
&& let attrs:: StabilityLevel :: Stable { since : stab_since, .. } = stab. level
453
453
&& let Some ( span) = find_attr_span ! ( Stability )
454
454
{
455
+ let item_sp = self . tcx . def_span ( def_id) ;
455
456
match stab_since {
456
457
StableSince :: Current => {
457
458
self . tcx
@@ -506,19 +507,20 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
506
507
}
507
508
508
509
#[ instrument( level = "debug" , skip( self ) ) ]
509
- fn check_missing_stability ( & self , def_id : LocalDefId , span : Span ) {
510
+ fn check_missing_stability ( & self , def_id : LocalDefId ) {
510
511
let stab = self . tcx . lookup_stability ( def_id) ;
511
512
self . tcx . ensure_ok ( ) . lookup_const_stability ( def_id) ;
512
513
if !self . tcx . sess . is_test_crate ( )
513
514
&& stab. is_none ( )
514
515
&& self . effective_visibilities . is_reachable ( def_id)
515
516
{
516
517
let descr = self . tcx . def_descr ( def_id. to_def_id ( ) ) ;
518
+ let span = self . tcx . def_span ( def_id) ;
517
519
self . tcx . dcx ( ) . emit_err ( errors:: MissingStabilityAttr { span, descr } ) ;
518
520
}
519
521
}
520
522
521
- fn check_missing_const_stability ( & self , def_id : LocalDefId , span : Span ) {
523
+ fn check_missing_const_stability ( & self , def_id : LocalDefId ) {
522
524
let is_const = self . tcx . is_const_fn ( def_id. to_def_id ( ) )
523
525
|| ( self . tcx . def_kind ( def_id. to_def_id ( ) ) == DefKind :: Trait
524
526
&& self . tcx . is_const_trait ( def_id. to_def_id ( ) ) ) ;
@@ -528,6 +530,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
528
530
&& self . effective_visibilities . is_reachable ( def_id)
529
531
&& self . tcx . lookup_const_stability ( def_id) . is_none ( )
530
532
{
533
+ let span = self . tcx . def_span ( def_id) ;
531
534
let descr = self . tcx . def_descr ( def_id. to_def_id ( ) ) ;
532
535
self . tcx . dcx ( ) . emit_err ( errors:: MissingConstStabAttr { span, descr } ) ;
533
536
}
@@ -542,7 +545,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
542
545
}
543
546
544
547
fn visit_item ( & mut self , i : & ' tcx Item < ' tcx > ) {
545
- self . check_compatible_stability ( i. owner_id . def_id , i . span ) ;
548
+ self . check_compatible_stability ( i. owner_id . def_id ) ;
546
549
547
550
// Inherent impls and foreign modules serve only as containers for other items,
548
551
// they don't have their own stability. They still can be annotated as unstable
@@ -553,54 +556,54 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
553
556
hir:: ItemKind :: Impl ( hir:: Impl { of_trait: None , .. } )
554
557
| hir:: ItemKind :: ForeignMod { .. }
555
558
) {
556
- self . check_missing_stability ( i. owner_id . def_id , i . span ) ;
559
+ self . check_missing_stability ( i. owner_id . def_id ) ;
557
560
}
558
561
559
562
// Ensure stable `const fn` have a const stability attribute.
560
- self . check_missing_const_stability ( i. owner_id . def_id , i . span ) ;
563
+ self . check_missing_const_stability ( i. owner_id . def_id ) ;
561
564
562
565
intravisit:: walk_item ( self , i)
563
566
}
564
567
565
568
fn visit_trait_item ( & mut self , ti : & ' tcx hir:: TraitItem < ' tcx > ) {
566
- self . check_compatible_stability ( ti. owner_id . def_id , ti . span ) ;
567
- self . check_missing_stability ( ti. owner_id . def_id , ti . span ) ;
569
+ self . check_compatible_stability ( ti. owner_id . def_id ) ;
570
+ self . check_missing_stability ( ti. owner_id . def_id ) ;
568
571
intravisit:: walk_trait_item ( self , ti) ;
569
572
}
570
573
571
574
fn visit_impl_item ( & mut self , ii : & ' tcx hir:: ImplItem < ' tcx > ) {
572
- self . check_compatible_stability ( ii. owner_id . def_id , ii . span ) ;
575
+ self . check_compatible_stability ( ii. owner_id . def_id ) ;
573
576
let impl_def_id = self . tcx . hir_get_parent_item ( ii. hir_id ( ) ) ;
574
577
if self . tcx . impl_trait_ref ( impl_def_id) . is_none ( ) {
575
- self . check_missing_stability ( ii. owner_id . def_id , ii . span ) ;
576
- self . check_missing_const_stability ( ii. owner_id . def_id , ii . span ) ;
578
+ self . check_missing_stability ( ii. owner_id . def_id ) ;
579
+ self . check_missing_const_stability ( ii. owner_id . def_id ) ;
577
580
}
578
581
intravisit:: walk_impl_item ( self , ii) ;
579
582
}
580
583
581
584
fn visit_variant ( & mut self , var : & ' tcx Variant < ' tcx > ) {
582
- self . check_compatible_stability ( var. def_id , var . span ) ;
583
- self . check_missing_stability ( var. def_id , var . span ) ;
585
+ self . check_compatible_stability ( var. def_id ) ;
586
+ self . check_missing_stability ( var. def_id ) ;
584
587
if let Some ( ctor_def_id) = var. data . ctor_def_id ( ) {
585
- self . check_missing_stability ( ctor_def_id, var . span ) ;
588
+ self . check_missing_stability ( ctor_def_id) ;
586
589
}
587
590
intravisit:: walk_variant ( self , var) ;
588
591
}
589
592
590
593
fn visit_field_def ( & mut self , s : & ' tcx FieldDef < ' tcx > ) {
591
- self . check_compatible_stability ( s. def_id , s . span ) ;
592
- self . check_missing_stability ( s. def_id , s . span ) ;
594
+ self . check_compatible_stability ( s. def_id ) ;
595
+ self . check_missing_stability ( s. def_id ) ;
593
596
intravisit:: walk_field_def ( self , s) ;
594
597
}
595
598
596
599
fn visit_foreign_item ( & mut self , i : & ' tcx hir:: ForeignItem < ' tcx > ) {
597
- self . check_compatible_stability ( i. owner_id . def_id , i . span ) ;
598
- self . check_missing_stability ( i. owner_id . def_id , i . span ) ;
600
+ self . check_compatible_stability ( i. owner_id . def_id ) ;
601
+ self . check_missing_stability ( i. owner_id . def_id ) ;
599
602
intravisit:: walk_foreign_item ( self , i) ;
600
603
}
601
604
602
605
fn visit_generic_param ( & mut self , p : & ' tcx hir:: GenericParam < ' tcx > ) {
603
- self . check_compatible_stability ( p. def_id , p . span ) ;
606
+ self . check_compatible_stability ( p. def_id ) ;
604
607
// Note that we don't need to `check_missing_stability` for default generic parameters,
605
608
// as we assume that any default generic parameters without attributes are automatically
606
609
// stable (assuming they have not inherited instability from their parent).
@@ -619,6 +622,21 @@ fn stability_implications(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> UnordMap<S
619
622
/// features and possibly prints errors.
620
623
fn check_mod_unstable_api_usage ( tcx : TyCtxt < ' _ > , module_def_id : LocalModDefId ) {
621
624
tcx. hir_visit_item_likes_in_module ( module_def_id, & mut Checker { tcx } ) ;
625
+
626
+ let is_staged_api =
627
+ tcx. sess . opts . unstable_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ( ) ;
628
+ if is_staged_api {
629
+ let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
630
+ let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities } ;
631
+ if module_def_id. is_top_level_module ( ) {
632
+ missing. check_missing_stability ( CRATE_DEF_ID ) ;
633
+ }
634
+ tcx. hir_visit_item_likes_in_module ( module_def_id, & mut missing) ;
635
+ }
636
+
637
+ if module_def_id. is_top_level_module ( ) {
638
+ check_unused_or_stable_features ( tcx)
639
+ }
622
640
}
623
641
624
642
pub ( crate ) fn provide ( providers : & mut Providers ) {
@@ -969,16 +987,9 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
969
987
/// Given the list of enabled features that were not language features (i.e., that
970
988
/// were expected to be library features), and the list of features used from
971
989
/// libraries, identify activated features that don't exist and error about them.
990
+ // This is `pub` for rustdoc. rustc should call it through `check_mod_unstable_api_usage`.
972
991
pub fn check_unused_or_stable_features ( tcx : TyCtxt < ' _ > ) {
973
- let is_staged_api =
974
- tcx. sess . opts . unstable_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ( ) ;
975
- if is_staged_api {
976
- let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
977
- let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities } ;
978
- missing. check_missing_stability ( CRATE_DEF_ID , tcx. hir_span ( CRATE_HIR_ID ) ) ;
979
- tcx. hir_walk_toplevel_module ( & mut missing) ;
980
- tcx. hir_visit_all_item_likes_in_crate ( & mut missing) ;
981
- }
992
+ let _prof_timer = tcx. sess . timer ( "unused_lib_feature_checking" ) ;
982
993
983
994
let enabled_lang_features = tcx. features ( ) . enabled_lang_features ( ) ;
984
995
let mut lang_features = UnordSet :: default ( ) ;
0 commit comments