|
3 | 3 |
|
4 | 4 | use attr::StabilityLevel;
|
5 | 5 | use rustc_attr::{self as attr, ConstStability, Stability, Unstable, UnstableReason};
|
6 |
| -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; |
| 6 | +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; |
7 | 7 | use rustc_errors::{struct_span_err, Applicability};
|
8 | 8 | use rustc_hir as hir;
|
9 | 9 | use rustc_hir::def::{DefKind, Res};
|
@@ -949,52 +949,40 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
|
949 | 949 | remaining_lib_features.remove(&sym::libc);
|
950 | 950 | remaining_lib_features.remove(&sym::test);
|
951 | 951 |
|
952 |
| - // We always collect the lib features declared in the current crate, even if there are |
953 |
| - // no unknown features, because the collection also does feature attribute validation. |
954 |
| - let local_defined_features = tcx.lib_features(()); |
955 |
| - let mut all_lib_features: FxHashMap<_, _> = |
956 |
| - local_defined_features.to_vec().iter().map(|el| *el).collect(); |
957 | 952 | let mut implications = tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE).clone();
|
958 | 953 | for &cnum in tcx.crates(()) {
|
959 | 954 | implications.extend(tcx.stability_implications(cnum));
|
960 |
| - all_lib_features.extend(tcx.defined_lib_features(cnum).iter().map(|el| *el)); |
961 |
| - } |
962 |
| - |
963 |
| - // Check that every feature referenced by an `implied_by` exists (for features defined in the |
964 |
| - // local crate). |
965 |
| - for (implied_by, feature) in tcx.stability_implications(rustc_hir::def_id::LOCAL_CRATE) { |
966 |
| - // Only `implied_by` needs to be checked, `feature` is guaranteed to exist. |
967 |
| - if !all_lib_features.contains_key(implied_by) { |
968 |
| - let span = local_defined_features |
969 |
| - .stable |
970 |
| - .get(feature) |
971 |
| - .map(|(_, span)| span) |
972 |
| - .or_else(|| local_defined_features.unstable.get(feature)) |
973 |
| - .expect("feature that implied another does not exist"); |
974 |
| - tcx.sess |
975 |
| - .struct_span_err( |
976 |
| - *span, |
977 |
| - format!("feature `{implied_by}` implying `{feature}` does not exist"), |
978 |
| - ) |
979 |
| - .emit(); |
980 |
| - } |
981 | 955 | }
|
982 | 956 |
|
983 |
| - if !remaining_lib_features.is_empty() { |
984 |
| - for (feature, since) in all_lib_features.iter() { |
| 957 | + let check_features = |remaining_lib_features: &mut FxIndexMap<_, _>, defined_features: &[_]| { |
| 958 | + for &(feature, since) in defined_features { |
985 | 959 | if let Some(since) = since && let Some(span) = remaining_lib_features.get(&feature) {
|
986 | 960 | // Warn if the user has enabled an already-stable lib feature.
|
987 | 961 | if let Some(implies) = implications.get(&feature) {
|
988 |
| - unnecessary_partially_stable_feature_lint(tcx, *span, *feature, *implies, *since); |
| 962 | + unnecessary_partially_stable_feature_lint(tcx, *span, feature, *implies, since); |
989 | 963 | } else {
|
990 |
| - unnecessary_stable_feature_lint(tcx, *span, *feature, *since); |
| 964 | + unnecessary_stable_feature_lint(tcx, *span, feature, since); |
991 | 965 | }
|
992 | 966 | }
|
993 | 967 | remaining_lib_features.remove(&feature);
|
994 | 968 | if remaining_lib_features.is_empty() {
|
995 | 969 | break;
|
996 | 970 | }
|
997 | 971 | }
|
| 972 | + }; |
| 973 | + |
| 974 | + // We always collect the lib features declared in the current crate, even if there are |
| 975 | + // no unknown features, because the collection also does feature attribute validation. |
| 976 | + let local_defined_features = tcx.lib_features(()).to_vec(); |
| 977 | + if !remaining_lib_features.is_empty() { |
| 978 | + check_features(&mut remaining_lib_features, &local_defined_features); |
| 979 | + |
| 980 | + for &cnum in tcx.crates(()) { |
| 981 | + if remaining_lib_features.is_empty() { |
| 982 | + break; |
| 983 | + } |
| 984 | + check_features(&mut remaining_lib_features, tcx.defined_lib_features(cnum)); |
| 985 | + } |
998 | 986 | }
|
999 | 987 |
|
1000 | 988 | for (feature, span) in remaining_lib_features {
|
|
0 commit comments