diff --git a/Cargo.lock b/Cargo.lock index 563d99d5475c4..2952bbea8b0bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5540,9 +5540,9 @@ dependencies = [ [[package]] name = "thin-vec" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" +checksum = "da322882471314edc77fa5232c587bcb87c9df52bfd0d7d4826f8868ead61899" [[package]] name = "thiserror" diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ec6eb7e7dc106..450a93ee8481e 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -47,6 +47,8 @@ use bitflags::bitflags; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; #[cfg(feature = "nightly")] +use rustc_error_messages::{DiagArgValue, IntoDiagArg}; +#[cfg(feature = "nightly")] use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg}; use rustc_hashes::Hash64; use rustc_index::{Idx, IndexSlice, IndexVec}; @@ -1775,6 +1777,24 @@ impl NumScalableVectors { } } +#[cfg(feature = "nightly")] +impl IntoDiagArg for NumScalableVectors { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + DiagArgValue::Str(std::borrow::Cow::Borrowed(match self.0 { + 0 => panic!("`NumScalableVectors(0)` is illformed"), + 1 => "one", + 2 => "two", + 3 => "three", + 4 => "four", + 5 => "five", + 6 => "six", + 7 => "seven", + 8 => "eight", + _ => panic!("`NumScalableVectors(N)` for N>8 is illformed"), + })) + } +} + /// The way we represent values to the backend /// /// Previously this was conflated with the "ABI" a type is given, as in the platform-specific ABI. diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 471a6bf1df131..97256963118f3 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -15,6 +15,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index c00bac5d3c5a5..42befe958633b 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -23,6 +23,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index ffc47f6807da9..ee4a52fb3863e 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -433,7 +433,6 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // also nested delegations may need to access information about this code (#154332), // so it is better to leave this code as opposed to bodies of extern functions, // which are completely erased from existence. - // FIXME(fn_delegation): fix `help` in error message (see `inner-attr.stderr`) if param_count == 0 && let Some(block) = block { diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index 4e960e3b9290c..fa51772b40027 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -10,18 +10,38 @@ use rustc_span::{Ident, Span}; use crate::{LoweringContext, ResolverAstLoweringExt}; -pub(super) enum DelegationGenerics { +#[derive(Clone, Copy)] +pub(super) enum DelegationGenericsKind { /// User-specified args are present: `reuse foo::;`. UserSpecified, /// The default case when no user-specified args are present: `reuse Trait::foo;`. - Default(T), + Default, /// In free-to-trait reuse, when user specified args for trait `reuse Trait::::foo;` /// in this case we need to both generate `Self` and process user args. - SelfAndUserSpecified(T), + SelfAndUserSpecified, /// In delegations from trait impl to other entities like free functions or trait functions, /// we want to generate a function whose generics matches generics of signature function /// in trait. - TraitImpl(T, bool /* Has user-specified args */), + TraitImpl(bool /* Has user-specified args */), +} + +pub(super) struct DelegationGenerics { + generics: T, + kind: DelegationGenericsKind, +} + +impl<'hir> DelegationGenerics<&'hir [ty::GenericParamDef]> { + fn default(generics: &'hir [ty::GenericParamDef]) -> Self { + DelegationGenerics { generics, kind: DelegationGenericsKind::Default } + } + + fn user_specified(generics: &'hir [ty::GenericParamDef]) -> Self { + DelegationGenerics { generics, kind: DelegationGenericsKind::UserSpecified } + } + + fn trait_impl(generics: &'hir [ty::GenericParamDef], user_specified: bool) -> Self { + DelegationGenerics { generics, kind: DelegationGenericsKind::TraitImpl(user_specified) } + } } /// Used for storing either ty generics or their uplifted HIR version. First we obtain @@ -54,20 +74,19 @@ pub(super) struct GenericArgsPropagationDetails { pub(super) use_args_in_sig_inheritance: bool, } -impl DelegationGenerics { - fn args_propagation_details(&self) -> GenericArgsPropagationDetails { +impl DelegationGenericsKind { + fn args_propagation_details(self) -> GenericArgsPropagationDetails { match self { - DelegationGenerics::UserSpecified | DelegationGenerics::SelfAndUserSpecified { .. } => { - GenericArgsPropagationDetails { - should_propagate: false, - use_args_in_sig_inheritance: true, - } - } - DelegationGenerics::TraitImpl(_, user_specified) => GenericArgsPropagationDetails { - should_propagate: !*user_specified, + DelegationGenericsKind::UserSpecified + | DelegationGenericsKind::SelfAndUserSpecified => GenericArgsPropagationDetails { + should_propagate: false, + use_args_in_sig_inheritance: true, + }, + DelegationGenericsKind::TraitImpl(user_specified) => GenericArgsPropagationDetails { + should_propagate: !user_specified, use_args_in_sig_inheritance: false, }, - DelegationGenerics::Default(_) => GenericArgsPropagationDetails { + DelegationGenericsKind::Default => GenericArgsPropagationDetails { should_propagate: true, use_args_in_sig_inheritance: false, }, @@ -81,25 +100,9 @@ impl<'hir> HirOrTyGenerics<'hir> { ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, span: Span, ) -> &mut HirOrTyGenerics<'hir> { - if let HirOrTyGenerics::Ty(params) = self { - let mut uplift_params = |generics: &'hir [ty::GenericParamDef]| { - ctx.uplift_delegation_generic_params(span, generics) - }; - - let hir_generics = match params { - DelegationGenerics::UserSpecified => DelegationGenerics::UserSpecified, - DelegationGenerics::Default(params) => { - DelegationGenerics::Default(uplift_params(params)) - } - DelegationGenerics::SelfAndUserSpecified(params) => { - DelegationGenerics::SelfAndUserSpecified(uplift_params(params)) - } - DelegationGenerics::TraitImpl(params, user_specified) => { - DelegationGenerics::TraitImpl(uplift_params(params), *user_specified) - } - }; - - *self = HirOrTyGenerics::Hir(hir_generics); + if let HirOrTyGenerics::Ty(ty) = self { + let params = ctx.uplift_delegation_generic_params(span, ty.generics); + *self = HirOrTyGenerics::Hir(DelegationGenerics { generics: params, kind: ty.kind }); } self @@ -108,12 +111,7 @@ impl<'hir> HirOrTyGenerics<'hir> { fn hir_generics_or_empty(&self) -> &'hir hir::Generics<'hir> { match self { HirOrTyGenerics::Ty(_) => hir::Generics::empty(), - HirOrTyGenerics::Hir(hir_generics) => match hir_generics { - DelegationGenerics::UserSpecified => hir::Generics::empty(), - DelegationGenerics::Default(generics) - | DelegationGenerics::SelfAndUserSpecified(generics) - | DelegationGenerics::TraitImpl(generics, _) => generics, - }, + HirOrTyGenerics::Hir(hir) => hir.generics, } } @@ -127,21 +125,16 @@ impl<'hir> HirOrTyGenerics<'hir> { HirOrTyGenerics::Ty(_) => { bug!("Attempting to get generic args before uplifting to HIR") } - HirOrTyGenerics::Hir(hir_generics) => match hir_generics { - DelegationGenerics::UserSpecified => hir::GenericArgs::NONE, - DelegationGenerics::Default(generics) - | DelegationGenerics::SelfAndUserSpecified(generics) - | DelegationGenerics::TraitImpl(generics, _) => { - ctx.create_generics_args_from_params(generics.params, add_lifetimes, span) - } - }, + HirOrTyGenerics::Hir(hir) => { + ctx.create_generics_args_from_params(hir.generics.params, add_lifetimes, span) + } } } pub(super) fn args_propagation_details(&self) -> GenericArgsPropagationDetails { match self { - HirOrTyGenerics::Ty(ty_generics) => ty_generics.args_propagation_details(), - HirOrTyGenerics::Hir(hir_generics) => hir_generics.args_propagation_details(), + HirOrTyGenerics::Ty(ty) => ty.kind.args_propagation_details(), + HirOrTyGenerics::Hir(hir) => hir.kind.args_propagation_details(), } } } @@ -231,9 +224,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { if matches!(delegation_parent_kind, DefKind::Impl { of_trait: true }) { // Considering parent generics, during signature inheritance // we will take those args that are in trait impl header trait ref. - let parent = GenericsGenerationResult::new(DelegationGenerics::TraitImpl(&[], true)); + let parent = DelegationGenerics::trait_impl(&[], true); + let parent = GenericsGenerationResult::new(parent); - let child = DelegationGenerics::TraitImpl(sig_params, child_user_specified); + let child = DelegationGenerics::trait_impl(sig_params, child_user_specified); let child = GenericsGenerationResult::new(child); return GenericsGenerationResults { parent, child }; @@ -257,22 +251,28 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { if segments[len - 2].args.is_some() { if generate_self { // Take only first Self parameter, it is trait so Self must be present. - DelegationGenerics::SelfAndUserSpecified(&sig_parent_params[..1]) + DelegationGenerics { + kind: DelegationGenericsKind::SelfAndUserSpecified, + generics: &sig_parent_params[..1], + } } else { - DelegationGenerics::UserSpecified + DelegationGenerics::user_specified(&[]) } } else { let skip_self = usize::from(!generate_self); - DelegationGenerics::Default(&sig_parent_params[skip_self..]) + DelegationGenerics::default(&sig_parent_params[skip_self..]) } } else { - DelegationGenerics::<&'hir [ty::GenericParamDef]>::Default(&[]) + DelegationGenerics::default(&[]) }; let child_generics = if child_user_specified { - DelegationGenerics::UserSpecified + let synth_params_index = + sig_params.iter().position(|p| p.kind.is_synthetic()).unwrap_or(sig_params.len()); + + DelegationGenerics::user_specified(&sig_params[synth_params_index..]) } else { - DelegationGenerics::Default(sig_params) + DelegationGenerics::default(sig_params) }; GenericsGenerationResults { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3939cb1901d44..6a89700f59b36 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -38,7 +38,7 @@ pub(super) enum Owners<'a, 'hir> { } impl<'hir> Owners<'_, 'hir> { - pub(super) fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> { + fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> { match self { Owners::IndexVec(index_vec) => { index_vec.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 13971bdb3fd55..6d9fe9870c42e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,7 +39,6 @@ use std::mem; use std::sync::Arc; use rustc_ast::node_id::NodeMap; -use rustc_ast::visit::AssocCtxt; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, Late, OmitDoc}; use rustc_data_structures::fingerprint::Fingerprint; @@ -634,29 +633,13 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut delayed_ids: FxIndexSet = Default::default(); for def_id in ast_index.indices() { - let delayed_owner_kind = match &ast_index[def_id] { - AstOwner::Item(Item { kind: ItemKind::Delegation(_), .. }) => { - Some(hir::DelayedOwnerKind::Item) + match &ast_index[def_id] { + AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) + | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { + delayed_ids.insert(def_id); } - AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(_), .. }, ctx) => { - Some(match ctx { - AssocCtxt::Trait => hir::DelayedOwnerKind::TraitItem, - AssocCtxt::Impl { .. } => hir::DelayedOwnerKind::ImplItem, - }) - } - _ => None, + _ => lowerer.lower_node(def_id), }; - - if let Some(kind) = delayed_owner_kind { - delayed_ids.insert(def_id); - - let owner = lowerer.owners.get_or_insert_mut(def_id); - if let hir::MaybeOwner::Phantom = owner { - *owner = hir::MaybeOwner::Delayed(kind) - } - } else { - lowerer.lower_node(def_id); - } } // Don't hash unless necessary, because it's expensive. diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index c9def6246d1b1..42cbd7b3d3620 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -18,5 +18,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.12" +thin-vec = "0.2.15" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index b704040be9618..957fc1297c58e 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -13,5 +13,5 @@ rustc_span = { path = "../rustc_span" } [dev-dependencies] # tidy-alphabetical-start -thin-vec = "0.2.12" +thin-vec = "0.2.15" # tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index 886df58e8d6f0..fc83c3b6e9bca 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -19,5 +19,5 @@ rustc_parse_format = { path = "../rustc_parse_format" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.12" +thin-vec = "0.2.15" # tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 866b53e4c0d9b..0559469bc3691 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -2,6 +2,7 @@ use std::num::NonZero; use rustc_errors::ErrorGuaranteed; use rustc_feature::ACCEPTED_LANG_FEATURES; +use rustc_hir::attrs::UnstableRemovedFeature; use rustc_hir::target::GenericParamKind; use rustc_hir::{ DefaultBodyStability, MethodKind, PartialConstStability, Stability, StabilityLevel, @@ -476,3 +477,89 @@ pub(crate) fn parse_unstability( (Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None, } } + +pub(crate) struct UnstableRemovedParser; + +impl CombineAttributeParser for UnstableRemovedParser { + type Item = UnstableRemovedFeature; + const PATH: &[Symbol] = &[sym::unstable_removed]; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const TEMPLATE: AttributeTemplate = + template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]); + + const CONVERT: ConvertFn = |items, _| AttributeKind::UnstableRemoved(items); + + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { + let mut feature = None; + let mut reason = None; + let mut link = None; + let mut since = None; + + if !cx.features().staged_api() { + cx.emit_err(session_diagnostics::StabilityOutsideStd { span: cx.attr_span }); + return None; + } + + let ArgParser::List(list) = args else { + let attr_span = cx.attr_span; + cx.adcx().expected_list(attr_span, args); + return None; + }; + + for param in list.mixed() { + let Some(param) = param.meta_item() else { + cx.adcx().expected_not_literal(param.span()); + return None; + }; + + let Some(word) = param.path().word() else { + cx.adcx().expected_specific_argument( + param.span(), + &[sym::feature, sym::reason, sym::link, sym::since], + ); + return None; + }; + match word.name { + sym::feature => insert_value_into_option_or_error(cx, ¶m, &mut feature, word)?, + sym::since => insert_value_into_option_or_error(cx, ¶m, &mut since, word)?, + sym::reason => insert_value_into_option_or_error(cx, ¶m, &mut reason, word)?, + sym::link => insert_value_into_option_or_error(cx, ¶m, &mut link, word)?, + _ => { + cx.adcx().expected_specific_argument( + param.span(), + &[sym::feature, sym::reason, sym::link, sym::since], + ); + return None; + } + } + } + + // Check all the arguments are present + let Some(feature) = feature else { + cx.adcx().missing_name_value(list.span, sym::feature); + return None; + }; + let Some(reason) = reason else { + cx.adcx().missing_name_value(list.span, sym::reason); + return None; + }; + let Some(link) = link else { + cx.adcx().missing_name_value(list.span, sym::link); + return None; + }; + let Some(since) = since else { + cx.adcx().missing_name_value(list.span, sym::since); + return None; + }; + + let Some(version) = parse_version(since) else { + cx.emit_err(session_diagnostics::InvalidSince { span: cx.attr_span }); + return None; + }; + + Some(UnstableRemovedFeature { feature, reason, link, since: version }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index cfc5be3f0b9b4..51345162ee071 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -179,6 +179,7 @@ attribute_parsers!( Combine, Combine, Combine, + Combine, // tidy-alphabetical-end // tidy-alphabetical-start @@ -776,6 +777,11 @@ where self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNameValue(name)) } + /// Emit an error that a `name = value` argument is missing in a list of name-value pairs. + pub(crate) fn missing_name_value(&mut self, span: Span, name: Symbol) -> ErrorGuaranteed { + self.emit_parse_error(span, AttributeParseErrorReason::MissingNameValue(name)) + } + /// Emit an error that a `name = value` pair was found where that name was already seen. pub(crate) fn duplicate_key(&mut self, span: Span, key: Symbol) -> ErrorGuaranteed { self.emit_parse_error(span, AttributeParseErrorReason::DuplicateKey(key)) diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index ace233acbd50b..203c7f8ebff1b 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -568,6 +568,7 @@ pub(crate) enum AttributeParseErrorReason<'a> { ExpectedNonEmptyStringLiteral, ExpectedNotLiteral, ExpectedNameValue(Option), + MissingNameValue(Symbol), DuplicateKey(Symbol), ExpectedSpecificArgument { possibilities: &'a [Symbol], @@ -823,6 +824,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { format!("expected this to be of the form `{name} = \"...\"`"), ); } + AttributeParseErrorReason::MissingNameValue(name) => { + diag.span_label(self.span, format!("missing argument `{name} = \"...\"`")); + } AttributeParseErrorReason::ExpectedSpecificArgument { possibilities, strings, diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index dd84a2c1802d5..ebf25d68314db 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -29,7 +29,7 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index c74e0b9b1a669..4329c5d682cb8 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -380,11 +380,9 @@ fn codegen_cgu_content( fn module_codegen( tcx: TyCtxt<'_>, - (global_asm_config, cgu_name, token): ( - Arc, - rustc_span::Symbol, - ConcurrencyLimiterToken, - ), + global_asm_config: Arc, + cgu_name: rustc_span::Symbol, + token: ConcurrencyLimiterToken, ) -> OngoingModuleCodegen { let mut module = make_module(tcx.sess, cgu_name.as_str().to_string()); @@ -513,8 +511,14 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box { let (module, _) = tcx.dep_graph.with_task( dep_node, tcx, - (global_asm_config.clone(), cgu.name(), concurrency_limiter.acquire(tcx.dcx())), - module_codegen, + || { + module_codegen( + tcx, + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.dcx()), + ) + }, Some(rustc_middle::dep_graph::hash_result), ); IntoDynSyncSend(module) diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index 73b0723895b4a..7d63f430af685 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -83,8 +83,7 @@ pub fn compile_codegen_unit( let (module, _) = tcx.dep_graph.with_task( dep_node, tcx, - (cgu_name, target_info, lto_supported), - module_codegen, + || module_codegen(tcx, cgu_name, target_info, lto_supported), Some(dep_graph::hash_result), ); let time_to_codegen = start_time.elapsed(); @@ -96,7 +95,9 @@ pub fn compile_codegen_unit( fn module_codegen( tcx: TyCtxt<'_>, - (cgu_name, target_info, lto_supported): (Symbol, LockedTargetInfo, bool), + cgu_name: Symbol, + target_info: LockedTargetInfo, + lto_supported: bool, ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index e1a6785942638..a7dec13422f46 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -65,8 +65,7 @@ pub(crate) fn compile_codegen_unit( let (module, _) = tcx.dep_graph.with_task( dep_node, tcx, - cgu_name, - module_codegen, + || module_codegen(tcx, cgu_name), Some(dep_graph::hash_result), ); let time_to_codegen = start_time.elapsed(); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3e600914d6f42..3663f66f9c1fd 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -606,27 +606,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.pointercast(val, self.type_ptr()) } - sym::sve_cast => { - let Some((in_cnt, in_elem, in_num_vecs)) = - args[0].layout.ty.scalable_vector_parts(self.cx.tcx) - else { - bug!("input parameter to `sve_cast` was not scalable vector"); - }; - let out_layout = self.layout_of(fn_args.type_at(1)); - let Some((out_cnt, out_elem, out_num_vecs)) = - out_layout.ty.scalable_vector_parts(self.cx.tcx) - else { - bug!("output parameter to `sve_cast` was not scalable vector"); - }; - assert_eq!(in_cnt, out_cnt); - assert_eq!(in_num_vecs, out_num_vecs); - let out_llty = self.backend_type(out_layout); - match simd_cast(self, sym::simd_cast, args, out_llty, in_elem, out_elem) { - Some(val) => val, - _ => bug!("could not cast scalable vectors"), - } - } - sym::sve_tuple_create2 => { assert_matches!( self.layout_of(fn_args.type_at(0)).backend_repr, @@ -1668,6 +1647,23 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }}; } + macro_rules! require_simd_or_scalable { + ($ty: expr, $variant:ident) => {{ + require!( + $ty.is_simd() || $ty.is_scalable_vector(), + InvalidMonomorphization::$variant { span, name, ty: $ty } + ); + if $ty.is_simd() { + let (len, ty) = $ty.simd_size_and_type(bx.tcx()); + (len, ty, None) + } else { + let (count, ty, num_vecs) = + $ty.scalable_vector_parts(bx.tcx()).expect("`is_scalable_vector` was wrong"); + (count as u64, ty, Some(num_vecs)) + } + }}; + } + /// Returns the bitwidth of the `$ty` argument if it is an `Int` or `Uint` type. macro_rules! require_int_or_uint_ty { ($ty: expr, $diag: expr) => { @@ -1787,8 +1783,19 @@ fn generic_simd_intrinsic<'ll, 'tcx>( return Ok(splat); } - // every intrinsic below takes a SIMD vector as its first argument - let (in_len, in_elem) = require_simd!(args[0].layout.ty, SimdInput); + let supports_scalable = match name { + sym::simd_cast | sym::simd_select => true, + _ => false, + }; + + // Every intrinsic below takes a SIMD vector as its first argument. Some intrinsics also accept + // scalable vectors. `require_simd_or_scalable` is used regardless as it'll do the right thing + // for non-scalable vectors, and an additional check to prohibit scalable vectors for those + // intrinsics that do not support them is added. + if !supports_scalable { + let _ = require_simd!(args[0].layout.ty, SimdInput); + } + let (in_len, in_elem, in_num_vecs) = require_simd_or_scalable!(args[0].layout.ty, SimdInput); let in_ty = args[0].layout.ty; let comparison = match name { @@ -1977,7 +1984,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::simd_select { let m_elem_ty = in_elem; let m_len = in_len; - let (v_len, _) = require_simd!(args[1].layout.ty, SimdArgument); + let (v_len, _, _) = require_simd_or_scalable!(args[1].layout.ty, SimdArgument); require!( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } @@ -2781,7 +2788,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_cast || name == sym::simd_as { - let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn); + let (out_len, out_elem, out_num_vecs) = require_simd_or_scalable!(ret_ty, SimdReturn); require!( in_len == out_len, InvalidMonomorphization::ReturnLengthInputType { @@ -2793,9 +2800,99 @@ fn generic_simd_intrinsic<'ll, 'tcx>( out_len } ); - match simd_cast(bx, name, args, llret_ty, in_elem, out_elem) { - Some(val) => return Ok(val), - None => return_error!(InvalidMonomorphization::UnsupportedCast { + require!( + in_num_vecs == out_num_vecs, + InvalidMonomorphization::ReturnNumVecsInputType { + span, + name, + in_num_vecs: in_num_vecs.unwrap_or(NumScalableVectors(1)), + in_ty, + ret_ty, + out_num_vecs: out_num_vecs.unwrap_or(NumScalableVectors(1)) + } + ); + + // Casting cares about nominal type, not just structural type + if in_elem == out_elem { + return Ok(args[0].immediate()); + } + + #[derive(Copy, Clone)] + enum Sign { + Unsigned, + Signed, + } + use Sign::*; + + enum Style { + Float, + Int(Sign), + Unsupported, + } + + let (in_style, in_width) = match in_elem.kind() { + // vectors of pointer-sized integers should've been + // disallowed before here, so this unwrap is safe. + ty::Int(i) => ( + Style::Int(Signed), + i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Uint(u) => ( + Style::Int(Unsigned), + u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Float(f) => (Style::Float, f.bit_width()), + _ => (Style::Unsupported, 0), + }; + let (out_style, out_width) = match out_elem.kind() { + ty::Int(i) => ( + Style::Int(Signed), + i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Uint(u) => ( + Style::Int(Unsigned), + u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), + ), + ty::Float(f) => (Style::Float, f.bit_width()), + _ => (Style::Unsupported, 0), + }; + + match (in_style, out_style) { + (Style::Int(sign), Style::Int(_)) => { + return Ok(match in_width.cmp(&out_width) { + Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), + Ordering::Equal => args[0].immediate(), + Ordering::Less => match sign { + Sign::Signed => bx.sext(args[0].immediate(), llret_ty), + Sign::Unsigned => bx.zext(args[0].immediate(), llret_ty), + }, + }); + } + (Style::Int(Sign::Signed), Style::Float) => { + return Ok(bx.sitofp(args[0].immediate(), llret_ty)); + } + (Style::Int(Sign::Unsigned), Style::Float) => { + return Ok(bx.uitofp(args[0].immediate(), llret_ty)); + } + (Style::Float, Style::Int(sign)) => { + return Ok(match (sign, name == sym::simd_as) { + (Sign::Unsigned, false) => bx.fptoui(args[0].immediate(), llret_ty), + (Sign::Signed, false) => bx.fptosi(args[0].immediate(), llret_ty), + (_, true) => bx.cast_float_to_int( + matches!(sign, Sign::Signed), + args[0].immediate(), + llret_ty, + ), + }); + } + (Style::Float, Style::Float) => { + return Ok(match in_width.cmp(&out_width) { + Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty), + Ordering::Equal => args[0].immediate(), + Ordering::Less => bx.fpext(args[0].immediate(), llret_ty), + }); + } + _ => return_error!(InvalidMonomorphization::UnsupportedCast { span, name, in_ty, @@ -2977,86 +3074,3 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span_bug!(span, "unknown SIMD intrinsic"); } - -/// Implementation of `core::intrinsics::simd_cast`, re-used by `core::scalable::sve_cast`. -fn simd_cast<'ll, 'tcx>( - bx: &mut Builder<'_, 'll, 'tcx>, - name: Symbol, - args: &[OperandRef<'tcx, &'ll Value>], - llret_ty: &'ll Type, - in_elem: Ty<'tcx>, - out_elem: Ty<'tcx>, -) -> Option<&'ll Value> { - // Casting cares about nominal type, not just structural type - if in_elem == out_elem { - return Some(args[0].immediate()); - } - - #[derive(Copy, Clone)] - enum Sign { - Unsigned, - Signed, - } - use Sign::*; - - enum Style { - Float, - Int(Sign), - Unsupported, - } - - let (in_style, in_width) = match in_elem.kind() { - // vectors of pointer-sized integers should've been - // disallowed before here, so this unwrap is safe. - ty::Int(i) => ( - Style::Int(Signed), - i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Uint(u) => ( - Style::Int(Unsigned), - u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Float(f) => (Style::Float, f.bit_width()), - _ => (Style::Unsupported, 0), - }; - let (out_style, out_width) = match out_elem.kind() { - ty::Int(i) => ( - Style::Int(Signed), - i.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Uint(u) => ( - Style::Int(Unsigned), - u.normalize(bx.tcx().sess.target.pointer_width).bit_width().unwrap(), - ), - ty::Float(f) => (Style::Float, f.bit_width()), - _ => (Style::Unsupported, 0), - }; - - match (in_style, out_style) { - (Style::Int(sign), Style::Int(_)) => Some(match in_width.cmp(&out_width) { - Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), - Ordering::Equal => args[0].immediate(), - Ordering::Less => match sign { - Sign::Signed => bx.sext(args[0].immediate(), llret_ty), - Sign::Unsigned => bx.zext(args[0].immediate(), llret_ty), - }, - }), - (Style::Int(Sign::Signed), Style::Float) => Some(bx.sitofp(args[0].immediate(), llret_ty)), - (Style::Int(Sign::Unsigned), Style::Float) => { - Some(bx.uitofp(args[0].immediate(), llret_ty)) - } - (Style::Float, Style::Int(sign)) => Some(match (sign, name == sym::simd_as) { - (Sign::Unsigned, false) => bx.fptoui(args[0].immediate(), llret_ty), - (Sign::Signed, false) => bx.fptosi(args[0].immediate(), llret_ty), - (_, true) => { - bx.cast_float_to_int(matches!(sign, Sign::Signed), args[0].immediate(), llret_ty) - } - }), - (Style::Float, Style::Float) => Some(match in_width.cmp(&out_width) { - Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty), - Ordering::Equal => args[0].immediate(), - Ordering::Less => bx.fpext(args[0].immediate(), llret_ty), - }), - _ => None, - } -} diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index cec84f60a7b0e..8a97521feb436 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -6,6 +6,7 @@ use std::io::Error; use std::path::{Path, PathBuf}; use std::process::ExitStatus; +use rustc_abi::NumScalableVectors; use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, IntoDiagArg, @@ -809,6 +810,17 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type with {$in_num_vecs} vectors (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_num_vecs}", code = E0511)] + ReturnNumVecsInputType { + #[primary_span] + span: Span, + name: Symbol, + in_num_vecs: NumScalableVectors, + in_ty: Ty<'tcx>, + ret_ty: Ty<'tcx>, + out_num_vecs: NumScalableVectors, + }, + #[diag("invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}", code = E0511)] SecondArgumentLength { #[primary_span] diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index f358ffffb47d1..3f7a604978b6a 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -23,17 +23,21 @@ rustc_index = { path = "../rustc_index", package = "rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_thread_pool = { path = "../rustc_thread_pool" } -smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] } +smallvec = { version = "1.8.1", features = [ + "const_generics", + "union", + "may_dangle", +] } stacker = "0.1.17" tempfile = "3.2" -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end [dependencies.hashbrown] version = "0.16.1" default-features = false -features = ["nightly"] # for may_dangle +features = ["nightly"] # for may_dangle [target.'cfg(windows)'.dependencies.windows] version = "0.61.0" diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index de086085c4cb2..0cfa8dd90d533 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -80,7 +80,6 @@ pub mod svh; pub mod sync; pub mod tagged_ptr; pub mod temp_dir; -pub mod thinvec; pub mod thousands; pub mod transitive_relation; pub mod unhash; diff --git a/compiler/rustc_data_structures/src/thinvec.rs b/compiler/rustc_data_structures/src/thinvec.rs deleted file mode 100644 index e60ac2cbc8b49..0000000000000 --- a/compiler/rustc_data_structures/src/thinvec.rs +++ /dev/null @@ -1,92 +0,0 @@ -//! This is a copy-paste of `Vec::extract_if` for `ThinVec`. -//! -//! FIXME: is merged, this can be removed. - -use std::{ptr, slice}; - -use thin_vec::ThinVec; - -/// An iterator for [`ThinVec`] which uses a closure to determine if an element should be removed. -#[must_use = "iterators are lazy and do nothing unless consumed"] -pub struct ExtractIf<'a, T, F> { - vec: &'a mut ThinVec, - /// The index of the item that will be inspected by the next call to `next`. - idx: usize, - /// The number of items that have been drained (removed) thus far. - del: usize, - /// The original length of `vec` prior to draining. - old_len: usize, - /// The filter test predicate. - pred: F, -} - -impl<'a, T, F> ExtractIf<'a, T, F> -where - F: FnMut(&mut T) -> bool, -{ - pub fn new(vec: &'a mut ThinVec, filter: F) -> Self { - let old_len = vec.len(); - - // Guard against us getting leaked (leak amplification) - unsafe { - vec.set_len(0); - } - - ExtractIf { vec, idx: 0, del: 0, old_len, pred: filter } - } -} - -impl Iterator for ExtractIf<'_, T, F> -where - F: FnMut(&mut T) -> bool, -{ - type Item = T; - fn next(&mut self) -> Option { - unsafe { - while self.idx < self.old_len { - let i = self.idx; - let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); - let drained = (self.pred)(&mut v[i]); - // Update the index *after* the predicate is called. If the index - // is updated prior and the predicate panics, the element at this - // index would be leaked. - self.idx += 1; - if drained { - self.del += 1; - return Some(ptr::read(&v[i])); - } else if self.del > 0 { - let del = self.del; - let src: *const T = &v[i]; - let dst: *mut T = &mut v[i - del]; - ptr::copy_nonoverlapping(src, dst, 1); - } - } - None - } - } - - fn size_hint(&self) -> (usize, Option) { - (0, Some(self.old_len - self.idx)) - } -} - -impl Drop for ExtractIf<'_, A, F> { - fn drop(&mut self) { - unsafe { - if self.idx < self.old_len && self.del > 0 { - // This is a pretty messed up state, and there isn't really an - // obviously right thing to do. We don't want to keep trying - // to execute `pred`, so we just backshift all the unprocessed - // elements and tell the vec that they still exist. The backshift - // is required to prevent a double-drop of the last successfully - // drained item prior to a panic in the predicate. - let ptr = self.vec.as_mut_ptr(); - let src = ptr.add(self.idx); - let dst = src.sub(self.del); - let tail_len = self.old_len - self.idx; - src.copy_to(dst, tail_len); - } - self.vec.set_len(self.old_len - self.del); - } - } -} diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 12b0c384a8aea..0154d05266fd7 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -30,6 +30,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } scoped-tls = "1.0" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 60223cc835043..6db23aadcac3c 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -928,6 +928,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ unstable_feature_bound, Normal, template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No, ), + ungated!( + unstable_removed, CrateLevel, + template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]), + DuplicatesOk, EncodeCrossCrate::Yes + ), ungated!( rustc_const_unstable, Normal, template!(List: &[r#"feature = "name""#]), DuplicatesOk, EncodeCrossCrate::Yes diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 1e08ad1384ccf..7508fb7c250c7 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -310,18 +310,4 @@ declare_features! ( // ------------------------------------------------------------------------- // feature-group-end: removed features // ------------------------------------------------------------------------- - - - // ------------------------------------------------------------------------- - // feature-group-start: removed library features - // ------------------------------------------------------------------------- - // - // FIXME(#141617): we should have a better way to track removed library features, but we reuse - // the infrastructure here so users still get hints. The symbols used here can be remove from - // `symbol.rs` when that happens. - (removed, concat_idents, "1.90.0", Some(29599), - Some("use the `${concat(..)}` metavariable expression instead"), 142704), - // ------------------------------------------------------------------------- - // feature-group-end: removed library features - // ------------------------------------------------------------------------- ); diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 13e73acf07375..f1cd660a8f5b4 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -22,6 +22,6 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 48b03bc946591..67bf1c9b91d06 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -894,6 +894,14 @@ impl fmt::Display for AutoDiffItem { } } +#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub struct UnstableRemovedFeature { + pub feature: Symbol, + pub reason: Symbol, + pub link: Symbol, + pub since: RustcVersion, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -1648,6 +1656,9 @@ pub enum AttributeKind { /// Represents `#[unstable_feature_bound]`. UnstableFeatureBound(ThinVec<(Symbol, Span)>), + /// Represents all `#![unstable_removed(...)]` features + UnstableRemoved(ThinVec), + /// Represents `#[used]` Used { used_by: UsedBy, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index eea6549c02f49..dace9756dc393 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -199,6 +199,7 @@ impl AttributeKind { TrackCaller(..) => Yes, TypeLengthLimit { .. } => No, UnstableFeatureBound(..) => No, + UnstableRemoved(..) => Yes, Used { .. } => No, WindowsSubsystem(..) => No, // tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 15afa9a929099..e4e6642981d1a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1641,18 +1641,10 @@ impl<'tcx> OwnerInfo<'tcx> { } } -#[derive(Copy, Clone, Debug, HashStable_Generic)] -pub enum DelayedOwnerKind { - Item, - ImplItem, - TraitItem, -} - #[derive(Copy, Clone, Debug, HashStable_Generic)] pub enum MaybeOwner<'tcx> { Owner(&'tcx OwnerInfo<'tcx>), NonOwner(HirId), - Delayed(DelayedOwnerKind), /// Used as a placeholder for unused LocalDefId. Phantom, } @@ -1661,19 +1653,12 @@ impl<'tcx> MaybeOwner<'tcx> { pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> { match self { MaybeOwner::Owner(i) => Some(i), - _ => None, + MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None, } } pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> { - self.as_owner().unwrap_or_else(|| panic!("not a HIR owner")) - } - - pub fn expect_delayed(self) -> DelayedOwnerKind { - match self { - MaybeOwner::Delayed(delayed_owner) => delayed_owner, - _ => panic!("not a delayed owner"), - } + self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9ffcd3461f2de..99511189e9283 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -226,11 +226,6 @@ pub trait Visitor<'v>: Sized { /// or `ControlFlow`. type Result: VisitorResult = (); - #[inline] - fn visit_if_delayed(&self, _: LocalDefId) -> bool { - true - } - /// If `type NestedFilter` is set to visit nested items, this method /// must also be overridden to provide a map to retrieve nested items. fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { @@ -249,23 +244,18 @@ pub trait Visitor<'v>: Sized { /// this method is if you want a nested pattern but cannot supply a /// `TyCtxt`; see `maybe_tcx` for advice. fn visit_nested_item(&mut self, id: ItemId) -> Self::Result { - if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) { + if Self::NestedFilter::INTER { let item = self.maybe_tcx().hir_item(id); try_visit!(self.visit_item(item)); } Self::Result::output() } - // Now delayed owners are only delegations, which are either item, trait item or impl item. - fn should_visit_maybe_delayed_inter(&mut self, id: LocalDefId) -> bool { - Self::NestedFilter::INTER && self.visit_if_delayed(id) - } - /// Like `visit_nested_item()`, but for trait items. See /// `visit_nested_item()` for advice on when to override this /// method. fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result { - if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) { + if Self::NestedFilter::INTER { let item = self.maybe_tcx().hir_trait_item(id); try_visit!(self.visit_trait_item(item)); } @@ -276,7 +266,7 @@ pub trait Visitor<'v>: Sized { /// `visit_nested_item()` for advice on when to override this /// method. fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result { - if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) { + if Self::NestedFilter::INTER { let item = self.maybe_tcx().hir_impl_item(id); try_visit!(self.visit_impl_item(item)); } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 593284df38a3a..e97830ccd23fa 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -318,11 +318,15 @@ fn create_generic_args<'tcx>( let (caller_kind, callee_kind) = (fn_kind(tcx, delegation_id), fn_kind(tcx, sig_id)); let delegation_args = ty::GenericArgs::identity_for_item(tcx, delegation_id); - let delegation_parent_args_count = tcx.generics_of(delegation_id).parent_count; let deleg_parent_args_without_self_count = get_delegation_parent_args_count_without_self(tcx, delegation_id, sig_id); + let delegation_generics = tcx.generics_of(delegation_id); + let real_args_count = delegation_args.len() - delegation_generics.own_synthetic_params_count(); + let synth_args = &delegation_args[real_args_count..]; + let delegation_args = &delegation_args[..real_args_count]; + let args = match (caller_kind, callee_kind) { (FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) @@ -339,14 +343,15 @@ fn create_generic_args<'tcx>( assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); - tcx.mk_args(&delegation_args[delegation_parent_args_count..]) + tcx.mk_args(&delegation_args[delegation_generics.parent_count..]) } (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { let self_ty = tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity(); tcx.mk_args_from_iter( - std::iter::once(ty::GenericArg::from(self_ty)).chain(delegation_args.iter()), + std::iter::once(ty::GenericArg::from(self_ty)) + .chain(delegation_args.iter().copied()), ) } @@ -411,7 +416,7 @@ fn create_generic_args<'tcx>( new_args.extend_from_slice(&child_args[child_lifetimes_count..]); } else if !parent_args.is_empty() { - let child_args = &delegation_args[delegation_parent_args_count..]; + let child_args = &delegation_args[delegation_generics.parent_count..]; let child_lifetimes_count = child_args.iter().take_while(|a| a.as_region().is_some()).count(); @@ -424,6 +429,8 @@ fn create_generic_args<'tcx>( new_args.extend(&child_args[child_lifetimes_count + skip_self as usize..]); } + new_args.extend(synth_args); + new_args } @@ -606,7 +613,8 @@ fn get_delegation_user_specified_args<'tcx>( .lower_generic_args_of_path(segment.ident.span, def_id, parent_args, segment, None) .0; - &args[parent_args.len()..] + let synth_params_count = tcx.generics_of(def_id).own_synthetic_params_count(); + &args[parent_args.len()..args.len() - synth_params_count] }); (parent_args.unwrap_or_default(), child_args.unwrap_or_default()) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index ede9de6adc2d0..c47bd227e3d94 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -747,7 +747,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { GenericParamDefKind::Lifetime => { self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into() } - GenericParamDefKind::Type { has_default, .. } => { + GenericParamDefKind::Type { has_default, synthetic } => { if !infer_args && has_default { // No type parameter provided, but a default exists. if let Some(prev) = @@ -763,6 +763,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .type_of(param.def_id) .instantiate(tcx, preceding_args) .into() + } else if synthetic { + Ty::new_param(tcx, param.index, param.name).into() } else if infer_args { self.lowerer.ty_infer(Some(param), self.span).into() } else { diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index c4fbe89315db0..1896ce10faf2f 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -17,6 +17,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ab61ba635720b..d1f95591b92d6 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1054,10 +1054,6 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) { /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. /// This function never fails. fn run_required_analyses(tcx: TyCtxt<'_>) { - // Forces all delayed owners to be lowered and drops AST crate after it. - // Also refetches hir_crate_items to prevent multiple threads from blocking on it later. - tcx.force_delayed_owners_lowering(); - if tcx.sess.opts.unstable_opts.input_stats { rustc_passes::input_stats::print_hir_stats(tcx); } @@ -1066,6 +1062,11 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { #[cfg(all(not(doc), debug_assertions))] rustc_passes::hir_id_validator::check_crate(tcx); + // Prefetch this to prevent multiple threads from blocking on it later. + // This is needed since the `hir_id_validator::check_crate` call above is not guaranteed + // to use `hir_crate_items`. + tcx.ensure_done().hir_crate_items(()); + let sess = tcx.sess; sess.time("misc_checking_1", || { par_fns(&mut [ diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 72787c841204b..05eaf54f5d468 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2477,8 +2477,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { tcx.dep_graph.with_task( dep_node, tcx, - path, - |tcx, path| { + || { with_encode_metadata_header(tcx, path, |ecx| { // Encode all the entries and extra information in the crate, // culminating in the `CrateRoot` which points to all of it. diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 8bad0e291bf8b..f0e47e0075ff6 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -16,7 +16,7 @@ rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } -rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links +rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_graphviz = { path = "../rustc_graphviz" } @@ -33,7 +33,7 @@ rustc_target = { path = "../rustc_target" } rustc_thread_pool = { path = "../rustc_thread_pool" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index abd37f2488009..be29e053a17c0 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -52,6 +52,7 @@ pub enum QuerySideEffect { /// the side effect dep node as a dependency. CheckFeature { symbol: Symbol }, } + #[derive(Clone)] pub struct DepGraph { data: Option>, @@ -274,17 +275,19 @@ impl DepGraph { } #[inline(always)] - pub fn with_task<'tcx, A: Debug, R>( + pub fn with_task<'tcx, OP, R>( &self, dep_node: DepNode, tcx: TyCtxt<'tcx>, - task_arg: A, - task_fn: fn(tcx: TyCtxt<'tcx>, task_arg: A) -> R, + op: OP, hash_result: Option, &R) -> Fingerprint>, - ) -> (R, DepNodeIndex) { + ) -> (R, DepNodeIndex) + where + OP: FnOnce() -> R, + { match self.data() { - Some(data) => data.with_task(dep_node, tcx, task_arg, task_fn, hash_result), - None => (task_fn(tcx, task_arg), self.next_virtual_depnode_index()), + Some(data) => data.with_task(dep_node, tcx, op, hash_result), + None => (op(), self.next_virtual_depnode_index()), } } @@ -309,44 +312,27 @@ impl DepGraph { } impl DepGraphData { - /// Starts a new dep-graph task. Dep-graph tasks are specified - /// using a free function (`task`) and **not** a closure -- this - /// is intentional because we want to exercise tight control over - /// what state they have access to. In particular, we want to - /// prevent implicit 'leaks' of tracked state into the task (which - /// could then be read without generating correct edges in the - /// dep-graph -- see the [rustc dev guide] for more details on - /// the dep-graph). - /// - /// Therefore, the task function takes a `TyCtxt`, plus exactly one - /// additional argument, `task_arg`. The additional argument type can be - /// `()` if no argument is needed, or a tuple if multiple arguments are - /// needed. - /// - /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation.html #[inline(always)] - pub fn with_task<'tcx, A: Debug, R>( + pub fn with_task<'tcx, OP, R>( &self, dep_node: DepNode, tcx: TyCtxt<'tcx>, - task_arg: A, - task_fn: fn(tcx: TyCtxt<'tcx>, task_arg: A) -> R, + op: OP, hash_result: Option, &R) -> Fingerprint>, - ) -> (R, DepNodeIndex) { + ) -> (R, DepNodeIndex) + where + OP: FnOnce() -> R, + { // If the following assertion triggers, it can have two reasons: // 1. Something is wrong with DepNode creation, either here or // in `DepGraph::try_mark_green()`. // 2. Two distinct query keys get mapped to the same `DepNode` // (see for example #48923). self.assert_dep_node_not_yet_allocated_in_current_session(tcx.sess, &dep_node, || { - format!( - "forcing query with already existing `DepNode`\n\ - - query-key: {task_arg:?}\n\ - - dep-node: {dep_node:?}" - ) + format!("forcing query with already existing `DepNode`: {dep_node:?}") }); - let with_deps = |task_deps| with_deps(task_deps, || task_fn(tcx, task_arg)); + let with_deps = |task_deps| with_deps(task_deps, op); let (result, edges) = if tcx.is_eval_always(dep_node.kind) { (with_deps(TaskDepsRef::EvalAlways), EdgesVec::new()) } else { diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 6e82d1cbab99c..20aa0a809006f 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -5,10 +5,9 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; @@ -1246,7 +1245,25 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod } } +fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { + let krate = tcx.hir_crate(()); + for &id in &krate.delayed_ids { + tcx.ensure_done().lower_delayed_owner(id); + } + + let (_, krate) = krate.delayed_resolver.steal(); + let prof = tcx.sess.prof.clone(); + + // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. + spawn(move || { + let _timer = prof.verbose_generic_activity("drop_ast"); + drop(krate); + }); +} + pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { + force_delayed_owners_lowering(tcx); + let mut collector = ItemCollector::new(tcx, true); // A "crate collector" and "module collector" start at a @@ -1307,12 +1324,11 @@ struct ItemCollector<'tcx> { nested_bodies: Vec, delayed_lint_items: Vec, eiis: Vec, - delayed_ids: Option<&'tcx FxIndexSet>, } impl<'tcx> ItemCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> { - let mut collector = ItemCollector { + ItemCollector { crate_collector, tcx, submodules: Vec::default(), @@ -1325,46 +1341,13 @@ impl<'tcx> ItemCollector<'tcx> { nested_bodies: Vec::default(), delayed_lint_items: Vec::default(), eiis: Vec::default(), - delayed_ids: None, - }; - - if crate_collector { - let krate = tcx.hir_crate(()); - collector.delayed_ids = Some(&krate.delayed_ids); - - let delayed_kinds = - krate.delayed_ids.iter().copied().map(|id| (id, krate.owners[id].expect_delayed())); - - // FIXME(fn_delegation): need to add delayed lints, eiis - for (def_id, kind) in delayed_kinds { - let owner_id = OwnerId { def_id }; - - match kind { - DelayedOwnerKind::Item => collector.items.push(ItemId { owner_id }), - DelayedOwnerKind::ImplItem => { - collector.impl_items.push(ImplItemId { owner_id }) - } - DelayedOwnerKind::TraitItem => { - collector.trait_items.push(TraitItemId { owner_id }) - } - }; - - collector.body_owners.push(def_id); - } } - - collector } } impl<'hir> Visitor<'hir> for ItemCollector<'hir> { type NestedFilter = nested_filter::All; - #[inline] - fn visit_if_delayed(&self, def_id: LocalDefId) -> bool { - !self.crate_collector || self.delayed_ids.is_none_or(|ids| !ids.contains(&def_id)) - } - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { self.tcx } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 606d4947a4eac..814b333cfb0f8 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{DynSend, DynSync, spawn, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::lints::DelayedLint; @@ -64,8 +64,7 @@ impl<'hir> Crate<'hir> { // which is greater than delayed LocalDefId, we use IndexVec for owners, // so we will call ensure_contains_elem which will grow it. if let Some(owner) = self.owners.get(def_id) - && (self.delayed_ids.is_empty() - || !matches!(owner, MaybeOwner::Phantom | MaybeOwner::Delayed(_))) + && (self.delayed_ids.is_empty() || !matches!(owner, MaybeOwner::Phantom)) { return *owner; } @@ -208,24 +207,6 @@ impl ModuleItems { } impl<'tcx> TyCtxt<'tcx> { - pub fn force_delayed_owners_lowering(self) { - let krate = self.hir_crate(()); - self.ensure_done().hir_crate_items(()); - - for &id in &krate.delayed_ids { - self.ensure_done().lower_delayed_owner(id); - } - - let (_, krate) = krate.delayed_resolver.steal(); - let prof = self.sess.prof.clone(); - - // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. - spawn(move || { - let _timer = prof.verbose_generic_activity("drop_ast"); - drop(krate); - }); - } - pub fn parent_module(self, id: HirId) -> LocalModDefId { if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod { LocalModDefId::new_unchecked(id.owner.def_id) @@ -494,8 +475,7 @@ pub fn provide(providers: &mut Providers) { providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) { MaybeOwner::Owner(_) => HirId::make_owner(def_id), MaybeOwner::NonOwner(hir_id) => hir_id, - MaybeOwner::Phantom => bug!("no HirId for {:?}", def_id), - MaybeOwner::Delayed(_) => bug!("delayed owner should be lowered {:?}", def_id), + MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), }; providers.opt_hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes); diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index ed587cbc3c285..11a236f314c26 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -274,6 +274,10 @@ impl<'tcx> Generics { }) } + pub fn own_synthetic_params_count(&'tcx self) -> usize { + self.own_params.iter().filter(|p| p.kind.is_synthetic()).count() + } + /// Returns the args corresponding to the generic parameters /// of this item, excluding `Self`. /// diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 28a67ae12126b..53727efb46501 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -17,7 +17,7 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" unicode-normalization = "0.1.25" unicode-width = "0.2.2" diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c18e8c631fecc..437102d549e79 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3464,11 +3464,7 @@ impl<'a> Parser<'a> { } pub(crate) fn eat_metavar_guard(&mut self) -> Option> { - self.eat_metavar_seq_with_matcher( - |mv_kind| matches!(mv_kind, MetaVarKind::Guard), - |this| this.parse_match_arm_guard(), - ) - .flatten() + self.eat_metavar_seq(MetaVarKind::Guard, |this| this.parse_match_arm_guard()).flatten() } fn parse_match_arm_guard(&mut self) -> PResult<'a, Option>> { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index ddf1b10e5235d..37b76fc26a486 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -105,7 +105,10 @@ impl<'a> Parser<'a> { token::Lifetime(..) | token::NtLifetime(..) => true, _ => false, }, - NonterminalKind::Guard => token.is_keyword(kw::If), + NonterminalKind::Guard => match token.kind { + token::OpenInvisible(InvisibleOrigin::MetaVar(MetaVarKind::Guard)) => true, + _ => token.is_keyword(kw::If), + }, NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => { token.kind.close_delim().is_none() } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 54d34ef26a021..17f12b81751cf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -385,6 +385,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::ThreadLocal | AttributeKind::TypeLengthLimit { .. } | AttributeKind::UnstableFeatureBound(..) + | AttributeKind::UnstableRemoved(..) | AttributeKind::Used { .. } | AttributeKind::WindowsSubsystem(..) // tidy-alphabetical-end diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 5de43f24b2dc6..b32bb70e3fb69 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -895,6 +895,20 @@ pub(crate) struct ImpliedFeatureNotExist { pub implied_by: Symbol, } +#[derive(Diagnostic)] +#[diag("feature `{$feature}` has been removed", code = E0557)] +#[note("removed in {$since}; see <{$link}> for more information")] +#[note("{$reason}")] +pub(crate) struct FeatureRemoved { + #[primary_span] + #[label("feature has been removed")] + pub span: Span, + pub feature: Symbol, + pub reason: Symbol, + pub since: String, + pub link: Symbol, +} + #[derive(Diagnostic)] #[diag( "attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const`" diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 220cb57ddd393..e41df43e34bd3 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -1097,7 +1097,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let lang_features = UNSTABLE_LANG_FEATURES.iter().map(|feature| feature.name).collect::>(); let lib_features = crates - .into_iter() + .iter() .flat_map(|&cnum| { tcx.lib_features(cnum).stability.keys().copied().into_sorted_stable_ord() }) @@ -1105,11 +1105,33 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let valid_feature_names = [lang_features, lib_features].concat(); + // Collect all of the marked as "removed" features + let unstable_removed_features = crates + .iter() + .flat_map(|&cnum| { + find_attr!(tcx, cnum.as_def_id(), UnstableRemoved(rem_features) => rem_features) + .into_iter() + .flatten() + }) + .collect::>(); + for (feature, span) in remaining_lib_features { - let suggestion = feature - .find_similar(&valid_feature_names) - .map(|(actual_name, _)| errors::MisspelledFeature { span, actual_name }); - tcx.dcx().emit_err(errors::UnknownFeature { span, feature, suggestion }); + if let Some(removed) = + unstable_removed_features.iter().find(|removed| removed.feature == feature) + { + tcx.dcx().emit_err(errors::FeatureRemoved { + span, + feature, + reason: removed.reason, + link: removed.link, + since: removed.since.to_string(), + }); + } else { + let suggestion = feature + .find_similar(&valid_feature_names) + .map(|(actual_name, _)| errors::MisspelledFeature { span, actual_name }); + tcx.dcx().emit_err(errors::UnknownFeature { span, feature, suggestion }); + } } } } diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 45be65b02964e..8c242679780d4 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -447,8 +447,7 @@ fn execute_job_incr<'tcx, C: QueryCache>( dep_graph_data.with_task( dep_node, tcx, - (query, key), - |tcx, (query, key)| (query.invoke_provider_fn)(tcx, key), + || (query.invoke_provider_fn)(tcx, key), query.hash_value_fn, ) }); diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index feb0a93d0788a..2fc251e2b525e 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -7,7 +7,9 @@ edition = "2024" # tidy-alphabetical-start indexmap = "2.4.0" itertools = "0.12" -pulldown-cmark = { version = "0.11", features = ["html"], default-features = false } +pulldown-cmark = { version = "0.11", features = [ + "html", +], default-features = false } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } @@ -24,6 +26,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 948242352e7a8..193c89a295980 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" indexmap = "2.0.0" rustc_hashes = { path = "../rustc_hashes" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" +thin-vec = "0.2.15" # tidy-alphabetical-end [dev-dependencies] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e7126cf70b574..80d1c91c81ddc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -641,7 +641,6 @@ symbols! { compiler_move, concat, concat_bytes, - concat_idents, conservative_impl_trait, console, const_allocate, @@ -2185,6 +2184,7 @@ symbols! { unstable_location_reason_default: "this crate is being loaded from the sysroot, an \ unstable location; did you mean to load this crate \ from crates.io via `Cargo.toml` instead?", + unstable_removed, untagged_unions, unused_imports, unwind, diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 0ba46c6ddd56a..802fdda6f0375 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -19,6 +19,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2" +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 62f6b87c9e98c..fc611a0a2da5e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -6074,7 +6074,16 @@ fn point_at_assoc_type_restriction( let ty::ClauseKind::Projection(proj) = clause else { return; }; - let name = tcx.item_name(proj.projection_term.def_id); + let Some(name) = tcx + .opt_rpitit_info(proj.projection_term.def_id) + .and_then(|data| match data { + ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => Some(tcx.item_name(fn_def_id)), + ty::ImplTraitInTraitData::Impl { .. } => None, + }) + .or_else(|| tcx.opt_item_name(proj.projection_term.def_id)) + else { + return; + }; let mut predicates = generics.predicates.iter().peekable(); let mut prev: Option<(&hir::WhereBoundPredicate<'_>, Span)> = None; while let Some(pred) = predicates.next() { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 7b61a653ae31e..26a9f392e2a47 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -2,7 +2,6 @@ use std::marker::PhantomData; use std::mem; use std::ops::ControlFlow; -use rustc_data_structures::thinvec::ExtractIf; use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; @@ -103,18 +102,18 @@ impl<'tcx> ObligationStorage<'tcx> { // we get all obligations involved in the overflow. We pretty much check: if // we were to do another step of `try_evaluate_obligations`, which goals would // change. - // FIXME: is merged, this can be removed. self.overflowed.extend( - ExtractIf::new(&mut self.pending, |(o, stalled_on)| { - let goal = o.as_goal(); - let result = <&SolverDelegate<'tcx>>::from(infcx).evaluate_root_goal( - goal, - o.cause.span, - stalled_on.take(), - ); - matches!(result, Ok(GoalEvaluation { has_changed: HasChanged::Yes, .. })) - }) - .map(|(o, _)| o), + self.pending + .extract_if(.., |(o, stalled_on)| { + let goal = o.as_goal(); + let result = <&SolverDelegate<'tcx>>::from(infcx).evaluate_root_goal( + goal, + o.cause.span, + stalled_on.take(), + ); + matches!(result, Ok(GoalEvaluation { has_changed: HasChanged::Yes, .. })) + }) + .map(|(o, _)| o), ); }) } diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 58fc4d8788b11..7b0b4aa899723 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -20,8 +20,10 @@ rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } -smallvec = { version = "1.8.1", default-features = false, features = ["const_generics"] } -thin-vec = "0.2.12" +smallvec = { version = "1.8.1", default-features = false, features = [ + "const_generics", +] } +thin-vec = "0.2.15" tracing = "0.1" # tidy-alphabetical-end diff --git a/library/core/src/intrinsics/simd/scalable.rs b/library/core/src/intrinsics/simd/scalable.rs index b2b0fec487c08..a8984b3a2f7db 100644 --- a/library/core/src/intrinsics/simd/scalable.rs +++ b/library/core/src/intrinsics/simd/scalable.rs @@ -2,27 +2,6 @@ //! //! In this module, a "vector" is any `#[rustc_scalable_vector]`-annotated type. -/// Numerically casts a vector, elementwise. -/// -/// `T` and `U` must be vectors of integers or floats, and must have the same length. -/// -/// When casting floats to integers, the result is truncated. Out-of-bounds result lead to UB. -/// When casting integers to floats, the result is rounded. -/// Otherwise, truncates or extends the value, maintaining the sign for signed integers. -/// -/// # Safety -/// Casting from integer types is always safe. -/// Casting between two float types is also always safe. -/// -/// Casting floats to integers truncates, following the same rules as `to_int_unchecked`. -/// Specifically, each element must: -/// * Not be `NaN` -/// * Not be infinite -/// * Be representable in the return type, after truncating off its fractional part -#[rustc_intrinsic] -#[rustc_nounwind] -pub unsafe fn sve_cast(x: T) -> U; - /// Create a tuple of two vectors. /// /// `SVecTup` must be a scalable vector tuple (`#[rustc_scalable_vector]`) and `SVec` must be a diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index e6467dd0546ae..6b5d21e1046ff 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -418,6 +418,13 @@ // tidy-alphabetical-end // #![default_lib_allocator] +// Removed features +#![unstable_removed( + feature = "concat_idents", + reason = "Replaced by the macro_metavar_expr_concat feature", + link = "https://github.com/rust-lang/rust/issues/29599#issuecomment-2986866250", + since = "1.90.0" +)] // The Rust prelude // The compiler expects the prelude definition to be defined before its use statement. diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index f2f2dd909fae9..93c59675d8936 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -23,6 +23,9 @@ The `unstable` attribute infects all sub-items, where the attribute doesn't have to be reapplied. So if you apply this to a module, all items in the module will be unstable. +If you rename a feature, you can add `old_name = "old_name"` to produce a +useful error message. + You can make specific sub-items stable by using the `#[stable]` attribute on them. The stability scheme works similarly to how `pub` works. You can have public functions of nonpublic modules and you can have stable functions in @@ -189,4 +192,11 @@ Currently, the items that can be annotated with `#[unstable_feature_bound]` are: - free function - trait +## renamed and removed features +Unstable features can get renamed and removed. If you rename a feature, you can add `old_name = "old_name"` to the `#[unstable]` attribute. +If you remove a feature, the `#!unstable_removed(feature = "foo", reason = "brief description", link = "link", since = "1.90.0")` +attribute should be used to produce a good error message for users of the removed feature. + +The `link` field can be used to link to the most relevant information on the removal of the feature such as a GitHub issue, comment or PR. + [blog]: https://www.ralfj.de/blog/2018/07/19/const.html diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 4634b24106e4d..751db71ceff00 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -904,7 +904,6 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { return; } - tcx.force_delayed_owners_lowering(); rustc_interface::passes::emit_delayed_lints(tcx); if render_opts.dep_info().is_some() { diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 712dcf60e695e..d1096a02fd634 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -10,7 +10,6 @@ use rustc_ast::mut_visit::*; use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind, Pinnedness}; use rustc_ast_pretty::pprust; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; -use rustc_data_structures::thinvec::ExtractIf; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::impl_lint_pass; @@ -422,9 +421,7 @@ fn drain_matching( let mut tail_or = ThinVec::new(); let mut idx = 0; - // FIXME: once `thin-vec` releases a new version, change this to `alternatives.extract_if()` - // See https://github.com/mozilla/thin-vec/issues/77 - for pat in ExtractIf::new(alternatives, |p| { + for pat in alternatives.extract_if(.., |p| { // Check if we should extract, but only if `idx >= start`. idx += 1; idx > start && predicate(&p.kind) diff --git a/src/tools/rust-analyzer/.github/workflows/gen-lints.yml b/src/tools/rust-analyzer/.github/workflows/gen-lints.yml index 7319b2b3263b9..c978e3571c40d 100644 --- a/src/tools/rust-analyzer/.github/workflows/gen-lints.yml +++ b/src/tools/rust-analyzer/.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/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 770f8cb94095c..da530b3a9304d 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index cf2a7607b0192..15de1f329385d 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs index d253f6f492c7c..7af3ed5dc9a60 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs +++ b/src/tools/rust-analyzer/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, - ) -> 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, -) -> Option { - 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 { use intern::sym; diff --git a/src/tools/rust-analyzer/crates/cfg/src/tests.rs b/src/tools/rust-analyzer/crates/cfg/src/tests.rs index 52c581dbbd3ae..bfc9220a05d9b 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/tests.rs +++ b/src/tools/rust-analyzer/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::>(); 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::>(); 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/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs index dddfe8cefdaa4..b560d08492ff9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs +++ b/src/tools/rust-analyzer/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 { +fn match_attr_flags(attr_flags: &mut AttrFlags, attr: ast::Meta) -> ControlFlow { 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 {} }, - 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( db: &dyn DefDatabase, owner: AttrDefId, - mut callback: impl FnMut(Meta) -> ControlFlow, + mut callback: impl FnMut(ast::Meta) -> ControlFlow, ) -> Option { 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( 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, attr: Meta) -> ControlFlow { - if let Meta::TokenTree { path, tt } = attr - && path.is1("doc") +fn extract_doc_aliases(result: &mut Vec, attr: ast::Meta) -> ControlFlow { + 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, attr: Meta) -> ControlFlow, attr: Meta) -> ControlFlow { - if let Meta::TokenTree { path, tt } = attr - && path.is1("cfg") +fn extract_cfgs(result: &mut Vec, attr: ast::Meta) -> ControlFlow { + 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::::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::::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 { 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 { let mut result = None; collect_attrs::(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> { 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 { let mut result = FxHashSet::default(); collect_attrs::(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::(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 { 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 { 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/src/tools/rust-analyzer/crates/hir-def/src/attrs/docs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs/docs.rs index 8c14808c71957..9a715b19688e6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attrs/docs.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs index 4308d0ef1c296..c38ceccd1fc09 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs @@ -68,7 +68,7 @@ pub mod keys { pub const MACRO_CALL: Key = Key::new(); pub const ATTR_MACRO_CALL: Key = Key::new(); pub const DERIVE_MACRO_CALL: Key< - ast::Attr, + ast::Meta, ( AttrId, /* derive() */ MacroCallId, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs index 79076112847bf..867d813e3f2b9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/attrs.rs +++ b/src/tools/rust-analyzer/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::(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::(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/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs index 7b5d0103e66ee..e75c96b630390 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs index ddabb50251a4d..cac248f47fff9 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs index bf04a500a57dc..8c91cf6793a57 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/proc_macros.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml index 4fa476afb64a3..43b0bea891e39 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs index e3f10b2129048..49baecb90cd50 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs +++ b/src/tools/rust-analyzer/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, - 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; + + fn as_up_to_two_segment(&self) -> Option<(SmolStr, Option)>; } -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 { + 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, - value: Option, - }, - TokenTree { - path: AttrPath, - tt: ast::TokenTree, - }, - Path { - path: AttrPath, - }, + fn as_up_to_two_segment(&self) -> Option<(SmolStr, Option)> { + 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 { + fn is1(&self, segment: &str) -> bool { + self.as_ref().is_some_and(|it| it.is1(segment)) } - fn extract(iter: &mut Peekable) -> 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 { + 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)> { + self.as_ref().and_then(|it| it.as_up_to_two_segment()) } +} + +pub trait AstKeyValueMetaExt { + fn value_string(&self) -> Option; +} - fn extract_possibly_unsafe( - iter: &mut Peekable, - 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 { + 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, cfg_options: impl FnMut() -> &'a CfgOptions, - mut callback: impl FnMut(Meta, &SyntaxNode, TextRange, &ast::Attr) -> ControlFlow, + mut callback: impl FnMut(ast::Meta, ast::Attr) -> ControlFlow, ) -> Option { expand_cfg_attr_with_doc_comments::( 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>, mut cfg_options: impl FnMut() -> &'a CfgOptions, - mut callback: impl FnMut( - Either<(Meta, &SyntaxNode, TextRange, &ast::Attr), DocComment>, - ) -> ControlFlow, + mut callback: impl FnMut(Either<(ast::Meta, ast::Attr), DocComment>) -> ControlFlow, ) -> Option { 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, + mut on_attr: impl FnMut(ast::Meta, ast::Attr) -> ControlFlow, ) -> Option> { 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( self, db: &dyn ExpandDatabase, krate: Crate, owner: AstId, - ) -> (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, 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/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs b/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs index ccef9168ac3a2..6258fac0e9923 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs +++ b/src/tools/rust-analyzer/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 { - let cfg_expr = CfgExpr::parse_from_ast(&mut TokenTreeChildren::new(attr).peekable()); - krate.cfg_options(db).check(&cfg_expr) -} diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs b/src/tools/rust-analyzer/crates/hir-expand/src/db.rs index 8a6b56d93226d..8dddddfabb7a2 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/db.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs b/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs index 1726412275991..4b2c6e73517b8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/declarative.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 4b2c75ed386e7..8d42a24e2fae8 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 89f3cfd140980..2829902035985 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs index 9a31a08ffb52d..9996162485910 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs +++ b/src/tools/rust-analyzer/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 Semantics<'_, DB> { hir_expand::attrs::expand_cfg_attr::( 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 { - 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 { - let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; + pub fn expand_derive_as_pseudo_attr_macro(&self, attr: &ast::Meta) -> Option { + 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>> { + pub fn resolve_derive_macro(&self, attr: &ast::Meta) -> Option>> { 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>>> { 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>>> { - 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/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index f6d1bec5754cb..babeb3591345c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs index 59bccc22d8de6..d932198b43a7d 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs +++ b/src/tools/rust-analyzer/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, + src: InFile, ) -> Option<(AttrId, MacroCallId, &[Option>])> { 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/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs index e022a27e519a5..fccc04770e897 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs +++ b/src/tools/rust-analyzer/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 { - 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/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs index 3ef68f06e499d..7aeb5e3396969 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_derive.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs index 2fc2b9efe81f7..7746cdc068a1f 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_single_field_struct_from.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 04c9d8e54de5c..5e595218f6b1a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/src/tools/rust-analyzer/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::>(); - 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/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 36df4af31d5e2..3b8988db7aae7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/src/tools/rust-analyzer/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) -> 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::>>()?; 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 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::>(); 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/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs index 66d5cf834f177..a499607c1f711 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs index 3de8ec7f536c3..896743342c1a0 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs index 4a94383ff4cbd..9a09e9bd4a20b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs index 20776f6c49f69..da1e664f961c7 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs index 8c532e0f4d04f..99ca55bdaf74a 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs index 413830904aa8c..2cf87baf33077 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/flyimport.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/context.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs index ae3f71760744a..485e5f0cafd7f 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs +++ b/src/tools/rust-analyzer/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, + fake_attribute_under_caret: Option, extern_crate: Option, }, + /// Set if we are inside the predicate of a #[cfg] or #[cfg_attr]. + CfgPredicate, MacroSegment, } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs index d8f160c1005e6..2a293313f2c92 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs +++ b/src/tools/rust-analyzer/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::( + &speculative_file, + speculative_offset, + ) + .is_some() + { + CompletionAnalysis::CfgPredicate } else { return None; } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index 69ca2af7721b8..3867e65ae57e4 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/render.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs index b946441991383..b6da6fba638fc 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs index 8e50ef10eca65..4a5983097a12c 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/expression.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs index d7db896679dfd..5391e6c9ce6e5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/flyimport.rs @@ -1242,6 +1242,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() { + ::foo$0 +} + "#, + expect![[r#""#]], + ); + + check( + r#" +mod m { + pub fn foo() {} +} +struct Bar; +trait Foo {} +impl Foo for Bar {} +fn main() { + ::foo$0 +} + "#, + expect![[r#""#]], + ); +} + #[test] fn no_inherent_candidates_proposed() { check( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs index b82b23541c5c8..55059a4035e73 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/special.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index 9e6d58600888c..c25feceb4157d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/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, @@ -40,10 +40,24 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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, }, @@ -54,6 +68,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -61,6 +82,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -145,13 +173,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -194,6 +215,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -201,6 +229,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -215,10 +257,17 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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, @@ -285,6 +341,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -320,13 +383,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -397,6 +453,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -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, }, @@ -460,6 +523,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -481,9 +551,30 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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, }, @@ -537,6 +628,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -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, }, @@ -614,6 +712,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -642,6 +754,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -656,10 +782,24 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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", @@ -838,17 +978,10 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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, }, @@ -901,13 +1034,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -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), @@ -1167,13 +1314,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -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, @@ -1251,6 +1391,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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::`"##, @@ -1258,6 +1412,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -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, @@ -1489,6 +1650,13 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -1503,6 +1671,20 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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"##, @@ -1517,13 +1699,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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 { }`"##, @@ -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, @@ -1601,9 +1776,16 @@ pub const DEFAULT_LINTS: &[Lint] = &[ warn_since: None, 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 { @@ -1788,10 +1971,25 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[ "unsafe_op_in_unsafe_fn", ], }, + 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", @@ -1901,16 +2100,9 @@ pub const RUSTDOC_LINTS: &[Lint] = &[ warn_since: None, 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. + +The tracking issue for this feature is: [#150244] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#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. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150245] + +[#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. - ``` 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:: u32>(addr) }; + unsafe { core::mem::transmute:: u32>(addr) }; non_secure_function() } ``` @@ -2079,18 +2272,50 @@ call_nonsecure_function: deny_since: None, }, Lint { - label: "abi_msp430_interrupt", - description: r##"# `abi_msp430_interrupt` - -The tracking issue for this feature is: [#38487] + label: "abi_custom", + description: r##"# `abi_custom` -[#38487]: https://github.com/rust-lang/rust/issues/38487 +Allows `extern "custom" fn()`. ------------------------- +The tracking issue for this feature is: [#140829] -In the MSP430 architecture, interrupt handlers have a special calling -convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply -the right calling convention to the interrupt handlers you define. +[#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` + +The tracking issue for this feature is: [#38487] + +[#38487]: https://github.com/rust-lang/rust/issues/38487 + +------------------------ + +In the MSP430 architecture, interrupt handlers have a special calling +convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply +the right calling convention to the interrupt handlers you define. @@ -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 @@ -2339,6 +2576,22 @@ fn is_foo_a_and_bar_true() -> bool { } } ``` +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -2348,6 +2601,8 @@ fn is_foo_a_and_bar_true() -> bool { 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 ------------------------ "##, @@ -2428,6 +2689,20 @@ This feature does not have a tracking issue, it is an unstable implementation detail of the `global_allocator` feature not intended for use outside the compiler. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -2438,6 +2713,8 @@ compiler. 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` 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) -> i32 { 1 } // note self type +} + +struct SmartPtr(T); + +impl core::ops::Receiver for SmartPtr { + 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) -> 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) {} // can extract the pointer and do + // what it needs +} + +struct Wrapper(*const T); + +impl core::ops::Receiver for Wrapper { + 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 ` 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 `. - -When `label ` 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,12 +3399,14 @@ 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` + label: "associated_type_defaults", + description: r##"# `associated_type_defaults` + +Allows associated type defaults. -The tracking issue for this feature is: [#82775] +The tracking issue for this feature is: [#29661] -[#82775]: https://github.com/rust-lang/rust/issues/82775 +[#29661]: https://github.com/rust-lang/rust/issues/29661 ------------------------ "##, @@ -3005,12 +3415,14 @@ The tracking issue for this feature is: [#82775] deny_since: None, }, Lint { - label: "associated_const_equality", - description: r##"# `associated_const_equality` + label: "async_drop", + description: r##"# `async_drop` -The tracking issue for this feature is: [#92827] +Allows implementing `AsyncDrop`. + +The tracking issue for this feature is: [#126482] -[#92827]: https://github.com/rust-lang/rust/issues/92827 +[#126482]: https://github.com/rust-lang/rust/issues/126482 ------------------------ "##, @@ -3019,12 +3431,14 @@ The tracking issue for this feature is: [#92827] deny_since: None, }, Lint { - label: "associated_type_defaults", - description: r##"# `associated_type_defaults` + label: "async_fn_in_dyn_trait", + description: r##"# `async_fn_in_dyn_trait` -The tracking issue for this feature is: [#29661] +Allows async functions to be called from `dyn Trait`. -[#29661]: https://github.com/rust-lang/rust/issues/29661 +The tracking issue for this feature is: [#133119] + +[#133119]: https://github.com/rust-lang/rust/issues/133119 ------------------------ "##, @@ -3033,40 +3447,14 @@ The tracking issue for this feature is: [#29661] deny_since: None, }, Lint { - label: "async_closure", - description: r##"# `async_closure` + label: "async_fn_track_caller", + description: r##"# `async_fn_track_caller` -The tracking issue for this feature is: [#62290] +Allows `#[track_caller]` on async functions. -[#62290]: https://github.com/rust-lang/rust/issues/62290 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "async_drop", - description: r##"# `async_drop` - -The tracking issue for this feature is: [#126482] - -[#126482]: https://github.com/rust-lang/rust/issues/126482 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "async_fn_track_caller", - description: r##"# `async_fn_track_caller` - -The tracking issue for this feature is: [#110011] - -[#110011]: https://github.com/rust-lang/rust/issues/110011 +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,10 +3564,42 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -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` + +Target features on avr. + +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` -The tracking issue for this feature is: [#44839] +Allows using Intel AVX10 target features and intrinsics -[#44839]: https://github.com/rust-lang/rust/issues/44839 +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` -The tracking issue for this feature is: [#85532] -[#85532]: https://github.com/rust-lang/rust/issues/85532 + +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: [#154009] + +[#154009]: https://github.com/rust-lang/rust/issues/154009 ------------------------ "##, @@ -3349,10 +3817,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -3363,10 +3849,76 @@ The tracking issue for this feature is: [#59278] 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -3377,10 +3929,28 @@ The tracking issue for this feature is: [#59278] 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -3391,6 +3961,8 @@ The tracking issue for this feature is: [#80996] 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`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] -[#129397]: https://github.com/rust-lang/rust/issues/129397 +The tracking issue for this feature is: [#147212] + +[#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. + +The tracking issue for this feature is: [#150247] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#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,14 @@ 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 ------------------------ "##, @@ -3537,12 +4127,28 @@ The tracking issue for this feature is: [#107540] deny_since: None, }, Lint { - label: "btree_entry_insert", - description: r##"# `btree_entry_insert` + label: "bstr_internals", + description: r##"# `bstr_internals` -The tracking issue for this feature is: [#65225] -[#65225]: https://github.com/rust-lang/rust/issues/65225 + +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: "btree_cursors", + description: r##"# `btree_cursors` + + + +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] +The tracking issue for this feature is: [#152152] -[#70530]: https://github.com/rust-lang/rust/issues/70530 +[#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] - -[#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. + label: "c_variadic_naked_functions", + description: r##"# `c_variadic_naked_functions` -## Examples +Allows defining c-variadic naked functions with any extern ABI that is allowed on c-variadic foreign functions. -```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::(); - } - 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,46 @@ 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cast_maybe_uninit", + description: r##"# `cast_maybe_uninit` + + + +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 ------------------------ "##, @@ -3767,12 +4392,14 @@ The tracking issue for this feature is: [#69099] deny_since: None, }, Lint { - label: "cell_update", - description: r##"# `cell_update` + label: "cell_leak", + description: r##"# `cell_leak` + -The tracking issue for this feature is: [#50186] -[#50186]: https://github.com/rust-lang/rust/issues/50186 +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,28 @@ 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "cfg_emscripten_wasm_eh", + description: r##"# `cfg_emscripten_wasm_eh` + +Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -3809,12 +4454,14 @@ The tracking issue for this feature is: [#82679] deny_since: None, }, Lint { - label: "cfg_match", - description: r##"# `cfg_match` + label: "cfg_eval", + description: r##"# `cfg_eval` + -The tracking issue for this feature is: [#115585] -[#115585]: https://github.com/rust-lang/rust/issues/115585 +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,10 +4594,26 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -3951,6 +4624,8 @@ The tracking issue for this feature is: [#93822] 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,8 +4730,58 @@ 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. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -4065,6 +4792,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp 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 } ``` @@ -4205,6 +4935,20 @@ $ arm-none-eabi-objdump -D function.o 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E> 40: defe udf #254 ; 0xfe ``` +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -4214,6 +4958,8 @@ $ arm-none-eabi-objdump -D function.o 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,10 +4971,14 @@ The tracking issue for this feature is: [#18598] deny_since: None, }, Lint { - label: "compiler_builtins", - description: r##"# `compiler_builtins` + label: "command_resolved_envs", + description: r##"# `command_resolved_envs` -This feature is internal to the Rust compiler and is not intended for general use. + + +The tracking issue for this feature is: [#149070] + +[#149070]: https://github.com/rust-lang/rust/issues/149070 ------------------------ "##, @@ -4237,12 +4987,10 @@ This feature is internal to the Rust compiler and is not intended for general us deny_since: None, }, Lint { - label: "concat_bytes", - description: r##"# `concat_bytes` - -The tracking issue for this feature is: [#87555] + label: "compiler_builtins", + description: r##"# `compiler_builtins` -[#87555]: https://github.com/rust-lang/rust/issues/87555 +This feature is internal to the Rust compiler and is not intended for general use. ------------------------ "##, @@ -4251,29 +4999,16 @@ The tracking issue for this feature is: [#87555] deny_since: None, }, Lint { - label: "concat_idents", - description: r##"# `concat_idents` - -The tracking issue for this feature is: [#29599] - -[#29599]: https://github.com/rust-lang/rust/issues/29599 + label: "concat_bytes", + description: r##"# `concat_bytes` ------------------------- -The `concat_idents` feature adds a macro for concatenating multiple identifiers -into one identifier. -## Examples +The tracking issue for this feature is: [#87555] -```rust -#![feature(concat_idents)] +[#87555]: https://github.com/rust-lang/rust/issues/87555 -fn main() { - fn foobar() -> u32 { 23 } - let f = concat_idents!(foo, bar); - assert_eq!(f(), 23); -} -``` +------------------------ "##, default_severity: Severity::Allow, warn_since: None, @@ -4283,6 +5018,8 @@ fn main() { label: "const_alloc_error", description: r##"# `const_alloc_error` + + The tracking issue for this feature is: [#92523] [#92523]: https://github.com/rust-lang/rust/issues/92523 @@ -4294,12 +5031,14 @@ The tracking issue for this feature is: [#92523] deny_since: None, }, Lint { - label: "const_alloc_layout", - description: r##"# `const_alloc_layout` + label: "const_array", + description: r##"# `const_array` -The tracking issue for this feature is: [#67521] -[#67521]: https://github.com/rust-lang/rust/issues/67521 + +The tracking issue for this feature is: [#147606] + +[#147606]: https://github.com/rust-lang/rust/issues/147606 ------------------------ "##, @@ -4308,12 +5047,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_async_blocks", + description: r##"# `const_async_blocks` -The tracking issue for this feature is: [#133333] +Allows `async {}` expressions in const contexts. -[#133333]: https://github.com/rust-lang/rust/issues/133333 +The tracking issue for this feature is: [#85368] + +[#85368]: https://github.com/rust-lang/rust/issues/85368 ------------------------ "##, @@ -4322,12 +5063,14 @@ 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_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: [#133289] +The tracking issue for this feature is: [#149226] -[#133289]: https://github.com/rust-lang/rust/issues/133289 +[#149226]: https://github.com/rust-lang/rust/issues/149226 ------------------------ "##, @@ -4336,12 +5079,14 @@ The tracking issue for this feature is: [#133289] deny_since: None, }, Lint { - label: "const_async_blocks", - description: r##"# `const_async_blocks` + label: "const_bool", + description: r##"# `const_bool` -The tracking issue for this feature is: [#85368] -[#85368]: https://github.com/rust-lang/rust/issues/85368 + +The tracking issue for this feature is: [#151531] + +[#151531]: https://github.com/rust-lang/rust/issues/151531 ------------------------ "##, @@ -4350,8 +5095,10 @@ The tracking issue for this feature is: [#85368] deny_since: None, }, Lint { - label: "const_black_box", - description: r##"# `const_black_box` + label: "const_btree_len", + description: r##"# `const_btree_len` + + This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. @@ -4362,12 +5109,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_c_variadic", + description: r##"# `const_c_variadic` -The tracking issue for this feature is: [#92521] +Allows defining and calling c-variadic functions in const contexts. -[#92521]: https://github.com/rust-lang/rust/issues/92521 +The tracking issue for this feature is: [#151787] + +[#151787]: https://github.com/rust-lang/rust/issues/151787 ------------------------ "##, @@ -4376,10 +5125,14 @@ The tracking issue for this feature is: [#92521] deny_since: None, }, Lint { - label: "const_btree_len", - description: r##"# `const_btree_len` + 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 ------------------------ "##, @@ -4388,12 +5141,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_cell_traits", + description: r##"# `const_cell_traits` + -The tracking issue for this feature is: [#131283] -[#131283]: https://github.com/rust-lang/rust/issues/131283 +The tracking issue for this feature is: [#147787] + +[#147787]: https://github.com/rust-lang/rust/issues/147787 ------------------------ "##, @@ -4402,12 +5157,14 @@ The tracking issue for this feature is: [#131283] deny_since: None, }, Lint { - label: "const_char_classify", - description: r##"# `const_char_classify` + label: "const_clone", + description: r##"# `const_clone` + -The tracking issue for this feature is: [#132241] -[#132241]: https://github.com/rust-lang/rust/issues/132241 +The tracking issue for this feature is: [#142757] + +[#142757]: https://github.com/rust-lang/rust/issues/142757 ------------------------ "##, @@ -4419,6 +5176,8 @@ The tracking issue for this feature is: [#132241] label: "const_closures", description: r##"# `const_closures` +Allows `const || {}` closures in const contexts. + The tracking issue for this feature is: [#106003] [#106003]: https://github.com/rust-lang/rust/issues/106003 @@ -4430,12 +5189,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_cmp", + description: r##"# `const_cmp` -The tracking issue for this feature is: [#131415] -[#131415]: https://github.com/rust-lang/rust/issues/131415 + +The tracking issue for this feature is: [#143800] + +[#143800]: https://github.com/rust-lang/rust/issues/143800 ------------------------ "##, @@ -4444,12 +5205,14 @@ The tracking issue for this feature is: [#131415] deny_since: None, }, Lint { - label: "const_destruct", - description: r##"# `const_destruct` + label: "const_control_flow", + description: r##"# `const_control_flow` -The tracking issue for this feature is: [#133214] -[#133214]: https://github.com/rust-lang/rust/issues/133214 + +The tracking issue for this feature is: [#148739] + +[#148739]: https://github.com/rust-lang/rust/issues/148739 ------------------------ "##, @@ -4458,12 +5221,14 @@ The tracking issue for this feature is: [#133214] deny_since: None, }, Lint { - label: "const_eval_select", - description: r##"# `const_eval_select` + label: "const_convert", + description: r##"# `const_convert` -The tracking issue for this feature is: [#124625] -[#124625]: https://github.com/rust-lang/rust/issues/124625 + +The tracking issue for this feature is: [#143773] + +[#143773]: https://github.com/rust-lang/rust/issues/143773 ------------------------ "##, @@ -4472,12 +5237,14 @@ The tracking issue for this feature is: [#124625] deny_since: None, }, Lint { - label: "const_for", - description: r##"# `const_for` + label: "const_default", + description: r##"# `const_default` -The tracking issue for this feature is: [#87575] -[#87575]: https://github.com/rust-lang/rust/issues/87575 + +The tracking issue for this feature is: [#143894] + +[#143894]: https://github.com/rust-lang/rust/issues/143894 ------------------------ "##, @@ -4486,10 +5253,14 @@ The tracking issue for this feature is: [#87575] deny_since: None, }, Lint { - label: "const_format_args", - description: r##"# `const_format_args` + label: "const_destruct", + description: r##"# `const_destruct` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +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 ------------------------ "##, @@ -4498,12 +5269,12 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "const_heap", - description: r##"# `const_heap` + label: "const_drop_guard", + description: r##"# `const_drop_guard` -The tracking issue for this feature is: [#79597] -[#79597]: https://github.com/rust-lang/rust/issues/79597 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -4512,12 +5283,14 @@ 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_drop_in_place", + description: r##"# `const_drop_in_place` + -The tracking issue for this feature is: [#131516] -[#131516]: https://github.com/rust-lang/rust/issues/131516 +The tracking issue for this feature is: [#109342] + +[#109342]: https://github.com/rust-lang/rust/issues/109342 ------------------------ "##, @@ -4526,12 +5299,14 @@ The tracking issue for this feature is: [#131516] deny_since: None, }, Lint { - label: "const_mut_cursor", - description: r##"# `const_mut_cursor` + label: "const_eval_select", + description: r##"# `const_eval_select` + -The tracking issue for this feature is: [#130801] -[#130801]: https://github.com/rust-lang/rust/issues/130801 +The tracking issue for this feature is: [#124625] + +[#124625]: https://github.com/rust-lang/rust/issues/124625 ------------------------ "##, @@ -4540,12 +5315,14 @@ The tracking issue for this feature is: [#130801] deny_since: None, }, Lint { - label: "const_precise_live_drops", - description: r##"# `const_precise_live_drops` + label: "const_for", + description: r##"# `const_for` -The tracking issue for this feature is: [#73255] +Allows `for _ in _` loops in const contexts. -[#73255]: https://github.com/rust-lang/rust/issues/73255 +The tracking issue for this feature is: [#87575] + +[#87575]: https://github.com/rust-lang/rust/issues/87575 ------------------------ "##, @@ -4554,12 +5331,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_format_args", + description: r##"# `const_format_args` -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. ------------------------ "##, @@ -4568,8 +5345,198 @@ The tracking issue for this feature is: [#95892] deny_since: None, }, Lint { - label: "const_range_bounds", - description: r##"# `const_range_bounds` + label: "const_heap", + description: r##"# `const_heap` + + + +The tracking issue for this feature is: [#79597] + +[#79597]: https://github.com/rust-lang/rust/issues/79597 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_index", + description: r##"# `const_index` + + + +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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_never_short_circuit", + description: r##"# `const_never_short_circuit` + + + +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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_range", + description: r##"# `const_range` + + + +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_range_bounds", + description: r##"# `const_range_bounds` + + The tracking issue for this feature is: [#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] +The tracking issue for this feature is: [#137844] -[#95629]: https://github.com/rust-lang/rust/issues/95629 +[#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,14 @@ 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: [#89792] -[#89792]: https://github.com/rust-lang/rust/issues/89792 + +The tracking issue for this feature is: [#148714] + +[#148714]: https://github.com/rust-lang/rust/issues/148714 ------------------------ "##, @@ -4638,12 +5613,14 @@ The tracking issue for this feature is: [#89792] deny_since: None, }, Lint { - label: "const_sockaddr_setters", - description: r##"# `const_sockaddr_setters` + label: "const_select_unpredictable", + description: r##"# `const_select_unpredictable` + + -The tracking issue for this feature is: [#131714] +The tracking issue for this feature is: [#145938] -[#131714]: https://github.com/rust-lang/rust/issues/131714 +[#145938]: https://github.com/rust-lang/rust/issues/145938 ------------------------ "##, @@ -4652,12 +5629,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_mut_ptr_range", + description: r##"# `const_slice_from_mut_ptr_range` -The tracking issue for this feature is: [#91006] -[#91006]: https://github.com/rust-lang/rust/issues/91006 + +The tracking issue for this feature is: [#89792] + +[#89792]: https://github.com/rust-lang/rust/issues/89792 ------------------------ "##, @@ -4666,12 +5645,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_from_ptr_range", + description: r##"# `const_slice_from_ptr_range` + -The tracking issue for this feature is: [#131518] -[#131518]: https://github.com/rust-lang/rust/issues/131518 +The tracking issue for this feature is: [#89792] + +[#89792]: https://github.com/rust-lang/rust/issues/89792 ------------------------ "##, @@ -4680,12 +5661,30 @@ The tracking issue for this feature is: [#131518] deny_since: None, }, Lint { - label: "const_swap", - description: r##"# `const_swap` + label: "const_slice_make_iter", + description: r##"# `const_slice_make_iter` -The tracking issue for this feature is: [#83163] -[#83163]: https://github.com/rust-lang/rust/issues/83163 + +The tracking issue for this feature is: [#137737] + +[#137737]: https://github.com/rust-lang/rust/issues/137737 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "const_split_off_first_last", + description: r##"# `const_split_off_first_last` + + + +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] -[#133668]: https://github.com/rust-lang/rust/issues/133668 +The tracking issue for this feature is: [#142204] + +[#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] -[#129041]: https://github.com/rust-lang/rust/issues/129041 +The tracking issue for this feature is: [#123392] + +[#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,10 +5870,42 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -4835,6 +5918,20 @@ The tracking issue for this feature is: [#67057] 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: "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, @@ -4845,6 +5942,8 @@ This feature is internal to the Rust compiler and is not intended for general us 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. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150248] + +[#150248]: https://github.com/rust-lang/rust/issues/150248 ------------------------ "##, @@ -5230,10 +6337,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5244,8 +6369,26 @@ The tracking issue for this feature is: [#112115] 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. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5256,6 +6399,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp 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. ------------------------ @@ -5326,6 +6475,22 @@ const WILL_PASS: i32 = 0; #[test_case] const WILL_FAIL: i32 = 4; ``` +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5335,6 +6500,8 @@ const WILL_FAIL: i32 = 4; 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, // 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. -[#94978]: https://github.com/rust-lang/rust/issues/94978 +The tracking issue for this feature is: [#94785] + +[#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::(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,11 +6858,75 @@ 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. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5509,6 +6937,8 @@ This feature is internal to the Rust compiler and is not intended for general us 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. ------------------------ "##, @@ -5619,20 +7073,6 @@ pub struct Icon { [#43781]: https://github.com/rust-lang/rust/issues/43781 [#43348]: https://github.com/rust-lang/rust/issues/43348 -"##, - default_severity: Severity::Allow, - warn_since: None, - 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, @@ -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,10 +7169,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5741,6 +7201,8 @@ The tracking issue for this feature is: [#101122] 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 @@ -5776,6 +7240,22 @@ The tracking issue for this feature is: [#120301] ------------------------ Add the methods `from_days` and `from_weeks` to `Duration`. +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5785,9 +7265,27 @@ Add the methods `from_days` and `from_weeks` to `Duration`. 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 +[#122451]: https://github.com/rust-lang/rust/issues/122451 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "duration_units", + description: r##"# `duration_units` + + + +The tracking issue for this feature is: [#120301] + +[#120301]: https://github.com/rust-lang/rust/issues/120301 ------------------------ "##, @@ -5796,12 +7294,12 @@ The tracking issue for this feature is: [#122451] deny_since: None, }, Lint { - label: "duration_units", - description: r##"# `duration_units` + label: "edition_panic", + description: r##"# `edition_panic` -The tracking issue for this feature is: [#120301] -[#120301]: https://github.com/rust-lang/rust/issues/120301 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -5810,12 +7308,14 @@ The tracking issue for this feature is: [#120301] deny_since: None, }, Lint { - label: "dyn_compatible_for_dispatch", - description: r##"# `dyn_compatible_for_dispatch` + label: "effective_target_features", + description: r##"# `effective_target_features` -The tracking issue for this feature is: [#43561] +Allows features to allow target_feature to better interact with traits. -[#43561]: https://github.com/rust-lang/rust/issues/43561 +The tracking issue for this feature is: [#143352] + +[#143352]: https://github.com/rust-lang/rust/issues/143352 ------------------------ "##, @@ -5824,12 +7324,12 @@ The tracking issue for this feature is: [#43561] deny_since: None, }, Lint { - label: "dyn_star", - description: r##"# `dyn_star` + label: "eii_internals", + description: r##"# `eii_internals` -The tracking issue for this feature is: [#102425] +Implementation details of externally implementable items -[#102425]: https://github.com/rust-lang/rust/issues/102425 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -5838,10 +7338,14 @@ The tracking issue for this feature is: [#102425] deny_since: None, }, Lint { - label: "edition_panic", - description: r##"# `edition_panic` + label: "ergonomic_clones", + description: r##"# `ergonomic_clones` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +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 ------------------------ "##, @@ -5853,9 +7357,11 @@ This feature has no tracking issue, and is therefore likely internal to the comp 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,10 +7421,44 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5923,6 +7469,8 @@ The tracking issue for this feature is: [#60784] 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,11 +7533,45 @@ 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 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -5993,10 +7581,28 @@ The tracking issue for this feature is: [#97100] 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -6007,6 +7613,8 @@ The tracking issue for this feature is: [#112788] 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` + +Allows defining `extern type`s. -The tracking issue for this feature is: [#43244] +The tracking issue for this feature is: [#43467] -[#43244]: https://github.com/rust-lang/rust/issues/43244 +[#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, @@ -6095,18 +7709,6 @@ Enable the `f16` type for IEEE 16-bit floating numbers (half precision). 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: "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, @@ -6230,6 +7832,36 @@ against are compatible with those of the `#[ffi_pure]`. [ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html [GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute [IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -6239,6 +7871,8 @@ against are compatible with those of the `#[ffi_pure]`. 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: [#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: [#130994] -[#130994]: https://github.com/rust-lang/rust/issues/130994 +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,23 +8185,91 @@ 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 ------------------------- +The tracking issue for this feature is: [#118117] + +[#118117]: https://github.com/rust-lang/rust/issues/118117 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "freeze", + description: r##"# `freeze` + + + +The tracking issue for this feature is: [#121675] + +[#121675]: https://github.com/rust-lang/rust/issues/121675 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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: "freeze", - description: r##"# `freeze` + label: "fs_set_times", + description: r##"# `fs_set_times` -The tracking issue for this feature is: [#121675] -[#121675]: https://github.com/rust-lang/rust/issues/121675 + +The tracking issue for this feature is: [#147455] + +[#147455]: https://github.com/rust-lang/rust/issues/147455 ------------------------ "##, @@ -6490,12 +8278,14 @@ The tracking issue for this feature is: [#121675] deny_since: None, }, Lint { - label: "freeze_impls", - description: r##"# `freeze_impls` + label: "fundamental", + description: r##"# `fundamental` -The tracking issue for this feature is: [#121675] +Allows using the `#[fundamental]` attribute. -[#121675]: https://github.com/rust-lang/rust/issues/121675 +The tracking issue for this feature is: [#29635] + +[#29635]: https://github.com/rust-lang/rust/issues/29635 ------------------------ "##, @@ -6504,12 +8294,14 @@ The tracking issue for this feature is: [#121675] deny_since: None, }, Lint { - label: "fundamental", - description: r##"# `fundamental` + label: "funnel_shifts", + description: r##"# `funnel_shifts` -The tracking issue for this feature is: [#29635] -[#29635]: https://github.com/rust-lang/rust/issues/29635 + +The tracking issue for this feature is: [#145686] + +[#145686]: https://github.com/rust-lang/rust/issues/145686 ------------------------ "##, @@ -6521,6 +8313,8 @@ The tracking issue for this feature is: [#29635] 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` + +Allows any generic constants being used as pattern type range ends -The tracking issue for this feature is: [#104642] +The tracking issue for this feature is: [#136574] -[#104642]: https://github.com/rust-lang/rust/issues/104642 +[#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,10 +8499,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -6671,10 +8531,26 @@ The tracking issue for this feature is: [#63292] 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -6685,6 +8561,8 @@ The tracking issue for this feature is: [#125119] 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] +The tracking issue for this feature is: [#144032] -[#56167]: https://github.com/rust-lang/rust/issues/56167 +[#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. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150250] + +[#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` + +Allows `impl(crate) trait Foo` restrictions. -The tracking issue for this feature is: [#51114] +The tracking issue for this feature is: [#105077] -[#51114]: https://github.com/rust-lang/rust/issues/51114 +[#105077]: https://github.com/rust-lang/rust/issues/105077 ------------------------ "##, @@ -6845,10 +8753,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -6859,11 +8785,42 @@ The tracking issue for this feature is: [#63063] 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 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -6873,6 +8830,8 @@ The tracking issue for this feature is: [#99697] 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(x: T) -> U; - fn arith_offset(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,10 +9351,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -7362,6 +9383,8 @@ The tracking issue for this feature is: [#62544] 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. + +The tracking issue for this feature is: [#150251] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#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,10 +9874,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -7852,10 +9906,28 @@ The tracking issue for this feature is: [#82971] label: "local_waker", description: r##"# `local_waker` + + The tracking issue for this feature is: [#118959] [#118959]: https://github.com/rust-lang/rust/issues/118959 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -7866,6 +9938,8 @@ The tracking issue for this feature is: [#118959] 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,134 @@ 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] + +[#150252]: https://github.com/rust-lang/rust/issues/150252 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "loop_match", + description: r##"# `loop_match` + +The tracking issue for this feature is: [#132306] + +[#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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "macro_attr", + description: r##"# `macro_attr` + +Allow `macro_rules!` attribute rules + +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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "macro_guard_matcher", + description: r##"# `macro_guard_matcher` + +Allow `$x:guard` matcher in macros -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#153104] + +[#153104]: https://github.com/rust-lang/rust/issues/153104 ------------------------ "##, @@ -7896,37 +10095,152 @@ The tracking issue for this feature is: [#44839] 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 + } +} +``` ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "macro_metavar_expr_concat", - description: r##"# `macro_metavar_expr_concat` +#### Create names for macro generated tests -The tracking issue for this feature is: [#124225] +```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) + } -[#124225]: https://github.com/rust-lang/rust/issues/124225 + #[test] + fn ${ concat(test_, $integer, _, subtraction) } () { + let a: $integer = 73; + let b: $integer = 42; + assert_eq!(a - b, 31) + } + } +} ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "map_many_mut", - description: r##"# `map_many_mut` +test_math!(i32); +test_math!(u64); +test_math!(u128); +``` -The tracking issue for this feature is: [#97601] +Running this returns the following output: -[#97601]: https://github.com/rust-lang/rust/issues/97601 +```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 @@ -7997,6 +10315,22 @@ fn cheap_clone(t: T) -> T { This is expected to replace the unstable `overlapping_marker_traits` feature, which applied to all empty traits (without needing an opt-in). +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -8006,6 +10340,8 @@ feature, which applied to all empty traits (without needing an opt-in). 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] +Target features on mips. -[#44839]: https://github.com/rust-lang/rust/issues/44839 +The tracking issue for this feature is: [#150253] ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "mixed_integer_ops_unsigned_sub", - description: r##"# `mixed_integer_ops_unsigned_sub` - -The tracking issue for this feature is: [#126043] - -[#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. ------------------------ @@ -8231,6 +10577,38 @@ impl A for Foo { type Assoc = StructStruct; } ``` +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -8240,10 +10618,28 @@ impl A for Foo { label: "mpmc_channel", description: r##"# `mpmc_channel` + + The tracking issue for this feature is: [#126840] [#126840]: https://github.com/rust-lang/rust/issues/126840 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -8254,7 +10650,11 @@ The tracking issue for this feature is: [#126840] 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: [#138997] + +[#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: [#90957] +The tracking issue for this feature is: [#138568] -[#90957]: https://github.com/rust-lang/rust/issues/90957 +[#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,30 @@ 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: [#154458] + +[#154458]: https://github.com/rust-lang/rust/issues/154458 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "next_index", + description: r##"# `next_index` + -The tracking issue for this feature is: [#129396] -[#129396]: https://github.com/rust-lang/rust/issues/129396 +The tracking issue for this feature is: [#130711] + +[#130711]: https://github.com/rust-lang/rust/issues/130711 ------------------------ "##, @@ -8493,6 +10961,8 @@ The tracking issue for this feature is: [#129396] label: "no_core", description: r##"# `no_core` +Allows `#![no_core]`. + The tracking issue for this feature is: [#29639] [#29639]: https://github.com/rust-lang/rust/issues/29639 @@ -8504,48 +10974,110 @@ The tracking issue for this feature is: [#29639] deny_since: None, }, Lint { - label: "no_sanitize", - description: r##"# `no_sanitize` + label: "non_exhaustive_omitted_patterns_lint", + description: r##"# `non_exhaustive_omitted_patterns_lint` -The tracking issue for this feature is: [#39699] +Allows using the `non_exhaustive_omitted_patterns` lint. -[#39699]: https://github.com/rust-lang/rust/issues/39699 +The tracking issue for this feature is: [#89554] + +[#89554]: https://github.com/rust-lang/rust/issues/89554 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "non_lifetime_binders", + description: r##"# `non_lifetime_binders` + +Allows `for` binders in where-clauses + +The tracking issue for this feature is: [#108185] + +[#108185]: https://github.com/rust-lang/rust/issues/108185 ------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonpoison_condvar", + description: r##"# `nonpoison_condvar` -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. -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. -## Examples +The tracking issue for this feature is: [#134645] -``` rust -#![feature(no_sanitize)] +[#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: [#134645] + +[#134645]: https://github.com/rust-lang/rust/issues/134645 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "nonpoison_rwlock", + description: r##"# `nonpoison_rwlock` + + + +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: "nonzero_bitwise", + description: r##"# `nonzero_bitwise` + + + +The tracking issue for this feature is: [#128281] + +[#128281]: https://github.com/rust-lang/rust/issues/128281 -#[no_sanitize(address)] -fn foo() { - // ... -} -``` +------------------------ "##, default_severity: Severity::Allow, warn_since: None, deny_since: None, }, Lint { - label: "non_exhaustive_omitted_patterns_lint", - description: r##"# `non_exhaustive_omitted_patterns_lint` + label: "nonzero_from_mut", + description: r##"# `nonzero_from_mut` -The tracking issue for this feature is: [#89554] -[#89554]: https://github.com/rust-lang/rust/issues/89554 + +The tracking issue for this feature is: [#106290] + +[#106290]: https://github.com/rust-lang/rust/issues/106290 ------------------------ "##, @@ -8554,12 +11086,14 @@ The tracking issue for this feature is: [#89554] deny_since: None, }, Lint { - label: "non_lifetime_binders", - description: r##"# `non_lifetime_binders` + label: "nonzero_from_str_radix", + description: r##"# `nonzero_from_str_radix` -The tracking issue for this feature is: [#108185] -[#108185]: https://github.com/rust-lang/rust/issues/108185 + +The tracking issue for this feature is: [#152193] + +[#152193]: https://github.com/rust-lang/rust/issues/152193 ------------------------ "##, @@ -8568,12 +11102,12 @@ The tracking issue for this feature is: [#108185] deny_since: None, }, Lint { - label: "non_null_from_ref", - description: r##"# `non_null_from_ref` + label: "nonzero_internals", + description: r##"# `nonzero_internals` + -The tracking issue for this feature is: [#130823] -[#130823]: https://github.com/rust-lang/rust/issues/130823 +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -8582,12 +11116,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: "nonzero_ops", + description: r##"# `nonzero_ops` + -The tracking issue for this feature is: [#120287] -[#120287]: https://github.com/rust-lang/rust/issues/120287 +The tracking issue for this feature is: [#84186] + +[#84186]: https://github.com/rust-lang/rust/issues/84186 ------------------------ "##, @@ -8596,12 +11132,14 @@ The tracking issue for this feature is: [#120287] deny_since: None, }, Lint { - label: "nonzero_bitwise", - description: r##"# `nonzero_bitwise` + label: "normalize_lexically", + description: r##"# `normalize_lexically` -The tracking issue for this feature is: [#128281] -[#128281]: https://github.com/rust-lang/rust/issues/128281 + +The tracking issue for this feature is: [#134694] + +[#134694]: https://github.com/rust-lang/rust/issues/134694 ------------------------ "##, @@ -8610,12 +11148,12 @@ The tracking issue for this feature is: [#128281] deny_since: None, }, Lint { - label: "nonzero_from_mut", - description: r##"# `nonzero_from_mut` + label: "num_internals", + description: r##"# `num_internals` -The tracking issue for this feature is: [#106290] -[#106290]: https://github.com/rust-lang/rust/issues/106290 + +This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. ------------------------ "##, @@ -8624,8 +11162,10 @@ The tracking issue for this feature is: [#106290] deny_since: None, }, Lint { - label: "nonzero_internals", - description: r##"# `nonzero_internals` + 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. @@ -8636,12 +11176,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "nonzero_ops", - description: r##"# `nonzero_ops` + label: "nvptx_target_feature", + description: r##"# `nvptx_target_feature` -The tracking issue for this feature is: [#84186] +Target feaures on nvptx. -[#84186]: https://github.com/rust-lang/rust/issues/84186 +The tracking issue for this feature is: [#150254] + +[#150254]: https://github.com/rust-lang/rust/issues/150254 ------------------------ "##, @@ -8650,12 +11192,12 @@ The tracking issue for this feature is: [#84186] deny_since: None, }, Lint { - label: "num_midpoint_signed", - description: r##"# `num_midpoint_signed` + label: "objc_class_variant", + description: r##"# `objc_class_variant` -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. ------------------------ "##, @@ -8664,8 +11206,10 @@ The tracking issue for this feature is: [#110840] deny_since: None, }, Lint { - label: "numfmt", - description: r##"# `numfmt` + 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. @@ -8684,6 +11228,28 @@ 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, @@ -8698,18 +11264,29 @@ The tracking issue for this feature is: [#126151] [#126151]: https://github.com/rust-lang/rust/issues/126151 ------------------------ -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "omit_gdb_pretty_printer_section", - description: r##"# `omit_gdb_pretty_printer_section` -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +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, @@ -8719,6 +11296,8 @@ This feature has no tracking issue, and is therefore likely internal to the comp 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] +The tracking issue for this feature is: [#69780] -[#127527]: https://github.com/rust-lang/rust/issues/127527 +[#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] -[#120048]: https://github.com/rust-lang/rust/issues/120048 +The tracking issue for this feature is: [#148441] + +[#148441]: https://github.com/rust-lang/rust/issues/148441 ------------------------ "##, @@ -8842,12 +11437,46 @@ 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "option_reference_flattening", + description: r##"# `option_reference_flattening` + + + +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 ------------------------ "##, @@ -8856,12 +11485,14 @@ The tracking issue for this feature is: [#118485] deny_since: None, }, Lint { - label: "os_string_pathbuf_leak", - description: r##"# `os_string_pathbuf_leak` + label: "os_str_slice", + description: r##"# `os_str_slice` + -The tracking issue for this feature is: [#125965] -[#125965]: https://github.com/rust-lang/rust/issues/125965 +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,10 +11630,26 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -9011,6 +11660,8 @@ The tracking issue for this feature is: [#92649] 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,9 +11786,43 @@ The tracking issue for this feature is: [#123646] label: "pattern_types", description: r##"# `pattern_types` -The tracking issue for this feature is: [#123646] +Allows using pattern types. + +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: "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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "phantom_variance_markers", + description: r##"# `phantom_variance_markers` + -[#123646]: https://github.com/rust-lang/rust/issues/123646 + +The tracking issue for this feature is: [#135806] + +[#135806]: https://github.com/rust-lang/rust/issues/135806 ------------------------ "##, @@ -9104,12 +11831,14 @@ The tracking issue for this feature is: [#123646] deny_since: None, }, Lint { - label: "peer_credentials_unix_socket", - description: r##"# `peer_credentials_unix_socket` + label: "pin_coerce_unsized_trait", + description: r##"# `pin_coerce_unsized_trait` -The tracking issue for this feature is: [#42839] -[#42839]: https://github.com/rust-lang/rust/issues/42839 + +The tracking issue for this feature is: [#150112] + +[#150112]: https://github.com/rust-lang/rust/issues/150112 ------------------------ "##, @@ -9118,12 +11847,12 @@ The tracking issue for this feature is: [#42839] deny_since: None, }, Lint { - label: "pin_coerce_unsized_trait", - description: r##"# `pin_coerce_unsized_trait` + label: "pin_derefmut_internals", + description: r##"# `pin_derefmut_internals` -The tracking issue for this feature is: [#123430] -[#123430]: https://github.com/rust-lang/rust/issues/123430 + +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,10 +12175,60 @@ 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -9428,6 +12239,8 @@ The tracking issue for this feature is: [#99515] 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,8 +12253,26 @@ 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. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -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,10 +12339,44 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -9518,6 +12387,8 @@ The tracking issue for this feature is: [#75402] 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,9 +12511,73 @@ 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 +[#107792]: https://github.com/rust-lang/rust/issues/107792 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + 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 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + 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. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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 ------------------------ "##, @@ -9609,12 +12586,14 @@ The tracking issue for this feature is: [#107792] deny_since: None, }, Lint { - label: "raw_slice_split", - description: r##"# `raw_slice_split` + label: "read_buf_at", + description: r##"# `read_buf_at` -The tracking issue for this feature is: [#95595] -[#95595]: https://github.com/rust-lang/rust/issues/95595 + +The tracking issue for this feature is: [#140771] + +[#140771]: https://github.com/rust-lang/rust/issues/140771 ------------------------ "##, @@ -9623,10 +12602,14 @@ The tracking issue for this feature is: [#95595] deny_since: None, }, Lint { - label: "raw_vec_internals", - description: r##"# `raw_vec_internals` + label: "reborrow", + description: r##"# `reborrow` -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: [#145612] + +[#145612]: https://github.com/rust-lang/rust/issues/145612 ------------------------ "##, @@ -9635,12 +12618,14 @@ This feature has no tracking issue, and is therefore likely internal to the comp deny_since: None, }, Lint { - label: "read_buf", - description: r##"# `read_buf` + label: "reentrant_lock", + description: r##"# `reentrant_lock` -The tracking issue for this feature is: [#78485] -[#78485]: https://github.com/rust-lang/rust/issues/78485 + +The tracking issue for this feature is: [#121440] + +[#121440]: https://github.com/rust-lang/rust/issues/121440 ------------------------ "##, @@ -9649,12 +12634,14 @@ The tracking issue for this feature is: [#78485] deny_since: None, }, Lint { - label: "reentrant_lock", - description: r##"# `reentrant_lock` + label: "reentrant_lock_data_ptr", + description: r##"# `reentrant_lock_data_ptr` -The tracking issue for this feature is: [#121440] -[#121440]: https://github.com/rust-lang/rust/issues/121440 + +The tracking issue for this feature is: [#140368] + +[#140368]: https://github.com/rust-lang/rust/issues/140368 ------------------------ "##, @@ -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 {} +# impl Eq for T {} +# fn has_type(_: impl Eq) {} + +// `&` can match against a `ref` binding mode instead of a reference type: +let (x, &y) = &(0, 1); +has_type::<&u8>(x); +has_type::(y); + +// `&` can match against `&mut` references: +let &z = &mut 2; +has_type::(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 {} +# impl Eq for T {} +# fn has_type(_: impl Eq) {} + +// `&` can match against a `ref` binding mode instead of a reference type: +let (x, &y) = &(0, 1); +has_type::<&u8>(x); +has_type::(y); + +// `&` can match against `&mut` references: +let &z = &mut 2; +has_type::(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] -[#70142]: https://github.com/rust-lang/rust/issues/70142 +The tracking issue for this feature is: [#138099] + +[#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` -The tracking issue for this feature is: [#93743] +Target features on riscv. -[#93743]: https://github.com/rust-lang/rust/issues/93743 +The tracking issue for this feature is: [#150257] + +[#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. + +The tracking issue for this feature is: [#150258] -[#44839]: https://github.com/rust-lang/rust/issues/44839 +[#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` + +Allows `extern "rust-preserve-none"`. -The tracking issue for this feature is: [#69399] +The tracking issue for this feature is: [#151401] -[#69399]: https://github.com/rust-lang/rust/issues/69399 +[#151401]: https://github.com/rust-lang/rust/issues/151401 ------------------------ "##, @@ -9920,18 +13031,6 @@ error: size: Size { raw: 16 } error: aborting due to 2 previous errors ``` -"##, - default_severity: Severity::Allow, - warn_since: None, - 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, @@ -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`: -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`. +```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 + +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,11 +13139,93 @@ 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] + +[#150259]: https://github.com/rust-lang/rust/issues/150259 -[#44839]: https://github.com/rust-lang/rust/issues/44839 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10015,8 +13235,26 @@ The tracking issue for this feature is: [#44839] 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. +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10027,10 +13265,28 @@ This feature has no tracking issue, and is therefore likely internal to the comp 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10041,6 +13297,8 @@ The tracking issue for this feature is: [#59359] 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] +The tracking issue for this feature is: [#151989] -[#126624]: https://github.com/rust-lang/rust/issues/126624 +[#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,10 +13483,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10231,6 +13515,8 @@ The tracking issue for this feature is: [#93079] 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,10 +13563,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10287,6 +13595,8 @@ The tracking issue for this feature is: [#76393] 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] -[#62280]: https://github.com/rust-lang/rust/issues/62280 + +The tracking issue for this feature is: [#144419] + +[#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,10 +13875,44 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10557,10 +13923,28 @@ The tracking issue for this feature is: [#111191] 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -10571,6 +13955,8 @@ The tracking issue for this feature is: [#98288] 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,9 +14235,59 @@ 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 + +The tracking issue for this feature is: [#126769] + +[#126769]: https://github.com/rust-lang/rust/issues/126769 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "super_let", + description: r##"# `super_let` + +Allows `super let` statements. + +The tracking issue for this feature is: [#139076] + +[#139076]: https://github.com/rust-lang/rust/issues/139076 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "supertrait_item_shadowing", + description: r##"# `supertrait_item_shadowing` + +Allows subtrait items to shadow supertrait items. + +The tracking issue for this feature is: [#89151] + +[#89151]: https://github.com/rust-lang/rust/issues/89151 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "sync_nonpoison", + description: r##"# `sync_nonpoison` + + + +The tracking issue for this feature is: [#134645] + +[#134645]: https://github.com/rust-lang/rust/issues/134645 ------------------------ "##, @@ -10870,12 +14296,14 @@ The tracking issue for this feature is: [#126769] deny_since: None, }, Lint { - label: "sync_unsafe_cell", - description: r##"# `sync_unsafe_cell` + label: "sync_poison_mod", + description: r##"# `sync_poison_mod` -The tracking issue for this feature is: [#95439] -[#95439]: https://github.com/rust-lang/rust/issues/95439 + +The tracking issue for this feature is: [#134646] + +[#134646]: https://github.com/rust-lang/rust/issues/134646 ------------------------ "##, @@ -10884,12 +14312,14 @@ The tracking issue for this feature is: [#95439] deny_since: None, }, Lint { - label: "target_feature_11", - description: r##"# `target_feature_11` + label: "sync_unsafe_cell", + description: r##"# `sync_unsafe_cell` + + -The tracking issue for this feature is: [#69098] +The tracking issue for this feature is: [#95439] -[#69098]: https://github.com/rust-lang/rust/issues/69098 +[#95439]: https://github.com/rust-lang/rust/issues/95439 ------------------------ "##, @@ -10898,12 +14328,14 @@ The tracking issue for this feature is: [#69098] deny_since: None, }, Lint { - label: "tbm_target_feature", - description: r##"# `tbm_target_feature` + label: "target_feature_inline_always", + description: r##"# `target_feature_inline_always` -The tracking issue for this feature is: [#44839] +Allows the use of target_feature when a function is marked inline(always). -[#44839]: https://github.com/rust-lang/rust/issues/44839 +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] -[#96256]: https://github.com/rust-lang/rust/issues/96256 +The tracking issue for this feature is: [#88373] + +[#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. ------------------------ "##, @@ -11127,6 +14565,20 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured However, the optimizer can still modify a testcase in an undesirable manner even when using either of the above. +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11136,6 +14588,8 @@ even when using either of the above. 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,10 +14694,60 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11281,20 +14795,6 @@ note: trace_macro Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs ``` -"##, - default_severity: Severity::Allow, - warn_since: None, - 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, @@ -11336,39 +14836,6 @@ pub fn main() { println!("{:?}", b); } ``` -"##, - default_severity: Severity::Allow, - warn_since: None, - 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 Bar for T {} - -let bar: &dyn Bar = &123; -let foo: &dyn Foo = bar; -``` "##, default_severity: Severity::Allow, warn_since: None, @@ -11378,6 +14845,8 @@ let foo: &dyn Foo = bar; 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 @@ -11487,6 +14958,22 @@ example, it is unspecified whether `size_of::()` is equal to it is transparent). The Rust compiler is free to perform this optimization if possible, but is not required to, and different compiler versions may differ in their application of these optimizations. +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11496,10 +14983,26 @@ their application of these optimizations. 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11510,6 +15013,8 @@ The tracking issue for this feature is: [#48214] 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,10 +15073,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11604,6 +15133,22 @@ let result = try { }; assert!(result.is_err()); ``` +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11613,6 +15158,8 @@ assert!(result.is_err()); 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,37 +15238,193 @@ 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 ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "tuple_trait", - description: r##"# `tuple_trait` +The tracking issue for this feature is: [#91913] + +[#91913]: https://github.com/rust-lang/rust/issues/91913 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + 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. + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "type_alias_impl_trait", + description: r##"# `type_alias_impl_trait` + +The tracking issue for this feature is: [#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) { + // ... +} -This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use. +// ...is *not* the same as +pub fn take_impl(x: impl Trait) { + // ... +} +# fn main(){} +``` ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "type_alias_impl_trait", - description: r##"# `type_alias_impl_trait` +```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 +# } +``` -The tracking issue for this feature is: [#63063] +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 @@ -11768,6 +15481,22 @@ fn main () { }; } ``` +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11777,6 +15506,8 @@ fn main () { 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,10 +15646,44 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11889,6 +15694,8 @@ The tracking issue for this feature is: [#89517] 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,10 +15710,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -11917,6 +15742,8 @@ The tracking issue for this feature is: [#76915] 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() {`. + The tracking issue for this feature is: [#95174] [#95174]: https://github.com/rust-lang/rust/issues/95174 @@ -12039,193 +15886,13 @@ The tracking issue for this feature is: [#95174] label: "unsized_fn_params", description: r##"# `unsized_fn_params` -The tracking issue for this feature is: [#48055] - -[#48055]: https://github.com/rust-lang/rust/issues/48055 - ------------------------- -"##, - default_severity: Severity::Allow, - warn_since: None, - deny_since: None, - }, - Lint { - label: "unsized_locals", - description: r##"# `unsized_locals` - -The tracking issue for this feature is: [#48055] - -[#48055]: https://github.com/rust-lang/rust/issues/48055 - ------------------------- - -This implements [RFC1909]. When turned on, you can have unsized arguments and locals: - -[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md - -```rust -#![allow(incomplete_features)] -#![feature(unsized_locals, unsized_fn_params)] - -use std::any::Any; - -fn main() { - let x: Box = Box::new(42); - let x: dyn Any = *x; - // ^ unsized local variable - // ^^ unsized temporary - foo(x); -} - -fn foo(_: dyn Any) {} -// ^^^^^^ unsized argument -``` - -The RFC still forbids the following unsized expressions: - -```rust,compile_fail -#![feature(unsized_locals)] - -use std::any::Any; - -struct MyStruct { - content: T, -} - -struct MyTupleStruct(T); - -fn answer() -> Box { - 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 - -With this feature, you can have by-value `self` arguments without `Self: Sized` bounds. - -```rust -#![feature(unsized_fn_params)] - -trait Foo { - fn foo(self) {} -} - -impl Foo for T {} - -fn main() { - let slice: Box<[i32]> = Box::new([1, 2, 3]); - <[i32] as Foo>::foo(*slice); -} -``` - -And `Foo` will also be object-safe. - -```rust -#![feature(unsized_fn_params)] - -trait Foo { - fn foo(self) {} -} - -impl Foo for T {} - -fn main () { - let slice: Box = Box::new([1, 2, 3]); - // doesn't compile yet - ::foo(*slice); -} -``` - -One of the objectives of this feature is to allow `Box`. - -## Variable length arrays - -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(a: &mut [T]) { - let mut tmp = [T; dyn a.len()]; - // ... -} - -fn main() { - let mut a = [3, 1, 5, 6]; - mergesort(&mut a); - assert_eq!(a, [1, 3, 5, 6]); -} -``` - -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]`. - -## 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. - -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 - -```rust -#![feature(unsized_locals)] - -fn main() { - let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]); - let _x = {{{{{{{{{{*x}}}}}}}}}}; -} -``` - -and the code - -```rust -#![feature(unsized_locals)] - -fn main() { - for _ in 0..10 { - let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]); - let _x = *x; - } -} -``` +Allows unsized fn parameters. -will unnecessarily extend the stack frame. +The tracking issue for this feature is: [#48055] + +[#48055]: https://github.com/rust-lang/rust/issues/48055 + +------------------------ "##, default_severity: Severity::Allow, warn_since: None, @@ -12235,6 +15902,8 @@ will unnecessarily extend the stack frame. label: "unwrap_infallible", description: r##"# `unwrap_infallible` + + The tracking issue for this feature is: [#61695] [#61695]: https://github.com/rust-lang/rust/issues/61695 @@ -12261,6 +15930,8 @@ This feature is internal to the Rust compiler and is not intended for general us label: "used_with_arg", description: r##"# `used_with_arg` +Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute. + The tracking issue for this feature is: [#93798] [#93798]: https://github.com/rust-lang/rust/issues/93798 @@ -12275,6 +15946,8 @@ The tracking issue for this feature is: [#93798] label: "utf16_extra", description: r##"# `utf16_extra` + + The tracking issue for this feature is: [#94919] [#94919]: https://github.com/rust-lang/rust/issues/94919 @@ -12289,10 +15962,28 @@ The tracking issue for this feature is: [#94919] label: "variant_count", description: r##"# `variant_count` + + The tracking issue for this feature is: [#73662] [#73662]: https://github.com/rust-lang/rust/issues/73662 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_deque_extract_if", + description: r##"# `vec_deque_extract_if` + + + +The tracking issue for this feature is: [#147750] + +[#147750]: https://github.com/rust-lang/rust/issues/147750 + ------------------------ "##, default_severity: Severity::Allow, @@ -12303,6 +15994,8 @@ The tracking issue for this feature is: [#73662] label: "vec_deque_iter_as_slices", description: r##"# `vec_deque_iter_as_slices` + + The tracking issue for this feature is: [#123947] [#123947]: https://github.com/rust-lang/rust/issues/123947 @@ -12314,12 +16007,62 @@ The tracking issue for this feature is: [#123947] deny_since: None, }, Lint { - label: "vec_into_raw_parts", - description: r##"# `vec_into_raw_parts` + label: "vec_deque_truncate_front", + description: r##"# `vec_deque_truncate_front` + + + +The tracking issue for this feature is: [#140667] + +[#140667]: https://github.com/rust-lang/rust/issues/140667 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_fallible_shrink", + description: r##"# `vec_fallible_shrink` + + + +The tracking issue for this feature is: [#152350] + +[#152350]: https://github.com/rust-lang/rust/issues/152350 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_from_fn", + description: r##"# `vec_from_fn` + + + +The tracking issue for this feature is: [#149698] + +[#149698]: https://github.com/rust-lang/rust/issues/149698 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_into_chunks", + description: r##"# `vec_into_chunks` + + -The tracking issue for this feature is: [#65816] +The tracking issue for this feature is: [#142137] -[#65816]: https://github.com/rust-lang/rust/issues/65816 +[#142137]: https://github.com/rust-lang/rust/issues/142137 ------------------------ "##, @@ -12328,12 +16071,14 @@ The tracking issue for this feature is: [#65816] deny_since: None, }, Lint { - label: "vec_pop_if", - description: r##"# `vec_pop_if` + label: "vec_peek_mut", + description: r##"# `vec_peek_mut` -The tracking issue for this feature is: [#122741] -[#122741]: https://github.com/rust-lang/rust/issues/122741 + +The tracking issue for this feature is: [#122742] + +[#122742]: https://github.com/rust-lang/rust/issues/122742 ------------------------ "##, @@ -12345,10 +16090,28 @@ The tracking issue for this feature is: [#122741] label: "vec_push_within_capacity", description: r##"# `vec_push_within_capacity` + + The tracking issue for this feature is: [#100486] [#100486]: https://github.com/rust-lang/rust/issues/100486 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_recycle", + description: r##"# `vec_recycle` + + + +The tracking issue for this feature is: [#148227] + +[#148227]: https://github.com/rust-lang/rust/issues/148227 + ------------------------ "##, default_severity: Severity::Allow, @@ -12359,10 +16122,60 @@ The tracking issue for this feature is: [#100486] label: "vec_split_at_spare", description: r##"# `vec_split_at_spare` + + The tracking issue for this feature is: [#81944] [#81944]: https://github.com/rust-lang/rust/issues/81944 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "vec_try_remove", + description: r##"# `vec_try_remove` + + + +The tracking issue for this feature is: [#146954] + +[#146954]: https://github.com/rust-lang/rust/issues/146954 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "waker_fn", + description: r##"# `waker_fn` + + + +The tracking issue for this feature is: [#149580] + +[#149580]: https://github.com/rust-lang/rust/issues/149580 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "waker_from_fn_ptr", + description: r##"# `waker_from_fn_ptr` + + + +The tracking issue for this feature is: [#148457] + +[#148457]: https://github.com/rust-lang/rust/issues/148457 + ------------------------ "##, default_severity: Severity::Allow, @@ -12373,6 +16186,8 @@ The tracking issue for this feature is: [#81944] label: "wasi_ext", description: r##"# `wasi_ext` + + The tracking issue for this feature is: [#71213] [#71213]: https://github.com/rust-lang/rust/issues/71213 @@ -12387,9 +16202,43 @@ The tracking issue for this feature is: [#71213] label: "wasm_target_feature", description: r##"# `wasm_target_feature` -The tracking issue for this feature is: [#44839] +Target features on wasm. + +The tracking issue for this feature is: [#150260] + +[#150260]: https://github.com/rust-lang/rust/issues/150260 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "where_clause_attrs", + description: r##"# `where_clause_attrs` + +Allows use of attributes in `where` clauses. + +The tracking issue for this feature is: [#115590] + +[#115590]: https://github.com/rust-lang/rust/issues/115590 + +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + deny_since: None, + }, + Lint { + label: "widening_mul", + description: r##"# `widening_mul` + + + +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,10 +16278,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -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,10 +16366,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -12507,6 +16398,8 @@ The tracking issue for this feature is: [#82227] 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,10 +16430,28 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -12551,6 +16464,22 @@ The tracking issue for this feature is: [#127544] 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: "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, @@ -12561,6 +16490,8 @@ This feature is internal to the Rust compiler and is not intended for general us 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,10 +16536,26 @@ 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -12615,10 +16566,28 @@ The tracking issue for this feature is: [#70436] 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 +------------------------ +"##, + default_severity: Severity::Allow, + warn_since: None, + 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, @@ -12629,6 +16598,8 @@ The tracking issue for this feature is: [#126622] 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. ------------------------ @@ -12679,6 +16652,22 @@ fn bar() -> Option { } assert_eq!(bar(), None); ``` +"##, + default_severity: Severity::Allow, + 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, @@ -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::() * 8` when + description: r##"Checks for usage of `std::mem::size_of::() * 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/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs index 2f696d07e21be..9018552afb4d7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/import_assets.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs index 41ce1e59603d7..9318c3e132725 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/insert_use.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs index 3301719f5ce29..76645464ddf5d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs +++ b/src/tools/rust-analyzer/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 { - 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/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs index 9bfbeeebf7800..be4fe763a0549 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/inactive_code.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs b/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs index 6f4ea70e0adc4..fb885c2ad11f5 100644 --- a/src/tools/rust-analyzer/crates/ide/src/expand_macro.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index ce9ec7431a975..dcfe4dd41e761 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html @@ -166,12 +166,12 @@ /// /// ``` /// loop {} -#[cfg_attr(not(feature = "false"), doc = "loop {}")] +#[cfg_attr(not(feature = "false"), doc = "loop {}")] #[doc = "loop {}"] /// ``` /// -#[cfg_attr(feature = "alloc", doc = "```rust")] -#[cfg_attr(not(feature = "alloc"), doc = "```ignore")] +#[cfg_attr(feature = "alloc", doc = "```rust")] +#[cfg_attr(not(feature = "alloc"), doc = "```ignore")] /// let _ = example(&alloc::vec![1, 2, 3]); /// ``` pub fn mix_and_match() {} diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs index c0cf43a87bf77..2eeaa25257dba 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index a2295e4495503..9cd48f2aa4f3e 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 01fc172ed9537..71978390df6a8 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast index 77b4d06321d5a..cf45dcf522ad0 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast index b657e9834156a..2334b730e4cc8 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast index b5bc3d84df096..acacee2348263 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0033_match_arms_outer_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rast new file mode 100644 index 0000000000000..de5fc7d5bdc0b --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rs new file mode 100644 index 0000000000000..9a981bf939cc2 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/key_ident_cfg_predicate.rs @@ -0,0 +1 @@ +#![cfg(key = value)] diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast index b5c16e0798cc8..9e456c98554de 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/meta_recovery.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast index ae1074c3680ca..672f2c2f7f99e 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/arg_with_attr.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rast index 6eb8af3311955..2812bbf71bcc1 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/array_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast index 9cb3c8a5c3b44..7c6dbf65cfdca 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/assoc_item_list_inner_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast index 81b7f2b3cbbea..248e6d1360db3 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/attr_on_expr_stmt.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_attr.rast new file mode 100644 index 0000000000000..9af94f447db83 --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_attr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_attr.rs new file mode 100644 index 0000000000000..5fe2776144e3f --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rast new file mode 100644 index 0000000000000..89d06d134fe28 --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rs new file mode 100644 index 0000000000000..7d830c1288152 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_composite_pred.rs @@ -0,0 +1 @@ +#![cfg(any(a, all(b = "c", d)))] diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rast new file mode 100644 index 0000000000000..e48d39bf55db9 --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rs new file mode 100644 index 0000000000000..dc194ed86be2a --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_key_value_pred.rs @@ -0,0 +1 @@ +#![cfg(key = "value")] diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_meta.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_meta.rast new file mode 100644 index 0000000000000..f024cfd1aae41 --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_meta.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_meta.rs new file mode 100644 index 0000000000000..ef0030e75fde8 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_meta.rs @@ -0,0 +1,2 @@ +#![cfg(foo)] +#![cfg(foo = "bar",)] diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rast new file mode 100644 index 0000000000000..e33595a93dcdc --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rs new file mode 100644 index 0000000000000..473582164a226 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/cfg_true_false_pred.rs @@ -0,0 +1,2 @@ +#![cfg(true)] +#![cfg(false)] diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast index 28a216e873097..5567a53c56a21 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_param_attribute.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast index 6fd9f424676b6..edb04387336a9 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_inner_attribute.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast index 0f7580c1a3392..321db782d133f 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/match_arms_outer_attributes.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rast index b1ac60b530ef1..6360552a6f060 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/metas.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast index c63ea020a3f7a..7495ba7b31a28 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_outer_arg.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast index 639ee0eb77702..cfa2694fd1def 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_field_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast index a1df70841e854..717dee8c9f39f 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_literal_field_with_attr.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rast index f3d2fde466983..7fba529be9e97 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast index f69ae1d6445f9..af5b82b889d3e 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/record_pat_field_list.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast index db583f7d5266e..3a163e5b8ee79 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/self_param_outer_attr.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast index 39857b23c6e39..76954927d566f 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast index 1699602f4fbaf..1f7100c46d4e9 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/tuple_field_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0006_inner_attributes.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0006_inner_attributes.rast index cb63ba80e77d1..ddab028c06864 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0006_inner_attributes.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0008_mod_item.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0008_mod_item.rast index adee67181b1a3..cb6da8717ddd9 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0008_mod_item.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0011_outer_attribute.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0011_outer_attribute.rast index dbb9bc54da8d7..47a5cfce081a7 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0011_outer_attribute.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast index 7c914e2542eb7..c5d054702fa44 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0017_attr_trailing_comma.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0035_weird_exprs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0035_weird_exprs.rast index 318d492ab4a57..15ce6c70bea72 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0035_weird_exprs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0044_let_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0044_let_attrs.rast index f3c20337e43fb..fcdc1a9895d8b 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0044_let_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0045_block_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0045_block_attrs.rast index c22d99f1ae107..f26bb85df2927 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0045_block_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast index 4eb51cfdf09e2..3d33eb4ff73ce 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0046_extern_inner_attributes.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast index eafee90db427d..24d4392282a06 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast index b94d43beb3c28..c300b7af50589 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0062_macro_2.0.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0062_macro_2.0.rast index 1415a866b6956..b92d78e5bd60d 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0062_macro_2.0.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0063_variadic_fun.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0063_variadic_fun.rast index e36399123bcc1..f1c6d2efeb9c8 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0063_variadic_fun.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast index 3d00b27ab8d3d..5229b97eb2af3 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0070_expr_attr_placement.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast index 1cafc775cdf7a..c0685448f2565 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 86516b6079c72..c1806c82c724c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index 01196b80cdb2d..5bdc9d8ca3159 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml index 8909fb423c4de..e65836ed8dcb4 100644 --- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 3113fc74308b2..324b2bbd58e1c 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/syntax/src/ast.rs b/src/tools/rust-analyzer/crates/syntax/src/ast.rs index 5d67fd4491755..dc592a43727b4 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 7334de0fd96fd..cd7f6a018ab2b 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -377,6 +377,68 @@ impl CastExpr { #[inline] pub fn as_token(&self) -> Option { support::token(&self.syntax, T![as]) } } +pub struct CfgAtom { + pub(crate) syntax: SyntaxNode, +} +impl CfgAtom { + #[inline] + pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } + #[inline] + pub fn false_token(&self) -> Option { support::token(&self.syntax, T![false]) } + #[inline] + pub fn ident_token(&self) -> Option { support::token(&self.syntax, T![ident]) } + #[inline] + pub fn string_token(&self) -> Option { support::token(&self.syntax, T![string]) } + #[inline] + pub fn true_token(&self) -> Option { support::token(&self.syntax, T![true]) } +} +pub struct CfgAttrMeta { + pub(crate) syntax: SyntaxNode, +} +impl CfgAttrMeta { + #[inline] + pub fn cfg_predicate(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn metas(&self) -> AstChildren { support::children(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } + #[inline] + pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } + #[inline] + pub fn cfg_attr_token(&self) -> Option { + support::token(&self.syntax, T![cfg_attr]) + } +} +pub struct CfgComposite { + pub(crate) syntax: SyntaxNode, +} +impl CfgComposite { + #[inline] + pub fn cfg_predicates(&self) -> AstChildren { support::children(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } + #[inline] + pub fn keyword(&self) -> Option { support::token(&self.syntax, T![ident]) } +} +pub struct CfgMeta { + pub(crate) syntax: SyntaxNode, +} +impl CfgMeta { + #[inline] + pub fn cfg_predicate(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } + #[inline] + pub fn comma_token(&self) -> Option { support::token(&self.syntax, T![,]) } + #[inline] + pub fn cfg_token(&self) -> Option { 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 { support::token(&self.syntax, T!['}']) } } +pub struct KeyValueMeta { + pub(crate) syntax: SyntaxNode, +} +impl KeyValueMeta { + #[inline] + pub fn expr(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn path(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn eq_token(&self) -> Option { 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 { support::token(&self.syntax, T![if]) } } -pub struct Meta { - pub(crate) syntax: SyntaxNode, -} -impl Meta { - #[inline] - pub fn expr(&self) -> Option { support::child(&self.syntax) } - #[inline] - pub fn path(&self) -> Option { support::child(&self.syntax) } - #[inline] - pub fn token_tree(&self) -> Option { support::child(&self.syntax) } - #[inline] - pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } - #[inline] - pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } - #[inline] - pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } - #[inline] - pub fn unsafe_token(&self) -> Option { 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 { support::child(&self.syntax) } } +pub struct PathMeta { + pub(crate) syntax: SyntaxNode, +} +impl PathMeta { + #[inline] + pub fn path(&self) -> Option { 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 { support::token(&self.syntax, T!['}']) } } +pub struct TokenTreeMeta { + pub(crate) syntax: SyntaxNode, +} +impl TokenTreeMeta { + #[inline] + pub fn path(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn token_tree(&self) -> Option { support::child(&self.syntax) } +} pub struct Trait { pub(crate) syntax: SyntaxNode, } @@ -1834,6 +1904,19 @@ impl Union { #[inline] pub fn union_token(&self) -> Option { support::token(&self.syntax, T![union]) } } +pub struct UnsafeMeta { + pub(crate) syntax: SyntaxNode, +} +impl UnsafeMeta { + #[inline] + pub fn meta(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn l_paren_token(&self) -> Option { support::token(&self.syntax, T!['(']) } + #[inline] + pub fn r_paren_token(&self) -> Option { support::token(&self.syntax, T![')']) } + #[inline] + pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } +} pub struct Use { pub(crate) syntax: SyntaxNode, } @@ -2024,6 +2107,12 @@ pub enum AssocItem { 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), @@ -2118,6 +2207,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), @@ -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 { + 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(&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 { + 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(&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 { + 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(&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 { + 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(&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 { + 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(&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 { - 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(&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 { + 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(&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 { + 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(&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 { + 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(&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 for CfgPredicate { + #[inline] + fn from(node: CfgAtom) -> CfgPredicate { CfgPredicate::CfgAtom(node) } +} +impl From 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 { + 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 for Expr { #[inline] fn from(node: ArrayExpr) -> Expr { Expr::ArrayExpr(node) } @@ -7970,6 +8321,63 @@ impl AstNode for Item { } } } +impl From for Meta { + #[inline] + fn from(node: CfgAttrMeta) -> Meta { Meta::CfgAttrMeta(node) } +} +impl From for Meta { + #[inline] + fn from(node: CfgMeta) -> Meta { Meta::CfgMeta(node) } +} +impl From for Meta { + #[inline] + fn from(node: KeyValueMeta) -> Meta { Meta::KeyValueMeta(node) } +} +impl From for Meta { + #[inline] + fn from(node: PathMeta) -> Meta { Meta::PathMeta(node) } +} +impl From for Meta { + #[inline] + fn from(node: TokenTreeMeta) -> Meta { Meta::TokenTreeMeta(node) } +} +impl From 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 { + 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 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/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 00971569a2ef3..ac02cc9e43fdf 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/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, +) -> 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>, diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 3fc3b39feef08..03118d01dc90a 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/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 { - 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 { - 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 { - 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 { + 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 { + self.syntax().ancestors().find_map(ast::Attr::cast) + } +} + +impl ast::Attr { + pub fn as_simple_atom(&self) -> Option { + 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 { + self.meta().and_then(|meta| meta.as_simple_path()) + } + + pub fn simple_name(&self) -> Option { + self.meta().and_then(|meta| meta.simple_name()) + } + pub fn path(&self) -> Option { - self.meta()?.path() + self.meta().and_then(|meta| meta.path()) } - pub fn expr(&self) -> Option { - self.meta()?.expr() + pub fn kind(&self) -> AttrKind { + match self.excl_token() { + Some(_) => AttrKind::Inner, + None => AttrKind::Outer, + } } - pub fn token_tree(&self) -> Option { - 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 { - self.syntax().parent().and_then(ast::Attr::cast) - } -} - impl ast::GenericArgList { pub fn lifetime_args(&self) -> impl Iterator { 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 { + 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/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index e91e444a32336..c66f096e8342c 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/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, + ) -> 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/src/tools/rust-analyzer/crates/syntax/src/ast/traits.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/traits.rs index 2f4109a2c9760..6fe5abb84e22b 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/traits.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/traits.rs @@ -73,9 +73,6 @@ pub trait HasAttrs: AstNode { fn attrs(&self) -> AstChildren { 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/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast index 50057a02d8091..5fdde93c603d0 100644 --- a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rast @@ -29,7 +29,7 @@ SOURCE_FILE@0..350 POUND@39..40 "#" BANG@40..41 "!" L_BRACK@41..42 "[" - META@42..82 + TOKEN_TREE_META@42..82 PATH@42..45 PATH_SEGMENT@42..45 NAME_REF@42..45 @@ -60,7 +60,7 @@ SOURCE_FILE@0..350 POUND@152..153 "#" BANG@153..154 "!" L_BRACK@154..155 "[" - META@155..170 + TOKEN_TREE_META@155..170 PATH@155..158 PATH_SEGMENT@155..158 NAME_REF@155..158 @@ -75,7 +75,7 @@ SOURCE_FILE@0..350 POUND@180..181 "#" BANG@181..182 "!" L_BRACK@182..183 "[" - META@183..211 + TOKEN_TREE_META@183..211 PATH@183..186 PATH_SEGMENT@183..186 NAME_REF@183..186 @@ -104,7 +104,7 @@ SOURCE_FILE@0..350 POUND@283..284 "#" BANG@284..285 "!" L_BRACK@285..286 "[" - META@286..301 + TOKEN_TREE_META@286..301 PATH@286..289 PATH_SEGMENT@286..289 NAME_REF@286..289 diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index 4e980bb3d986d..257429c42661f 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -780,7 +780,7 @@ impl Field { } fn token_kind(&self) -> Option { 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, 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/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs index 564d9cc24efe8..a0abdf09d3a58 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs +++ b/src/tools/rust-analyzer/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, token: String }, Node { name: String, ty: String, cardinality: Cardinality }, } diff --git a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs b/src/tools/rust-analyzer/xtask/src/codegen/lints.rs index 3b4c2e8da3c37..788ae8d6c1dd9 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/lints.rs +++ b/src/tools/rust-analyzer/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(); diff --git a/tests/ui/associated-type-bounds/return-type-notation/return-type-notation-where-clause-doesnt-apply.rs b/tests/ui/associated-type-bounds/return-type-notation/return-type-notation-where-clause-doesnt-apply.rs new file mode 100644 index 0000000000000..a12e8235662ba --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/return-type-notation-where-clause-doesnt-apply.rs @@ -0,0 +1,18 @@ +// Regression test for https://github.com/rust-lang/rust/issues/152887 +//@ edition: 2024 + +#![feature(return_type_notation)] + +pub trait Trait { + async fn func(); +} + +impl> Trait for T {} +//~^ ERROR not all trait items implemented, missing: `func` + +fn check(_: impl Trait) {} + +fn main() { + check(()); + //~^ ERROR overflow evaluating the requirement +} diff --git a/tests/ui/associated-type-bounds/return-type-notation/return-type-notation-where-clause-doesnt-apply.stderr b/tests/ui/associated-type-bounds/return-type-notation/return-type-notation-where-clause-doesnt-apply.stderr new file mode 100644 index 0000000000000..84697aecfc638 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/return-type-notation-where-clause-doesnt-apply.stderr @@ -0,0 +1,34 @@ +error[E0046]: not all trait items implemented, missing: `func` + --> $DIR/return-type-notation-where-clause-doesnt-apply.rs:10:1 + | +LL | async fn func(); + | ---------------- `func` from trait +... +LL | impl> Trait for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `func` in implementation + +error[E0275]: overflow evaluating the requirement `impl Future { <() as Trait>::func(..) } == _` + --> $DIR/return-type-notation-where-clause-doesnt-apply.rs:16:5 + | +LL | check(()); + | ^^^^^^^^^ + | +note: required for `()` to implement `Trait` + --> $DIR/return-type-notation-where-clause-doesnt-apply.rs:10:32 + | +LL | impl> Trait for T {} + | ---- ^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 1 redundant requirement hidden + = note: required for `()` to implement `Trait` +note: required by a bound in `check` + --> $DIR/return-type-notation-where-clause-doesnt-apply.rs:13:18 + | +LL | fn check(_: impl Trait) {} + | ^^^^^ required by this bound in `check` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0046, E0275. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/attributes/auxiliary/unstable_removed_feature.rs b/tests/ui/attributes/auxiliary/unstable_removed_feature.rs new file mode 100644 index 0000000000000..3944ef35f8fe7 --- /dev/null +++ b/tests/ui/attributes/auxiliary/unstable_removed_feature.rs @@ -0,0 +1,9 @@ +#![feature(staged_api)] +#![stable(feature = "unstable_removed_test", since = "1.0.0")] + +#![unstable_removed( + feature="old_feature", + reason="deprecated", + link="https://github.com/rust-lang/rust/issues/141617", + since="1.92.0" +)] diff --git a/tests/ui/attributes/malformed-unstable-removed.rs b/tests/ui/attributes/malformed-unstable-removed.rs new file mode 100644 index 0000000000000..d2ba10154bc96 --- /dev/null +++ b/tests/ui/attributes/malformed-unstable-removed.rs @@ -0,0 +1,16 @@ +#![feature(staged_api)] + +#![unstable_removed(feature = "old_feature")] +//~^ ERROR: malformed `unstable_removed` attribute + +#![unstable_removed(invalid = "old_feature")] +//~^ ERROR: malformed `unstable_removed` attribute + +#![unstable_removed("invalid literal")] +//~^ ERROR: malformed `unstable_removed` attribute + +#![unstable_removed = "invalid literal"] +//~^ ERROR: malformed `unstable_removed` attribute + +#![stable(feature="main", since="1.0.0")] +fn main() {} diff --git a/tests/ui/attributes/malformed-unstable-removed.stderr b/tests/ui/attributes/malformed-unstable-removed.stderr new file mode 100644 index 0000000000000..02cf3e543c887 --- /dev/null +++ b/tests/ui/attributes/malformed-unstable-removed.stderr @@ -0,0 +1,40 @@ +error[E0539]: malformed `unstable_removed` attribute input + --> $DIR/malformed-unstable-removed.rs:3:1 + | +LL | #![unstable_removed(feature = "old_feature")] + | ^^^^^^^^^^^^^^^^^^^-------------------------^ + | | | + | | missing argument `reason = "..."` + | help: must be of the form: `#![unstable_removed(feature = "name", reason = "...", link = "...", since = "version")]` + +error[E0539]: malformed `unstable_removed` attribute input + --> $DIR/malformed-unstable-removed.rs:6:1 + | +LL | #![unstable_removed(invalid = "old_feature")] + | ^^^^^^^^^^^^^^^^^^^^-----------------------^^ + | | | + | | valid arguments are `feature`, `reason`, `link` or `since` + | help: must be of the form: `#![unstable_removed(feature = "name", reason = "...", link = "...", since = "version")]` + +error[E0565]: malformed `unstable_removed` attribute input + --> $DIR/malformed-unstable-removed.rs:9:1 + | +LL | #![unstable_removed("invalid literal")] + | ^^^^^^^^^^^^^^^^^^^^-----------------^^ + | | | + | | didn't expect a literal here + | help: must be of the form: `#![unstable_removed(feature = "name", reason = "...", link = "...", since = "version")]` + +error[E0539]: malformed `unstable_removed` attribute input + --> $DIR/malformed-unstable-removed.rs:12:1 + | +LL | #![unstable_removed = "invalid literal"] + | ^^^^^^^^^^^^^^^^^^^^-------------------^ + | | | + | | expected this to be a list + | help: must be of the form: `#![unstable_removed(feature = "name", reason = "...", link = "...", since = "version")]` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0539, E0565. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/unstable_removed.rs b/tests/ui/attributes/unstable_removed.rs new file mode 100644 index 0000000000000..7a9330a1a93eb --- /dev/null +++ b/tests/ui/attributes/unstable_removed.rs @@ -0,0 +1,19 @@ +//@ aux-build:unstable_removed_feature.rs + +#![feature(old_feature)] +//~^ ERROR: feature `old_feature` has been removed + +#![feature(concat_idents)] +//~^ ERROR: feature `concat_idents` has been removed + +#![unstable_removed( +//~^ ERROR: stability attributes may not be used outside of the standard library + feature = "old_feature", + reason = "a good one", + link = "https://github.com/rust-lang/rust/issues/141617", + since="1.92.0" +)] + +extern crate unstable_removed_feature; + +fn main() {} diff --git a/tests/ui/attributes/unstable_removed.stderr b/tests/ui/attributes/unstable_removed.stderr new file mode 100644 index 0000000000000..e9c81b833f409 --- /dev/null +++ b/tests/ui/attributes/unstable_removed.stderr @@ -0,0 +1,34 @@ +error[E0734]: stability attributes may not be used outside of the standard library + --> $DIR/unstable_removed.rs:9:1 + | +LL | / #![unstable_removed( +LL | | +LL | | feature = "old_feature", +LL | | reason = "a good one", +LL | | link = "https://github.com/rust-lang/rust/issues/141617", +LL | | since="1.92.0" +LL | | )] + | |__^ + +error[E0557]: feature `old_feature` has been removed + --> $DIR/unstable_removed.rs:3:12 + | +LL | #![feature(old_feature)] + | ^^^^^^^^^^^ feature has been removed + | + = note: removed in 1.92.0; see for more information + = note: deprecated + +error[E0557]: feature `concat_idents` has been removed + --> $DIR/unstable_removed.rs:6:12 + | +LL | #![feature(concat_idents)] + | ^^^^^^^^^^^^^ feature has been removed + | + = note: removed in 1.90.0; see for more information + = note: Replaced by the macro_metavar_expr_concat feature + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0557, E0734. +For more information about an error, try `rustc --explain E0557`. diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr index 9f816ee75c12f..6cf844f29b06f 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr @@ -43,6 +43,15 @@ help: consider introducing lifetime `'a` here LL | impl<'a> Trait for Z { | ++++ +error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41 + | +LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); + | -------------------------------------- associated function or constant `new` not found for this struct +... +LL | pub const NEW: Self = InvariantRef::new(&()); + | ^^^ associated function or constant not found in `InvariantRef<'_, _>` + error[E0277]: the trait bound `u8: Trait` is not satisfied --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:12 | @@ -110,15 +119,6 @@ LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW found struct `InvariantRef<'_, ()>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope - --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41 - | -LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); - | -------------------------------------- associated function or constant `new` not found for this struct -... -LL | pub const NEW: Self = InvariantRef::new(&()); - | ^^^ associated function or constant not found in `InvariantRef<'_, _>` - error: aborting due to 10 previous errors Some errors have detailed explanations: E0261, E0277, E0308, E0599. diff --git a/tests/ui/delegation/generics/const-type-ice-153499.stderr b/tests/ui/delegation/generics/const-type-ice-153499.stderr index 851c2f14efbfe..02fd7197dcdc3 100644 --- a/tests/ui/delegation/generics/const-type-ice-153499.stderr +++ b/tests/ui/delegation/generics/const-type-ice-153499.stderr @@ -10,18 +10,18 @@ LL + use std::ffi::CStr; | error: using function pointers as const generic parameters is forbidden - --> $DIR/const-type-ice-153499.rs:10:14 + --> $DIR/const-type-ice-153499.rs:4:29 | -LL | reuse Trait::foo; - | ^^^ +LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { + | ^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` error: using function pointers as const generic parameters is forbidden - --> $DIR/const-type-ice-153499.rs:4:29 + --> $DIR/const-type-ice-153499.rs:10:14 | -LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { - | ^^^^^^^^^^^^^^^^^^ +LL | reuse Trait::foo; + | ^^^ | = note: the only supported types are integers, `bool`, and `char` diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.stderr b/tests/ui/delegation/generics/generics-gen-args-errors.stderr index 0489e40eefeda..cf06d397244a2 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.stderr +++ b/tests/ui/delegation/generics/generics-gen-args-errors.stderr @@ -621,23 +621,6 @@ note: method defined here, with 2 generic parameters: `U`, `M` LL | fn foo<'d: 'd, U, const M: bool>(self) {} | ^^^ - ------------- -error[E0747]: unresolved item provided when a constant was expected - --> $DIR/generics-gen-args-errors.rs:34:27 - | -LL | reuse foo:: as xd; - | ^ - | -help: if this generic argument was intended as a const parameter, surround it with braces - | -LL | reuse foo:: as xd; - | + + - -error[E0747]: constant provided when a type was expected - --> $DIR/generics-gen-args-errors.rs:75:17 - | -LL | reuse foo::<{}, {}, {}> as bar8; - | ^^ - error[E0107]: function takes 3 generic arguments but 6 generic arguments were supplied --> $DIR/generics-gen-args-errors.rs:11:9 | @@ -697,6 +680,23 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | bar::(); | + + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/generics-gen-args-errors.rs:34:27 + | +LL | reuse foo:: as xd; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | reuse foo:: as xd; + | + + + +error[E0747]: constant provided when a type was expected + --> $DIR/generics-gen-args-errors.rs:75:17 + | +LL | reuse foo::<{}, {}, {}> as bar8; + | ^^ + error: aborting due to 58 previous errors Some errors have detailed explanations: E0106, E0107, E0121, E0261, E0401, E0423, E0425, E0747. diff --git a/tests/ui/delegation/generics/mapping/free-to-free-pass.rs b/tests/ui/delegation/generics/mapping/free-to-free-pass.rs index 2b877cc668ff3..bfdcb416d6445 100644 --- a/tests/ui/delegation/generics/mapping/free-to-free-pass.rs +++ b/tests/ui/delegation/generics/mapping/free-to-free-pass.rs @@ -9,14 +9,32 @@ //! delegation parent if applicable. At some tests predicates are //! added. At some tests user-specified args are specified in reuse statement. -// Testing lifetimes + types + consts, reusing without -// user args, checking predicates inheritance +// Testing lifetimes + types + consts, reusing with(out) +// user args, checking predicates inheritance, testing with impl Traits mod test_1 { - fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>() {} + trait Bound1 {} + trait Bound2 {} + trait Bound3 {} + + struct X {} + + impl Bound1 for X {} + impl Bound2 for X {} + impl Bound3 for X {} + + fn foo<'a: 'a, 'b: 'b, T: Clone, U: Clone, const N: usize>( + _x: impl Bound1 + Bound2 + Bound3, + _f: impl FnOnce(T) -> U, + ) { + } pub fn check() { reuse foo as bar; - bar::(); + bar::(X {}, |x| x); + + reuse foo::<'static, 'static, usize, String, 132> as bar1; + + bar1(X {}, |x| x.to_string()); } } diff --git a/tests/ui/delegation/generics/mapping/free-to-trait-pass.rs b/tests/ui/delegation/generics/mapping/free-to-trait-pass.rs index 0aa3798cdbef8..cd779a9887a27 100644 --- a/tests/ui/delegation/generics/mapping/free-to-trait-pass.rs +++ b/tests/ui/delegation/generics/mapping/free-to-trait-pass.rs @@ -10,10 +10,10 @@ //! added. At some tests user-specified args are specified in reuse statement. // Testing lifetimes + types + consts in both parent and child, reusing in -// a function without generic params +// a function without generic params, with impl traits mod test_1 { trait Trait<'b, 'c, 'a, T, const N: usize>: Sized { - fn foo<'d: 'd, U, const M: bool>(self) {} + fn foo<'d: 'd, U, const M: bool>(self, _f: impl FnOnce() -> ()) {} } impl Trait<'static, 'static, 'static, i32, 1> for u8 {} @@ -21,12 +21,12 @@ mod test_1 { pub fn check() { fn no_ctx() { reuse Trait::foo as bar; - bar::<'static, 'static, 'static, 'static, u8, i32, 1, String, true>(123); + bar::<'static, 'static, 'static, 'static, u8, i32, 1, String, true>(123, || ()); } fn with_ctx<'a, 'b, 'c, A, B, C, const N: usize, const M: bool>() { reuse Trait::foo as bar; - bar::<'static, 'static, 'static, 'a, u8, i32, 1, A, M>(123); + bar::<'static, 'static, 'static, 'a, u8, i32, 1, A, M>(123, || ()); } no_ctx(); diff --git a/tests/ui/delegation/generics/mapping/impl-trait-to-free-pass.rs b/tests/ui/delegation/generics/mapping/impl-trait-to-free-pass.rs index 53947c41cf570..7abd9e19dde63 100644 --- a/tests/ui/delegation/generics/mapping/impl-trait-to-free-pass.rs +++ b/tests/ui/delegation/generics/mapping/impl-trait-to-free-pass.rs @@ -10,19 +10,19 @@ //! delegation parent if applicable. At some tests predicates are //! added. At some tests user-specified args are specified in reuse statement. -// Testing lifetimes + types/consts in child reuses, +// Testing lifetimes + types/consts in child reuses, with impl traits, // with (un)specified user args with additional generic params in delegation parent mod test_1 { mod to_reuse { pub fn foo<'a: 'a, 'b: 'b, A, B, const N: usize>() {} - pub fn bar<'a: 'a, 'b: 'b, A, B, const N: usize>(_x: &super::XX) {} + pub fn bar<'a: 'a, 'b: 'b, A, B, const N: usize>(_x: &super::XX, _f: impl FnOnce(A) -> B) {} } trait Trait<'a, 'b, 'c, A, B, const N: usize>: Sized { fn foo<'x: 'x, 'y: 'y, AA, BB, const NN: usize>() {} - fn bar<'x: 'x, 'y: 'y, AA, BB, const NN: usize>(&self) {} + fn bar<'x: 'x, 'y: 'y, AA, BB, const NN: usize>(&self, _f: impl FnOnce(AA) -> BB) {} fn oof() {} - fn rab(&self) {} + fn rab(&self, _f: impl FnOnce(A) -> B) {} } #[allow(dead_code)] // Fields are used instead of phantom data for generics use @@ -44,9 +44,9 @@ mod test_1 { > ::foo::<'static, 'static, i8, i16, 123>(); > - ::bar::<'static, 'static, String, i16, 123>(&x); + ::bar::<'static, 'static, String, i16, 123>(&x, |_| 123); >::oof(); - >::rab(&x); + >::rab(&x, |_| 123.to_string()); } } diff --git a/tests/ui/delegation/generics/mapping/impl-trait-to-trait-pass.rs b/tests/ui/delegation/generics/mapping/impl-trait-to-trait-pass.rs index 2f556f81c1ef0..3dcb359ab2e52 100644 --- a/tests/ui/delegation/generics/mapping/impl-trait-to-trait-pass.rs +++ b/tests/ui/delegation/generics/mapping/impl-trait-to-trait-pass.rs @@ -12,12 +12,12 @@ // Testing types in parent, types in child reuse, // testing predicates inheritance, -// with additional generic params in delegation parent +// with additional generic params in delegation parent, with impl traits mod test_1 { trait Trait0 {} trait Trait1 { - fn foo(&self) + fn foo(&self, _f: impl FnOnce(T, U) -> (U, T)) where T: Trait0, U: Trait0, @@ -39,7 +39,7 @@ mod test_1 { pub fn check() { let s = S(F, &123, &123, &123); - as Trait1>::foo::(&s); + as Trait1>::foo::(&s, |x, y| (y, x)); } } diff --git a/tests/ui/delegation/generics/mapping/inherent-impl-to-free-pass.rs b/tests/ui/delegation/generics/mapping/inherent-impl-to-free-pass.rs index 7d99bc753cc2e..1e08e155c5de8 100644 --- a/tests/ui/delegation/generics/mapping/inherent-impl-to-free-pass.rs +++ b/tests/ui/delegation/generics/mapping/inherent-impl-to-free-pass.rs @@ -11,10 +11,10 @@ // Testing lifetimes + types/consts OR types/consts OR none in delegation parent, // lifetimes + types/consts in child reuse, -// with(out) user-specified args +// with(out) user-specified args, with impl traits mod test_1 { mod to_reuse { - pub fn foo<'a: 'a, 'b: 'b, A, B, const N: usize>() {} + pub fn foo<'a: 'a, 'b: 'b, A, B, const N: usize>(_f: impl FnOnce(A, B) -> B) {} } #[allow(dead_code)] // Fields are used instead of phantom data for generics use @@ -39,14 +39,14 @@ mod test_1 { pub fn check() { X1::<'static, 'static, i32, i32, 1> - ::foo::<'static, 'static, String, String, 123>(); - X1::<'static, 'static, i32, i32, 1>::bar(); + ::foo::<'static, 'static, String, String, 123>(|_, y| y); + X1::<'static, 'static, i32, i32, 1>::bar(|_, y| y); - X2::::foo::<'static, 'static, String, String, 123>(); - X2::::bar(); + X2::::foo::<'static, 'static, String, String, 123>(|_, y| y); + X2::::bar(|_, y| y); - X3::foo::<'static, 'static, String, String, 123>(); - X3::bar(); + X3::foo::<'static, 'static, String, String, 123>(|_, y| y); + X3::bar(|_, y| y); } } diff --git a/tests/ui/delegation/generics/mapping/inherent-impl-to-trait-pass.rs b/tests/ui/delegation/generics/mapping/inherent-impl-to-trait-pass.rs index 9e85a7c07c3a3..bf4d1a7ca2cb0 100644 --- a/tests/ui/delegation/generics/mapping/inherent-impl-to-trait-pass.rs +++ b/tests/ui/delegation/generics/mapping/inherent-impl-to-trait-pass.rs @@ -12,10 +12,10 @@ // Testing types in parent, none in child, // user-specified args in parent, checking predicates inheritance, -// with additional generic params in delegation parent +// with additional generic params in delegation parent, with impl traits mod test_1 { trait Trait { - fn foo(&self) {} + fn foo(&self, _f: impl FnOnce(T) -> String) {} } struct F; @@ -29,8 +29,8 @@ mod test_1 { pub fn check() { let s = S(F, &123, &123, &123); - S::<'static, 'static, 'static, i32, i32>::foo(&s); - s.foo(); + S::<'static, 'static, 'static, i32, i32>::foo(&s, |t| t.to_string()); + s.foo(|t| t.to_string()); } } diff --git a/tests/ui/delegation/generics/mapping/trait-to-free-pass.rs b/tests/ui/delegation/generics/mapping/trait-to-free-pass.rs index c43dc41931e9d..12edc3b72facd 100644 --- a/tests/ui/delegation/generics/mapping/trait-to-free-pass.rs +++ b/tests/ui/delegation/generics/mapping/trait-to-free-pass.rs @@ -10,9 +10,10 @@ //! added. At some tests user-specified args are specified in reuse statement. // Testing lifetimes + types/consts in child, lifetimes + types/consts in delegation parent, -// with(out) user-specified args +// with(out) user-specified args, with impl traits mod test_1 { - fn foo<'a: 'a, 'b: 'b, T: Clone + ToString, U: Clone, const N: usize>() {} + fn foo<'a: 'a, 'b: 'b, T: Clone + ToString, U: Clone, const N: usize>( + _f: impl FnOnce(T) -> (T, U)) {} trait Trait<'a, A, B, C, const N: usize> { reuse foo; @@ -21,8 +22,10 @@ mod test_1 { impl Trait<'static, i32, i32, i32, 1> for u32 {} pub fn check() { - >::foo::<'static, 'static, i32, String, 1>(); - >::bar(); + > + ::foo::<'static, 'static, i32, String, 1>(|t| (t, "".to_string())); + >::bar(|t| (t, t.to_string())); + u32::bar(|t| (t, t.to_string())); } } diff --git a/tests/ui/delegation/generics/mapping/trait-to-trait-pass.rs b/tests/ui/delegation/generics/mapping/trait-to-trait-pass.rs index 0e96f045065ac..bcc1369aa4408 100644 --- a/tests/ui/delegation/generics/mapping/trait-to-trait-pass.rs +++ b/tests/ui/delegation/generics/mapping/trait-to-trait-pass.rs @@ -14,10 +14,10 @@ // lifetimes + types/consts in child, // in delegation parent with: // lifetimes + types OR none OR lifetimes OR types, -// with(out) user-specified args, with different target expr +// with(out) user-specified args, with different target expr, with impl traits mod test_1 { trait Trait<'b, 'c, 'a, T>: Sized { - fn foo<'d: 'd, U, const M: bool>(&self) {} + fn foo<'d: 'd, U, const M: bool>(&self, _f: impl FnOnce(T) -> U) {} } impl<'b, 'c, 'a, T> Trait<'b, 'c, 'a, T> for u8 {} @@ -83,26 +83,26 @@ mod test_1 { pub fn check<'a: 'a>() { > - ::bar1::<'static, String, true>(&123); - ::bar1::<'static, String, true>(&123); - >::bar1::<'static, String, true>(&123); - >::bar1::<'static, String, true>(&123); + ::bar1::<'static, String, true>(&123, |x| x.to_string()); + ::bar1::<'static, String, true>(&123, |x| x.to_string()); + >::bar1::<'static, String, true>(&123, |x| x.to_string()); + >::bar1::<'static, String, true>(&123, |x| x.to_string()); - >::bar2(&123); - ::bar2(&123); - >::bar2(&123); - >::bar2(&123); + >::bar2(&123, |x| x.to_string()); + ::bar2(&123, |x| x.to_string()); + >::bar2(&123, |x| x.to_string()); + >::bar2(&123, |x| x.to_string()); > - ::bar3::<'static, String, true>(&123); - ::bar3::<'static, String, true>(&123); - >::bar3::<'static, String, true>(&123); - >::bar3::<'static, String, true>(&123); - - >::bar4(&123); - ::bar4(&123); - >::bar4(&123); - >::bar4(&123); + ::bar3::<'static, String, true>(&123, |x| x.to_string()); + ::bar3::<'static, String, true>(&123, |x| x.to_string()); + >::bar3::<'static, String, true>(&123, |x| x.to_string()); + >::bar3::<'static, String, true>(&123, |x| x.to_string()); + + >::bar4(&123, |x| x.to_string()); + ::bar4(&123, |x| x.to_string()); + >::bar4(&123, |x| x.to_string()); + >::bar4(&123, |x| x.to_string()); } } diff --git a/tests/ui/delegation/generics/query-cycle-oom-154169.rs b/tests/ui/delegation/generics/query-cycle-oom-154169.rs deleted file mode 100644 index 04a2896f6dd21..0000000000000 --- a/tests/ui/delegation/generics/query-cycle-oom-154169.rs +++ /dev/null @@ -1,53 +0,0 @@ -#![feature(fn_delegation)] -#![allow(incomplete_features)] - -mod test_1 { - trait Trait { - fn foo(&self, x: T) -> S { x } - //~^ ERROR: missing generics for struct `test_1::S` - } - struct F; - - struct S(F, T); - - impl Trait for S { - reuse to_reuse::foo { &self.0 } - //~^ ERROR: cannot find module or crate `to_reuse` in this scope - } -} - -mod test_2 { - trait Trait { - fn foo() -> Self::Assoc; - //~^ ERROR: associated type `Assoc` not found for `Self` - //~| ERROR: this function takes 0 arguments but 1 argument was supplied - fn bar(&self) -> u8; - } - - impl Trait for u8 { - //~^ ERROR: not all trait items implemented, missing: `foo` - fn bar(&self) -> u8 { 1 } - } - - struct S(u8); - - impl Trait for S { - reuse Trait::* { &self.0 } - fn bar(&self) -> u8 { 2 } - } -} - -mod test_3 { - trait Trait { - fn foo(&self) -> Self::Assoc<3> { //~ ERROR: associated type `Assoc` not found for `Self` - //~^ ERROR: no method named `foo` found for reference `&()` in the current scope - [(); 3] - } - } - - impl () { //~ ERROR: cannot define inherent `impl` for primitive types - reuse Trait::*; - } -} - -fn main() {} diff --git a/tests/ui/delegation/generics/query-cycle-oom-154169.stderr b/tests/ui/delegation/generics/query-cycle-oom-154169.stderr deleted file mode 100644 index 1baed6fd6748d..0000000000000 --- a/tests/ui/delegation/generics/query-cycle-oom-154169.stderr +++ /dev/null @@ -1,103 +0,0 @@ -error[E0107]: missing generics for struct `test_1::S` - --> $DIR/query-cycle-oom-154169.rs:6:32 - | -LL | fn foo(&self, x: T) -> S { x } - | ^ expected 1 generic argument - | -note: struct defined here, with 1 generic parameter: `T` - --> $DIR/query-cycle-oom-154169.rs:11:12 - | -LL | struct S(F, T); - | ^ - -help: add missing generic argument - | -LL | fn foo(&self, x: T) -> S { x } - | +++ - -error[E0220]: associated type `Assoc` not found for `Self` - --> $DIR/query-cycle-oom-154169.rs:21:27 - | -LL | fn foo() -> Self::Assoc; - | ^^^^^ associated type `Assoc` not found - -error[E0220]: associated type `Assoc` not found for `Self` - --> $DIR/query-cycle-oom-154169.rs:42:32 - | -LL | fn foo(&self) -> Self::Assoc<3> { - | ^^^^^ associated type `Assoc` not found - -error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/query-cycle-oom-154169.rs:27:5 - | -LL | fn foo() -> Self::Assoc; - | ------------------------ `foo` from trait -... -LL | impl Trait for u8 { - | ^^^^^^^^^^^^^^^^^ missing `foo` in implementation - -error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/query-cycle-oom-154169.rs:48:5 - | -LL | impl () { - | ^^^^^^^ - | - = help: consider using an extension trait instead - -error[E0433]: cannot find module or crate `to_reuse` in this scope - --> $DIR/query-cycle-oom-154169.rs:14:15 - | -LL | reuse to_reuse::foo { &self.0 } - | ^^^^^^^^ use of unresolved module or unlinked crate `to_reuse` - | - = help: you might be missing a crate named `to_reuse` - -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/query-cycle-oom-154169.rs:21:12 - | -LL | fn foo() -> Self::Assoc; - | ^^^ -... -LL | reuse Trait::* { &self.0 } - | ------- unexpected argument - | -note: associated function defined here - --> $DIR/query-cycle-oom-154169.rs:21:12 - | -LL | fn foo() -> Self::Assoc; - | ^^^ -help: remove the extra argument - | -LL - fn foo() -> Self::Assoc; -LL - -LL - -LL - fn bar(&self) -> u8; -LL - } -LL - -LL - impl Trait for u8 { -LL - -LL - fn bar(&self) -> u8 { 1 } -LL - } -LL - -LL - struct S(u8); -LL - -LL - impl Trait for S { -LL - reuse Trait::* { &self.0 } -LL + fn fo&self.0 } - | - -error[E0599]: no method named `foo` found for reference `&()` in the current scope - --> $DIR/query-cycle-oom-154169.rs:42:12 - | -LL | fn foo(&self) -> Self::Assoc<3> { - | ^^^ method not found in `&()` - | - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following traits define an item `foo`, perhaps you need to implement one of them: - candidate #1: `test_1::Trait` - candidate #2: `test_2::Trait` - candidate #3: `test_3::Trait` - -error: aborting due to 8 previous errors - -Some errors have detailed explanations: E0046, E0061, E0107, E0220, E0390, E0433, E0599. -For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/generics/synth-params-ice-154780.rs b/tests/ui/delegation/generics/synth-params-ice-154780.rs new file mode 100644 index 0000000000000..96af4ed86b4c2 --- /dev/null +++ b/tests/ui/delegation/generics/synth-params-ice-154780.rs @@ -0,0 +1,101 @@ +//@ run-pass + +#![feature(fn_delegation)] + +// Almost original ICE with recursive delegation. +mod test_1 { + pub fn check() { + fn foo(f: impl FnOnce() -> usize) -> usize { + f() + } + + reuse foo::<1, String, String> as bar; + + reuse bar as bar2; + + assert_eq!(bar(|| 123), 123); + assert_eq!(bar2(|| 123), 123); + } +} + +// Test recursive delegations through trait. +mod test_2 { + fn foo<'a, const B: bool, T, U>(_x: impl Trait<'a, T, B>, f: impl FnOnce() -> usize) -> usize { + f() + } + + trait Trait<'a, A, const B: bool> { + reuse foo; + reuse foo::<'a, false, (), ()> as bar; + } + + struct X; + impl<'a, A, const B: bool> Trait<'a, A, B> for X {} + + reuse ::foo as foo2; + reuse ::bar as bar2; + + pub fn check() { + assert_eq!(foo2::<'static, 'static, X, (), true, false, (), ()>(X, || 123), 123); + assert_eq!(bar2::<'static, X, (), true>(X, || 123), 123); + } +} + +// Testing impl Traits with SelfAndUserSpecified case. +mod test_3 { + trait Trait<'a, A, const B: bool> { + fn foo<'b, const B2: bool, T, U>(&self, f: impl FnOnce() -> usize) -> usize { + f() + } + } + + struct X; + impl<'a, A, const B: bool> Trait<'a, A, B> for X {} + + reuse Trait::foo; + reuse Trait::<'static, (), true>::foo:: as bar; + + pub fn check() { + assert_eq!(foo::<'static, X, (), true, false, (), ()>(&X, || 123), 123); + assert_eq!(bar::(&X, || 123), 123); + assert_eq!(bar(&X, || 123), 123); + } +} + +// FIXME(fn_delegation): rename Self generic param in recursive delegations +// mod test_4 { +// trait Trait<'a, A, const B: bool> { +// fn foo<'b, const B2: bool, T, U>(&self, f: impl FnOnce() -> usize) -> usize { +// f() +// } +// } + +// struct X; +// impl<'a, A, const B: bool> Trait<'a, A, B> for X {} + +// reuse Trait::foo; +// reuse Trait::<'static, (), true>::foo:: as bar; + +// trait Trait2 { +// reuse foo; +// reuse bar; +// } + +// reuse Trait2::foo as foo2; +// reuse Trait2::foo::<'static, X, (), true, false, (), ()> as foo3; +// reuse Trait2::bar as bar2; +// reuse Trait2::bar:: as bar3; + +// pub fn check() { +// assert_eq!(foo::<'static, X, (), true, false, (), ()>(&X, || 123), 123); +// assert_eq!(bar::(&X, || 123), 123); +// assert_eq!(bar(&X, || 123), 123); +// } +// } + +fn main() { + test_1::check(); + test_2::check(); + test_3::check(); + // test_4::check(); +} diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs new file mode 100644 index 0000000000000..1dc2f2f8a2634 --- /dev/null +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs @@ -0,0 +1,66 @@ +#![feature(min_generic_const_args, fn_delegation)] +#![allow(incomplete_features)] + +mod ice_155125 { + struct S; + impl + S< + { //~ ERROR: complex const arguments must be placed inside of a `const` block + fn foo() {} + reuse foo; //~ ERROR: the name `foo` is defined multiple times + 2 + }, + > + { + } +} + +mod ice_155127 { + struct S; + + fn foo() {} + impl S { + #[deprecated] //~ ERROR: `#[deprecated]` attribute cannot be used on delegations + //~^ WARN: this was previously accepted by the compiler but is being phased out; + reuse foo; + } +} + +mod ice_155128 { + fn a() {} + + reuse a as b { //~ ERROR: this function takes 0 arguments but 1 argument was supplied + fn foo() {}; + foo + } +} + +mod ice_155164 { + struct X { + inner: std::iter::Map< + { + //~^ ERROR: complex const arguments must be placed inside of a `const` block + //~| ERROR: constant provided when a type was expected + struct W; + impl W { + reuse Iterator::fold; + } + }, + F, + >, + } +} + +mod ice_155202 { + trait Trait { + fn bar(self); + } + impl Trait for () { + reuse Trait::bar { + async || {}; //~ ERROR: mismatched types + //~^ ERROR: cannot find value `async` in this scope + } + } +} + +fn main() {} diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.stderr b/tests/ui/delegation/hir-crate-items-before-lowering-ices.stderr new file mode 100644 index 0000000000000..1bc4c1f7de4e5 --- /dev/null +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.stderr @@ -0,0 +1,89 @@ +error[E0428]: the name `foo` is defined multiple times + --> $DIR/hir-crate-items-before-lowering-ices.rs:10:17 + | +LL | fn foo() {} + | -------- previous definition of the value `foo` here +LL | reuse foo; + | ^^^^^^^^^^ `foo` redefined here + | + = note: `foo` must be defined only once in the value namespace of this block + +error[E0425]: cannot find value `async` in this scope + --> $DIR/hir-crate-items-before-lowering-ices.rs:60:13 + | +LL | async || {}; + | ^^^^^ not found in this scope + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/hir-crate-items-before-lowering-ices.rs:8:13 + | +LL | / { +LL | | fn foo() {} +LL | | reuse foo; +LL | | 2 +LL | | }, + | |_____________^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/hir-crate-items-before-lowering-ices.rs:41:13 + | +LL | / { +LL | | +LL | | +LL | | struct W; +... | +LL | | }, + | |_____________^ + +error: `#[deprecated]` attribute cannot be used on delegations + --> $DIR/hir-crate-items-before-lowering-ices.rs:23:9 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements + = note: `#[deny(useless_deprecated)]` on by default + +error[E0747]: constant provided when a type was expected + --> $DIR/hir-crate-items-before-lowering-ices.rs:41:13 + | +LL | / { +LL | | +LL | | +LL | | struct W; +... | +LL | | }, + | |_____________^ + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/hir-crate-items-before-lowering-ices.rs:32:11 + | +LL | reuse a as b { + | ___________^______- +LL | | fn foo() {}; +LL | | foo +LL | | } + | |_____- unexpected argument of type `fn() {b::foo::<_>}` + | +note: function defined here + --> $DIR/hir-crate-items-before-lowering-ices.rs:30:8 + | +LL | fn a() {} + | ^ +help: remove the extra argument + | +LL - reuse a as b { +LL + reuse { + | + +error[E0308]: mismatched types + --> $DIR/hir-crate-items-before-lowering-ices.rs:60:22 + | +LL | async || {}; + | ^^ expected `bool`, found `()` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0061, E0308, E0425, E0428, E0747. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/ice-issue-122550.stderr b/tests/ui/delegation/ice-issue-122550.stderr index c0b6305227a07..01355c8ad921c 100644 --- a/tests/ui/delegation/ice-issue-122550.stderr +++ b/tests/ui/delegation/ice-issue-122550.stderr @@ -1,3 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/ice-issue-122550.rs:5:35 + | +LL | fn description(&self) -> &str {} + | ^^ expected `&str`, found `()` + error[E0277]: the trait bound `S: Trait` is not satisfied --> $DIR/ice-issue-122550.rs:13:12 | @@ -31,12 +37,6 @@ note: method defined here LL | fn description(&self) -> &str {} | ^^^^^^^^^^^ ----- -error[E0308]: mismatched types - --> $DIR/ice-issue-122550.rs:5:35 - | -LL | fn description(&self) -> &str {} - | ^^ expected `&str`, found `()` - error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308. diff --git a/tests/ui/macros/macro-guard-matcher.rs b/tests/ui/macros/macro-guard-matcher.rs index 81a4412686de3..d66bae455c2c2 100644 --- a/tests/ui/macros/macro-guard-matcher.rs +++ b/tests/ui/macros/macro-guard-matcher.rs @@ -2,7 +2,7 @@ fn main() { macro_rules! m { - ($x:guard) => {}; + ($g:guard) => {}; } // Accepts @@ -14,4 +14,12 @@ fn main() { // Rejects m!(let Some(x) = Some(1)); //~ERROR no rules expected keyword `let` + + macro_rules! m_m { + ($g:guard) => { m!($g); }; + } + + // Accepted since `m` recognizes that the sequence produced by the expansion of + // metavar `$g` "begins" (i.e., is) a guard since it's of kind `guard`. + m_m!(if true); } diff --git a/tests/ui/macros/macro-guard-matcher.stderr b/tests/ui/macros/macro-guard-matcher.stderr index eddb0de9c4c54..883f80069db8d 100644 --- a/tests/ui/macros/macro-guard-matcher.stderr +++ b/tests/ui/macros/macro-guard-matcher.stderr @@ -7,10 +7,10 @@ LL | macro_rules! m { LL | m!(let Some(x) = Some(1)); | ^^^ no rules expected this token in macro call | -note: while trying to match meta-variable `$x:guard` +note: while trying to match meta-variable `$g:guard` --> $DIR/macro-guard-matcher.rs:5:10 | -LL | ($x:guard) => {}; +LL | ($g:guard) => {}; | ^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/scalable-vectors/cast-intrinsic.rs b/tests/ui/scalable-vectors/cast-intrinsic.rs index f2157d8bcc14b..e5d2efb0b6c85 100644 --- a/tests/ui/scalable-vectors/cast-intrinsic.rs +++ b/tests/ui/scalable-vectors/cast-intrinsic.rs @@ -4,7 +4,7 @@ #![allow(incomplete_features, internal_features, improper_ctypes)] #![feature(abi_unadjusted, core_intrinsics, link_llvm_intrinsics, rustc_attrs)] -use std::intrinsics::simd::scalable::sve_cast; +use std::intrinsics::simd::simd_cast; #[derive(Copy, Clone)] #[rustc_scalable_vector(16)] @@ -61,5 +61,5 @@ pub unsafe fn svld1sh_gather_s64offset_s64( offsets: svint64_t, ) -> nxv2i16; } - sve_cast(_svld1sh_gather_s64offset_s64(pg.sve_into(), base, offsets)) + simd_cast(_svld1sh_gather_s64offset_s64(pg.sve_into(), base, offsets)) } diff --git a/tests/ui/scalable-vectors/select-intrinsic.rs b/tests/ui/scalable-vectors/select-intrinsic.rs new file mode 100644 index 0000000000000..7ae2683b3dfef --- /dev/null +++ b/tests/ui/scalable-vectors/select-intrinsic.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ only-aarch64 +#![crate_type = "lib"] +#![allow(incomplete_features, internal_features, improper_ctypes)] +#![feature(abi_unadjusted, core_intrinsics, link_llvm_intrinsics, rustc_attrs)] + +use std::intrinsics::simd::simd_select; + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +pub struct svbool_t(bool); + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +pub struct svint8_t(i8); + +#[target_feature(enable = "sve")] +pub fn svsel_s8(pg: svbool_t, op1: svint8_t, op2: svint8_t) -> svint8_t { + unsafe { simd_select::(pg, op1, op2) } +} diff --git a/tests/ui/std/open-options-ext-compat.rs b/tests/ui/std/open-options-ext-compat.rs new file mode 100644 index 0000000000000..783b1e0961cbb --- /dev/null +++ b/tests/ui/std/open-options-ext-compat.rs @@ -0,0 +1,20 @@ +//@ only-windows +//@ check-pass + +// Regression test for https://github.com/rust-lang/rust/issues/153486 +// Ensures that `OpenOptionsExt` remains implementable by downstream crates +// without requiring changes when new methods are added to the standard library. + +use std::os::windows::fs::OpenOptionsExt; + +struct MockOptions; + +impl OpenOptionsExt for MockOptions { + fn access_mode(&mut self, _: u32) -> &mut Self { self } + fn share_mode(&mut self, _: u32) -> &mut Self { self } + fn custom_flags(&mut self, _: u32) -> &mut Self { self } + fn attributes(&mut self, _: u32) -> &mut Self { self } + fn security_qos_flags(&mut self, _: u32) -> &mut Self { self } +} + +fn main() {}