Unnamed repository; edit this file 'description' to name the repository.
110 files changed, 7389 insertions, 2759 deletions
diff --git a/.github/workflows/gen-lints.yml b/.github/workflows/gen-lints.yml index 7319b2b326..c978e3571c 100644 --- a/.github/workflows/gen-lints.yml +++ b/.github/workflows/gen-lints.yml @@ -13,6 +13,8 @@ jobs: lints-gen: name: Generate lints runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v6 @@ -23,9 +25,16 @@ jobs: - name: Generate lints/feature flags run: cargo codegen lint-definitions + - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 + id: app-token + with: + app-id: ${{ vars.APP_CLIENT_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Submit PR uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: + token: ${{ steps.app-token.outputs.token }} commit-message: "internal: update generated lints" branch: "ci/gen-lints" delete-branch: true diff --git a/Cargo.lock b/Cargo.lock index 770f8cb940..da530b3a93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,7 +234,6 @@ dependencies = [ "intern", "oorandom", "rustc-hash 2.1.1", - "span", "syntax", "syntax-bridge", "tracing", @@ -846,7 +845,6 @@ dependencies = [ name = "hir-expand" version = "0.0.0" dependencies = [ - "arrayvec", "base-db", "cfg", "cov-mark", @@ -2733,6 +2731,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustc-literal-escaper 0.0.4", "rustc_apfloat", + "smallvec", "smol_str 0.3.2", "stdx", "test-utils", diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml index cf2a7607b0..15de1f3293 100644 --- a/crates/cfg/Cargo.toml +++ b/crates/cfg/Cargo.toml @@ -19,7 +19,6 @@ tracing.workspace = true # locals deps tt = { workspace = true, optional = true } syntax = { workspace = true, optional = true } -span = { path = "../span", version = "0.0", optional = true } intern.workspace = true [dev-dependencies] @@ -36,7 +35,7 @@ cfg = { path = ".", default-features = false, features = ["tt"] } [features] default = [] -syntax = ["dep:syntax", "dep:span"] +syntax = ["dep:syntax"] tt = ["dep:tt"] in-rust-tree = [] diff --git a/crates/cfg/src/cfg_expr.rs b/crates/cfg/src/cfg_expr.rs index d253f6f492..7af3ed5dc9 100644 --- a/crates/cfg/src/cfg_expr.rs +++ b/crates/cfg/src/cfg_expr.rs @@ -106,10 +106,54 @@ impl CfgExpr { } #[cfg(feature = "syntax")] - pub fn parse_from_ast( - ast: &mut std::iter::Peekable<syntax::ast::TokenTreeChildren>, - ) -> CfgExpr { - next_cfg_expr_from_ast(ast).unwrap_or(CfgExpr::Invalid) + pub fn parse_from_ast(ast: syntax::ast::CfgPredicate) -> CfgExpr { + use intern::sym; + use syntax::ast::{self, AstToken}; + + match ast { + ast::CfgPredicate::CfgAtom(atom) => { + let atom = match atom.key() { + Some(ast::CfgAtomKey::True) => CfgAtom::Flag(sym::true_), + Some(ast::CfgAtomKey::False) => CfgAtom::Flag(sym::false_), + Some(ast::CfgAtomKey::Ident(key)) => { + let key = Symbol::intern(key.text()); + match atom.string_token().and_then(ast::String::cast) { + Some(value) => { + if let Ok(value) = value.value() { + CfgAtom::KeyValue { key, value: Symbol::intern(&value) } + } else { + return CfgExpr::Invalid; + } + } + None => CfgAtom::Flag(key), + } + } + None => return CfgExpr::Invalid, + }; + CfgExpr::Atom(atom) + } + ast::CfgPredicate::CfgComposite(composite) => { + let Some(keyword) = composite.keyword() else { + return CfgExpr::Invalid; + }; + match keyword.text() { + "all" => CfgExpr::All( + composite.cfg_predicates().map(CfgExpr::parse_from_ast).collect(), + ), + "any" => CfgExpr::Any( + composite.cfg_predicates().map(CfgExpr::parse_from_ast).collect(), + ), + "not" => { + let mut inner = composite.cfg_predicates(); + let (Some(inner), None) = (inner.next(), inner.next()) else { + return CfgExpr::Invalid; + }; + CfgExpr::Not(Box::new(CfgExpr::parse_from_ast(inner))) + } + _ => CfgExpr::Invalid, + } + } + } } /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates. @@ -128,65 +172,6 @@ impl CfgExpr { } } -#[cfg(feature = "syntax")] -fn next_cfg_expr_from_ast( - it: &mut std::iter::Peekable<syntax::ast::TokenTreeChildren>, -) -> Option<CfgExpr> { - use intern::sym; - use syntax::{NodeOrToken, SyntaxKind, T, ast}; - - let name = match it.next() { - None => return None, - Some(NodeOrToken::Token(ident)) if ident.kind().is_any_identifier() => { - Symbol::intern(ident.text()) - } - Some(_) => return Some(CfgExpr::Invalid), - }; - - let ret = match it.peek() { - Some(NodeOrToken::Token(eq)) if eq.kind() == T![=] => { - it.next(); - if let Some(NodeOrToken::Token(literal)) = it.peek() - && matches!(literal.kind(), SyntaxKind::STRING) - { - let dummy_span = span::Span { - range: span::TextRange::empty(span::TextSize::new(0)), - anchor: span::SpanAnchor { - file_id: span::EditionedFileId::from_raw(0), - ast_id: span::FIXUP_ERASED_FILE_AST_ID_MARKER, - }, - ctx: span::SyntaxContext::root(span::Edition::Edition2015), - }; - let literal = - Symbol::intern(tt::token_to_literal(literal.text(), dummy_span).text()); - it.next(); - CfgAtom::KeyValue { key: name, value: literal.clone() }.into() - } else { - return Some(CfgExpr::Invalid); - } - } - Some(NodeOrToken::Node(subtree)) => { - let mut subtree_iter = ast::TokenTreeChildren::new(subtree).peekable(); - it.next(); - let mut subs = std::iter::from_fn(|| next_cfg_expr_from_ast(&mut subtree_iter)); - match name { - s if s == sym::all => CfgExpr::All(subs.collect()), - s if s == sym::any => CfgExpr::Any(subs.collect()), - s if s == sym::not => { - CfgExpr::Not(Box::new(subs.next().unwrap_or(CfgExpr::Invalid))) - } - _ => CfgExpr::Invalid, - } - } - _ => CfgAtom::Flag(name).into(), - }; - - // Eat comma separator - while it.next().is_some_and(|it| it.as_token().is_none_or(|it| it.kind() != T![,])) {} - - Some(ret) -} - #[cfg(feature = "tt")] fn next_cfg_expr(it: &mut tt::iter::TtIter<'_>) -> Option<CfgExpr> { use intern::sym; diff --git a/crates/cfg/src/tests.rs b/crates/cfg/src/tests.rs index 52c581dbbd..bfc9220a05 100644 --- a/crates/cfg/src/tests.rs +++ b/crates/cfg/src/tests.rs @@ -1,10 +1,7 @@ use arbitrary::{Arbitrary, Unstructured}; use expect_test::{Expect, expect}; use intern::Symbol; -use syntax::{ - AstNode, Edition, - ast::{self, TokenTreeChildren}, -}; +use syntax::{AstNode, Edition, ast}; use syntax_bridge::{ DocCommentDesugarMode, dummy_test_span_utils::{DUMMY, DummyTestSpanMap}, @@ -14,32 +11,32 @@ use syntax_bridge::{ use crate::{CfgAtom, CfgExpr, CfgOptions, DnfExpr}; #[track_caller] -fn parse_ast_cfg(tt: &ast::TokenTree) -> CfgExpr { - CfgExpr::parse_from_ast(&mut TokenTreeChildren::new(tt).peekable()) +fn parse_ast_cfg(pred: ast::CfgPredicate) -> CfgExpr { + CfgExpr::parse_from_ast(pred) } #[track_caller] fn assert_parse_result(input: &str, expected: CfgExpr) { - let source_file = ast::SourceFile::parse(input, Edition::CURRENT).ok().unwrap(); - let tt_ast = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); + let source_file = ast::SourceFile::parse(input, Edition::CURRENT).syntax_node(); + let pred_ast = source_file.descendants().find_map(ast::CfgPredicate::cast).unwrap(); let tt = syntax_node_to_token_tree( - tt_ast.syntax(), + pred_ast.syntax(), DummyTestSpanMap, DUMMY, DocCommentDesugarMode::ProcMacro, ); let cfg = CfgExpr::parse(&tt); assert_eq!(cfg, expected); - let cfg = parse_ast_cfg(&tt_ast); + let cfg = parse_ast_cfg(pred_ast); assert_eq!(cfg, expected); } #[track_caller] fn check_dnf(input: &str, expect: Expect) { let source_file = ast::SourceFile::parse(input, Edition::CURRENT).ok().unwrap(); - let tt_ast = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); + let pred_ast = source_file.syntax().descendants().find_map(ast::CfgPredicate::cast).unwrap(); let tt = syntax_node_to_token_tree( - tt_ast.syntax(), + pred_ast.syntax(), DummyTestSpanMap, DUMMY, DocCommentDesugarMode::ProcMacro, @@ -47,7 +44,7 @@ fn check_dnf(input: &str, expect: Expect) { let cfg = CfgExpr::parse(&tt); let actual = format!("#![cfg({})]", DnfExpr::new(&cfg)); expect.assert_eq(&actual); - let cfg = parse_ast_cfg(&tt_ast); + let cfg = parse_ast_cfg(pred_ast); let actual = format!("#![cfg({})]", DnfExpr::new(&cfg)); expect.assert_eq(&actual); } @@ -55,9 +52,9 @@ fn check_dnf(input: &str, expect: Expect) { #[track_caller] fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) { let source_file = ast::SourceFile::parse(input, Edition::CURRENT).ok().unwrap(); - let tt_ast = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); + let pred_ast = source_file.syntax().descendants().find_map(ast::CfgPredicate::cast).unwrap(); let tt = syntax_node_to_token_tree( - tt_ast.syntax(), + pred_ast.syntax(), DummyTestSpanMap, DUMMY, DocCommentDesugarMode::ProcMacro, @@ -66,7 +63,7 @@ fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) { let dnf = DnfExpr::new(&cfg); let why_inactive = dnf.why_inactive(opts).unwrap().to_string(); expect.assert_eq(&why_inactive); - let cfg = parse_ast_cfg(&tt_ast); + let cfg = parse_ast_cfg(pred_ast); let dnf = DnfExpr::new(&cfg); let why_inactive = dnf.why_inactive(opts).unwrap().to_string(); expect.assert_eq(&why_inactive); @@ -75,9 +72,9 @@ fn check_why_inactive(input: &str, opts: &CfgOptions, expect: Expect) { #[track_caller] fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) { let source_file = ast::SourceFile::parse(input, Edition::CURRENT).ok().unwrap(); - let tt_ast = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); + let pred_ast = source_file.syntax().descendants().find_map(ast::CfgPredicate::cast).unwrap(); let tt = syntax_node_to_token_tree( - tt_ast.syntax(), + pred_ast.syntax(), DummyTestSpanMap, DUMMY, DocCommentDesugarMode::ProcMacro, @@ -86,7 +83,7 @@ fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) { let dnf = DnfExpr::new(&cfg); let hints = dnf.compute_enable_hints(opts).map(|diff| diff.to_string()).collect::<Vec<_>>(); assert_eq!(hints, expected_hints); - let cfg = parse_ast_cfg(&tt_ast); + let cfg = parse_ast_cfg(pred_ast); let dnf = DnfExpr::new(&cfg); let hints = dnf.compute_enable_hints(opts).map(|diff| diff.to_string()).collect::<Vec<_>>(); assert_eq!(hints, expected_hints); @@ -119,20 +116,6 @@ fn test_cfg_expr_parser() { .into_boxed_slice(), ), ); - - assert_parse_result( - r#"#![cfg(any(not(), all(), , bar = "baz",))]"#, - CfgExpr::Any( - vec![ - CfgExpr::Not(Box::new(CfgExpr::Invalid)), - CfgExpr::All(Box::new([])), - CfgExpr::Invalid, - CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") } - .into(), - ] - .into_boxed_slice(), - ), - ); } #[test] diff --git a/crates/hir-def/src/attrs.rs b/crates/hir-def/src/attrs.rs index dddfe8cefd..b560d08492 100644 --- a/crates/hir-def/src/attrs.rs +++ b/crates/hir-def/src/attrs.rs @@ -22,7 +22,7 @@ use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ InFile, Lookup, - attrs::{Meta, expand_cfg_attr}, + attrs::{AstKeyValueMetaExt, AstPathExt, expand_cfg_attr}, }; use intern::Symbol; use itertools::Itertools; @@ -128,63 +128,89 @@ fn extract_rustc_skip_during_method_dispatch(attr_flags: &mut AttrFlags, tt: ast } #[inline] -fn match_attr_flags(attr_flags: &mut AttrFlags, attr: Meta) -> ControlFlow<Infallible> { +fn match_attr_flags(attr_flags: &mut AttrFlags, attr: ast::Meta) -> ControlFlow<Infallible> { match attr { - Meta::NamedKeyValue { name: Some(name), value, .. } => match name.text() { - "deprecated" => attr_flags.insert(AttrFlags::IS_DEPRECATED), - "ignore" => attr_flags.insert(AttrFlags::IS_IGNORE), - "lang" => attr_flags.insert(AttrFlags::LANG_ITEM), - "path" => attr_flags.insert(AttrFlags::HAS_PATH), - "unstable" => attr_flags.insert(AttrFlags::IS_UNSTABLE), - "export_name" => { - if let Some(value) = value - && let Some(value) = ast::String::cast(value) - && let Ok(value) = value.value() - && *value == *"main" - { - attr_flags.insert(AttrFlags::IS_EXPORT_NAME_MAIN); - } - } - _ => {} - }, - Meta::TokenTree { path, tt } => match path.segments.len() { - 1 => match path.segments[0].text() { + ast::Meta::CfgMeta(_) => attr_flags.insert(AttrFlags::HAS_CFG), + ast::Meta::KeyValueMeta(attr) => { + let Some(key) = attr.path().as_one_segment() else { return ControlFlow::Continue(()) }; + match &*key { "deprecated" => attr_flags.insert(AttrFlags::IS_DEPRECATED), - "cfg" => attr_flags.insert(AttrFlags::HAS_CFG), - "doc" => extract_doc_tt_attr(attr_flags, tt), - "repr" => attr_flags.insert(AttrFlags::HAS_REPR), - "target_feature" => attr_flags.insert(AttrFlags::HAS_TARGET_FEATURE), - "proc_macro_derive" | "rustc_builtin_macro" => { - attr_flags.insert(AttrFlags::IS_DERIVE_OR_BUILTIN_MACRO) - } + "ignore" => attr_flags.insert(AttrFlags::IS_IGNORE), + "lang" => attr_flags.insert(AttrFlags::LANG_ITEM), + "path" => attr_flags.insert(AttrFlags::HAS_PATH), "unstable" => attr_flags.insert(AttrFlags::IS_UNSTABLE), - "rustc_layout_scalar_valid_range_start" | "rustc_layout_scalar_valid_range_end" => { - attr_flags.insert(AttrFlags::RUSTC_LAYOUT_SCALAR_VALID_RANGE) - } - "rustc_legacy_const_generics" => { - attr_flags.insert(AttrFlags::HAS_LEGACY_CONST_GENERICS) - } - "rustc_skip_during_method_dispatch" => { - extract_rustc_skip_during_method_dispatch(attr_flags, tt) - } - "rustc_deprecated_safe_2024" => { - attr_flags.insert(AttrFlags::RUSTC_DEPRECATED_SAFE_2024) + "export_name" => { + if let Some(value) = attr.value_string() + && *value == *"main" + { + attr_flags.insert(AttrFlags::IS_EXPORT_NAME_MAIN); + } } _ => {} - }, - 2 => match path.segments[0].text() { - "rust_analyzer" => match path.segments[1].text() { - "completions" => extract_ra_completions(attr_flags, tt), - "macro_style" => extract_ra_macro_style(attr_flags, tt), + } + } + ast::Meta::TokenTreeMeta(attr) => { + let (Some((first_segment, second_segment)), Some(tt)) = + (attr.path().as_up_to_two_segment(), attr.token_tree()) + else { + return ControlFlow::Continue(()); + }; + match second_segment { + None => match &*first_segment { + "deprecated" => attr_flags.insert(AttrFlags::IS_DEPRECATED), + "doc" => extract_doc_tt_attr(attr_flags, tt), + "repr" => attr_flags.insert(AttrFlags::HAS_REPR), + "target_feature" => attr_flags.insert(AttrFlags::HAS_TARGET_FEATURE), + "proc_macro_derive" | "rustc_builtin_macro" => { + attr_flags.insert(AttrFlags::IS_DERIVE_OR_BUILTIN_MACRO) + } + "unstable" => attr_flags.insert(AttrFlags::IS_UNSTABLE), + "rustc_layout_scalar_valid_range_start" + | "rustc_layout_scalar_valid_range_end" => { + attr_flags.insert(AttrFlags::RUSTC_LAYOUT_SCALAR_VALID_RANGE) + } + "rustc_legacy_const_generics" => { + attr_flags.insert(AttrFlags::HAS_LEGACY_CONST_GENERICS) + } + "rustc_skip_during_method_dispatch" => { + extract_rustc_skip_during_method_dispatch(attr_flags, tt) + } + "rustc_deprecated_safe_2024" => { + attr_flags.insert(AttrFlags::RUSTC_DEPRECATED_SAFE_2024) + } _ => {} }, - _ => {} - }, - _ => {} - }, - Meta::Path { path } => { - match path.segments.len() { - 1 => match path.segments[0].text() { + Some(second_segment) => match &*first_segment { + "rust_analyzer" => match &*second_segment { + "completions" => extract_ra_completions(attr_flags, tt), + "macro_style" => extract_ra_macro_style(attr_flags, tt), + _ => {} + }, + _ => {} + }, + } + } + ast::Meta::PathMeta(attr) => { + let is_test = attr.path().is_some_and(|path| { + let Some(segment1) = (|| path.segment()?.name_ref())() else { return false }; + let segment2 = path.qualifier(); + let segment3 = segment2.as_ref().and_then(|it| it.qualifier()); + let segment4 = segment3.as_ref().and_then(|it| it.qualifier()); + let segment3 = segment3.and_then(|it| it.segment()?.name_ref()); + let segment4 = segment4.and_then(|it| it.segment()?.name_ref()); + segment1.text() == "test" + && segment3.is_none_or(|it| it.text() == "prelude") + && segment4.is_none_or(|it| it.text() == "core") + }); + if is_test { + attr_flags.insert(AttrFlags::IS_TEST); + } + + let Some((first_segment, second_segment)) = attr.path().as_up_to_two_segment() else { + return ControlFlow::Continue(()); + }; + match second_segment { + None => match &*first_segment { "rustc_has_incoherent_inherent_impls" => { attr_flags.insert(AttrFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS) } @@ -228,18 +254,13 @@ fn match_attr_flags(attr_flags: &mut AttrFlags, attr: Meta) -> ControlFlow<Infal } _ => {} }, - 2 => match path.segments[0].text() { - "rust_analyzer" => match path.segments[1].text() { + Some(second_segment) => match &*first_segment { + "rust_analyzer" => match &*second_segment { "skip" => attr_flags.insert(AttrFlags::RUST_ANALYZER_SKIP), _ => {} }, _ => {} }, - _ => {} - } - - if path.is_test { - attr_flags.insert(AttrFlags::IS_TEST); } } _ => {} @@ -420,7 +441,7 @@ fn resolver_for_attr_def_id(db: &dyn DefDatabase, owner: AttrDefId) -> Resolver< fn collect_attrs<BreakValue>( db: &dyn DefDatabase, owner: AttrDefId, - mut callback: impl FnMut(Meta) -> ControlFlow<BreakValue>, + mut callback: impl FnMut(ast::Meta) -> ControlFlow<BreakValue>, ) -> Option<BreakValue> { let (source, outer_mod_decl, extra_crate_attrs, krate) = attrs_source(db, owner); let extra_attrs = extra_crate_attrs @@ -432,7 +453,7 @@ fn collect_attrs<BreakValue>( expand_cfg_attr( extra_attrs.chain(ast::attrs_including_inner(&source.value)), || cfg_options.get_or_insert_with(|| krate.cfg_options(db)), - move |meta, _, _, _| callback(meta), + move |meta, _| callback(meta), ) } @@ -500,9 +521,10 @@ pub struct DeriveInfo { pub helpers: Box<[Symbol]>, } -fn extract_doc_aliases(result: &mut Vec<Symbol>, attr: Meta) -> ControlFlow<Infallible> { - if let Meta::TokenTree { path, tt } = attr - && path.is1("doc") +fn extract_doc_aliases(result: &mut Vec<Symbol>, attr: ast::Meta) -> ControlFlow<Infallible> { + if let ast::Meta::TokenTreeMeta(attr) = attr + && attr.path().is1("doc") + && let Some(tt) = attr.token_tree() { for atom in DocAtom::parse(tt) { match atom { @@ -519,11 +541,11 @@ fn extract_doc_aliases(result: &mut Vec<Symbol>, attr: Meta) -> ControlFlow<Infa ControlFlow::Continue(()) } -fn extract_cfgs(result: &mut Vec<CfgExpr>, attr: Meta) -> ControlFlow<Infallible> { - if let Meta::TokenTree { path, tt } = attr - && path.is1("cfg") +fn extract_cfgs(result: &mut Vec<CfgExpr>, attr: ast::Meta) -> ControlFlow<Infallible> { + if let ast::Meta::CfgMeta(attr) = attr + && let Some(cfg_predicate) = attr.cfg_predicate() { - result.push(CfgExpr::parse_from_ast(&mut TokenTreeChildren::new(&tt).peekable())); + result.push(CfgExpr::parse_from_ast(cfg_predicate)); } ControlFlow::Continue(()) } @@ -554,7 +576,7 @@ impl AttrFlags { expand_cfg_attr( field.value.attrs(), || cfg_options, - |attr, _, _, _| match_attr_flags(&mut attr_flags, attr), + |attr, _| match_attr_flags(&mut attr_flags, attr), ); attr_flags }) @@ -591,7 +613,7 @@ impl AttrFlags { let lifetimes_source = HasChildSource::<LocalLifetimeParamId>::child_source(&def, db); for (lifetime_id, lifetime) in lifetimes_source.value.iter() { let mut attr_flags = AttrFlags::empty(); - expand_cfg_attr(lifetime.attrs(), &mut cfg_options, |attr, _, _, _| { + expand_cfg_attr(lifetime.attrs(), &mut cfg_options, |attr, _| { match_attr_flags(&mut attr_flags, attr) }); if !attr_flags.is_empty() { @@ -603,7 +625,7 @@ impl AttrFlags { HasChildSource::<LocalTypeOrConstParamId>::child_source(&def, db); for (type_or_const_id, type_or_const) in type_and_consts_source.value.iter() { let mut attr_flags = AttrFlags::empty(); - expand_cfg_attr(type_or_const.attrs(), &mut cfg_options, |attr, _, _, _| { + expand_cfg_attr(type_or_const.attrs(), &mut cfg_options, |attr, _| { match_attr_flags(&mut attr_flags, attr) }); if !attr_flags.is_empty() { @@ -642,11 +664,10 @@ impl AttrFlags { let result = expand_cfg_attr( attrs, || cfg_options, - |attr, _, _, _| { - if let Meta::TokenTree { path, tt } = attr - && path.is1("cfg") - && let cfg = - CfgExpr::parse_from_ast(&mut TokenTreeChildren::new(&tt).peekable()) + |attr, _| { + if let ast::Meta::CfgMeta(attr) = attr + && let Some(cfg_predicate) = attr.cfg_predicate() + && let cfg = CfgExpr::parse_from_ast(cfg_predicate) && cfg_options.check(&cfg) == Some(false) { ControlFlow::Break(cfg) @@ -678,10 +699,9 @@ impl AttrFlags { #[salsa::tracked] fn lang_item(db: &dyn DefDatabase, owner: AttrDefId) -> Option<Symbol> { collect_attrs(db, owner, |attr| { - if let Meta::NamedKeyValue { name: Some(name), value: Some(value), .. } = attr - && name.text() == "lang" - && let Some(value) = ast::String::cast(value) - && let Ok(value) = value.value() + if let ast::Meta::KeyValueMeta(attr) = attr + && attr.path().is1("lang") + && let Some(value) = attr.value_string() { ControlFlow::Break(Symbol::intern(&value)) } else { @@ -704,8 +724,9 @@ impl AttrFlags { fn repr(db: &dyn DefDatabase, owner: AdtId) -> Option<ReprOptions> { let mut result = None; collect_attrs::<Infallible>(db, owner.into(), |attr| { - if let Meta::TokenTree { path, tt } = attr - && path.is1("repr") + if let ast::Meta::TokenTreeMeta(attr) = attr + && attr.path().is1("repr") + && let Some(tt) = attr.token_tree() && let Some(repr) = parse_repr_tt(&tt) { match &mut result { @@ -726,8 +747,9 @@ impl AttrFlags { owner: FunctionId, ) -> Option<Box<[u32]>> { let result = collect_attrs(db, owner.into(), |attr| { - if let Meta::TokenTree { path, tt } = attr - && path.is1("rustc_legacy_const_generics") + if let ast::Meta::TokenTreeMeta(attr) = attr + && attr.path().is1("rustc_legacy_const_generics") + && let Some(tt) = attr.token_tree() { let result = parse_rustc_legacy_const_generics(tt); ControlFlow::Break(result) @@ -750,9 +772,10 @@ impl AttrFlags { expand_cfg_attr( extra_crate_attrs.chain(syntax.attrs()), || cfg_options.get_or_insert(krate.cfg_options(db)), - |attr, _, _, _| { - if let Meta::TokenTree { path, tt } = attr - && path.is1("doc") + |attr, _| { + if let ast::Meta::TokenTreeMeta(attr) = attr + && attr.path().is1("doc") + && let Some(tt) = attr.token_tree() && let Some(result) = DocAtom::parse(tt).into_iter().find_map(|atom| { if let DocAtom::KeyValue { key, value } = atom && key == "html_root_url" @@ -783,8 +806,9 @@ impl AttrFlags { fn target_features(db: &dyn DefDatabase, owner: FunctionId) -> FxHashSet<Symbol> { let mut result = FxHashSet::default(); collect_attrs::<Infallible>(db, owner.into(), |attr| { - if let Meta::TokenTree { path, tt } = attr - && path.is1("target_feature") + if let ast::Meta::TokenTreeMeta(attr) = attr + && attr.path().is1("target_feature") + && let Some(tt) = attr.token_tree() { let mut tt = TokenTreeChildren::new(&tt); while let Some(NodeOrToken::Token(enable_ident)) = tt.next() @@ -831,9 +855,11 @@ impl AttrFlags { ) -> RustcLayoutScalarValidRange { let mut result = RustcLayoutScalarValidRange::default(); collect_attrs::<Infallible>(db, owner.into(), |attr| { - if let Meta::TokenTree { path, tt } = attr + if let ast::Meta::TokenTreeMeta(attr) = attr + && let path = attr.path() && (path.is1("rustc_layout_scalar_valid_range_start") || path.is1("rustc_layout_scalar_valid_range_end")) + && let Some(tt) = attr.token_tree() && let tt = TokenTreeChildren::new(&tt) && let Ok(NodeOrToken::Token(value)) = Itertools::exactly_one(tt) && let Some(value) = ast::IntNumber::cast(value) @@ -881,7 +907,7 @@ impl AttrFlags { expand_cfg_attr( field.value.attrs(), || cfg_options, - |attr, _, _, _| extract_doc_aliases(&mut result, attr), + |attr, _| extract_doc_aliases(&mut result, attr), ); result.into_boxed_slice() }) @@ -923,7 +949,7 @@ impl AttrFlags { expand_cfg_attr( field.value.attrs(), || cfg_options, - |attr, _, _, _| extract_cfgs(&mut result, attr), + |attr, _| extract_cfgs(&mut result, attr), ); match result.len() { 0 => None, @@ -944,8 +970,9 @@ impl AttrFlags { #[salsa::tracked] fn doc_keyword(db: &dyn DefDatabase, owner: ModuleId) -> Option<Symbol> { collect_attrs(db, AttrDefId::ModuleId(owner), |attr| { - if let Meta::TokenTree { path, tt } = attr - && path.is1("doc") + if let ast::Meta::TokenTreeMeta(attr) = attr + && attr.path().is1("doc") + && let Some(tt) = attr.token_tree() { for atom in DocAtom::parse(tt) { if let DocAtom::KeyValue { key, value } = atom @@ -1015,12 +1042,10 @@ impl AttrFlags { #[salsa::tracked(returns(ref))] fn derive_info(db: &dyn DefDatabase, owner: MacroId) -> Option<DeriveInfo> { collect_attrs(db, owner.into(), |attr| { - if let Meta::TokenTree { path, tt } = attr - && path.segments.len() == 1 - && matches!( - path.segments[0].text(), - "proc_macro_derive" | "rustc_builtin_macro" - ) + if let ast::Meta::TokenTreeMeta(attr) = attr + && (attr.path().is1("proc_macro_derive") + || attr.path().is1("rustc_builtin_macro")) + && let Some(tt) = attr.token_tree() && let mut tt = TokenTreeChildren::new(&tt) && let Some(NodeOrToken::Token(trait_name)) = tt.next() && trait_name.kind().is_any_identifier() diff --git a/crates/hir-def/src/attrs/docs.rs b/crates/hir-def/src/attrs/docs.rs index 8c14808c71..9a715b1968 100644 --- a/crates/hir-def/src/attrs/docs.rs +++ b/crates/hir-def/src/attrs/docs.rs @@ -16,7 +16,7 @@ use cfg::CfgOptions; use either::Either; use hir_expand::{ AstId, ExpandTo, HirFileId, InFile, - attrs::{Meta, expand_cfg_attr_with_doc_comments}, + attrs::{AstPathExt, expand_cfg_attr_with_doc_comments}, mod_path::ModPath, span_map::SpanMap, }; @@ -182,8 +182,7 @@ impl Docs { self.extend_with_doc_str(doc, comment.syntax().text_range().start() + offset, indent); } - fn extend_with_doc_attr(&mut self, value: syntax::SyntaxToken, indent: &mut usize) { - let Some(value) = ast::String::cast(value) else { return }; + fn extend_with_doc_attr(&mut self, value: ast::String, indent: &mut usize) { let Some(value_offset) = value.text_range_between_quotes() else { return }; let value_offset = value_offset.start(); let Ok(value) = value.value() else { return }; @@ -423,10 +422,6 @@ fn extend_with_attrs<'a, 'db>( // Lazily initialised when we first encounter a `#[doc = macro!()]`. let mut expander: Option<(DocMacroExpander<'db>, DocExprSourceCtx<'db>)> = None; - // FIXME: `#[cfg_attr(..., doc = macro!())]` skips macro expansion because - // `top_attr` points to the `cfg_attr` node, not the inner `doc = macro!()`. - // Fixing this is difficult as we need an `Expr` that doesn't exist here for - // the ast id and for sanely parsing the macro call. expand_cfg_attr_with_doc_comments::<_, Infallible>( AttrDocCommentIter::from_syntax_node(node).filter(|attr| match attr { Either::Left(attr) => attr.kind().is_inner() == expect_inner_attrs, @@ -439,46 +434,38 @@ fn extend_with_attrs<'a, 'db>( |attr| { match attr { Either::Right(doc_comment) => result.extend_with_doc_comment(doc_comment, indent), - Either::Left((attr, _, _, top_attr)) => match attr { - Meta::NamedKeyValue { name: Some(name), value: Some(value), .. } - if name.text() == "doc" => - { - result.extend_with_doc_attr(value, indent); - } - Meta::NamedKeyValue { name: Some(name), value: None, .. } - if name.text() == "doc" => - { - // When the doc attribute comes from inside a `cfg_attr`, - // `top_attr` points to the `cfg_attr(...)` node, not the - // inner `doc = macro!()`. In that case `top_attr.expr()` - // would not yield the macro expression we need, so skip - // expansion (see FIXME above). - let is_from_cfg_attr = - top_attr.as_simple_call().is_some_and(|(name, _)| name == "cfg_attr"); - if !is_from_cfg_attr && let Some(expr) = top_attr.expr() { - let (exp, ctx) = expander.get_or_insert_with(|| { - let resolver = make_resolver(); - let def_map = resolver.top_level_def_map(); - let recursion_limit = def_map.recursion_limit() as usize; - ( - DocMacroExpander { - db, - krate, - recursion_depth: 0, - recursion_limit, - }, - DocExprSourceCtx { - resolver, - file_id, - ast_id_map: db.ast_id_map(file_id), - span_map: db.span_map(file_id), - }, - ) - }); - if let Some(expanded) = - expand_doc_expr_via_macro_pipeline(exp, ctx, expr) + Either::Left((attr, _)) => match attr { + ast::Meta::KeyValueMeta(attr) if attr.path().is1("doc") => { + if let Some(value) = attr.expr() { + if let ast::Expr::Literal(value) = &value + && let ast::LiteralKind::String(value) = value.kind() { - result.extend_with_unmapped_doc_str(&expanded, indent); + result.extend_with_doc_attr(value, indent); + } else { + let (exp, ctx) = expander.get_or_insert_with(|| { + let resolver = make_resolver(); + let def_map = resolver.top_level_def_map(); + let recursion_limit = def_map.recursion_limit() as usize; + ( + DocMacroExpander { + db, + krate, + recursion_depth: 0, + recursion_limit, + }, + DocExprSourceCtx { + resolver, + file_id, + ast_id_map: db.ast_id_map(file_id), + span_map: db.span_map(file_id), + }, + ) + }); + if let Some(expanded) = + expand_doc_expr_via_macro_pipeline(exp, ctx, value) + { + result.extend_with_unmapped_doc_str(&expanded, indent); + } } } } diff --git a/crates/hir-def/src/dyn_map.rs b/crates/hir-def/src/dyn_map.rs index 4308d0ef1c..c38ceccd1f 100644 --- a/crates/hir-def/src/dyn_map.rs +++ b/crates/hir-def/src/dyn_map.rs @@ -68,7 +68,7 @@ pub mod keys { pub const MACRO_CALL: Key<ast::MacroCall, MacroCallId> = Key::new(); pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new(); pub const DERIVE_MACRO_CALL: Key< - ast::Attr, + ast::Meta, ( AttrId, /* derive() */ MacroCallId, diff --git a/crates/hir-def/src/item_tree/attrs.rs b/crates/hir-def/src/item_tree/attrs.rs index 7907611284..867d813e3f 100644 --- a/crates/hir-def/src/item_tree/attrs.rs +++ b/crates/hir-def/src/item_tree/attrs.rs @@ -13,12 +13,12 @@ use std::{ use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ - attrs::{Attr, AttrId, AttrInput, Meta, collect_item_tree_attrs}, + attrs::{Attr, AttrId, AttrInput, collect_item_tree_attrs}, mod_path::ModPath, name::Name, }; use intern::{Interned, Symbol, sym}; -use syntax::{AstNode, T, ast}; +use syntax::{AstNode, ast}; use syntax_bridge::DocCommentDesugarMode; use tt::token_to_literal; @@ -51,58 +51,62 @@ impl AttrsOrCfg { S: syntax_bridge::SpanMapper + Copy, { let mut attrs = Vec::new(); - let result = - collect_item_tree_attrs::<Infallible>(owner, cfg_options, |meta, container, _, _| { - // NOTE: We cannot early return from this function, *every* attribute must be pushed, otherwise we'll mess the `AttrId` - // tracking. - let (span, path_range, input) = match meta { - Meta::NamedKeyValue { path_range, name: _, value } => { - let span = span_map.span_for(path_range); - let input = value.map(|value| { - Box::new(AttrInput::Literal(token_to_literal( - value.text(), - span_map.span_for(value.text_range()), - ))) - }); - (span, path_range, input) - } - Meta::TokenTree { path, tt } => { - let span = span_map.span_for(path.range); - let tt = syntax_bridge::syntax_node_to_token_tree( - tt.syntax(), - span_map, - span, - DocCommentDesugarMode::ProcMacro, - ); - let input = Some(Box::new(AttrInput::TokenTree(tt))); - (span, path.range, input) - } - Meta::Path { path } => { - let span = span_map.span_for(path.range); - (span, path.range, None) - } - }; + let result = collect_item_tree_attrs::<Infallible>(owner, cfg_options, |meta, _| { + // NOTE: We cannot early return from this function, *every* attribute must be pushed, otherwise we'll mess the `AttrId` + // tracking. + let path = meta.path(); + let path_range = path + .as_ref() + .map(|path| path.syntax().text_range()) + .unwrap_or_else(|| meta.syntax().text_range()); + let (span, input) = match &meta { + ast::Meta::KeyValueMeta(meta) => { + let span = span_map.span_for(path_range); + let input = meta.expr().and_then(|value| { + if let ast::Expr::Literal(value) = value { + Some(Box::new(AttrInput::Literal(token_to_literal( + value.token().text(), + span_map.span_for(value.syntax().text_range()), + )))) + } else { + None + } + }); + (span, input) + } + ast::Meta::TokenTreeMeta(meta) => { + let span = span_map.span_for(path_range); + let tt = syntax_bridge::syntax_node_to_token_tree( + &meta + .token_tree() + .map(|it| it.syntax().clone()) + .unwrap_or_else(|| meta.syntax().clone()), + span_map, + span, + DocCommentDesugarMode::ProcMacro, + ); + let input = Some(Box::new(AttrInput::TokenTree(tt))); + (span, input) + } + ast::Meta::PathMeta(_) => { + let span = span_map.span_for(path_range); + (span, None) + } + ast::Meta::CfgMeta(_) | ast::Meta::CfgAttrMeta(_) | ast::Meta::UnsafeMeta(_) => { + unreachable!( + "`cfg`, `cfg_attr` and `unsafe(...)` are handled in `collect_item_tree_attrs()`" + ) + } + }; - let path = container.token_at_offset(path_range.start()).right_biased().and_then( - |first_path_token| { - let is_abs = matches!(first_path_token.kind(), T![:] | T![::]); - let segments = - std::iter::successors(Some(first_path_token), |it| it.next_token()) - .take_while(|it| it.text_range().end() <= path_range.end()) - .filter(|it| it.kind().is_any_identifier()); - ModPath::from_tokens( - db, - &mut |range| span_map.span_for(range).ctx, - is_abs, - segments, - ) - }, - ); - let path = path.unwrap_or_else(|| Name::missing().into()); - - attrs.push(Attr { path: Interned::new(path), input, ctxt: span.ctx }); - ControlFlow::Continue(()) + let path = path.and_then(|path| { + ModPath::from_src(db, path, &mut |range| span_map.span_for(range).ctx) }); + let path = path.unwrap_or_else(|| Name::missing().into()); + + attrs.push(Attr { path: Interned::new(path), input, ctxt: span.ctx }); + ControlFlow::Continue(()) + }); let attrs = AttrsOwned(attrs.into_boxed_slice()); match result { Some(Either::Right(cfg)) => AttrsOrCfg::CfgDisabled(Box::new((cfg, attrs))), diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs index 7b5d0103e6..e75c96b630 100644 --- a/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs @@ -1198,7 +1198,7 @@ m! { hello::world } macro_rules! m { ($m:meta) => ( #[$m] fn bar() {} ) } -#[cfg(target_os = "windows")] fn bar() {} +#[cfg (target_os = "windows")] fn bar() {} #[hello::world] fn bar() {} "#]], ); diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs index ddabb50251..cac248f47f 100644 --- a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs +++ b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs @@ -205,7 +205,7 @@ impl Clone for D3DVSHADERCAPS2_0 { *self } } -#[cfg(feature = "impl-default")] impl Default for D3DVSHADERCAPS2_0 { +#[cfg (feature = "impl-default")] impl Default for D3DVSHADERCAPS2_0 { #[inline] fn default() -> D3DVSHADERCAPS2_0 { unsafe { $crate::_core::mem::zeroed() @@ -215,7 +215,7 @@ impl Clone for D3DVSHADERCAPS2_0 { #[repr(C)] #[derive(Copy)] -#[cfg_attr(target_arch = "x86", repr(packed))] pub struct D3DCONTENTPROTECTIONCAPS { +#[cfg_attr (target_arch = "x86", repr(packed))] pub struct D3DCONTENTPROTECTIONCAPS { pub Caps: u8, } impl Clone for D3DCONTENTPROTECTIONCAPS { @@ -223,7 +223,7 @@ impl Clone for D3DCONTENTPROTECTIONCAPS { *self } } -#[cfg(feature = "impl-default")] impl Default for D3DCONTENTPROTECTIONCAPS { +#[cfg (feature = "impl-default")] impl Default for D3DCONTENTPROTECTIONCAPS { #[inline] fn default() -> D3DCONTENTPROTECTIONCAPS { unsafe { $crate::_core::mem::zeroed() @@ -1001,8 +1001,8 @@ macro_rules! with_std { ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*) } -#[cfg(feature = "std")] mod m; -#[cfg(feature = "std")] mod f; +#[cfg (feature = "std")] mod m; +#[cfg (feature = "std")] mod f; "#]], ) } diff --git a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs index bf04a500a5..8c91cf6793 100644 --- a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs +++ b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs @@ -55,8 +55,8 @@ mod foo { # ![doc = "123..."] # ![attr2] # ![attr3] - #[cfg_attr(true , cfg(false ))] fn foo() {} - #[cfg(true )] fn bar() {} + #[cfg_attr (true , cfg (false ))] fn foo() {} + #[cfg (true )] fn bar() {} }"##]], ); } diff --git a/crates/hir-expand/Cargo.toml b/crates/hir-expand/Cargo.toml index 4fa476afb6..43b0bea891 100644 --- a/crates/hir-expand/Cargo.toml +++ b/crates/hir-expand/Cargo.toml @@ -23,7 +23,6 @@ triomphe.workspace = true query-group.workspace = true salsa.workspace = true salsa-macros.workspace = true -arrayvec.workspace = true thin-vec.workspace = true # local deps diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs index e3f10b2129..49baecb90c 100644 --- a/crates/hir-expand/src/attrs.rs +++ b/crates/hir-expand/src/attrs.rs @@ -4,20 +4,8 @@ //! [`expand_cfg_attr_with_doc_comments()`]. It is used to implement all attribute lowering //! in r-a. Its basic job is to list attributes; however, attributes do not necessarily map //! into [`ast::Attr`], because `cfg_attr` can map to zero, one, or more attributes -//! (`#[cfg_attr(predicate, attr1, attr2, ...)]`). To bridge this gap, this module defines -//! [`Meta`], which represents a desugared attribute. Various bits of r-a need different -//! things from [`Meta`], therefore it contains many parts. The basic idea is: -//! -//! - There are three kinds of attributes, `path = value`, `path`, and `path(token_tree)`. -//! - Most bits of rust-analyzer only need to deal with some paths. Therefore, we keep -//! the path only if it has up to 2 segments, or one segment for `path = value`. -//! We also only keep the value in `path = value` if it is a literal. However, we always -//! save the all relevant ranges of attributes (the path range, and the full attribute range) -//! for parts of r-a (e.g. name resolution) that need a faithful representation of the -//! attribute. -//! -//! [`expand_cfg_attr()`] expands `cfg_attr`s as it goes (as its name implies), to list -//! all attributes. +//! (`#[cfg_attr(predicate, attr1, attr2, ...)]`). [`expand_cfg_attr()`] expands `cfg_attr`s +//! as it goes (as its name implies), to list all attributes. //! //! Another thing to note is that we need to be able to map an attribute back to a range //! (for diagnostic purposes etc.). This is only ever needed for attributes that participate @@ -26,26 +14,18 @@ //! place (here) and one function ([`is_item_tree_filtered_attr()`]) that decides whether //! an attribute participate in name resolution. -use std::{ - borrow::Cow, cell::OnceCell, convert::Infallible, fmt, iter::Peekable, ops::ControlFlow, -}; +use std::{borrow::Cow, cell::OnceCell, convert::Infallible, fmt, ops::ControlFlow}; -use ::tt::{TextRange, TextSize}; -use arrayvec::ArrayVec; +use ::tt::TextRange; use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use intern::Interned; use itertools::Itertools; use mbe::{DelimiterKind, Punct}; -use parser::T; use smallvec::SmallVec; use span::{RealSpanMap, Span, SyntaxContext}; -use syntax::{ - AstNode, NodeOrToken, SyntaxNode, SyntaxToken, - ast::{self, TokenTreeChildren}, - unescape, -}; +use syntax::{AstNode, SmolStr, ast, unescape}; use syntax_bridge::DocCommentDesugarMode; use crate::{ @@ -56,207 +36,75 @@ use crate::{ tt::{self, TopSubtree}, }; -#[derive(Debug)] -pub struct AttrPath { - /// This can be empty if the path is not of 1 or 2 segments exactly. - pub segments: ArrayVec<SyntaxToken, 2>, - pub range: TextRange, - // FIXME: This shouldn't be textual, `#[test]` needs name resolution. - // And if textual, it shouldn't be here, it should be in hir-def/src/attrs.rs. But some macros - // fully qualify `test` as `core::prelude::vX::test`, and this is more than 2 segments, so hir-def - // attrs can't find it. But this will mean we have to push every up-to-4-segments path, which - // may impact perf. So it was easier to just hack it here. - pub is_test: bool, +pub trait AstPathExt { + fn is1(&self, segment: &str) -> bool; + + fn as_one_segment(&self) -> Option<SmolStr>; + + fn as_up_to_two_segment(&self) -> Option<(SmolStr, Option<SmolStr>)>; } -impl AttrPath { - #[inline] - fn extract(path: &ast::Path) -> Self { - let mut is_test = false; - let segments = (|| { - let mut segments = ArrayVec::new(); - let segment2 = path.segment()?.name_ref()?.syntax().first_token()?; - if segment2.text() == "test" { - // `#[test]` or `#[core::prelude::vX::test]`. - is_test = true; - } - let segment1 = path.qualifier(); - if let Some(segment1) = segment1 { - if segment1.qualifier().is_some() { - None - } else { - let segment1 = segment1.segment()?.name_ref()?.syntax().first_token()?; - segments.push(segment1); - segments.push(segment2); - Some(segments) - } - } else { - segments.push(segment2); - Some(segments) - } - })(); - AttrPath { - segments: segments.unwrap_or(ArrayVec::new()), - range: path.syntax().text_range(), - is_test, - } +impl AstPathExt for ast::Path { + fn is1(&self, segment: &str) -> bool { + self.as_one_segment().is_some_and(|it| it == segment) } - #[inline] - pub fn is1(&self, segment: &str) -> bool { - self.segments.len() == 1 && self.segments[0].text() == segment + fn as_one_segment(&self) -> Option<SmolStr> { + Some(self.as_single_name_ref()?.text().into()) } -} -#[derive(Debug)] -pub enum Meta { - /// `name` is `None` if not a single token. `value` is a literal or `None`. - NamedKeyValue { - path_range: TextRange, - name: Option<SyntaxToken>, - value: Option<SyntaxToken>, - }, - TokenTree { - path: AttrPath, - tt: ast::TokenTree, - }, - Path { - path: AttrPath, - }, + fn as_up_to_two_segment(&self) -> Option<(SmolStr, Option<SmolStr>)> { + let parent = self.qualifier().as_one_segment(); + let this = self.segment()?.name_ref()?.text().into(); + if let Some(parent) = parent { Some((parent, Some(this))) } else { Some((this, None)) } + } } -impl Meta { - #[inline] - pub fn path_range(&self) -> TextRange { - match self { - Meta::NamedKeyValue { path_range, .. } => *path_range, - Meta::TokenTree { path, .. } | Meta::Path { path } => path.range, - } +impl AstPathExt for Option<ast::Path> { + fn is1(&self, segment: &str) -> bool { + self.as_ref().is_some_and(|it| it.is1(segment)) } - fn extract(iter: &mut Peekable<TokenTreeChildren>) -> Option<(Self, TextSize)> { - let mut start_offset = None; - if let Some(NodeOrToken::Token(colon1)) = iter.peek() - && colon1.kind() == T![:] - { - start_offset = Some(colon1.text_range().start()); - iter.next(); - iter.next_if(|it| it.as_token().is_some_and(|it| it.kind() == T![:])); - } - let first_segment = iter - .next_if(|it| it.as_token().is_some_and(|it| it.kind().is_any_identifier()))? - .into_token()?; - let mut is_test = first_segment.text() == "test"; - let start_offset = start_offset.unwrap_or_else(|| first_segment.text_range().start()); - - let mut segments_len = 1; - let mut second_segment = None; - let mut path_range = first_segment.text_range(); - while iter.peek().and_then(NodeOrToken::as_token).is_some_and(|it| it.kind() == T![:]) - && let _ = iter.next() - && iter.peek().and_then(NodeOrToken::as_token).is_some_and(|it| it.kind() == T![:]) - && let _ = iter.next() - && let Some(NodeOrToken::Token(segment)) = iter.peek() - && segment.kind().is_any_identifier() - { - segments_len += 1; - is_test = segment.text() == "test"; - second_segment = Some(segment.clone()); - path_range = TextRange::new(path_range.start(), segment.text_range().end()); - iter.next(); - } + fn as_one_segment(&self) -> Option<SmolStr> { + self.as_ref().and_then(|it| it.as_one_segment()) + } - let segments = |first, second| { - let mut segments = ArrayVec::new(); - if segments_len <= 2 { - segments.push(first); - if let Some(second) = second { - segments.push(second); - } - } - segments - }; - let meta = match iter.peek() { - Some(NodeOrToken::Token(eq)) if eq.kind() == T![=] => { - iter.next(); - let value = match iter.peek() { - Some(NodeOrToken::Token(token)) if token.kind().is_literal() => { - // No need to consume it, it will be consumed by `extract_and_eat_comma()`. - Some(token.clone()) - } - _ => None, - }; - let name = if second_segment.is_none() { Some(first_segment) } else { None }; - Meta::NamedKeyValue { path_range, name, value } - } - Some(NodeOrToken::Node(tt)) => Meta::TokenTree { - path: AttrPath { - segments: segments(first_segment, second_segment), - range: path_range, - is_test, - }, - tt: tt.clone(), - }, - _ => Meta::Path { - path: AttrPath { - segments: segments(first_segment, second_segment), - range: path_range, - is_test, - }, - }, - }; - Some((meta, start_offset)) + fn as_up_to_two_segment(&self) -> Option<(SmolStr, Option<SmolStr>)> { + self.as_ref().and_then(|it| it.as_up_to_two_segment()) } +} + +pub trait AstKeyValueMetaExt { + fn value_string(&self) -> Option<SmolStr>; +} - fn extract_possibly_unsafe( - iter: &mut Peekable<TokenTreeChildren>, - container: &ast::TokenTree, - ) -> Option<(Self, TextRange)> { - if iter.peek().is_some_and(|it| it.as_token().is_some_and(|it| it.kind() == T![unsafe])) { - iter.next(); - let tt = iter.next()?.into_node()?; - let result = Self::extract(&mut TokenTreeChildren::new(&tt).peekable()).map( - |(meta, start_offset)| (meta, TextRange::new(start_offset, tt_end_offset(&tt))), - ); - while iter.next().is_some_and(|it| it.as_token().is_none_or(|it| it.kind() != T![,])) {} - result +impl AstKeyValueMetaExt for ast::KeyValueMeta { + fn value_string(&self) -> Option<SmolStr> { + if let Some(ast::Expr::Literal(value)) = self.expr() + && let ast::LiteralKind::String(value) = value.kind() + && let Ok(value) = value.value() + { + Some((*value).into()) } else { - Self::extract(iter).map(|(meta, start_offset)| { - let end_offset = 'find_end_offset: { - for it in iter { - if let NodeOrToken::Token(it) = it - && it.kind() == T![,] - { - break 'find_end_offset it.text_range().start(); - } - } - tt_end_offset(container) - }; - (meta, TextRange::new(start_offset, end_offset)) - }) + None } } } -fn tt_end_offset(tt: &ast::TokenTree) -> TextSize { - tt.syntax().last_token().unwrap().text_range().start() -} - -/// The callback is passed a desugared form of the attribute ([`Meta`]), a [`SyntaxNode`] fully containing it -/// (note: it may not be the direct parent), the range within the [`SyntaxNode`] bounding the attribute, -/// and the outermost `ast::Attr`. Note that one node may map to multiple [`Meta`]s due to `cfg_attr`. +/// The callback is passed the attribute and the outermost `ast::Attr`. +/// Note that one node may map to multiple [`Meta`]s due to `cfg_attr`. +/// +/// `unsafe(attr)` are passed the inner attribute for now. #[inline] pub fn expand_cfg_attr<'a, BreakValue>( attrs: impl Iterator<Item = ast::Attr>, cfg_options: impl FnMut() -> &'a CfgOptions, - mut callback: impl FnMut(Meta, &SyntaxNode, TextRange, &ast::Attr) -> ControlFlow<BreakValue>, + mut callback: impl FnMut(ast::Meta, ast::Attr) -> ControlFlow<BreakValue>, ) -> Option<BreakValue> { expand_cfg_attr_with_doc_comments::<Infallible, _>( attrs.map(Either::Left), cfg_options, - move |Either::Left((meta, container, range, top_attr))| { - callback(meta, container, range, top_attr) - }, + move |Either::Left((meta, top_attr))| callback(meta, top_attr), ) } @@ -264,66 +112,47 @@ pub fn expand_cfg_attr<'a, BreakValue>( pub fn expand_cfg_attr_with_doc_comments<'a, DocComment, BreakValue>( mut attrs: impl Iterator<Item = Either<ast::Attr, DocComment>>, mut cfg_options: impl FnMut() -> &'a CfgOptions, - mut callback: impl FnMut( - Either<(Meta, &SyntaxNode, TextRange, &ast::Attr), DocComment>, - ) -> ControlFlow<BreakValue>, + mut callback: impl FnMut(Either<(ast::Meta, ast::Attr), DocComment>) -> ControlFlow<BreakValue>, ) -> Option<BreakValue> { let mut stack = SmallVec::<[_; 1]>::new(); - let result = attrs.try_for_each(|top_attr| { - let top_attr = match top_attr { - Either::Left(it) => it, - Either::Right(comment) => return callback(Either::Right(comment)), - }; - if let Some((attr_name, tt)) = top_attr.as_simple_call() - && attr_name == "cfg_attr" - { - let mut tt_iter = TokenTreeChildren::new(&tt).peekable(); - let cfg = cfg::CfgExpr::parse_from_ast(&mut tt_iter); - if cfg_options().check(&cfg) != Some(false) { - stack.push((tt_iter, tt)); - while let Some((tt_iter, tt)) = stack.last_mut() { - let Some((attr, range)) = Meta::extract_possibly_unsafe(tt_iter, tt) else { - stack.pop(); - continue; - }; - if let Meta::TokenTree { path, tt: nested_tt } = &attr - && path.is1("cfg_attr") - { - let mut nested_tt_iter = TokenTreeChildren::new(nested_tt).peekable(); - let cfg = cfg::CfgExpr::parse_from_ast(&mut nested_tt_iter); - if cfg_options().check(&cfg) != Some(false) { - stack.push((nested_tt_iter, nested_tt.clone())); - } - } else { - callback(Either::Left((attr, tt.syntax(), range, &top_attr)))?; + loop { + let (mut meta, top_attr) = if let Some(it) = stack.pop() { + it + } else { + let attr = attrs.next()?; + match attr { + Either::Left(attr) => { + let Some(meta) = attr.meta() else { continue }; + stack.push((meta, attr)); + } + Either::Right(doc_comment) => { + if let ControlFlow::Break(break_value) = callback(Either::Right(doc_comment)) { + return Some(break_value); } } } - } else if let Some(ast_meta) = top_attr.meta() - && let Some(path) = ast_meta.path() - { - let path = AttrPath::extract(&path); - let meta = if let Some(tt) = ast_meta.token_tree() { - Meta::TokenTree { path, tt } - } else if let Some(value) = ast_meta.expr() { - let value = - if let ast::Expr::Literal(value) = value { Some(value.token()) } else { None }; - let name = - if path.segments.len() == 1 { Some(path.segments[0].clone()) } else { None }; - Meta::NamedKeyValue { name, value, path_range: path.range } - } else { - Meta::Path { path } - }; - callback(Either::Left(( - meta, - ast_meta.syntax(), - ast_meta.syntax().text_range(), - &top_attr, - )))?; + continue; + }; + + while let ast::Meta::UnsafeMeta(unsafe_meta) = &meta { + let Some(inner) = unsafe_meta.meta() else { continue }; + meta = inner; } - ControlFlow::Continue(()) - }); - result.break_value() + + if let ast::Meta::CfgAttrMeta(meta) = meta { + let Some(cfg_predicate) = meta.cfg_predicate() else { continue }; + let cfg_predicate = CfgExpr::parse_from_ast(cfg_predicate); + if cfg_options().check(&cfg_predicate) != Some(false) { + let prev_stack_len = stack.len(); + stack.extend(meta.metas().map(|meta| (meta, top_attr.clone()))); + stack[prev_stack_len..].reverse(); + } + } else { + if let ControlFlow::Break(break_value) = callback(Either::Left((meta, top_attr))) { + return Some(break_value); + } + } + } } #[inline] @@ -351,39 +180,33 @@ pub(crate) fn is_item_tree_filtered_attr(name: &str) -> bool { pub fn collect_item_tree_attrs<'a, BreakValue>( owner: &dyn ast::HasAttrs, cfg_options: impl Fn() -> &'a CfgOptions, - mut on_attr: impl FnMut(Meta, &SyntaxNode, &ast::Attr, TextRange) -> ControlFlow<BreakValue>, + mut on_attr: impl FnMut(ast::Meta, ast::Attr) -> ControlFlow<BreakValue>, ) -> Option<Either<BreakValue, CfgExpr>> { let attrs = ast::attrs_including_inner(owner); expand_cfg_attr( attrs, || cfg_options(), - |attr, container, range, top_attr| { + |attr, top_attr| { // We filter builtin attributes that we don't need for nameres, because this saves memory. // I only put the most common attributes, but if some attribute becomes common feel free to add it. // Notice, however: for an attribute to be filtered out, it *must* not be shadowable with a macro! let filter = match &attr { - Meta::NamedKeyValue { name: Some(name), .. } => { - is_item_tree_filtered_attr(name.text()) - } - Meta::TokenTree { path, tt } if path.segments.len() == 1 => { - let name = path.segments[0].text(); - if name == "cfg" { - let cfg = - CfgExpr::parse_from_ast(&mut TokenTreeChildren::new(tt).peekable()); - if cfg_options().check(&cfg) == Some(false) { - return ControlFlow::Break(Either::Right(cfg)); - } - true - } else { - is_item_tree_filtered_attr(name) + ast::Meta::CfgMeta(attr) => { + let Some(cfg_predicate) = attr.cfg_predicate() else { + return ControlFlow::Continue(()); + }; + let cfg = CfgExpr::parse_from_ast(cfg_predicate); + if cfg_options().check(&cfg) == Some(false) { + return ControlFlow::Break(Either::Right(cfg)); } + true } - Meta::Path { path } => { - path.segments.len() == 1 && is_item_tree_filtered_attr(path.segments[0].text()) - } - _ => false, + _ => attr + .path() + .and_then(|path| path.as_one_segment()) + .is_some_and(|segment| is_item_tree_filtered_attr(&segment)), }; - if !filter && let ControlFlow::Break(v) = on_attr(attr, container, top_attr, range) { + if !filter && let ControlFlow::Break(v) = on_attr(attr, top_attr) { return ControlFlow::Break(Either::Left(v)); } ControlFlow::Continue(()) @@ -540,34 +363,32 @@ impl AttrId { } /// Returns the containing `ast::Attr` (note that it may contain other attributes as well due - /// to `cfg_attr`), a `SyntaxNode` guaranteed to contain the attribute, the full range of the - /// attribute, and its desugared [`Meta`]. + /// to `cfg_attr`) and its [`ast::Meta`]. pub fn find_attr_range<N: ast::HasAttrs>( self, db: &dyn ExpandDatabase, krate: Crate, owner: AstId<N>, - ) -> (ast::Attr, SyntaxNode, TextRange, Meta) { + ) -> (ast::Attr, ast::Meta) { self.find_attr_range_with_source(db, krate, &owner.to_node(db)) } /// Returns the containing `ast::Attr` (note that it may contain other attributes as well due - /// to `cfg_attr`), a `SyntaxNode` guaranteed to contain the attribute, the full range of the - /// attribute, and its desugared [`Meta`]. + /// to `cfg_attr`) and its [`ast::Meta`]. pub fn find_attr_range_with_source( self, db: &dyn ExpandDatabase, krate: Crate, owner: &dyn ast::HasAttrs, - ) -> (ast::Attr, SyntaxNode, TextRange, Meta) { + ) -> (ast::Attr, ast::Meta) { let cfg_options = OnceCell::new(); let mut index = 0; let result = collect_item_tree_attrs( owner, || cfg_options.get_or_init(|| krate.cfg_options(db)), - |meta, container, top_attr, range| { + |meta, top_attr| { if index == self.id { - return ControlFlow::Break((top_attr.clone(), container.clone(), range, meta)); + return ControlFlow::Break((top_attr, meta)); } index += 1; ControlFlow::Continue(()) @@ -588,9 +409,12 @@ impl AttrId { owner: AstId<ast::Adt>, derive_index: u32, ) -> TextRange { - let (_, _, derive_attr_range, derive_attr) = self.find_attr_range(db, krate, owner); - let Meta::TokenTree { tt, .. } = derive_attr else { - return derive_attr_range; + let (_, derive_attr) = self.find_attr_range(db, krate, owner); + let ast::Meta::TokenTreeMeta(derive_attr) = derive_attr else { + return derive_attr.syntax().text_range(); + }; + let Some(tt) = derive_attr.token_tree() else { + return derive_attr.syntax().text_range(); }; // Fake the span map, as we don't really need spans here, just the offsets of the node in the file. let span_map = RealSpanMap::absolute(span::EditionedFileId::current_edition( @@ -605,11 +429,11 @@ impl AttrId { let Some((_, _, derive_tts)) = parse_path_comma_token_tree(db, &tt).nth(derive_index as usize) else { - return derive_attr_range; + return derive_attr.syntax().text_range(); }; let (Some(first_span), Some(last_span)) = (derive_tts.first_span(), derive_tts.last_span()) else { - return derive_attr_range; + return derive_attr.syntax().text_range(); }; let start = first_span.range.start(); let end = last_span.range.end(); diff --git a/crates/hir-expand/src/cfg_process.rs b/crates/hir-expand/src/cfg_process.rs index ccef9168ac..6258fac0e9 100644 --- a/crates/hir-expand/src/cfg_process.rs +++ b/crates/hir-expand/src/cfg_process.rs @@ -8,12 +8,12 @@ use parser::T; use smallvec::SmallVec; use syntax::{ AstNode, PreorderWithTokens, SyntaxElement, SyntaxNode, SyntaxToken, WalkEvent, - ast::{self, HasAttrs, TokenTreeChildren}, + ast::{self, HasAttrs}, }; use syntax_bridge::DocCommentDesugarMode; use crate::{ - attrs::{AttrId, Meta, expand_cfg_attr, is_item_tree_filtered_attr}, + attrs::{AstPathExt, AttrId, expand_cfg_attr, is_item_tree_filtered_attr}, db::ExpandDatabase, fixup::{self, SyntaxFixupUndoInfo}, span_map::SpanMapRef, @@ -24,7 +24,7 @@ struct ItemIsCfgedOut; #[derive(Debug)] struct ExpandedAttrToProcess { - range: TextRange, + attr: ast::Meta, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -143,42 +143,29 @@ fn macro_input_callback( }); attrs_idx = 0; - let strip_current_item = expand_cfg_attr( - node_attrs, - &cfg_options, - |attr, _container, range, top_attr| { + let strip_current_item = + expand_cfg_attr(node_attrs, &cfg_options, |attr, top_attr| { // Find the attr. while attrs[attrs_idx].range != top_attr.syntax().text_range() { attrs_idx += 1; } let mut strip_current_attr = false; - match attr { - Meta::NamedKeyValue { name, .. } => { - if name - .is_none_or(|name| !is_item_tree_filtered_attr(name.text())) - { - strip_current_attr = should_strip_attr(); - } - } - Meta::TokenTree { path, tt } => { - if path.is1("cfg") { - let cfg_expr = CfgExpr::parse_from_ast( - &mut TokenTreeChildren::new(&tt).peekable(), - ); + match &attr { + ast::Meta::CfgMeta(attr) => { + if let Some(cfg_predicate) = attr.cfg_predicate() { + let cfg_expr = CfgExpr::parse_from_ast(cfg_predicate); if cfg_options().check(&cfg_expr) == Some(false) { return ControlFlow::Break(ItemIsCfgedOut); } strip_current_attr = true; - } else if path.segments.len() != 1 - || !is_item_tree_filtered_attr(path.segments[0].text()) - { - strip_current_attr = should_strip_attr(); } } - Meta::Path { path } => { - if path.segments.len() != 1 - || !is_item_tree_filtered_attr(path.segments[0].text()) + _ => { + if attr + .path() + .as_one_segment() + .is_none_or(|name| !is_item_tree_filtered_attr(&name)) { strip_current_attr = should_strip_attr(); } @@ -188,12 +175,11 @@ fn macro_input_callback( if !strip_current_attr { attrs[attrs_idx] .expanded_attrs - .push(ExpandedAttrToProcess { range }); + .push(ExpandedAttrToProcess { attr }); } ControlFlow::Continue(()) - }, - ); + }); attrs_idx = 0; if strip_current_item.is_some() { @@ -248,7 +234,7 @@ fn macro_input_callback( }; match ast_attr.next_expanded_attr { NextExpandedAttrState::NotStarted => { - if token_range.start() >= expanded_attr.range.start() { + if token_range.start() >= expanded_attr.attr.syntax().text_range().start() { // We started the next attribute. let mut insert_tokens = Vec::with_capacity(3); insert_tokens.push(tt::Leaf::Punct(tt::Punct { @@ -278,7 +264,7 @@ fn macro_input_callback( } } NextExpandedAttrState::InTheMiddle => { - if token_range.start() >= expanded_attr.range.end() { + if token_range.start() >= expanded_attr.attr.syntax().text_range().end() { // Finished the current attribute. let insert_tokens = vec![tt::Leaf::Punct(tt::Punct { char: ']', @@ -329,12 +315,3 @@ pub(crate) fn attr_macro_input_to_token_tree( fixups.undo_info, ) } - -pub fn check_cfg_attr_value( - db: &dyn ExpandDatabase, - attr: &ast::TokenTree, - krate: Crate, -) -> Option<bool> { - let cfg_expr = CfgExpr::parse_from_ast(&mut TokenTreeChildren::new(attr).peekable()); - krate.cfg_options(db).check(&cfg_expr) -} diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index 8a6b56d932..8dddddfabb 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -11,7 +11,6 @@ use crate::{ AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo, EagerExpander, EditionedFileId, ExpandError, ExpandResult, ExpandTo, FileRange, HirFileId, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, - attrs::Meta, builtin::pseudo_derive_attr_expansion, cfg_process::attr_macro_input_to_token_tree, declarative::DeclarativeMacroExpander, @@ -239,8 +238,15 @@ pub fn expand_speculative( MacroCallKind::Attr { censored_attr_ids: attr_ids, .. } => { if loc.def.is_attribute_derive() { // for pseudo-derive expansion we actually pass the attribute itself only - ast::Attr::cast(speculative_args.clone()).and_then(|attr| attr.token_tree()).map( - |token_tree| { + ast::Attr::cast(speculative_args.clone()) + .and_then(|attr| { + if let ast::Meta::TokenTreeMeta(meta) = attr.meta()? { + meta.token_tree() + } else { + None + } + }) + .map(|token_tree| { let mut tree = syntax_node_to_token_tree( token_tree.syntax(), span_map, @@ -250,26 +256,26 @@ pub fn expand_speculative( tree.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); tree.set_top_subtree_delimiter_span(tt::DelimSpan::from_single(span)); tree - }, - ) + }) } else { // Attributes may have an input token tree, build the subtree and map for this as well // then try finding a token id for our token if it is inside this input subtree. let item = ast::Item::cast(speculative_args.clone())?; - let (_, _, _, meta) = + let (_, meta) = attr_ids.invoc_attr().find_attr_range_with_source(db, loc.krate, &item); - match meta { - Meta::TokenTree { tt, .. } => { - let mut attr_arg = syntax_bridge::syntax_node_to_token_tree( - tt.syntax(), - span_map, - span, - DocCommentDesugarMode::ProcMacro, - ); - attr_arg.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); - Some(attr_arg) - } - _ => None, + if let ast::Meta::TokenTreeMeta(meta) = meta + && let Some(tt) = meta.token_tree() + { + let mut attr_arg = syntax_bridge::syntax_node_to_token_tree( + tt.syntax(), + span_map, + span, + DocCommentDesugarMode::ProcMacro, + ); + attr_arg.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); + Some(attr_arg) + } else { + None } } } @@ -501,11 +507,11 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { } MacroCallKind::Attr { ast_id, censored_attr_ids: attr_ids, .. } => { let node = ast_id.to_ptr(db).to_node(&root); - let range = attr_ids - .invoc_attr() - .find_attr_range_with_source(db, loc.krate, &node) - .3 - .path_range(); + let (_, attr) = attr_ids.invoc_attr().find_attr_range_with_source(db, loc.krate, &node); + let range = attr + .path() + .map(|path| path.syntax().text_range()) + .unwrap_or_else(|| attr.syntax().text_range()); let span = map.span_for_range(range); let is_derive = matches!(loc.def.kind, MacroDefKind::BuiltInAttr(_, expander) if expander.is_derive()); diff --git a/crates/hir-expand/src/declarative.rs b/crates/hir-expand/src/declarative.rs index 1726412275..4b2c6e7351 100644 --- a/crates/hir-expand/src/declarative.rs +++ b/crates/hir-expand/src/declarative.rs @@ -6,7 +6,7 @@ use base_db::Crate; use span::{Edition, Span, SyntaxContext}; use stdx::TupleExt; use syntax::{ - AstNode, AstToken, + AstNode, ast::{self, HasAttrs}, }; use syntax_bridge::DocCommentDesugarMode; @@ -15,7 +15,7 @@ use triomphe::Arc; use crate::{ AstId, ExpandError, ExpandErrorKind, ExpandResult, HirFileId, Lookup, MacroCallId, MacroCallStyle, - attrs::{Meta, expand_cfg_attr}, + attrs::{AstKeyValueMetaExt, AstPathExt, expand_cfg_attr}, db::ExpandDatabase, hygiene::{Transparency, apply_mark}, tt, @@ -92,11 +92,10 @@ impl DeclarativeMacroExpander { expand_cfg_attr( node.attrs(), || cfg_options.get_or_init(|| def_crate.cfg_options(db)), - |attr, _, _, _| { - if let Meta::NamedKeyValue { name: Some(name), value, .. } = attr - && name.text() == "rustc_macro_transparency" - && let Some(value) = value.and_then(ast::String::cast) - && let Ok(value) = value.value() + |attr, _| { + if let ast::Meta::KeyValueMeta(attr) = attr + && attr.path().is1("rustc_macro_transparency") + && let Some(value) = attr.value_string() { match &*value { "transparent" => ControlFlow::Break(Transparency::Transparent), diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index 4b2c75ed38..8d42a24e2f 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -58,7 +58,6 @@ use crate::{ }; pub use crate::{ - cfg_process::check_cfg_attr_value, files::{AstId, ErasedAstId, FileRange, InFile, InMacroFile, InRealFile}, prettify_macro_expansion_::prettify_macro_expansion, }; @@ -635,14 +634,12 @@ impl MacroCallLoc { ast_id.with_value(ast_id.to_node(db).syntax().clone()) } MacroCallKind::Derive { ast_id, derive_attr_index, .. } => { - // FIXME: handle `cfg_attr` - let (attr, _, _, _) = derive_attr_index.find_attr_range(db, self.krate, *ast_id); + let (_, attr) = derive_attr_index.find_attr_range(db, self.krate, *ast_id); ast_id.with_value(attr.syntax().clone()) } MacroCallKind::Attr { ast_id, censored_attr_ids: attr_ids, .. } => { if self.def.is_attribute_derive() { - let (attr, _, _, _) = - attr_ids.invoc_attr().find_attr_range(db, self.krate, *ast_id); + let (_, attr) = attr_ids.invoc_attr().find_attr_range(db, self.krate, *ast_id); ast_id.with_value(attr.syntax().clone()) } else { ast_id.with_value(ast_id.to_node(db).syntax().clone()) @@ -770,11 +767,11 @@ impl MacroCallKind { } MacroCallKind::Derive { ast_id, derive_attr_index, .. } => { // FIXME: should be the range of the macro name, not the whole derive - derive_attr_index.find_attr_range(db, krate, ast_id).2 + derive_attr_index.find_attr_range(db, krate, ast_id).1.syntax().text_range() } // FIXME: handle `cfg_attr` MacroCallKind::Attr { ast_id, censored_attr_ids: attr_ids, .. } => { - attr_ids.invoc_attr().find_attr_range(db, krate, ast_id).2 + attr_ids.invoc_attr().find_attr_range(db, krate, ast_id).1.syntax().text_range() } }; diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 89f3cfd140..2829902035 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1239,11 +1239,15 @@ fn emit_def_diagnostic_<'db>( ); } DefDiagnosticKind::InvalidDeriveTarget { ast, id } => { - let derive = id.find_attr_range(db, krate, *ast).3.path_range(); + let (_, attr) = id.find_attr_range(db, krate, *ast); + let derive = attr + .path() + .map(|path| path.syntax().text_range()) + .unwrap_or_else(|| attr.syntax().text_range()); acc.push(InvalidDeriveTarget { range: ast.with_value(derive) }.into()); } DefDiagnosticKind::MalformedDerive { ast, id } => { - let derive = id.find_attr_range(db, krate, *ast).2; + let derive = id.find_attr_range(db, krate, *ast).1.syntax().text_range(); acc.push(MalformedDerive { range: ast.with_value(derive) }.into()); } DefDiagnosticKind::MacroDefError { ast, message } => { @@ -1283,7 +1287,8 @@ fn precise_macro_call_location( ast_id.with_value(range) } MacroCallKind::Attr { ast_id, censored_attr_ids: attr_ids, .. } => { - let attr_range = attr_ids.invoc_attr().find_attr_range(db, krate, *ast_id).2; + let attr_range = + attr_ids.invoc_attr().find_attr_range(db, krate, *ast_id).1.syntax().text_range(); ast_id.with_value(attr_range) } } diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 9a31a08ffb..9996162485 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -24,6 +24,7 @@ use hir_def::{ }; use hir_expand::{ EditionedFileId, ExpandResult, FileRange, HirFileId, InMacroFile, MacroCallId, + attrs::AstPathExt, builtin::{BuiltinFnLikeExpander, EagerExpander}, db::ExpandDatabase, files::{FileRangeWrapper, HirFileRange, InRealFile}, @@ -298,14 +299,15 @@ impl<DB: HirDatabase + ?Sized> Semantics<'_, DB> { hir_expand::attrs::expand_cfg_attr::<Infallible>( extra_crate_attrs.chain(ast::attrs_including_inner(&item)), cfg_options, - |attr, _, _, _| { - let hir_expand::attrs::Meta::TokenTree { path, tt } = attr else { + |attr, _| { + let ast::Meta::TokenTreeMeta(attr) = attr else { return ControlFlow::Continue(()); }; - if path.segments.len() != 1 { + let (Some(segment), Some(tt)) = (attr.path().as_one_segment(), attr.token_tree()) + else { return ControlFlow::Continue(()); - } - let lint_attr = match path.segments[0].text() { + }; + let lint_attr = match &*segment { "allow" => LintAttr::Allow, "expect" => LintAttr::Expect, "warn" => LintAttr::Warn, @@ -554,17 +556,6 @@ impl<'db> SemanticsImpl<'db> { Some(InFile::new(file_id.into(), node)) } - pub fn check_cfg_attr(&self, attr: &ast::TokenTree) -> Option<bool> { - let file_id = self.find_file(attr.syntax()).file_id; - let krate = match file_id { - HirFileId::FileId(file_id) => { - self.file_to_module_defs(file_id.file_id(self.db)).next()?.krate(self.db).id - } - HirFileId::MacroFile(macro_file) => self.db.lookup_intern_macro_call(macro_file).krate, - }; - hir_expand::check_cfg_attr_value(self.db, attr, krate) - } - /// Expands the macro if it isn't one of the built-in ones that expand to custom syntax or dummy /// expansions. pub fn expand_allowed_builtins( @@ -608,8 +599,8 @@ impl<'db> SemanticsImpl<'db> { Some(self.expand(macro_call_id).map(|it| InFile::new(macro_call_id.into(), it))) } - pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Attr) -> Option<SyntaxNode> { - let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; + pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Meta) -> Option<SyntaxNode> { + let adt = attr.parent_attr()?.syntax().parent().and_then(ast::Adt::cast)?; let src = self.wrap_node_infile(attr.clone()); let call_id = self.with_ctx(|ctx| { ctx.attr_to_derive_macro_call(src.with_value(&adt), src).map(|(_, it, _)| it) @@ -617,7 +608,7 @@ impl<'db> SemanticsImpl<'db> { Some(self.parse_or_expand(call_id.into())) } - pub fn resolve_derive_macro(&self, attr: &ast::Attr) -> Option<Vec<Option<Macro>>> { + pub fn resolve_derive_macro(&self, attr: &ast::Meta) -> Option<Vec<Option<Macro>>> { let calls = self.derive_macro_calls(attr)?; self.with_ctx(|ctx| { Some( @@ -644,7 +635,7 @@ impl<'db> SemanticsImpl<'db> { pub fn expand_derive_macro( &self, - attr: &ast::Attr, + attr: &ast::Meta, ) -> Option<Vec<Option<ExpandResult<SyntaxNode>>>> { let res: Vec<_> = self .derive_macro_calls(attr)? @@ -662,9 +653,9 @@ impl<'db> SemanticsImpl<'db> { fn derive_macro_calls( &self, - attr: &ast::Attr, + attr: &ast::Meta, ) -> Option<Vec<Option<Either<MacroCallId, BuiltinDeriveImplId>>>> { - let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; + let adt = attr.parent_attr()?.syntax().parent().and_then(ast::Adt::cast)?; let file_id = self.find_file(adt.syntax()).file_id; let adt = InFile::new(file_id, &adt); let src = InFile::new(file_id, attr.clone()); @@ -773,7 +764,11 @@ impl<'db> SemanticsImpl<'db> { let attr = self.wrap_node_infile(actual_macro_call.clone()); let adt = actual_macro_call.syntax().parent().and_then(ast::Adt::cast)?; let macro_call_id = self.with_ctx(|ctx| { - ctx.attr_to_derive_macro_call(attr.with_value(&adt), attr).map(|(_, it, _)| it) + ctx.attr_to_derive_macro_call( + attr.with_value(&adt), + attr.with_value(attr.value.meta()?), + ) + .map(|(_, it, _)| it) })?; hir_expand::db::expand_speculative( self.db, @@ -1328,7 +1323,7 @@ impl<'db> SemanticsImpl<'db> { // text ranges of the outer ones, and then all of the inner ones up // to the invoking attribute so that the inbetween is ignored. // FIXME: Should cfg_attr be handled differently? - let (attr, _, _, _) = attr_ids + let (attr, _) = attr_ids .invoc_attr() .find_attr_range_with_source(db, loc.krate, &item); let start = attr.syntax().text_range().start(); @@ -1435,7 +1430,7 @@ impl<'db> SemanticsImpl<'db> { let derive_call = ctx .attr_to_derive_macro_call( InFile::new(expansion, &adt), - InFile::new(expansion, attr.clone()), + InFile::new(expansion, meta.clone()), )? .1; diff --git a/crates/hir/src/semantics/child_by_source.rs b/crates/hir/src/semantics/child_by_source.rs index f6d1bec575..babeb35913 100644 --- a/crates/hir/src/semantics/child_by_source.rs +++ b/crates/hir/src/semantics/child_by_source.rs @@ -126,8 +126,7 @@ impl ChildBySource for ItemScope { calls.for_each(|(attr_id, call_id, calls)| { // FIXME: Is this the right crate? let krate = call_id.lookup(db).krate; - // FIXME: Fix cfg_attr handling. - let (attr, _, _, _) = attr_id.find_attr_range_with_source(db, krate, &adt); + let (_, attr) = attr_id.find_attr_range_with_source(db, krate, &adt); res[keys::DERIVE_MACRO_CALL] .insert(AstPtr::new(&attr), (attr_id, call_id, calls.into())); }); diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 59bccc22d8..d932198b43 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -398,7 +398,7 @@ impl SourceToDefCtx<'_, '_> { pub(super) fn attr_to_derive_macro_call( &mut self, item: InFile<&ast::Adt>, - src: InFile<ast::Attr>, + src: InFile<ast::Meta>, ) -> Option<(AttrId, MacroCallId, &[Option<Either<MacroCallId, BuiltinDeriveImplId>>])> { let map = self.dyn_map(item)?; map[keys::DERIVE_MACRO_CALL] @@ -423,6 +423,7 @@ impl SourceToDefCtx<'_, '_> { let dyn_map = &map[keys::DERIVE_MACRO_CALL]; adt.value .attrs() + .flat_map(|attr| attr.skip_cfg_attrs()) .filter_map(move |attr| dyn_map.get(&AstPtr::new(&attr))) .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids)) }) diff --git a/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs index e022a27e51..fccc04770e 100644 --- a/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs +++ b/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs @@ -279,7 +279,7 @@ fn todo_fn(f: &ast::Fn, config: &AssistConfig) -> ast::Fn { } fn cfg_attrs(node: &impl HasAttrs) -> impl Iterator<Item = ast::Attr> { - node.attrs().filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg")) + node.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))) } #[cfg(test)] diff --git a/crates/ide-assists/src/handlers/generate_derive.rs b/crates/ide-assists/src/handlers/generate_derive.rs index 3ef68f06e4..7aeb5e3396 100644 --- a/crates/ide-assists/src/handlers/generate_derive.rs +++ b/crates/ide-assists/src/handlers/generate_derive.rs @@ -68,9 +68,11 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt ], ); - let delimiter = derive - .meta() - .expect("make::attr_outer was expected to have Meta") + let meta = derive.meta().expect("make::attr_outer was expected to have Meta"); + let ast::Meta::TokenTreeMeta(meta) = meta else { + unreachable!("make::attr_outer was passed a token tree meta"); + }; + let delimiter = meta .token_tree() .expect("failed to get token tree out of Meta") .r_paren_token() diff --git a/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs b/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs index 2fc2b9efe8..7746cdc068 100644 --- a/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs +++ b/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs @@ -121,9 +121,8 @@ pub(crate) fn generate_single_field_struct_from( ) .indent_with_mapping(1.into(), &make); - let cfg_attrs = strukt - .attrs() - .filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg")); + let cfg_attrs = + strukt.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))); let impl_ = make.impl_trait( cfg_attrs, diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 04c9d8e54d..5e595218f6 100644 --- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -64,9 +64,10 @@ pub(crate) fn replace_derive_with_manual_impl( .filter_map(|attr| attr.path()) .collect::<Vec<_>>(); - let adt = value.parent().and_then(ast::Adt::cast)?; - let attr = ast::Attr::cast(value)?; - let args = attr.token_tree()?; + let attr = ast::Meta::cast(value)?.parent_attr()?; + let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; + let ast::Meta::TokenTreeMeta(meta) = attr.meta()? else { return None }; + let args = meta.token_tree()?; let current_module = ctx.sema.scope(adt.syntax())?.module(); let current_crate = current_module.krate(ctx.db()); diff --git a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 36df4af31d..3b8988db7a 100644 --- a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs @@ -19,7 +19,7 @@ use crate::{AssistContext, AssistId, Assists}; // ``` // -> // ``` -// #[cfg_attr($0, derive(Debug))] +// #[cfg_attr(${0:cfg}, derive(Debug))] // struct S { // field: i32 // } @@ -147,12 +147,15 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) - } }?; match option { - WrapUnwrapOption::WrapAttr(attrs) => match &attrs[..] { - [attr] if attr.simple_name().as_deref() == Some("cfg_attr") => { - unwrap_cfg_attr(acc, attrs.into_iter().next().unwrap()) + WrapUnwrapOption::WrapAttr(attrs) => { + if let [attr] = &attrs[..] + && let Some(ast::Meta::CfgAttrMeta(meta)) = attr.meta() + { + unwrap_cfg_attr(acc, meta) + } else { + wrap_cfg_attrs(acc, ctx, attrs) } - _ => wrap_cfg_attrs(acc, ctx, attrs), - }, + } WrapUnwrapOption::WrapDerive { derive, attr } => wrap_derive(acc, ctx, attr, derive), } } @@ -164,7 +167,8 @@ fn wrap_derive( derive_element: TextRange, ) -> Option<()> { let range = attr.syntax().text_range(); - let token_tree = attr.token_tree()?; + let ast::Meta::TokenTreeMeta(meta) = attr.meta()? else { return None }; + let token_tree = meta.token_tree()?; let mut path_text = String::new(); let mut cfg_derive_tokens = Vec::new(); @@ -193,20 +197,15 @@ fn wrap_derive( let new_derive = make.attr_outer( make.meta_token_tree(make.ident_path("derive"), make.token_tree(T!['('], new_derive)), ); - let meta = make.meta_token_tree( - make.ident_path("cfg_attr"), - make.token_tree( - T!['('], - vec![ - NodeOrToken::Token(make.token(T![,])), - NodeOrToken::Token(make.whitespace(" ")), - NodeOrToken::Token(make.ident("derive")), - NodeOrToken::Node(make.token_tree(T!['('], cfg_derive_tokens)), - ], - ), + let meta = make.cfg_attr_meta( + make.cfg_flag("cfg"), + [make.meta_token_tree( + make.ident_path("derive"), + make.token_tree(T!['('], cfg_derive_tokens), + )], ); - let cfg_attr = make.attr_outer(meta); + let cfg_attr = make.attr_outer(meta.clone().into()); editor.replace_with_many( attr.syntax(), vec![ @@ -217,11 +216,10 @@ fn wrap_derive( ); if let Some(snippet_cap) = ctx.config.snippet_cap - && let Some(first_meta) = - cfg_attr.meta().and_then(|meta| meta.token_tree()).and_then(|tt| tt.l_paren_token()) + && let Some(cfg_predicate) = meta.cfg_predicate() { - let tabstop = edit.make_tabstop_after(snippet_cap); - editor.add_annotation(first_meta, tabstop); + let tabstop = edit.make_placeholder_snippet(snippet_cap); + editor.add_annotation(cfg_predicate.syntax(), tabstop); } editor.add_mappings(make.finish_with_mappings()); @@ -236,58 +234,29 @@ fn wrap_derive( ); Some(()) } + fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec<ast::Attr>) -> Option<()> { let (first_attr, last_attr) = (attrs.first()?, attrs.last()?); let range = first_attr.syntax().text_range().cover(last_attr.syntax().text_range()); - let path_attrs = - attrs.iter().map(|attr| Some((attr.path()?, attr.clone()))).collect::<Option<Vec<_>>>()?; let handle_source_change = |edit: &mut SourceChangeBuilder| { let make = SyntaxFactory::with_mappings(); let mut editor = edit.make_editor(first_attr.syntax()); - let mut raw_tokens = vec![]; - for (path, attr) in path_attrs { - raw_tokens.extend([ - NodeOrToken::Token(make.token(T![,])), - NodeOrToken::Token(make.whitespace(" ")), - ]); - path.syntax().descendants_with_tokens().for_each(|it| { - if let NodeOrToken::Token(token) = it { - raw_tokens.push(NodeOrToken::Token(token)); - } - }); - if let Some(meta) = attr.meta() { - if let (Some(eq), Some(expr)) = (meta.eq_token(), meta.expr()) { - raw_tokens.push(NodeOrToken::Token(make.whitespace(" "))); - raw_tokens.push(NodeOrToken::Token(eq)); - raw_tokens.push(NodeOrToken::Token(make.whitespace(" "))); - - expr.syntax().descendants_with_tokens().for_each(|it| { - if let NodeOrToken::Token(token) = it { - raw_tokens.push(NodeOrToken::Token(token)); - } - }); - } else if let Some(tt) = meta.token_tree() { - raw_tokens.extend(tt.token_trees_and_tokens()); - } - } - } let meta = - make.meta_token_tree(make.ident_path("cfg_attr"), make.token_tree(T!['('], raw_tokens)); + make.cfg_attr_meta(make.cfg_flag("cfg"), attrs.iter().filter_map(|attr| attr.meta())); let cfg_attr = if first_attr.excl_token().is_some() { - make.attr_inner(meta) + make.attr_inner(meta.clone().into()) } else { - make.attr_outer(meta) + make.attr_outer(meta.clone().into()) }; let syntax_range = first_attr.syntax().clone().into()..=last_attr.syntax().clone().into(); editor.replace_all(syntax_range, vec![cfg_attr.syntax().clone().into()]); if let Some(snippet_cap) = ctx.config.snippet_cap - && let Some(first_meta) = - cfg_attr.meta().and_then(|meta| meta.token_tree()).and_then(|tt| tt.l_paren_token()) + && let Some(cfg_flag) = meta.cfg_predicate() { - let tabstop = edit.make_tabstop_after(snippet_cap); - editor.add_annotation(first_meta, tabstop); + let tabstop = edit.make_placeholder_snippet(snippet_cap); + editor.add_annotation(cfg_flag.syntax(), tabstop); } editor.add_mappings(make.finish_with_mappings()); @@ -301,66 +270,28 @@ fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec<ast::At ); Some(()) } -fn unwrap_cfg_attr(acc: &mut Assists, attr: ast::Attr) -> Option<()> { - let range = attr.syntax().text_range(); - let meta = attr.meta()?; - let meta_tt = meta.token_tree()?; - let mut inner_attrs = Vec::with_capacity(1); - let mut found_comma = false; - let mut iter = meta_tt.token_trees_and_tokens().skip(1).peekable(); - while let Some(tt) = iter.next() { - if let NodeOrToken::Token(token) = &tt { - if token.kind() == T![')'] { - break; - } - if token.kind() == T![,] { - found_comma = true; - continue; - } - } - if !found_comma { - continue; - } - let Some(attr_name) = tt.into_token().and_then(|token| { - if token.kind() == T![ident] { Some(make::ext::ident_path(token.text())) } else { None } - }) else { - continue; - }; - let next_tt = iter.next()?; - let meta = match next_tt { - NodeOrToken::Node(tt) => make::meta_token_tree(attr_name, tt), - NodeOrToken::Token(token) if token.kind() == T![,] || token.kind() == T![')'] => { - make::meta_path(attr_name) - } - NodeOrToken::Token(token) => { - let equals = algo::skip_trivia_token(token, syntax::Direction::Next)?; - if equals.kind() != T![=] { - return None; - } - let expr_token = - algo::skip_trivia_token(equals.next_token()?, syntax::Direction::Next) - .and_then(|it| { - if it.kind().is_literal() { - Some(make::expr_literal(it.text())) - } else { - None - } - })?; - make::meta_expr(attr_name, ast::Expr::Literal(expr_token)) + +fn unwrap_cfg_attr(acc: &mut Assists, meta: ast::CfgAttrMeta) -> Option<()> { + let top_attr = ast::Meta::from(meta.clone()).parent_attr()?; + let range = top_attr.syntax().text_range(); + let inner_attrs = meta + .metas() + .map(|meta| { + if top_attr.excl_token().is_some() { + make::attr_inner(meta) + } else { + make::attr_outer(meta) } - }; - if attr.excl_token().is_some() { - inner_attrs.push(make::attr_inner(meta)); - } else { - inner_attrs.push(make::attr_outer(meta)); - } - } + }) + .collect::<Vec<_>>(); if inner_attrs.is_empty() { return None; } let handle_source_change = |f: &mut SourceChangeBuilder| { - let inner_attrs = - inner_attrs.iter().map(|it| it.to_string()).join(&format!("\n{}", attr.indent_level())); + let inner_attrs = inner_attrs + .iter() + .map(|it| it.to_string()) + .join(&format!("\n{}", top_attr.indent_level())); f.replace(range, inner_attrs); }; acc.add( @@ -388,7 +319,7 @@ mod tests { } "#, r#" - #[cfg_attr($0, derive(Debug))] + #[cfg_attr(${0:cfg}, derive(Debug))] pub struct Test { test: u32, } @@ -422,7 +353,7 @@ mod tests { "#, r#" pub struct Test { - #[cfg_attr($0, foo)] + #[cfg_attr(${0:cfg}, foo)] test: u32, } "#, @@ -456,7 +387,7 @@ mod tests { r#" pub struct Test { #[other_attr] - #[cfg_attr($0, foo, bar)] + #[cfg_attr(${0:cfg}, foo, bar)] #[other_attr] test: u32, } @@ -491,7 +422,7 @@ mod tests { "#, r#" pub struct Test { - #[cfg_attr($0, foo = "bar")] + #[cfg_attr(${0:cfg}, foo = "bar")] test: u32, } "#, @@ -520,7 +451,7 @@ mod tests { #![no_std$0] "#, r#" - #![cfg_attr($0, no_std)] + #![cfg_attr(${0:cfg}, no_std)] "#, ); check_assist( @@ -545,7 +476,7 @@ mod tests { "#, r#" #[derive( Clone, Copy)] - #[cfg_attr($0, derive(Debug))] + #[cfg_attr(${0:cfg}, derive(Debug))] pub struct Test { test: u32, } @@ -561,7 +492,7 @@ mod tests { "#, r#" #[derive(Clone, Copy)] - #[cfg_attr($0, derive(Debug))] + #[cfg_attr(${0:cfg}, derive(Debug))] pub struct Test { test: u32, } @@ -580,7 +511,7 @@ mod tests { "#, r#" #[derive( Clone, Copy)] - #[cfg_attr($0, derive(std::fmt::Debug))] + #[cfg_attr(${0:cfg}, derive(std::fmt::Debug))] pub struct Test { test: u32, } @@ -596,7 +527,7 @@ mod tests { "#, r#" #[derive(Clone, Copy)] - #[cfg_attr($0, derive(std::fmt::Debug))] + #[cfg_attr(${0:cfg}, derive(std::fmt::Debug))] pub struct Test { test: u32, } @@ -615,7 +546,7 @@ mod tests { "#, r#" #[derive(std::fmt::Debug, Clone)] - #[cfg_attr($0, derive(Copy))] + #[cfg_attr(${0:cfg}, derive(Copy))] pub struct Test { test: u32, } @@ -631,7 +562,7 @@ mod tests { "#, r#" #[derive(Clone, Copy)] - #[cfg_attr($0, derive(std::fmt::Debug))] + #[cfg_attr(${0:cfg}, derive(std::fmt::Debug))] pub struct Test { test: u32, } diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 66d5cf834f..a499607c1f 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -3852,7 +3852,7 @@ struct S { } "#####, r#####" -#[cfg_attr($0, derive(Debug))] +#[cfg_attr(${0:cfg}, derive(Debug))] struct S { field: i32 } diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 3de8ec7f53..896743342c 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -598,9 +598,7 @@ fn generate_impl_text_inner( // Copy any cfg attrs from the original adt buf.push_str("\n\n"); - let cfg_attrs = adt - .attrs() - .filter(|attr| attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false)); + let cfg_attrs = adt.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))); cfg_attrs.for_each(|attr| buf.push_str(&format!("{attr}\n"))); // `impl{generic_params} {trait_text} for {name}{generic_params.to_generic_args()}` @@ -740,8 +738,7 @@ fn generate_impl_inner( let ty = make::ty_path(make::ext::ident_path(&adt.name().unwrap().text())); - let cfg_attrs = - adt.attrs().filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg")); + let cfg_attrs = adt.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))); match trait_ { Some(trait_) => make::impl_trait( cfg_attrs, @@ -811,8 +808,7 @@ fn generate_impl_inner_with_factory( let ty: ast::Type = make.ty_path(make.ident_path(&adt.name().unwrap().text())).into(); - let cfg_attrs = - adt.attrs().filter(|attr| attr.as_simple_call().is_some_and(|(name, _arg)| name == "cfg")); + let cfg_attrs = adt.attrs().filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))); match trait_ { Some(trait_) => make.impl_trait( cfg_attrs, diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 4a94383ff4..9a09e9bd4a 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -756,7 +756,7 @@ pub(super) fn complete_name_ref( match &path_ctx.kind { PathKind::Expr { expr_ctx } => { expr::complete_expr_path(acc, ctx, path_ctx, expr_ctx); - expr::complete_expr(acc, ctx); + expr::complete_expr(acc, ctx, path_ctx); dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx); item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx); diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index 20776f6c49..da1e664f96 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -30,6 +30,7 @@ mod lint; mod macro_use; mod repr; +pub(crate) use self::cfg::complete_cfg; pub(crate) use self::derive::complete_derive_path; /// Complete inputs to known builtin attributes as well as derive attributes @@ -37,7 +38,7 @@ pub(crate) fn complete_known_attribute_input( acc: &mut Completions, ctx: &CompletionContext<'_>, &colon_prefix: &bool, - fake_attribute_under_caret: &ast::Attr, + fake_attribute_under_caret: &ast::TokenTreeMeta, extern_crate: Option<&ast::ExternCrate>, ) -> Option<()> { let attribute = fake_attribute_under_caret; @@ -70,7 +71,6 @@ pub(crate) fn complete_known_attribute_input( lint::complete_lint(acc, ctx, colon_prefix, &existing_lints, &lints); } - ["cfg"] | ["cfg_attr"] => cfg::complete_cfg(acc, ctx), ["macro_use"] => macro_use::complete_macro_use( acc, ctx, diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 8c532e0f4d..99ca55bdaf 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -451,7 +451,11 @@ pub(crate) fn complete_expr_path( } } -pub(crate) fn complete_expr(acc: &mut Completions, ctx: &CompletionContext<'_>) { +pub(crate) fn complete_expr( + acc: &mut Completions, + ctx: &CompletionContext<'_>, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, +) { let _p = tracing::info_span!("complete_expr").entered(); if !ctx.config.enable_term_search { @@ -462,6 +466,10 @@ pub(crate) fn complete_expr(acc: &mut Completions, ctx: &CompletionContext<'_>) return; } + if !matches!(qualified, Qualified::No) { + return; + } + if let Some(ty) = &ctx.expected_type { // Ignore unit types as they are not very interesting if ty.is_unit() || ty.is_unknown() { diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 413830904a..2cf87baf33 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -133,7 +133,8 @@ pub(crate) fn import_on_the_fly_path( let potential_import_name = import_name(ctx); let qualifier = match qualified { Qualified::With { path, .. } => Some(path.clone()), - _ => None, + Qualified::TypeAnchor { .. } => return None, + Qualified::No | Qualified::Absolute => None, }; let import_assets = import_assets_for_path( ctx, diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index ae3f717607..485e5f0caf 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -408,9 +408,11 @@ pub(crate) enum CompletionAnalysis<'db> { /// Set if we are currently completing in an unexpanded attribute, this usually implies a builtin attribute like `allow($0)` UnexpandedAttrTT { colon_prefix: bool, - fake_attribute_under_caret: Option<ast::Attr>, + fake_attribute_under_caret: Option<ast::TokenTreeMeta>, extern_crate: Option<ast::ExternCrate>, }, + /// Set if we are inside the predicate of a #[cfg] or #[cfg_attr]. + CfgPredicate, MacroSegment, } diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index d8f160c100..2a293313f2 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -284,9 +284,12 @@ fn expand( }; // Expand pseudo-derive expansion aka `derive(Debug$0)` - if let Some((orig_attr, spec_attr)) = attrs { + if let Some((orig_attr, spec_attr)) = attrs + && let Some(orig_meta) = orig_attr.meta() + { + // FIXME: Support speculative expansion with `cfg_attr`. if let (Some(actual_expansion), Some((fake_expansion, fake_mapped_tokens))) = ( - sema.expand_derive_as_pseudo_attr_macro(&orig_attr), + sema.expand_derive_as_pseudo_attr_macro(&orig_meta), sema.speculative_expand_derive_as_pseudo_attr_macro( &orig_attr, &spec_attr, @@ -463,7 +466,9 @@ fn analyze<'db>( } // Overwrite the path kind for derives - if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx { + if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx + && let Some(origin_meta) = origin_attr.meta() + { if let Some(ast::NameLike::NameRef(name_ref)) = find_node_at_offset(&file_with_fake_ident, offset) { @@ -473,7 +478,7 @@ fn analyze<'db>( if let NameRefKind::Path(path_ctx) = &mut nameref_ctx.kind { path_ctx.kind = PathKind::Derive { existing_derives: sema - .resolve_derive_macro(&origin_attr) + .resolve_derive_macro(&origin_meta) .into_iter() .flatten() .flatten() @@ -498,7 +503,7 @@ fn analyze<'db>( let token = syntax::algo::skip_trivia_token(self_token.clone(), Direction::Prev)?; let p = token.parent()?; if p.kind() == SyntaxKind::TOKEN_TREE - && p.ancestors().any(|it| it.kind() == SyntaxKind::META) + && p.ancestors().any(|it| it.kind() == SyntaxKind::TOKEN_TREE_META) { let colon_prefix = previous_non_trivia_token(self_token.clone()) .is_some_and(|it| T![:] == it.kind()); @@ -506,7 +511,7 @@ fn analyze<'db>( CompletionAnalysis::UnexpandedAttrTT { fake_attribute_under_caret: fake_ident_token .parent_ancestors() - .find_map(ast::Attr::cast), + .find_map(ast::TokenTreeMeta::cast), colon_prefix, extern_crate: p.ancestors().find_map(ast::ExternCrate::cast), } @@ -525,6 +530,13 @@ fn analyze<'db>( } else { return None; } + } else if find_node_at_offset::<ast::CfgPredicate>( + &speculative_file, + speculative_offset, + ) + .is_some() + { + CompletionAnalysis::CfgPredicate } else { return None; } diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index 69ca2af772..3867e65ae5 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -263,6 +263,7 @@ pub fn completions( extern_crate.as_ref(), ); } + CompletionAnalysis::CfgPredicate => completions::attribute::complete_cfg(acc, ctx), CompletionAnalysis::MacroSegment => { completions::macro_def::complete_macro_segment(acc, ctx); } diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index b946441991..b6da6fba63 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -2211,7 +2211,6 @@ fn bb()-> &'static aa { } "#, expect![[r#" - ex bb() [type] fn from_bytes(…) fn(&[u8]) -> &aa [type_could_unify] "#]], ); diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs index 8e50ef10ec..4a5983097a 100644 --- a/crates/ide-completion/src/tests/expression.rs +++ b/crates/ide-completion/src/tests/expression.rs @@ -1030,8 +1030,6 @@ fn main() { "#, expect![[r#" fn test() fn() -> Zulu - ex Zulu - ex Zulu::test() "#]], ); } diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs index d7db896679..5391e6c9ce 100644 --- a/crates/ide-completion/src/tests/flyimport.rs +++ b/crates/ide-completion/src/tests/flyimport.rs @@ -1243,6 +1243,39 @@ impl Bar for Foo { } #[test] +fn no_flyimports_type_anchor() { + check( + r#" +mod m { + pub fn foo() {} +} +struct Bar; +trait Foo {} +impl Foo for Bar {} +fn main() { + <Bar as Foo>::foo$0 +} + "#, + expect![[r#""#]], + ); + + check( + r#" +mod m { + pub fn foo() {} +} +struct Bar; +trait Foo {} +impl Foo for Bar {} +fn main() { + <Bar>::foo$0 +} + "#, + expect![[r#""#]], + ); +} + +#[test] fn no_inherent_candidates_proposed() { check( r#" diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs index b82b23541c..55059a4035 100644 --- a/crates/ide-completion/src/tests/special.rs +++ b/crates/ide-completion/src/tests/special.rs @@ -896,9 +896,6 @@ fn bar() -> Bar { "#, expect![[r#" fn foo() (as Foo) fn() -> Self - ex Bar - ex Bar::foo() - ex bar() "#]], ); } @@ -926,9 +923,6 @@ fn bar() -> Bar { expect![[r#" fn bar() fn() fn foo() (as Foo) fn() -> Self - ex Bar - ex Bar::foo() - ex bar() "#]], ); } @@ -955,9 +949,6 @@ fn bar() -> Bar { "#, expect![[r#" fn foo() (as Foo) fn() -> Self - ex Bar - ex Bar::foo() - ex bar() "#]], ); } diff --git a/crates/ide-db/src/generated/lints.rs b/crates/ide-db/src/generated/lints.rs index 9e6d586008..c25feceb41 100644 --- a/crates/ide-db/src/generated/lints.rs +++ b/crates/ide-db/src/generated/lints.rs @@ -1,4 +1,4 @@ -//! Generated by `cargo codegen lint-definitions`, do not edit by hand. +//! Generated by `cargo xtask codegen lint-definitions`, do not edit by hand. use span::Edition; @@ -20,8 +20,8 @@ pub struct LintGroup { pub const DEFAULT_LINTS: &[Lint] = &[ Lint { - label: "abi_unsupported_vector_types", - description: r##"this function call or definition uses a vector type which is not enabled"##, + label: "aarch64_softfloat_neon", + description: r##"detects code that could be affected by ABI issues on aarch64 softfloat targets"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, @@ -41,9 +41,23 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "ambiguous_derive_helpers", + description: r##"detects derive helper attributes that are ambiguous with built-in attributes"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ambiguous_glob_imported_traits", + description: r##"detects uses of ambiguously glob imported traits"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "ambiguous_glob_imports", description: r##"detects certain glob imports that require reporting an ambiguity error"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, deny_since: None, }, @@ -55,6 +69,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "ambiguous_import_visibilities", + description: r##"detects certain glob imports that require reporting an ambiguity error"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "ambiguous_negative_literals", description: r##"ambiguous negative literals operations"##, default_severity: Severity::Allow, @@ -62,6 +83,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "ambiguous_panic_imports", + description: r##"detects ambiguous core and std panic imports"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "ambiguous_wide_pointer_comparisons", description: r##"detects ambiguous wide pointer comparisons"##, default_severity: Severity::Warning, @@ -146,13 +174,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "cenum_impl_drop_cast", - description: r##"a C-like enum implementing Drop is cast"##, - default_severity: Severity::Error, - warn_since: None, - deny_since: None, - }, - Lint { label: "clashing_extern_declarations", description: r##"detects when an extern fn has been declared with the same name but different types"##, default_severity: Severity::Warning, @@ -195,6 +216,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "const_item_interior_mutations", + description: r##"checks for calls which mutates a interior mutable const-item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "const_item_mutation", description: r##"detects attempts to mutate a `const` item"##, default_severity: Severity::Warning, @@ -202,6 +230,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "dangerous_implicit_autorefs", + description: r##"implicit reference to a dereference of a raw pointer"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "dangling_pointers_from_locals", + description: r##"detects returning a pointer from a local variable"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "dangling_pointers_from_temporaries", description: r##"detects getting a pointer from a temporary"##, default_severity: Severity::Warning, @@ -216,9 +258,16 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "default_overrides_default_fields", + description: r##"detect `Default` impl that should use the type's default field values"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { label: "dependency_on_unit_never_type_fallback", description: r##"never type fallback affecting unsafe function calls"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, deny_since: None, }, @@ -252,14 +301,21 @@ pub const DEFAULT_LINTS: &[Lint] = &[ }, Lint { label: "deref_into_dyn_supertrait", - description: r##"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future"##, - default_severity: Severity::Warning, + description: r##"`Deref` implementation with a supertrait trait object for output is shadowed by trait upcasting"##, + default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { label: "deref_nullptr", description: r##"detects when an null pointer is dereferenced"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "double_negations", + description: r##"detects expressions of the form `--x`"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, @@ -286,6 +342,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "duplicate_features", + description: r##"duplicate features found in crate-level `#[feature]` directives"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { label: "duplicate_macro_attributes", description: r##"duplicated attribute"##, default_severity: Severity::Warning, @@ -321,13 +384,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "elided_named_lifetimes", - description: r##"detects when an elided lifetime gets resolved to be `'static` or some named parameter"##, - default_severity: Severity::Warning, - warn_since: None, - deny_since: None, - }, - Lint { label: "ellipsis_inclusive_range_patterns", description: r##"`...` range patterns are deprecated"##, default_severity: Severity::Warning, @@ -398,6 +454,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "function_casts_as_integer", + description: r##"casting a function into an integer"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "function_item_references", description: r##"suggest casting to a function pointer when attempting to take references to function items"##, default_severity: Severity::Warning, @@ -442,7 +505,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ Lint { label: "impl_trait_redundant_captures", description: r##"redundant precise-capturing `use<...>` syntax on an `impl Trait`"##, - default_severity: Severity::Warning, + default_severity: Severity::Allow, warn_since: None, deny_since: None, }, @@ -461,6 +524,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "improper_gpu_kernel_arg", + description: r##"GPU kernel entry points have a limited ABI"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "incomplete_features", description: r##"incomplete features that may function improperly in some or all cases"##, default_severity: Severity::Warning, @@ -482,8 +552,29 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "inline_always_mismatching_target_features", + description: r##"detects when a function annotated with `#[inline(always)]` and `#[target_feature(enable = "..")]` is inlined into a caller without the required target feature"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "inline_no_sanitize", - description: r##"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"##, + description: r##"detects incompatible use of `#[inline(always)]` and `#[sanitize(... = "off")]`"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "integer_to_ptr_transmutes", + description: r##"detects integer to pointer transmutes"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "internal_eq_trait_method_impls", + description: r##"manual implementation of the internal `Eq::assert_receiver_is_total_eq` method"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, @@ -505,7 +596,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ Lint { label: "invalid_doc_attributes", description: r##"detects invalid `#[doc(...)]` attributes"##, - default_severity: Severity::Error, + default_severity: Severity::Warning, warn_since: None, deny_since: None, }, @@ -526,7 +617,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ Lint { label: "invalid_macro_export_arguments", description: r##""invalid_parameter" isn't a valid argument for `#[macro_export]`"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, deny_since: None, }, @@ -538,6 +629,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "invalid_null_arguments", + description: r##"invalid null pointer in arguments"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { label: "invalid_reference_casting", description: r##"casts of `&T` to `&mut T` without interior mutability"##, default_severity: Severity::Error, @@ -596,7 +694,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ Lint { label: "legacy_derive_helpers", description: r##"detects derive helper attributes that are used before they are introduced"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, deny_since: None, }, @@ -615,6 +713,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "linker_info", + description: r##"linker warnings known to be informational-only and not indicative of a problem"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "linker_messages", + description: r##"warnings emitted at runtime by the target-specific linker program"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "long_running_const_eval", description: r##"detects long const eval operations"##, default_severity: Severity::Error, @@ -643,6 +755,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "malformed_diagnostic_attributes", + description: r##"detects malformed diagnostic attributes"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "malformed_diagnostic_format_literals", + description: r##"detects diagnostic attribute with malformed diagnostic format literals"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "map_unit_fn", description: r##"`Iterator::map` call that discard the iterator's values"##, default_severity: Severity::Warning, @@ -657,9 +783,23 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "mismatched_lifetime_syntaxes", + description: r##"detects when a lifetime uses different syntax between arguments and return values"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "misplaced_diagnostic_attributes", + description: r##"detects diagnostic attributes that are placed on the wrong item"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "missing_abi", description: r##"No declared ABI for extern declaration"##, - default_severity: Severity::Allow, + default_severity: Severity::Warning, warn_since: None, deny_since: None, }, @@ -685,9 +825,9 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "missing_fragment_specifier", - description: r##"detects missing fragment specifiers in unused `macro_rules!` patterns"##, - default_severity: Severity::Error, + label: "missing_gpu_kernel_export_name", + description: r##"mangled gpu-kernel function"##, + default_severity: Severity::Warning, warn_since: None, deny_since: None, }, @@ -743,9 +883,9 @@ pub const DEFAULT_LINTS: &[Lint] = &[ Lint { label: "never_type_fallback_flowing_into_unsafe", description: r##"never type fallback affecting unsafe function calls"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, - deny_since: Some(Edition::Edition2024), + deny_since: None, }, Lint { label: "no_mangle_const_items", @@ -839,16 +979,9 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "order_dependent_trait_objects", - description: r##"trait-object types were treated as different depending on marker-trait order"##, - default_severity: Severity::Error, - warn_since: None, - deny_since: None, - }, - Lint { label: "out_of_scope_macro_calls", description: r##"detects out of scope calls to `macro_rules` in key-value attributes"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, deny_since: None, }, @@ -902,13 +1035,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "ptr_cast_add_auto_to_object", - description: r##"detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`"##, - default_severity: Severity::Warning, - warn_since: None, - deny_since: None, - }, - Lint { label: "ptr_to_integer_transmute_in_consts", description: r##"detects pointer to integer transmutes in const functions and associated constants"##, default_severity: Severity::Warning, @@ -965,8 +1091,29 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "repr_transparent_external_private_fields", + label: "repr_c_enums_larger_than_int", + description: r##"repr(C) enums with discriminant values that do not fit into a C int"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "repr_transparent_non_zst_fields", description: r##"transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields"##, + default_severity: Severity::Error, + warn_since: None, + deny_since: None, + }, + Lint { + label: "resolving_to_items_shadowing_supertrait_items", + description: r##"detects when a supertrait item is shadowed by a subtrait item"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "rtsan_nonblocking_async", + description: r##"detects incompatible uses of `#[sanitize(realtime = "nonblocking")]` on async functions"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, @@ -1030,21 +1177,21 @@ pub const DEFAULT_LINTS: &[Lint] = &[ Lint { label: "semicolon_in_expressions_from_macros", description: r##"trailing semicolon in macro body used as expression"##, - default_severity: Severity::Warning, + default_severity: Severity::Error, warn_since: None, deny_since: None, }, Lint { - label: "single_use_lifetimes", - description: r##"detects lifetime parameters that are only used once"##, + label: "shadowing_supertrait_items", + description: r##"detects when a supertrait item is shadowed by a subtrait item"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "soft_unstable", - description: r##"a feature gate that doesn't break dependent crates"##, - default_severity: Severity::Error, + label: "single_use_lifetimes", + description: r##"detects lifetime parameters that are only used once"##, + default_severity: Severity::Allow, warn_since: None, deny_since: None, }, @@ -1064,7 +1211,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ }, Lint { label: "static_mut_refs", - description: r##"shared references or mutable references of mutable static is discouraged"##, + description: r##"creating a shared reference to mutable static"##, default_severity: Severity::Warning, warn_since: None, deny_since: Some(Edition::Edition2024), @@ -1168,13 +1315,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "undefined_naked_function_abi", - description: r##"undefined naked function ABI"##, - default_severity: Severity::Warning, - warn_since: None, - deny_since: None, - }, - Lint { label: "undropped_manually_drops", description: r##"calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of it's inner value"##, default_severity: Severity::Error, @@ -1224,15 +1364,15 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "unknown_lints", - description: r##"unrecognized lint attribute"##, + label: "unknown_diagnostic_attributes", + description: r##"detects unknown diagnostic attributes"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, }, Lint { - label: "unknown_or_malformed_diagnostic_attributes", - description: r##"unrecognized or malformed diagnostic attribute"##, + label: "unknown_lints", + description: r##"unrecognized lint attribute"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, @@ -1252,6 +1392,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "unnecessary_transmutes", + description: r##"detects transmutes that can also be achieved by other operations"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unpredictable_function_pointer_comparisons", + description: r##"detects unpredictable function pointer comparisons"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "unqualified_local_imports", description: r##"`use` of a local item without leading `self::`, `super::`, or `crate::`"##, default_severity: Severity::Allow, @@ -1259,6 +1413,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "unreachable_cfg_select_predicates", + description: r##"detects unreachable configuration predicates in the cfg_select macro"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "unreachable_code", description: r##"detects unreachable code paths"##, default_severity: Severity::Warning, @@ -1322,8 +1483,8 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "unsupported_fn_ptr_calling_conventions", - description: r##"use of unsupported calling convention for function pointer"##, + label: "unsupported_calling_conventions", + description: r##"use of unsupported calling convention"##, default_severity: Severity::Warning, warn_since: None, deny_since: None, @@ -1490,6 +1651,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "unused_visibilities", + description: r##"detect visibility qualifiers on `const _` items"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "useless_deprecated", description: r##"detects deprecation attributes with no effect"##, default_severity: Severity::Error, @@ -1504,6 +1672,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "uses_power_alignment", + description: r##"Structs do not follow the power alignment rule under repr(C)"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { + label: "varargs_without_pattern", + description: r##"detects usage of `...` arguments without a pattern in non-foreign items"##, + default_severity: Severity::Warning, + warn_since: None, + deny_since: None, + }, + Lint { label: "variant_size_differences", description: r##"detects enums with widely varying variant sizes"##, default_severity: Severity::Allow, @@ -1518,13 +1700,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "wasm_c_abi", - description: r##"detects dependencies that are incompatible with the Wasm C ABI"##, - default_severity: Severity::Error, - warn_since: None, - deny_since: None, - }, - Lint { label: "while_true", description: r##"suggest using `loop { }` instead of `while true { }`"##, default_severity: Severity::Warning, @@ -1540,7 +1715,7 @@ pub const DEFAULT_LINTS: &[Lint] = &[ }, Lint { label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##, + description: r##"lint group for: internal-eq-trait-method-impls, aarch64-softfloat-neon, ambiguous-associated-items, ambiguous-derive-helpers, ambiguous-glob-imported-traits, ambiguous-glob-imports, ambiguous-import-visibilities, ambiguous-panic-imports, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-macro-export-arguments, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-c-enums-larger-than-int, repr-transparent-non-zst-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, varargs-without-pattern"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, @@ -1602,8 +1777,15 @@ pub const DEFAULT_LINTS: &[Lint] = &[ deny_since: None, }, Lint { + label: "unknown_or_malformed_diagnostic_attributes", + description: r##"lint group for: malformed-diagnostic-attributes, malformed-diagnostic-format-literals, misplaced-diagnostic-attributes, unknown-diagnostic-attributes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "unused", - description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + description: r##"lint group for: unused-imports, unused-variables, unused-visibilities, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, @@ -1631,44 +1813,45 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ LintGroup { lint: Lint { label: "future_incompatible", - description: r##"lint group for: deref-into-dyn-supertrait, abi-unsupported-vector-types, ambiguous-associated-items, ambiguous-glob-imports, cenum-impl-drop-cast, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, missing-fragment-specifier, order-dependent-trait-objects, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, ptr-cast-add-auto-to-object, pub-use-of-private-extern-crate, repr-transparent-external-private-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, soft-unstable, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-fn-ptr-calling-conventions, wasm-c-abi"##, + description: r##"lint group for: internal-eq-trait-method-impls, aarch64-softfloat-neon, ambiguous-associated-items, ambiguous-derive-helpers, ambiguous-glob-imported-traits, ambiguous-glob-imports, ambiguous-import-visibilities, ambiguous-panic-imports, coherence-leak-check, conflicting-repr-hints, const-evaluatable-unchecked, elided-lifetimes-in-associated-constant, forbidden-lint-groups, ill-formed-attribute-input, invalid-macro-export-arguments, invalid-type-param-default, late-bound-lifetime-arguments, legacy-derive-helpers, macro-expanded-macro-exports-accessed-by-absolute-paths, out-of-scope-macro-calls, patterns-in-fns-without-body, proc-macro-derive-resolution-fallback, pub-use-of-private-extern-crate, repr-c-enums-larger-than-int, repr-transparent-non-zst-fields, self-constructor-from-outer-item, semicolon-in-expressions-from-macros, uncovered-param-in-projection, uninhabited-static, unstable-name-collisions, unstable-syntax-pre-expansion, unsupported-calling-conventions, varargs-without-pattern"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, children: &[ - "deref_into_dyn_supertrait", - "abi_unsupported_vector_types", + "internal_eq_trait_method_impls", + "aarch64_softfloat_neon", "ambiguous_associated_items", + "ambiguous_derive_helpers", + "ambiguous_glob_imported_traits", "ambiguous_glob_imports", - "cenum_impl_drop_cast", + "ambiguous_import_visibilities", + "ambiguous_panic_imports", "coherence_leak_check", "conflicting_repr_hints", "const_evaluatable_unchecked", "elided_lifetimes_in_associated_constant", "forbidden_lint_groups", "ill_formed_attribute_input", + "invalid_macro_export_arguments", "invalid_type_param_default", "late_bound_lifetime_arguments", "legacy_derive_helpers", "macro_expanded_macro_exports_accessed_by_absolute_paths", - "missing_fragment_specifier", - "order_dependent_trait_objects", "out_of_scope_macro_calls", "patterns_in_fns_without_body", "proc_macro_derive_resolution_fallback", - "ptr_cast_add_auto_to_object", "pub_use_of_private_extern_crate", - "repr_transparent_external_private_fields", + "repr_c_enums_larger_than_int", + "repr_transparent_non_zst_fields", "self_constructor_from_outer_item", "semicolon_in_expressions_from_macros", - "soft_unstable", "uncovered_param_in_projection", "uninhabited_static", "unstable_name_collisions", "unstable_syntax_pre_expansion", - "unsupported_fn_ptr_calling_conventions", - "wasm_c_abi", + "unsupported_calling_conventions", + "varargs_without_pattern", ], }, LintGroup { @@ -1790,8 +1973,23 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ }, LintGroup { lint: Lint { + label: "unknown_or_malformed_diagnostic_attributes", + description: r##"lint group for: malformed-diagnostic-attributes, malformed-diagnostic-format-literals, misplaced-diagnostic-attributes, unknown-diagnostic-attributes"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + children: &[ + "malformed_diagnostic_attributes", + "malformed_diagnostic_format_literals", + "misplaced_diagnostic_attributes", + "unknown_diagnostic_attributes", + ], + }, + LintGroup { + lint: Lint { label: "unused", - description: r##"lint group for: unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, + description: r##"lint group for: unused-imports, unused-variables, unused-visibilities, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-macro-rules, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons, map-unit-fn"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, @@ -1799,6 +1997,7 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ children: &[ "unused_imports", "unused_variables", + "unused_visibilities", "unused_assignments", "dead_code", "unused_mut", @@ -1902,15 +2101,8 @@ pub const RUSTDOC_LINTS: &[Lint] = &[ deny_since: None, }, Lint { - label: "rustdoc::unportable_markdown", - description: r##"detects markdown that is interpreted differently in different parser"##, - default_severity: Severity::Warning, - warn_since: None, - deny_since: None, - }, - Lint { label: "rustdoc::all", - description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, @@ -1920,7 +2112,7 @@ pub const RUSTDOC_LINTS: &[Lint] = &[ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup { lint: Lint { label: "rustdoc::all", - description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links, rustdoc::unportable-markdown"##, + description: r##"lint group for: rustdoc::broken-intra-doc-links, rustdoc::private-intra-doc-links, rustdoc::private-doc-tests, rustdoc::invalid-codeblock-attributes, rustdoc::invalid-rust-codeblocks, rustdoc::invalid-html-tags, rustdoc::bare-urls, rustdoc::missing-crate-level-docs, rustdoc::unescaped-backticks, rustdoc::redundant-explicit-links"##, default_severity: Severity::Allow, warn_since: None, deny_since: None, @@ -1936,7 +2128,6 @@ pub const RUSTDOC_LINT_GROUPS: &[LintGroup] = &[LintGroup { "rustdoc::missing_crate_level_docs", "rustdoc::unescaped_backticks", "rustdoc::redundant_explicit_links", - "rustdoc::unportable_markdown", ], }]; @@ -1945,9 +2136,11 @@ pub const FEATURES: &[Lint] = &[ label: "aarch64_unstable_target_feature", description: r##"# `aarch64_unstable_target_feature` -The tracking issue for this feature is: [#44839] +The remaining unstable target features on aarch64. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150244] + +[#150244]: https://github.com/rust-lang/rust/issues/150244 ------------------------ "##, @@ -1959,9 +2152,11 @@ The tracking issue for this feature is: [#44839] label: "aarch64_ver_target_feature", description: r##"# `aarch64_ver_target_feature` -The tracking issue for this feature is: [#44839] +Instruction set "version" target features on aarch64. + +The tracking issue for this feature is: [#150245] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#150245]: https://github.com/rust-lang/rust/issues/150245 ------------------------ "##, @@ -1973,6 +2168,8 @@ The tracking issue for this feature is: [#44839] label: "abi_avr_interrupt", description: r##"# `abi_avr_interrupt` +Allows `extern "avr-interrupt" fn()` and `extern "avr-non-blocking-interrupt" fn()`. + The tracking issue for this feature is: [#69664] [#69664]: https://github.com/rust-lang/rust/issues/69664 @@ -1984,8 +2181,8 @@ The tracking issue for this feature is: [#69664] deny_since: None, }, Lint { - label: "abi_c_cmse_nonsecure_call", - description: r##"# `abi_c_cmse_nonsecure_call` + label: "abi_cmse_nonsecure_call", + description: r##"# `abi_cmse_nonsecure_call` The tracking issue for this feature is: [#81391] @@ -2001,10 +2198,9 @@ LLVM, the Rust compiler and the linker are providing [support](https://developer.arm.com/documentation/ecm0359818/latest/) for the TrustZone-M feature. -One of the things provided, with this unstable feature, is the -`C-cmse-nonsecure-call` function ABI. This ABI is used on function pointers to -non-secure code to mark a non-secure function call (see [section -5.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details). +One of the things provided with this unstable feature is the "cmse-nonsecure-call" function ABI. +This ABI is used on function pointers to non-secure code to mark a non-secure function call +(see [section 5.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details). With this ABI, the compiler will do the following to perform the call: * save registers needed after the call to Secure memory @@ -2015,19 +2211,16 @@ With this ABI, the compiler will do the following to perform the call: To avoid using the non-secure stack, the compiler will constrain the number and type of parameters/return value. -The `extern "C-cmse-nonsecure-call"` ABI is otherwise equivalent to the -`extern "C"` ABI. - <!-- NOTE(ignore) this example is specific to thumbv8m targets --> ``` rust,ignore #![no_std] -#![feature(abi_c_cmse_nonsecure_call)] +#![feature(abi_cmse_nonsecure_call)] #[no_mangle] pub fn call_nonsecure_function(addr: usize) -> u32 { let non_secure_function = - unsafe { core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn() -> u32>(addr) }; + unsafe { core::mem::transmute::<usize, extern "cmse-nonsecure-call" fn() -> u32>(addr) }; non_secure_function() } ``` @@ -2079,6 +2272,38 @@ call_nonsecure_function: deny_since: None, }, Lint { + label: "abi_custom", + description: r##"# `abi_custom` + +Allows `extern "custom" fn()`. + +The tracking issue for this feature is: [#140829] + +[#140829]: https://github.com/rust-lang/rust/issues/140829 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "abi_gpu_kernel", + description: r##"# `abi_gpu_kernel` + +Allows `extern "gpu-kernel" fn()`. + +The tracking issue for this feature is: [#135467] + +[#135467]: https://github.com/rust-lang/rust/issues/135467 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "abi_msp430_interrupt", description: r##"# `abi_msp430_interrupt` @@ -2198,6 +2423,8 @@ $ cat $(find -name '*.s') label: "abi_riscv_interrupt", description: r##"# `abi_riscv_interrupt` +Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`. + The tracking issue for this feature is: [#111889] [#111889]: https://github.com/rust-lang/rust/issues/111889 @@ -2212,6 +2439,8 @@ The tracking issue for this feature is: [#111889] label: "abi_unadjusted", description: r##"# `abi_unadjusted` +Allows using the `unadjusted` ABI; perma-unstable. + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -2250,6 +2479,8 @@ fn main() { label: "abi_x86_interrupt", description: r##"# `abi_x86_interrupt` +Allows `extern "x86-interrupt" fn()`. + The tracking issue for this feature is: [#40180] [#40180]: https://github.com/rust-lang/rust/issues/40180 @@ -2264,6 +2495,8 @@ The tracking issue for this feature is: [#40180] label: "abort_unwind", description: r##"# `abort_unwind` + + The tracking issue for this feature is: [#130338] [#130338]: https://github.com/rust-lang/rust/issues/130338 @@ -2278,6 +2511,8 @@ The tracking issue for this feature is: [#130338] label: "acceptfilter", description: r##"# `acceptfilter` + + The tracking issue for this feature is: [#121891] [#121891]: https://github.com/rust-lang/rust/issues/121891 @@ -2292,6 +2527,8 @@ The tracking issue for this feature is: [#121891] label: "addr_parse_ascii", description: r##"# `addr_parse_ascii` + + The tracking issue for this feature is: [#101035] [#101035]: https://github.com/rust-lang/rust/issues/101035 @@ -2345,9 +2582,27 @@ fn is_foo_a_and_bar_true<const F: Foo, const B: Bar>() -> bool { deny_since: None, }, Lint { + label: "align_to_uninit_mut", + description: r##"# `align_to_uninit_mut` + + + +The tracking issue for this feature is: [#139062] + +[#139062]: https://github.com/rust-lang/rust/issues/139062 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "alloc_error_handler", description: r##"# `alloc_error_handler` +Allows defining an `#[alloc_error_handler]`. + The tracking issue for this feature is: [#51540] [#51540]: https://github.com/rust-lang/rust/issues/51540 @@ -2362,6 +2617,8 @@ The tracking issue for this feature is: [#51540] label: "alloc_error_hook", description: r##"# `alloc_error_hook` + + The tracking issue for this feature is: [#51245] [#51245]: https://github.com/rust-lang/rust/issues/51245 @@ -2376,6 +2633,8 @@ The tracking issue for this feature is: [#51245] label: "alloc_internals", description: r##"# `alloc_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -2385,12 +2644,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "alloc_layout_extra", - description: r##"# `alloc_layout_extra` + label: "alloc_slice_into_array", + description: r##"# `alloc_slice_into_array` + -The tracking issue for this feature is: [#55724] -[#55724]: https://github.com/rust-lang/rust/issues/55724 +The tracking issue for this feature is: [#148082] + +[#148082]: https://github.com/rust-lang/rust/issues/148082 ------------------------ "##, @@ -2435,9 +2696,25 @@ compiler. deny_since: None, }, Lint { + label: "alloctests", + description: r##"# `alloctests` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "allow_internal_unsafe", description: r##"# `allow_internal_unsafe` +Allows using `#[allow_internal_unsafe]`. This is an attribute on `macro_rules!` and can't use the attribute handling below (it has to be checked before expansion possibly makes macros disappear). + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -2450,6 +2727,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "allow_internal_unstable", description: r##"# `allow_internal_unstable` +Allows using `#[allow_internal_unstable]`. This is an attribute on `macro_rules!` and can't use the attribute handling below (it has to be checked before expansion possibly makes macros disappear). + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -2462,6 +2741,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "anonymous_lifetime_in_impl_trait", description: r##"# `anonymous_lifetime_in_impl_trait` +Allows using anonymous lifetimes in argument-position impl-trait. + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -2471,12 +2752,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "anonymous_pipe", - description: r##"# `anonymous_pipe` + label: "apx_target_feature", + description: r##"# `apx_target_feature` -The tracking issue for this feature is: [#127154] +The `apxf` target feature on x86 -[#127154]: https://github.com/rust-lang/rust/issues/127154 +The tracking issue for this feature is: [#139284] + +[#139284]: https://github.com/rust-lang/rust/issues/139284 ------------------------ "##, @@ -2493,6 +2776,153 @@ The tracking issue for this feature is: [#44874] [#44874]: https://github.com/rust-lang/rust/issues/44874 ------------------------ + +Allows any type implementing `core::ops::Receiver<Target=T>` to be used as the type +of `self` in a method belonging to `T`. + +For example, + +```rust +#![feature(arbitrary_self_types)] + +struct A; + +impl A { + fn f(self: SmartPtr<Self>) -> i32 { 1 } // note self type +} + +struct SmartPtr<T>(T); + +impl<T> core::ops::Receiver for SmartPtr<T> { + type Target = T; +} + +fn main() { + let smart_ptr = SmartPtr(A); + assert_eq!(smart_ptr.f(), 1); +} +``` + +The `Receiver` trait has a blanket implementation for all `T: Deref`, so in fact +things like this work too: + +```rust +#![feature(arbitrary_self_types)] + +use std::rc::Rc; + +struct A; + +impl A { + fn f(self: Rc<Self>) -> i32 { 1 } // Rc implements Deref +} + +fn main() { + let smart_ptr = Rc::new(A); + assert_eq!(smart_ptr.f(), 1); +} +``` + +Interestingly, that works even without the `arbitrary_self_types` feature +- but that's because certain types are _effectively_ hard coded, including +`Rc`. ("Hard coding" isn't quite true; they use a lang-item called +`LegacyReceiver` to denote their special-ness in this way). With the +`arbitrary_self_types` feature, their special-ness goes away, and custom +smart pointers can achieve the same. + +## Changes to method lookup + +Method lookup previously used to work by stepping through the `Deref` +chain then using the resulting list of steps in two different ways: + +* To identify types that might contribute methods via their `impl` + blocks (inherent methods) or via traits +* To identify the types that the method receiver (`a` in the above + examples) can be converted to. + +With this feature, these lists are created by instead stepping through +the `Receiver` chain. However, a note is kept about whether the type +can be reached also via the `Deref` chain. + +The full chain (via `Receiver` hops) is used for the first purpose +(identifying relevant `impl` blocks and traits); whereas the shorter +list (reachable via `Deref`) is used for the second purpose. That's +because, to convert the method target (`a` in `a.b()`) to the self +type, Rust may need to be able to use `Deref::deref`. Type conversions, +then, can only proceed as far as the end of the `Deref` chain whereas +the longer `Receiver` chain can be used to explore more places where +useful methods might reside. + +## Types suitable for use as smart pointers + +This feature allows the creation of customised smart pointers - for example +your own equivalent to `Rc` or `Box` with whatever capabilities you like. +Those smart pointers can either implement `Deref` (if it's safe to +create a reference to the referent) or `Receiver` (if it isn't). + +Either way, smart pointer types should mostly _avoid having methods_. +Calling methods on a smart pointer leads to ambiguity about whether you're +aiming for a method on the pointer, or on the referent. + +Best practice is therefore to put smart pointer functionality into +associated functions instead - that's what's done in all the smart pointer +types within Rust's standard library which implement `Receiver`. + +If you choose to add any methods to your smart pointer type, your users +may run into errors from deshadowing, as described in the next section. + +## Avoiding shadowing + +With or without this feature, Rust emits an error if it finds two method +candidates, like this: + +```rust,compile_fail +use std::pin::Pin; +use std::pin::pin; + +struct A; + +impl A { + fn get_ref(self: Pin<&A>) {} +} + +fn main() { + let pinned_a: Pin<&A> = pin!(A).as_ref(); + let pinned_a: Pin<&A> = pinned_a.as_ref(); + pinned_a.get_ref(); // error[E0034]: multiple applicable items in scope +} +``` + +(this is why Rust's smart pointers are mostly carefully designed to avoid +having methods at all, and shouldn't add new methods in future.) + +With `arbitrary_self_types`, we take care to spot some other kinds of +conflict: + +```rust,compile_fail +#![feature(arbitrary_self_types)] + +use std::pin::Pin; +use std::pin::pin; + +struct A; + +impl A { + fn get_ref(self: &Pin<&A>) {} // note &Pin +} + +fn main() { + let pinned_a: Pin<&mut A> = pin!(A); + let pinned_a: Pin<&A> = pinned_a.as_ref(); + pinned_a.get_ref(); +} +``` + +This is to guard against the case where an inner (referent) type has a +method of a given name, taking the smart pointer by reference, and then +the smart pointer implementer adds a similar method taking self by value. +As noted in the previous section, the safe option is simply +not to add methods to smart pointers, and then these errors can't occur. "##, default_severity: Severity::Allow, warn_since: None, @@ -2504,21 +2934,73 @@ The tracking issue for this feature is: [#44874] The tracking issue for this feature is: [#44874] -[#44874]: https://github.com/rust-lang/rust/issues/44874 +[#38788]: https://github.com/rust-lang/rust/issues/44874 ------------------------ + +This extends the [arbitrary self types] feature to allow methods to +receive `self` by pointer. For example: + +```rust +#![feature(arbitrary_self_types_pointers)] + +struct A; + +impl A { + fn m(self: *const Self) {} +} + +fn main() { + let a = A; + let a_ptr: *const A = &a as *const A; + a_ptr.m(); +} +``` + +In general this is not advised: it's thought to be better practice to wrap +raw pointers in a newtype wrapper which implements the `core::ops::Receiver` +trait, then you need "only" the `arbitrary_self_types` feature. For example: + +```rust +#![feature(arbitrary_self_types)] +#![allow(dead_code)] + +struct A; + +impl A { + fn m(self: Wrapper<Self>) {} // can extract the pointer and do + // what it needs +} + +struct Wrapper<T>(*const T); + +impl<T> core::ops::Receiver for Wrapper<T> { + type Target = T; +} + +fn main() { + let a = A; + let a_ptr: *const A = &a as *const A; + let a_wrapper = Wrapper(a_ptr); + a_wrapper.m(); +} +``` + +[arbitrary self types]: arbitrary-self-types.md "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "arm_target_feature", - description: r##"# `arm_target_feature` + label: "arc_is_unique", + description: r##"# `arc_is_unique` -The tracking issue for this feature is: [#44839] -[#44839]: https://github.com/rust-lang/rust/issues/44839 + +The tracking issue for this feature is: [#138938] + +[#138938]: https://github.com/rust-lang/rust/issues/138938 ------------------------ "##, @@ -2527,12 +3009,14 @@ The tracking issue for this feature is: [#44839] deny_since: None, }, Lint { - label: "array_chunks", - description: r##"# `array_chunks` + label: "arm_target_feature", + description: r##"# `arm_target_feature` -The tracking issue for this feature is: [#74985] +Target features on arm. -[#74985]: https://github.com/rust-lang/rust/issues/74985 +The tracking issue for this feature is: [#150246] + +[#150246]: https://github.com/rust-lang/rust/issues/150246 ------------------------ "##, @@ -2544,6 +3028,8 @@ The tracking issue for this feature is: [#74985] label: "array_into_iter_constructors", description: r##"# `array_into_iter_constructors` + + The tracking issue for this feature is: [#91583] [#91583]: https://github.com/rust-lang/rust/issues/91583 @@ -2558,23 +3044,11 @@ The tracking issue for this feature is: [#91583] label: "array_ptr_get", description: r##"# `array_ptr_get` -The tracking issue for this feature is: [#119834] - -[#119834]: https://github.com/rust-lang/rust/issues/119834 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "array_repeat", - description: r##"# `array_repeat` -The tracking issue for this feature is: [#126695] +The tracking issue for this feature is: [#119834] -[#126695]: https://github.com/rust-lang/rust/issues/126695 +[#119834]: https://github.com/rust-lang/rust/issues/119834 ------------------------ "##, @@ -2586,6 +3060,8 @@ The tracking issue for this feature is: [#126695] label: "array_try_from_fn", description: r##"# `array_try_from_fn` + + The tracking issue for this feature is: [#89379] [#89379]: https://github.com/rust-lang/rust/issues/89379 @@ -2600,37 +3076,11 @@ The tracking issue for this feature is: [#89379] label: "array_try_map", description: r##"# `array_try_map` -The tracking issue for this feature is: [#79711] - -[#79711]: https://github.com/rust-lang/rust/issues/79711 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "array_windows", - description: r##"# `array_windows` - -The tracking issue for this feature is: [#75027] - -[#75027]: https://github.com/rust-lang/rust/issues/75027 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "as_array_of_cells", - description: r##"# `as_array_of_cells` -The tracking issue for this feature is: [#88248] +The tracking issue for this feature is: [#79711] -[#88248]: https://github.com/rust-lang/rust/issues/88248 +[#79711]: https://github.com/rust-lang/rust/issues/79711 ------------------------ "##, @@ -2642,6 +3092,8 @@ The tracking issue for this feature is: [#88248] label: "ascii_char", description: r##"# `ascii_char` + + The tracking issue for this feature is: [#110998] [#110998]: https://github.com/rust-lang/rust/issues/110998 @@ -2656,6 +3108,8 @@ The tracking issue for this feature is: [#110998] label: "ascii_char_variants", description: r##"# `ascii_char_variants` + + The tracking issue for this feature is: [#110998] [#110998]: https://github.com/rust-lang/rust/issues/110998 @@ -2678,7 +3132,6 @@ The tracking issue for this feature is: [#93335] This feature tracks `asm!` and `global_asm!` support for the following architectures: - NVPTX -- PowerPC - Hexagon - MIPS32r2 and MIPS64r2 - wasm32 @@ -2701,12 +3154,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg64` | None\* | `l` | | Hexagon | `reg` | `r[0-28]` | `r` | | Hexagon | `preg` | `p[0-3]` | Only clobbers | -| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | -| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | -| PowerPC | `freg` | `f[0-31]` | `f` | -| PowerPC | `vreg` | `v[0-31]` | `v` | -| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers | -| PowerPC | `xer` | `xer` | Only clobbers | | wasm32 | `local` | None\* | `r` | | BPF | `reg` | `r[0-10]` | `r` | | BPF | `wreg` | `w[0-10]` | `w` | @@ -2742,13 +3189,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | | Hexagon | `preg` | N/A | Only clobbers | -| PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | -| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | -| PowerPC | `freg` | None | `f32`, `f64` | -| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | -| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` | -| PowerPC | `cr` | N/A | Only clobbers | -| PowerPC | `xer` | N/A | Only clobbers | | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | | BPF | `reg` | None | `i8` `i16` `i32` `i64` | | BPF | `wreg` | `alu32` | `i8` `i16` `i32` | @@ -2769,10 +3209,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Hexagon | `r29` | `sp` | | Hexagon | `r30` | `fr` | | Hexagon | `r31` | `lr` | -| PowerPC | `r1` | `sp` | -| PowerPC | `r31` | `fp` | -| PowerPC | `r[0-31]` | `[0-31]` | -| PowerPC | `f[0-31]` | `fr[0-31]`| | BPF | `r[0-10]` | `w[0-10]` | | AVR | `XH` | `r27` | | AVR | `XL` | `r26` | @@ -2811,18 +3247,14 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | -| All | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | +| All | `fr` (Hexagon) `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. | +| All | `r19` (Hexagon) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | | MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. | | MIPS | `$ra` | Return address cannot be used as inputs or outputs. | | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | -| PowerPC | `r2`, `r13` | These are system reserved registers. | -| PowerPC | `lr` | The link register cannot be used as an input or output. | -| PowerPC | `ctr` | The counter register cannot be used as an input or output. | -| PowerPC | `vrsave` | The vrsave register cannot be used as an input or output. | | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | @@ -2849,10 +3281,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | NVPTX | `reg32` | None | `r0` | None | | NVPTX | `reg64` | None | `rd0` | None | | Hexagon | `reg` | None | `r0` | None | -| PowerPC | `reg` | None | `0` | None | -| PowerPC | `reg_nonzero` | None | `3` | None | -| PowerPC | `freg` | None | `0` | None | -| PowerPC | `vreg` | None | `0` | None | | SPARC | `reg` | None | `%o0` | None | | CSKY | `reg` | None | `r0` | None | | CSKY | `freg` | None | `f0` | None | @@ -2869,6 +3297,8 @@ These flags registers must be restored upon exiting the asm block if the `preser - SPARC - Integer condition codes (`icc` and `xcc`) - Floating-point condition codes (`fcc[0-3]`) +- CSKY + - Condition/carry bit (C) in `PSR`. "##, default_severity: Severity::Allow, warn_since: None, @@ -2890,16 +3320,14 @@ This tracks support for additional registers in architectures where inline assem | Architecture | Register class | Registers | LLVM constraint code | | ------------ | -------------- | --------- | -------------------- | -| s390x | `vreg` | `v[0-31]` | `v` | - -> **Notes**: -> - s390x `vreg` is clobber-only in stable. ## Register class supported types | Architecture | Register class | Target feature | Allowed types | | ------------ | -------------- | -------------- | ------------- | -| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| x86 | `xmm_reg` | `sse` | `i128` | +| x86 | `ymm_reg` | `avx` | `i128` | +| x86 | `zmm_reg` | `avx512f` | `i128` | ## Register aliases @@ -2915,15 +3343,14 @@ This tracks support for additional registers in architectures where inline assem | Architecture | Register class | Modifier | Example output | LLVM modifier | | ------------ | -------------- | -------- | -------------- | ------------- | -| s390x | `vreg` | None | `%v0` | None | "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "asm_goto", - description: r##"# `asm_goto` + label: "asm_goto_with_outputs", + description: r##"# `asm_goto_with_outputs` The tracking issue for this feature is: [#119364] @@ -2931,44 +3358,25 @@ The tracking issue for this feature is: [#119364] ------------------------ -This feature adds a `label <block>` operand type to `asm!`. +This feature allows label operands to be used together with output operands. Example: ```rust,ignore (partial-example, x86-only) unsafe { + let a: usize; asm!( + "mov {}, 1" "jmp {}", + out(reg) a, label { - println!("Jumped from asm!"); + println!("Jumped from asm {}!", a); } ); } ``` -The block must have unit type or diverge. The block starts a new safety context, -so despite outer `unsafe`, you need extra unsafe to perform unsafe operations -within `label <block>`. - -When `label <block>` is used together with `noreturn` option, it means that the -assembly will not fallthrough. It's allowed to jump to a label within the -assembly. In this case, the entire `asm!` expression will have an unit type as -opposed to diverging, if not all label blocks diverge. The `asm!` expression -still diverges if `noreturn` option is used and all label blocks diverge. -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "asm_goto_with_outputs", - description: r##"# `asm_goto_with_outputs` - -The tracking issue for this feature is: [#119364] - -[#119364]: https://github.com/rust-lang/rust/issues/119364 - ------------------------- +The output operands are assigned before the label blocks are executed. "##, default_severity: Severity::Allow, warn_since: None, @@ -2991,37 +3399,11 @@ This feature adds a `may_unwind` option to `asm!` which allows an `asm` block to deny_since: None, }, Lint { - label: "assert_matches", - description: r##"# `assert_matches` - -The tracking issue for this feature is: [#82775] - -[#82775]: https://github.com/rust-lang/rust/issues/82775 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "associated_const_equality", - description: r##"# `associated_const_equality` - -The tracking issue for this feature is: [#92827] - -[#92827]: https://github.com/rust-lang/rust/issues/92827 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { label: "associated_type_defaults", description: r##"# `associated_type_defaults` +Allows associated type defaults. + The tracking issue for this feature is: [#29661] [#29661]: https://github.com/rust-lang/rust/issues/29661 @@ -3033,12 +3415,14 @@ The tracking issue for this feature is: [#29661] deny_since: None, }, Lint { - label: "async_closure", - description: r##"# `async_closure` + label: "async_drop", + description: r##"# `async_drop` -The tracking issue for this feature is: [#62290] +Allows implementing `AsyncDrop`. -[#62290]: https://github.com/rust-lang/rust/issues/62290 +The tracking issue for this feature is: [#126482] + +[#126482]: https://github.com/rust-lang/rust/issues/126482 ------------------------ "##, @@ -3047,12 +3431,14 @@ The tracking issue for this feature is: [#62290] deny_since: None, }, Lint { - label: "async_drop", - description: r##"# `async_drop` + label: "async_fn_in_dyn_trait", + description: r##"# `async_fn_in_dyn_trait` -The tracking issue for this feature is: [#126482] +Allows async functions to be called from `dyn Trait`. -[#126482]: https://github.com/rust-lang/rust/issues/126482 +The tracking issue for this feature is: [#133119] + +[#133119]: https://github.com/rust-lang/rust/issues/133119 ------------------------ "##, @@ -3064,6 +3450,8 @@ The tracking issue for this feature is: [#126482] label: "async_fn_track_caller", description: r##"# `async_fn_track_caller` +Allows `#[track_caller]` on async functions. + The tracking issue for this feature is: [#110011] [#110011]: https://github.com/rust-lang/rust/issues/110011 @@ -3098,6 +3486,8 @@ that borrows from itself (`FnOnce::Output` has no lifetime parameters, while `As label: "async_for_loop", description: r##"# `async_for_loop` +Allows `for await` loops. + The tracking issue for this feature is: [#118898] [#118898]: https://github.com/rust-lang/rust/issues/118898 @@ -3112,6 +3502,8 @@ The tracking issue for this feature is: [#118898] label: "async_gen_internals", description: r##"# `async_gen_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -3124,6 +3516,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "async_iter_from_iter", description: r##"# `async_iter_from_iter` + + The tracking issue for this feature is: [#81798] [#81798]: https://github.com/rust-lang/rust/issues/81798 @@ -3138,6 +3532,8 @@ The tracking issue for this feature is: [#81798] label: "async_iterator", description: r##"# `async_iterator` + + The tracking issue for this feature is: [#79024] [#79024]: https://github.com/rust-lang/rust/issues/79024 @@ -3152,6 +3548,8 @@ The tracking issue for this feature is: [#79024] label: "async_trait_bounds", description: r##"# `async_trait_bounds` +Allows `async` trait bound modifier. + The tracking issue for this feature is: [#62290] [#62290]: https://github.com/rust-lang/rust/issues/62290 @@ -3166,6 +3564,8 @@ The tracking issue for this feature is: [#62290] label: "atomic_from_mut", description: r##"# `atomic_from_mut` + + The tracking issue for this feature is: [#76314] [#76314]: https://github.com/rust-lang/rust/issues/76314 @@ -3177,6 +3577,36 @@ The tracking issue for this feature is: [#76314] deny_since: None, }, Lint { + label: "atomic_internals", + description: r##"# `atomic_internals` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "atomic_ptr_null", + description: r##"# `atomic_ptr_null` + + + +The tracking issue for this feature is: [#150733] + +[#150733]: https://github.com/rust-lang/rust/issues/150733 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "auto_traits", description: r##"# `auto_traits` @@ -3293,6 +3723,8 @@ Auto traits cannot have supertraits. This is for soundness reasons, as the inter label: "autodiff", description: r##"# `autodiff` + + The tracking issue for this feature is: [#124509] [#124509]: https://github.com/rust-lang/rust/issues/124509 @@ -3304,12 +3736,30 @@ The tracking issue for this feature is: [#124509] deny_since: None, }, Lint { - label: "avx512_target_feature", - description: r##"# `avx512_target_feature` + label: "avr_target_feature", + description: r##"# `avr_target_feature` -The tracking issue for this feature is: [#44839] +Target features on avr. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#146889] + +[#146889]: https://github.com/rust-lang/rust/issues/146889 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "avx10_target_feature", + description: r##"# `avx10_target_feature` + +Allows using Intel AVX10 target features and intrinsics + +The tracking issue for this feature is: [#138843] + +[#138843]: https://github.com/rust-lang/rust/issues/138843 ------------------------ "##, @@ -3321,6 +3771,8 @@ The tracking issue for this feature is: [#44839] label: "backtrace_frames", description: r##"# `backtrace_frames` + + The tracking issue for this feature is: [#79676] [#79676]: https://github.com/rust-lang/rust/issues/79676 @@ -3332,12 +3784,28 @@ The tracking issue for this feature is: [#79676] deny_since: None, }, Lint { - label: "bigint_helper_methods", - description: r##"# `bigint_helper_methods` + label: "bikeshed_guaranteed_no_drop", + description: r##"# `bikeshed_guaranteed_no_drop` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "binary_heap_as_mut_slice", + description: r##"# `binary_heap_as_mut_slice` -The tracking issue for this feature is: [#85532] -[#85532]: https://github.com/rust-lang/rust/issues/85532 + +The tracking issue for this feature is: [#154009] + +[#154009]: https://github.com/rust-lang/rust/issues/154009 ------------------------ "##, @@ -3349,6 +3817,8 @@ The tracking issue for this feature is: [#85532] label: "binary_heap_drain_sorted", description: r##"# `binary_heap_drain_sorted` + + The tracking issue for this feature is: [#59278] [#59278]: https://github.com/rust-lang/rust/issues/59278 @@ -3360,9 +3830,27 @@ The tracking issue for this feature is: [#59278] deny_since: None, }, Lint { + label: "binary_heap_from_raw_vec", + description: r##"# `binary_heap_from_raw_vec` + + + +The tracking issue for this feature is: [#152500] + +[#152500]: https://github.com/rust-lang/rust/issues/152500 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "binary_heap_into_iter_sorted", description: r##"# `binary_heap_into_iter_sorted` + + The tracking issue for this feature is: [#59278] [#59278]: https://github.com/rust-lang/rust/issues/59278 @@ -3374,9 +3862,75 @@ The tracking issue for this feature is: [#59278] deny_since: None, }, Lint { + label: "binary_heap_peek_mut_refresh", + description: r##"# `binary_heap_peek_mut_refresh` + + + +The tracking issue for this feature is: [#138355] + +[#138355]: https://github.com/rust-lang/rust/issues/138355 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "binary_heap_pop_if", + description: r##"# `binary_heap_pop_if` + + + +The tracking issue for this feature is: [#151828] + +[#151828]: https://github.com/rust-lang/rust/issues/151828 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "bool_to_result", + description: r##"# `bool_to_result` + + + +The tracking issue for this feature is: [#142748] + +[#142748]: https://github.com/rust-lang/rust/issues/142748 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "borrowed_buf_init", + description: r##"# `borrowed_buf_init` + + + +The tracking issue for this feature is: [#78485] + +[#78485]: https://github.com/rust-lang/rust/issues/78485 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "bound_as_ref", description: r##"# `bound_as_ref` + + The tracking issue for this feature is: [#80996] [#80996]: https://github.com/rust-lang/rust/issues/80996 @@ -3388,9 +3942,27 @@ The tracking issue for this feature is: [#80996] deny_since: None, }, Lint { + label: "bound_copied", + description: r##"# `bound_copied` + + + +The tracking issue for this feature is: [#145966] + +[#145966]: https://github.com/rust-lang/rust/issues/145966 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "box_as_ptr", description: r##"# `box_as_ptr` + + The tracking issue for this feature is: [#129090] [#129090]: https://github.com/rust-lang/rust/issues/129090 @@ -3405,6 +3977,8 @@ The tracking issue for this feature is: [#129090] label: "box_into_boxed_slice", description: r##"# `box_into_boxed_slice` + + The tracking issue for this feature is: [#71582] [#71582]: https://github.com/rust-lang/rust/issues/71582 @@ -3419,6 +3993,8 @@ The tracking issue for this feature is: [#71582] label: "box_into_inner", description: r##"# `box_into_inner` + + The tracking issue for this feature is: [#80437] [#80437]: https://github.com/rust-lang/rust/issues/80437 @@ -3439,6 +4015,8 @@ The tracking issue for this feature is: [#29641] ------------------------ +> **Note**: This feature will be superseded by [`deref_patterns`] in the future. + Box patterns let you match on `Box<T>`s: @@ -3461,18 +4039,22 @@ fn main() { } } ``` + +[`deref_patterns`]: ./deref-patterns.md "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "box_uninit_write", - description: r##"# `box_uninit_write` + label: "box_take", + description: r##"# `box_take` + + -The tracking issue for this feature is: [#129397] +The tracking issue for this feature is: [#147212] -[#129397]: https://github.com/rust-lang/rust/issues/129397 +[#147212]: https://github.com/rust-lang/rust/issues/147212 ------------------------ "##, @@ -3484,6 +4066,8 @@ The tracking issue for this feature is: [#129397] label: "box_vec_non_null", description: r##"# `box_vec_non_null` + + The tracking issue for this feature is: [#130364] [#130364]: https://github.com/rust-lang/rust/issues/130364 @@ -3498,9 +4082,11 @@ The tracking issue for this feature is: [#130364] label: "bpf_target_feature", description: r##"# `bpf_target_feature` -The tracking issue for this feature is: [#44839] +Target features on bpf. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150247] + +[#150247]: https://github.com/rust-lang/rust/issues/150247 ------------------------ "##, @@ -3512,6 +4098,8 @@ The tracking issue for this feature is: [#44839] label: "breakpoint", description: r##"# `breakpoint` + + The tracking issue for this feature is: [#133724] [#133724]: https://github.com/rust-lang/rust/issues/133724 @@ -3523,12 +4111,28 @@ The tracking issue for this feature is: [#133724] deny_since: None, }, Lint { - label: "btree_cursors", - description: r##"# `btree_cursors` + label: "bstr", + description: r##"# `bstr` -The tracking issue for this feature is: [#107540] -[#107540]: https://github.com/rust-lang/rust/issues/107540 + +The tracking issue for this feature is: [#134915] + +[#134915]: https://github.com/rust-lang/rust/issues/134915 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "bstr_internals", + description: r##"# `bstr_internals` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -3537,12 +4141,14 @@ The tracking issue for this feature is: [#107540] deny_since: None, }, Lint { - label: "btree_entry_insert", - description: r##"# `btree_entry_insert` + label: "btree_cursors", + description: r##"# `btree_cursors` + -The tracking issue for this feature is: [#65225] -[#65225]: https://github.com/rust-lang/rust/issues/65225 +The tracking issue for this feature is: [#107540] + +[#107540]: https://github.com/rust-lang/rust/issues/107540 ------------------------ "##, @@ -3551,12 +4157,14 @@ The tracking issue for this feature is: [#65225] deny_since: None, }, Lint { - label: "btree_extract_if", - description: r##"# `btree_extract_if` + label: "btree_merge", + description: r##"# `btree_merge` + -The tracking issue for this feature is: [#70530] -[#70530]: https://github.com/rust-lang/rust/issues/70530 +The tracking issue for this feature is: [#152152] + +[#152152]: https://github.com/rust-lang/rust/issues/152152 ------------------------ "##, @@ -3568,6 +4176,8 @@ The tracking issue for this feature is: [#70530] label: "btree_set_entry", description: r##"# `btree_set_entry` + + The tracking issue for this feature is: [#133549] [#133549]: https://github.com/rust-lang/rust/issues/133549 @@ -3582,6 +4192,8 @@ The tracking issue for this feature is: [#133549] label: "btreemap_alloc", description: r##"# `btreemap_alloc` + + The tracking issue for this feature is: [#32838] [#32838]: https://github.com/rust-lang/rust/issues/32838 @@ -3596,6 +4208,8 @@ The tracking issue for this feature is: [#32838] label: "buf_read_has_data_left", description: r##"# `buf_read_has_data_left` + + The tracking issue for this feature is: [#86423] [#86423]: https://github.com/rust-lang/rust/issues/86423 @@ -3610,6 +4224,8 @@ The tracking issue for this feature is: [#86423] label: "bufreader_peek", description: r##"# `bufreader_peek` + + The tracking issue for this feature is: [#128405] [#128405]: https://github.com/rust-lang/rust/issues/128405 @@ -3624,6 +4240,8 @@ The tracking issue for this feature is: [#128405] label: "builtin_syntax", description: r##"# `builtin_syntax` +Allows builtin # foo() syntax + The tracking issue for this feature is: [#110680] [#110680]: https://github.com/rust-lang/rust/issues/110680 @@ -3638,23 +4256,11 @@ The tracking issue for this feature is: [#110680] label: "c_size_t", description: r##"# `c_size_t` -The tracking issue for this feature is: [#88345] - -[#88345]: https://github.com/rust-lang/rust/issues/88345 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "c_str_module", - description: r##"# `c_str_module` -The tracking issue for this feature is: [#112134] +The tracking issue for this feature is: [#88345] -[#112134]: https://github.com/rust-lang/rust/issues/112134 +[#88345]: https://github.com/rust-lang/rust/issues/88345 ------------------------ "##, @@ -3694,33 +4300,16 @@ pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize { deny_since: None, }, Lint { - label: "c_variadic", - description: r##"# `c_variadic` - -The tracking issue for this feature is: [#44930] + label: "c_variadic_naked_functions", + description: r##"# `c_variadic_naked_functions` -[#44930]: https://github.com/rust-lang/rust/issues/44930 - ------------------------- - -The `c_variadic` library feature exposes the `VaList` structure, -Rust's analogue of C's `va_list` type. +Allows defining c-variadic naked functions with any extern ABI that is allowed on c-variadic foreign functions. -## Examples - -```rust -#![feature(c_variadic)] +The tracking issue for this feature is: [#148767] -use std::ffi::VaList; +[#148767]: https://github.com/rust-lang/rust/issues/148767 -pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize { - let mut sum = 0; - for _ in 0..n { - sum += args.arg::<usize>(); - } - sum -} -``` +------------------------ "##, default_severity: Severity::Allow, warn_since: None, @@ -3742,6 +4331,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "can_vector", description: r##"# `can_vector` + + The tracking issue for this feature is: [#69941] [#69941]: https://github.com/rust-lang/rust/issues/69941 @@ -3753,12 +4344,14 @@ The tracking issue for this feature is: [#69941] deny_since: None, }, Lint { - label: "cell_leak", - description: r##"# `cell_leak` + label: "case_ignorable", + description: r##"# `case_ignorable` -The tracking issue for this feature is: [#69099] -[#69099]: https://github.com/rust-lang/rust/issues/69099 + +The tracking issue for this feature is: [#154848] + +[#154848]: https://github.com/rust-lang/rust/issues/154848 ------------------------ "##, @@ -3767,12 +4360,46 @@ The tracking issue for this feature is: [#69099] deny_since: None, }, Lint { - label: "cell_update", - description: r##"# `cell_update` + label: "cast_maybe_uninit", + description: r##"# `cast_maybe_uninit` -The tracking issue for this feature is: [#50186] -[#50186]: https://github.com/rust-lang/rust/issues/50186 + +The tracking issue for this feature is: [#145036] + +[#145036]: https://github.com/rust-lang/rust/issues/145036 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cell_get_cloned", + description: r##"# `cell_get_cloned` + + + +The tracking issue for this feature is: [#145329] + +[#145329]: https://github.com/rust-lang/rust/issues/145329 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cell_leak", + description: r##"# `cell_leak` + + + +The tracking issue for this feature is: [#69099] + +[#69099]: https://github.com/rust-lang/rust/issues/69099 ------------------------ "##, @@ -3784,6 +4411,8 @@ The tracking issue for this feature is: [#50186] label: "cfg_accessible", description: r##"# `cfg_accessible` + + The tracking issue for this feature is: [#64797] [#64797]: https://github.com/rust-lang/rust/issues/64797 @@ -3795,12 +4424,14 @@ The tracking issue for this feature is: [#64797] deny_since: None, }, Lint { - label: "cfg_eval", - description: r##"# `cfg_eval` + label: "cfg_contract_checks", + description: r##"# `cfg_contract_checks` -The tracking issue for this feature is: [#82679] +Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. -[#82679]: https://github.com/rust-lang/rust/issues/82679 +The tracking issue for this feature is: [#128044] + +[#128044]: https://github.com/rust-lang/rust/issues/128044 ------------------------ "##, @@ -3809,12 +4440,28 @@ The tracking issue for this feature is: [#82679] deny_since: None, }, Lint { - label: "cfg_match", - description: r##"# `cfg_match` + label: "cfg_emscripten_wasm_eh", + description: r##"# `cfg_emscripten_wasm_eh` -The tracking issue for this feature is: [#115585] +Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind -[#115585]: https://github.com/rust-lang/rust/issues/115585 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cfg_eval", + description: r##"# `cfg_eval` + + + +The tracking issue for this feature is: [#82679] + +[#82679]: https://github.com/rust-lang/rust/issues/82679 ------------------------ "##, @@ -3826,6 +4473,8 @@ The tracking issue for this feature is: [#115585] label: "cfg_overflow_checks", description: r##"# `cfg_overflow_checks` +Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. + The tracking issue for this feature is: [#111466] [#111466]: https://github.com/rust-lang/rust/issues/111466 @@ -3840,6 +4489,8 @@ The tracking issue for this feature is: [#111466] label: "cfg_relocation_model", description: r##"# `cfg_relocation_model` +Provides the relocation model information as cfg entry + The tracking issue for this feature is: [#114929] [#114929]: https://github.com/rust-lang/rust/issues/114929 @@ -3895,6 +4546,8 @@ fn b() { label: "cfg_sanitizer_cfi", description: r##"# `cfg_sanitizer_cfi` +Allows `cfg(sanitizer_cfi_generalize_pointers)` and `cfg(sanitizer_cfi_normalize_integers)`. + The tracking issue for this feature is: [#89653] [#89653]: https://github.com/rust-lang/rust/issues/89653 @@ -3909,6 +4562,8 @@ The tracking issue for this feature is: [#89653] label: "cfg_target_compact", description: r##"# `cfg_target_compact` +Allows `cfg(target(abi = "..."))`. + The tracking issue for this feature is: [#96901] [#96901]: https://github.com/rust-lang/rust/issues/96901 @@ -3923,6 +4578,8 @@ The tracking issue for this feature is: [#96901] label: "cfg_target_has_atomic", description: r##"# `cfg_target_has_atomic` +Allows `cfg(target_has_atomic_load_store = "...")`. + The tracking issue for this feature is: [#94039] [#94039]: https://github.com/rust-lang/rust/issues/94039 @@ -3937,6 +4594,8 @@ The tracking issue for this feature is: [#94039] label: "cfg_target_has_atomic_equal_alignment", description: r##"# `cfg_target_has_atomic_equal_alignment` +Allows `cfg(target_has_atomic_equal_alignment = "...")`. + The tracking issue for this feature is: [#93822] [#93822]: https://github.com/rust-lang/rust/issues/93822 @@ -3948,9 +4607,25 @@ The tracking issue for this feature is: [#93822] deny_since: None, }, Lint { + label: "cfg_target_has_reliable_f16_f128", + description: r##"# `cfg_target_has_reliable_f16_f128` + +Allows checking whether or not the backend correctly supports unstable float types. + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "cfg_target_thread_local", description: r##"# `cfg_target_thread_local` +Allows `cfg(target_thread_local)`. + The tracking issue for this feature is: [#29594] [#29594]: https://github.com/rust-lang/rust/issues/29594 @@ -3965,6 +4640,8 @@ The tracking issue for this feature is: [#29594] label: "cfg_ub_checks", description: r##"# `cfg_ub_checks` +Allows the use of `#[cfg(ub_checks)` to check if UB checks are enabled. + The tracking issue for this feature is: [#123499] [#123499]: https://github.com/rust-lang/rust/issues/123499 @@ -4053,6 +4730,8 @@ extern { label: "char_internals", description: r##"# `char_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -4062,9 +4741,59 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "char_max_len", + description: r##"# `char_max_len` + + + +The tracking issue for this feature is: [#121714] + +[#121714]: https://github.com/rust-lang/rust/issues/121714 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clamp_magnitude", + description: r##"# `clamp_magnitude` + + + +The tracking issue for this feature is: [#148519] + +[#148519]: https://github.com/rust-lang/rust/issues/148519 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "clone_from_ref", + description: r##"# `clone_from_ref` + + + +The tracking issue for this feature is: [#149075] + +[#149075]: https://github.com/rust-lang/rust/issues/149075 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "clone_to_uninit", description: r##"# `clone_to_uninit` + + The tracking issue for this feature is: [#126799] [#126799]: https://github.com/rust-lang/rust/issues/126799 @@ -4079,6 +4808,8 @@ The tracking issue for this feature is: [#126799] label: "closure_lifetime_binder", description: r##"# `closure_lifetime_binder` +Allows `for<...>` on closures and coroutines. + The tracking issue for this feature is: [#97362] [#97362]: https://github.com/rust-lang/rust/issues/97362 @@ -4112,6 +4843,8 @@ available through `std::panic::Location::caller()`, just like using label: "cmp_minmax", description: r##"# `cmp_minmax` + + The tracking issue for this feature is: [#115939] [#115939]: https://github.com/rust-lang/rust/issues/115939 @@ -4140,10 +4873,9 @@ LLVM, the Rust compiler and the linker are providing [support](https://developer.arm.com/documentation/ecm0359818/latest/) for the TrustZone-M feature. -One of the things provided, with this unstable feature, is the -`C-cmse-nonsecure-entry` ABI. This ABI marks a Secure function as an -entry function (see [section -5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details). +One of the things provided with this unstable feature is the "cmse-nonsecure-entry" ABI. +This ABI marks a Secure function as an entry function (see +[section 5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details). With this ABI, the compiler will do the following: * add a special symbol on the function which is the `__acle_se_` prefix and the standard function name @@ -4154,9 +4886,7 @@ With this ABI, the compiler will do the following: Because the stack can not be used to pass parameters, there will be compilation errors if: -* the total size of all parameters is too big (for example more than four 32 - bits integers) -* the entry function is not using a C ABI +* the total size of all parameters is too big (for example, more than four 32-bit integers) The special symbol `__acle_se_` will be used by the linker to generate a secure gateway veneer. @@ -4168,7 +4898,7 @@ gateway veneer. #![feature(cmse_nonsecure_entry)] #[no_mangle] -pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { +pub extern "cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { input + 6 } ``` @@ -4211,9 +4941,25 @@ $ arm-none-eabi-objdump -D function.o deny_since: None, }, Lint { + label: "coerce_pointee_validated", + description: r##"# `coerce_pointee_validated` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "coerce_unsized", description: r##"# `coerce_unsized` + + The tracking issue for this feature is: [#18598] [#18598]: https://github.com/rust-lang/rust/issues/18598 @@ -4225,6 +4971,22 @@ The tracking issue for this feature is: [#18598] deny_since: None, }, Lint { + label: "command_resolved_envs", + description: r##"# `command_resolved_envs` + + + +The tracking issue for this feature is: [#149070] + +[#149070]: https://github.com/rust-lang/rust/issues/149070 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "compiler_builtins", description: r##"# `compiler_builtins` @@ -4240,6 +5002,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "concat_bytes", description: r##"# `concat_bytes` + + The tracking issue for this feature is: [#87555] [#87555]: https://github.com/rust-lang/rust/issues/87555 @@ -4251,41 +5015,46 @@ The tracking issue for this feature is: [#87555] deny_since: None, }, Lint { - label: "concat_idents", - description: r##"# `concat_idents` + label: "const_alloc_error", + description: r##"# `const_alloc_error` + -The tracking issue for this feature is: [#29599] -[#29599]: https://github.com/rust-lang/rust/issues/29599 +The tracking issue for this feature is: [#92523] + +[#92523]: https://github.com/rust-lang/rust/issues/92523 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_array", + description: r##"# `const_array` -The `concat_idents` feature adds a macro for concatenating multiple identifiers -into one identifier. -## Examples -```rust -#![feature(concat_idents)] +The tracking issue for this feature is: [#147606] -fn main() { - fn foobar() -> u32 { 23 } - let f = concat_idents!(foo, bar); - assert_eq!(f(), 23); -} -``` +[#147606]: https://github.com/rust-lang/rust/issues/147606 + +------------------------ "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "const_alloc_error", - description: r##"# `const_alloc_error` + label: "const_async_blocks", + description: r##"# `const_async_blocks` -The tracking issue for this feature is: [#92523] +Allows `async {}` expressions in const contexts. -[#92523]: https://github.com/rust-lang/rust/issues/92523 +The tracking issue for this feature is: [#85368] + +[#85368]: https://github.com/rust-lang/rust/issues/85368 ------------------------ "##, @@ -4294,12 +5063,14 @@ The tracking issue for this feature is: [#92523] deny_since: None, }, Lint { - label: "const_alloc_layout", - description: r##"# `const_alloc_layout` + label: "const_block_items", + description: r##"# `const_block_items` + +Allows `const { ... }` as a shorthand for `const _: () = const { ... };` for module items. -The tracking issue for this feature is: [#67521] +The tracking issue for this feature is: [#149226] -[#67521]: https://github.com/rust-lang/rust/issues/67521 +[#149226]: https://github.com/rust-lang/rust/issues/149226 ------------------------ "##, @@ -4308,12 +5079,14 @@ The tracking issue for this feature is: [#67521] deny_since: None, }, Lint { - label: "const_array_as_mut_slice", - description: r##"# `const_array_as_mut_slice` + label: "const_bool", + description: r##"# `const_bool` -The tracking issue for this feature is: [#133333] -[#133333]: https://github.com/rust-lang/rust/issues/133333 + +The tracking issue for this feature is: [#151531] + +[#151531]: https://github.com/rust-lang/rust/issues/151531 ------------------------ "##, @@ -4322,12 +5095,12 @@ The tracking issue for this feature is: [#133333] deny_since: None, }, Lint { - label: "const_array_each_ref", - description: r##"# `const_array_each_ref` + label: "const_btree_len", + description: r##"# `const_btree_len` -The tracking issue for this feature is: [#133289] -[#133289]: https://github.com/rust-lang/rust/issues/133289 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -4336,12 +5109,14 @@ The tracking issue for this feature is: [#133289] deny_since: None, }, Lint { - label: "const_async_blocks", - description: r##"# `const_async_blocks` + label: "const_c_variadic", + description: r##"# `const_c_variadic` -The tracking issue for this feature is: [#85368] +Allows defining and calling c-variadic functions in const contexts. -[#85368]: https://github.com/rust-lang/rust/issues/85368 +The tracking issue for this feature is: [#151787] + +[#151787]: https://github.com/rust-lang/rust/issues/151787 ------------------------ "##, @@ -4350,10 +5125,14 @@ The tracking issue for this feature is: [#85368] deny_since: None, }, Lint { - label: "const_black_box", - description: r##"# `const_black_box` + label: "const_carrying_mul_add", + description: r##"# `const_carrying_mul_add` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#85532] + +[#85532]: https://github.com/rust-lang/rust/issues/85532 ------------------------ "##, @@ -4362,12 +5141,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "const_box", - description: r##"# `const_box` + label: "const_cell_traits", + description: r##"# `const_cell_traits` + -The tracking issue for this feature is: [#92521] -[#92521]: https://github.com/rust-lang/rust/issues/92521 +The tracking issue for this feature is: [#147787] + +[#147787]: https://github.com/rust-lang/rust/issues/147787 ------------------------ "##, @@ -4376,10 +5157,14 @@ The tracking issue for this feature is: [#92521] deny_since: None, }, Lint { - label: "const_btree_len", - description: r##"# `const_btree_len` + label: "const_clone", + description: r##"# `const_clone` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#142757] + +[#142757]: https://github.com/rust-lang/rust/issues/142757 ------------------------ "##, @@ -4388,12 +5173,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "const_cell", - description: r##"# `const_cell` + label: "const_closures", + description: r##"# `const_closures` + +Allows `const || {}` closures in const contexts. -The tracking issue for this feature is: [#131283] +The tracking issue for this feature is: [#106003] -[#131283]: https://github.com/rust-lang/rust/issues/131283 +[#106003]: https://github.com/rust-lang/rust/issues/106003 ------------------------ "##, @@ -4402,12 +5189,14 @@ The tracking issue for this feature is: [#131283] deny_since: None, }, Lint { - label: "const_char_classify", - description: r##"# `const_char_classify` + label: "const_cmp", + description: r##"# `const_cmp` + + -The tracking issue for this feature is: [#132241] +The tracking issue for this feature is: [#143800] -[#132241]: https://github.com/rust-lang/rust/issues/132241 +[#143800]: https://github.com/rust-lang/rust/issues/143800 ------------------------ "##, @@ -4416,12 +5205,30 @@ The tracking issue for this feature is: [#132241] deny_since: None, }, Lint { - label: "const_closures", - description: r##"# `const_closures` + label: "const_control_flow", + description: r##"# `const_control_flow` -The tracking issue for this feature is: [#106003] -[#106003]: https://github.com/rust-lang/rust/issues/106003 + +The tracking issue for this feature is: [#148739] + +[#148739]: https://github.com/rust-lang/rust/issues/148739 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_convert", + description: r##"# `const_convert` + + + +The tracking issue for this feature is: [#143773] + +[#143773]: https://github.com/rust-lang/rust/issues/143773 ------------------------ "##, @@ -4430,12 +5237,14 @@ The tracking issue for this feature is: [#106003] deny_since: None, }, Lint { - label: "const_copy_from_slice", - description: r##"# `const_copy_from_slice` + label: "const_default", + description: r##"# `const_default` + + -The tracking issue for this feature is: [#131415] +The tracking issue for this feature is: [#143894] -[#131415]: https://github.com/rust-lang/rust/issues/131415 +[#143894]: https://github.com/rust-lang/rust/issues/143894 ------------------------ "##, @@ -4447,6 +5256,8 @@ The tracking issue for this feature is: [#131415] label: "const_destruct", description: r##"# `const_destruct` +Allows using `[const] Destruct` bounds and calling drop impls in const contexts. + The tracking issue for this feature is: [#133214] [#133214]: https://github.com/rust-lang/rust/issues/133214 @@ -4458,9 +5269,41 @@ The tracking issue for this feature is: [#133214] deny_since: None, }, Lint { + label: "const_drop_guard", + description: r##"# `const_drop_guard` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_drop_in_place", + description: r##"# `const_drop_in_place` + + + +The tracking issue for this feature is: [#109342] + +[#109342]: https://github.com/rust-lang/rust/issues/109342 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "const_eval_select", description: r##"# `const_eval_select` + + The tracking issue for this feature is: [#124625] [#124625]: https://github.com/rust-lang/rust/issues/124625 @@ -4475,6 +5318,8 @@ The tracking issue for this feature is: [#124625] label: "const_for", description: r##"# `const_for` +Allows `for _ in _` loops in const contexts. + The tracking issue for this feature is: [#87575] [#87575]: https://github.com/rust-lang/rust/issues/87575 @@ -4489,6 +5334,8 @@ The tracking issue for this feature is: [#87575] label: "const_format_args", description: r##"# `const_format_args` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -4501,6 +5348,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "const_heap", description: r##"# `const_heap` + + The tracking issue for this feature is: [#79597] [#79597]: https://github.com/rust-lang/rust/issues/79597 @@ -4512,12 +5361,46 @@ The tracking issue for this feature is: [#79597] deny_since: None, }, Lint { - label: "const_is_char_boundary", - description: r##"# `const_is_char_boundary` + label: "const_index", + description: r##"# `const_index` -The tracking issue for this feature is: [#131516] -[#131516]: https://github.com/rust-lang/rust/issues/131516 + +The tracking issue for this feature is: [#143775] + +[#143775]: https://github.com/rust-lang/rust/issues/143775 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_iter", + description: r##"# `const_iter` + + + +The tracking issue for this feature is: [#92476] + +[#92476]: https://github.com/rust-lang/rust/issues/92476 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_manually_drop_take", + description: r##"# `const_manually_drop_take` + + + +The tracking issue for this feature is: [#148773] + +[#148773]: https://github.com/rust-lang/rust/issues/148773 ------------------------ "##, @@ -4526,12 +5409,92 @@ The tracking issue for this feature is: [#131516] deny_since: None, }, Lint { - label: "const_mut_cursor", - description: r##"# `const_mut_cursor` + label: "const_never_short_circuit", + description: r##"# `const_never_short_circuit` -The tracking issue for this feature is: [#130801] -[#130801]: https://github.com/rust-lang/rust/issues/130801 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_nonnull_with_exposed_provenance", + description: r##"# `const_nonnull_with_exposed_provenance` + + + +The tracking issue for this feature is: [#154215] + +[#154215]: https://github.com/rust-lang/rust/issues/154215 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_ops", + description: r##"# `const_ops` + + + +The tracking issue for this feature is: [#143802] + +[#143802]: https://github.com/rust-lang/rust/issues/143802 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_option_ops", + description: r##"# `const_option_ops` + + + +The tracking issue for this feature is: [#143956] + +[#143956]: https://github.com/rust-lang/rust/issues/143956 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_param_ty_trait", + description: r##"# `const_param_ty_trait` + + + +The tracking issue for this feature is: [#95174] + +[#95174]: https://github.com/rust-lang/rust/issues/95174 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_path_separators", + description: r##"# `const_path_separators` + + + +The tracking issue for this feature is: [#153106] + +[#153106]: https://github.com/rust-lang/rust/issues/153106 ------------------------ "##, @@ -4543,6 +5506,8 @@ The tracking issue for this feature is: [#130801] label: "const_precise_live_drops", description: r##"# `const_precise_live_drops` +Be more precise when looking for live drops in a const context. + The tracking issue for this feature is: [#73255] [#73255]: https://github.com/rust-lang/rust/issues/73255 @@ -4554,12 +5519,12 @@ The tracking issue for this feature is: [#73255] deny_since: None, }, Lint { - label: "const_ptr_sub_ptr", - description: r##"# `const_ptr_sub_ptr` + label: "const_range", + description: r##"# `const_range` -The tracking issue for this feature is: [#95892] -[#95892]: https://github.com/rust-lang/rust/issues/95892 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -4571,6 +5536,8 @@ The tracking issue for this feature is: [#95892] label: "const_range_bounds", description: r##"# `const_range_bounds` + + The tracking issue for this feature is: [#108082] [#108082]: https://github.com/rust-lang/rust/issues/108082 @@ -4585,6 +5552,8 @@ The tracking issue for this feature is: [#108082] label: "const_raw_ptr_comparison", description: r##"# `const_raw_ptr_comparison` + + The tracking issue for this feature is: [#53020] [#53020]: https://github.com/rust-lang/rust/issues/53020 @@ -4596,12 +5565,14 @@ The tracking issue for this feature is: [#53020] deny_since: None, }, Lint { - label: "const_slice_flatten", - description: r##"# `const_slice_flatten` + label: "const_ref_cell", + description: r##"# `const_ref_cell` -The tracking issue for this feature is: [#95629] -[#95629]: https://github.com/rust-lang/rust/issues/95629 + +The tracking issue for this feature is: [#137844] + +[#137844]: https://github.com/rust-lang/rust/issues/137844 ------------------------ "##, @@ -4610,12 +5581,14 @@ The tracking issue for this feature is: [#95629] deny_since: None, }, Lint { - label: "const_slice_from_mut_ptr_range", - description: r##"# `const_slice_from_mut_ptr_range` + label: "const_result_trait_fn", + description: r##"# `const_result_trait_fn` -The tracking issue for this feature is: [#89792] -[#89792]: https://github.com/rust-lang/rust/issues/89792 + +The tracking issue for this feature is: [#144211] + +[#144211]: https://github.com/rust-lang/rust/issues/144211 ------------------------ "##, @@ -4624,12 +5597,30 @@ The tracking issue for this feature is: [#89792] deny_since: None, }, Lint { - label: "const_slice_from_ptr_range", - description: r##"# `const_slice_from_ptr_range` + label: "const_result_unwrap_unchecked", + description: r##"# `const_result_unwrap_unchecked` + + + +The tracking issue for this feature is: [#148714] + +[#148714]: https://github.com/rust-lang/rust/issues/148714 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_select_unpredictable", + description: r##"# `const_select_unpredictable` -The tracking issue for this feature is: [#89792] -[#89792]: https://github.com/rust-lang/rust/issues/89792 + +The tracking issue for this feature is: [#145938] + +[#145938]: https://github.com/rust-lang/rust/issues/145938 ------------------------ "##, @@ -4638,12 +5629,14 @@ The tracking issue for this feature is: [#89792] deny_since: None, }, Lint { - label: "const_sockaddr_setters", - description: r##"# `const_sockaddr_setters` + label: "const_slice_from_mut_ptr_range", + description: r##"# `const_slice_from_mut_ptr_range` -The tracking issue for this feature is: [#131714] -[#131714]: https://github.com/rust-lang/rust/issues/131714 + +The tracking issue for this feature is: [#89792] + +[#89792]: https://github.com/rust-lang/rust/issues/89792 ------------------------ "##, @@ -4652,12 +5645,14 @@ The tracking issue for this feature is: [#131714] deny_since: None, }, Lint { - label: "const_str_from_utf8", - description: r##"# `const_str_from_utf8` + label: "const_slice_from_ptr_range", + description: r##"# `const_slice_from_ptr_range` + + -The tracking issue for this feature is: [#91006] +The tracking issue for this feature is: [#89792] -[#91006]: https://github.com/rust-lang/rust/issues/91006 +[#89792]: https://github.com/rust-lang/rust/issues/89792 ------------------------ "##, @@ -4666,12 +5661,14 @@ The tracking issue for this feature is: [#91006] deny_since: None, }, Lint { - label: "const_str_split_at", - description: r##"# `const_str_split_at` + label: "const_slice_make_iter", + description: r##"# `const_slice_make_iter` + + -The tracking issue for this feature is: [#131518] +The tracking issue for this feature is: [#137737] -[#131518]: https://github.com/rust-lang/rust/issues/131518 +[#137737]: https://github.com/rust-lang/rust/issues/137737 ------------------------ "##, @@ -4680,12 +5677,14 @@ The tracking issue for this feature is: [#131518] deny_since: None, }, Lint { - label: "const_swap", - description: r##"# `const_swap` + label: "const_split_off_first_last", + description: r##"# `const_split_off_first_last` -The tracking issue for this feature is: [#83163] -[#83163]: https://github.com/rust-lang/rust/issues/83163 + +The tracking issue for this feature is: [#138539] + +[#138539]: https://github.com/rust-lang/rust/issues/138539 ------------------------ "##, @@ -4694,12 +5693,14 @@ The tracking issue for this feature is: [#83163] deny_since: None, }, Lint { - label: "const_swap_nonoverlapping", - description: r##"# `const_swap_nonoverlapping` + label: "const_swap_with_slice", + description: r##"# `const_swap_with_slice` + + -The tracking issue for this feature is: [#133668] +The tracking issue for this feature is: [#142204] -[#133668]: https://github.com/rust-lang/rust/issues/133668 +[#142204]: https://github.com/rust-lang/rust/issues/142204 ------------------------ "##, @@ -4711,6 +5712,8 @@ The tracking issue for this feature is: [#133668] label: "const_trait_impl", description: r##"# `const_trait_impl` +Allows `impl const Trait for T` syntax. + The tracking issue for this feature is: [#143874] [#143874]: https://github.com/rust-lang/rust/issues/143874 @@ -4725,6 +5728,8 @@ The tracking issue for this feature is: [#143874] label: "const_try", description: r##"# `const_try` +Allows the `?` operator in const contexts. + The tracking issue for this feature is: [#74935] [#74935]: https://github.com/rust-lang/rust/issues/74935 @@ -4736,12 +5741,14 @@ The tracking issue for this feature is: [#74935] deny_since: None, }, Lint { - label: "const_type_id", - description: r##"# `const_type_id` + label: "const_try_residual", + description: r##"# `const_try_residual` + + -The tracking issue for this feature is: [#77125] +The tracking issue for this feature is: [#91285] -[#77125]: https://github.com/rust-lang/rust/issues/77125 +[#91285]: https://github.com/rust-lang/rust/issues/91285 ------------------------ "##, @@ -4753,6 +5760,8 @@ The tracking issue for this feature is: [#77125] label: "const_type_name", description: r##"# `const_type_name` + + The tracking issue for this feature is: [#63084] [#63084]: https://github.com/rust-lang/rust/issues/63084 @@ -4764,8 +5773,26 @@ The tracking issue for this feature is: [#63084] deny_since: None, }, Lint { - label: "const_typed_swap", - description: r##"# `const_typed_swap` + label: "const_unsigned_bigint_helpers", + description: r##"# `const_unsigned_bigint_helpers` + + + +The tracking issue for this feature is: [#152015] + +[#152015]: https://github.com/rust-lang/rust/issues/152015 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "container_error_extra", + description: r##"# `container_error_extra` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -4776,12 +5803,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "const_vec_string_slice", - description: r##"# `const_vec_string_slice` + label: "context_ext", + description: r##"# `context_ext` + + -The tracking issue for this feature is: [#129041] +The tracking issue for this feature is: [#123392] -[#129041]: https://github.com/rust-lang/rust/issues/129041 +[#123392]: https://github.com/rust-lang/rust/issues/123392 ------------------------ "##, @@ -4790,10 +5819,14 @@ The tracking issue for this feature is: [#129041] deny_since: None, }, Lint { - label: "container_error_extra", - description: r##"# `container_error_extra` + label: "contracts", + description: r##"# `contracts` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +Allows use of contracts attributes. + +The tracking issue for this feature is: [#128044] + +[#128044]: https://github.com/rust-lang/rust/issues/128044 ------------------------ "##, @@ -4802,12 +5835,30 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "context_ext", - description: r##"# `context_ext` + label: "contracts_internals", + description: r##"# `contracts_internals` -The tracking issue for this feature is: [#123392] +Allows access to internal machinery used to implement contracts. -[#123392]: https://github.com/rust-lang/rust/issues/123392 +The tracking issue for this feature is: [#128044] + +[#128044]: https://github.com/rust-lang/rust/issues/128044 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "control_flow_into_value", + description: r##"# `control_flow_into_value` + + + +The tracking issue for this feature is: [#137461] + +[#137461]: https://github.com/rust-lang/rust/issues/137461 ------------------------ "##, @@ -4819,6 +5870,8 @@ The tracking issue for this feature is: [#123392] label: "convert_float_to_int", description: r##"# `convert_float_to_int` + + The tracking issue for this feature is: [#67057] [#67057]: https://github.com/rust-lang/rust/issues/67057 @@ -4830,6 +5883,36 @@ The tracking issue for this feature is: [#67057] deny_since: None, }, Lint { + label: "copied_into_inner", + description: r##"# `copied_into_inner` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "core_float_math", + description: r##"# `core_float_math` + + + +The tracking issue for this feature is: [#137578] + +[#137578]: https://github.com/rust-lang/rust/issues/137578 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "core_intrinsics", description: r##"# `core_intrinsics` @@ -4842,9 +5925,25 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { + label: "core_intrinsics_fallbacks", + description: r##"# `core_intrinsics_fallbacks` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "core_io_borrowed_buf", description: r##"# `core_io_borrowed_buf` + + The tracking issue for this feature is: [#117693] [#117693]: https://github.com/rust-lang/rust/issues/117693 @@ -4883,6 +5982,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "coroutine_clone", description: r##"# `coroutine_clone` +Allows coroutines to be cloned. + The tracking issue for this feature is: [#95360] [#95360]: https://github.com/rust-lang/rust/issues/95360 @@ -4897,6 +5998,8 @@ The tracking issue for this feature is: [#95360] label: "coroutine_trait", description: r##"# `coroutine_trait` + + The tracking issue for this feature is: [#43122] [#43122]: https://github.com/rust-lang/rust/issues/43122 @@ -5202,6 +6305,8 @@ fn bar() { label: "cow_is_borrowed", description: r##"# `cow_is_borrowed` + + The tracking issue for this feature is: [#65143] [#65143]: https://github.com/rust-lang/rust/issues/65143 @@ -5216,9 +6321,11 @@ The tracking issue for this feature is: [#65143] label: "csky_target_feature", description: r##"# `csky_target_feature` -The tracking issue for this feature is: [#44839] +Target features on csky. + +The tracking issue for this feature is: [#150248] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#150248]: https://github.com/rust-lang/rust/issues/150248 ------------------------ "##, @@ -5230,6 +6337,8 @@ The tracking issue for this feature is: [#44839] label: "cstr_bytes", description: r##"# `cstr_bytes` + + The tracking issue for this feature is: [#112115] [#112115]: https://github.com/rust-lang/rust/issues/112115 @@ -5241,9 +6350,27 @@ The tracking issue for this feature is: [#112115] deny_since: None, }, Lint { + label: "cstr_display", + description: r##"# `cstr_display` + + + +The tracking issue for this feature is: [#139984] + +[#139984]: https://github.com/rust-lang/rust/issues/139984 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "cstr_internals", description: r##"# `cstr_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -5253,9 +6380,27 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "current_thread_id", + description: r##"# `current_thread_id` + + + +The tracking issue for this feature is: [#147194] + +[#147194]: https://github.com/rust-lang/rust/issues/147194 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "cursor_split", description: r##"# `cursor_split` + + The tracking issue for this feature is: [#86369] [#86369]: https://github.com/rust-lang/rust/issues/86369 @@ -5270,6 +6415,8 @@ The tracking issue for this feature is: [#86369] label: "custom_inner_attributes", description: r##"# `custom_inner_attributes` +Allows non-builtin attributes in inner attribute position. + The tracking issue for this feature is: [#54726] [#54726]: https://github.com/rust-lang/rust/issues/54726 @@ -5284,6 +6431,8 @@ The tracking issue for this feature is: [#54726] label: "custom_mir", description: r##"# `custom_mir` +Allows writing custom MIR + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -5332,9 +6481,27 @@ const WILL_FAIL: i32 = 4; deny_since: None, }, Lint { + label: "darwin_objc", + description: r##"# `darwin_objc` + + + +The tracking issue for this feature is: [#145496] + +[#145496]: https://github.com/rust-lang/rust/issues/145496 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "deadline_api", description: r##"# `deadline_api` + + The tracking issue for this feature is: [#46316] [#46316]: https://github.com/rust-lang/rust/issues/46316 @@ -5349,6 +6516,8 @@ The tracking issue for this feature is: [#46316] label: "debug_closure_helpers", description: r##"# `debug_closure_helpers` + + The tracking issue for this feature is: [#117729] [#117729]: https://github.com/rust-lang/rust/issues/117729 @@ -5375,6 +6544,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "decl_macro", description: r##"# `decl_macro` +Allows declarative macros 2.0 (`macro`). + The tracking issue for this feature is: [#39412] [#39412]: https://github.com/rust-lang/rust/issues/39412 @@ -5393,19 +6564,107 @@ The tracking issue for this feature is: [#132162] [#132162]: https://github.com/rust-lang/rust/issues/132162 +The RFC for this feature is: [#3681] + +[#3681]: https://github.com/rust-lang/rfcs/blob/master/text/3681-default-field-values.md + ------------------------ + +The `default_field_values` feature allows users to specify a const value for +individual fields in struct definitions, allowing those to be omitted from +initializers. + +## Examples + +```rust +#![feature(default_field_values)] + +#[derive(Default)] +struct Pet { + name: Option<String>, // impl Default for Pet will use Default::default() for name + age: i128 = 42, // impl Default for Pet will use the literal 42 for age +} + +fn main() { + let a = Pet { name: Some(String::new()), .. }; // Pet { name: Some(""), age: 42 } + let b = Pet::default(); // Pet { name: None, age: 42 } + assert_eq!(a.age, b.age); + // The following would be a compilation error: `name` needs to be specified + // let _ = Pet { .. }; +} +``` + +## `#[derive(Default)]` + +When deriving Default, the provided values are then used. On enum variants, +the variant must still be marked with `#[default]` and have all its fields +with default values. + +```rust +#![feature(default_field_values)] + +#[derive(Default)] +enum A { + #[default] + B { + x: i32 = 0, + y: i32 = 0, + }, + C, +} +``` + +## Enum variants + +This feature also supports enum variants for both specifying default values +and `#[derive(Default)]`. + +## Interaction with `#[non_exhaustive]` + +A struct or enum variant marked with `#[non_exhaustive]` is not allowed to +have default field values. + +## Lints + +When manually implementing the `Default` trait for a type that has default +field values, if any of these are overridden in the impl the +`default_overrides_default_fields` lint will trigger. This lint is in place +to avoid surprising diverging behavior between `S { .. }` and +`S::default()`, where using the same type in both ways could result in +different values. The appropriate way to write a manual `Default` +implementation is to use the functional update syntax: + +```rust +#![feature(default_field_values)] + +struct Pet { + name: String, + age: i128 = 42, // impl Default for Pet will use the literal 42 for age +} + +impl Default for Pet { + fn default() -> Pet { + Pet { + name: "no-name".to_string(), + .. + } + } +} +``` "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "deprecated_safe", - description: r##"# `deprecated_safe` + label: "deprecated_suggestion", + description: r##"# `deprecated_suggestion` -The tracking issue for this feature is: [#94978] +Allows having using `suggestion` in the `#[deprecated]` attribute. + +The tracking issue for this feature is: [#94785] -[#94978]: https://github.com/rust-lang/rust/issues/94978 +[#94785]: https://github.com/rust-lang/rust/issues/94785 ------------------------ "##, @@ -5414,12 +6673,14 @@ The tracking issue for this feature is: [#94978] deny_since: None, }, Lint { - label: "deprecated_suggestion", - description: r##"# `deprecated_suggestion` + label: "deque_extend_front", + description: r##"# `deque_extend_front` -The tracking issue for this feature is: [#94785] -[#94785]: https://github.com/rust-lang/rust/issues/94785 + +The tracking issue for this feature is: [#146975] + +[#146975]: https://github.com/rust-lang/rust/issues/146975 ------------------------ "##, @@ -5436,6 +6697,101 @@ The tracking issue for this feature is: [#87121] [#87121]: https://github.com/rust-lang/rust/issues/87121 ------------------------ + +> **Note**: This feature supersedes [`box_patterns`]. + +This feature permits pattern matching on [smart pointers in the standard library] through their +`Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which +is currently a placeholder). + +```rust +#![feature(deref_patterns)] + +let mut v = vec![Box::new(Some(0))]; + +// Implicit dereferences are inserted when a pattern can match against the +// result of repeatedly dereferencing but can't match against a smart +// pointer itself. This works alongside match ergonomics for references. +if let [Some(x)] = &mut v { + *x += 1; +} + +// Explicit `deref!(_)` patterns may instead be used when finer control is +// needed, e.g. to dereference only a single smart pointer, or to bind the +// the result of dereferencing to a variable. +if let deref!([deref!(opt_x @ Some(1))]) = &mut v { + opt_x.as_mut().map(|x| *x += 1); +} + +assert_eq!(v, [Box::new(Some(2))]); +``` + +Without this feature, it may be necessary to introduce temporaries to represent dereferenced places +when matching on nested structures: + +```rust +let mut v = vec![Box::new(Some(0))]; +if let [b] = &mut *v { + if let Some(x) = &mut **b { + *x += 1; + } +} +if let [b] = &mut *v { + if let opt_x @ Some(1) = &mut **b { + opt_x.as_mut().map(|x| *x += 1); + } +} +assert_eq!(v, [Box::new(Some(2))]); +``` + +Like [`box_patterns`], deref patterns may move out of boxes: + +```rust +# #![feature(deref_patterns)] +struct NoCopy; +let deref!(x) = Box::new(NoCopy); +drop::<NoCopy>(x); +``` + +Additionally, `deref_patterns` implements changes to string and byte string literal patterns, +allowing then to be used in deref patterns: + +```rust +# #![feature(deref_patterns)] +match ("test".to_string(), Box::from("test"), b"test".to_vec()) { + ("test", "test", b"test") => {} + _ => panic!(), +} + +// This works through multiple layers of reference and smart pointer: +match (&Box::new(&"test".to_string()), &&&"test") { + ("test", "test") => {} + _ => panic!(), +} + +// `deref!("...")` syntax may also be used: +match "test".to_string() { + deref!("test") => {} + _ => panic!(), +} + +// Matching on slices and arrays using literals is possible elsewhere as well: +match *"test" { + "test" => {} + _ => panic!(), +} +match *b"test" { + b"test" => {} + _ => panic!(), +} +match *(b"test" as &[u8]) { + b"test" => {} + _ => panic!(), +} +``` + +[`box_patterns`]: ./box-patterns.md +[smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors "##, default_severity: Severity::Allow, warn_since: None, @@ -5445,6 +6801,8 @@ The tracking issue for this feature is: [#87121] label: "deref_pure_trait", description: r##"# `deref_pure_trait` + + The tracking issue for this feature is: [#87121] [#87121]: https://github.com/rust-lang/rust/issues/87121 @@ -5456,8 +6814,8 @@ The tracking issue for this feature is: [#87121] deny_since: None, }, Lint { - label: "derive_clone_copy", - description: r##"# `derive_clone_copy` + label: "derive_clone_copy_internals", + description: r##"# `derive_clone_copy_internals` This feature is internal to the Rust compiler and is not intended for general use. @@ -5471,6 +6829,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "derive_coerce_pointee", description: r##"# `derive_coerce_pointee` + + The tracking issue for this feature is: [#123430] [#123430]: https://github.com/rust-lang/rust/issues/123430 @@ -5485,7 +6845,11 @@ The tracking issue for this feature is: [#123430] label: "derive_const", description: r##"# `derive_const` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#118304] + +[#118304]: https://github.com/rust-lang/rust/issues/118304 ------------------------ "##, @@ -5494,8 +6858,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "derive_eq", - description: r##"# `derive_eq` + label: "derive_eq_internals", + description: r##"# `derive_eq_internals` This feature is internal to the Rust compiler and is not intended for general use. @@ -5506,9 +6870,75 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { + label: "derive_from", + description: r##"# `derive_from` + +Allows deriving the From trait on single-field structs. + +The tracking issue for this feature is: [#144889] + +[#144889]: https://github.com/rust-lang/rust/issues/144889 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "derive_macro_global_path", + description: r##"# `derive_macro_global_path` + + + +The tracking issue for this feature is: [#154645] + +[#154645]: https://github.com/rust-lang/rust/issues/154645 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "diagnostic_on_const", + description: r##"# `diagnostic_on_const` + +Allows giving non-const impls custom diagnostic messages if attempted to be used as const + +The tracking issue for this feature is: [#143874] + +[#143874]: https://github.com/rust-lang/rust/issues/143874 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "diagnostic_on_move", + description: r##"# `diagnostic_on_move` + +Allows giving on-move borrowck custom diagnostic messages for a type + +The tracking issue for this feature is: [#154181] + +[#154181]: https://github.com/rust-lang/rust/issues/154181 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "dir_entry_ext2", description: r##"# `dir_entry_ext2` + + The tracking issue for this feature is: [#85573] [#85573]: https://github.com/rust-lang/rust/issues/85573 @@ -5520,10 +6950,14 @@ The tracking issue for this feature is: [#85573] deny_since: None, }, Lint { - label: "discriminant_kind", - description: r##"# `discriminant_kind` + label: "dirfd", + description: r##"# `dirfd` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#120426] + +[#120426]: https://github.com/rust-lang/rust/issues/120426 ------------------------ "##, @@ -5532,8 +6966,26 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "dispatch_from_dyn", - description: r##"# `dispatch_from_dyn` + label: "dirhandle", + description: r##"# `dirhandle` + + + +The tracking issue for this feature is: [#120426] + +[#120426]: https://github.com/rust-lang/rust/issues/120426 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "discriminant_kind", + description: r##"# `discriminant_kind` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -5544,12 +6996,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "do_not_recommend", - description: r##"# `do_not_recommend` + label: "disjoint_bitor", + description: r##"# `disjoint_bitor` + -The tracking issue for this feature is: [#51992] -[#51992]: https://github.com/rust-lang/rust/issues/51992 +The tracking issue for this feature is: [#135758] + +[#135758]: https://github.com/rust-lang/rust/issues/135758 ------------------------ "##, @@ -5558,12 +7012,12 @@ The tracking issue for this feature is: [#51992] deny_since: None, }, Lint { - label: "doc_auto_cfg", - description: r##"# `doc_auto_cfg` + label: "dispatch_from_dyn", + description: r##"# `dispatch_from_dyn` -The tracking issue for this feature is: [#43781] -[#43781]: https://github.com/rust-lang/rust/issues/43781 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -5625,20 +7079,6 @@ pub struct Icon { deny_since: None, }, Lint { - label: "doc_cfg_hide", - description: r##"# `doc_cfg_hide` - -The tracking issue for this feature is: [#43781] - -[#43781]: https://github.com/rust-lang/rust/issues/43781 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { label: "doc_masked", description: r##"# `doc_masked` @@ -5713,6 +7153,8 @@ See also its documentation in [the rustdoc book][rustdoc-book-notable_trait]. label: "downcast_unchecked", description: r##"# `downcast_unchecked` + + The tracking issue for this feature is: [#90850] [#90850]: https://github.com/rust-lang/rust/issues/90850 @@ -5727,6 +7169,8 @@ The tracking issue for this feature is: [#90850] label: "drain_keep_rest", description: r##"# `drain_keep_rest` + + The tracking issue for this feature is: [#101122] [#101122]: https://github.com/rust-lang/rust/issues/101122 @@ -5738,9 +7182,27 @@ The tracking issue for this feature is: [#101122] deny_since: None, }, Lint { + label: "drop_guard", + description: r##"# `drop_guard` + + + +The tracking issue for this feature is: [#144426] + +[#144426]: https://github.com/rust-lang/rust/issues/144426 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "dropck_eyepatch", description: r##"# `dropck_eyepatch` +Allows using the `may_dangle` attribute (RFC 1327). + The tracking issue for this feature is: [#34761] [#34761]: https://github.com/rust-lang/rust/issues/34761 @@ -5755,6 +7217,8 @@ The tracking issue for this feature is: [#34761] label: "duration_constants", description: r##"# `duration_constants` + + The tracking issue for this feature is: [#57391] [#57391]: https://github.com/rust-lang/rust/issues/57391 @@ -5782,9 +7246,27 @@ Add the methods `from_days` and `from_weeks` to `Duration`. deny_since: None, }, Lint { + label: "duration_integer_division", + description: r##"# `duration_integer_division` + + + +The tracking issue for this feature is: [#149573] + +[#149573]: https://github.com/rust-lang/rust/issues/149573 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "duration_millis_float", description: r##"# `duration_millis_float` + + The tracking issue for this feature is: [#122451] [#122451]: https://github.com/rust-lang/rust/issues/122451 @@ -5799,6 +7281,8 @@ The tracking issue for this feature is: [#122451] label: "duration_units", description: r##"# `duration_units` + + The tracking issue for this feature is: [#120301] [#120301]: https://github.com/rust-lang/rust/issues/120301 @@ -5810,12 +7294,12 @@ The tracking issue for this feature is: [#120301] deny_since: None, }, Lint { - label: "dyn_compatible_for_dispatch", - description: r##"# `dyn_compatible_for_dispatch` + label: "edition_panic", + description: r##"# `edition_panic` -The tracking issue for this feature is: [#43561] -[#43561]: https://github.com/rust-lang/rust/issues/43561 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -5824,12 +7308,14 @@ The tracking issue for this feature is: [#43561] deny_since: None, }, Lint { - label: "dyn_star", - description: r##"# `dyn_star` + label: "effective_target_features", + description: r##"# `effective_target_features` -The tracking issue for this feature is: [#102425] +Allows features to allow target_feature to better interact with traits. -[#102425]: https://github.com/rust-lang/rust/issues/102425 +The tracking issue for this feature is: [#143352] + +[#143352]: https://github.com/rust-lang/rust/issues/143352 ------------------------ "##, @@ -5838,8 +7324,10 @@ The tracking issue for this feature is: [#102425] deny_since: None, }, Lint { - label: "edition_panic", - description: r##"# `edition_panic` + label: "eii_internals", + description: r##"# `eii_internals` + +Implementation details of externally implementable items This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -5850,12 +7338,30 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "ergonomic_clones", + description: r##"# `ergonomic_clones` + +Allows the .use postfix syntax `x.use` and use closures `use |x| { ... }` + +The tracking issue for this feature is: [#132290] + +[#132290]: https://github.com/rust-lang/rust/issues/132290 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "ermsb_target_feature", description: r##"# `ermsb_target_feature` -The tracking issue for this feature is: [#44839] +ermsb target feature on x86. + +The tracking issue for this feature is: [#150249] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#150249]: https://github.com/rust-lang/rust/issues/150249 ------------------------ "##, @@ -5867,6 +7373,8 @@ The tracking issue for this feature is: [#44839] label: "error_generic_member_access", description: r##"# `error_generic_member_access` + + The tracking issue for this feature is: [#99301] [#99301]: https://github.com/rust-lang/rust/issues/99301 @@ -5881,6 +7389,8 @@ The tracking issue for this feature is: [#99301] label: "error_iter", description: r##"# `error_iter` + + The tracking issue for this feature is: [#58520] [#58520]: https://github.com/rust-lang/rust/issues/58520 @@ -5895,6 +7405,8 @@ The tracking issue for this feature is: [#58520] label: "error_reporter", description: r##"# `error_reporter` + + The tracking issue for this feature is: [#90172] [#90172]: https://github.com/rust-lang/rust/issues/90172 @@ -5909,6 +7421,8 @@ The tracking issue for this feature is: [#90172] label: "error_type_id", description: r##"# `error_type_id` + + The tracking issue for this feature is: [#60784] [#60784]: https://github.com/rust-lang/rust/issues/60784 @@ -5920,9 +7434,43 @@ The tracking issue for this feature is: [#60784] deny_since: None, }, Lint { + label: "exact_bitshifts", + description: r##"# `exact_bitshifts` + + + +The tracking issue for this feature is: [#144336] + +[#144336]: https://github.com/rust-lang/rust/issues/144336 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "exact_div", + description: r##"# `exact_div` + + + +The tracking issue for this feature is: [#139911] + +[#139911]: https://github.com/rust-lang/rust/issues/139911 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "exact_size_is_empty", description: r##"# `exact_size_is_empty` + + The tracking issue for this feature is: [#35428] [#35428]: https://github.com/rust-lang/rust/issues/35428 @@ -5937,6 +7485,8 @@ The tracking issue for this feature is: [#35428] label: "exclusive_wrapper", description: r##"# `exclusive_wrapper` + + The tracking issue for this feature is: [#98407] [#98407]: https://github.com/rust-lang/rust/issues/98407 @@ -5951,6 +7501,8 @@ The tracking issue for this feature is: [#98407] label: "exhaustive_patterns", description: r##"# `exhaustive_patterns` +Allows exhaustive pattern matching on types that contain uninhabited types. + The tracking issue for this feature is: [#51085] [#51085]: https://github.com/rust-lang/rust/issues/51085 @@ -5965,6 +7517,8 @@ The tracking issue for this feature is: [#51085] label: "exit_status_error", description: r##"# `exit_status_error` + + The tracking issue for this feature is: [#84908] [#84908]: https://github.com/rust-lang/rust/issues/84908 @@ -5979,6 +7533,8 @@ The tracking issue for this feature is: [#84908] label: "exitcode_exit_method", description: r##"# `exitcode_exit_method` + + The tracking issue for this feature is: [#97100] [#97100]: https://github.com/rust-lang/rust/issues/97100 @@ -5990,9 +7546,43 @@ The tracking issue for this feature is: [#97100] deny_since: None, }, Lint { + label: "explicit_extern_abis", + description: r##"# `explicit_extern_abis` + +The tracking issue for this feature is: [#134986] + +------ + +Disallow `extern` without an explicit ABI. We should write `extern "C"` +(or another ABI) instead of just `extern`. + +By making the ABI explicit, it becomes much clearer that "C" is just one of the +possible choices, rather than the "standard" way for external functions. +Removing the default makes it easier to add a new ABI on equal footing as "C". + +```rust,editionfuture,compile_fail +#![feature(explicit_extern_abis)] + +extern fn function1() {} // ERROR `extern` declarations without an explicit ABI + // are disallowed + +extern "C" fn function2() {} // compiles + +extern "aapcs" fn function3() {} // compiles +``` + +[#134986]: https://github.com/rust-lang/rust/issues/134986 +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "explicit_tail_calls", description: r##"# `explicit_tail_calls` +Allows explicit tail calls via `become` expression. + The tracking issue for this feature is: [#112788] [#112788]: https://github.com/rust-lang/rust/issues/112788 @@ -6004,9 +7594,27 @@ The tracking issue for this feature is: [#112788] deny_since: None, }, Lint { + label: "export_stable", + description: r##"# `export_stable` + +Allows using `#[export_stable]` which indicates that an item is exportable. + +The tracking issue for this feature is: [#139939] + +[#139939]: https://github.com/rust-lang/rust/issues/139939 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "extend_one", description: r##"# `extend_one` + + The tracking issue for this feature is: [#72631] [#72631]: https://github.com/rust-lang/rust/issues/72631 @@ -6021,6 +7629,8 @@ The tracking issue for this feature is: [#72631] label: "extend_one_unchecked", description: r##"# `extend_one_unchecked` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -6030,12 +7640,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "extern_types", - description: r##"# `extern_types` + label: "extern_item_impls", + description: r##"# `extern_item_impls` -The tracking issue for this feature is: [#43467] +Externally implementable items -[#43467]: https://github.com/rust-lang/rust/issues/43467 +The tracking issue for this feature is: [#125418] + +[#125418]: https://github.com/rust-lang/rust/issues/125418 ------------------------ "##, @@ -6044,12 +7656,14 @@ The tracking issue for this feature is: [#43467] deny_since: None, }, Lint { - label: "extract_if", - description: r##"# `extract_if` + label: "extern_types", + description: r##"# `extern_types` -The tracking issue for this feature is: [#43244] +Allows defining `extern type`s. -[#43244]: https://github.com/rust-lang/rust/issues/43244 +The tracking issue for this feature is: [#43467] + +[#43467]: https://github.com/rust-lang/rust/issues/43467 ------------------------ "##, @@ -6067,7 +7681,7 @@ The tracking issue for this feature is: [#116909] --- -Enable the `f128` type for IEEE 128-bit floating numbers (quad precision). +Enable the `f128` type for IEEE 128-bit floating numbers (quad precision). "##, default_severity: Severity::Allow, warn_since: None, @@ -6083,7 +7697,7 @@ The tracking issue for this feature is: [#116909] --- -Enable the `f16` type for IEEE 16-bit floating numbers (half precision). +Enable the `f16` type for IEEE 16-bit floating numbers (half precision). "##, default_severity: Severity::Allow, warn_since: None, @@ -6102,18 +7716,6 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { - label: "fd_read", - description: r##"# `fd_read` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { label: "ffi_const", description: r##"# `ffi_const` @@ -6236,9 +7838,41 @@ against are compatible with those of the `#[ffi_pure]`. deny_since: None, }, Lint { + label: "field_projections", + description: r##"# `field_projections` + +Experimental field projections. + +The tracking issue for this feature is: [#145383] + +[#145383]: https://github.com/rust-lang/rust/issues/145383 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "field_representing_type_raw", + description: r##"# `field_representing_type_raw` + +Implementation details of field representing types. + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "file_buffered", description: r##"# `file_buffered` + + The tracking issue for this feature is: [#130804] [#130804]: https://github.com/rust-lang/rust/issues/130804 @@ -6250,12 +7884,78 @@ The tracking issue for this feature is: [#130804] deny_since: None, }, Lint { - label: "file_lock", - description: r##"# `file_lock` + label: "final_associated_functions", + description: r##"# `final_associated_functions` + +Allows marking trait functions as `final` to prevent overriding impls + +The tracking issue for this feature is: [#131179] + +[#131179]: https://github.com/rust-lang/rust/issues/131179 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "float_algebraic", + description: r##"# `float_algebraic` -The tracking issue for this feature is: [#130994] -[#130994]: https://github.com/rust-lang/rust/issues/130994 + +The tracking issue for this feature is: [#136469] + +[#136469]: https://github.com/rust-lang/rust/issues/136469 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "float_bits_const", + description: r##"# `float_bits_const` + + + +The tracking issue for this feature is: [#151073] + +[#151073]: https://github.com/rust-lang/rust/issues/151073 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "float_erf", + description: r##"# `float_erf` + + + +The tracking issue for this feature is: [#136321] + +[#136321]: https://github.com/rust-lang/rust/issues/136321 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "float_exact_integer_constants", + description: r##"# `float_exact_integer_constants` + + + +The tracking issue for this feature is: [#152466] + +[#152466]: https://github.com/rust-lang/rust/issues/152466 ------------------------ "##, @@ -6267,6 +7967,8 @@ The tracking issue for this feature is: [#130994] label: "float_gamma", description: r##"# `float_gamma` + + The tracking issue for this feature is: [#99842] [#99842]: https://github.com/rust-lang/rust/issues/99842 @@ -6281,6 +7983,8 @@ The tracking issue for this feature is: [#99842] label: "float_minimum_maximum", description: r##"# `float_minimum_maximum` + + The tracking issue for this feature is: [#91079] [#91079]: https://github.com/rust-lang/rust/issues/91079 @@ -6292,12 +7996,10 @@ The tracking issue for this feature is: [#91079] deny_since: None, }, Lint { - label: "float_next_up_down", - description: r##"# `float_next_up_down` - -The tracking issue for this feature is: [#91399] + label: "flt2dec", + description: r##"# `flt2dec` -[#91399]: https://github.com/rust-lang/rust/issues/91399 +This feature is internal to the Rust compiler and is not intended for general use. ------------------------ "##, @@ -6306,10 +8008,14 @@ The tracking issue for this feature is: [#91399] deny_since: None, }, Lint { - label: "flt2dec", - description: r##"# `flt2dec` + label: "fmt_arguments_from_str", + description: r##"# `fmt_arguments_from_str` -This feature is internal to the Rust compiler and is not intended for general use. + + +The tracking issue for this feature is: [#148905] + +[#148905]: https://github.com/rust-lang/rust/issues/148905 ------------------------ "##, @@ -6321,6 +8027,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "fmt_debug", description: r##"# `fmt_debug` +Controlling the behavior of fmt::Debug + The tracking issue for this feature is: [#129709] [#129709]: https://github.com/rust-lang/rust/issues/129709 @@ -6335,6 +8043,8 @@ The tracking issue for this feature is: [#129709] label: "fmt_helpers_for_derive", description: r##"# `fmt_helpers_for_derive` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -6359,6 +8069,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "fn_align", description: r##"# `fn_align` +Allows using `#[align(...)]` on function items + The tracking issue for this feature is: [#82232] [#82232]: https://github.com/rust-lang/rust/issues/82232 @@ -6373,6 +8085,8 @@ The tracking issue for this feature is: [#82232] label: "fn_delegation", description: r##"# `fn_delegation` +Support delegating implementation of functions to other already implemented functions. + The tracking issue for this feature is: [#118212] [#118212]: https://github.com/rust-lang/rust/issues/118212 @@ -6387,6 +8101,8 @@ The tracking issue for this feature is: [#118212] label: "fn_ptr_trait", description: r##"# `fn_ptr_trait` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -6441,6 +8157,8 @@ fn main() { label: "forget_unsized", description: r##"# `forget_unsized` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -6453,6 +8171,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "format_args_nl", description: r##"# `format_args_nl` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -6465,6 +8185,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "formatting_options", description: r##"# `formatting_options` + + The tracking issue for this feature is: [#118117] [#118117]: https://github.com/rust-lang/rust/issues/118117 @@ -6479,6 +8201,8 @@ The tracking issue for this feature is: [#118117] label: "freeze", description: r##"# `freeze` + + The tracking issue for this feature is: [#121675] [#121675]: https://github.com/rust-lang/rust/issues/121675 @@ -6493,6 +8217,8 @@ The tracking issue for this feature is: [#121675] label: "freeze_impls", description: r##"# `freeze_impls` +Allows impls for the Freeze trait. + The tracking issue for this feature is: [#121675] [#121675]: https://github.com/rust-lang/rust/issues/121675 @@ -6504,9 +8230,59 @@ The tracking issue for this feature is: [#121675] deny_since: None, }, Lint { + label: "frontmatter", + description: r##"# `frontmatter` + +The tracking issue for this feature is: [#136889] + +------ + +The `frontmatter` feature allows an extra metadata block at the top of files for consumption by +external tools. For example, it can be used by [`cargo-script`] files to specify dependencies. + +```rust +#!/usr/bin/env -S cargo -Zscript +--- +[dependencies] +libc = "0.2.172" +--- +#![feature(frontmatter)] +# mod libc { pub type c_int = i32; } + +fn main() { + let x: libc::c_int = 1i32; +} +``` + +[#136889]: https://github.com/rust-lang/rust/issues/136889 +[`cargo-script`]: https://rust-lang.github.io/rfcs/3502-cargo-script.html +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "fs_set_times", + description: r##"# `fs_set_times` + + + +The tracking issue for this feature is: [#147455] + +[#147455]: https://github.com/rust-lang/rust/issues/147455 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "fundamental", description: r##"# `fundamental` +Allows using the `#[fundamental]` attribute. + The tracking issue for this feature is: [#29635] [#29635]: https://github.com/rust-lang/rust/issues/29635 @@ -6518,9 +8294,27 @@ The tracking issue for this feature is: [#29635] deny_since: None, }, Lint { + label: "funnel_shifts", + description: r##"# `funnel_shifts` + + + +The tracking issue for this feature is: [#145686] + +[#145686]: https://github.com/rust-lang/rust/issues/145686 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "future_join", description: r##"# `future_join` + + The tracking issue for this feature is: [#91642] [#91642]: https://github.com/rust-lang/rust/issues/91642 @@ -6535,6 +8329,8 @@ The tracking issue for this feature is: [#91642] label: "gen_blocks", description: r##"# `gen_blocks` +Allows defining gen blocks and `gen fn`. + The tracking issue for this feature is: [#117078] [#117078]: https://github.com/rust-lang/rust/issues/117078 @@ -6549,9 +8345,9 @@ The tracking issue for this feature is: [#117078] label: "gen_future", description: r##"# `gen_future` -The tracking issue for this feature is: [#50547] -[#50547]: https://github.com/rust-lang/rust/issues/50547 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -6560,12 +8356,12 @@ The tracking issue for this feature is: [#50547] deny_since: None, }, Lint { - label: "generic_arg_infer", - description: r##"# `generic_arg_infer` + label: "generic_assert", + description: r##"# `generic_assert` -The tracking issue for this feature is: [#85077] +Outputs useful `assert!` messages -[#85077]: https://github.com/rust-lang/rust/issues/85077 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -6574,10 +8370,14 @@ The tracking issue for this feature is: [#85077] deny_since: None, }, Lint { - label: "generic_assert", - description: r##"# `generic_assert` + label: "generic_assert_internals", + description: r##"# `generic_assert_internals` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#44838] + +[#44838]: https://github.com/rust-lang/rust/issues/44838 ------------------------ "##, @@ -6586,12 +8386,30 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "generic_assert_internals", - description: r##"# `generic_assert_internals` + label: "generic_atomic", + description: r##"# `generic_atomic` -The tracking issue for this feature is: [#44838] -[#44838]: https://github.com/rust-lang/rust/issues/44838 + +The tracking issue for this feature is: [#130539] + +[#130539]: https://github.com/rust-lang/rust/issues/130539 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "generic_const_args", + description: r##"# `generic_const_args` + +Allows using generics in more complex const expressions, based on definitional equality. + +The tracking issue for this feature is: [#151972] + +[#151972]: https://github.com/rust-lang/rust/issues/151972 ------------------------ "##, @@ -6603,6 +8421,8 @@ The tracking issue for this feature is: [#44838] label: "generic_const_exprs", description: r##"# `generic_const_exprs` +Allows non-trivial generic constants which have to have wfness manually propagated to callers + The tracking issue for this feature is: [#76560] [#76560]: https://github.com/rust-lang/rust/issues/76560 @@ -6617,6 +8437,8 @@ The tracking issue for this feature is: [#76560] label: "generic_const_items", description: r##"# `generic_const_items` +Allows generic parameters and where-clauses on free & associated const items. + The tracking issue for this feature is: [#113521] [#113521]: https://github.com/rust-lang/rust/issues/113521 @@ -6628,12 +8450,30 @@ The tracking issue for this feature is: [#113521] deny_since: None, }, Lint { - label: "get_many_mut", - description: r##"# `get_many_mut` + label: "generic_const_parameter_types", + description: r##"# `generic_const_parameter_types` + +Allows the type of const generics to depend on generic parameters + +The tracking issue for this feature is: [#137626] + +[#137626]: https://github.com/rust-lang/rust/issues/137626 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "generic_pattern_types", + description: r##"# `generic_pattern_types` -The tracking issue for this feature is: [#104642] +Allows any generic constants being used as pattern type range ends -[#104642]: https://github.com/rust-lang/rust/issues/104642 +The tracking issue for this feature is: [#136574] + +[#136574]: https://github.com/rust-lang/rust/issues/136574 ------------------------ "##, @@ -6642,8 +8482,10 @@ The tracking issue for this feature is: [#104642] deny_since: None, }, Lint { - label: "get_many_mut_helpers", - description: r##"# `get_many_mut_helpers` + label: "get_disjoint_mut_helpers", + description: r##"# `get_disjoint_mut_helpers` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -6657,6 +8499,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "get_mut_unchecked", description: r##"# `get_mut_unchecked` + + The tracking issue for this feature is: [#63292] [#63292]: https://github.com/rust-lang/rust/issues/63292 @@ -6668,9 +8512,27 @@ The tracking issue for this feature is: [#63292] deny_since: None, }, Lint { + label: "gethostname", + description: r##"# `gethostname` + + + +The tracking issue for this feature is: [#135142] + +[#135142]: https://github.com/rust-lang/rust/issues/135142 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "global_registration", description: r##"# `global_registration` +Allows registering static items globally, possibly across crates, to iterate over at runtime. + The tracking issue for this feature is: [#125119] [#125119]: https://github.com/rust-lang/rust/issues/125119 @@ -6682,9 +8544,25 @@ The tracking issue for this feature is: [#125119] deny_since: None, }, Lint { + label: "gpu_intrinsics", + description: r##"# `gpu_intrinsics` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "guard_patterns", description: r##"# `guard_patterns` +Allows using guards in patterns. + The tracking issue for this feature is: [#129967] [#129967]: https://github.com/rust-lang/rust/issues/129967 @@ -6732,12 +8610,12 @@ fn main() { deny_since: None, }, Lint { - label: "hash_extract_if", - description: r##"# `hash_extract_if` + label: "hash_map_internals", + description: r##"# `hash_map_internals` + -The tracking issue for this feature is: [#59618] -[#59618]: https://github.com/rust-lang/rust/issues/59618 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -6746,12 +8624,14 @@ The tracking issue for this feature is: [#59618] deny_since: None, }, Lint { - label: "hash_raw_entry", - description: r##"# `hash_raw_entry` + label: "hash_map_macro", + description: r##"# `hash_map_macro` + -The tracking issue for this feature is: [#56167] -[#56167]: https://github.com/rust-lang/rust/issues/56167 +The tracking issue for this feature is: [#144032] + +[#144032]: https://github.com/rust-lang/rust/issues/144032 ------------------------ "##, @@ -6763,6 +8643,8 @@ The tracking issue for this feature is: [#56167] label: "hash_set_entry", description: r##"# `hash_set_entry` + + The tracking issue for this feature is: [#60896] [#60896]: https://github.com/rust-lang/rust/issues/60896 @@ -6777,6 +8659,8 @@ The tracking issue for this feature is: [#60896] label: "hasher_prefixfree_extras", description: r##"# `hasher_prefixfree_extras` + + The tracking issue for this feature is: [#96762] [#96762]: https://github.com/rust-lang/rust/issues/96762 @@ -6791,6 +8675,8 @@ The tracking issue for this feature is: [#96762] label: "hashmap_internals", description: r##"# `hashmap_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -6803,9 +8689,11 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "hexagon_target_feature", description: r##"# `hexagon_target_feature` -The tracking issue for this feature is: [#44839] +Target features on hexagon. + +The tracking issue for this feature is: [#150250] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#150250]: https://github.com/rust-lang/rust/issues/150250 ------------------------ "##, @@ -6817,6 +8705,8 @@ The tracking issue for this feature is: [#44839] label: "hint_must_use", description: r##"# `hint_must_use` + + The tracking issue for this feature is: [#94745] [#94745]: https://github.com/rust-lang/rust/issues/94745 @@ -6828,12 +8718,30 @@ The tracking issue for this feature is: [#94745] deny_since: None, }, Lint { - label: "if_let_guard", - description: r##"# `if_let_guard` + label: "hint_prefetch", + description: r##"# `hint_prefetch` + + + +The tracking issue for this feature is: [#146941] + +[#146941]: https://github.com/rust-lang/rust/issues/146941 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "impl_restriction", + description: r##"# `impl_restriction` -The tracking issue for this feature is: [#51114] +Allows `impl(crate) trait Foo` restrictions. -[#51114]: https://github.com/rust-lang/rust/issues/51114 +The tracking issue for this feature is: [#105077] + +[#105077]: https://github.com/rust-lang/rust/issues/105077 ------------------------ "##, @@ -6845,6 +8753,8 @@ The tracking issue for this feature is: [#51114] label: "impl_trait_in_assoc_type", description: r##"# `impl_trait_in_assoc_type` +Allows `impl Trait` to be used inside associated types (RFC 2515). + The tracking issue for this feature is: [#63063] [#63063]: https://github.com/rust-lang/rust/issues/63063 @@ -6856,9 +8766,27 @@ The tracking issue for this feature is: [#63063] deny_since: None, }, Lint { + label: "impl_trait_in_bindings", + description: r##"# `impl_trait_in_bindings` + +Allows `impl Trait` in bindings (`let`). + +The tracking issue for this feature is: [#63065] + +[#63065]: https://github.com/rust-lang/rust/issues/63065 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "impl_trait_in_fn_trait_return", description: r##"# `impl_trait_in_fn_trait_return` +Allows `impl Trait` as output type in `Fn` traits in return position of functions. + The tracking issue for this feature is: [#99697] [#99697]: https://github.com/rust-lang/rust/issues/99697 @@ -6870,9 +8798,40 @@ The tracking issue for this feature is: [#99697] deny_since: None, }, Lint { + label: "import_trait_associated_functions", + description: r##"# import_trait_associated_functions + +The tracking issue for this feature is: [#134691] + +[#134691]: https://github.com/rust-lang/rust/issues/134691 + +------------------------ + +This feature allows importing associated functions and constants from traits and then using them like regular items. + +```rust +#![feature(import_trait_associated_functions)] + +use std::ops::Add::add; + +fn main() { + let numbers = vec![1, 2, 3, 4, 5, 6]; + let sum = numbers.into_iter().reduce(add); // instead of `.reduce(Add:add)` + + assert_eq!(sum, Some(21)); +} +``` +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "inherent_associated_types", description: r##"# `inherent_associated_types` +Allows associated types in inherent impls. + The tracking issue for this feature is: [#8995] [#8995]: https://github.com/rust-lang/rust/issues/8995 @@ -6884,39 +8843,60 @@ The tracking issue for this feature is: [#8995] deny_since: None, }, Lint { - label: "inline_const_pat", - description: r##"# `inline_const_pat` + label: "inplace_iteration", + description: r##"# `inplace_iteration` -The tracking issue for this feature is: [#76001] ------- -This feature allows you to use inline constant expressions in pattern position: +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. -```rust -#![feature(inline_const_pat)] +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "int_format_into", + description: r##"# `int_format_into` -const fn one() -> i32 { 1 } -let some_int = 3; -match some_int { - const { 1 + 2 } => println!("Matched 1 + 2"), - const { one() } => println!("Matched const fn returning 1"), - _ => println!("Didn't match anything :("), -} -``` -[#76001]: https://github.com/rust-lang/rust/issues/76001 +The tracking issue for this feature is: [#138215] + +[#138215]: https://github.com/rust-lang/rust/issues/138215 + +------------------------ "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "inplace_iteration", - description: r##"# `inplace_iteration` + label: "int_from_ascii", + description: r##"# `int_from_ascii` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#134821] + +[#134821]: https://github.com/rust-lang/rust/issues/134821 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "int_lowest_highest_one", + description: r##"# `int_lowest_highest_one` + + + +The tracking issue for this feature is: [#145203] + +[#145203]: https://github.com/rust-lang/rust/issues/145203 ------------------------ "##, @@ -6928,6 +8908,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "int_roundings", description: r##"# `int_roundings` + + The tracking issue for this feature is: [#88581] [#88581]: https://github.com/rust-lang/rust/issues/88581 @@ -6942,6 +8924,8 @@ The tracking issue for this feature is: [#88581] label: "integer_atomics", description: r##"# `integer_atomics` + + The tracking issue for this feature is: [#99069] [#99069]: https://github.com/rust-lang/rust/issues/99069 @@ -6953,24 +8937,14 @@ The tracking issue for this feature is: [#99069] deny_since: None, }, Lint { - label: "integer_sign_cast", - description: r##"# `integer_sign_cast` + label: "integer_extend_truncate", + description: r##"# `integer_extend_truncate` -The tracking issue for this feature is: [#125882] -[#125882]: https://github.com/rust-lang/rust/issues/125882 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "internal_impls_macro", - description: r##"# `internal_impls_macro` +The tracking issue for this feature is: [#154330] -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +[#154330]: https://github.com/rust-lang/rust/issues/154330 ------------------------ "##, @@ -7068,9 +9042,9 @@ with any regular function. Various intrinsics have native MIR operations that they correspond to. Instead of requiring backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass will convert the calls to the MIR operation. Backends do not need to know about these intrinsics -at all. These intrinsics only make sense without a body, and can either be declared as a "rust-intrinsic" -or as a `#[rustc_intrinsic]`. The body is never used, as calls to the intrinsic do not exist -anymore after MIR analyses. +at all. These intrinsics only make sense without a body, and can be declared as a `#[rustc_intrinsic]`. +The body is never used as the lowering pass implements support for all backends, so we never have to +use the fallback logic. ## Intrinsics without fallback logic @@ -7078,33 +9052,14 @@ These must be implemented by all backends. ### `#[rustc_intrinsic]` declarations -These are written like intrinsics with fallback bodies, but the body is irrelevant. -Use `loop {}` for the body or call the intrinsic recursively and add -`#[rustc_intrinsic_must_be_overridden]` to the function to ensure that backends don't -invoke the body. - -### Legacy extern ABI based intrinsics - -These are imported as if they were FFI functions, with the special -`rust-intrinsic` ABI. For example, if one was in a freestanding -context, but wished to be able to `transmute` between types, and -perform efficient pointer arithmetic, one would import those functions -via a declaration like - +These are written without a body: ```rust #![feature(intrinsics)] #![allow(internal_features)] -# fn main() {} -extern "rust-intrinsic" { - fn transmute<T, U>(x: T) -> U; - - fn arith_offset<T>(dst: *const T, offset: isize) -> *const T; -} +#[rustc_intrinsic] +pub fn abort() -> !; ``` - -As with any other FFI functions, these are by default always `unsafe` to call. -You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call. "##, default_severity: Severity::Allow, warn_since: None, @@ -7114,6 +9069,8 @@ You can add `#[rustc_safe_intrinsic]` to the intrinsic to make it safe to call. label: "io_const_error", description: r##"# `io_const_error` + + The tracking issue for this feature is: [#133448] [#133448]: https://github.com/rust-lang/rust/issues/133448 @@ -7128,6 +9085,8 @@ The tracking issue for this feature is: [#133448] label: "io_const_error_internals", description: r##"# `io_const_error_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -7140,6 +9099,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "io_error_inprogress", description: r##"# `io_error_inprogress` + + The tracking issue for this feature is: [#130840] [#130840]: https://github.com/rust-lang/rust/issues/130840 @@ -7154,6 +9115,8 @@ The tracking issue for this feature is: [#130840] label: "io_error_more", description: r##"# `io_error_more` + + The tracking issue for this feature is: [#86442] [#86442]: https://github.com/rust-lang/rust/issues/86442 @@ -7168,6 +9131,8 @@ The tracking issue for this feature is: [#86442] label: "io_error_uncategorized", description: r##"# `io_error_uncategorized` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -7180,6 +9145,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "io_slice_as_bytes", description: r##"# `io_slice_as_bytes` + + The tracking issue for this feature is: [#132818] [#132818]: https://github.com/rust-lang/rust/issues/132818 @@ -7194,6 +9161,8 @@ The tracking issue for this feature is: [#132818] label: "ip", description: r##"# `ip` + + The tracking issue for this feature is: [#27709] [#27709]: https://github.com/rust-lang/rust/issues/27709 @@ -7205,12 +9174,28 @@ The tracking issue for this feature is: [#27709] deny_since: None, }, Lint { - label: "ip_from", - description: r##"# `ip_from` + label: "ip_as_octets", + description: r##"# `ip_as_octets` + + + +The tracking issue for this feature is: [#137259] + +[#137259]: https://github.com/rust-lang/rust/issues/137259 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ip_multicast_reserved", + description: r##"# `ip_multicast_reserved` -The tracking issue for this feature is: [#131360] -[#131360]: https://github.com/rust-lang/rust/issues/131360 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -7222,6 +9207,8 @@ The tracking issue for this feature is: [#131360] label: "is_ascii_octdigit", description: r##"# `is_ascii_octdigit` + + The tracking issue for this feature is: [#101288] [#101288]: https://github.com/rust-lang/rust/issues/101288 @@ -7236,6 +9223,8 @@ The tracking issue for this feature is: [#101288] label: "is_loongarch_feature_detected", description: r##"# `is_loongarch_feature_detected` + + The tracking issue for this feature is: [#117425] [#117425]: https://github.com/rust-lang/rust/issues/117425 @@ -7250,6 +9239,8 @@ The tracking issue for this feature is: [#117425] label: "is_riscv_feature_detected", description: r##"# `is_riscv_feature_detected` + + The tracking issue for this feature is: [#111192] [#111192]: https://github.com/rust-lang/rust/issues/111192 @@ -7261,12 +9252,14 @@ The tracking issue for this feature is: [#111192] deny_since: None, }, Lint { - label: "iter_advance_by", - description: r##"# `iter_advance_by` + label: "isolate_most_least_significant_one", + description: r##"# `isolate_most_least_significant_one` -The tracking issue for this feature is: [#77404] -[#77404]: https://github.com/rust-lang/rust/issues/77404 + +The tracking issue for this feature is: [#136909] + +[#136909]: https://github.com/rust-lang/rust/issues/136909 ------------------------ "##, @@ -7275,12 +9268,14 @@ The tracking issue for this feature is: [#77404] deny_since: None, }, Lint { - label: "iter_array_chunks", - description: r##"# `iter_array_chunks` + label: "iter_advance_by", + description: r##"# `iter_advance_by` -The tracking issue for this feature is: [#100450] -[#100450]: https://github.com/rust-lang/rust/issues/100450 + +The tracking issue for this feature is: [#77404] + +[#77404]: https://github.com/rust-lang/rust/issues/77404 ------------------------ "##, @@ -7289,12 +9284,14 @@ The tracking issue for this feature is: [#100450] deny_since: None, }, Lint { - label: "iter_chain", - description: r##"# `iter_chain` + label: "iter_array_chunks", + description: r##"# `iter_array_chunks` -The tracking issue for this feature is: [#125964] -[#125964]: https://github.com/rust-lang/rust/issues/125964 + +The tracking issue for this feature is: [#100450] + +[#100450]: https://github.com/rust-lang/rust/issues/100450 ------------------------ "##, @@ -7306,6 +9303,8 @@ The tracking issue for this feature is: [#125964] label: "iter_collect_into", description: r##"# `iter_collect_into` + + The tracking issue for this feature is: [#94780] [#94780]: https://github.com/rust-lang/rust/issues/94780 @@ -7320,6 +9319,8 @@ The tracking issue for this feature is: [#94780] label: "iter_from_coroutine", description: r##"# `iter_from_coroutine` + + The tracking issue for this feature is: [#43122] [#43122]: https://github.com/rust-lang/rust/issues/43122 @@ -7334,6 +9335,8 @@ The tracking issue for this feature is: [#43122] label: "iter_intersperse", description: r##"# `iter_intersperse` + + The tracking issue for this feature is: [#79524] [#79524]: https://github.com/rust-lang/rust/issues/79524 @@ -7348,6 +9351,8 @@ The tracking issue for this feature is: [#79524] label: "iter_is_partitioned", description: r##"# `iter_is_partitioned` + + The tracking issue for this feature is: [#62544] [#62544]: https://github.com/rust-lang/rust/issues/62544 @@ -7359,9 +9364,27 @@ The tracking issue for this feature is: [#62544] deny_since: None, }, Lint { + label: "iter_macro", + description: r##"# `iter_macro` + + + +The tracking issue for this feature is: [#142269] + +[#142269]: https://github.com/rust-lang/rust/issues/142269 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "iter_map_windows", description: r##"# `iter_map_windows` + + The tracking issue for this feature is: [#87155] [#87155]: https://github.com/rust-lang/rust/issues/87155 @@ -7376,6 +9399,8 @@ The tracking issue for this feature is: [#87155] label: "iter_next_chunk", description: r##"# `iter_next_chunk` + + The tracking issue for this feature is: [#98326] [#98326]: https://github.com/rust-lang/rust/issues/98326 @@ -7390,6 +9415,8 @@ The tracking issue for this feature is: [#98326] label: "iter_order_by", description: r##"# `iter_order_by` + + The tracking issue for this feature is: [#64295] [#64295]: https://github.com/rust-lang/rust/issues/64295 @@ -7404,6 +9431,8 @@ The tracking issue for this feature is: [#64295] label: "iter_partition_in_place", description: r##"# `iter_partition_in_place` + + The tracking issue for this feature is: [#62543] [#62543]: https://github.com/rust-lang/rust/issues/62543 @@ -7418,6 +9447,8 @@ The tracking issue for this feature is: [#62543] label: "iterator_try_collect", description: r##"# `iterator_try_collect` + + The tracking issue for this feature is: [#94047] [#94047]: https://github.com/rust-lang/rust/issues/94047 @@ -7432,6 +9463,8 @@ The tracking issue for this feature is: [#94047] label: "iterator_try_reduce", description: r##"# `iterator_try_reduce` + + The tracking issue for this feature is: [#87053] [#87053]: https://github.com/rust-lang/rust/issues/87053 @@ -7446,6 +9479,8 @@ The tracking issue for this feature is: [#87053] label: "junction_point", description: r##"# `junction_point` + + The tracking issue for this feature is: [#121709] [#121709]: https://github.com/rust-lang/rust/issues/121709 @@ -7460,9 +9495,11 @@ The tracking issue for this feature is: [#121709] label: "lahfsahf_target_feature", description: r##"# `lahfsahf_target_feature` -The tracking issue for this feature is: [#44839] +lahfsahf target feature on x86. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150251] + +[#150251]: https://github.com/rust-lang/rust/issues/150251 ------------------------ "##, @@ -7520,14 +9557,15 @@ allocation. A freestanding program that uses the `Box` sugar for dynamic allocations via `malloc` and `free`: ```rust,ignore (libc-is-finicky) -#![feature(lang_items, start, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)] +#![feature(lang_items, core_intrinsics, rustc_private, panic_unwind, rustc_attrs)] #![allow(internal_features)] #![no_std] +#![no_main] extern crate libc; extern crate unwind; -use core::ffi::c_void; +use core::ffi::{c_int, c_void}; use core::intrinsics; use core::panic::PanicInfo; use core::ptr::NonNull; @@ -7565,8 +9603,8 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { p } -#[start] -fn main(_argc: isize, _argv: *const *const u8) -> isize { +#[no_mangle] +extern "C" fn main(_argc: c_int, _argv: *const *const u8) -> c_int { let _x = Box::new(1); 0 @@ -7596,6 +9634,8 @@ An up-to-date list of all language items can be found [here] in the compiler cod label: "large_assignments", description: r##"# `large_assignments` +Allows setting the threshold for the `large_assignments` lint. + The tracking issue for this feature is: [#83518] [#83518]: https://github.com/rust-lang/rust/issues/83518 @@ -7610,6 +9650,8 @@ The tracking issue for this feature is: [#83518] label: "layout_for_ptr", description: r##"# `layout_for_ptr` + + The tracking issue for this feature is: [#69835] [#69835]: https://github.com/rust-lang/rust/issues/69835 @@ -7624,23 +9666,11 @@ The tracking issue for this feature is: [#69835] label: "lazy_cell_into_inner", description: r##"# `lazy_cell_into_inner` -The tracking issue for this feature is: [#125623] - -[#125623]: https://github.com/rust-lang/rust/issues/125623 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "lazy_get", - description: r##"# `lazy_get` -The tracking issue for this feature is: [#129333] +The tracking issue for this feature is: [#125623] -[#129333]: https://github.com/rust-lang/rust/issues/129333 +[#125623]: https://github.com/rust-lang/rust/issues/125623 ------------------------ "##, @@ -7652,6 +9682,8 @@ The tracking issue for this feature is: [#129333] label: "lazy_type_alias", description: r##"# `lazy_type_alias` +Allow to have type alias types for inter-crate use. + The tracking issue for this feature is: [#112792] [#112792]: https://github.com/rust-lang/rust/issues/112792 @@ -7666,21 +9698,9 @@ The tracking issue for this feature is: [#112792] label: "legacy_receiver_trait", description: r##"# `legacy_receiver_trait` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "let_chains", - description: r##"# `let_chains` - -The tracking issue for this feature is: [#53667] -[#53667]: https://github.com/rust-lang/rust/issues/53667 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -7692,6 +9712,8 @@ The tracking issue for this feature is: [#53667] label: "liballoc_internals", description: r##"# `liballoc_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -7713,10 +9735,14 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { - label: "lifetime_capture_rules_2024", - description: r##"# `lifetime_capture_rules_2024` + label: "likely_unlikely", + description: r##"# `likely_unlikely` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#151619] + +[#151619]: https://github.com/rust-lang/rust/issues/151619 ------------------------ "##, @@ -7768,6 +9794,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "link_llvm_intrinsics", description: r##"# `link_llvm_intrinsics` +Allows using `#[link_name="llvm.*"]`. + The tracking issue for this feature is: [#29602] [#29602]: https://github.com/rust-lang/rust/issues/29602 @@ -7782,6 +9810,8 @@ The tracking issue for this feature is: [#29602] label: "linkage", description: r##"# `linkage` +Allows using the `#[linkage = ".."]` attribute. + The tracking issue for this feature is: [#29603] [#29603]: https://github.com/rust-lang/rust/issues/29603 @@ -7796,6 +9826,8 @@ The tracking issue for this feature is: [#29603] label: "linked_list_cursors", description: r##"# `linked_list_cursors` + + The tracking issue for this feature is: [#58533] [#58533]: https://github.com/rust-lang/rust/issues/58533 @@ -7810,6 +9842,8 @@ The tracking issue for this feature is: [#58533] label: "linked_list_remove", description: r##"# `linked_list_remove` + + The tracking issue for this feature is: [#69210] [#69210]: https://github.com/rust-lang/rust/issues/69210 @@ -7824,6 +9858,8 @@ The tracking issue for this feature is: [#69210] label: "linked_list_retain", description: r##"# `linked_list_retain` + + The tracking issue for this feature is: [#114135] [#114135]: https://github.com/rust-lang/rust/issues/114135 @@ -7838,6 +9874,8 @@ The tracking issue for this feature is: [#114135] label: "linux_pidfd", description: r##"# `linux_pidfd` + + The tracking issue for this feature is: [#82971] [#82971]: https://github.com/rust-lang/rust/issues/82971 @@ -7849,9 +9887,27 @@ The tracking issue for this feature is: [#82971] deny_since: None, }, Lint { + label: "local_key_cell_update", + description: r##"# `local_key_cell_update` + + + +The tracking issue for this feature is: [#143989] + +[#143989]: https://github.com/rust-lang/rust/issues/143989 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "local_waker", description: r##"# `local_waker` + + The tracking issue for this feature is: [#118959] [#118959]: https://github.com/rust-lang/rust/issues/118959 @@ -7863,9 +9919,27 @@ The tracking issue for this feature is: [#118959] deny_since: None, }, Lint { + label: "lock_value_accessors", + description: r##"# `lock_value_accessors` + + + +The tracking issue for this feature is: [#133407] + +[#133407]: https://github.com/rust-lang/rust/issues/133407 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "log_syntax", description: r##"# `log_syntax` + + The tracking issue for this feature is: [#29598] [#29598]: https://github.com/rust-lang/rust/issues/29598 @@ -7880,9 +9954,11 @@ The tracking issue for this feature is: [#29598] label: "loongarch_target_feature", description: r##"# `loongarch_target_feature` -The tracking issue for this feature is: [#44839] +Target features on loongarch. + +The tracking issue for this feature is: [#150252] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#150252]: https://github.com/rust-lang/rust/issues/150252 ------------------------ "##, @@ -7891,12 +9967,73 @@ The tracking issue for this feature is: [#44839] deny_since: None, }, Lint { - label: "macro_metavar_expr", - description: r##"# `macro_metavar_expr` + label: "loop_match", + description: r##"# `loop_match` -The tracking issue for this feature is: [#83527] +The tracking issue for this feature is: [#132306] -[#83527]: https://github.com/rust-lang/rust/issues/83527 +[#132306]: https://github.com/rust-lang/rust/issues/132306 + +------ + +The `#[loop_match]` and `#[const_continue]` attributes can be used to improve the code +generation of logic that fits this shape: + +```ignore (pseudo-rust) +loop { + state = 'blk: { + match state { + State::A => { + break 'blk State::B + } + State::B => { /* ... */ } + /* ... */ + } + } +} +``` + +Here the loop itself can be annotated with `#[loop_match]`, and any `break 'blk` with +`#[const_continue]` if the value is know at compile time: + +```ignore (pseudo-rust) +#[loop_match] +loop { + state = 'blk: { + match state { + State::A => { + #[const_continue] + break 'blk State::B + } + State::B => { /* ... */ } + /* ... */ + } + } +} +``` + +The observable behavior of this loop is exactly the same as without the extra attributes. +The difference is in the generated output: normally, when the state is `A`, control flow +moves from the `A` branch, back to the top of the loop, then to the `B` branch. With the +attributes, The `A` branch will immediately jump to the `B` branch. + +Removing the indirection can be beneficial for stack usage and branch prediction, and +enables other optimizations by clearly splitting out the control flow paths that your +program will actually use. +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "m68k_target_feature", + description: r##"# `m68k_target_feature` + +Target features on m68k. + +The tracking issue for this feature is: [#134328] + +[#134328]: https://github.com/rust-lang/rust/issues/134328 ------------------------ "##, @@ -7905,12 +10042,30 @@ The tracking issue for this feature is: [#83527] deny_since: None, }, Lint { - label: "macro_metavar_expr_concat", - description: r##"# `macro_metavar_expr_concat` + label: "macro_attr", + description: r##"# `macro_attr` -The tracking issue for this feature is: [#124225] +Allow `macro_rules!` attribute rules -[#124225]: https://github.com/rust-lang/rust/issues/124225 +The tracking issue for this feature is: [#143547] + +[#143547]: https://github.com/rust-lang/rust/issues/143547 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "macro_derive", + description: r##"# `macro_derive` + +Allow `macro_rules!` derive rules + +The tracking issue for this feature is: [#143549] + +[#143549]: https://github.com/rust-lang/rust/issues/143549 ------------------------ "##, @@ -7919,14 +10074,173 @@ The tracking issue for this feature is: [#124225] deny_since: None, }, Lint { - label: "map_many_mut", - description: r##"# `map_many_mut` + label: "macro_guard_matcher", + description: r##"# `macro_guard_matcher` -The tracking issue for this feature is: [#97601] +Allow `$x:guard` matcher in macros -[#97601]: https://github.com/rust-lang/rust/issues/97601 +The tracking issue for this feature is: [#153104] + +[#153104]: https://github.com/rust-lang/rust/issues/153104 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "macro_metavar_expr", + description: r##"# `macro_metavar_expr` + +The tracking issue for this feature is: [#83527] ------------------------ + +> This feature is not to be confused with [`macro_metavar_expr_concat`]. + +[`macro_metavar_expr_concat`]: ./macro-metavar-expr-concat.md +[#83527]: https://github.com/rust-lang/rust/issues/83527 +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "macro_metavar_expr_concat", + description: r##"# `macro_metavar_expr_concat` + +The tracking issue for this feature is: [#124225] + +------------------------ + +In stable Rust, there is no way to create new identifiers by joining identifiers to literals or other identifiers without using procedural macros such as [`paste`]. + `#![feature(macro_metavar_expr_concat)]` introduces a way to do this, using the concat metavariable expression. + +> This feature uses the syntax from [`macro_metavar_expr`] but is otherwise +> independent. It replaces the since-removed unstable feature +> [`concat_idents`]. + +> This is an experimental feature; it and its syntax will require a RFC before stabilization. + + +### Overview + +`#![feature(macro_metavar_expr_concat)]` provides the `concat` metavariable expression for creating new identifiers: + +```rust +#![feature(macro_metavar_expr_concat)] + +macro_rules! create_some_structs { + ($name:ident) => { + pub struct ${ concat(First, $name) }; + pub struct ${ concat(Second, $name) }; + pub struct ${ concat(Third, $name) }; + } +} + +create_some_structs!(Thing); +``` + +This macro invocation expands to: + +```rust +pub struct FirstThing; +pub struct SecondThing; +pub struct ThirdThing; +``` + +### Syntax + +This feature builds upon the metavariable expression syntax `${ .. }` as specified in [RFC 3086] ([`macro_metavar_expr`]). + `concat` is available like `${ concat(items) }`, where `items` is a comma separated sequence of idents and/or literals. + +### Examples + +#### Create a function or method with a concatenated name + +```rust +#![feature(macro_metavar_expr_concat)] + +macro_rules! make_getter { + ($name:ident, $field: ident, $ret:ty) => { + impl $name { + pub fn ${ concat(get_, $field) }(&self) -> &$ret { + &self.$field + } + } + } +} + +pub struct Thing { + description: String, +} + +make_getter!(Thing, description, String); +``` + +This expands to: + +```rust +pub struct Thing { + description: String, +} + +impl Thing { + pub fn get_description(&self) -> &String { + &self.description + } +} +``` + +#### Create names for macro generated tests + +```rust +#![feature(macro_metavar_expr_concat)] + +macro_rules! test_math { + ($integer:ident) => { + #[test] + fn ${ concat(test_, $integer, _, addition) } () { + let a: $integer = 73; + let b: $integer = 42; + assert_eq!(a + b, 115) + } + + #[test] + fn ${ concat(test_, $integer, _, subtraction) } () { + let a: $integer = 73; + let b: $integer = 42; + assert_eq!(a - b, 31) + } + } +} + +test_math!(i32); +test_math!(u64); +test_math!(u128); +``` + +Running this returns the following output: + +```text +running 6 tests +test test_i32_subtraction ... ok +test test_i32_addition ... ok +test test_u128_addition ... ok +test test_u128_subtraction ... ok +test test_u64_addition ... ok +test test_u64_subtraction ... ok + +test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +``` + +[`paste`]: https://crates.io/crates/paste +[RFC 3086]: https://rust-lang.github.io/rfcs/3086-macro-metavar-expr.html +[`macro_metavar_expr`]: ../language-features/macro-metavar-expr.md +[`concat_idents`]: https://github.com/rust-lang/rust/issues/29599 +[#124225]: https://github.com/rust-lang/rust/issues/124225 +[declarative macros]: https://doc.rust-lang.org/stable/reference/macros-by-example.html "##, default_severity: Severity::Allow, warn_since: None, @@ -7936,6 +10250,8 @@ The tracking issue for this feature is: [#97601] label: "map_try_insert", description: r##"# `map_try_insert` + + The tracking issue for this feature is: [#82766] [#82766]: https://github.com/rust-lang/rust/issues/82766 @@ -7950,6 +10266,8 @@ The tracking issue for this feature is: [#82766] label: "mapped_lock_guards", description: r##"# `mapped_lock_guards` + + The tracking issue for this feature is: [#117108] [#117108]: https://github.com/rust-lang/rust/issues/117108 @@ -8003,9 +10321,27 @@ feature, which applied to all empty traits (without needing an opt-in). deny_since: None, }, Lint { + label: "maybe_dangling", + description: r##"# `maybe_dangling` + + + +The tracking issue for this feature is: [#118166] + +[#118166]: https://github.com/rust-lang/rust/issues/118166 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "maybe_uninit_array_assume_init", description: r##"# `maybe_uninit_array_assume_init` + + The tracking issue for this feature is: [#96097] [#96097]: https://github.com/rust-lang/rust/issues/96097 @@ -8020,6 +10356,8 @@ The tracking issue for this feature is: [#96097] label: "maybe_uninit_as_bytes", description: r##"# `maybe_uninit_as_bytes` + + The tracking issue for this feature is: [#93092] [#93092]: https://github.com/rust-lang/rust/issues/93092 @@ -8034,6 +10372,8 @@ The tracking issue for this feature is: [#93092] label: "maybe_uninit_fill", description: r##"# `maybe_uninit_fill` + + The tracking issue for this feature is: [#117428] [#117428]: https://github.com/rust-lang/rust/issues/117428 @@ -8045,12 +10385,14 @@ The tracking issue for this feature is: [#117428] deny_since: None, }, Lint { - label: "maybe_uninit_slice", - description: r##"# `maybe_uninit_slice` + label: "maybe_uninit_uninit_array_transpose", + description: r##"# `maybe_uninit_uninit_array_transpose` -The tracking issue for this feature is: [#63569] -[#63569]: https://github.com/rust-lang/rust/issues/63569 + +The tracking issue for this feature is: [#96097] + +[#96097]: https://github.com/rust-lang/rust/issues/96097 ------------------------ "##, @@ -8059,12 +10401,14 @@ The tracking issue for this feature is: [#63569] deny_since: None, }, Lint { - label: "maybe_uninit_uninit_array", - description: r##"# `maybe_uninit_uninit_array` + label: "mem_conjure_zst", + description: r##"# `mem_conjure_zst` -The tracking issue for this feature is: [#96097] -[#96097]: https://github.com/rust-lang/rust/issues/96097 + +The tracking issue for this feature is: [#95383] + +[#95383]: https://github.com/rust-lang/rust/issues/95383 ------------------------ "##, @@ -8073,12 +10417,14 @@ The tracking issue for this feature is: [#96097] deny_since: None, }, Lint { - label: "maybe_uninit_uninit_array_transpose", - description: r##"# `maybe_uninit_uninit_array_transpose` + label: "mem_copy_fn", + description: r##"# `mem_copy_fn` -The tracking issue for this feature is: [#96097] -[#96097]: https://github.com/rust-lang/rust/issues/96097 + +The tracking issue for this feature is: [#98262] + +[#98262]: https://github.com/rust-lang/rust/issues/98262 ------------------------ "##, @@ -8087,12 +10433,14 @@ The tracking issue for this feature is: [#96097] deny_since: None, }, Lint { - label: "maybe_uninit_write_slice", - description: r##"# `maybe_uninit_write_slice` + label: "mgca_type_const_syntax", + description: r##"# `mgca_type_const_syntax` -The tracking issue for this feature is: [#79995] +Enable mgca `type const` syntax before expansion. + +The tracking issue for this feature is: [#132980] -[#79995]: https://github.com/rust-lang/rust/issues/79995 +[#132980]: https://github.com/rust-lang/rust/issues/132980 ------------------------ "##, @@ -8101,12 +10449,14 @@ The tracking issue for this feature is: [#79995] deny_since: None, }, Lint { - label: "mem_copy_fn", - description: r##"# `mem_copy_fn` + label: "min_adt_const_params", + description: r##"# `min_adt_const_params` -The tracking issue for this feature is: [#98262] +Allows additional const parameter types, such as [u8; 10] or user defined types. User defined types must not have fields more private than the type itself. -[#98262]: https://github.com/rust-lang/rust/issues/98262 +The tracking issue for this feature is: [#154042] + +[#154042]: https://github.com/rust-lang/rust/issues/154042 ------------------------ "##, @@ -8118,6 +10468,8 @@ The tracking issue for this feature is: [#98262] label: "min_generic_const_args", description: r##"# `min_generic_const_args` +Enables the generic const args MVP (only bare paths, not arbitrary computation). + The tracking issue for this feature is: [#132980] [#132980]: https://github.com/rust-lang/rust/issues/132980 @@ -8132,6 +10484,8 @@ The tracking issue for this feature is: [#132980] label: "min_specialization", description: r##"# `min_specialization` +A minimal, sound subset of specialization intended to be used by the standard library until the soundness issues with specialization are fixed. + The tracking issue for this feature is: [#31844] [#31844]: https://github.com/rust-lang/rust/issues/31844 @@ -8146,23 +10500,11 @@ The tracking issue for this feature is: [#31844] label: "mips_target_feature", description: r##"# `mips_target_feature` -The tracking issue for this feature is: [#44839] - -[#44839]: https://github.com/rust-lang/rust/issues/44839 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "mixed_integer_ops_unsigned_sub", - description: r##"# `mixed_integer_ops_unsigned_sub` +Target features on mips. -The tracking issue for this feature is: [#126043] +The tracking issue for this feature is: [#150253] -[#126043]: https://github.com/rust-lang/rust/issues/126043 +[#150253]: https://github.com/rust-lang/rust/issues/150253 ------------------------ "##, @@ -8174,9 +10516,11 @@ The tracking issue for this feature is: [#126043] label: "more_float_constants", description: r##"# `more_float_constants` -The tracking issue for this feature is: [#103883] -[#103883]: https://github.com/rust-lang/rust/issues/103883 + +The tracking issue for this feature is: [#146939] + +[#146939]: https://github.com/rust-lang/rust/issues/146939 ------------------------ "##, @@ -8188,6 +10532,8 @@ The tracking issue for this feature is: [#103883] label: "more_maybe_bounds", description: r##"# `more_maybe_bounds` +Allows using `?Trait` trait bounds in more contexts. + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -8237,9 +10583,43 @@ impl A for Foo { deny_since: None, }, Lint { + label: "motor_ext", + description: r##"# `motor_ext` + + + +The tracking issue for this feature is: [#147456] + +[#147456]: https://github.com/rust-lang/rust/issues/147456 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "movrs_target_feature", + description: r##"# `movrs_target_feature` + +The `movrs` target feature on x86. + +The tracking issue for this feature is: [#137976] + +[#137976]: https://github.com/rust-lang/rust/issues/137976 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "mpmc_channel", description: r##"# `mpmc_channel` + + The tracking issue for this feature is: [#126840] [#126840]: https://github.com/rust-lang/rust/issues/126840 @@ -8251,10 +10631,30 @@ The tracking issue for this feature is: [#126840] deny_since: None, }, Lint { + label: "mpsc_is_disconnected", + description: r##"# `mpsc_is_disconnected` + + + +The tracking issue for this feature is: [#153668] + +[#153668]: https://github.com/rust-lang/rust/issues/153668 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "multiple_supertrait_upcastable", description: r##"# `multiple_supertrait_upcastable` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +Allows the `multiple_supertrait_upcastable` lint. + +The tracking issue for this feature is: [#150833] + +[#150833]: https://github.com/rust-lang/rust/issues/150833 ------------------------ "##, @@ -8266,6 +10666,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "must_not_suspend", description: r##"# `must_not_suspend` +Allows the `#[must_not_suspend]` attribute. + The tracking issue for this feature is: [#83310] [#83310]: https://github.com/rust-lang/rust/issues/83310 @@ -8280,6 +10682,8 @@ The tracking issue for this feature is: [#83310] label: "mut_ref", description: r##"# `mut_ref` +Allows `mut ref` and `mut ref mut` identifier patterns. + The tracking issue for this feature is: [#123076] [#123076]: https://github.com/rust-lang/rust/issues/123076 @@ -8291,12 +10695,46 @@ The tracking issue for this feature is: [#123076] deny_since: None, }, Lint { - label: "naked_functions", - description: r##"# `naked_functions` + label: "mutex_data_ptr", + description: r##"# `mutex_data_ptr` + + + +The tracking issue for this feature is: [#140368] + +[#140368]: https://github.com/rust-lang/rust/issues/140368 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "naked_functions_rustic_abi", + description: r##"# `naked_functions_rustic_abi` + +Allows using `#[naked]` on `extern "Rust"` functions. -The tracking issue for this feature is: [#90957] +The tracking issue for this feature is: [#138997] -[#90957]: https://github.com/rust-lang/rust/issues/90957 +[#138997]: https://github.com/rust-lang/rust/issues/138997 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "naked_functions_target_feature", + description: r##"# `naked_functions_target_feature` + +Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions. + +The tracking issue for this feature is: [#138568] + +[#138568]: https://github.com/rust-lang/rust/issues/138568 ------------------------ "##, @@ -8333,6 +10771,8 @@ The default for this modifier is unclear, some targets currently specify it as ` label: "needs_panic_runtime", description: r##"# `needs_panic_runtime` +Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. + The tracking issue for this feature is: [#32837] [#32837]: https://github.com/rust-lang/rust/issues/32837 @@ -8347,6 +10787,8 @@ The tracking issue for this feature is: [#32837] label: "negative_bounds", description: r##"# `negative_bounds` +Allow negative trait bounds. This is an internal-only feature for testing the trait solver! + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -8423,6 +10865,8 @@ This serves two purposes: label: "never_patterns", description: r##"# `never_patterns` +Allows the `!` pattern. + The tracking issue for this feature is: [#118155] [#118155]: https://github.com/rust-lang/rust/issues/118155 @@ -8437,6 +10881,8 @@ The tracking issue for this feature is: [#118155] label: "never_type", description: r##"# `never_type` +Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. + The tracking issue for this feature is: [#35121] [#35121]: https://github.com/rust-lang/rust/issues/35121 @@ -8448,22 +10894,26 @@ The tracking issue for this feature is: [#35121] deny_since: None, }, Lint { - label: "never_type_fallback", - description: r##"# `never_type_fallback` + label: "new_range", + description: r##"# `new_range` -The tracking issue for this feature is: [#65992] +The tracking issue for this feature is: [#123741] -[#65992]: https://github.com/rust-lang/rust/issues/65992 +[#123741]: https://github.com/rust-lang/rust/issues/123741 ------------------------- +--- + +Switch the syntaxes `a..`, `a..b`, and `a..=b` to resolve the new range types. "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "new_range_api", - description: r##"# `new_range_api` + label: "new_range_api_legacy", + description: r##"# `new_range_api_legacy` + + The tracking issue for this feature is: [#125687] @@ -8476,12 +10926,14 @@ The tracking issue for this feature is: [#125687] deny_since: None, }, Lint { - label: "new_zeroed_alloc", - description: r##"# `new_zeroed_alloc` + label: "new_range_remainder", + description: r##"# `new_range_remainder` + + -The tracking issue for this feature is: [#129396] +The tracking issue for this feature is: [#154458] -[#129396]: https://github.com/rust-lang/rust/issues/129396 +[#154458]: https://github.com/rust-lang/rust/issues/154458 ------------------------ "##, @@ -8490,12 +10942,14 @@ The tracking issue for this feature is: [#129396] deny_since: None, }, Lint { - label: "no_core", - description: r##"# `no_core` + label: "next_index", + description: r##"# `next_index` -The tracking issue for this feature is: [#29639] -[#29639]: https://github.com/rust-lang/rust/issues/29639 + +The tracking issue for this feature is: [#130711] + +[#130711]: https://github.com/rust-lang/rust/issues/130711 ------------------------ "##, @@ -8504,36 +10958,16 @@ The tracking issue for this feature is: [#29639] deny_since: None, }, Lint { - label: "no_sanitize", - description: r##"# `no_sanitize` - -The tracking issue for this feature is: [#39699] - -[#39699]: https://github.com/rust-lang/rust/issues/39699 - ------------------------- - -The `no_sanitize` attribute can be used to selectively disable sanitizer -instrumentation in an annotated function. This might be useful to: avoid -instrumentation overhead in a performance critical function, or avoid -instrumenting code that contains constructs unsupported by given sanitizer. + label: "no_core", + description: r##"# `no_core` -The precise effect of this annotation depends on particular sanitizer in use. -For example, with `no_sanitize(thread)`, the thread sanitizer will no longer -instrument non-atomic store / load operations, but it will instrument atomic -operations to avoid reporting false positives and provide meaning full stack -traces. +Allows `#![no_core]`. -## Examples +The tracking issue for this feature is: [#29639] -``` rust -#![feature(no_sanitize)] +[#29639]: https://github.com/rust-lang/rust/issues/29639 -#[no_sanitize(address)] -fn foo() { - // ... -} -``` +------------------------ "##, default_severity: Severity::Allow, warn_since: None, @@ -8543,6 +10977,8 @@ fn foo() { label: "non_exhaustive_omitted_patterns_lint", description: r##"# `non_exhaustive_omitted_patterns_lint` +Allows using the `non_exhaustive_omitted_patterns` lint. + The tracking issue for this feature is: [#89554] [#89554]: https://github.com/rust-lang/rust/issues/89554 @@ -8557,6 +10993,8 @@ The tracking issue for this feature is: [#89554] label: "non_lifetime_binders", description: r##"# `non_lifetime_binders` +Allows `for<T>` binders in where-clauses + The tracking issue for this feature is: [#108185] [#108185]: https://github.com/rust-lang/rust/issues/108185 @@ -8568,12 +11006,30 @@ The tracking issue for this feature is: [#108185] deny_since: None, }, Lint { - label: "non_null_from_ref", - description: r##"# `non_null_from_ref` + label: "nonpoison_condvar", + description: r##"# `nonpoison_condvar` + + + +The tracking issue for this feature is: [#134645] + +[#134645]: https://github.com/rust-lang/rust/issues/134645 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonpoison_mutex", + description: r##"# `nonpoison_mutex` + + -The tracking issue for this feature is: [#130823] +The tracking issue for this feature is: [#134645] -[#130823]: https://github.com/rust-lang/rust/issues/130823 +[#134645]: https://github.com/rust-lang/rust/issues/134645 ------------------------ "##, @@ -8582,12 +11038,14 @@ The tracking issue for this feature is: [#130823] deny_since: None, }, Lint { - label: "non_zero_count_ones", - description: r##"# `non_zero_count_ones` + label: "nonpoison_rwlock", + description: r##"# `nonpoison_rwlock` -The tracking issue for this feature is: [#120287] -[#120287]: https://github.com/rust-lang/rust/issues/120287 + +The tracking issue for this feature is: [#134645] + +[#134645]: https://github.com/rust-lang/rust/issues/134645 ------------------------ "##, @@ -8599,6 +11057,8 @@ The tracking issue for this feature is: [#120287] label: "nonzero_bitwise", description: r##"# `nonzero_bitwise` + + The tracking issue for this feature is: [#128281] [#128281]: https://github.com/rust-lang/rust/issues/128281 @@ -8613,6 +11073,8 @@ The tracking issue for this feature is: [#128281] label: "nonzero_from_mut", description: r##"# `nonzero_from_mut` + + The tracking issue for this feature is: [#106290] [#106290]: https://github.com/rust-lang/rust/issues/106290 @@ -8624,9 +11086,27 @@ The tracking issue for this feature is: [#106290] deny_since: None, }, Lint { + label: "nonzero_from_str_radix", + description: r##"# `nonzero_from_str_radix` + + + +The tracking issue for this feature is: [#152193] + +[#152193]: https://github.com/rust-lang/rust/issues/152193 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "nonzero_internals", description: r##"# `nonzero_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -8639,6 +11119,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "nonzero_ops", description: r##"# `nonzero_ops` + + The tracking issue for this feature is: [#84186] [#84186]: https://github.com/rust-lang/rust/issues/84186 @@ -8650,12 +11132,28 @@ The tracking issue for this feature is: [#84186] deny_since: None, }, Lint { - label: "num_midpoint_signed", - description: r##"# `num_midpoint_signed` + label: "normalize_lexically", + description: r##"# `normalize_lexically` + + + +The tracking issue for this feature is: [#134694] + +[#134694]: https://github.com/rust-lang/rust/issues/134694 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "num_internals", + description: r##"# `num_internals` -The tracking issue for this feature is: [#110840] -[#110840]: https://github.com/rust-lang/rust/issues/110840 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -8667,6 +11165,8 @@ The tracking issue for this feature is: [#110840] label: "numfmt", description: r##"# `numfmt` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -8676,12 +11176,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "offset_of_enum", - description: r##"# `offset_of_enum` + label: "nvptx_target_feature", + description: r##"# `nvptx_target_feature` -The tracking issue for this feature is: [#120141] +Target feaures on nvptx. -[#120141]: https://github.com/rust-lang/rust/issues/120141 +The tracking issue for this feature is: [#150254] + +[#150254]: https://github.com/rust-lang/rust/issues/150254 ------------------------ "##, @@ -8690,12 +11192,12 @@ The tracking issue for this feature is: [#120141] deny_since: None, }, Lint { - label: "offset_of_slice", - description: r##"# `offset_of_slice` + label: "objc_class_variant", + description: r##"# `objc_class_variant` -The tracking issue for this feature is: [#126151] -[#126151]: https://github.com/rust-lang/rust/issues/126151 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -8704,8 +11206,10 @@ The tracking issue for this feature is: [#126151] deny_since: None, }, Lint { - label: "omit_gdb_pretty_printer_section", - description: r##"# `omit_gdb_pretty_printer_section` + label: "objc_selector_variant", + description: r##"# `objc_selector_variant` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -8716,9 +11220,84 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "offset_of_enum", + description: r##"# `offset_of_enum` + +The tracking issue for this feature is: [#120141] + +[#120141]: https://github.com/rust-lang/rust/issues/120141 + +------------------------ + +When the `offset_of_enum` feature is enabled, the [`offset_of!`] macro may be used to obtain the +offsets of fields of `enum`s; to express this, `enum` variants may be traversed as if they were +fields. Variants themselves do not have an offset, so they cannot appear as the last path component. + +```rust +#![feature(offset_of_enum)] +use std::mem; + +#[repr(u8)] +enum Enum { + A(u8, u16), + B { one: u8, two: u16 }, +} + +assert_eq!(mem::offset_of!(Enum, A.0), 1); +assert_eq!(mem::offset_of!(Enum, B.two), 2); + +assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); +``` + +[`offset_of!`]: ../../std/mem/macro.offset_of.html +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "offset_of_slice", + description: r##"# `offset_of_slice` + +The tracking issue for this feature is: [#126151] + +[#126151]: https://github.com/rust-lang/rust/issues/126151 + +------------------------ + +When the `offset_of_slice` feature is enabled, the [`offset_of!`] macro may be used to determine +the offset of fields whose type is `[T]`, that is, a slice of dynamic size. + +In general, fields whose type is dynamically sized do not have statically known offsets because +they do not have statically known alignments. However, `[T]` has the same alignment as `T`, so +it specifically may be allowed. + +```rust +#![feature(offset_of_slice)] + +#[repr(C)] +pub struct Struct { + head: u32, + tail: [u8], +} + +fn main() { + assert_eq!(std::mem::offset_of!(Struct, tail), 4); +} +``` + +[`offset_of!`]: ../../std/mem/macro.offset_of.html +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "once_cell_get_mut", description: r##"# `once_cell_get_mut` + + The tracking issue for this feature is: [#121641] [#121641]: https://github.com/rust-lang/rust/issues/121641 @@ -8733,6 +11312,8 @@ The tracking issue for this feature is: [#121641] label: "once_cell_try", description: r##"# `once_cell_try` + + The tracking issue for this feature is: [#109737] [#109737]: https://github.com/rust-lang/rust/issues/109737 @@ -8747,6 +11328,8 @@ The tracking issue for this feature is: [#109737] label: "once_cell_try_insert", description: r##"# `once_cell_try_insert` + + The tracking issue for this feature is: [#116693] [#116693]: https://github.com/rust-lang/rust/issues/116693 @@ -8758,12 +11341,14 @@ The tracking issue for this feature is: [#116693] deny_since: None, }, Lint { - label: "once_wait", - description: r##"# `once_wait` + label: "one_sided_range", + description: r##"# `one_sided_range` + -The tracking issue for this feature is: [#127527] -[#127527]: https://github.com/rust-lang/rust/issues/127527 +The tracking issue for this feature is: [#69780] + +[#69780]: https://github.com/rust-lang/rust/issues/69780 ------------------------ "##, @@ -8772,12 +11357,14 @@ The tracking issue for this feature is: [#127527] deny_since: None, }, Lint { - label: "one_sided_range", - description: r##"# `one_sided_range` + label: "oneshot_channel", + description: r##"# `oneshot_channel` -The tracking issue for this feature is: [#69780] -[#69780]: https://github.com/rust-lang/rust/issues/69780 + +The tracking issue for this feature is: [#143674] + +[#143674]: https://github.com/rust-lang/rust/issues/143674 ------------------------ "##, @@ -8789,6 +11376,8 @@ The tracking issue for this feature is: [#69780] label: "optimize_attribute", description: r##"# `optimize_attribute` +Allows using `#[optimize(X)]`. + The tracking issue for this feature is: [#54882] [#54882]: https://github.com/rust-lang/rust/issues/54882 @@ -8803,6 +11392,8 @@ The tracking issue for this feature is: [#54882] label: "option_array_transpose", description: r##"# `option_array_transpose` + + The tracking issue for this feature is: [#130828] [#130828]: https://github.com/rust-lang/rust/issues/130828 @@ -8814,12 +11405,14 @@ The tracking issue for this feature is: [#130828] deny_since: None, }, Lint { - label: "option_zip", - description: r##"# `option_zip` + label: "option_get_or_try_insert_with", + description: r##"# `option_get_or_try_insert_with` -The tracking issue for this feature is: [#70086] -[#70086]: https://github.com/rust-lang/rust/issues/70086 + +The tracking issue for this feature is: [#143648] + +[#143648]: https://github.com/rust-lang/rust/issues/143648 ------------------------ "##, @@ -8828,12 +11421,14 @@ The tracking issue for this feature is: [#70086] deny_since: None, }, Lint { - label: "os_str_display", - description: r##"# `os_str_display` + label: "option_into_flat_iter", + description: r##"# `option_into_flat_iter` + + -The tracking issue for this feature is: [#120048] +The tracking issue for this feature is: [#148441] -[#120048]: https://github.com/rust-lang/rust/issues/120048 +[#148441]: https://github.com/rust-lang/rust/issues/148441 ------------------------ "##, @@ -8842,12 +11437,14 @@ The tracking issue for this feature is: [#120048] deny_since: None, }, Lint { - label: "os_str_slice", - description: r##"# `os_str_slice` + label: "option_reduce", + description: r##"# `option_reduce` -The tracking issue for this feature is: [#118485] -[#118485]: https://github.com/rust-lang/rust/issues/118485 + +The tracking issue for this feature is: [#144273] + +[#144273]: https://github.com/rust-lang/rust/issues/144273 ------------------------ "##, @@ -8856,12 +11453,46 @@ The tracking issue for this feature is: [#118485] deny_since: None, }, Lint { - label: "os_string_pathbuf_leak", - description: r##"# `os_string_pathbuf_leak` + label: "option_reference_flattening", + description: r##"# `option_reference_flattening` + -The tracking issue for this feature is: [#125965] -[#125965]: https://github.com/rust-lang/rust/issues/125965 +The tracking issue for this feature is: [#149221] + +[#149221]: https://github.com/rust-lang/rust/issues/149221 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "option_zip", + description: r##"# `option_zip` + + + +The tracking issue for this feature is: [#70086] + +[#70086]: https://github.com/rust-lang/rust/issues/70086 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "os_str_slice", + description: r##"# `os_str_slice` + + + +The tracking issue for this feature is: [#118485] + +[#118485]: https://github.com/rust-lang/rust/issues/118485 ------------------------ "##, @@ -8873,6 +11504,8 @@ The tracking issue for this feature is: [#125965] label: "os_string_truncate", description: r##"# `os_string_truncate` + + The tracking issue for this feature is: [#133262] [#133262]: https://github.com/rust-lang/rust/issues/133262 @@ -8887,6 +11520,8 @@ The tracking issue for this feature is: [#133262] label: "panic_abort", description: r##"# `panic_abort` + + The tracking issue for this feature is: [#32837] [#32837]: https://github.com/rust-lang/rust/issues/32837 @@ -8901,6 +11536,8 @@ The tracking issue for this feature is: [#32837] label: "panic_always_abort", description: r##"# `panic_always_abort` + + The tracking issue for this feature is: [#84438] [#84438]: https://github.com/rust-lang/rust/issues/84438 @@ -8915,6 +11552,8 @@ The tracking issue for this feature is: [#84438] label: "panic_backtrace_config", description: r##"# `panic_backtrace_config` + + The tracking issue for this feature is: [#93346] [#93346]: https://github.com/rust-lang/rust/issues/93346 @@ -8929,6 +11568,8 @@ The tracking issue for this feature is: [#93346] label: "panic_can_unwind", description: r##"# `panic_can_unwind` + + The tracking issue for this feature is: [#92988] [#92988]: https://github.com/rust-lang/rust/issues/92988 @@ -8943,21 +11584,9 @@ The tracking issue for this feature is: [#92988] label: "panic_internals", description: r##"# `panic_internals` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "panic_payload_as_str", - description: r##"# `panic_payload_as_str` -The tracking issue for this feature is: [#125175] -[#125175]: https://github.com/rust-lang/rust/issues/125175 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -8969,6 +11598,8 @@ The tracking issue for this feature is: [#125175] label: "panic_runtime", description: r##"# `panic_runtime` +Allows using the `#![panic_runtime]` attribute. + The tracking issue for this feature is: [#32837] [#32837]: https://github.com/rust-lang/rust/issues/32837 @@ -8983,6 +11614,8 @@ The tracking issue for this feature is: [#32837] label: "panic_unwind", description: r##"# `panic_unwind` + + The tracking issue for this feature is: [#32837] [#32837]: https://github.com/rust-lang/rust/issues/32837 @@ -8997,6 +11630,8 @@ The tracking issue for this feature is: [#32837] label: "panic_update_hook", description: r##"# `panic_update_hook` + + The tracking issue for this feature is: [#92649] [#92649]: https://github.com/rust-lang/rust/issues/92649 @@ -9008,9 +11643,25 @@ The tracking issue for this feature is: [#92649] deny_since: None, }, Lint { + label: "partial_ord_chaining_methods", + description: r##"# `partial_ord_chaining_methods` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "patchable_function_entry", description: r##"# `patchable_function_entry` +Allows specifying nop padding on functions for dynamic patching. + The tracking issue for this feature is: [#123115] [#123115]: https://github.com/rust-lang/rust/issues/123115 @@ -9022,12 +11673,30 @@ The tracking issue for this feature is: [#123115] deny_since: None, }, Lint { - label: "path_add_extension", - description: r##"# `path_add_extension` + label: "path_absolute_method", + description: r##"# `path_absolute_method` + + + +The tracking issue for this feature is: [#153328] + +[#153328]: https://github.com/rust-lang/rust/issues/153328 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "path_is_empty", + description: r##"# `path_is_empty` + -The tracking issue for this feature is: [#127292] -[#127292]: https://github.com/rust-lang/rust/issues/127292 +The tracking issue for this feature is: [#148494] + +[#148494]: https://github.com/rust-lang/rust/issues/148494 ------------------------ "##, @@ -9036,12 +11705,14 @@ The tracking issue for this feature is: [#127292] deny_since: None, }, Lint { - label: "path_file_prefix", - description: r##"# `path_file_prefix` + label: "path_trailing_sep", + description: r##"# `path_trailing_sep` + -The tracking issue for this feature is: [#86319] -[#86319]: https://github.com/rust-lang/rust/issues/86319 +The tracking issue for this feature is: [#142503] + +[#142503]: https://github.com/rust-lang/rust/issues/142503 ------------------------ "##, @@ -9053,6 +11724,8 @@ The tracking issue for this feature is: [#86319] label: "pattern", description: r##"# `pattern` + + The tracking issue for this feature is: [#27721] [#27721]: https://github.com/rust-lang/rust/issues/27721 @@ -9067,6 +11740,8 @@ The tracking issue for this feature is: [#27721] label: "pattern_complexity_limit", description: r##"# `pattern_complexity_limit` +Set the maximum pattern complexity allowed (not limited by default). + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -9079,6 +11754,24 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "pattern_type_macro", description: r##"# `pattern_type_macro` + + +The tracking issue for this feature is: [#123646] + +[#123646]: https://github.com/rust-lang/rust/issues/123646 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "pattern_type_range_trait", + description: r##"# `pattern_type_range_trait` + + + The tracking issue for this feature is: [#123646] [#123646]: https://github.com/rust-lang/rust/issues/123646 @@ -9093,6 +11786,8 @@ The tracking issue for this feature is: [#123646] label: "pattern_types", description: r##"# `pattern_types` +Allows using pattern types. + The tracking issue for this feature is: [#123646] [#123646]: https://github.com/rust-lang/rust/issues/123646 @@ -9107,6 +11802,8 @@ The tracking issue for this feature is: [#123646] label: "peer_credentials_unix_socket", description: r##"# `peer_credentials_unix_socket` + + The tracking issue for this feature is: [#42839] [#42839]: https://github.com/rust-lang/rust/issues/42839 @@ -9118,12 +11815,44 @@ The tracking issue for this feature is: [#42839] deny_since: None, }, Lint { + label: "phantom_variance_markers", + description: r##"# `phantom_variance_markers` + + + +The tracking issue for this feature is: [#135806] + +[#135806]: https://github.com/rust-lang/rust/issues/135806 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "pin_coerce_unsized_trait", description: r##"# `pin_coerce_unsized_trait` -The tracking issue for this feature is: [#123430] -[#123430]: https://github.com/rust-lang/rust/issues/123430 + +The tracking issue for this feature is: [#150112] + +[#150112]: https://github.com/rust-lang/rust/issues/150112 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "pin_derefmut_internals", + description: r##"# `pin_derefmut_internals` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -9135,6 +11864,8 @@ The tracking issue for this feature is: [#123430] label: "pin_ergonomics", description: r##"# `pin_ergonomics` +Experimental features that make `Pin` more ergonomic. + The tracking issue for this feature is: [#130494] [#130494]: https://github.com/rust-lang/rust/issues/130494 @@ -9149,6 +11880,8 @@ The tracking issue for this feature is: [#130494] label: "pointer_is_aligned_to", description: r##"# `pointer_is_aligned_to` + + The tracking issue for this feature is: [#96284] [#96284]: https://github.com/rust-lang/rust/issues/96284 @@ -9160,10 +11893,14 @@ The tracking issue for this feature is: [#96284] deny_since: None, }, Lint { - label: "pointer_like_trait", - description: r##"# `pointer_like_trait` + label: "pointer_try_cast_aligned", + description: r##"# `pointer_try_cast_aligned` + -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +The tracking issue for this feature is: [#141221] + +[#141221]: https://github.com/rust-lang/rust/issues/141221 ------------------------ "##, @@ -9175,6 +11912,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "portable_simd", description: r##"# `portable_simd` + + The tracking issue for this feature is: [#86656] [#86656]: https://github.com/rust-lang/rust/issues/86656 @@ -9222,9 +11961,11 @@ get_foo().match { label: "powerpc_target_feature", description: r##"# `powerpc_target_feature` -The tracking issue for this feature is: [#44839] +Target features on powerpc. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150255] + +[#150255]: https://github.com/rust-lang/rust/issues/150255 ------------------------ "##, @@ -9233,12 +11974,12 @@ The tracking issue for this feature is: [#44839] deny_since: None, }, Lint { - label: "precise_capturing_in_traits", - description: r##"# `precise_capturing_in_traits` + label: "prelude_future", + description: r##"# `prelude_future` + -The tracking issue for this feature is: [#130044] -[#130044]: https://github.com/rust-lang/rust/issues/130044 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -9247,12 +11988,12 @@ The tracking issue for this feature is: [#130044] deny_since: None, }, Lint { - label: "prelude_2024", - description: r##"# `prelude_2024` + label: "prelude_import", + description: r##"# `prelude_import` -The tracking issue for this feature is: [#121042] +Allows using `#[prelude_import]` on glob `use` items. -[#121042]: https://github.com/rust-lang/rust/issues/121042 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -9261,8 +12002,10 @@ The tracking issue for this feature is: [#121042] deny_since: None, }, Lint { - label: "prelude_import", - description: r##"# `prelude_import` + label: "prelude_next", + description: r##"# `prelude_next` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -9276,9 +12019,11 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "prfchw_target_feature", description: r##"# `prfchw_target_feature` -The tracking issue for this feature is: [#44839] +The prfchw target feature on x86. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150256] + +[#150256]: https://github.com/rust-lang/rust/issues/150256 ------------------------ "##, @@ -9302,6 +12047,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "proc_macro_def_site", description: r##"# `proc_macro_def_site` + + The tracking issue for this feature is: [#54724] [#54724]: https://github.com/rust-lang/rust/issues/54724 @@ -9316,6 +12063,8 @@ The tracking issue for this feature is: [#54724] label: "proc_macro_diagnostic", description: r##"# `proc_macro_diagnostic` + + The tracking issue for this feature is: [#54140] [#54140]: https://github.com/rust-lang/rust/issues/54140 @@ -9330,6 +12079,8 @@ The tracking issue for this feature is: [#54140] label: "proc_macro_expand", description: r##"# `proc_macro_expand` + + The tracking issue for this feature is: [#90765] [#90765]: https://github.com/rust-lang/rust/issues/90765 @@ -9344,6 +12095,8 @@ The tracking issue for this feature is: [#90765] label: "proc_macro_hygiene", description: r##"# `proc_macro_hygiene` +Allows macro attributes on expressions, statements and non-inline modules. + The tracking issue for this feature is: [#54727] [#54727]: https://github.com/rust-lang/rust/issues/54727 @@ -9358,6 +12111,8 @@ The tracking issue for this feature is: [#54727] label: "proc_macro_internals", description: r##"# `proc_macro_internals` + + The tracking issue for this feature is: [#27812] [#27812]: https://github.com/rust-lang/rust/issues/27812 @@ -9372,6 +12127,8 @@ The tracking issue for this feature is: [#27812] label: "proc_macro_quote", description: r##"# `proc_macro_quote` + + The tracking issue for this feature is: [#54722] [#54722]: https://github.com/rust-lang/rust/issues/54722 @@ -9386,6 +12143,8 @@ The tracking issue for this feature is: [#54722] label: "proc_macro_span", description: r##"# `proc_macro_span` + + The tracking issue for this feature is: [#54725] [#54725]: https://github.com/rust-lang/rust/issues/54725 @@ -9400,6 +12159,8 @@ The tracking issue for this feature is: [#54725] label: "proc_macro_totokens", description: r##"# `proc_macro_totokens` + + The tracking issue for this feature is: [#130977] [#130977]: https://github.com/rust-lang/rust/issues/130977 @@ -9414,6 +12175,8 @@ The tracking issue for this feature is: [#130977] label: "proc_macro_tracked_env", description: r##"# `proc_macro_tracked_env` + + The tracking issue for this feature is: [#99515] [#99515]: https://github.com/rust-lang/rust/issues/99515 @@ -9425,9 +12188,59 @@ The tracking issue for this feature is: [#99515] deny_since: None, }, Lint { + label: "proc_macro_tracked_path", + description: r##"# `proc_macro_tracked_path` + + + +The tracking issue for this feature is: [#99515] + +[#99515]: https://github.com/rust-lang/rust/issues/99515 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "proc_macro_value", + description: r##"# `proc_macro_value` + + + +The tracking issue for this feature is: [#136652] + +[#136652]: https://github.com/rust-lang/rust/issues/136652 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "process_chroot", + description: r##"# `process_chroot` + + + +The tracking issue for this feature is: [#141298] + +[#141298]: https://github.com/rust-lang/rust/issues/141298 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "process_exitcode_internals", description: r##"# `process_exitcode_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -9440,6 +12253,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "process_internals", description: r##"# `process_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -9449,6 +12264,22 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "process_setsid", + description: r##"# `process_setsid` + + + +The tracking issue for this feature is: [#105376] + +[#105376]: https://github.com/rust-lang/rust/issues/105376 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "profiler_runtime", description: r##"# `profiler_runtime` @@ -9473,12 +12304,14 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { - label: "ptr_alignment_type", - description: r##"# `ptr_alignment_type` + label: "profiling_marker_api", + description: r##"# `profiling_marker_api` -The tracking issue for this feature is: [#102070] -[#102070]: https://github.com/rust-lang/rust/issues/102070 + +The tracking issue for this feature is: [#148197] + +[#148197]: https://github.com/rust-lang/rust/issues/148197 ------------------------ "##, @@ -9487,12 +12320,14 @@ The tracking issue for this feature is: [#102070] deny_since: None, }, Lint { - label: "ptr_as_ref_unchecked", - description: r##"# `ptr_as_ref_unchecked` + label: "ptr_alignment_type", + description: r##"# `ptr_alignment_type` + + -The tracking issue for this feature is: [#122034] +The tracking issue for this feature is: [#102070] -[#122034]: https://github.com/rust-lang/rust/issues/122034 +[#102070]: https://github.com/rust-lang/rust/issues/102070 ------------------------ "##, @@ -9504,6 +12339,8 @@ The tracking issue for this feature is: [#122034] label: "ptr_as_uninit", description: r##"# `ptr_as_uninit` + + The tracking issue for this feature is: [#75402] [#75402]: https://github.com/rust-lang/rust/issues/75402 @@ -9515,9 +12352,43 @@ The tracking issue for this feature is: [#75402] deny_since: None, }, Lint { + label: "ptr_cast_array", + description: r##"# `ptr_cast_array` + + + +The tracking issue for this feature is: [#144514] + +[#144514]: https://github.com/rust-lang/rust/issues/144514 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "ptr_cast_slice", + description: r##"# `ptr_cast_slice` + + + +The tracking issue for this feature is: [#149103] + +[#149103]: https://github.com/rust-lang/rust/issues/149103 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "ptr_internals", description: r##"# `ptr_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -9530,6 +12401,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "ptr_mask", description: r##"# `ptr_mask` + + The tracking issue for this feature is: [#98290] [#98290]: https://github.com/rust-lang/rust/issues/98290 @@ -9544,6 +12417,8 @@ The tracking issue for this feature is: [#98290] label: "ptr_metadata", description: r##"# `ptr_metadata` + + The tracking issue for this feature is: [#81513] [#81513]: https://github.com/rust-lang/rust/issues/81513 @@ -9555,12 +12430,12 @@ The tracking issue for this feature is: [#81513] deny_since: None, }, Lint { - label: "ptr_sub_ptr", - description: r##"# `ptr_sub_ptr` + label: "pub_crate_should_not_need_unstable_attr", + description: r##"# `pub_crate_should_not_need_unstable_attr` + -The tracking issue for this feature is: [#95892] -[#95892]: https://github.com/rust-lang/rust/issues/95892 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -9569,10 +12444,14 @@ The tracking issue for this feature is: [#95892] deny_since: None, }, Lint { - label: "pub_crate_should_not_need_unstable_attr", - description: r##"# `pub_crate_should_not_need_unstable_attr` + label: "random", + description: r##"# `random` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#130703] + +[#130703]: https://github.com/rust-lang/rust/issues/130703 ------------------------ "##, @@ -9581,12 +12460,46 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "random", - description: r##"# `random` + label: "range_bounds_is_empty", + description: r##"# `range_bounds_is_empty` -The tracking issue for this feature is: [#130703] -[#130703]: https://github.com/rust-lang/rust/issues/130703 + +The tracking issue for this feature is: [#137300] + +[#137300]: https://github.com/rust-lang/rust/issues/137300 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "range_into_bounds", + description: r##"# `range_into_bounds` + + + +The tracking issue for this feature is: [#136903] + +[#136903]: https://github.com/rust-lang/rust/issues/136903 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "raw_dylib_elf", + description: r##"# `raw_dylib_elf` + +Allows the use of raw-dylibs on ELF platforms + +The tracking issue for this feature is: [#135694] + +[#135694]: https://github.com/rust-lang/rust/issues/135694 ------------------------ "##, @@ -9598,6 +12511,8 @@ The tracking issue for this feature is: [#130703] label: "raw_os_error_ty", description: r##"# `raw_os_error_ty` + + The tracking issue for this feature is: [#107792] [#107792]: https://github.com/rust-lang/rust/issues/107792 @@ -9612,6 +12527,8 @@ The tracking issue for this feature is: [#107792] label: "raw_slice_split", description: r##"# `raw_slice_split` + + The tracking issue for this feature is: [#95595] [#95595]: https://github.com/rust-lang/rust/issues/95595 @@ -9626,6 +12543,8 @@ The tracking issue for this feature is: [#95595] label: "raw_vec_internals", description: r##"# `raw_vec_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -9635,9 +12554,27 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "read_array", + description: r##"# `read_array` + + + +The tracking issue for this feature is: [#148848] + +[#148848]: https://github.com/rust-lang/rust/issues/148848 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "read_buf", description: r##"# `read_buf` + + The tracking issue for this feature is: [#78485] [#78485]: https://github.com/rust-lang/rust/issues/78485 @@ -9649,9 +12586,43 @@ The tracking issue for this feature is: [#78485] deny_since: None, }, Lint { + label: "read_buf_at", + description: r##"# `read_buf_at` + + + +The tracking issue for this feature is: [#140771] + +[#140771]: https://github.com/rust-lang/rust/issues/140771 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "reborrow", + description: r##"# `reborrow` + + + +The tracking issue for this feature is: [#145612] + +[#145612]: https://github.com/rust-lang/rust/issues/145612 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "reentrant_lock", description: r##"# `reentrant_lock` + + The tracking issue for this feature is: [#121440] [#121440]: https://github.com/rust-lang/rust/issues/121440 @@ -9663,6 +12634,22 @@ The tracking issue for this feature is: [#121440] deny_since: None, }, Lint { + label: "reentrant_lock_data_ptr", + description: r##"# `reentrant_lock_data_ptr` + + + +The tracking issue for this feature is: [#140368] + +[#140368]: https://github.com/rust-lang/rust/issues/140368 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "ref_pat_eat_one_layer_2024", description: r##"# `ref_pat_eat_one_layer_2024` @@ -9670,7 +12657,41 @@ The tracking issue for this feature is: [#123076] [#123076]: https://github.com/rust-lang/rust/issues/123076 ------------------------- +--- + +This feature is incomplete and not yet intended for general use. + +This implements experimental, Edition-dependent match ergonomics under consideration for inclusion +in Rust, allowing `&` patterns in more places. For example: + +```rust,edition2024 +#![feature(ref_pat_eat_one_layer_2024)] +#![allow(incomplete_features)] +# +# // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`. +# trait Eq<T> {} +# impl<T> Eq<T> for T {} +# fn has_type<T>(_: impl Eq<T>) {} + +// `&` can match against a `ref` binding mode instead of a reference type: +let (x, &y) = &(0, 1); +has_type::<&u8>(x); +has_type::<u8>(y); + +// `&` can match against `&mut` references: +let &z = &mut 2; +has_type::<u8>(z); +``` + +For specifics, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For more information on binding modes, see [The Rust Reference]. + +For alternative experimental match ergonomics, see the feature +[`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md). + +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false +[Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false +[The Rust Reference]: https://doc.rust-lang.org/reference/patterns.html#binding-modes "##, default_severity: Severity::Allow, warn_since: None, @@ -9684,19 +12705,54 @@ The tracking issue for this feature is: [#123076] [#123076]: https://github.com/rust-lang/rust/issues/123076 ------------------------- +--- + +This feature is incomplete and not yet intended for general use. + +This implements experimental, Edition-dependent match ergonomics under consideration for inclusion +in Rust, allowing `&` patterns in more places. For example: +```rust,edition2024 +#![feature(ref_pat_eat_one_layer_2024_structural)] +#![allow(incomplete_features)] +# +# // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`. +# trait Eq<T> {} +# impl<T> Eq<T> for T {} +# fn has_type<T>(_: impl Eq<T>) {} + +// `&` can match against a `ref` binding mode instead of a reference type: +let (x, &y) = &(0, 1); +has_type::<&u8>(x); +has_type::<u8>(y); + +// `&` can match against `&mut` references: +let &z = &mut 2; +has_type::<u8>(z); +``` + +For specifics, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For more information on binding modes, see [The Rust Reference]. + +For alternative experimental match ergonomics, see the feature +[`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md). + +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQEBAAAAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false +[Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false +[The Rust Reference]: https://doc.rust-lang.org/reference/patterns.html#binding-modes "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "register_tool", - description: r##"# `register_tool` + label: "refcell_try_map", + description: r##"# `refcell_try_map` -The tracking issue for this feature is: [#66079] -[#66079]: https://github.com/rust-lang/rust/issues/66079 + +The tracking issue for this feature is: [#143801] + +[#143801]: https://github.com/rust-lang/rust/issues/143801 ------------------------ "##, @@ -9705,25 +12761,62 @@ The tracking issue for this feature is: [#66079] deny_since: None, }, Lint { - label: "repr128", - description: r##"# `repr128` + label: "register_tool", + description: r##"# `register_tool` -The tracking issue for this feature is: [#56071] +The tracking issue for this feature is: [#66079] -[#56071]: https://github.com/rust-lang/rust/issues/56071 +[#66079]: https://github.com/rust-lang/rust/issues/66079 ------------------------ -The `repr128` feature adds support for `#[repr(u128)]` on `enum`s. +The `register_tool` language feature informs the compiler that attributes in your code are meant to be used with tools other than the compiler itself. This can be useful if your code has semantic meaning without the external tool, but enables additional features when the tool is present. -```rust -#![feature(repr128)] +`register_tool` also allows configuring lint levels for external tools. -#[repr(u128)] -enum Foo { - Bar(u64), +Tool attributes are only meant for ignorable attributes. If your code *changes* meaning when the attribute is present, it should not use a tool attribute (because it cannot be compiled with anything other than the external tool, and in a sense is a fork of the language). + +------------------------ + +`#![register_tool(tool)]` is an attribute, and is only valid at the crate root. +Attributes using the registered tool are checked for valid syntax, and lint attributes are checked to be in a valid format. However, the compiler cannot validate the semantics of the attribute, nor can it tell whether the configured lint is present in the external tool. + +Semantically, `clippy::*`, `rustdoc::*`, and `rustfmt::*` lints and attributes all behave as if `#![register_tool(clippy, rustdoc, rustfmt)]` were injected into the crate root, except that the `rustdoc` namespace can only be used for lints, not for attributes. +When compiling with `-Z unstable-features`, `rustc::*` lints can also be used. Like `rustdoc`, the `rustc` namespace can only be used with lints, not attributes. + +The compiler will emit an error if it encounters a lint/attribute whose namespace isn't a registered tool. + +Tool namespaces cannot be nested; `register_tool(main_tool::subtool)` is an error. + +## Examples + +Tool attributes: + +```rust +#![feature(register_tool)] +#![register_tool(c2rust)] + +// Mark which C header file this module was generated from. +#[c2rust::header_src = "operations.h"] +pub mod operations_h { + use std::ffi::c_int; + + // Mark which source line this struct was generated from. + #[c2rust::src_loc = "11:0"] + pub struct Point { + pub x: c_int, + pub y: c_int, + } } ``` + +Tool lints: + +``` +#![feature(register_tool)] +#![register_tool(bevy)] +#![deny(bevy::duplicate_bevy_dependencies)] +``` "##, default_severity: Severity::Allow, warn_since: None, @@ -9733,6 +12826,8 @@ enum Foo { label: "repr_simd", description: r##"# `repr_simd` +Allows `repr(simd)` and importing the various simd intrinsics. + The tracking issue for this feature is: [#27731] [#27731]: https://github.com/rust-lang/rust/issues/27731 @@ -9747,6 +12842,8 @@ The tracking issue for this feature is: [#27731] label: "restricted_std", description: r##"# `restricted_std` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -9756,12 +12853,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "result_flattening", - description: r##"# `result_flattening` + label: "result_option_map_or_default", + description: r##"# `result_option_map_or_default` + + -The tracking issue for this feature is: [#70142] +The tracking issue for this feature is: [#138099] -[#70142]: https://github.com/rust-lang/rust/issues/70142 +[#138099]: https://github.com/rust-lang/rust/issues/138099 ------------------------ "##, @@ -9773,6 +12872,8 @@ The tracking issue for this feature is: [#70142] label: "return_type_notation", description: r##"# `return_type_notation` +Allows bounding the return type of AFIT/RPITIT. + The tracking issue for this feature is: [#109417] [#109417]: https://github.com/rust-lang/rust/issues/109417 @@ -9784,12 +12885,14 @@ The tracking issue for this feature is: [#109417] deny_since: None, }, Lint { - label: "riscv_target_feature", - description: r##"# `riscv_target_feature` + label: "rev_into_inner", + description: r##"# `rev_into_inner` + -The tracking issue for this feature is: [#44839] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#144277] + +[#144277]: https://github.com/rust-lang/rust/issues/144277 ------------------------ "##, @@ -9798,12 +12901,14 @@ The tracking issue for this feature is: [#44839] deny_since: None, }, Lint { - label: "round_char_boundary", - description: r##"# `round_char_boundary` + label: "riscv_target_feature", + description: r##"# `riscv_target_feature` + +Target features on riscv. -The tracking issue for this feature is: [#93743] +The tracking issue for this feature is: [#150257] -[#93743]: https://github.com/rust-lang/rust/issues/93743 +[#150257]: https://github.com/rust-lang/rust/issues/150257 ------------------------ "##, @@ -9827,9 +12932,11 @@ This feature is internal to the Rust compiler and is not intended for general us label: "rtm_target_feature", description: r##"# `rtm_target_feature` -The tracking issue for this feature is: [#44839] +The rtm target feature on x86. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150258] + +[#150258]: https://github.com/rust-lang/rust/issues/150258 ------------------------ "##, @@ -9841,6 +12948,8 @@ The tracking issue for this feature is: [#44839] label: "rust_cold_cc", description: r##"# `rust_cold_cc` +Allows `extern "rust-cold"`. + The tracking issue for this feature is: [#97544] [#97544]: https://github.com/rust-lang/rust/issues/97544 @@ -9852,12 +12961,14 @@ The tracking issue for this feature is: [#97544] deny_since: None, }, Lint { - label: "rustc_allow_const_fn_unstable", - description: r##"# `rustc_allow_const_fn_unstable` + label: "rust_preserve_none_cc", + description: r##"# `rust_preserve_none_cc` -The tracking issue for this feature is: [#69399] +Allows `extern "rust-preserve-none"`. -[#69399]: https://github.com/rust-lang/rust/issues/69399 +The tracking issue for this feature is: [#151401] + +[#151401]: https://github.com/rust-lang/rust/issues/151401 ------------------------ "##, @@ -9926,18 +13037,6 @@ error: aborting due to 2 previous errors deny_since: None, }, Lint { - label: "rustc_encodable_decodable", - description: r##"# `rustc_encodable_decodable` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { label: "rustc_private", description: r##"# `rustc_private` @@ -9947,9 +13046,42 @@ The tracking issue for this feature is: [#27812] ------------------------ -This feature allows access to unstable internal compiler crates. +This feature allows access to unstable internal compiler crates such as `rustc_driver`. + +The presence of this feature changes the way the linkage format for dylibs is calculated in a way +that is necessary for linking against dylibs that statically link `std` (such as `rustc_driver`). +This makes this feature "viral" in linkage; its use in a given crate makes its use required in +dependent crates which link to it (including integration tests, which are built as separate crates). + +## Common linker failures related to missing LLVM libraries + +### When using `rustc-private` with Official Toolchains + +When using the `rustc_private` feature with official toolchains distributed via rustup, you'll need to install: + +1. The `rustc-dev` component (provides compiler libraries) +2. The `llvm-tools` component (provides LLVM libraries needed for linking) + +You can install these components using `rustup`: + +```text +rustup component add rustc-dev llvm-tools +``` + +Without the `llvm-tools` component, you may encounter linking errors like: + +```text +error: linking with `cc` failed: exit status: 1 + | + = note: rust-lld: error: unable to find library -lLLVM-{version} +``` + +### When using `rustc-private` with Custom Toolchains -Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`. +For custom-built toolchains or environments not using rustup, different configuration may be required: + +- Ensure LLVM libraries are available in your library search paths +- You might need to configure library paths explicitly depending on your LLVM installation "##, default_severity: Severity::Allow, warn_since: None, @@ -9959,6 +13091,8 @@ Additionally it changes the linking behavior of crates which have this feature e label: "rustdoc_internals", description: r##"# `rustdoc_internals` +Allows using internal rustdoc features like `doc(keyword)`. + The tracking issue for this feature is: [#90418] [#90418]: https://github.com/rust-lang/rust/issues/90418 @@ -9973,6 +13107,8 @@ The tracking issue for this feature is: [#90418] label: "rustdoc_missing_doc_code_examples", description: r##"# `rustdoc_missing_doc_code_examples` +Allows using the `rustdoc::missing_doc_code_examples` lint + The tracking issue for this feature is: [#101730] [#101730]: https://github.com/rust-lang/rust/issues/101730 @@ -9984,12 +13120,14 @@ The tracking issue for this feature is: [#101730] deny_since: None, }, Lint { - label: "rwlock_downgrade", - description: r##"# `rwlock_downgrade` + label: "rwlock_data_ptr", + description: r##"# `rwlock_data_ptr` + -The tracking issue for this feature is: [#128203] -[#128203]: https://github.com/rust-lang/rust/issues/128203 +The tracking issue for this feature is: [#140368] + +[#140368]: https://github.com/rust-lang/rust/issues/140368 ------------------------ "##, @@ -10001,9 +13139,11 @@ The tracking issue for this feature is: [#128203] label: "s390x_target_feature", description: r##"# `s390x_target_feature` -The tracking issue for this feature is: [#44839] +Target features on s390x. + +The tracking issue for this feature is: [#150259] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#150259]: https://github.com/rust-lang/rust/issues/150259 ------------------------ "##, @@ -10012,9 +13152,91 @@ The tracking issue for this feature is: [#44839] deny_since: None, }, Lint { + label: "sanitize", + description: r##"# `sanitize` + +The tracking issue for this feature is: [#39699] + +[#39699]: https://github.com/rust-lang/rust/issues/39699 + +------------------------ + +The `sanitize` attribute can be used to selectively disable or enable sanitizer +instrumentation in an annotated function. This might be useful to: avoid +instrumentation overhead in a performance critical function, or avoid +instrumenting code that contains constructs unsupported by given sanitizer. + +The precise effect of this annotation depends on particular sanitizer in use. +For example, with `sanitize(thread = "off")`, the thread sanitizer will no +longer instrument non-atomic store / load operations, but it will instrument +atomic operations to avoid reporting false positives and provide meaning full +stack traces. + +This attribute was previously named `no_sanitize`. + +## Examples + +``` rust +#![feature(sanitize)] + +#[sanitize(address = "off")] +fn foo() { + // ... +} +``` + +It is also possible to disable sanitizers for entire modules and enable them +for single items or functions. + +```rust +#![feature(sanitize)] + +#[sanitize(address = "off")] +mod foo { + fn unsanitized() { + // ... + } + + #[sanitize(address = "on")] + fn sanitized() { + // ... + } +} +``` + +It's also applicable to impl blocks. + +```rust +#![feature(sanitize)] + +trait MyTrait { + fn foo(&self); + fn bar(&self); +} + +#[sanitize(address = "off")] +impl MyTrait for () { + fn foo(&self) { + // ... + } + + #[sanitize(address = "on")] + fn bar(&self) { + // ... + } +} +``` +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "sealed", description: r##"# `sealed` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -10024,9 +13246,27 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { + label: "seek_io_take_position", + description: r##"# `seek_io_take_position` + + + +The tracking issue for this feature is: [#97227] + +[#97227]: https://github.com/rust-lang/rust/issues/97227 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "seek_stream_len", description: r##"# `seek_stream_len` + + The tracking issue for this feature is: [#59359] [#59359]: https://github.com/rust-lang/rust/issues/59359 @@ -10038,9 +13278,27 @@ The tracking issue for this feature is: [#59359] deny_since: None, }, Lint { + label: "set_permissions_nofollow", + description: r##"# `set_permissions_nofollow` + + + +The tracking issue for this feature is: [#141607] + +[#141607]: https://github.com/rust-lang/rust/issues/141607 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "set_ptr_value", description: r##"# `set_ptr_value` + + The tracking issue for this feature is: [#75091] [#75091]: https://github.com/rust-lang/rust/issues/75091 @@ -10055,6 +13313,8 @@ The tracking issue for this feature is: [#75091] label: "setgroups", description: r##"# `setgroups` + + The tracking issue for this feature is: [#90747] [#90747]: https://github.com/rust-lang/rust/issues/90747 @@ -10069,6 +13329,8 @@ The tracking issue for this feature is: [#90747] label: "sgx_platform", description: r##"# `sgx_platform` + + The tracking issue for this feature is: [#56975] [#56975]: https://github.com/rust-lang/rust/issues/56975 @@ -10080,12 +13342,14 @@ The tracking issue for this feature is: [#56975] deny_since: None, }, Lint { - label: "sha512_sm_x86", - description: r##"# `sha512_sm_x86` + label: "signed_bigint_helpers", + description: r##"# `signed_bigint_helpers` -The tracking issue for this feature is: [#126624] -[#126624]: https://github.com/rust-lang/rust/issues/126624 + +The tracking issue for this feature is: [#151989] + +[#151989]: https://github.com/rust-lang/rust/issues/151989 ------------------------ "##, @@ -10097,6 +13361,8 @@ The tracking issue for this feature is: [#126624] label: "simd_ffi", description: r##"# `simd_ffi` +Allows the use of SIMD types in functions declared in `extern` blocks. + The tracking issue for this feature is: [#27731] [#27731]: https://github.com/rust-lang/rust/issues/27731 @@ -10108,24 +13374,14 @@ The tracking issue for this feature is: [#27731] deny_since: None, }, Lint { - label: "sized_type_properties", - description: r##"# `sized_type_properties` - -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + label: "sized_hierarchy", + description: r##"# `sized_hierarchy` ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "slice_as_array", - description: r##"# `slice_as_array` +Introduces a hierarchy of `Sized` traits (RFC 3729). -The tracking issue for this feature is: [#133508] +The tracking issue for this feature is: [#144404] -[#133508]: https://github.com/rust-lang/rust/issues/133508 +[#144404]: https://github.com/rust-lang/rust/issues/144404 ------------------------ "##, @@ -10134,12 +13390,12 @@ The tracking issue for this feature is: [#133508] deny_since: None, }, Lint { - label: "slice_as_chunks", - description: r##"# `slice_as_chunks` + label: "sized_type_properties", + description: r##"# `sized_type_properties` -The tracking issue for this feature is: [#74985] -[#74985]: https://github.com/rust-lang/rust/issues/74985 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -10151,6 +13407,8 @@ The tracking issue for this feature is: [#74985] label: "slice_concat_ext", description: r##"# `slice_concat_ext` + + The tracking issue for this feature is: [#27747] [#27747]: https://github.com/rust-lang/rust/issues/27747 @@ -10165,6 +13423,8 @@ The tracking issue for this feature is: [#27747] label: "slice_concat_trait", description: r##"# `slice_concat_trait` + + The tracking issue for this feature is: [#27747] [#27747]: https://github.com/rust-lang/rust/issues/27747 @@ -10179,6 +13439,8 @@ The tracking issue for this feature is: [#27747] label: "slice_from_ptr_range", description: r##"# `slice_from_ptr_range` + + The tracking issue for this feature is: [#89792] [#89792]: https://github.com/rust-lang/rust/issues/89792 @@ -10193,6 +13455,8 @@ The tracking issue for this feature is: [#89792] label: "slice_index_methods", description: r##"# `slice_index_methods` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -10205,6 +13469,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "slice_internals", description: r##"# `slice_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -10217,6 +13483,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "slice_iter_mut_as_mut_slice", description: r##"# `slice_iter_mut_as_mut_slice` + + The tracking issue for this feature is: [#93079] [#93079]: https://github.com/rust-lang/rust/issues/93079 @@ -10228,9 +13496,27 @@ The tracking issue for this feature is: [#93079] deny_since: None, }, Lint { + label: "slice_partial_sort_unstable", + description: r##"# `slice_partial_sort_unstable` + + + +The tracking issue for this feature is: [#149046] + +[#149046]: https://github.com/rust-lang/rust/issues/149046 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "slice_partition_dedup", description: r##"# `slice_partition_dedup` + + The tracking issue for this feature is: [#54279] [#54279]: https://github.com/rust-lang/rust/issues/54279 @@ -10245,6 +13531,8 @@ The tracking issue for this feature is: [#54279] label: "slice_pattern", description: r##"# `slice_pattern` + + The tracking issue for this feature is: [#56345] [#56345]: https://github.com/rust-lang/rust/issues/56345 @@ -10259,6 +13547,8 @@ The tracking issue for this feature is: [#56345] label: "slice_ptr_get", description: r##"# `slice_ptr_get` + + The tracking issue for this feature is: [#74265] [#74265]: https://github.com/rust-lang/rust/issues/74265 @@ -10273,6 +13563,8 @@ The tracking issue for this feature is: [#74265] label: "slice_range", description: r##"# `slice_range` + + The tracking issue for this feature is: [#76393] [#76393]: https://github.com/rust-lang/rust/issues/76393 @@ -10284,9 +13576,27 @@ The tracking issue for this feature is: [#76393] deny_since: None, }, Lint { + label: "slice_shift", + description: r##"# `slice_shift` + + + +The tracking issue for this feature is: [#151772] + +[#151772]: https://github.com/rust-lang/rust/issues/151772 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "slice_split_once", description: r##"# `slice_split_once` + + The tracking issue for this feature is: [#112811] [#112811]: https://github.com/rust-lang/rust/issues/112811 @@ -10301,6 +13611,8 @@ The tracking issue for this feature is: [#112811] label: "slice_swap_unchecked", description: r##"# `slice_swap_unchecked` + + The tracking issue for this feature is: [#88539] [#88539]: https://github.com/rust-lang/rust/issues/88539 @@ -10312,12 +13624,30 @@ The tracking issue for this feature is: [#88539] deny_since: None, }, Lint { - label: "slice_take", - description: r##"# `slice_take` + label: "sliceindex_wrappers", + description: r##"# `sliceindex_wrappers` + + + +The tracking issue for this feature is: [#146179] + +[#146179]: https://github.com/rust-lang/rust/issues/146179 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "smart_pointer_try_map", + description: r##"# `smart_pointer_try_map` + + -The tracking issue for this feature is: [#62280] +The tracking issue for this feature is: [#144419] -[#62280]: https://github.com/rust-lang/rust/issues/62280 +[#144419]: https://github.com/rust-lang/rust/issues/144419 ------------------------ "##, @@ -10329,6 +13659,8 @@ The tracking issue for this feature is: [#62280] label: "solid_ext", description: r##"# `solid_ext` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -10341,6 +13673,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "sort_floats", description: r##"# `sort_floats` + + The tracking issue for this feature is: [#93396] [#93396]: https://github.com/rust-lang/rust/issues/93396 @@ -10355,6 +13689,8 @@ The tracking issue for this feature is: [#93396] label: "sparc_target_feature", description: r##"# `sparc_target_feature` +Target features on sparc. + The tracking issue for this feature is: [#132783] [#132783]: https://github.com/rust-lang/rust/issues/132783 @@ -10369,6 +13705,8 @@ The tracking issue for this feature is: [#132783] label: "specialization", description: r##"# `specialization` +Allows specialization of implementations (RFC 1210). + The tracking issue for this feature is: [#31844] [#31844]: https://github.com/rust-lang/rust/issues/31844 @@ -10383,6 +13721,8 @@ The tracking issue for this feature is: [#31844] label: "split_array", description: r##"# `split_array` + + The tracking issue for this feature is: [#90091] [#90091]: https://github.com/rust-lang/rust/issues/90091 @@ -10397,6 +13737,8 @@ The tracking issue for this feature is: [#90091] label: "split_as_slice", description: r##"# `split_as_slice` + + The tracking issue for this feature is: [#96137] [#96137]: https://github.com/rust-lang/rust/issues/96137 @@ -10408,12 +13750,12 @@ The tracking issue for this feature is: [#96137] deny_since: None, }, Lint { - label: "sse4a_target_feature", - description: r##"# `sse4a_target_feature` + label: "staged_api", + description: r##"# `staged_api` -The tracking issue for this feature is: [#44839] +Allows using the `#[stable]` and `#[unstable]` attributes. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -10422,10 +13764,14 @@ The tracking issue for this feature is: [#44839] deny_since: None, }, Lint { - label: "staged_api", - description: r##"# `staged_api` + label: "static_align", + description: r##"# `static_align` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +Allows using `#[rustc_align_static(...)]` on static items. + +The tracking issue for this feature is: [#146177] + +[#146177]: https://github.com/rust-lang/rust/issues/146177 ------------------------ "##, @@ -10434,74 +13780,56 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "start", - description: r##"# `start` - -The tracking issue for this feature is: [#29633] - -[#29633]: https://github.com/rust-lang/rust/issues/29633 - ------------------------- + label: "std_internals", + description: r##"# `std_internals` -Allows you to mark a function as the entry point of the executable, which is -necessary in `#![no_std]` environments. -The function marked `#[start]` is passed the command line parameters in the same -format as the C main function (aside from the integer types being used). -It has to be non-generic and have the following signature: -```rust,ignore (only-for-syntax-highlight) -# let _: -fn(isize, *const *const u8) -> isize -# ; -``` +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. -This feature should not be confused with the `start` *lang item* which is -defined by the `std` crate and is written `#[lang = "start"]`. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "stdarch_aarch64_feature_detection", + description: r##"# `stdarch_aarch64_feature_detection` -## Usage together with the `std` crate -`#[start]` can be used in combination with the `std` crate, in which case the -normal `main` function (which would get called from the `std` crate) won't be -used as an entry point. -The initialization code in `std` will be skipped this way. -Example: +The tracking issue for this feature is: [#127764] -```rust -#![feature(start)] +[#127764]: https://github.com/rust-lang/rust/issues/127764 -#[start] -fn start(_argc: isize, _argv: *const *const u8) -> isize { - 0 -} -``` +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "stdarch_arm_feature_detection", + description: r##"# `stdarch_arm_feature_detection` -Unwinding the stack past the `#[start]` function is currently considered -Undefined Behavior (for any unwinding implementation): -```rust,ignore (UB) -#![feature(start)] -#[start] -fn start(_argc: isize, _argv: *const *const u8) -> isize { - std::panic::catch_unwind(|| { - panic!(); // panic safely gets caught or safely aborts execution - }); +The tracking issue for this feature is: [#111190] - panic!(); // UB! +[#111190]: https://github.com/rust-lang/rust/issues/111190 - 0 -} -``` +------------------------ "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "std_internals", - description: r##"# `std_internals` + label: "stdarch_internal", + description: r##"# `stdarch_internal` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -10512,12 +13840,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "stdarch_arm_feature_detection", - description: r##"# `stdarch_arm_feature_detection` + label: "stdarch_loongarch_feature_detection", + description: r##"# `stdarch_loongarch_feature_detection` -The tracking issue for this feature is: [#111190] -[#111190]: https://github.com/rust-lang/rust/issues/111190 + +The tracking issue for this feature is: [#117425] + +[#117425]: https://github.com/rust-lang/rust/issues/117425 ------------------------ "##, @@ -10529,6 +13859,8 @@ The tracking issue for this feature is: [#111190] label: "stdarch_mips_feature_detection", description: r##"# `stdarch_mips_feature_detection` + + The tracking issue for this feature is: [#111188] [#111188]: https://github.com/rust-lang/rust/issues/111188 @@ -10543,6 +13875,8 @@ The tracking issue for this feature is: [#111188] label: "stdarch_powerpc_feature_detection", description: r##"# `stdarch_powerpc_feature_detection` + + The tracking issue for this feature is: [#111191] [#111191]: https://github.com/rust-lang/rust/issues/111191 @@ -10554,9 +13888,43 @@ The tracking issue for this feature is: [#111191] deny_since: None, }, Lint { + label: "stdarch_riscv_feature_detection", + description: r##"# `stdarch_riscv_feature_detection` + + + +The tracking issue for this feature is: [#111192] + +[#111192]: https://github.com/rust-lang/rust/issues/111192 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "stdio_fd_consts", + description: r##"# `stdio_fd_consts` + + + +The tracking issue for this feature is: [#150836] + +[#150836]: https://github.com/rust-lang/rust/issues/150836 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "stdio_makes_pipe", description: r##"# `stdio_makes_pipe` + + The tracking issue for this feature is: [#98288] [#98288]: https://github.com/rust-lang/rust/issues/98288 @@ -10568,9 +13936,27 @@ The tracking issue for this feature is: [#98288] deny_since: None, }, Lint { + label: "stdio_swap", + description: r##"# `stdio_swap` + + + +The tracking issue for this feature is: [#150667] + +[#150667]: https://github.com/rust-lang/rust/issues/150667 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "step_trait", description: r##"# `step_trait` + + The tracking issue for this feature is: [#42168] [#42168]: https://github.com/rust-lang/rust/issues/42168 @@ -10585,6 +13971,8 @@ The tracking issue for this feature is: [#42168] label: "stmt_expr_attributes", description: r##"# `stmt_expr_attributes` +Allows attributes on expressions and non-item statements. + The tracking issue for this feature is: [#15701] [#15701]: https://github.com/rust-lang/rust/issues/15701 @@ -10599,6 +13987,8 @@ The tracking issue for this feature is: [#15701] label: "str_as_str", description: r##"# `str_as_str` + + The tracking issue for this feature is: [#130366] [#130366]: https://github.com/rust-lang/rust/issues/130366 @@ -10613,6 +14003,8 @@ The tracking issue for this feature is: [#130366] label: "str_from_raw_parts", description: r##"# `str_from_raw_parts` + + The tracking issue for this feature is: [#119206] [#119206]: https://github.com/rust-lang/rust/issues/119206 @@ -10627,6 +14019,8 @@ The tracking issue for this feature is: [#119206] label: "str_from_utf16_endian", description: r##"# `str_from_utf16_endian` + + The tracking issue for this feature is: [#116258] [#116258]: https://github.com/rust-lang/rust/issues/116258 @@ -10653,6 +14047,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "str_lines_remainder", description: r##"# `str_lines_remainder` + + The tracking issue for this feature is: [#77998] [#77998]: https://github.com/rust-lang/rust/issues/77998 @@ -10667,6 +14063,8 @@ The tracking issue for this feature is: [#77998] label: "str_split_inclusive_remainder", description: r##"# `str_split_inclusive_remainder` + + The tracking issue for this feature is: [#77998] [#77998]: https://github.com/rust-lang/rust/issues/77998 @@ -10681,6 +14079,8 @@ The tracking issue for this feature is: [#77998] label: "str_split_remainder", description: r##"# `str_split_remainder` + + The tracking issue for this feature is: [#77998] [#77998]: https://github.com/rust-lang/rust/issues/77998 @@ -10695,23 +14095,11 @@ The tracking issue for this feature is: [#77998] label: "str_split_whitespace_remainder", description: r##"# `str_split_whitespace_remainder` -The tracking issue for this feature is: [#77998] - -[#77998]: https://github.com/rust-lang/rust/issues/77998 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "strict_provenance_atomic_ptr", - description: r##"# `strict_provenance_atomic_ptr` -The tracking issue for this feature is: [#99108] +The tracking issue for this feature is: [#77998] -[#99108]: https://github.com/rust-lang/rust/issues/99108 +[#77998]: https://github.com/rust-lang/rust/issues/77998 ------------------------ "##, @@ -10748,64 +14136,46 @@ fn main() { deny_since: None, }, Lint { - label: "string_deref_patterns", - description: r##"# `string_deref_patterns` + label: "string_from_utf8_lossy_owned", + description: r##"# `string_from_utf8_lossy_owned` -The tracking issue for this feature is: [#87121] -[#87121]: https://github.com/rust-lang/rust/issues/87121 ------------------------- +The tracking issue for this feature is: [#129436] -This feature permits pattern matching `String` to `&str` through [its `Deref` implementation]. +[#129436]: https://github.com/rust-lang/rust/issues/129436 -```rust -#![feature(string_deref_patterns)] +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "string_into_chars", + description: r##"# `string_into_chars` -pub enum Value { - String(String), - Number(u32), -} -pub fn is_it_the_answer(value: Value) -> bool { - match value { - Value::String("42") => true, - Value::Number(42) => true, - _ => false, - } -} -``` -Without this feature other constructs such as match guards have to be used. +The tracking issue for this feature is: [#133125] -```rust -# pub enum Value { -# String(String), -# Number(u32), -# } -# -pub fn is_it_the_answer(value: Value) -> bool { - match value { - Value::String(s) if s == "42" => true, - Value::Number(42) => true, - _ => false, - } -} -``` +[#133125]: https://github.com/rust-lang/rust/issues/133125 -[its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String +------------------------ "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "string_extend_from_within", - description: r##"# `string_extend_from_within` + label: "string_remove_matches", + description: r##"# `string_remove_matches` -The tracking issue for this feature is: [#103806] -[#103806]: https://github.com/rust-lang/rust/issues/103806 + +The tracking issue for this feature is: [#72826] + +[#72826]: https://github.com/rust-lang/rust/issues/72826 ------------------------ "##, @@ -10814,12 +14184,14 @@ The tracking issue for this feature is: [#103806] deny_since: None, }, Lint { - label: "string_from_utf8_lossy_owned", - description: r##"# `string_from_utf8_lossy_owned` + label: "string_replace_in_place", + description: r##"# `string_replace_in_place` -The tracking issue for this feature is: [#129436] -[#129436]: https://github.com/rust-lang/rust/issues/129436 + +The tracking issue for this feature is: [#147949] + +[#147949]: https://github.com/rust-lang/rust/issues/147949 ------------------------ "##, @@ -10828,12 +14200,14 @@ The tracking issue for this feature is: [#129436] deny_since: None, }, Lint { - label: "string_remove_matches", - description: r##"# `string_remove_matches` + label: "strip_circumfix", + description: r##"# `strip_circumfix` -The tracking issue for this feature is: [#72826] -[#72826]: https://github.com/rust-lang/rust/issues/72826 + +The tracking issue for this feature is: [#147946] + +[#147946]: https://github.com/rust-lang/rust/issues/147946 ------------------------ "##, @@ -10845,6 +14219,8 @@ The tracking issue for this feature is: [#72826] label: "structural_match", description: r##"# `structural_match` +Allows using `#[structural_match]` which indicates that a type is structurally matchable. FIXME: Subsumed by trait `StructuralPartialEq`, cannot move to removed until a library feature with the same name exists. + The tracking issue for this feature is: [#31434] [#31434]: https://github.com/rust-lang/rust/issues/31434 @@ -10859,6 +14235,8 @@ The tracking issue for this feature is: [#31434] label: "substr_range", description: r##"# `substr_range` + + The tracking issue for this feature is: [#126769] [#126769]: https://github.com/rust-lang/rust/issues/126769 @@ -10870,12 +14248,14 @@ The tracking issue for this feature is: [#126769] deny_since: None, }, Lint { - label: "sync_unsafe_cell", - description: r##"# `sync_unsafe_cell` + label: "super_let", + description: r##"# `super_let` -The tracking issue for this feature is: [#95439] +Allows `super let` statements. -[#95439]: https://github.com/rust-lang/rust/issues/95439 +The tracking issue for this feature is: [#139076] + +[#139076]: https://github.com/rust-lang/rust/issues/139076 ------------------------ "##, @@ -10884,12 +14264,14 @@ The tracking issue for this feature is: [#95439] deny_since: None, }, Lint { - label: "target_feature_11", - description: r##"# `target_feature_11` + label: "supertrait_item_shadowing", + description: r##"# `supertrait_item_shadowing` -The tracking issue for this feature is: [#69098] +Allows subtrait items to shadow supertrait items. -[#69098]: https://github.com/rust-lang/rust/issues/69098 +The tracking issue for this feature is: [#89151] + +[#89151]: https://github.com/rust-lang/rust/issues/89151 ------------------------ "##, @@ -10898,12 +14280,62 @@ The tracking issue for this feature is: [#69098] deny_since: None, }, Lint { - label: "tbm_target_feature", - description: r##"# `tbm_target_feature` + label: "sync_nonpoison", + description: r##"# `sync_nonpoison` + -The tracking issue for this feature is: [#44839] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#134645] + +[#134645]: https://github.com/rust-lang/rust/issues/134645 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "sync_poison_mod", + description: r##"# `sync_poison_mod` + + + +The tracking issue for this feature is: [#134646] + +[#134646]: https://github.com/rust-lang/rust/issues/134646 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "sync_unsafe_cell", + description: r##"# `sync_unsafe_cell` + + + +The tracking issue for this feature is: [#95439] + +[#95439]: https://github.com/rust-lang/rust/issues/95439 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "target_feature_inline_always", + description: r##"# `target_feature_inline_always` + +Allows the use of target_feature when a function is marked inline(always). + +The tracking issue for this feature is: [#145574] + +[#145574]: https://github.com/rust-lang/rust/issues/145574 ------------------------ "##, @@ -10915,6 +14347,8 @@ The tracking issue for this feature is: [#44839] label: "tcp_deferaccept", description: r##"# `tcp_deferaccept` + + The tracking issue for this feature is: [#119639] [#119639]: https://github.com/rust-lang/rust/issues/119639 @@ -10929,6 +14363,8 @@ The tracking issue for this feature is: [#119639] label: "tcp_linger", description: r##"# `tcp_linger` + + The tracking issue for this feature is: [#88494] [#88494]: https://github.com/rust-lang/rust/issues/88494 @@ -10940,12 +14376,14 @@ The tracking issue for this feature is: [#88494] deny_since: None, }, Lint { - label: "tcp_quickack", - description: r##"# `tcp_quickack` + label: "tcplistener_into_incoming", + description: r##"# `tcplistener_into_incoming` + + -The tracking issue for this feature is: [#96256] +The tracking issue for this feature is: [#88373] -[#96256]: https://github.com/rust-lang/rust/issues/96256 +[#88373]: https://github.com/rust-lang/rust/issues/88373 ------------------------ "##, @@ -10954,12 +14392,12 @@ The tracking issue for this feature is: [#96256] deny_since: None, }, Lint { - label: "tcplistener_into_incoming", - description: r##"# `tcplistener_into_incoming` + label: "temporary_niche_types", + description: r##"# `temporary_niche_types` -The tracking issue for this feature is: [#88373] -[#88373]: https://github.com/rust-lang/rust/issues/88373 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -11133,9 +14571,25 @@ even when using either of the above. deny_since: None, }, Lint { + label: "test_incomplete_feature", + description: r##"# `test_incomplete_feature` + +Perma-unstable, only used to test the `incomplete_features` lint. + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "test_unstable_lint", description: r##"# `test_unstable_lint` +Added for testing unstable lints; perma-unstable. + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -11148,6 +14602,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "thin_box", description: r##"# `thin_box` + + The tracking issue for this feature is: [#92791] [#92791]: https://github.com/rust-lang/rust/issues/92791 @@ -11162,6 +14618,8 @@ The tracking issue for this feature is: [#92791] label: "thread_id_value", description: r##"# `thread_id_value` + + The tracking issue for this feature is: [#67939] [#67939]: https://github.com/rust-lang/rust/issues/67939 @@ -11176,6 +14634,8 @@ The tracking issue for this feature is: [#67939] label: "thread_local", description: r##"# `thread_local` +Allows using `#[thread_local]` on `static` items. + The tracking issue for this feature is: [#29594] [#29594]: https://github.com/rust-lang/rust/issues/29594 @@ -11202,6 +14662,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "thread_raw", description: r##"# `thread_raw` + + The tracking issue for this feature is: [#97523] [#97523]: https://github.com/rust-lang/rust/issues/97523 @@ -11216,6 +14678,8 @@ The tracking issue for this feature is: [#97523] label: "thread_sleep_until", description: r##"# `thread_sleep_until` + + The tracking issue for this feature is: [#113752] [#113752]: https://github.com/rust-lang/rust/issues/113752 @@ -11230,6 +14694,8 @@ The tracking issue for this feature is: [#113752] label: "thread_spawn_hook", description: r##"# `thread_spawn_hook` + + The tracking issue for this feature is: [#132951] [#132951]: https://github.com/rust-lang/rust/issues/132951 @@ -11241,6 +14707,54 @@ The tracking issue for this feature is: [#132951] deny_since: None, }, Lint { + label: "time_saturating_systemtime", + description: r##"# `time_saturating_systemtime` + + + +The tracking issue for this feature is: [#151199] + +[#151199]: https://github.com/rust-lang/rust/issues/151199 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "time_systemtime_limits", + description: r##"# `time_systemtime_limits` + + + +The tracking issue for this feature is: [#149067] + +[#149067]: https://github.com/rust-lang/rust/issues/149067 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "titlecase", + description: r##"# `titlecase` + + + +The tracking issue for this feature is: [#153892] + +[#153892]: https://github.com/rust-lang/rust/issues/153892 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "trace_macros", description: r##"# `trace_macros` @@ -11287,20 +14801,6 @@ note: trace_macro deny_since: None, }, Lint { - label: "track_path", - description: r##"# `track_path` - -The tracking issue for this feature is: [#99515] - -[#99515]: https://github.com/rust-lang/rust/issues/99515 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { label: "trait_alias", description: r##"# `trait_alias` @@ -11342,42 +14842,11 @@ pub fn main() { deny_since: None, }, Lint { - label: "trait_upcasting", - description: r##"# `trait_upcasting` - -The tracking issue for this feature is: [#65991] - -[#65991]: https://github.com/rust-lang/rust/issues/65991 - ------------------------- - -The `trait_upcasting` feature adds support for trait upcasting coercion. This allows a -trait object of type `dyn Bar` to be cast to a trait object of type `dyn Foo` -so long as `Bar: Foo`. - -```rust,edition2018 -#![feature(trait_upcasting)] - -trait Foo {} - -trait Bar: Foo {} - -impl Foo for i32 {} - -impl<T: Foo + ?Sized> Bar for T {} - -let bar: &dyn Bar = &123; -let foo: &dyn Foo = bar; -``` -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { label: "transmutability", description: r##"# `transmutability` + + The tracking issue for this feature is: [#99571] [#99571]: https://github.com/rust-lang/rust/issues/99571 @@ -11392,6 +14861,8 @@ The tracking issue for this feature is: [#99571] label: "transmute_generic_consts", description: r##"# `transmute_generic_consts` +Allows for transmuting between arrays with sizes that contain generic consts. + The tracking issue for this feature is: [#109929] [#109929]: https://github.com/rust-lang/rust/issues/109929 @@ -11493,9 +14964,27 @@ their application of these optimizations. deny_since: None, }, Lint { + label: "trim_prefix_suffix", + description: r##"# `trim_prefix_suffix` + + + +The tracking issue for this feature is: [#142312] + +[#142312]: https://github.com/rust-lang/rust/issues/142312 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "trivial_bounds", description: r##"# `trivial_bounds` +Allows inconsistent bounds in where clauses. + The tracking issue for this feature is: [#48214] [#48214]: https://github.com/rust-lang/rust/issues/48214 @@ -11507,9 +14996,25 @@ The tracking issue for this feature is: [#48214] deny_since: None, }, Lint { + label: "trivial_clone", + description: r##"# `trivial_clone` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "trusted_fused", description: r##"# `trusted_fused` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -11522,6 +15027,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "trusted_len", description: r##"# `trusted_len` + + The tracking issue for this feature is: [#37572] [#37572]: https://github.com/rust-lang/rust/issues/37572 @@ -11536,6 +15043,8 @@ The tracking issue for this feature is: [#37572] label: "trusted_len_next_unchecked", description: r##"# `trusted_len_next_unchecked` + + The tracking issue for this feature is: [#37572] [#37572]: https://github.com/rust-lang/rust/issues/37572 @@ -11550,6 +15059,8 @@ The tracking issue for this feature is: [#37572] label: "trusted_random_access", description: r##"# `trusted_random_access` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -11562,6 +15073,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "trusted_step", description: r##"# `trusted_step` + + The tracking issue for this feature is: [#85731] [#85731]: https://github.com/rust-lang/rust/issues/85731 @@ -11573,6 +15086,22 @@ The tracking issue for this feature is: [#85731] deny_since: None, }, Lint { + label: "try_as_dyn", + description: r##"# `try_as_dyn` + + + +The tracking issue for this feature is: [#144361] + +[#144361]: https://github.com/rust-lang/rust/issues/144361 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "try_blocks", description: r##"# `try_blocks` @@ -11610,9 +15139,27 @@ assert!(result.is_err()); deny_since: None, }, Lint { + label: "try_blocks_heterogeneous", + description: r##"# `try_blocks_heterogeneous` + +Allows using `try bikeshed TargetType {...}` expressions. + +The tracking issue for this feature is: [#149488] + +[#149488]: https://github.com/rust-lang/rust/issues/149488 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "try_find", description: r##"# `try_find` + + The tracking issue for this feature is: [#63178] [#63178]: https://github.com/rust-lang/rust/issues/63178 @@ -11627,6 +15174,8 @@ The tracking issue for this feature is: [#63178] label: "try_reserve_kind", description: r##"# `try_reserve_kind` + + The tracking issue for this feature is: [#48043] [#48043]: https://github.com/rust-lang/rust/issues/48043 @@ -11641,6 +15190,8 @@ The tracking issue for this feature is: [#48043] label: "try_trait_v2", description: r##"# `try_trait_v2` + + The tracking issue for this feature is: [#84277] [#84277]: https://github.com/rust-lang/rust/issues/84277 @@ -11655,6 +15206,8 @@ The tracking issue for this feature is: [#84277] label: "try_trait_v2_residual", description: r##"# `try_trait_v2_residual` + + The tracking issue for this feature is: [#91285] [#91285]: https://github.com/rust-lang/rust/issues/91285 @@ -11669,6 +15222,8 @@ The tracking issue for this feature is: [#91285] label: "try_trait_v2_yeet", description: r##"# `try_trait_v2_yeet` + + The tracking issue for this feature is: [#96374] [#96374]: https://github.com/rust-lang/rust/issues/96374 @@ -11683,6 +15238,8 @@ The tracking issue for this feature is: [#96374] label: "try_with_capacity", description: r##"# `try_with_capacity` + + The tracking issue for this feature is: [#91913] [#91913]: https://github.com/rust-lang/rust/issues/91913 @@ -11697,6 +15254,8 @@ The tracking issue for this feature is: [#91913] label: "tuple_trait", description: r##"# `tuple_trait` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -11711,9 +15270,161 @@ This feature has no tracking issue, and is therefore likely internal to the comp The tracking issue for this feature is: [#63063] -[#63063]: https://github.com/rust-lang/rust/issues/63063 - ------------------------ + +> This feature is not to be confused with [`trait_alias`] or [`impl_trait_in_assoc_type`]. + +### What is `impl Trait`? + +`impl Trait` in return position is useful for declaring types that are constrained by traits, but whose concrete type should be hidden: + +```rust +use std::fmt::Debug; + +fn new() -> impl Debug { + 42 +} + +fn main() { + let thing = new(); + // What actually is a `thing`? + // No idea but we know it implements `Debug`, so we can debug print it + println!("{thing:?}"); +} +``` + +See the [reference] for more information about `impl Trait` in return position. + +### `type_alias_impl_trait` + +However, we might want to use an `impl Trait` in multiple locations but actually use the same concrete type everywhere while keeping it hidden. +This can be useful in libraries where you want to hide implementation details. + +The `#[define_opaque]` attribute must be used to explicitly list opaque items constrained by the item it's on. + +```rust +#![feature(type_alias_impl_trait)] +# #![allow(unused_variables, dead_code)] +trait Trait {} + +struct MyType; + +impl Trait for MyType {} + +type Alias = impl Trait; + +#[define_opaque(Alias)] // To constrain the type alias to `MyType` +fn new() -> Alias { + MyType +} + +#[define_opaque(Alias)] // So we can name the concrete type inside this item +fn main() { + let thing: MyType = new(); +} + +// It can be a part of a struct too +struct HaveAlias { + stuff: String, + thing: Alias, +} +``` + +In this example, the concrete type referred to by `Alias` is guaranteed to be the same wherever `Alias` occurs. + +> Originally this feature included type aliases as an associated type of a trait. In [#110237] this was split off to [`impl_trait_in_assoc_type`]. + +### `type_alias_impl_trait` in argument position. + +Note that using `Alias` as an argument type is *not* the same as argument-position `impl Trait`, as `Alias` refers to a unique type, whereas the concrete type for argument-position `impl Trait` is chosen by the caller. + +```rust +# #![feature(type_alias_impl_trait)] +# #![allow(unused_variables)] +# pub mod x { +# pub trait Trait {} +# +# struct MyType; +# +# impl Trait for MyType {} +# +# pub type Alias = impl Trait; +# +# #[define_opaque(Alias)] +# pub fn new() -> Alias { +# MyType +# } +# } +# use x::*; +// this... +pub fn take_alias(x: Alias) { + // ... +} + +// ...is *not* the same as +pub fn take_impl(x: impl Trait) { + // ... +} +# fn main(){} +``` + +```rust,compile_fail,E0308 +# #![feature(type_alias_impl_trait)] +# #![allow(unused_variables)] +# pub mod x { +# pub trait Trait {} +# +# struct MyType; +# +# impl Trait for MyType {} +# +# pub type Alias = impl Trait; +# +# #[define_opaque(Alias)] +# pub fn new() -> Alias { +# MyType +# } +# } +# use x::*; +# pub fn take_alias(x: Alias) { +# // ... +# } +# +# pub fn take_impl(x: impl Trait) { +# // ... +# } +# +// a user's crate using the trait and type alias +struct UserType; +impl Trait for UserType {} + +# fn main(){ +let x = UserType; +take_alias(x); +// ERROR expected opaque type, found `UserType` +// this function *actually* takes a `MyType` as is constrained in `new` + +let x = UserType; +take_impl(x); +// OK + +let x = new(); +take_alias(x); +// OK + +let x = new(); +take_impl(x); +// OK +# } +``` + +Note that the user cannot use `#[define_opaque(Alias)]` to reify the opaque type because only the crate where the type alias is declared may do so. But if this happened in the same crate and the opaque type was reified, they'd get a familiar error: "expected `MyType`, got `UserType`". + +[#63063]: https://github.com/rust-lang/rust/issues/63063 +[#110237]: https://github.com/rust-lang/rust/pull/110237 +[reference]: https://doc.rust-lang.org/stable/reference/types/impl-trait.html#abstract-return-types +[`trait_alias`]: ./trait-alias.md +[`impl_trait_in_assoc_type`]: ./impl-trait-in-assoc-type.md "##, default_severity: Severity::Allow, warn_since: None, @@ -11723,6 +15434,8 @@ The tracking issue for this feature is: [#63063] label: "type_ascription", description: r##"# `type_ascription` + + The tracking issue for this feature is: [#23416] [#23416]: https://github.com/rust-lang/rust/issues/23416 @@ -11774,9 +15487,27 @@ fn main () { deny_since: None, }, Lint { + label: "type_info", + description: r##"# `type_info` + + + +The tracking issue for this feature is: [#146922] + +[#146922]: https://github.com/rust-lang/rust/issues/146922 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "ub_checks", description: r##"# `ub_checks` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -11789,6 +15520,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "uefi_std", description: r##"# `uefi_std` + + The tracking issue for this feature is: [#100499] [#100499]: https://github.com/rust-lang/rust/issues/100499 @@ -11800,12 +15533,46 @@ The tracking issue for this feature is: [#100499] deny_since: None, }, Lint { - label: "unbounded_shifts", - description: r##"# `unbounded_shifts` + label: "uint_bit_width", + description: r##"# `uint_bit_width` + + + +The tracking issue for this feature is: [#142326] + +[#142326]: https://github.com/rust-lang/rust/issues/142326 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "uint_carryless_mul", + description: r##"# `uint_carryless_mul` + + + +The tracking issue for this feature is: [#152080] + +[#152080]: https://github.com/rust-lang/rust/issues/152080 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "uint_gather_scatter_bits", + description: r##"# `uint_gather_scatter_bits` + + -The tracking issue for this feature is: [#129375] +The tracking issue for this feature is: [#149069] -[#129375]: https://github.com/rust-lang/rust/issues/129375 +[#149069]: https://github.com/rust-lang/rust/issues/149069 ------------------------ "##, @@ -11849,6 +15616,8 @@ fn main() {} label: "unicode_internals", description: r##"# `unicode_internals` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -11861,6 +15630,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "unique_rc_arc", description: r##"# `unique_rc_arc` + + The tracking issue for this feature is: [#112566] [#112566]: https://github.com/rust-lang/rust/issues/112566 @@ -11875,6 +15646,8 @@ The tracking issue for this feature is: [#112566] label: "unix_file_vectored_at", description: r##"# `unix_file_vectored_at` + + The tracking issue for this feature is: [#89517] [#89517]: https://github.com/rust-lang/rust/issues/89517 @@ -11886,9 +15659,43 @@ The tracking issue for this feature is: [#89517] deny_since: None, }, Lint { + label: "unix_mkfifo", + description: r##"# `unix_mkfifo` + + + +The tracking issue for this feature is: [#139324] + +[#139324]: https://github.com/rust-lang/rust/issues/139324 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "unix_send_signal", + description: r##"# `unix_send_signal` + + + +The tracking issue for this feature is: [#141975] + +[#141975]: https://github.com/rust-lang/rust/issues/141975 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "unix_set_mark", description: r##"# `unix_set_mark` + + The tracking issue for this feature is: [#96467] [#96467]: https://github.com/rust-lang/rust/issues/96467 @@ -11903,6 +15710,8 @@ The tracking issue for this feature is: [#96467] label: "unix_socket_ancillary_data", description: r##"# `unix_socket_ancillary_data` + + The tracking issue for this feature is: [#76915] [#76915]: https://github.com/rust-lang/rust/issues/76915 @@ -11914,9 +15723,27 @@ The tracking issue for this feature is: [#76915] deny_since: None, }, Lint { + label: "unix_socket_exclbind", + description: r##"# `unix_socket_exclbind` + + + +The tracking issue for this feature is: [#123481] + +[#123481]: https://github.com/rust-lang/rust/issues/123481 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "unix_socket_peek", description: r##"# `unix_socket_peek` + + The tracking issue for this feature is: [#76923] [#76923]: https://github.com/rust-lang/rust/issues/76923 @@ -11931,7 +15758,11 @@ The tracking issue for this feature is: [#76923] label: "unqualified_local_imports", description: r##"# `unqualified_local_imports` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +Helps with formatting for `group_imports = "StdExternalCrate"`. + +The tracking issue for this feature is: [#138299] + +[#138299]: https://github.com/rust-lang/rust/issues/138299 ------------------------ "##, @@ -11940,12 +15771,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "unsafe_fields", - description: r##"# `unsafe_fields` + label: "unsafe_binders", + description: r##"# `unsafe_binders` -The tracking issue for this feature is: [#132922] +Allows using `unsafe<'a> &'a T` unsafe binder types. -[#132922]: https://github.com/rust-lang/rust/issues/132922 +The tracking issue for this feature is: [#130516] + +[#130516]: https://github.com/rust-lang/rust/issues/130516 ------------------------ "##, @@ -11954,10 +15787,14 @@ The tracking issue for this feature is: [#132922] deny_since: None, }, Lint { - label: "unsafe_pin_internals", - description: r##"# `unsafe_pin_internals` + label: "unsafe_cell_access", + description: r##"# `unsafe_cell_access` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + + +The tracking issue for this feature is: [#136327] + +[#136327]: https://github.com/rust-lang/rust/issues/136327 ------------------------ "##, @@ -11966,12 +15803,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "unsigned_is_multiple_of", - description: r##"# `unsigned_is_multiple_of` + label: "unsafe_fields", + description: r##"# `unsafe_fields` -The tracking issue for this feature is: [#128101] +Allows declaring fields `unsafe`. + +The tracking issue for this feature is: [#132922] -[#128101]: https://github.com/rust-lang/rust/issues/128101 +[#132922]: https://github.com/rust-lang/rust/issues/132922 ------------------------ "##, @@ -11980,12 +15819,14 @@ The tracking issue for this feature is: [#128101] deny_since: None, }, Lint { - label: "unsigned_nonzero_div_ceil", - description: r##"# `unsigned_nonzero_div_ceil` + label: "unsafe_pinned", + description: r##"# `unsafe_pinned` + -The tracking issue for this feature is: [#132968] -[#132968]: https://github.com/rust-lang/rust/issues/132968 +The tracking issue for this feature is: [#125735] + +[#125735]: https://github.com/rust-lang/rust/issues/125735 ------------------------ "##, @@ -11994,12 +15835,14 @@ The tracking issue for this feature is: [#132968] deny_since: None, }, Lint { - label: "unsigned_signed_diff", - description: r##"# `unsigned_signed_diff` + label: "unsafe_unpin", + description: r##"# `unsafe_unpin` + -The tracking issue for this feature is: [#126041] -[#126041]: https://github.com/rust-lang/rust/issues/126041 +The tracking issue for this feature is: [#125735] + +[#125735]: https://github.com/rust-lang/rust/issues/125735 ------------------------ "##, @@ -12011,6 +15854,8 @@ The tracking issue for this feature is: [#126041] label: "unsize", description: r##"# `unsize` + + The tracking issue for this feature is: [#18598] [#18598]: https://github.com/rust-lang/rust/issues/18598 @@ -12025,6 +15870,8 @@ The tracking issue for this feature is: [#18598] label: "unsized_const_params", description: r##"# `unsized_const_params` +Allows const generic parameters to be defined with types that are not `Sized`, e.g. `fn foo<const N: [u8]>() {`. + The tracking issue for this feature is: [#95174] [#95174]: https://github.com/rust-lang/rust/issues/95174 @@ -12039,6 +15886,8 @@ The tracking issue for this feature is: [#95174] label: "unsized_fn_params", description: r##"# `unsized_fn_params` +Allows unsized fn parameters. + The tracking issue for this feature is: [#48055] [#48055]: https://github.com/rust-lang/rust/issues/48055 @@ -12050,194 +15899,170 @@ The tracking issue for this feature is: [#48055] deny_since: None, }, Lint { - label: "unsized_locals", - description: r##"# `unsized_locals` + label: "unwrap_infallible", + description: r##"# `unwrap_infallible` -The tracking issue for this feature is: [#48055] -[#48055]: https://github.com/rust-lang/rust/issues/48055 + +The tracking issue for this feature is: [#61695] + +[#61695]: https://github.com/rust-lang/rust/issues/61695 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "update_panic_count", + description: r##"# `update_panic_count` -This implements [RFC1909]. When turned on, you can have unsized arguments and locals: +This feature is internal to the Rust compiler and is not intended for general use. -[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "used_with_arg", + description: r##"# `used_with_arg` -```rust -#![allow(incomplete_features)] -#![feature(unsized_locals, unsized_fn_params)] +Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. -use std::any::Any; +The tracking issue for this feature is: [#93798] -fn main() { - let x: Box<dyn Any> = Box::new(42); - let x: dyn Any = *x; - // ^ unsized local variable - // ^^ unsized temporary - foo(x); -} +[#93798]: https://github.com/rust-lang/rust/issues/93798 -fn foo(_: dyn Any) {} -// ^^^^^^ unsized argument -``` +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "utf16_extra", + description: r##"# `utf16_extra` -The RFC still forbids the following unsized expressions: -```rust,compile_fail -#![feature(unsized_locals)] -use std::any::Any; +The tracking issue for this feature is: [#94919] -struct MyStruct<T: ?Sized> { - content: T, -} +[#94919]: https://github.com/rust-lang/rust/issues/94919 -struct MyTupleStruct<T: ?Sized>(T); +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "variant_count", + description: r##"# `variant_count` -fn answer() -> Box<dyn Any> { - Box::new(42) -} -fn main() { - // You CANNOT have unsized statics. - static X: dyn Any = *answer(); // ERROR - const Y: dyn Any = *answer(); // ERROR - - // You CANNOT have struct initialized unsized. - MyStruct { content: *answer() }; // ERROR - MyTupleStruct(*answer()); // ERROR - (42, *answer()); // ERROR - - // You CANNOT have unsized return types. - fn my_function() -> dyn Any { *answer() } // ERROR - - // You CAN have unsized local variables... - let mut x: dyn Any = *answer(); // OK - // ...but you CANNOT reassign to them. - x = *answer(); // ERROR - - // You CANNOT even initialize them separately. - let y: dyn Any; // OK - y = *answer(); // ERROR - - // Not mentioned in the RFC, but by-move captured variables are also Sized. - let x: dyn Any = *answer(); - (move || { // ERROR - let y = x; - })(); - - // You CAN create a closure with unsized arguments, - // but you CANNOT call it. - // This is an implementation detail and may be changed in the future. - let f = |x: dyn Any| {}; - f(*answer()); // ERROR -} -``` -## By-value trait objects +The tracking issue for this feature is: [#73662] -With this feature, you can have by-value `self` arguments without `Self: Sized` bounds. +[#73662]: https://github.com/rust-lang/rust/issues/73662 -```rust -#![feature(unsized_fn_params)] +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_deque_extract_if", + description: r##"# `vec_deque_extract_if` -trait Foo { - fn foo(self) {} -} -impl<T: ?Sized> Foo for T {} -fn main() { - let slice: Box<[i32]> = Box::new([1, 2, 3]); - <[i32] as Foo>::foo(*slice); -} -``` +The tracking issue for this feature is: [#147750] -And `Foo` will also be object-safe. +[#147750]: https://github.com/rust-lang/rust/issues/147750 -```rust -#![feature(unsized_fn_params)] +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_deque_iter_as_slices", + description: r##"# `vec_deque_iter_as_slices` -trait Foo { - fn foo(self) {} -} -impl<T: ?Sized> Foo for T {} -fn main () { - let slice: Box<dyn Foo> = Box::new([1, 2, 3]); - // doesn't compile yet - <dyn Foo as Foo>::foo(*slice); -} -``` +The tracking issue for this feature is: [#123947] -One of the objectives of this feature is to allow `Box<dyn FnOnce>`. +[#123947]: https://github.com/rust-lang/rust/issues/123947 -## Variable length arrays +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_deque_truncate_front", + description: r##"# `vec_deque_truncate_front` -The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`. -```rust,ignore (not-yet-implemented) -#![feature(unsized_locals)] -fn mergesort<T: Ord>(a: &mut [T]) { - let mut tmp = [T; dyn a.len()]; - // ... -} +The tracking issue for this feature is: [#140667] -fn main() { - let mut a = [3, 1, 5, 6]; - mergesort(&mut a); - assert_eq!(a, [1, 3, 5, 6]); -} -``` +[#140667]: https://github.com/rust-lang/rust/issues/140667 -VLAs are not implemented yet. The syntax isn't final, either. We may need an alternative syntax for Rust 2015 because, in Rust 2015, expressions like `[e; dyn(1)]` would be ambiguous. One possible alternative proposed in the RFC is `[e; n]`: if `n` captures one or more local variables, then it is considered as `[e; dyn n]`. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_fallible_shrink", + description: r##"# `vec_fallible_shrink` -## Advisory on stack usage -It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are: -- When you need a by-value trait objects. -- When you really need a fast allocation of small temporary arrays. +The tracking issue for this feature is: [#152350] -Another pitfall is repetitive allocation and temporaries. Currently the compiler simply extends the stack frame every time it encounters an unsized assignment. So for example, the code +[#152350]: https://github.com/rust-lang/rust/issues/152350 -```rust -#![feature(unsized_locals)] +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_from_fn", + description: r##"# `vec_from_fn` -fn main() { - let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]); - let _x = {{{{{{{{{{*x}}}}}}}}}}; -} -``` -and the code -```rust -#![feature(unsized_locals)] +The tracking issue for this feature is: [#149698] -fn main() { - for _ in 0..10 { - let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]); - let _x = *x; - } -} -``` +[#149698]: https://github.com/rust-lang/rust/issues/149698 -will unnecessarily extend the stack frame. +------------------------ "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "unwrap_infallible", - description: r##"# `unwrap_infallible` + label: "vec_into_chunks", + description: r##"# `vec_into_chunks` -The tracking issue for this feature is: [#61695] -[#61695]: https://github.com/rust-lang/rust/issues/61695 + +The tracking issue for this feature is: [#142137] + +[#142137]: https://github.com/rust-lang/rust/issues/142137 ------------------------ "##, @@ -12246,10 +16071,14 @@ The tracking issue for this feature is: [#61695] deny_since: None, }, Lint { - label: "update_panic_count", - description: r##"# `update_panic_count` + label: "vec_peek_mut", + description: r##"# `vec_peek_mut` + -This feature is internal to the Rust compiler and is not intended for general use. + +The tracking issue for this feature is: [#122742] + +[#122742]: https://github.com/rust-lang/rust/issues/122742 ------------------------ "##, @@ -12258,12 +16087,14 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { - label: "used_with_arg", - description: r##"# `used_with_arg` + label: "vec_push_within_capacity", + description: r##"# `vec_push_within_capacity` -The tracking issue for this feature is: [#93798] -[#93798]: https://github.com/rust-lang/rust/issues/93798 + +The tracking issue for this feature is: [#100486] + +[#100486]: https://github.com/rust-lang/rust/issues/100486 ------------------------ "##, @@ -12272,12 +16103,14 @@ The tracking issue for this feature is: [#93798] deny_since: None, }, Lint { - label: "utf16_extra", - description: r##"# `utf16_extra` + label: "vec_recycle", + description: r##"# `vec_recycle` -The tracking issue for this feature is: [#94919] -[#94919]: https://github.com/rust-lang/rust/issues/94919 + +The tracking issue for this feature is: [#148227] + +[#148227]: https://github.com/rust-lang/rust/issues/148227 ------------------------ "##, @@ -12286,12 +16119,14 @@ The tracking issue for this feature is: [#94919] deny_since: None, }, Lint { - label: "variant_count", - description: r##"# `variant_count` + label: "vec_split_at_spare", + description: r##"# `vec_split_at_spare` -The tracking issue for this feature is: [#73662] -[#73662]: https://github.com/rust-lang/rust/issues/73662 + +The tracking issue for this feature is: [#81944] + +[#81944]: https://github.com/rust-lang/rust/issues/81944 ------------------------ "##, @@ -12300,12 +16135,14 @@ The tracking issue for this feature is: [#73662] deny_since: None, }, Lint { - label: "vec_deque_iter_as_slices", - description: r##"# `vec_deque_iter_as_slices` + label: "vec_try_remove", + description: r##"# `vec_try_remove` -The tracking issue for this feature is: [#123947] -[#123947]: https://github.com/rust-lang/rust/issues/123947 + +The tracking issue for this feature is: [#146954] + +[#146954]: https://github.com/rust-lang/rust/issues/146954 ------------------------ "##, @@ -12314,12 +16151,14 @@ The tracking issue for this feature is: [#123947] deny_since: None, }, Lint { - label: "vec_into_raw_parts", - description: r##"# `vec_into_raw_parts` + label: "waker_fn", + description: r##"# `waker_fn` + + -The tracking issue for this feature is: [#65816] +The tracking issue for this feature is: [#149580] -[#65816]: https://github.com/rust-lang/rust/issues/65816 +[#149580]: https://github.com/rust-lang/rust/issues/149580 ------------------------ "##, @@ -12328,12 +16167,14 @@ The tracking issue for this feature is: [#65816] deny_since: None, }, Lint { - label: "vec_pop_if", - description: r##"# `vec_pop_if` + label: "waker_from_fn_ptr", + description: r##"# `waker_from_fn_ptr` -The tracking issue for this feature is: [#122741] -[#122741]: https://github.com/rust-lang/rust/issues/122741 + +The tracking issue for this feature is: [#148457] + +[#148457]: https://github.com/rust-lang/rust/issues/148457 ------------------------ "##, @@ -12342,12 +16183,14 @@ The tracking issue for this feature is: [#122741] deny_since: None, }, Lint { - label: "vec_push_within_capacity", - description: r##"# `vec_push_within_capacity` + label: "wasi_ext", + description: r##"# `wasi_ext` -The tracking issue for this feature is: [#100486] -[#100486]: https://github.com/rust-lang/rust/issues/100486 + +The tracking issue for this feature is: [#71213] + +[#71213]: https://github.com/rust-lang/rust/issues/71213 ------------------------ "##, @@ -12356,12 +16199,14 @@ The tracking issue for this feature is: [#100486] deny_since: None, }, Lint { - label: "vec_split_at_spare", - description: r##"# `vec_split_at_spare` + label: "wasm_target_feature", + description: r##"# `wasm_target_feature` -The tracking issue for this feature is: [#81944] +Target features on wasm. -[#81944]: https://github.com/rust-lang/rust/issues/81944 +The tracking issue for this feature is: [#150260] + +[#150260]: https://github.com/rust-lang/rust/issues/150260 ------------------------ "##, @@ -12370,12 +16215,14 @@ The tracking issue for this feature is: [#81944] deny_since: None, }, Lint { - label: "wasi_ext", - description: r##"# `wasi_ext` + label: "where_clause_attrs", + description: r##"# `where_clause_attrs` -The tracking issue for this feature is: [#71213] +Allows use of attributes in `where` clauses. -[#71213]: https://github.com/rust-lang/rust/issues/71213 +The tracking issue for this feature is: [#115590] + +[#115590]: https://github.com/rust-lang/rust/issues/115590 ------------------------ "##, @@ -12384,12 +16231,14 @@ The tracking issue for this feature is: [#71213] deny_since: None, }, Lint { - label: "wasm_target_feature", - description: r##"# `wasm_target_feature` + label: "widening_mul", + description: r##"# `widening_mul` + + -The tracking issue for this feature is: [#44839] +The tracking issue for this feature is: [#152016] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#152016]: https://github.com/rust-lang/rust/issues/152016 ------------------------ "##, @@ -12401,6 +16250,8 @@ The tracking issue for this feature is: [#44839] label: "windows_by_handle", description: r##"# `windows_by_handle` + + The tracking issue for this feature is: [#63010] [#63010]: https://github.com/rust-lang/rust/issues/63010 @@ -12427,6 +16278,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "windows_change_time", description: r##"# `windows_change_time` + + The tracking issue for this feature is: [#121478] [#121478]: https://github.com/rust-lang/rust/issues/121478 @@ -12438,6 +16291,22 @@ The tracking issue for this feature is: [#121478] deny_since: None, }, Lint { + label: "windows_freeze_file_times", + description: r##"# `windows_freeze_file_times` + + + +The tracking issue for this feature is: [#149715] + +[#149715]: https://github.com/rust-lang/rust/issues/149715 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "windows_handle", description: r##"# `windows_handle` @@ -12465,6 +16334,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "windows_process_exit_code_from", description: r##"# `windows_process_exit_code_from` + + The tracking issue for this feature is: [#111688] [#111688]: https://github.com/rust-lang/rust/issues/111688 @@ -12479,6 +16350,8 @@ The tracking issue for this feature is: [#111688] label: "windows_process_extensions_async_pipes", description: r##"# `windows_process_extensions_async_pipes` + + The tracking issue for this feature is: [#98289] [#98289]: https://github.com/rust-lang/rust/issues/98289 @@ -12493,6 +16366,8 @@ The tracking issue for this feature is: [#98289] label: "windows_process_extensions_force_quotes", description: r##"# `windows_process_extensions_force_quotes` + + The tracking issue for this feature is: [#82227] [#82227]: https://github.com/rust-lang/rust/issues/82227 @@ -12504,9 +16379,27 @@ The tracking issue for this feature is: [#82227] deny_since: None, }, Lint { + label: "windows_process_extensions_inherit_handles", + description: r##"# `windows_process_extensions_inherit_handles` + + + +The tracking issue for this feature is: [#146407] + +[#146407]: https://github.com/rust-lang/rust/issues/146407 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "windows_process_extensions_main_thread_handle", description: r##"# `windows_process_extensions_main_thread_handle` + + The tracking issue for this feature is: [#96723] [#96723]: https://github.com/rust-lang/rust/issues/96723 @@ -12521,6 +16414,8 @@ The tracking issue for this feature is: [#96723] label: "windows_process_extensions_raw_attribute", description: r##"# `windows_process_extensions_raw_attribute` + + The tracking issue for this feature is: [#114854] [#114854]: https://github.com/rust-lang/rust/issues/114854 @@ -12535,6 +16430,8 @@ The tracking issue for this feature is: [#114854] label: "windows_process_extensions_show_window", description: r##"# `windows_process_extensions_show_window` + + The tracking issue for this feature is: [#127544] [#127544]: https://github.com/rust-lang/rust/issues/127544 @@ -12546,6 +16443,22 @@ The tracking issue for this feature is: [#127544] deny_since: None, }, Lint { + label: "windows_process_extensions_startupinfo", + description: r##"# `windows_process_extensions_startupinfo` + + + +The tracking issue for this feature is: [#141010] + +[#141010]: https://github.com/rust-lang/rust/issues/141010 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "windows_stdio", description: r##"# `windows_stdio` @@ -12558,9 +16471,27 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { + label: "windows_unix_domain_sockets", + description: r##"# `windows_unix_domain_sockets` + + + +The tracking issue for this feature is: [#150487] + +[#150487]: https://github.com/rust-lang/rust/issues/150487 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "with_negative_coherence", description: r##"# `with_negative_coherence` +Use for stable + negative coherence and strict coherence depending on trait's rustc_strict_coherence value. + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -12573,6 +16504,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp label: "wrapping_int_impl", description: r##"# `wrapping_int_impl` + + The tracking issue for this feature is: [#32463] [#32463]: https://github.com/rust-lang/rust/issues/32463 @@ -12587,6 +16520,8 @@ The tracking issue for this feature is: [#32463] label: "wrapping_next_power_of_two", description: r##"# `wrapping_next_power_of_two` + + The tracking issue for this feature is: [#32463] [#32463]: https://github.com/rust-lang/rust/issues/32463 @@ -12601,6 +16536,8 @@ The tracking issue for this feature is: [#32463] label: "write_all_vectored", description: r##"# `write_all_vectored` + + The tracking issue for this feature is: [#70436] [#70436]: https://github.com/rust-lang/rust/issues/70436 @@ -12612,9 +16549,25 @@ The tracking issue for this feature is: [#70436] deny_since: None, }, Lint { + label: "wtf8_internals", + description: r##"# `wtf8_internals` + + + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "x86_amx_intrinsics", description: r##"# `x86_amx_intrinsics` +Allows use of x86 `AMX` target-feature attributes and intrinsics + The tracking issue for this feature is: [#126622] [#126622]: https://github.com/rust-lang/rust/issues/126622 @@ -12626,9 +16579,27 @@ The tracking issue for this feature is: [#126622] deny_since: None, }, Lint { + label: "x87_target_feature", + description: r##"# `x87_target_feature` + +The x87 target feature on x86. + +The tracking issue for this feature is: [#150261] + +[#150261]: https://github.com/rust-lang/rust/issues/150261 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { label: "xop_target_feature", description: r##"# `xop_target_feature` +Allows use of the `xop` target-feature + The tracking issue for this feature is: [#127208] [#127208]: https://github.com/rust-lang/rust/issues/127208 @@ -12643,6 +16614,8 @@ The tracking issue for this feature is: [#127208] label: "yeet_desugar_details", description: r##"# `yeet_desugar_details` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ @@ -12684,6 +16657,22 @@ assert_eq!(bar(), None); warn_since: None, deny_since: None, }, + Lint { + label: "yield_expr", + description: r##"# `yield_expr` + + + +The tracking issue for this feature is: [#43122] + +[#43122]: https://github.com/rust-lang/rust/issues/43122 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, ]; pub const CLIPPY_LINTS: &[Lint] = &[ @@ -14967,7 +18956,7 @@ cannot be represented as the underlying type without loss."##, }, Lint { label: "clippy::manual_bits", - description: r##"Checks for usage of `size_of::<T>() * 8` when + description: r##"Checks for usage of `std::mem::size_of::<T>() * 8` when `T::BITS` is available."##, default_severity: Severity::Allow, warn_since: None, @@ -17309,7 +21298,7 @@ count of elements of type `T`"##, }, Lint { label: "clippy::size_of_ref", - description: r##"Checks for calls to `size_of_val()` where the argument is + description: r##"Checks for calls to `std::mem::size_of_val()` where the argument is a reference to a reference."##, default_severity: Severity::Allow, warn_since: None, diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs index 2f696d07e2..9018552afb 100644 --- a/crates/ide-db/src/imports/import_assets.rs +++ b/crates/ide-db/src/imports/import_assets.rs @@ -117,7 +117,9 @@ impl PathDefinitionKinds { // validate that the following segment resolve. SyntaxKind::PATH => Self { modules: true, type_namespace: true, ..Self::ALL_DISABLED }, SyntaxKind::MACRO_CALL => Self { bang_macros: true, ..Self::ALL_DISABLED }, - SyntaxKind::META => Self { attr_macros: true, ..Self::ALL_DISABLED }, + SyntaxKind::PATH_META | SyntaxKind::KEY_VALUE_META | SyntaxKind::TOKEN_TREE_META => { + Self { attr_macros: true, ..Self::ALL_DISABLED } + } SyntaxKind::USE_TREE => { if ast::UseTree::cast(parent).unwrap().use_tree_list().is_some() { Self { modules: true, ..Self::ALL_DISABLED } diff --git a/crates/ide-db/src/imports/insert_use.rs b/crates/ide-db/src/imports/insert_use.rs index 41ce1e5960..9318c3e132 100644 --- a/crates/ide-db/src/imports/insert_use.rs +++ b/crates/ide-db/src/imports/insert_use.rs @@ -101,14 +101,12 @@ impl ImportScope { { block = b.stmt_list(); } - if has_attrs - .attrs() - .any(|attr| attr.as_simple_call().is_some_and(|(ident, _)| ident == "cfg")) + if has_attrs.attrs().any(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))) { if let Some(b) = block.clone() { - let current_cfgs = has_attrs.attrs().filter(|attr| { - attr.as_simple_call().is_some_and(|(ident, _)| ident == "cfg") - }); + let current_cfgs = has_attrs + .attrs() + .filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))); let total_cfgs: Vec<_> = required_cfgs.iter().cloned().chain(current_cfgs).collect(); @@ -118,7 +116,7 @@ impl ImportScope { if let Some(parent) = parent { can_merge = parent.children().filter_map(ast::Use::cast).any(|u| { let u_attrs = u.attrs().filter(|attr| { - attr.as_simple_call().is_some_and(|(ident, _)| ident == "cfg") + matches!(attr.meta(), Some(ast::Meta::CfgMeta(_))) }); crate::imports::merge_imports::eq_attrs( u_attrs, @@ -134,9 +132,11 @@ impl ImportScope { }); } } - required_cfgs.extend(has_attrs.attrs().filter(|attr| { - attr.as_simple_call().is_some_and(|(ident, _)| ident == "cfg") - })); + required_cfgs.extend( + has_attrs + .attrs() + .filter(|attr| matches!(attr.meta(), Some(ast::Meta::CfgMeta(_)))), + ); } } } diff --git a/crates/ide-db/src/imports/merge_imports.rs b/crates/ide-db/src/imports/merge_imports.rs index 3301719f5c..76645464dd 100644 --- a/crates/ide-db/src/imports/merge_imports.rs +++ b/crates/ide-db/src/imports/merge_imports.rs @@ -256,16 +256,6 @@ pub fn try_normalize_import(use_item: &ast::Use, style: NormalizationStyle) -> O Some(use_item) } -/// Normalizes a use tree (see [`try_normalize_import`] doc). -pub fn try_normalize_use_tree( - use_tree: &ast::UseTree, - style: NormalizationStyle, -) -> Option<ast::UseTree> { - let use_tree = use_tree.clone_subtree().clone_for_update(); - try_normalize_use_tree_mut(&use_tree, style)?; - Some(use_tree) -} - pub fn try_normalize_use_tree_mut( use_tree: &ast::UseTree, style: NormalizationStyle, diff --git a/crates/ide-diagnostics/src/handlers/inactive_code.rs b/crates/ide-diagnostics/src/handlers/inactive_code.rs index 9bfbeeebf7..be4fe763a0 100644 --- a/crates/ide-diagnostics/src/handlers/inactive_code.rs +++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs @@ -209,8 +209,8 @@ union FooBar { #[cfg(true)] fn active() {} - #[cfg(any(not(true)), false)] fn inactive2() {} -//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: true is enabled + #[cfg(any(not(true), false))] fn inactive2() {} +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: true is enabled and false is disabled "#, ); diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 6f4ea70e0a..fb885c2ad1 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -54,8 +54,9 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< let InFile { file_id, value: tokens } = hir::InMacroFile::new(macro_file, descended).upmap_once(db); let token = sema.parse_or_expand(file_id).covering_element(tokens[0]).into_token()?; - let attr = token.parent_ancestors().find_map(ast::Attr::cast)?; + let attr = token.parent_ancestors().find_map(ast::Meta::cast)?; let expansions = sema.expand_derive_macro(&attr)?; + let ast::Meta::TokenTreeMeta(attr) = attr else { return None }; let idx = attr .token_tree()? .token_trees_and_tokens() diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index ce9ec7431a..dcfe4dd41e 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -166,12 +166,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd <span class="comment documentation">///</span> <span class="comment documentation">/// ```</span> <span class="comment documentation">///</span><span class="none injected"> </span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span> -<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"false"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span> <span class="none attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span> +<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="keyword attribute">cfg_attr</span><span class="parenthesis attribute">(</span>not<span class="parenthesis attribute">(</span>feature <span class="operator attribute">=</span> <span class="string_literal attribute">"false"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span> <span class="builtin_attr attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span> <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"</span><span class="keyword control injected">loop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span><span class="string_literal attribute">"</span><span class="attribute_bracket attribute">]</span> <span class="comment documentation">/// ```</span> <span class="comment documentation">///</span> -<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"alloc"</span><span class="comma attribute">,</span> <span class="none attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"```rust"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span> -<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span> <span class="none attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span> +<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="keyword attribute">cfg_attr</span><span class="parenthesis attribute">(</span>feature <span class="operator attribute">=</span> <span class="string_literal attribute">"alloc"</span><span class="comma attribute">,</span> <span class="builtin_attr attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"```rust"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span> +<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="keyword attribute">cfg_attr</span><span class="parenthesis attribute">(</span>not<span class="parenthesis attribute">(</span>feature <span class="operator attribute">=</span> <span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span> <span class="builtin_attr attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span> <span class="comment documentation">///</span><span class="none injected"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="module injected">alloc</span><span class="operator injected">::</span><span class="macro injected">vec</span><span class="macro_bang injected">!</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> <span class="comment documentation">/// ```</span> <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration public">mix_and_match</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> diff --git a/crates/parser/src/grammar/attributes.rs b/crates/parser/src/grammar/attributes.rs index c0cf43a87b..2eeaa25257 100644 --- a/crates/parser/src/grammar/attributes.rs +++ b/crates/parser/src/grammar/attributes.rs @@ -40,6 +40,86 @@ fn attr(p: &mut Parser<'_>, inner: bool) { // #![unsafe] // #![unsafe =] +fn cfg_attr_meta(p: &mut Parser<'_>, m: Marker) { + // test cfg_attr + // #![cfg_attr(not(foo), unsafe(bar()), cfg_attr(all(true, foo = "bar"), baz = "baz"))] + p.eat_contextual_kw(T![cfg_attr]); + p.bump(T!['(']); + cfg_predicate(p); + p.expect(T![,]); + while !p.at(T![')']) && !p.at(EOF) { + meta(p); + if !p.eat(T![,]) { + break; + } + } + p.expect(T![')']); + m.complete(p, CFG_ATTR_META); +} + +const CFG_PREDICATE_FIRST_SET: TokenSet = TokenSet::new(&[T![true], T![false], T![ident]]); + +fn cfg_predicate(p: &mut Parser<'_>) { + let m = p.start(); + if p.eat(T![true]) || p.eat(T![false]) { + // test cfg_true_false_pred + // #![cfg(true)] + // #![cfg(false)] + m.complete(p, CFG_ATOM); + return; + } + p.expect(T![ident]); + if p.eat(T![=]) { + if p.at(T![ident]) { + // This is required for completion, that inserts an identifier, to work in cases like + // `#[cfg(key = $0)]`, and also makes sense on itself. + + // test_err key_ident_cfg_predicate + // #![cfg(key = value)] + p.err_and_bump("expected a string literal"); + } else { + // test cfg_key_value_pred + // #![cfg(key = "value")] + p.expect(T![string]); + } + m.complete(p, CFG_ATOM); + } else if p.at(T!['(']) { + // test cfg_composite_pred + // #![cfg(any(a, all(b = "c", d)))] + delimited( + p, + T!['('], + T![')'], + T![,], + || "expected a cfg predicate".to_owned(), + CFG_PREDICATE_FIRST_SET, + |p| { + if p.at_ts(CFG_PREDICATE_FIRST_SET) { + cfg_predicate(p); + true + } else { + false + } + }, + ); + m.complete(p, CFG_COMPOSITE); + } else { + m.complete(p, CFG_ATOM); + } +} + +fn cfg_meta(p: &mut Parser<'_>, m: Marker) { + // test cfg_meta + // #![cfg(foo)] + // #![cfg(foo = "bar",)] + p.eat_contextual_kw(T![cfg]); + p.bump(T!['(']); + cfg_predicate(p); + p.eat(T![,]); + p.expect(T![')']); + m.complete(p, CFG_META); +} + // test metas // #![simple_ident] // #![simple::path] @@ -62,11 +142,23 @@ fn attr(p: &mut Parser<'_>, inner: bool) { // #![unsafe(simple::path::tt[a b c])] // #![unsafe(simple::path::tt{a b c})] pub(super) fn meta(p: &mut Parser<'_>) { - let meta = p.start(); - let is_unsafe = p.eat(T![unsafe]); - if is_unsafe { + let m = p.start(); + if p.eat(T![unsafe]) { p.expect(T!['(']); + meta(p); + p.expect(T![')']); + m.complete(p, UNSAFE_META); + return; + } + + if p.nth_at(1, T!['(']) { + if p.at_contextual_kw(T![cfg_attr]) { + return cfg_attr_meta(p, m); + } else if p.at_contextual_kw(T![cfg]) { + return cfg_meta(p, m); + } } + paths::attr_path(p); match p.current() { @@ -75,13 +167,14 @@ pub(super) fn meta(p: &mut Parser<'_>) { if expressions::expr(p).is_none() { p.error("expected expression"); } + m.complete(p, KEY_VALUE_META); + } + T!['('] | T!['['] | T!['{'] => { + items::token_tree(p); + m.complete(p, TOKEN_TREE_META); + } + _ => { + m.complete(p, PATH_META); } - T!['('] | T!['['] | T!['{'] => items::token_tree(p), - _ => {} - } - if is_unsafe { - p.expect(T![')']); } - - meta.complete(p, META); } diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index a2295e4495..9cd48f2aa4 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs @@ -116,6 +116,8 @@ pub enum SyntaxKind { AWAIT_KW, BIKESHED_KW, BUILTIN_KW, + CFG_ATTR_KW, + CFG_KW, CLOBBER_ABI_KW, DEFAULT_KW, DYN_KW, @@ -186,6 +188,10 @@ pub enum SyntaxKind { BREAK_EXPR, CALL_EXPR, CAST_EXPR, + CFG_ATOM, + CFG_ATTR_META, + CFG_COMPOSITE, + CFG_META, CLOSURE_EXPR, CONST, CONST_ARG, @@ -216,6 +222,7 @@ pub enum SyntaxKind { INDEX_EXPR, INFER_TYPE, ITEM_LIST, + KEY_VALUE_META, LABEL, LET_ELSE, LET_EXPR, @@ -238,7 +245,6 @@ pub enum SyntaxKind { MATCH_ARM_LIST, MATCH_EXPR, MATCH_GUARD, - META, METHOD_CALL_EXPR, MODULE, NAME, @@ -254,6 +260,7 @@ pub enum SyntaxKind { PAREN_TYPE, PATH, PATH_EXPR, + PATH_META, PATH_PAT, PATH_SEGMENT, PATH_TYPE, @@ -285,6 +292,7 @@ pub enum SyntaxKind { STMT_LIST, STRUCT, TOKEN_TREE, + TOKEN_TREE_META, TRAIT, TRY_BLOCK_MODIFIER, TRY_EXPR, @@ -302,6 +310,7 @@ pub enum SyntaxKind { TYPE_PARAM, UNDERSCORE_EXPR, UNION, + UNSAFE_META, USE, USE_BOUND_GENERIC_ARGS, USE_TREE, @@ -360,6 +369,10 @@ impl SyntaxKind { | BREAK_EXPR | CALL_EXPR | CAST_EXPR + | CFG_ATOM + | CFG_ATTR_META + | CFG_COMPOSITE + | CFG_META | CLOSURE_EXPR | CONST | CONST_ARG @@ -390,6 +403,7 @@ impl SyntaxKind { | INDEX_EXPR | INFER_TYPE | ITEM_LIST + | KEY_VALUE_META | LABEL | LET_ELSE | LET_EXPR @@ -412,7 +426,6 @@ impl SyntaxKind { | MATCH_ARM_LIST | MATCH_EXPR | MATCH_GUARD - | META | METHOD_CALL_EXPR | MODULE | NAME @@ -428,6 +441,7 @@ impl SyntaxKind { | PAREN_TYPE | PATH | PATH_EXPR + | PATH_META | PATH_PAT | PATH_SEGMENT | PATH_TYPE @@ -459,6 +473,7 @@ impl SyntaxKind { | STMT_LIST | STRUCT | TOKEN_TREE + | TOKEN_TREE_META | TRAIT | TRY_BLOCK_MODIFIER | TRY_EXPR @@ -476,6 +491,7 @@ impl SyntaxKind { | TYPE_PARAM | UNDERSCORE_EXPR | UNION + | UNSAFE_META | USE | USE_BOUND_GENERIC_ARGS | USE_TREE @@ -601,6 +617,8 @@ impl SyntaxKind { AUTO_KW => "auto", BIKESHED_KW => "bikeshed", BUILTIN_KW => "builtin", + CFG_KW => "cfg", + CFG_ATTR_KW => "cfg_attr", CLOBBER_ABI_KW => "clobber_abi", DEFAULT_KW => "default", DYN_KW => "dyn", @@ -704,6 +722,8 @@ impl SyntaxKind { AUTO_KW => true, BIKESHED_KW => true, BUILTIN_KW => true, + CFG_KW => true, + CFG_ATTR_KW => true, CLOBBER_ABI_KW => true, DEFAULT_KW => true, DYN_KW if edition < Edition::Edition2018 => true, @@ -795,6 +815,8 @@ impl SyntaxKind { AUTO_KW => true, BIKESHED_KW => true, BUILTIN_KW => true, + CFG_KW => true, + CFG_ATTR_KW => true, CLOBBER_ABI_KW => true, DEFAULT_KW => true, DYN_KW if edition < Edition::Edition2018 => true, @@ -949,6 +971,8 @@ impl SyntaxKind { "auto" => AUTO_KW, "bikeshed" => BIKESHED_KW, "builtin" => BUILTIN_KW, + "cfg" => CFG_KW, + "cfg_attr" => CFG_ATTR_KW, "clobber_abi" => CLOBBER_ABI_KW, "default" => DEFAULT_KW, "dyn" if edition < Edition::Edition2018 => DYN_KW, @@ -1121,6 +1145,8 @@ macro_rules ! T_ { [auto] => { $ crate :: SyntaxKind :: AUTO_KW }; [bikeshed] => { $ crate :: SyntaxKind :: BIKESHED_KW }; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW }; + [cfg] => { $ crate :: SyntaxKind :: CFG_KW }; + [cfg_attr] => { $ crate :: SyntaxKind :: CFG_ATTR_KW }; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW }; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW }; [dyn] => { $ crate :: SyntaxKind :: DYN_KW }; diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs index 01fc172ed9..71978390df 100644 --- a/crates/parser/test_data/generated/runner.rs +++ b/crates/parser/test_data/generated/runner.rs @@ -87,6 +87,22 @@ mod ok { #[test] fn cast_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/cast_expr.rs"); } #[test] + fn cfg_attr() { run_and_expect_no_errors("test_data/parser/inline/ok/cfg_attr.rs"); } + #[test] + fn cfg_composite_pred() { + run_and_expect_no_errors("test_data/parser/inline/ok/cfg_composite_pred.rs"); + } + #[test] + fn cfg_key_value_pred() { + run_and_expect_no_errors("test_data/parser/inline/ok/cfg_key_value_pred.rs"); + } + #[test] + fn cfg_meta() { run_and_expect_no_errors("test_data/parser/inline/ok/cfg_meta.rs"); } + #[test] + fn cfg_true_false_pred() { + run_and_expect_no_errors("test_data/parser/inline/ok/cfg_true_false_pred.rs"); + } + #[test] fn closure_binder() { run_and_expect_no_errors("test_data/parser/inline/ok/closure_binder.rs"); } @@ -826,6 +842,10 @@ mod err { ); } #[test] + fn key_ident_cfg_predicate() { + run_and_expect_errors("test_data/parser/inline/err/key_ident_cfg_predicate.rs"); + } + #[test] fn let_else_right_curly_brace() { run_and_expect_errors("test_data/parser/inline/err/let_else_right_curly_brace.rs"); } diff --git a/crates/parser/test_data/parser/err/0005_attribute_recover.rast b/crates/parser/test_data/parser/err/0005_attribute_recover.rast index 77b4d06321..cf45dcf522 100644 --- a/crates/parser/test_data/parser/err/0005_attribute_recover.rast +++ b/crates/parser/test_data/parser/err/0005_attribute_recover.rast @@ -3,7 +3,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -37,7 +37,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast index b657e98341..2334b730e4 100644 --- a/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast +++ b/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast @@ -136,15 +136,12 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "test" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " ATTR diff --git a/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast index b5bc3d84df..acacee2348 100644 --- a/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast +++ b/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast @@ -48,15 +48,12 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "test" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " R_CURLY "}" diff --git a/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rast b/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rast new file mode 100644 index 0000000000..de5fc7d5bd --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rast @@ -0,0 +1,19 @@ +SOURCE_FILE + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM + IDENT "key" + WHITESPACE " " + EQ "=" + WHITESPACE " " + ERROR + IDENT "value" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" +error 13: expected a string literal diff --git a/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rs b/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rs new file mode 100644 index 0000000000..9a981bf939 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rs @@ -0,0 +1 @@ +#![cfg(key = value)] diff --git a/crates/parser/test_data/parser/inline/err/meta_recovery.rast b/crates/parser/test_data/parser/inline/err/meta_recovery.rast index b5c16e0798..9e456c9855 100644 --- a/crates/parser/test_data/parser/inline/err/meta_recovery.rast +++ b/crates/parser/test_data/parser/inline/err/meta_recovery.rast @@ -3,14 +3,14 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META R_BRACK "]" WHITESPACE "\n" ATTR POUND "#" BANG "!" L_BRACK "[" - META + KEY_VALUE_META PATH PATH_SEGMENT NAME_REF @@ -24,7 +24,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META PATH PATH PATH_SEGMENT @@ -37,7 +37,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + KEY_VALUE_META PATH PATH PATH_SEGMENT @@ -52,18 +52,20 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" + PATH_META R_BRACK "]" WHITESPACE "\n" ATTR POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" WHITESPACE " " - EQ "=" + KEY_VALUE_META + EQ "=" R_BRACK "]" WHITESPACE "\n" error 3: expected identifier, `self`, `super`, `crate`, or `Self` @@ -77,7 +79,7 @@ error 41: expected L_PAREN error 41: expected identifier, `self`, `super`, `crate`, or `Self` error 41: expected R_PAREN error 52: expected L_PAREN -error 52: expected identifier, `self`, `super`, `crate`, or `Self` +error 53: expected identifier, `self`, `super`, `crate`, or `Self` error 54: expected expression error 54: expected expression error 54: expected R_PAREN diff --git a/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast b/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast index ae1074c368..672f2c2f7f 100644 --- a/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast +++ b/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast @@ -24,7 +24,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/array_attrs.rast b/crates/parser/test_data/parser/inline/ok/array_attrs.rast index 6eb8af3311..2812bbf71b 100644 --- a/crates/parser/test_data/parser/inline/ok/array_attrs.rast +++ b/crates/parser/test_data/parser/inline/ok/array_attrs.rast @@ -31,15 +31,12 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "test" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE " " INT_NUMBER "2" diff --git a/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast b/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast index 9cb3c8a5c3..7c6dbf65cf 100644 --- a/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast +++ b/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast @@ -15,7 +15,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast b/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast index 81b7f2b3cb..248e6d1360 100644 --- a/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast +++ b/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast @@ -17,7 +17,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -39,7 +39,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -61,7 +61,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -71,7 +71,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -87,7 +87,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/cfg_attr.rast b/crates/parser/test_data/parser/inline/ok/cfg_attr.rast new file mode 100644 index 0000000000..9af94f447d --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_attr.rast @@ -0,0 +1,63 @@ +SOURCE_FILE + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_ATTR_META + CFG_ATTR_KW "cfg_attr" + L_PAREN "(" + CFG_COMPOSITE + IDENT "not" + L_PAREN "(" + CFG_ATOM + IDENT "foo" + R_PAREN ")" + COMMA "," + WHITESPACE " " + UNSAFE_META + UNSAFE_KW "unsafe" + L_PAREN "(" + TOKEN_TREE_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" + COMMA "," + WHITESPACE " " + CFG_ATTR_META + CFG_ATTR_KW "cfg_attr" + L_PAREN "(" + CFG_COMPOSITE + IDENT "all" + L_PAREN "(" + CFG_ATOM + TRUE_KW "true" + COMMA "," + WHITESPACE " " + CFG_ATOM + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + STRING "\"bar\"" + R_PAREN ")" + COMMA "," + WHITESPACE " " + KEY_VALUE_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "baz" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "\"baz\"" + R_PAREN ")" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/cfg_attr.rs b/crates/parser/test_data/parser/inline/ok/cfg_attr.rs new file mode 100644 index 0000000000..5fe2776144 --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_attr.rs @@ -0,0 +1 @@ +#![cfg_attr(not(foo), unsafe(bar()), cfg_attr(all(true, foo = "bar"), baz = "baz"))] diff --git a/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rast b/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rast new file mode 100644 index 0000000000..89d06d134f --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rast @@ -0,0 +1,33 @@ +SOURCE_FILE + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_COMPOSITE + IDENT "any" + L_PAREN "(" + CFG_ATOM + IDENT "a" + COMMA "," + WHITESPACE " " + CFG_COMPOSITE + IDENT "all" + L_PAREN "(" + CFG_ATOM + IDENT "b" + WHITESPACE " " + EQ "=" + WHITESPACE " " + STRING "\"c\"" + COMMA "," + WHITESPACE " " + CFG_ATOM + IDENT "d" + R_PAREN ")" + R_PAREN ")" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rs b/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rs new file mode 100644 index 0000000000..7d830c1288 --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rs @@ -0,0 +1 @@ +#![cfg(any(a, all(b = "c", d)))] diff --git a/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rast b/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rast new file mode 100644 index 0000000000..e48d39bf55 --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rast @@ -0,0 +1,17 @@ +SOURCE_FILE + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM + IDENT "key" + WHITESPACE " " + EQ "=" + WHITESPACE " " + STRING "\"value\"" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rs b/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rs new file mode 100644 index 0000000000..dc194ed86b --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rs @@ -0,0 +1 @@ +#![cfg(key = "value")] diff --git a/crates/parser/test_data/parser/inline/ok/cfg_meta.rast b/crates/parser/test_data/parser/inline/ok/cfg_meta.rast new file mode 100644 index 0000000000..f024cfd1aa --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_meta.rast @@ -0,0 +1,30 @@ +SOURCE_FILE + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM + IDENT "foo" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + STRING "\"bar\"" + COMMA "," + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/cfg_meta.rs b/crates/parser/test_data/parser/inline/ok/cfg_meta.rs new file mode 100644 index 0000000000..ef0030e75f --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_meta.rs @@ -0,0 +1,2 @@ +#![cfg(foo)] +#![cfg(foo = "bar",)] diff --git a/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rast b/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rast new file mode 100644 index 0000000000..e33595a93d --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rast @@ -0,0 +1,25 @@ +SOURCE_FILE + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM + TRUE_KW "true" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" + ATTR + POUND "#" + BANG "!" + L_BRACK "[" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM + FALSE_KW "false" + R_PAREN ")" + R_BRACK "]" + WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rs b/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rs new file mode 100644 index 0000000000..473582164a --- /dev/null +++ b/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rs @@ -0,0 +1,2 @@ +#![cfg(true)] +#![cfg(false)] diff --git a/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast b/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast index 28a216e873..5567a53c56 100644 --- a/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast +++ b/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast @@ -10,7 +10,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -25,7 +25,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast b/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast index 6fd9f42467..edb0438733 100644 --- a/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast +++ b/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast @@ -26,7 +26,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -41,7 +41,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -56,7 +56,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast b/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast index 0f7580c1a3..321db782d1 100644 --- a/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast +++ b/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast @@ -26,19 +26,16 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "feature" WHITESPACE " " EQ "=" WHITESPACE " " STRING "\"some\"" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " WILDCARD_PAT @@ -55,19 +52,16 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "feature" WHITESPACE " " EQ "=" WHITESPACE " " STRING "\"other\"" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " WILDCARD_PAT @@ -84,55 +78,46 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "feature" WHITESPACE " " EQ "=" WHITESPACE " " STRING "\"many\"" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "feature" WHITESPACE " " EQ "=" WHITESPACE " " STRING "\"attributes\"" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "feature" WHITESPACE " " EQ "=" WHITESPACE " " STRING "\"before\"" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " WILDCARD_PAT diff --git a/crates/parser/test_data/parser/inline/ok/metas.rast b/crates/parser/test_data/parser/inline/ok/metas.rast index b1ac60b530..6360552a6f 100644 --- a/crates/parser/test_data/parser/inline/ok/metas.rast +++ b/crates/parser/test_data/parser/inline/ok/metas.rast @@ -3,7 +3,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -14,7 +14,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META PATH PATH PATH_SEGMENT @@ -30,7 +30,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + KEY_VALUE_META PATH PATH_SEGMENT NAME_REF @@ -46,7 +46,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + KEY_VALUE_META PATH PATH PATH @@ -72,7 +72,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -91,7 +91,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -110,7 +110,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -129,7 +129,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH PATH @@ -158,7 +158,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH PATH @@ -187,7 +187,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH PATH @@ -216,13 +216,14 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH - PATH_SEGMENT - NAME_REF - IDENT "simple_ident" + PATH_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple_ident" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -230,18 +231,19 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH + PATH_META PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple" + COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "simple" - COLON2 "::" - PATH_SEGMENT - NAME_REF - IDENT "path" + IDENT "path" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -249,18 +251,19 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH - PATH_SEGMENT - NAME_REF - IDENT "simple_ident_expr" - WHITESPACE " " - EQ "=" - WHITESPACE " " - LITERAL - STRING "\"\"" + KEY_VALUE_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple_ident_expr" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "\"\"" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -268,28 +271,29 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH + KEY_VALUE_META PATH PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple" + COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "simple" + IDENT "path" COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "path" - COLON2 "::" - PATH_SEGMENT - NAME_REF - IDENT "Expr" - WHITESPACE " " - EQ "=" - WHITESPACE " " - LITERAL - STRING "\"\"" + IDENT "Expr" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + STRING "\"\"" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -297,21 +301,22 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH - PATH_SEGMENT - NAME_REF - IDENT "simple_ident_tt" - TOKEN_TREE - L_PAREN "(" - IDENT "a" - WHITESPACE " " - IDENT "b" - WHITESPACE " " - IDENT "c" - R_PAREN ")" + TOKEN_TREE_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple_ident_tt" + TOKEN_TREE + L_PAREN "(" + IDENT "a" + WHITESPACE " " + IDENT "b" + WHITESPACE " " + IDENT "c" + R_PAREN ")" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -319,21 +324,22 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH - PATH_SEGMENT - NAME_REF - IDENT "simple_ident_tt" - TOKEN_TREE - L_BRACK "[" - IDENT "a" - WHITESPACE " " - IDENT "b" - WHITESPACE " " - IDENT "c" - R_BRACK "]" + TOKEN_TREE_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple_ident_tt" + TOKEN_TREE + L_BRACK "[" + IDENT "a" + WHITESPACE " " + IDENT "b" + WHITESPACE " " + IDENT "c" + R_BRACK "]" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -341,21 +347,22 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH - PATH_SEGMENT - NAME_REF - IDENT "simple_ident_tt" - TOKEN_TREE - L_CURLY "{" - IDENT "a" - WHITESPACE " " - IDENT "b" - WHITESPACE " " - IDENT "c" - R_CURLY "}" + TOKEN_TREE_META + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple_ident_tt" + TOKEN_TREE + L_CURLY "{" + IDENT "a" + WHITESPACE " " + IDENT "b" + WHITESPACE " " + IDENT "c" + R_CURLY "}" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -363,31 +370,32 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH + TOKEN_TREE_META PATH PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple" + COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "simple" + IDENT "path" COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "path" - COLON2 "::" - PATH_SEGMENT - NAME_REF - IDENT "tt" - TOKEN_TREE - L_PAREN "(" - IDENT "a" - WHITESPACE " " - IDENT "b" - WHITESPACE " " - IDENT "c" - R_PAREN ")" + IDENT "tt" + TOKEN_TREE + L_PAREN "(" + IDENT "a" + WHITESPACE " " + IDENT "b" + WHITESPACE " " + IDENT "c" + R_PAREN ")" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -395,31 +403,32 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH + TOKEN_TREE_META PATH PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple" + COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "simple" + IDENT "path" COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "path" - COLON2 "::" - PATH_SEGMENT - NAME_REF - IDENT "tt" - TOKEN_TREE - L_BRACK "[" - IDENT "a" - WHITESPACE " " - IDENT "b" - WHITESPACE " " - IDENT "c" - R_BRACK "]" + IDENT "tt" + TOKEN_TREE + L_BRACK "[" + IDENT "a" + WHITESPACE " " + IDENT "b" + WHITESPACE " " + IDENT "c" + R_BRACK "]" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" @@ -427,31 +436,32 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + UNSAFE_META UNSAFE_KW "unsafe" L_PAREN "(" - PATH + TOKEN_TREE_META PATH PATH + PATH + PATH_SEGMENT + NAME_REF + IDENT "simple" + COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "simple" + IDENT "path" COLON2 "::" PATH_SEGMENT NAME_REF - IDENT "path" - COLON2 "::" - PATH_SEGMENT - NAME_REF - IDENT "tt" - TOKEN_TREE - L_CURLY "{" - IDENT "a" - WHITESPACE " " - IDENT "b" - WHITESPACE " " - IDENT "c" - R_CURLY "}" + IDENT "tt" + TOKEN_TREE + L_CURLY "{" + IDENT "a" + WHITESPACE " " + IDENT "b" + WHITESPACE " " + IDENT "c" + R_CURLY "}" R_PAREN ")" R_BRACK "]" WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast b/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast index c63ea020a3..7495ba7b31 100644 --- a/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast +++ b/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast @@ -10,7 +10,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast b/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast index 639ee0eb77..cfa2694fd1 100644 --- a/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast +++ b/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast @@ -12,7 +12,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast b/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast index a1df70841e..717dee8c9f 100644 --- a/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast +++ b/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast @@ -25,15 +25,12 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "test" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE " " NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/record_pat_field.rast b/crates/parser/test_data/parser/inline/ok/record_pat_field.rast index f3d2fde466..7fba529be9 100644 --- a/crates/parser/test_data/parser/inline/ok/record_pat_field.rast +++ b/crates/parser/test_data/parser/inline/ok/record_pat_field.rast @@ -88,18 +88,14 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_COMPOSITE IDENT "any" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" + L_PAREN "(" R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE " " NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast b/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast index f69ae1d644..af5b82b889 100644 --- a/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast +++ b/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast @@ -146,18 +146,14 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_COMPOSITE IDENT "any" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" + L_PAREN "(" R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE " " DOT2 ".." diff --git a/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast b/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast index db583f7d52..3a163e5b8e 100644 --- a/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast +++ b/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast @@ -10,7 +10,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast b/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast index 39857b23c6..76954927d5 100644 --- a/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast +++ b/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast @@ -34,15 +34,12 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "test" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE " " INT_NUMBER "2" diff --git a/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast b/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast index 1699602f4f..1f7100c46d 100644 --- a/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast +++ b/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast @@ -11,7 +11,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0006_inner_attributes.rast b/crates/parser/test_data/parser/ok/0006_inner_attributes.rast index cb63ba80e7..ddab028c06 100644 --- a/crates/parser/test_data/parser/ok/0006_inner_attributes.rast +++ b/crates/parser/test_data/parser/ok/0006_inner_attributes.rast @@ -3,7 +3,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -14,7 +14,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -29,7 +29,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -44,7 +44,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -89,7 +89,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -104,7 +104,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -123,7 +123,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -138,7 +138,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -153,7 +153,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -175,7 +175,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0008_mod_item.rast b/crates/parser/test_data/parser/ok/0008_mod_item.rast index adee67181b..cb6da8717d 100644 --- a/crates/parser/test_data/parser/ok/0008_mod_item.rast +++ b/crates/parser/test_data/parser/ok/0008_mod_item.rast @@ -48,7 +48,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0011_outer_attribute.rast b/crates/parser/test_data/parser/ok/0011_outer_attribute.rast index dbb9bc54da..47a5cfce08 100644 --- a/crates/parser/test_data/parser/ok/0011_outer_attribute.rast +++ b/crates/parser/test_data/parser/ok/0011_outer_attribute.rast @@ -3,21 +3,18 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "test" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n" ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -41,7 +38,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + KEY_VALUE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast index 7c914e2542..c5d054702f 100644 --- a/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast +++ b/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast @@ -3,7 +3,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0035_weird_exprs.rast b/crates/parser/test_data/parser/ok/0035_weird_exprs.rast index 318d492ab4..15ce6c70be 100644 --- a/crates/parser/test_data/parser/ok/0035_weird_exprs.rast +++ b/crates/parser/test_data/parser/ok/0035_weird_exprs.rast @@ -11,7 +11,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -26,7 +26,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -41,7 +41,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -56,7 +56,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -71,7 +71,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + KEY_VALUE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0044_let_attrs.rast b/crates/parser/test_data/parser/ok/0044_let_attrs.rast index f3c20337e4..fcdc1a9895 100644 --- a/crates/parser/test_data/parser/ok/0044_let_attrs.rast +++ b/crates/parser/test_data/parser/ok/0044_let_attrs.rast @@ -18,19 +18,16 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "feature" WHITESPACE " " EQ "=" WHITESPACE " " STRING "\"backtrace\"" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE "\n " LET_KW "let" diff --git a/crates/parser/test_data/parser/ok/0045_block_attrs.rast b/crates/parser/test_data/parser/ok/0045_block_attrs.rast index c22d99f1ae..f26bb85df2 100644 --- a/crates/parser/test_data/parser/ok/0045_block_attrs.rast +++ b/crates/parser/test_data/parser/ok/0045_block_attrs.rast @@ -16,7 +16,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -38,7 +38,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -53,7 +53,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -77,7 +77,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -119,7 +119,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF @@ -211,7 +211,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast index 4eb51cfdf0..3d33eb4ff7 100644 --- a/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast +++ b/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast @@ -14,7 +14,7 @@ SOURCE_FILE POUND "#" BANG "!" L_BRACK "[" - META + TOKEN_TREE_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast index eafee90db4..24d4392282 100644 --- a/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast +++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast @@ -10,7 +10,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -20,7 +20,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -55,7 +55,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -116,7 +116,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -158,7 +158,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -181,7 +181,7 @@ SOURCE_FILE POUND "#" WHITESPACE " " L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -228,7 +228,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -255,7 +255,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -282,7 +282,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -316,7 +316,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -352,7 +352,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -389,7 +389,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -422,7 +422,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -456,7 +456,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast index b94d43beb3..c300b7af50 100644 --- a/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast +++ b/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast @@ -5,7 +5,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0062_macro_2.0.rast b/crates/parser/test_data/parser/ok/0062_macro_2.0.rast index 1415a866b6..b92d78e5bd 100644 --- a/crates/parser/test_data/parser/ok/0062_macro_2.0.rast +++ b/crates/parser/test_data/parser/ok/0062_macro_2.0.rast @@ -54,7 +54,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0063_variadic_fun.rast b/crates/parser/test_data/parser/ok/0063_variadic_fun.rast index e36399123b..f1c6d2efeb 100644 --- a/crates/parser/test_data/parser/ok/0063_variadic_fun.rast +++ b/crates/parser/test_data/parser/ok/0063_variadic_fun.rast @@ -96,15 +96,12 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META - PATH - PATH_SEGMENT - NAME_REF - IDENT "cfg" - TOKEN_TREE - L_PAREN "(" + CFG_META + CFG_KW "cfg" + L_PAREN "(" + CFG_ATOM IDENT "never" - R_PAREN ")" + R_PAREN ")" R_BRACK "]" WHITESPACE " " SLICE_PAT diff --git a/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast index 3d00b27ab8..5229b97eb2 100644 --- a/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast +++ b/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast @@ -19,7 +19,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -39,7 +39,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast index 1cafc775cd..c0685448f2 100644 --- a/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast +++ b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast @@ -17,7 +17,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -31,7 +31,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF @@ -56,7 +56,7 @@ SOURCE_FILE ATTR POUND "#" L_BRACK "[" - META + PATH_META PATH PATH_SEGMENT NAME_REF diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 86516b6079..c1806c82c7 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -2442,8 +2442,7 @@ fn run_rustfmt( } RustfmtConfig::CustomCommand { command, args } => { let cmd = Utf8PathBuf::from(&command); - let target_spec = - crates.first().and_then(|&crate_id| snap.target_spec_for_file(file_id, crate_id)); + let target_spec = TargetSpec::for_file(snap, file_id).ok().flatten(); let extra_env = snap.config.extra_env(source_root_id); let mut cmd = match target_spec { Some(TargetSpec::Cargo(_)) => { diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs index 01196b80cd..5bdc9d8ca3 100644 --- a/crates/rust-analyzer/src/target_spec.rs +++ b/crates/rust-analyzer/src/target_spec.rs @@ -381,23 +381,13 @@ mod tests { SmolStr, ast::{self, AstNode}, }; - use syntax_bridge::{ - DocCommentDesugarMode, - dummy_test_span_utils::{DUMMY, DummyTestSpanMap}, - syntax_node_to_token_tree, - }; fn check(cfg: &str, expected_features: &[&str]) { let cfg_expr = { let source_file = ast::SourceFile::parse(cfg, Edition::CURRENT).ok().unwrap(); - let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); - let tt = syntax_node_to_token_tree( - tt.syntax(), - &DummyTestSpanMap, - DUMMY, - DocCommentDesugarMode::Mbe, - ); - CfgExpr::parse(&tt) + let cfg_predicate = + source_file.syntax().descendants().find_map(ast::CfgPredicate::cast).unwrap(); + CfgExpr::parse_from_ast(cfg_predicate) }; let mut features = vec![]; diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 8909fb423c..e65836ed8d 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -21,6 +21,7 @@ rustc-literal-escaper.workspace = true smol_str.workspace = true triomphe.workspace = true tracing.workspace = true +smallvec.workspace = true parser.workspace = true stdx.workspace = true diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram index 3113fc7430..324b2bbd58 100644 --- a/crates/syntax/rust.ungram +++ b/crates/syntax/rust.ungram @@ -126,9 +126,41 @@ MacroStmts = Attr = '#' '!'? '[' Meta ']' +CfgAttrMeta = + 'cfg_attr' '(' CfgPredicate ',' (Meta (',' Meta)* ','?) ')' + +CfgMeta = + 'cfg' '(' CfgPredicate ','? ')' + +CfgPredicate = + CfgAtom +| CfgComposite + +CfgAtom = + ('#ident' | 'true' | 'false') ('=' '@string')? + +CfgComposite = + keyword:'#ident' '(' (CfgPredicate (',' CfgPredicate)* ','?) ')' + Meta = - 'unsafe' '(' Path ('=' Expr | TokenTree)? ')' -| Path ('=' Expr | TokenTree)? + CfgAttrMeta +| CfgMeta +| UnsafeMeta +| PathMeta +| KeyValueMeta +| TokenTreeMeta + +UnsafeMeta = + 'unsafe' '(' Meta ')' + +PathMeta = + Path + +KeyValueMeta = + Path '=' Expr + +TokenTreeMeta = + Path TokenTree //*************************// // Items // diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index 5d67fd4491..dc592a4372 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs @@ -25,9 +25,9 @@ pub use self::{ expr_ext::{ArrayExprKind, BlockModifier, CallableExpr, ElseBranch, LiteralKind}, generated::{nodes::*, tokens::*}, node_ext::{ - AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind, - SlicePatComponents, StructKind, TokenTreeChildren, TypeBoundKind, TypeOrConstParam, - VisibilityKind, + AttrKind, CfgAtomKey, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, + SelfParamKind, SlicePatComponents, StructKind, TokenTreeChildren, TypeBoundKind, + TypeOrConstParam, VisibilityKind, }, operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp}, token_ext::{ diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 7334de0fd9..cd7f6a018a 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -377,6 +377,68 @@ impl CastExpr { #[inline] pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) } } +pub struct CfgAtom { + pub(crate) syntax: SyntaxNode, +} +impl CfgAtom { + #[inline] + pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) } + #[inline] + pub fn false_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![false]) } + #[inline] + pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } + #[inline] + pub fn string_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![string]) } + #[inline] + pub fn true_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![true]) } +} +pub struct CfgAttrMeta { + pub(crate) syntax: SyntaxNode, +} +impl CfgAttrMeta { + #[inline] + pub fn cfg_predicate(&self) -> Option<CfgPredicate> { support::child(&self.syntax) } + #[inline] + pub fn metas(&self) -> AstChildren<Meta> { support::children(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } + #[inline] + pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) } + #[inline] + pub fn cfg_attr_token(&self) -> Option<SyntaxToken> { + support::token(&self.syntax, T![cfg_attr]) + } +} +pub struct CfgComposite { + pub(crate) syntax: SyntaxNode, +} +impl CfgComposite { + #[inline] + pub fn cfg_predicates(&self) -> AstChildren<CfgPredicate> { support::children(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } + #[inline] + pub fn keyword(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) } +} +pub struct CfgMeta { + pub(crate) syntax: SyntaxNode, +} +impl CfgMeta { + #[inline] + pub fn cfg_predicate(&self) -> Option<CfgPredicate> { support::child(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } + #[inline] + pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) } + #[inline] + pub fn cfg_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![cfg]) } +} pub struct ClosureExpr { pub(crate) syntax: SyntaxNode, } @@ -783,6 +845,17 @@ impl ItemList { #[inline] pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } } +pub struct KeyValueMeta { + pub(crate) syntax: SyntaxNode, +} +impl KeyValueMeta { + #[inline] + pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } + #[inline] + pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } + #[inline] + pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) } +} pub struct Label { pub(crate) syntax: SyntaxNode, } @@ -1012,25 +1085,6 @@ impl MatchGuard { #[inline] pub fn if_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![if]) } } -pub struct Meta { - pub(crate) syntax: SyntaxNode, -} -impl Meta { - #[inline] - pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } - #[inline] - pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } - #[inline] - pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } - #[inline] - pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } - #[inline] - pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } - #[inline] - pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) } - #[inline] - pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } -} pub struct MethodCallExpr { pub(crate) syntax: SyntaxNode, } @@ -1225,6 +1279,13 @@ impl PathExpr { #[inline] pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } } +pub struct PathMeta { + pub(crate) syntax: SyntaxNode, +} +impl PathMeta { + #[inline] + pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } +} pub struct PathPat { pub(crate) syntax: SyntaxNode, } @@ -1607,6 +1668,15 @@ impl TokenTree { #[inline] pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } } +pub struct TokenTreeMeta { + pub(crate) syntax: SyntaxNode, +} +impl TokenTreeMeta { + #[inline] + pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } + #[inline] + pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } +} pub struct Trait { pub(crate) syntax: SyntaxNode, } @@ -1834,6 +1904,19 @@ impl Union { #[inline] pub fn union_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![union]) } } +pub struct UnsafeMeta { + pub(crate) syntax: SyntaxNode, +} +impl UnsafeMeta { + #[inline] + pub fn meta(&self) -> Option<Meta> { support::child(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) } + #[inline] + pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } +} pub struct Use { pub(crate) syntax: SyntaxNode, } @@ -2025,6 +2108,12 @@ impl ast::HasAttrs for AssocItem {} impl ast::HasDocComments for AssocItem {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum CfgPredicate { + CfgAtom(CfgAtom), + CfgComposite(CfgComposite), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Expr { ArrayExpr(ArrayExpr), AsmExpr(AsmExpr), @@ -2119,6 +2208,16 @@ pub enum Item { impl ast::HasAttrs for Item {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Meta { + CfgAttrMeta(CfgAttrMeta), + CfgMeta(CfgMeta), + KeyValueMeta(KeyValueMeta), + PathMeta(PathMeta), + TokenTreeMeta(TokenTreeMeta), + UnsafeMeta(UnsafeMeta), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Pat { BoxPat(BoxPat), ConstBlockPat(ConstBlockPat), @@ -3133,6 +3232,134 @@ impl fmt::Debug for CastExpr { f.debug_struct("CastExpr").field("syntax", &self.syntax).finish() } } +impl AstNode for CfgAtom { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CFG_ATOM + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == CFG_ATOM } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for CfgAtom { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for CfgAtom {} +impl PartialEq for CfgAtom { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for CfgAtom { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for CfgAtom { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CfgAtom").field("syntax", &self.syntax).finish() + } +} +impl AstNode for CfgAttrMeta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CFG_ATTR_META + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == CFG_ATTR_META } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for CfgAttrMeta { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for CfgAttrMeta {} +impl PartialEq for CfgAttrMeta { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for CfgAttrMeta { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for CfgAttrMeta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CfgAttrMeta").field("syntax", &self.syntax).finish() + } +} +impl AstNode for CfgComposite { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CFG_COMPOSITE + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == CFG_COMPOSITE } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for CfgComposite { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for CfgComposite {} +impl PartialEq for CfgComposite { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for CfgComposite { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for CfgComposite { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CfgComposite").field("syntax", &self.syntax).finish() + } +} +impl AstNode for CfgMeta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CFG_META + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == CFG_META } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for CfgMeta { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for CfgMeta {} +impl PartialEq for CfgMeta { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for CfgMeta { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for CfgMeta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CfgMeta").field("syntax", &self.syntax).finish() + } +} impl AstNode for ClosureExpr { #[inline] fn kind() -> SyntaxKind @@ -4093,6 +4320,38 @@ impl fmt::Debug for ItemList { f.debug_struct("ItemList").field("syntax", &self.syntax).finish() } } +impl AstNode for KeyValueMeta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + KEY_VALUE_META + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == KEY_VALUE_META } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for KeyValueMeta { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for KeyValueMeta {} +impl PartialEq for KeyValueMeta { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for KeyValueMeta { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for KeyValueMeta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("KeyValueMeta").field("syntax", &self.syntax).finish() + } +} impl AstNode for Label { #[inline] fn kind() -> SyntaxKind @@ -4797,38 +5056,6 @@ impl fmt::Debug for MatchGuard { f.debug_struct("MatchGuard").field("syntax", &self.syntax).finish() } } -impl AstNode for Meta { - #[inline] - fn kind() -> SyntaxKind - where - Self: Sized, - { - META - } - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { kind == META } - #[inline] - fn cast(syntax: SyntaxNode) -> Option<Self> { - if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } - } - #[inline] - fn syntax(&self) -> &SyntaxNode { &self.syntax } -} -impl hash::Hash for Meta { - fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } -} -impl Eq for Meta {} -impl PartialEq for Meta { - fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } -} -impl Clone for Meta { - fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } -} -impl fmt::Debug for Meta { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Meta").field("syntax", &self.syntax).finish() - } -} impl AstNode for MethodCallExpr { #[inline] fn kind() -> SyntaxKind @@ -5309,6 +5536,38 @@ impl fmt::Debug for PathExpr { f.debug_struct("PathExpr").field("syntax", &self.syntax).finish() } } +impl AstNode for PathMeta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PATH_META + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_META } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for PathMeta { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for PathMeta {} +impl PartialEq for PathMeta { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for PathMeta { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for PathMeta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PathMeta").field("syntax", &self.syntax).finish() + } +} impl AstNode for PathPat { #[inline] fn kind() -> SyntaxKind @@ -6301,6 +6560,38 @@ impl fmt::Debug for TokenTree { f.debug_struct("TokenTree").field("syntax", &self.syntax).finish() } } +impl AstNode for TokenTreeMeta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TOKEN_TREE_META + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == TOKEN_TREE_META } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for TokenTreeMeta { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for TokenTreeMeta {} +impl PartialEq for TokenTreeMeta { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for TokenTreeMeta { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for TokenTreeMeta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TokenTreeMeta").field("syntax", &self.syntax).finish() + } +} impl AstNode for Trait { #[inline] fn kind() -> SyntaxKind @@ -6845,6 +7136,38 @@ impl fmt::Debug for Union { f.debug_struct("Union").field("syntax", &self.syntax).finish() } } +impl AstNode for UnsafeMeta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + UNSAFE_META + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == UNSAFE_META } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for UnsafeMeta { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for UnsafeMeta {} +impl PartialEq for UnsafeMeta { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for UnsafeMeta { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for UnsafeMeta { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("UnsafeMeta").field("syntax", &self.syntax).finish() + } +} impl AstNode for Use { #[inline] fn kind() -> SyntaxKind @@ -7413,6 +7736,34 @@ impl AstNode for AssocItem { } } } +impl From<CfgAtom> for CfgPredicate { + #[inline] + fn from(node: CfgAtom) -> CfgPredicate { CfgPredicate::CfgAtom(node) } +} +impl From<CfgComposite> for CfgPredicate { + #[inline] + fn from(node: CfgComposite) -> CfgPredicate { CfgPredicate::CfgComposite(node) } +} +impl AstNode for CfgPredicate { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, CFG_ATOM | CFG_COMPOSITE) } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + let res = match syntax.kind() { + CFG_ATOM => CfgPredicate::CfgAtom(CfgAtom { syntax }), + CFG_COMPOSITE => CfgPredicate::CfgComposite(CfgComposite { syntax }), + _ => return None, + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + CfgPredicate::CfgAtom(it) => &it.syntax, + CfgPredicate::CfgComposite(it) => &it.syntax, + } + } +} impl From<ArrayExpr> for Expr { #[inline] fn from(node: ArrayExpr) -> Expr { Expr::ArrayExpr(node) } @@ -7970,6 +8321,63 @@ impl AstNode for Item { } } } +impl From<CfgAttrMeta> for Meta { + #[inline] + fn from(node: CfgAttrMeta) -> Meta { Meta::CfgAttrMeta(node) } +} +impl From<CfgMeta> for Meta { + #[inline] + fn from(node: CfgMeta) -> Meta { Meta::CfgMeta(node) } +} +impl From<KeyValueMeta> for Meta { + #[inline] + fn from(node: KeyValueMeta) -> Meta { Meta::KeyValueMeta(node) } +} +impl From<PathMeta> for Meta { + #[inline] + fn from(node: PathMeta) -> Meta { Meta::PathMeta(node) } +} +impl From<TokenTreeMeta> for Meta { + #[inline] + fn from(node: TokenTreeMeta) -> Meta { Meta::TokenTreeMeta(node) } +} +impl From<UnsafeMeta> for Meta { + #[inline] + fn from(node: UnsafeMeta) -> Meta { Meta::UnsafeMeta(node) } +} +impl AstNode for Meta { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + CFG_ATTR_META | CFG_META | KEY_VALUE_META | PATH_META | TOKEN_TREE_META | UNSAFE_META + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + let res = match syntax.kind() { + CFG_ATTR_META => Meta::CfgAttrMeta(CfgAttrMeta { syntax }), + CFG_META => Meta::CfgMeta(CfgMeta { syntax }), + KEY_VALUE_META => Meta::KeyValueMeta(KeyValueMeta { syntax }), + PATH_META => Meta::PathMeta(PathMeta { syntax }), + TOKEN_TREE_META => Meta::TokenTreeMeta(TokenTreeMeta { syntax }), + UNSAFE_META => Meta::UnsafeMeta(UnsafeMeta { syntax }), + _ => return None, + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + Meta::CfgAttrMeta(it) => &it.syntax, + Meta::CfgMeta(it) => &it.syntax, + Meta::KeyValueMeta(it) => &it.syntax, + Meta::PathMeta(it) => &it.syntax, + Meta::TokenTreeMeta(it) => &it.syntax, + Meta::UnsafeMeta(it) => &it.syntax, + } + } +} impl From<BoxPat> for Pat { #[inline] fn from(node: BoxPat) -> Pat { Pat::BoxPat(node) } @@ -9334,6 +9742,11 @@ impl std::fmt::Display for AssocItem { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for CfgPredicate { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Expr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -9364,6 +9777,11 @@ impl std::fmt::Display for Item { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for Meta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Pat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -9524,6 +9942,26 @@ impl std::fmt::Display for CastExpr { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for CfgAtom { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl std::fmt::Display for CfgAttrMeta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl std::fmt::Display for CfgComposite { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} +impl std::fmt::Display for CfgMeta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for ClosureExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -9674,6 +10112,11 @@ impl std::fmt::Display for ItemList { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for KeyValueMeta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Label { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -9784,11 +10227,6 @@ impl std::fmt::Display for MatchGuard { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for Meta { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for MethodCallExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -9864,6 +10302,11 @@ impl std::fmt::Display for PathExpr { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for PathMeta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for PathPat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -10019,6 +10462,11 @@ impl std::fmt::Display for TokenTree { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for TokenTreeMeta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Trait { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -10104,6 +10552,11 @@ impl std::fmt::Display for Union { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for UnsafeMeta { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Use { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 00971569a2..ac02cc9e43 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -1322,6 +1322,18 @@ pub fn meta_path(path: ast::Path) -> ast::Meta { ast_from_text(&format!("#[{path}]")) } +pub fn cfg_attr_meta( + predicate: ast::CfgPredicate, + inner: impl IntoIterator<Item = ast::Meta>, +) -> ast::CfgAttrMeta { + let inner = inner.into_iter().join(", "); + ast_from_text(&format!("#![cfg_attr({predicate}, {inner})]")) +} + +pub fn cfg_flag(flag: &str) -> ast::CfgPredicate { + ast_from_text(&format!("#![cfg({flag})]")) +} + pub fn token_tree( delimiter: SyntaxKind, tt: impl IntoIterator<Item = NodeOrToken<ast::TokenTree, SyntaxToken>>, diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 3fc3b39fee..03118d01dc 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -8,6 +8,7 @@ use std::{borrow::Cow, fmt, iter::successors}; use itertools::Itertools; use parser::SyntaxKind; use rowan::{GreenNodeData, GreenTokenData}; +use smallvec::{SmallVec, smallvec}; use crate::{ NodeOrToken, SmolStr, SyntaxElement, SyntaxElementChildren, SyntaxToken, T, TokenText, @@ -201,53 +202,95 @@ impl AttrKind { } } -impl ast::Attr { +impl ast::Meta { pub fn as_simple_atom(&self) -> Option<SmolStr> { - let meta = self.meta()?; - if meta.eq_token().is_some() || meta.token_tree().is_some() { - return None; - } - self.simple_name() + Some(self.as_simple_path()?.as_single_name_ref()?.text().into()) } pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> { - let tt = self.meta()?.token_tree()?; - Some((self.simple_name()?, tt)) + let ast::Meta::TokenTreeMeta(meta) = self else { return None }; + Some((meta.path()?.as_single_name_ref()?.text().into(), meta.token_tree()?)) } pub fn as_simple_path(&self) -> Option<ast::Path> { - let meta = self.meta()?; - if meta.eq_token().is_some() || meta.token_tree().is_some() { - return None; - } - self.path() + let ast::Meta::PathMeta(meta) = self else { return None }; + meta.path() } pub fn simple_name(&self) -> Option<SmolStr> { - let path = self.meta()?.path()?; - match (path.segment(), path.qualifier()) { - (Some(segment), None) => Some(segment.syntax().first_token()?.text().into()), - _ => None, + match self { + ast::Meta::CfgAttrMeta(_) => Some(SmolStr::new_static("cfg_attr")), + ast::Meta::CfgMeta(_) => Some(SmolStr::new_static("cfg")), + _ => { + let path = self.path()?; + match (path.segment(), path.qualifier()) { + (Some(segment), None) => Some(segment.syntax().first_token()?.text().into()), + _ => None, + } + } } } - pub fn kind(&self) -> AttrKind { - match self.excl_token() { - Some(_) => AttrKind::Inner, - None => AttrKind::Outer, + pub fn path(&self) -> Option<ast::Path> { + match self { + ast::Meta::CfgAttrMeta(_) | ast::Meta::CfgMeta(_) => None, + ast::Meta::KeyValueMeta(it) => it.path(), + ast::Meta::PathMeta(it) => it.path(), + ast::Meta::TokenTreeMeta(it) => it.path(), + ast::Meta::UnsafeMeta(it) => it.meta()?.path(), } } + /// Includes `cfg_attr()` inner metas (without considering the predicate). + pub fn skip_cfg_attrs(self) -> SmallVec<[ast::Meta; 1]> { + match self { + ast::Meta::CfgAttrMeta(meta) => { + meta.metas().flat_map(|meta| meta.skip_cfg_attrs()).collect() + } + _ => smallvec![self], + } + } + + /// FIXME: Calling this is almost always incorrect, as `cfg_attr` can contains multiple `Meta`s. + pub fn parent_attr(&self) -> Option<ast::Attr> { + self.syntax().ancestors().find_map(ast::Attr::cast) + } +} + +impl ast::Attr { + pub fn as_simple_atom(&self) -> Option<SmolStr> { + self.meta().and_then(|meta| meta.as_simple_atom()) + } + + pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> { + self.meta().and_then(|meta| meta.as_simple_call()) + } + + pub fn as_simple_path(&self) -> Option<ast::Path> { + self.meta().and_then(|meta| meta.as_simple_path()) + } + + pub fn simple_name(&self) -> Option<SmolStr> { + self.meta().and_then(|meta| meta.simple_name()) + } + pub fn path(&self) -> Option<ast::Path> { - self.meta()?.path() + self.meta().and_then(|meta| meta.path()) } - pub fn expr(&self) -> Option<ast::Expr> { - self.meta()?.expr() + pub fn kind(&self) -> AttrKind { + match self.excl_token() { + Some(_) => AttrKind::Inner, + None => AttrKind::Outer, + } } - pub fn token_tree(&self) -> Option<ast::TokenTree> { - self.meta()?.token_tree() + /// Includes `cfg_attr()` inner metas (without considering the predicate). + pub fn skip_cfg_attrs(&self) -> SmallVec<[ast::Meta; 1]> { + match self.meta() { + Some(meta) => meta.skip_cfg_attrs(), + None => SmallVec::new(), + } } } @@ -1015,12 +1058,6 @@ impl ast::TokenTree { } } -impl ast::Meta { - pub fn parent_attr(&self) -> Option<ast::Attr> { - self.syntax().parent().and_then(ast::Attr::cast) - } -} - impl ast::GenericArgList { pub fn lifetime_args(&self) -> impl Iterator<Item = ast::LifetimeArg> { self.generic_args().filter_map(|arg| match arg { @@ -1164,6 +1201,25 @@ impl ast::OrPat { } } +#[derive(Debug, Clone)] +pub enum CfgAtomKey { + True, + False, + Ident(SyntaxToken), +} + +impl ast::CfgAtom { + pub fn key(&self) -> Option<CfgAtomKey> { + if self.true_token().is_some() { + Some(CfgAtomKey::True) + } else if self.false_token().is_some() { + Some(CfgAtomKey::False) + } else { + self.ident_token().map(CfgAtomKey::Ident) + } + } +} + /// An iterator over the elements in an [`ast::TokenTree`]. /// /// Does not yield trivia or the delimiters. diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs index e91e444a32..c66f096e83 100644 --- a/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -1848,7 +1848,36 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone()); - builder.map_node(tt.syntax().clone(), ast.token_tree().unwrap().syntax().clone()); + let ast::Meta::TokenTreeMeta(meta) = &ast else { unreachable!() }; + builder.map_node(tt.syntax().clone(), meta.token_tree().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn cfg_flag(&self, flag: &str) -> ast::CfgPredicate { + make::cfg_flag(flag).clone_for_update() + } + + pub fn cfg_attr_meta( + &self, + predicate: ast::CfgPredicate, + inner: impl IntoIterator<Item = ast::Meta>, + ) -> ast::CfgAttrMeta { + let inner = Vec::from_iter(inner); + let ast = make::cfg_attr_meta(predicate.clone(), inner.iter().cloned()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node( + predicate.syntax().clone(), + ast.cfg_predicate().unwrap().syntax().clone(), + ); + builder.map_children( + inner.iter().map(|it| it.syntax().clone()), + ast.metas().map(|it| it.syntax().clone()), + ); builder.finish(&mut mapping); } diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs index 2f4109a2c9..6fe5abb84e 100644 --- a/crates/syntax/src/ast/traits.rs +++ b/crates/syntax/src/ast/traits.rs @@ -73,9 +73,6 @@ pub trait HasAttrs: AstNode { fn attrs(&self) -> AstChildren<ast::Attr> { support::children(self.syntax()) } - fn has_atom_attr(&self, atom: &str) -> bool { - self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom) - } /// This may return the same node as called with (with `SourceFile`). The caller has the responsibility /// to avoid duplicate attributes. diff --git a/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast b/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast index 50057a02d8..5fdde93c60 100644 --- a/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast +++ b/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast @@ -29,7 +29,7 @@ [email protected] @@ -60,7 +60,7 @@ [email protected] @@ -75,7 +75,7 @@ [email protected] @@ -104,7 +104,7 @@ [email protected] diff --git a/xtask/src/codegen/grammar.rs b/xtask/src/codegen/grammar.rs index 4e980bb3d9..257429c426 100644 --- a/xtask/src/codegen/grammar.rs +++ b/xtask/src/codegen/grammar.rs @@ -780,7 +780,7 @@ impl Field { } fn token_kind(&self) -> Option<proc_macro2::TokenStream> { match self { - Field::Token(token) => { + Field::Token { token, .. } => { let token: proc_macro2::TokenStream = token.parse().unwrap(); Some(quote! { T![#token] }) } @@ -789,8 +789,11 @@ impl Field { } fn method_name(&self) -> String { match self { - Field::Token(name) => { - let name = match name.as_str() { + Field::Token { name, token, .. } => { + if let Some(name) = name { + return name.clone(); + } + let name = match token.as_str() { ";" => "semicolon", "->" => "thin_arrow", "'{'" => "l_curly", @@ -820,7 +823,7 @@ impl Field { "," => "comma", "|" => "pipe", "~" => "tilde", - _ => name, + _ => token, }; format!("{name}_token",) } @@ -835,7 +838,7 @@ impl Field { } fn ty(&self) -> proc_macro2::Ident { match self { - Field::Token(_) => format_ident!("SyntaxToken"), + Field::Token { .. } => format_ident!("SyntaxToken"), Field::Node { ty, .. } => format_ident!("{}", ty), } } @@ -885,7 +888,7 @@ fn lower(grammar: &Grammar) -> AstSrc { res.nodes.iter_mut().for_each(|it| { it.traits.sort(); it.fields.sort_by_key(|it| match it { - Field::Token(name) => (true, name.clone()), + Field::Token { token, .. } => (true, token.clone()), Field::Node { name, .. } => (false, name.clone()), }); }); @@ -925,12 +928,11 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, r acc.push(field); } Rule::Token(token) => { - assert!(label.is_none()); - let mut name = clean_token_name(&grammar[*token].name); - if "[]{}()".contains(&name) { - name = format!("'{name}'"); + let mut token = clean_token_name(&grammar[*token].name); + if "[]{}()".contains(&token) { + token = format!("'{token}'"); } - let field = Field::Token(name); + let field = Field::Token { name: label.cloned(), token }; acc.push(field); } Rule::Rep(inner) => { @@ -1018,8 +1020,8 @@ fn lower_separated_list( } match nt { Either::Right(token) => { - let name = clean_token_name(&grammar[*token].name); - let field = Field::Token(name); + let token = clean_token_name(&grammar[*token].name); + let field = Field::Token { token, name: None }; acc.push(field); } Either::Left(node) => { diff --git a/xtask/src/codegen/grammar/ast_src.rs b/xtask/src/codegen/grammar/ast_src.rs index 564d9cc24e..a0abdf09d3 100644 --- a/xtask/src/codegen/grammar/ast_src.rs +++ b/xtask/src/codegen/grammar/ast_src.rs @@ -111,8 +111,19 @@ const RESERVED: &[&str] = &[ ]; // keywords that are keywords only in specific parse contexts #[doc(alias = "WEAK_KEYWORDS")] -const CONTEXTUAL_KEYWORDS: &[&str] = - &["macro_rules", "union", "default", "raw", "dyn", "auto", "yeet", "safe", "bikeshed"]; +const CONTEXTUAL_KEYWORDS: &[&str] = &[ + "macro_rules", + "union", + "default", + "raw", + "dyn", + "auto", + "yeet", + "safe", + "bikeshed", + "cfg_attr", + "cfg", +]; // keywords we use for special macro expansions const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &[ "asm", @@ -261,7 +272,7 @@ pub(crate) struct AstNodeSrc { #[derive(Debug, Eq, PartialEq)] pub(crate) enum Field { - Token(String), + Token { name: Option<String>, token: String }, Node { name: String, ty: String, cardinality: Cardinality }, } diff --git a/xtask/src/codegen/lints.rs b/xtask/src/codegen/lints.rs index 3b4c2e8da3..788ae8d6c1 100644 --- a/xtask/src/codegen/lints.rs +++ b/xtask/src/codegen/lints.rs @@ -83,7 +83,7 @@ pub struct LintGroup { let lints_json = project_root().join("./target/clippy_lints.json"); cmd!( sh, - "curl https://rust-lang.github.io/rust-clippy/stable/lints.json --output {lints_json}" + "curl -f https://raw.githubusercontent.com/rust-lang/rust-clippy/21fd71e3fe6eb063cfb619ecc37b1023f5283894/beta/lints.json --output {lints_json}" ) .run() .unwrap(); |