5
5
//! item.
6
6
7
7
use crate :: errors;
8
- use rustc_ast:: { ast, AttrStyle , Attribute , Lit , LitKind , MetaItemKind , NestedMetaItem } ;
8
+ use rustc_ast:: { ast, AttrStyle , Attribute , Lit , LitKind , MetaItem , MetaItemKind , NestedMetaItem } ;
9
9
use rustc_data_structures:: fx:: FxHashMap ;
10
10
use rustc_errors:: { fluent, struct_span_err, Applicability , MultiSpan } ;
11
11
use rustc_expand:: base:: resolve_path;
@@ -25,6 +25,7 @@ use rustc_session::lint::builtin::{
25
25
CONFLICTING_REPR_HINTS , INVALID_DOC_ATTRIBUTES , UNUSED_ATTRIBUTES ,
26
26
} ;
27
27
use rustc_session:: parse:: feature_err;
28
+ use rustc_span:: edition:: Edition ;
28
29
use rustc_span:: symbol:: { kw, sym, Symbol } ;
29
30
use rustc_span:: { Span , DUMMY_SP } ;
30
31
use rustc_target:: spec:: abi:: Abi ;
@@ -945,6 +946,40 @@ impl CheckAttrVisitor<'_> {
945
946
is_valid
946
947
}
947
948
949
+ /// Checks that `doc(auto_cfg)` is valid (i.e. no value) and warn if it's used whereas the
950
+ /// "equivalent feature" is already enabled.
951
+ fn check_auto_cfg ( & self , meta : & MetaItem , hir_id : HirId ) -> bool {
952
+ let name = meta. name_or_empty ( ) ;
953
+ let mut is_valid = true ;
954
+ if !meta. is_word ( ) {
955
+ self . tcx
956
+ . sess
957
+ . emit_err ( errors:: DocAutoCfgMalformed { span : meta. span , attr_str : name. as_str ( ) } ) ;
958
+ is_valid = false ;
959
+ } else if name == sym:: no_auto_cfg {
960
+ if self . tcx . sess . edition ( ) < Edition :: Edition2024 {
961
+ self . tcx . emit_spanned_lint (
962
+ UNUSED_ATTRIBUTES ,
963
+ hir_id,
964
+ meta. span ,
965
+ errors:: DocNoAutoCfgEnabledByDefault ,
966
+ ) ;
967
+ is_valid = false ;
968
+ }
969
+ } else {
970
+ if self . tcx . sess . edition ( ) > Edition :: Edition2021 {
971
+ self . tcx . emit_spanned_lint (
972
+ UNUSED_ATTRIBUTES ,
973
+ hir_id,
974
+ meta. span ,
975
+ errors:: DocAutoCfgEnabledByDefault ,
976
+ ) ;
977
+ is_valid = false ;
978
+ }
979
+ }
980
+ is_valid
981
+ }
982
+
948
983
/// Runs various checks on `#[doc]` attributes. Returns `true` if valid.
949
984
///
950
985
/// `specified_inline` should be initialized to `None` and kept for the scope
@@ -993,6 +1028,8 @@ impl CheckAttrVisitor<'_> {
993
1028
| sym:: html_root_url
994
1029
| sym:: html_no_source
995
1030
| sym:: test
1031
+ | sym:: auto_cfg
1032
+ | sym:: no_auto_cfg
996
1033
if !self . check_attr_crate_level ( attr, meta, hir_id) =>
997
1034
{
998
1035
is_valid = false ;
@@ -1010,6 +1047,11 @@ impl CheckAttrVisitor<'_> {
1010
1047
is_valid = false ;
1011
1048
}
1012
1049
1050
+ sym:: auto_cfg | sym:: no_auto_cfg
1051
+ if !self . check_auto_cfg ( i_meta, hir_id) => {
1052
+ is_valid = false ;
1053
+ }
1054
+
1013
1055
// no_default_passes: deprecated
1014
1056
// passes: deprecated
1015
1057
// plugins: removed, but rustdoc warns about it itself
@@ -1031,6 +1073,8 @@ impl CheckAttrVisitor<'_> {
1031
1073
| sym:: notable_trait
1032
1074
| sym:: passes
1033
1075
| sym:: plugins
1076
+ | sym:: auto_cfg
1077
+ | sym:: no_auto_cfg
1034
1078
| sym:: fake_variadic => { }
1035
1079
1036
1080
sym:: test => {
0 commit comments