@@ -846,14 +846,34 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
846846 remaining_lib_features. remove ( & Symbol :: intern ( "libc" ) ) ;
847847 remaining_lib_features. remove ( & Symbol :: intern ( "test" ) ) ;
848848
849- for ( feature, stable) in tcx. lib_features ( ) . to_vec ( ) {
850- if let Some ( since) = stable {
851- if let Some ( span) = remaining_lib_features. get ( & feature) {
852- // Warn if the user has enabled an already-stable lib feature.
853- unnecessary_stable_feature_lint ( tcx, * span, feature, since) ;
849+ let check_features =
850+ |remaining_lib_features : & mut FxHashMap < _ , _ > , defined_features : & Vec < _ > | {
851+ for & ( feature, since) in defined_features {
852+ if let Some ( since) = since {
853+ if let Some ( span) = remaining_lib_features. get ( & feature) {
854+ // Warn if the user has enabled an already-stable lib feature.
855+ unnecessary_stable_feature_lint ( tcx, * span, feature, since) ;
856+ }
857+ }
858+ remaining_lib_features. remove ( & feature) ;
859+ if remaining_lib_features. is_empty ( ) {
860+ break ;
861+ }
862+ }
863+ } ;
864+
865+ // We always collect the lib features declared in the current crate, even if there are
866+ // no unknown features, because the collection also does feature attribute validation.
867+ let local_defined_features = tcx. lib_features ( ) . to_vec ( ) ;
868+ if !remaining_lib_features. is_empty ( ) {
869+ check_features ( & mut remaining_lib_features, & local_defined_features) ;
870+
871+ for & cnum in & * tcx. crates ( ) {
872+ if remaining_lib_features. is_empty ( ) {
873+ break ;
854874 }
875+ check_features ( & mut remaining_lib_features, & tcx. defined_lib_features ( cnum) ) ;
855876 }
856- remaining_lib_features. remove ( & feature) ;
857877 }
858878
859879 for ( feature, span) in remaining_lib_features {
0 commit comments