1use std::cell::RefCell;2use std::collections::BTreeMap;3use std::collections::btree_map::Entry;4use std::mem;5use std::ops::{Deref, DerefMut};6use std::sync::LazyLock;78use rustc_ast::{AttrStyle, MetaItemLit};9use rustc_data_structures::sync::{DynSend, DynSync};10use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan};11use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};12use rustc_hir::AttrPath;13use rustc_hir::attrs::AttributeKind;14use rustc_parse::parser::Recovery;15use rustc_session::Session;16use rustc_session::lint::{Lint, LintId};17use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};1819// Glob imports to avoid big, bitrotty import lists20use crate::attributes::allow_unstable::*;21use crate::attributes::autodiff::*;22use crate::attributes::body::*;23use crate::attributes::cfi_encoding::*;24use crate::attributes::codegen_attrs::*;25use crate::attributes::confusables::*;26use crate::attributes::crate_level::*;27use crate::attributes::debugger::*;28use crate::attributes::deprecation::*;29use crate::attributes::diagnostic::do_not_recommend::*;30use crate::attributes::diagnostic::on_const::*;31use crate::attributes::diagnostic::on_move::*;32use crate::attributes::diagnostic::on_unimplemented::*;33use crate::attributes::diagnostic::on_unknown::*;34use crate::attributes::diagnostic::on_unmatch_args::*;35use crate::attributes::doc::*;36use crate::attributes::dummy::*;37use crate::attributes::inline::*;38use crate::attributes::instruction_set::*;39use crate::attributes::link_attrs::*;40use crate::attributes::lint_helpers::*;41use crate::attributes::loop_match::*;42use crate::attributes::macro_attrs::*;43use crate::attributes::must_not_suspend::*;44use crate::attributes::must_use::*;45use crate::attributes::no_implicit_prelude::*;46use crate::attributes::no_link::*;47use crate::attributes::non_exhaustive::*;48use crate::attributes::path::PathParser as PathAttributeParser;49use crate::attributes::pin_v2::*;50use crate::attributes::proc_macro_attrs::*;51use crate::attributes::prototype::*;52use crate::attributes::repr::*;53use crate::attributes::rustc_allocator::*;54use crate::attributes::rustc_dump::*;55use crate::attributes::rustc_internal::*;56use crate::attributes::semantics::*;57use crate::attributes::stability::*;58use crate::attributes::test_attrs::*;59use crate::attributes::traits::*;60use crate::attributes::transparency::*;61use crate::attributes::{AttributeParser as _, AttributeSafety, Combine, Single, WithoutArgs};62use crate::parser::{63 ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItemParser, NameValueParser,64 RefPathParser,65};66use crate::session_diagnostics::{67 AttributeParseError, AttributeParseErrorReason, AttributeParseErrorSuggestions,68 ParsedDescription,69};70use crate::target_checking::AllowedTargets;71use crate::{AttributeParser, EmitAttribute};7273type GroupType = LazyLock<GroupTypeInner>;7475pub(super) struct GroupTypeInner {76 pub(super) accepters: BTreeMap<&'static [Symbol], GroupTypeInnerAccept>,77}7879pub(super) struct GroupTypeInnerAccept {80 pub(super) template: AttributeTemplate,81 pub(super) accept_fn: AcceptFn,82 pub(super) allowed_targets: AllowedTargets,83 pub(super) safety: AttributeSafety,84 pub(super) finalizer: FinalizeFn,85}8687pub(crate) type AcceptFn =88 Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess>, &ArgParser) + Send + Sync>;89pub(crate) type FinalizeFn = fn(&mut FinalizeContext<'_, '_>) -> Option<AttributeKind>;9091macro_rules! attribute_parsers {92 (93 pub(crate) static $name: ident = [$($names: ty),* $(,)?];94 ) => {95 pub(crate) static $name: GroupType = LazyLock::new(|| {96 let mut accepters = BTreeMap::<_, GroupTypeInnerAccept>::new();97 $(98 {99 thread_local! {100 static STATE_OBJECT: RefCell<$names> = RefCell::new(<$names>::default());101 };102103 for (path, template, accept_fn) in <$names>::ATTRIBUTES {104 match accepters.entry(*path) {105 Entry::Vacant(e) => {106 e.insert(GroupTypeInnerAccept {107 template: *template,108 accept_fn: Box::new(|cx, args| {109 STATE_OBJECT.with_borrow_mut(|s| {110 accept_fn(s, cx, args)111 })112 }),113 safety: <$names as crate::attributes::AttributeParser>::SAFETY,114 allowed_targets: <$names as crate::attributes::AttributeParser>::ALLOWED_TARGETS,115 finalizer: |cx| {116 let state = STATE_OBJECT.take();117 state.finalize(cx)118 }119 });120 }121 Entry::Occupied(_) => panic!("Attribute {path:?} has multiple accepters"),122 }123 }124 }125 )*126127 GroupTypeInner { accepters }128 });129 };130}131attribute_parsers!(132 pub(crate) static ATTRIBUTE_PARSERS = [133 // tidy-alphabetical-start134 BodyStabilityParser,135 ConfusablesParser,136 ConstStabilityParser,137 DocParser,138 MacroUseParser,139 NakedParser,140 OnConstParser,141 OnMoveParser,142 OnUnimplementedParser,143 OnUnknownParser,144 OnUnmatchArgsParser,145 RustcAlignParser,146 RustcAlignStaticParser,147 RustcCguTestAttributeParser,148 StabilityParser,149 UsedParser,150 // tidy-alphabetical-end151152 // tidy-alphabetical-start153 Combine<AllowInternalUnstableParser>,154 Combine<CrateTypeParser>,155 Combine<DebuggerViualizerParser>,156 Combine<FeatureParser>,157 Combine<ForceTargetFeatureParser>,158 Combine<LinkParser>,159 Combine<RegisterToolParser>,160 Combine<ReprParser>,161 Combine<RustcAllowConstFnUnstableParser>,162 Combine<RustcCleanParser>,163 Combine<RustcDumpLayoutParser>,164 Combine<RustcMirParser>,165 Combine<RustcThenThisWouldNeedParser>,166 Combine<TargetFeatureParser>,167 Combine<UnstableFeatureBoundParser>,168 Combine<UnstableRemovedParser>,169 // tidy-alphabetical-end170171 // tidy-alphabetical-start172 Single<CfiEncodingParser>,173 Single<CollapseDebugInfoParser>,174 Single<CoverageParser>,175 Single<CrateNameParser>,176 Single<CustomMirParser>,177 Single<DeprecatedParser>,178 Single<DoNotRecommendParser>,179 Single<ExportNameParser>,180 Single<IgnoreParser>,181 Single<InlineParser>,182 Single<InstructionSetParser>,183 Single<LangParser>,184 Single<LinkNameParser>,185 Single<LinkOrdinalParser>,186 Single<LinkSectionParser>,187 Single<LinkageParser>,188 Single<MacroExportParser>,189 Single<MoveSizeLimitParser>,190 Single<MustNotSuspendParser>,191 Single<MustUseParser>,192 Single<OptimizeParser>,193 Single<PatchableFunctionEntryParser>,194 Single<PathAttributeParser>,195 Single<PatternComplexityLimitParser>,196 Single<ProcMacroDeriveParser>,197 Single<RecursionLimitParser>,198 Single<ReexportTestHarnessMainParser>,199 Single<RustcAbiParser>,200 Single<RustcAllocatorZeroedVariantParser>,201 Single<RustcAutodiffParser>,202 Single<RustcBuiltinMacroParser>,203 Single<RustcDeprecatedSafe2024Parser>,204 Single<RustcDiagnosticItemParser>,205 Single<RustcDocPrimitiveParser>,206 Single<RustcDummyParser>,207 Single<RustcDumpDefPathParser>,208 Single<RustcDumpSymbolNameParser>,209 Single<RustcForceInlineParser>,210 Single<RustcIfThisChangedParser>,211 Single<RustcLegacyConstGenericsParser>,212 Single<RustcLintOptDenyFieldAccessParser>,213 Single<RustcMacroTransparencyParser>,214 Single<RustcMustImplementOneOfParser>,215 Single<RustcNeverTypeOptionsParser>,216 Single<RustcObjcClassParser>,217 Single<RustcObjcSelectorParser>,218 Single<RustcReservationImplParser>,219 Single<RustcScalableVectorParser>,220 Single<RustcSimdMonomorphizeLaneLimitParser>,221 Single<RustcSkipDuringMethodDispatchParser>,222 Single<RustcTestMarkerParser>,223 Single<SanitizeParser>,224 Single<ShouldPanicParser>,225 Single<TestRunnerParser>,226 Single<TypeLengthLimitParser>,227 Single<WindowsSubsystemParser>,228 Single<WithoutArgs<AllowInternalUnsafeParser>>,229 Single<WithoutArgs<AutomaticallyDerivedParser>>,230 Single<WithoutArgs<ColdParser>>,231 Single<WithoutArgs<CompilerBuiltinsParser>>,232 Single<WithoutArgs<ConstContinueParser>>,233 Single<WithoutArgs<CoroutineParser>>,234 Single<WithoutArgs<DefaultLibAllocatorParser>>,235 Single<WithoutArgs<ExportStableParser>>,236 Single<WithoutArgs<FfiConstParser>>,237 Single<WithoutArgs<FfiPureParser>>,238 Single<WithoutArgs<FundamentalParser>>,239 Single<WithoutArgs<LoopMatchParser>>,240 Single<WithoutArgs<MacroEscapeParser>>,241 Single<WithoutArgs<MarkerParser>>,242 Single<WithoutArgs<MayDangleParser>>,243 Single<WithoutArgs<NeedsAllocatorParser>>,244 Single<WithoutArgs<NeedsPanicRuntimeParser>>,245 Single<WithoutArgs<NoBuiltinsParser>>,246 Single<WithoutArgs<NoCoreParser>>,247 Single<WithoutArgs<NoImplicitPreludeParser>>,248 Single<WithoutArgs<NoLinkParser>>,249 Single<WithoutArgs<NoMainParser>>,250 Single<WithoutArgs<NoMangleParser>>,251 Single<WithoutArgs<NoStdParser>>,252 Single<WithoutArgs<NonExhaustiveParser>>,253 Single<WithoutArgs<PanicHandlerParser>>,254 Single<WithoutArgs<PanicRuntimeParser>>,255 Single<WithoutArgs<PinV2Parser>>,256 Single<WithoutArgs<PreludeImportParser>>,257 Single<WithoutArgs<ProcMacroAttributeParser>>,258 Single<WithoutArgs<ProcMacroParser>>,259 Single<WithoutArgs<ProfilerRuntimeParser>>,260 Single<WithoutArgs<RustcAllocatorParser>>,261 Single<WithoutArgs<RustcAllocatorZeroedParser>>,262 Single<WithoutArgs<RustcAllowIncoherentImplParser>>,263 Single<WithoutArgs<RustcAsPtrParser>>,264 Single<WithoutArgs<RustcCaptureAnalysisParser>>,265 Single<WithoutArgs<RustcCoherenceIsCoreParser>>,266 Single<WithoutArgs<RustcCoinductiveParser>>,267 Single<WithoutArgs<RustcConstStableIndirectParser>>,268 Single<WithoutArgs<RustcConversionSuggestionParser>>,269 Single<WithoutArgs<RustcDeallocatorParser>>,270 Single<WithoutArgs<RustcDelayedBugFromInsideQueryParser>>,271 Single<WithoutArgs<RustcDenyExplicitImplParser>>,272 Single<WithoutArgs<RustcDoNotConstCheckParser>>,273 Single<WithoutArgs<RustcDumpDefParentsParser>>,274 Single<WithoutArgs<RustcDumpHiddenTypeOfOpaquesParser>>,275 Single<WithoutArgs<RustcDumpInferredOutlivesParser>>,276 Single<WithoutArgs<RustcDumpItemBoundsParser>>,277 Single<WithoutArgs<RustcDumpObjectLifetimeDefaultsParser>>,278 Single<WithoutArgs<RustcDumpPredicatesParser>>,279 Single<WithoutArgs<RustcDumpUserArgsParser>>,280 Single<WithoutArgs<RustcDumpVariancesOfOpaquesParser>>,281 Single<WithoutArgs<RustcDumpVariancesParser>>,282 Single<WithoutArgs<RustcDumpVtableParser>>,283 Single<WithoutArgs<RustcDynIncompatibleTraitParser>>,284 Single<WithoutArgs<RustcEffectiveVisibilityParser>>,285 Single<WithoutArgs<RustcEiiForeignItemParser>>,286 Single<WithoutArgs<RustcEvaluateWhereClausesParser>>,287 Single<WithoutArgs<RustcExhaustiveParser>>,288 Single<WithoutArgs<RustcHasIncoherentInherentImplsParser>>,289 Single<WithoutArgs<RustcInheritOverflowChecksParser>>,290 Single<WithoutArgs<RustcInsignificantDtorParser>>,291 Single<WithoutArgs<RustcIntrinsicConstStableIndirectParser>>,292 Single<WithoutArgs<RustcIntrinsicParser>>,293 Single<WithoutArgs<RustcLintOptTyParser>>,294 Single<WithoutArgs<RustcLintQueryInstabilityParser>>,295 Single<WithoutArgs<RustcLintUntrackedQueryInformationParser>>,296 Single<WithoutArgs<RustcMainParser>>,297 Single<WithoutArgs<RustcNeverReturnsNullPtrParser>>,298 Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,299 Single<WithoutArgs<RustcNoImplicitBoundsParser>>,300 Single<WithoutArgs<RustcNoMirInlineParser>>,301 Single<WithoutArgs<RustcNoWritableParser>>,302 Single<WithoutArgs<RustcNonConstTraitMethodParser>>,303 Single<WithoutArgs<RustcNonnullOptimizationGuaranteedParser>>,304 Single<WithoutArgs<RustcNounwindParser>>,305 Single<WithoutArgs<RustcOffloadKernelParser>>,306 Single<WithoutArgs<RustcParenSugarParser>>,307 Single<WithoutArgs<RustcPassByValueParser>>,308 Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,309 Single<WithoutArgs<RustcPreserveUbChecksParser>>,310 Single<WithoutArgs<RustcProcMacroDeclsParser>>,311 Single<WithoutArgs<RustcPubTransparentParser>>,312 Single<WithoutArgs<RustcReallocatorParser>>,313 Single<WithoutArgs<RustcRegionsParser>>,314 Single<WithoutArgs<RustcShouldNotBeCalledOnConstItemsParser>>,315 Single<WithoutArgs<RustcSpecializationTraitParser>>,316 Single<WithoutArgs<RustcStdInternalSymbolParser>>,317 Single<WithoutArgs<RustcStrictCoherenceParser>>,318 Single<WithoutArgs<RustcTrivialFieldReadsParser>>,319 Single<WithoutArgs<RustcUnsafeSpecializationMarkerParser>>,320 Single<WithoutArgs<ThreadLocalParser>>,321 Single<WithoutArgs<TrackCallerParser>>,322 // tidy-alphabetical-end323 ];324);325326/// Context given to every attribute parser when accepting327///328/// Gives [`AttributeParser`]s enough information to create errors, for example.329pub struct AcceptContext<'f, 'sess> {330 pub(crate) shared: SharedContext<'f, 'sess>,331332 /// The outer span of the attribute currently being parsed333 ///334 /// ```none335 /// #[attribute(...)]336 /// ^^^^^^^^^^^^^^^^^ outer span337 /// ```338 /// For attributes in `cfg_attr`, the outer span and inner spans are equal.339 pub(crate) attr_span: Span,340 /// The inner span of the attribute currently being parsed.341 ///342 /// ```none343 /// #[attribute(...)]344 /// ^^^^^^^^^^^^^^ inner span345 /// ```346 pub(crate) inner_span: Span,347348 /// Whether it is an inner or outer attribute.349 pub(crate) attr_style: AttrStyle,350351 /// A description of the thing we are parsing using this attribute parser.352 /// We are not only using these parsers for attributes, but also for macros such as the `cfg!()` macro.353 pub(crate) parsed_description: ParsedDescription,354355 /// The expected structure of the attribute.356 ///357 /// Used in reporting errors to give a hint to users what the attribute *should* look like.358 pub(crate) template: &'f AttributeTemplate,359360 /// The name of the attribute we're currently accepting.361 pub(crate) attr_path: AttrPath,362}363364impl<'f, 'sess: 'f> SharedContext<'f, 'sess> {365 pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuaranteed {366 self.cx.emit_err(diag)367 }368369 /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing370 /// must be delayed until after HIR is built. This method will take care of the details of371 /// that.372 pub(crate) fn emit_lint(373 &mut self,374 lint: &'static Lint,375 diagnostic: impl for<'x> Diagnostic<'x, ()> + DynSend + DynSync + 'static,376 span: impl Into<MultiSpan>,377 ) {378 self.emit_lint_inner(379 lint,380 EmitAttribute(Box::new(move |dcx, level, _| diagnostic.into_diag(dcx, level))),381 span,382 );383 }384385 pub(crate) fn emit_lint_with_sess<386 F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level, &Session) -> Diag<'a, ()>387 + DynSend388 + DynSync389 + 'static,390 >(391 &mut self,392 lint: &'static Lint,393 callback: F,394 span: impl Into<MultiSpan>,395 ) {396 self.emit_lint_inner(lint, EmitAttribute(Box::new(callback)), span);397 }398399 fn emit_lint_inner(400 &mut self,401 lint: &'static Lint,402 kind: EmitAttribute,403 span: impl Into<MultiSpan>,404 ) {405 if !matches!(406 self.should_emit,407 ShouldEmit::ErrorsAndLints { .. } | ShouldEmit::EarlyFatal { also_emit_lints: true }408 ) {409 return;410 }411 (self.emit_lint)(LintId::of(lint), span.into(), kind);412 }413414 pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {415 self.emit_lint(416 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,417 rustc_errors::lints::UnusedDuplicate {418 this: unused_span,419 other: used_span,420 warning: false,421 },422 unused_span,423 )424 }425426 pub(crate) fn warn_unused_duplicate_future_error(427 &mut self,428 used_span: Span,429 unused_span: Span,430 ) {431 self.emit_lint(432 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,433 rustc_errors::lints::UnusedDuplicate {434 this: unused_span,435 other: used_span,436 warning: true,437 },438 unused_span,439 )440 }441}442443impl<'f, 'sess: 'f> AcceptContext<'f, 'sess> {444 pub(crate) fn adcx(&mut self) -> AttributeDiagnosticContext<'_, 'f, 'sess> {445 AttributeDiagnosticContext { ctx: self, custom_suggestions: Vec::new() }446 }447448 /// Asserts that this MetaItem is a list that contains a single element. Emits an error and449 /// returns `None` if it is not the case.450 ///451 /// Some examples:452 ///453 /// - In `#[allow(warnings)]`, `warnings` is returned454 /// - In `#[cfg_attr(docsrs, doc = "foo")]`, `None` is returned, "expected a single argument455 /// here" is emitted.456 /// - In `#[cfg()]`, `None` is returned, "expected an argument here" is emitted.457 ///458 /// The provided span is used as a fallback for diagnostic generation in case `arg` does not459 /// contain any. It should be the span of the node that contains `arg`.460 pub(crate) fn expect_single_element_list<'arg>(461 &mut self,462 arg: &'arg ArgParser,463 span: Span,464 ) -> Option<&'arg MetaItemOrLitParser> {465 let ArgParser::List(l) = arg else {466 self.adcx().expected_list(span, arg);467 return None;468 };469470 let Some(single) = l.as_single() else {471 self.adcx().expected_single_argument(l.span, l.len());472 return None;473 };474475 Some(single)476 }477478 /// Asserts that an [`ArgParser`] is a list and returns it, or emits an error and returns479 /// `None`.480 ///481 /// Some examples:482 ///483 /// - `#[allow(clippy::complexity)]`: `(clippy::complexity)` is a list484 /// - `#[rustfmt::skip::macros(target_macro_name)]`: `(target_macro_name)` is a list485 ///486 /// This is a higher-level (and harder to misuse) wrapper over [`ArgParser::as_list`] that487 /// allows using `?` when the attribute parsing function allows it. You may still want to use488 /// [`ArgParser::as_list`] for the following reasons:489 ///490 /// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).491 /// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.492 pub(crate) fn expect_list<'arg>(493 &mut self,494 args: &'arg ArgParser,495 span: Span,496 ) -> Option<&'arg MetaItemListParser> {497 let list = args.as_list();498 if list.is_none() {499 self.adcx().expected_list(span, args);500 }501 list502 }503504 /// Asserts that a [`MetaItemListParser`] contains a single element and returns it, or emits an505 /// error and returns `None`.506 ///507 /// This is a higher-level (and harder to misuse) wrapper over [`MetaItemListParser::as_single`],508 /// that allows using `?` to early return. You may still want to use509 /// [`MetaItemListParser::as_single`] for the following reasons:510 ///511 /// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).512 /// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.513 pub(crate) fn expect_single<'arg>(514 &mut self,515 list: &'arg MetaItemListParser,516 ) -> Option<&'arg MetaItemOrLitParser> {517 let single = list.as_single();518 if single.is_none() {519 self.adcx().expected_single_argument(list.span, list.len());520 }521 single522 }523524 /// Asserts that a node is a name-value pair.525 ///526 /// Some examples:527 ///528 /// - `#[clippy::cyclomatic_complexity = "100"]`: `clippy::cyclomatic_complexity = "100"` is a529 /// name-value pair, where the name is a path (`clippy::cyclomatic_complexity`). You already530 /// checked the path to get an `ArgParser`, so this method will effectively only assert that531 /// the `= "100"` is there and returns it.532 /// - `#[doc = "hello"]`: `doc = "hello` is also a name value pair. `= "hello"` is returned.533 /// - `#[serde(rename_all = "lowercase")]`: `rename_all = "lowercase"` is a name value pair,534 /// where the name is an identifier (`rename_all`) and the value is a literal (`"lowercase"`).535 /// This returns both the path and the value.536 ///537 /// `arg` must be a reference to any node that may contain a name-value pair, that is:538 ///539 /// - [`MetaItemOrLitParser`],540 /// - [`MetaItemParser`],541 /// - [`ArgParser`].542 ///543 /// `name` can be set to `Some` for a nicer error message talking about the specific name that544 /// was found lacking a value.545 ///546 /// This is a higher-level (and harder to misuse) wrapper over multiple `as_` methods in the547 /// [`parser`][crate::parser] module. You may still want to use the lower-level methods for the548 /// following reasons:549 ///550 /// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).551 /// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.552 pub(crate) fn expect_name_value<'arg, Arg>(553 &mut self,554 arg: &'arg Arg,555 span: Span,556 name: Option<Symbol>,557 ) -> Option<Arg::Output<'arg>>558 where559 Arg: ExpectNameValue,560 {561 arg.expect_name_value(self, span, name)562 }563564 /// Assert that an [`ArgParser`] has no args, or emits an error and return `None`.565 pub(crate) fn expect_no_args<'arg>(&mut self, arg: &'arg ArgParser) -> Option<()> {566 if let Err(span) = arg.as_no_args() {567 self.adcx().expected_no_args(span);568 return None;569 }570571 Some(())572 }573}574575pub(crate) trait ExpectNameValue {576 type Output<'a>577 where578 Self: 'a;579580 fn expect_name_value<'a, 'f, 'sess>(581 &'a self,582 cx: &mut AcceptContext<'f, 'sess>,583 span: Span,584 name: Option<Symbol>,585 ) -> Option<Self::Output<'a>>;586}587588impl ExpectNameValue for MetaItemOrLitParser {589 type Output<'a> = (Ident, &'a NameValueParser);590591 fn expect_name_value<'a, 'f, 'sess>(592 &'a self,593 cx: &mut AcceptContext<'f, 'sess>,594 span: Span,595 name: Option<Symbol>,596 ) -> Option<Self::Output<'a>> {597 let Some(meta_item) = self.meta_item() else {598 cx.adcx().expected_name_value(self.span(), name);599 return None;600 };601602 meta_item.expect_name_value(cx, span, name)603 }604}605606impl ExpectNameValue for MetaItemParser {607 type Output<'a> = (Ident, &'a NameValueParser);608609 fn expect_name_value<'a, 'f, 'sess>(610 &'a self,611 cx: &mut AcceptContext<'f, 'sess>,612 _span: Span, // Not needed: `MetaItemOrLitParser` carry its own span.613 name: Option<Symbol>,614 ) -> Option<Self::Output<'a>> {615 let word = self.path().word();616 let arg = self.args().as_name_value();617618 if word.is_none() {619 cx.adcx().expected_identifier(self.path().span());620 }621622 if arg.is_none() {623 cx.adcx().expected_name_value(self.span(), name);624 }625626 let Some((word, arg)) = word.zip(arg) else {627 return None;628 };629630 Some((word, arg))631 }632}633634impl ExpectNameValue for ArgParser {635 type Output<'a> = &'a NameValueParser;636637 fn expect_name_value<'a, 'f, 'sess>(638 &'a self,639 cx: &mut AcceptContext<'f, 'sess>,640 span: Span,641 name: Option<Symbol>,642 ) -> Option<Self::Output<'a>> {643 let Some(nv) = self.as_name_value() else {644 cx.adcx().expected_name_value(span, name);645 return None;646 };647648 Some(nv)649 }650}651652impl<'f, 'sess> Deref for AcceptContext<'f, 'sess> {653 type Target = SharedContext<'f, 'sess>;654655 fn deref(&self) -> &Self::Target {656 &self.shared657 }658}659660impl<'f, 'sess> DerefMut for AcceptContext<'f, 'sess> {661 fn deref_mut(&mut self) -> &mut Self::Target {662 &mut self.shared663 }664}665666/// Context given to every attribute parser during finalization.667///668/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create669/// errors, for example.670pub struct SharedContext<'p, 'sess> {671 /// The parse context, gives access to the session and the672 /// diagnostics context.673 pub(crate) cx: &'p mut AttributeParser<'sess>,674 /// The span of the syntactical component this attribute was applied to675 pub(crate) target_span: Span,676 pub(crate) target: rustc_hir::Target,677678 pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, EmitAttribute),679}680681/// Context given to every attribute parser during finalization.682///683/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create684/// errors, for example.685pub(crate) struct FinalizeContext<'p, 'sess> {686 pub(crate) shared: SharedContext<'p, 'sess>,687688 /// A list of all attribute on this syntax node.689 ///690 /// Useful for compatibility checks with other attributes in [`finalize`](crate::attributes::AttributeParser::finalize)691 ///692 /// Usually, you should use normal attribute parsing logic instead,693 /// especially when making a *denylist* of other attributes.694 pub(crate) all_attrs: &'p [RefPathParser<'p>],695}696697impl<'p, 'sess: 'p> Deref for FinalizeContext<'p, 'sess> {698 type Target = SharedContext<'p, 'sess>;699700 fn deref(&self) -> &Self::Target {701 &self.shared702 }703}704705impl<'p, 'sess: 'p> DerefMut for FinalizeContext<'p, 'sess> {706 fn deref_mut(&mut self) -> &mut Self::Target {707 &mut self.shared708 }709}710711impl<'p, 'sess: 'p> Deref for SharedContext<'p, 'sess> {712 type Target = AttributeParser<'sess>;713714 fn deref(&self) -> &Self::Target {715 self.cx716 }717}718719impl<'p, 'sess: 'p> DerefMut for SharedContext<'p, 'sess> {720 fn deref_mut(&mut self) -> &mut Self::Target {721 self.cx722 }723}724725#[derive(PartialEq, Clone, Copy, Debug)]726pub enum OmitDoc {727 Lower,728 Skip,729}730731#[derive(Copy, Clone, Debug)]732pub enum ShouldEmit {733 /// The operations will emit errors, and lints, and errors are fatal.734 ///735 /// Only relevant when early parsing, in late parsing equivalent to `ErrorsAndLints`.736 /// Late parsing is never fatal, and instead tries to emit as many diagnostics as possible.737 EarlyFatal { also_emit_lints: bool },738 /// The operation will emit errors and lints.739 /// This is usually what you need.740 ErrorsAndLints {741 /// Whether [`ArgParser`] will attempt to recover from errors.742 ///743 /// Whether it is allowed to recover from bad input (like an invalid literal). Setting744 /// this to `Forbidden` will instead return early, and not raise errors except at the top745 /// level (in [`ArgParser::from_attr_args`]).746 recovery: Recovery,747 },748 /// The operation will *not* emit errors and lints.749 ///750 /// The parser can still call `delay_bug`, so you *must* ensure that this operation will also be751 /// called with `ShouldEmit::ErrorsAndLints`.752 Nothing,753}754755impl ShouldEmit {756 pub(crate) fn emit_err(&self, diag: Diag<'_>) -> ErrorGuaranteed {757 match self {758 ShouldEmit::EarlyFatal { .. } if diag.level() == Level::DelayedBug => diag.emit(),759 ShouldEmit::EarlyFatal { .. } => diag.upgrade_to_fatal().emit(),760 ShouldEmit::ErrorsAndLints { .. } => diag.emit(),761 ShouldEmit::Nothing => diag.delay_as_bug(),762 }763 }764}765766pub(crate) struct AttributeDiagnosticContext<'a, 'f, 'sess> {767 ctx: &'a mut AcceptContext<'f, 'sess>,768 custom_suggestions: Vec<Suggestion>,769}770771impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {772 fn emit_parse_error(773 &mut self,774 span: Span,775 reason: AttributeParseErrorReason<'_>,776 ) -> ErrorGuaranteed {777 let suggestions = if !self.custom_suggestions.is_empty() {778 AttributeParseErrorSuggestions::CreatedByParser(mem::take(&mut self.custom_suggestions))779 } else {780 AttributeParseErrorSuggestions::CreatedByTemplate(self.template_suggestions())781 };782783 self.emit_err(AttributeParseError {784 span,785 attr_span: self.attr_span,786 template: self.template.clone(),787 path: self.attr_path.clone(),788 description: self.parsed_description,789 reason,790 suggestions,791 })792 }793794 /// Adds a custom suggestion to the diagnostic. This also prevents the default (template-based)795 /// suggestion to be emitted.796 pub(crate) fn push_suggestion(&mut self, msg: String, span: Span, code: String) -> &mut Self {797 self.custom_suggestions.push(Suggestion { msg, sp: span, code });798 self799 }800801 pub(crate) fn template_suggestions(&self) -> Vec<String> {802 let style = match self.parsed_description {803 // If the outer and inner spans are equal, we are parsing an embedded attribute804 ParsedDescription::Attribute if self.attr_span == self.inner_span => {805 AttrSuggestionStyle::EmbeddedAttribute806 }807 ParsedDescription::Attribute => AttrSuggestionStyle::Attribute(self.attr_style),808 ParsedDescription::Macro => AttrSuggestionStyle::Macro,809 };810811 self.template.suggestions(style, &self.attr_path)812 }813}814815/// Helpers that can be used to generate errors during attribute parsing.816impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {817 pub(crate) fn expected_integer_literal_in_range(818 &mut self,819 span: Span,820 lower_bound: isize,821 upper_bound: isize,822 ) -> ErrorGuaranteed {823 self.emit_parse_error(824 span,825 AttributeParseErrorReason::ExpectedIntegerLiteralInRange { lower_bound, upper_bound },826 )827 }828829 /// The provided span is used as a fallback in case `args` does not contain any. It should be830 /// the span of the node that contains `args`.831 pub(crate) fn expected_list(&mut self, span: Span, args: &ArgParser) -> ErrorGuaranteed {832 let span = match args {833 ArgParser::NoArgs => span,834 ArgParser::List(list) => list.span,835 ArgParser::NameValue(nv) => nv.args_span(),836 };837 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedList)838 }839840 pub(crate) fn expected_list_with_num_args_or_more(841 &mut self,842 args: usize,843 span: Span,844 ) -> ErrorGuaranteed {845 self.emit_parse_error(846 span,847 AttributeParseErrorReason::ExpectedListWithNumArgsOrMore { args },848 )849 }850851 pub(crate) fn expected_list_or_no_args(&mut self, span: Span) -> ErrorGuaranteed {852 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedListOrNoArgs)853 }854855 pub(crate) fn expected_nv_or_no_args(&mut self, span: Span) -> ErrorGuaranteed {856 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNameValueOrNoArgs)857 }858859 pub(crate) fn expected_non_empty_string_literal(&mut self, span: Span) -> ErrorGuaranteed {860 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNonEmptyStringLiteral)861 }862863 pub(crate) fn expected_no_args(&mut self, span: Span) -> ErrorGuaranteed {864 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNoArgs)865 }866867 /// Emit an error that a `name` was expected here868 pub(crate) fn expected_identifier(&mut self, span: Span) -> ErrorGuaranteed {869 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIdentifier)870 }871872 /// Emit an error that a `name = value` pair was expected at this span. The symbol can be given for873 /// a nicer error message talking about the specific name that was found lacking a value.874 fn expected_name_value(&mut self, span: Span, name: Option<Symbol>) -> ErrorGuaranteed {875 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNameValue(name))876 }877878 /// Emit an error that a `name = value` argument is missing in a list of name-value pairs.879 pub(crate) fn missing_name_value(&mut self, span: Span, name: Symbol) -> ErrorGuaranteed {880 self.emit_parse_error(span, AttributeParseErrorReason::MissingNameValue(name))881 }882883 /// Emit an error that a `name = value` pair was found where that name was already seen.884 pub(crate) fn duplicate_key(&mut self, span: Span, key: Symbol) -> ErrorGuaranteed {885 self.emit_parse_error(span, AttributeParseErrorReason::DuplicateKey(key))886 }887888 /// An error that should be emitted when a [`MetaItemOrLitParser`]889 /// was expected *not* to be a literal, but instead a meta item.890 pub(crate) fn expected_not_literal(&mut self, span: Span) -> ErrorGuaranteed {891 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNotLiteral)892 }893894 /// Signals that we expected exactly one argument and that we got either zero or two or more.895 /// The `provided_arguments` argument allows distinguishing between "expected an argument here"896 /// (when zero arguments are provided) and "expect a single argument here" (when two or more897 /// arguments are provided).898 pub(crate) fn expected_single_argument(899 &mut self,900 span: Span,901 provided_arguments: usize,902 ) -> ErrorGuaranteed {903 let reason = if provided_arguments == 0 {904 AttributeParseErrorReason::ExpectedArgument905 } else {906 AttributeParseErrorReason::ExpectedSingleArgument907 };908909 self.emit_parse_error(span, reason)910 }911912 pub(crate) fn expected_at_least_one_argument(&mut self, span: Span) -> ErrorGuaranteed {913 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedAtLeastOneArgument)914 }915916 /// Produces an error along the lines of `expected one of [foo, meow]`917 pub(crate) fn expected_specific_argument(918 &mut self,919 span: Span,920 possibilities: &[Symbol],921 ) -> ErrorGuaranteed {922 self.emit_parse_error(923 span,924 AttributeParseErrorReason::ExpectedSpecificArgument {925 possibilities,926 strings: false,927 list: false,928 },929 )930 }931932 /// Produces an error along the lines of `expected one of [foo, meow] as an argument`.933 /// i.e. slightly different wording to [`expected_specific_argument`](Self::expected_specific_argument).934 pub(crate) fn expected_specific_argument_and_list(935 &mut self,936 span: Span,937 possibilities: &[Symbol],938 ) -> ErrorGuaranteed {939 self.emit_parse_error(940 span,941 AttributeParseErrorReason::ExpectedSpecificArgument {942 possibilities,943 strings: false,944 list: true,945 },946 )947 }948949 /// produces an error along the lines of `expected one of ["foo", "meow"]`950 pub(crate) fn expected_specific_argument_strings(951 &mut self,952 span: Span,953 possibilities: &[Symbol],954 ) -> ErrorGuaranteed {955 self.emit_parse_error(956 span,957 AttributeParseErrorReason::ExpectedSpecificArgument {958 possibilities,959 strings: true,960 list: false,961 },962 )963 }964965 pub(crate) fn warn_empty_attribute(&mut self, span: Span) {966 let attr_path = self.attr_path.to_string();967 let valid_without_list = self.template.word;968 self.emit_lint(969 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,970 crate::errors::EmptyAttributeList { attr_span: span, attr_path, valid_without_list },971 span,972 );973 }974975 pub(crate) fn warn_ill_formed_attribute_input(&mut self, lint: &'static Lint) {976 self.warn_ill_formed_attribute_input_with_help(lint, None)977 }978 pub(crate) fn warn_ill_formed_attribute_input_with_help(979 &mut self,980 lint: &'static Lint,981 help: Option<String>,982 ) {983 let suggestions = self.suggestions();984 let span = self.attr_span;985 self.emit_lint(986 lint,987 crate::errors::IllFormedAttributeInput::new(&suggestions, None, help.as_deref()),988 span,989 );990 }991992 pub(crate) fn suggestions(&self) -> Vec<String> {993 let style = match self.parsed_description {994 // If the outer and inner spans are equal, we are parsing an embedded attribute995 ParsedDescription::Attribute if self.attr_span == self.inner_span => {996 AttrSuggestionStyle::EmbeddedAttribute997 }998 ParsedDescription::Attribute => AttrSuggestionStyle::Attribute(self.attr_style),999 ParsedDescription::Macro => AttrSuggestionStyle::Macro,1000 };10011002 self.template.suggestions(style, &self.attr_path)1003 }1004 /// Error that a string literal was expected.1005 /// You can optionally give the literal you did find (which you found not to be a string literal)1006 /// which can make better errors. For example, if the literal was a byte string it will suggest1007 /// removing the `b` prefix.1008 pub(crate) fn expected_string_literal(1009 &mut self,1010 span: Span,1011 actual_literal: Option<&MetaItemLit>,1012 ) -> ErrorGuaranteed {1013 self.emit_parse_error(1014 span,1015 AttributeParseErrorReason::ExpectedStringLiteral {1016 byte_string: actual_literal.and_then(|i| {1017 i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))1018 }),1019 },1020 )1021 }10221023 /// Error that a filename string literal was expected.1024 pub(crate) fn expected_filename_literal(&mut self, span: Span) {1025 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedFilenameLiteral);1026 }10271028 pub(crate) fn expected_integer_literal(&mut self, span: Span) -> ErrorGuaranteed {1029 self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIntegerLiteral)1030 }1031}10321033impl<'a, 'f, 'sess: 'f> Deref for AttributeDiagnosticContext<'a, 'f, 'sess> {1034 type Target = AcceptContext<'f, 'sess>;10351036 fn deref(&self) -> &Self::Target {1037 self.ctx1038 }1039}10401041impl<'a, 'f, 'sess: 'f> DerefMut for AttributeDiagnosticContext<'a, 'f, 'sess> {1042 fn deref_mut(&mut self) -> &mut Self::Target {1043 self.ctx1044 }1045}10461047/// Represents a custom suggestion that an attribute parser can emit.1048pub(crate) struct Suggestion {1049 pub(crate) msg: String,1050 pub(crate) sp: Span,1051 pub(crate) code: String,1052}
Code quality findings 64
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
pub(super) accepters: BTreeMap<&'static [Symbol], GroupTypeInnerAccept>,
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Gives [`AttributeParser`]s enough information to create errors, for example.
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Asserts that an [`ArgParser`] is a list and returns it, or emits an error and returns
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// This is a higher-level (and harder to misuse) wrapper over [`ArgParser::as_list`] that
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Asserts that a [`MetaItemListParser`] contains a single element and returns it, or emits an
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// This is a higher-level (and harder to misuse) wrapper over [`MetaItemListParser::as_single`],
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// [`parser`][crate::parser] module. You may still want to use the lower-level methods for the
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Assert that an [`ArgParser`] has no args, or emits an error and return `None`.
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Useful for compatibility checks with other attributes in [`finalize`](crate::attributes::AttributeParser::finalize)
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
pub(crate) all_attrs: &'p [RefPathParser<'p>],
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Whether [`ArgParser`] will attempt to recover from errors.
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// level (in [`ArgParser::from_attr_args`]).
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// An error that should be emitted when a [`MetaItemOrLitParser`]
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Produces an error along the lines of `expected one of [foo, meow]`
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// Produces an error along the lines of `expected one of [foo, meow] as an argument`.
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// i.e. slightly different wording to [`expected_specific_argument`](Self::expected_specific_argument).
Warning: Direct indexing (e.g., `vec[i]`, `slice[i]`) panics on out-of-bounds access. Prefer using `.get(index)` or `.get_mut(index)` which return Option<&T>/Option<&mut T>.
warning
correctness
unchecked-indexing
/// produces an error along the lines of `expected one of ["foo", "meow"]`
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::allow_unstable::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::autodiff::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::body::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::cfi_encoding::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::codegen_attrs::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::confusables::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::crate_level::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::debugger::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::deprecation::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::diagnostic::do_not_recommend::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::diagnostic::on_const::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::diagnostic::on_move::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::diagnostic::on_unimplemented::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::diagnostic::on_unknown::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::diagnostic::on_unmatch_args::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::doc::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::dummy::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::inline::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::instruction_set::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::link_attrs::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::lint_helpers::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::loop_match::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::macro_attrs::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::must_not_suspend::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::must_use::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::no_implicit_prelude::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::no_link::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::non_exhaustive::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::pin_v2::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::proc_macro_attrs::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::prototype::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::repr::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::rustc_allocator::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::rustc_dump::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::rustc_internal::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::semantics::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::stability::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::test_attrs::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::traits::*;
Info: Wildcard imports (`use some::path::*;`) can obscure the origin of names and lead to conflicts. Prefer importing specific items explicitly.
info
maintainability
wildcard-import
use crate::attributes::transparency::*;
Info: Usage of `#[allow(...)]` suppresses compiler lints. Ensure the allowance is justified, well-scoped, and ideally temporary. Overuse can hide potential issues.
info
maintainability
allow-lint
/// - In `#[allow(warnings)]`, `warnings` is returned
Info: Usage of `#[allow(...)]` suppresses compiler lints. Ensure the allowance is justified, well-scoped, and ideally temporary. Overuse can hide potential issues.
info
maintainability
allow-lint
/// - `#[allow(clippy::complexity)]`: `(clippy::complexity)` is a list