@@ -13,7 +13,6 @@ use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
1313use rustc_feature:: { EnabledLangFeature , EnabledLibFeature } ;
1414use rustc_hir:: def:: { DefKind , Res } ;
1515use rustc_hir:: def_id:: { CRATE_DEF_ID , LOCAL_CRATE , LocalDefId , LocalModDefId } ;
16- use rustc_hir:: hir_id:: CRATE_HIR_ID ;
1716use rustc_hir:: intravisit:: { self , Visitor , VisitorExt } ;
1817use rustc_hir:: { self as hir, AmbigArg , FieldDef , Item , ItemKind , TraitRef , Ty , TyKind , Variant } ;
1918use rustc_middle:: hir:: nested_filter;
@@ -411,7 +410,7 @@ struct MissingStabilityAnnotations<'tcx> {
411410impl < ' tcx > MissingStabilityAnnotations < ' tcx > {
412411 /// Verify that deprecation and stability attributes make sense with one another.
413412 #[ 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 ) {
415414 if !self . tcx . features ( ) . staged_api ( ) {
416415 return ;
417416 }
@@ -441,6 +440,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
441440 || ( kind == AnnotationKind :: Container && stab. level . is_stable ( ) && depr. is_some ( ) )
442441 {
443442 if let Some ( span) = find_attr_span ! ( Stability ) {
443+ let item_sp = self . tcx . def_span ( def_id) ;
444444 self . tcx . dcx ( ) . emit_err ( errors:: UselessStability { span, item_sp } ) ;
445445 }
446446 }
@@ -452,6 +452,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
452452 && let attrs:: StabilityLevel :: Stable { since : stab_since, .. } = stab. level
453453 && let Some ( span) = find_attr_span ! ( Stability )
454454 {
455+ let item_sp = self . tcx . def_span ( def_id) ;
455456 match stab_since {
456457 StableSince :: Current => {
457458 self . tcx
@@ -506,19 +507,20 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
506507 }
507508
508509 #[ 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 ) {
510511 let stab = self . tcx . lookup_stability ( def_id) ;
511512 self . tcx . ensure_ok ( ) . lookup_const_stability ( def_id) ;
512513 if !self . tcx . sess . is_test_crate ( )
513514 && stab. is_none ( )
514515 && self . effective_visibilities . is_reachable ( def_id)
515516 {
516517 let descr = self . tcx . def_descr ( def_id. to_def_id ( ) ) ;
518+ let span = self . tcx . def_span ( def_id) ;
517519 self . tcx . dcx ( ) . emit_err ( errors:: MissingStabilityAttr { span, descr } ) ;
518520 }
519521 }
520522
521- fn check_missing_const_stability ( & self , def_id : LocalDefId , span : Span ) {
523+ fn check_missing_const_stability ( & self , def_id : LocalDefId ) {
522524 let is_const = self . tcx . is_const_fn ( def_id. to_def_id ( ) )
523525 || ( self . tcx . def_kind ( def_id. to_def_id ( ) ) == DefKind :: Trait
524526 && self . tcx . is_const_trait ( def_id. to_def_id ( ) ) ) ;
@@ -528,6 +530,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
528530 && self . effective_visibilities . is_reachable ( def_id)
529531 && self . tcx . lookup_const_stability ( def_id) . is_none ( )
530532 {
533+ let span = self . tcx . def_span ( def_id) ;
531534 let descr = self . tcx . def_descr ( def_id. to_def_id ( ) ) ;
532535 self . tcx . dcx ( ) . emit_err ( errors:: MissingConstStabAttr { span, descr } ) ;
533536 }
@@ -542,7 +545,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
542545 }
543546
544547 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 ) ;
546549
547550 // Inherent impls and foreign modules serve only as containers for other items,
548551 // 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> {
553556 hir:: ItemKind :: Impl ( hir:: Impl { of_trait: None , .. } )
554557 | hir:: ItemKind :: ForeignMod { .. }
555558 ) {
556- self . check_missing_stability ( i. owner_id . def_id , i . span ) ;
559+ self . check_missing_stability ( i. owner_id . def_id ) ;
557560 }
558561
559562 // 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 ) ;
561564
562565 intravisit:: walk_item ( self , i)
563566 }
564567
565568 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 ) ;
568571 intravisit:: walk_trait_item ( self , ti) ;
569572 }
570573
571574 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 ) ;
573576 let impl_def_id = self . tcx . hir_get_parent_item ( ii. hir_id ( ) ) ;
574577 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 ) ;
577580 }
578581 intravisit:: walk_impl_item ( self , ii) ;
579582 }
580583
581584 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 ) ;
584587 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) ;
586589 }
587590 intravisit:: walk_variant ( self , var) ;
588591 }
589592
590593 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 ) ;
593596 intravisit:: walk_field_def ( self , s) ;
594597 }
595598
596599 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 ) ;
599602 intravisit:: walk_foreign_item ( self , i) ;
600603 }
601604
602605 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 ) ;
604607 // Note that we don't need to `check_missing_stability` for default generic parameters,
605608 // as we assume that any default generic parameters without attributes are automatically
606609 // stable (assuming they have not inherited instability from their parent).
@@ -619,6 +622,21 @@ fn stability_implications(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> UnordMap<S
619622/// features and possibly prints errors.
620623fn check_mod_unstable_api_usage ( tcx : TyCtxt < ' _ > , module_def_id : LocalModDefId ) {
621624 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+ }
622640}
623641
624642pub ( crate ) fn provide ( providers : & mut Providers ) {
@@ -974,16 +992,9 @@ impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
974992/// Given the list of enabled features that were not language features (i.e., that
975993/// were expected to be library features), and the list of features used from
976994/// libraries, identify activated features that don't exist and error about them.
995+ // This is `pub` for rustdoc. rustc should call it through `check_mod_unstable_api_usage`.
977996pub fn check_unused_or_stable_features ( tcx : TyCtxt < ' _ > ) {
978- let is_staged_api =
979- tcx. sess . opts . unstable_opts . force_unstable_if_unmarked || tcx. features ( ) . staged_api ( ) ;
980- if is_staged_api {
981- let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
982- let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities } ;
983- missing. check_missing_stability ( CRATE_DEF_ID , tcx. hir_span ( CRATE_HIR_ID ) ) ;
984- tcx. hir_walk_toplevel_module ( & mut missing) ;
985- tcx. hir_visit_all_item_likes_in_crate ( & mut missing) ;
986- }
997+ let _prof_timer = tcx. sess . timer ( "unused_lib_feature_checking" ) ;
987998
988999 let enabled_lang_features = tcx. features ( ) . enabled_lang_features ( ) ;
9891000 let mut lang_features = UnordSet :: default ( ) ;
0 commit comments