From 8aae7a7af74dbd3d6ca90234f75733e7311ad842 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Sat, 12 Sep 2026 11:48:45 +0300 Subject: [PATCH 01/13] Use attribute parser for `#[inline()]` attribute check --- .../rustc_attr_ir/src/encode_cross_crate.rs | 215 ++++++++++++++++++ .../src/attributes/allow_unstable.rs | 2 +- .../src/attributes/codegen_attrs.rs | 4 +- .../src/attributes/inline.rs | 27 ++- .../src/attributes/link_attrs.rs | 2 +- .../src/attributes/lint_helpers.rs | 2 +- .../src/attributes/macro_attrs.rs | 2 +- .../rustc_attr_parsing/src/attributes/mod.rs | 8 +- .../src/attributes/non_exhaustive.rs | 2 +- compiler/rustc_attr_parsing/src/context.rs | 2 +- .../rustc_attr_parsing/src/diagnostics.rs | 7 + compiler/rustc_attr_parsing/src/interface.rs | 2 +- .../src/middle/codegen_fn_attrs.rs | 4 +- compiler/rustc_passes/src/check_attr.rs | 34 +-- compiler/rustc_passes/src/diagnostics.rs | 7 - ...op.runtime-optimized.after.panic-abort.mir | 4 +- .../target-feature/invalid-attribute.stderr | 16 +- 17 files changed, 272 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_attr_ir/src/encode_cross_crate.rs b/compiler/rustc_attr_ir/src/encode_cross_crate.rs index 6f05f763f2ada..66fbbc1e3cbf7 100644 --- a/compiler/rustc_attr_ir/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_ir/src/encode_cross_crate.rs @@ -212,4 +212,219 @@ impl AttributeKind { // tidy-alphabetical-end } } + + /// Whether this attribute is an extern indicator. + /// + /// Must stay in sync with [`CodegenFnAttrs::contains_extern_indicator`]. + /// + /// [`CodegenFnAttrs::contains_extern_indicator`]: ../rustc_middle/middle/codegen_fn_attrs/struct.CodegenFnAttrs.html#method.contains_extern_indicator + pub fn is_extern_indicator(&self) -> bool { + use AttributeKind::*; + + match self { + // tidy-alphabetical-start + AllowInternalUnsafe(..) => false, + AllowInternalUnstable(..) => false, + AlwaysGca => false, + AutomaticallyDerived => false, + CfgAttrTrace(..) => false, + CfgTrace(..) => false, + CfiEncoding { .. } => false, + Cold => false, + CollapseDebugInfo(..) => false, + CompilerBuiltins => false, + ConstContinue(..) => false, + Coroutine => false, + Coverage(..) => false, + CrateName { .. } => false, + CrateType(_) => false, + CustomMir(_, _) => false, + DebuggerVisualizer(..) => false, + DefaultLibAllocator => false, + Deprecated { .. } => false, + DoNotRecommend => false, + Doc(_) => false, + DocComment { .. } => false, + EiiDeclaration(_) => false, + EiiImpl(..) => true, + ExportName { .. } => true, + ExportStable => false, + Feature(..) => false, + FfiConst => false, + FfiPure(..) => false, + Fundamental { .. } => false, + Ignore { .. } => false, + Inline(..) => false, + InstructionSet(..) => false, + InstrumentFn(..) => false, + Lang(item) => item.link_name().is_some(), + Link(..) => false, + LinkName { .. } => false, + LinkOrdinal { .. } => false, + LinkSection { .. } => false, + Linkage(linkage, _) => match *linkage { + crate::Linkage::Internal => false, + crate::Linkage::AvailableExternally + | crate::Linkage::Common + | crate::Linkage::External + | crate::Linkage::ExternalWeak + | crate::Linkage::LinkOnceAny + | crate::Linkage::LinkOnceODR + | crate::Linkage::WeakAny + | crate::Linkage::WeakODR => true, + }, + LoopMatch(..) => false, + MacroEscape => false, + MacroExport { .. } => false, + MacroUse { .. } => false, + Marker => false, + MayDangle(..) => false, + MoveSizeLimit { .. } => false, + MustNotSupend { .. } => false, + MustUse { .. } => false, + Naked(..) => false, + NeedsAllocator => false, + NeedsPanicRuntime => false, + NoBuiltins => false, + NoCore => false, + NoImplicitPrelude => false, + NoLink => false, + NoMain => false, + NoMangle(..) => true, + NoStd => false, + NonExhaustive(..) => false, + OnConst { .. } => false, + OnMove { .. } => false, + OnTypeError { .. } => false, + OnUnimplemented { .. } => false, + OnUnknown { .. } => false, + OnUnmatchedArgs { .. } => false, + Opaque => false, + Optimize(..) => false, + PanicRuntime => false, + PatchableFunctionEntry { .. } => false, + Path(..) => false, + PatternComplexityLimit { .. } => false, + PinV2(..) => false, + PreludeImport => false, + ProcMacro => false, + ProcMacroAttribute => false, + ProcMacroDerive { .. } => false, + ProfilerRuntime => false, + RecursionLimit { .. } => false, + ReexportTestHarnessMain(..) => false, + RegisterTool { .. } => false, + Repr { .. } => false, + RustcAbi { .. } => false, + RustcAlign { .. } => false, + RustcAllocator => false, + RustcAllocatorZeroed => false, + RustcAllocatorZeroedVariant { .. } => false, + RustcAllowConstFnUnstable(..) => false, + RustcAllowIncoherentImpl(..) => false, + RustcAllowLifetimeDependentSpecialization => false, + RustcAsPtr => false, + RustcAutodiff(..) => false, + RustcBodyStability { .. } => false, + RustcBuiltinMacro { .. } => false, + RustcCanonicalSymbol => false, + RustcCaptureAnalysis => false, + RustcCguTestAttr { .. } => false, + RustcClean { .. } => false, + RustcCoherenceIsCore => false, + RustcCoinductive => false, + RustcComptime(..) => false, + RustcConfusables { .. } => false, + RustcConstStability { .. } => false, + RustcConstStableIndirect => false, + RustcConversionSuggestion => false, + RustcDeallocator => false, + RustcDelayedBugFromInsideQuery => false, + RustcDenyExplicitImpl => false, + RustcDeprecatedSafe2024 { .. } => false, + RustcDiagnosticItem(..) => false, + RustcDoNotConstCheck => false, + RustcDocPrimitive(..) => false, + RustcDummy => false, + RustcDumpClauses => false, + RustcDumpDefParents => false, + RustcDumpDefPath(..) => false, + RustcDumpGenerics => false, + RustcDumpHiddenTypeOfOpaques => false, + RustcDumpInferredOutlives => false, + RustcDumpItemBounds => false, + RustcDumpLayout(..) => false, + RustcDumpObjectLifetimeDefaults => false, + RustcDumpSymbolName(..) => false, + RustcDumpUserArgs => false, + RustcDumpVariances => false, + RustcDumpVariancesOfOpaques => false, + RustcDumpVtable(..) => false, + RustcDynIncompatibleTrait(..) => false, + RustcEffectiveVisibility => false, + RustcEiiForeignItem => true, + RustcEvaluateWhereClauses => false, + RustcHasIncoherentInherentImpls => false, + RustcIfThisChanged(..) => false, + RustcInheritOverflowChecks => false, + RustcInsignificantDtor => false, + RustcIntrinsic => false, + RustcIntrinsicConstStableIndirect => false, + RustcLegacyConstGenerics { .. } => false, + RustcLintOptDenyFieldAccess { .. } => false, + RustcLintOptTy => false, + RustcLintQueryInstability => false, + RustcLintUntrackedQueryInformation => false, + RustcMacroTransparency(..) => false, + RustcMain => false, + RustcMir(..) => false, + RustcMustImplementOneOf { .. } => false, + RustcMustMatchExhaustively(..) => false, + RustcNeverReturnsNullPtr => false, + RustcNoImplicitAutorefs => false, + RustcNoImplicitBounds => false, + RustcNoMirInline => false, + RustcNoWritable => false, + RustcNonConstTraitMethod => false, + RustcNonnullOptimizationGuaranteed => false, + RustcNounwind => false, + RustcObjcClass { .. } => false, + RustcObjcSelector { .. } => false, + RustcOffloadKernel => true, + RustcPanicsWhenZero => false, + RustcParenSugar => false, + RustcPassByValue => false, + RustcPassIndirectlyInNonRusticAbis(..) => false, + RustcPreserveUbChecks => false, + RustcProcMacroDecls => false, + RustcPubTransparent(..) => false, + RustcReallocator => false, + RustcRegions => false, + RustcScalableVector { .. } => false, + RustcShouldNotBeCalledOnConstItems => false, + RustcSimdMonomorphizeLaneLimit(..) => false, + RustcSkipDuringMethodDispatch { .. } => false, + RustcSpecializationTrait => false, + RustcStdInternalSymbol => true, + RustcStrictCoherence(..) => false, + RustcTestMarker(..) => false, + RustcThenThisWouldNeed(..) => false, + RustcTrivialFieldReads => false, + Sanitize { .. } => false, + ShouldPanic { .. } => false, + Splat(..) => false, + Stability { .. } => false, + TargetFeature { .. } => false, + TestRunner(..) => false, + ThreadLocal => false, + TrackCaller(..) => false, + TypeLengthLimit { .. } => false, + Unroll(..) => false, + UnstableFeatureBound(..) => false, + UnstableRemoved(..) => false, + Used { .. } => false, + WindowsSubsystem(..) => false, + // tidy-alphabetical-end + } + } } diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 743d3c9b5e76e..42e5f0ca2add4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -30,7 +30,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser { .zip(iter::repeat(cx.attr_span)) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { check_macro_only(cx, attr_span); } } diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index bff7d7ad81cb9..2553829f8c5ce 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -349,7 +349,7 @@ impl NoArgsAttributeParser for TrackCallerParser { const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { match cx.target { Target::Fn => { // `#[track_caller]` is not valid on weak lang items because they are called via @@ -571,7 +571,7 @@ impl CombineAttributeParser for TargetFeatureParser { parse_tf_attribute(cx, args) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { // `#[target_feature]` is incompatible with lang item functions, // except on WASM where calling target-feature functions is safe (see #84988). if !cx.sess().target.is_like_wasm && !cx.sess().opts.actually_rustdoc { diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index f3e305ea266a1..b4a5c9da155c9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -1,9 +1,9 @@ -use rustc_attr_ir::{AttributeKind, InlineAttr, find_attr}; +use rustc_attr_ir::{Attribute, AttributeKind, InlineAttr, find_attr}; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::ILL_FORMED_ATTRIBUTE_INPUT; +use rustc_lint_defs::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNUSED_ATTRIBUTES}; use super::prelude::*; -use crate::diagnostics::InlineForceInlineConflict; +use crate::diagnostics::{InlineForceInlineConflict, InlineIgnoredForExported}; pub(crate) struct InlineParser; @@ -59,6 +59,25 @@ impl SingleAttributeParser for InlineParser { } } } + + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { + let exported = cx.parsed_attrs.iter().any(|attr| { + let Attribute::Parsed(kind) = attr else { return false }; + kind.is_extern_indicator() + }); + if matches!( + cx.target, + Target::Fn + | Target::Closure + | Target::Method( + MethodKind::Trait { body: true } | MethodKind::TraitImpl | MethodKind::Inherent, + ) + ) && !find_attr!(cx.parsed_attrs, Inline(InlineAttr::Never, _)) + && exported + { + cx.emit_lint(UNUSED_ATTRIBUTES, InlineIgnoredForExported, attr_span); + } + } } pub(crate) struct RustcForceInlineParser; @@ -94,7 +113,7 @@ impl SingleAttributeParser for RustcForceInlineParser { )) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { let Some(inline_span) = find_attr!(cx.parsed_attrs, Inline(attr, span) if !matches!(attr, InlineAttr::Force { .. }) => span) else { return; diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index a00e5af00c2eb..123cea41587f3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -584,7 +584,7 @@ impl NoArgsAttributeParser for FfiPureParser { const STABILITY: AttributeStability = unstable!(ffi_pure); const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { // `#[ffi_const]` functions cannot be `#[ffi_pure]`. if cx.all_attrs.iter().any(|a| a.word_is(sym::ffi_const)) { cx.emit_err(BothFfiConstAndPure { attr_span }); diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 4ead90af8d630..10e42ced30705 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -29,7 +29,7 @@ impl NoArgsAttributeParser for RustcPubTransparentParser { const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPubTransparent; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { // `#[rustc_pub_transparent]` may only be applied to `#[repr(transparent)]` types. let is_transparent = find_attr!( cx.parsed_attrs, diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index c9625521aec44..85aaeffec00d5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -140,7 +140,7 @@ impl NoArgsAttributeParser for AllowInternalUnsafeParser { const STABILITY: AttributeStability = unstable!(allow_internal_unsafe); const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span); - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { check_macro_only(cx, attr_span); } } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 242b4a73b06a6..8e47414f6c72a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -169,7 +169,7 @@ pub(crate) trait SingleAttributeParser: 'static { /// combinations. `attr_span` is the span of this attribute. /// /// Defaults to a no-op. - fn finalize_check(_cx: &FinalizeCheckContext<'_, '_>, _attr_span: Span) {} + fn finalize_check(_cx: &mut FinalizeCheckContext<'_, '_>, _attr_span: Span) {} } /// Use in combination with [`SingleAttributeParser`]. @@ -287,7 +287,7 @@ pub(crate) trait NoArgsAttributeParser: 'static { /// `attr_span` is the span of this attribute. /// /// Defaults to a no-op. - fn finalize_check(_cx: &FinalizeCheckContext<'_, '_>, _attr_span: Span) {} + fn finalize_check(_cx: &mut FinalizeCheckContext<'_, '_>, _attr_span: Span) {} } pub(crate) struct WithoutArgs(PhantomData); @@ -311,7 +311,7 @@ impl SingleAttributeParser for WithoutArgs { Some(T::CREATE(cx.attr_span)) } - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { T::finalize_check(cx, attr_span) } } @@ -355,7 +355,7 @@ pub(crate) trait CombineAttributeParser: 'static { /// `attr_span` is the span of the first attribute that was encountered. /// /// Defaults to a no-op. - fn finalize_check(_cx: &FinalizeCheckContext<'_, '_>, _attr_span: Span) {} + fn finalize_check(_cx: &mut FinalizeCheckContext<'_, '_>, _attr_span: Span) {} } /// Use in combination with [`CombineAttributeParser`]. diff --git a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs index 30fdadf95e4ce..2acba84956e67 100644 --- a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs +++ b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs @@ -21,7 +21,7 @@ impl NoArgsAttributeParser for NonExhaustiveParser { const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive; - fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) { + fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { if cx.target != Target::Struct { return; } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index f936f5aab8265..12170d9160213 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -102,7 +102,7 @@ pub(crate) type FinalizeFn = fn(&mut FinalizeContext<'_, '_>) -> FinalizeOutput; /// finalized, so it can inspect the fully parsed attributes via /// [`FinalizeCheckContext::parsed_attrs`]. The [`Span`] is the span of the attribute the /// check is associated with, used for diagnostics. -pub(crate) type FinalizeCheckFn = fn(&FinalizeCheckContext<'_, '_>, Span); +pub(crate) type FinalizeCheckFn = fn(&mut FinalizeCheckContext<'_, '_>, Span); /// The result of finalizing a single attribute parser. pub(crate) struct FinalizeOutput { diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index e5f49690f71dc..cc64586339667 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -896,6 +896,13 @@ pub(crate) struct InlineForceInlineConflict { pub inline_span: Span, } +#[derive(Diagnostic)] +#[diag("`#[inline]` is ignored on externally exported functions")] +#[help( + "externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`" +)] +pub(crate) struct InlineIgnoredForExported; + #[derive(Diagnostic)] #[diag("`#[ffi_const]` function cannot be `#[ffi_pure]`", code = E0757)] pub(crate) struct BothFfiConstAndPure { diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 1cecce8fd43ef..48d57d7210ca3 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -512,7 +512,7 @@ impl<'sess> AttributeParser<'sess> { // inspect the fully parsed attributes via `FinalizeCheckContext::parsed_attrs`. for (check, attr_span) in deferred_checks { check( - &FinalizeCheckContext { + &mut FinalizeCheckContext { shared: SharedContext { cx: self, target_span, diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index f15dc1001fd95..fc5345b0b0b92 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -270,7 +270,9 @@ impl CodegenFnAttrs { /// * `#[export_name(...)]` is present /// * `#[linkage]` is present /// - /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint. + /// Keep this in sync with [`AttributeKind::is_extern_indicator`]. + /// + /// [`AttributeKind::is_extern_indicator`]: rustc_attr_ir::AttributeKind::is_extern_indicator pub fn contains_extern_indicator(&self) -> bool { if self.flags.contains(CodegenFnAttrFlags::FOREIGN_ITEM) { return false; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 79987b86385ef..5d5d1c2b54407 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -199,10 +199,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::ProcMacroDerive { .. } => { self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } - AttributeKind::Inline(InlineAttr::Force { .. }, ..) => {} // handled separately below - AttributeKind::Inline(kind, attr_span) => { - self.check_inline(hir_id, *attr_span, kind, target) - } AttributeKind::RustcAllowConstFnUnstable(_, first_span) => { self.check_rustc_allow_const_fn_unstable(hir_id, *first_span, span, target) } @@ -268,6 +264,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::FfiPure(..) => (), AttributeKind::Fundamental => (), AttributeKind::Ignore { .. } => (), + AttributeKind::Inline(..) => (), AttributeKind::InstructionSet(..) => (), AttributeKind::InstrumentFn(..) => (), AttributeKind::Lang(..) => (), @@ -740,35 +737,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if an `#[inline]` is applied to a function or a closure. - fn check_inline(&self, hir_id: HirId, attr_span: Span, kind: &InlineAttr, target: Target) { - match target { - Target::Fn - | Target::Closure - | Target::Method( - MethodKind::Trait { body: true } | MethodKind::TraitImpl | MethodKind::Inherent, - ) => { - // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported. - if let Some(did) = hir_id.as_owner() - && self.tcx.def_kind(did).has_codegen_attrs() - && kind != &InlineAttr::Never - { - let attrs = self.tcx.codegen_fn_attrs(did); - // Not checking naked as `#[inline]` is forbidden for naked functions anyways. - if attrs.contains_extern_indicator() { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr_span, - diagnostics::InlineIgnoredForExported, - ); - } - } - } - _ => {} - } - } - /// Checks if `#[naked]` is applied to a function definition. fn check_naked(&self, hir_id: HirId, target: Target) { match target { diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 55f8ac9a585de..2524171d98ab9 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -562,13 +562,6 @@ pub(crate) struct UselessAssignment<'a> { pub ty: Ty<'a>, } -#[derive(Diagnostic)] -#[diag("`#[inline]` is ignored on externally exported functions")] -#[help( - "externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`" -)] -pub(crate) struct InlineIgnoredForExported; - #[derive(Diagnostic)] #[diag("transparent {$target} cannot have other repr hints", code = E0692)] pub(crate) struct TransparentIncompatible { diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir index 549af7af4d888..b42087b5c822d 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.runtime-optimized.after.panic-abort.mir @@ -21,7 +21,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug x => _34; } scope 18 (inlined > as Iterator>::next) { - let mut _22: std::option::Option; + let mut _22: std::option::Option; let mut _27: std::option::Option<&T>; let mut _30: (usize, bool); let mut _31: (usize, &T); @@ -32,7 +32,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } scope 20 { scope 21 { - scope 27 (inlined as FromResidual>>::from_residual) { + scope 27 (inlined as FromResidual>>::from_residual) { let mut _21: isize; let mut _23: bool; } diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr index a1a69188bdbbd..1dc87bfe5bfb2 100644 --- a/tests/ui/target-feature/invalid-attribute.stderr +++ b/tests/ui/target-feature/invalid-attribute.stderr @@ -160,14 +160,6 @@ LL | #[target_feature(enable = "sse2")] | = help: the `target_feature` attribute can be applied to functions and methods -error: cannot use `#[inline(always)]` with `#[target_feature]` - --> $DIR/invalid-attribute.rs:69:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - | - = note: See this issue for full discussion: https://github.com/rust-lang/rust/issues/145574 - error: the feature named `foo` is not valid for this target --> $DIR/invalid-attribute.rs:27:18 | @@ -176,6 +168,14 @@ LL | #[target_feature(enable = "foo")] | = help: valid names are: `fma`, `xop`, `adx`, `aes`, and `avx` and X more +error: cannot use `#[inline(always)]` with `#[target_feature]` + --> $DIR/invalid-attribute.rs:69:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + | + = note: See this issue for full discussion: https://github.com/rust-lang/rust/issues/145574 + error[E0046]: not all trait items implemented, missing: `foo` --> $DIR/invalid-attribute.rs:81:1 | From 0dde9186493b43dc2bc4e87c03d5030f735c8697 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 21 Sep 2026 14:48:10 +0300 Subject: [PATCH 02/13] Deterministic def path hash map encoding --- Cargo.lock | 1 + compiler/rustc_hir_id/src/definitions.rs | 68 ++++++++++++++++++- compiler/rustc_interface/src/passes.rs | 2 + compiler/rustc_metadata/Cargo.toml | 1 + .../src/rmeta/def_path_hash_map.rs | 33 ++++++--- compiler/rustc_middle/src/ty/context.rs | 4 +- 6 files changed, 94 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e57835c9cfef..44c2db1e941a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4415,6 +4415,7 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_hir_pretty", "rustc_index", diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 50f7a15b19adf..a06e8336db2e4 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -8,6 +8,7 @@ use std::fmt::{self, Write}; use std::hash::Hash; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hash::StableHasher; use rustc_hashes::Hash64; use rustc_index::IndexVec; @@ -46,13 +47,68 @@ impl LocalDefIdMap { } } +/// Struct that contains two maps: `det_part` is used at the earlier stages of compilation +/// (see where `commit_end_of_determinism` is called, at the moment of writing +/// it is after prefetch of `hir_crate_items` in `run_required_analysis`), `non_det_part` is used +/// when def ids are allocated non-deterministically (in parallel compiler), +/// i.e., order of serialized pairs may be different. +/// In order to preserve deterministic output of the compiler we need to deterministically encode this map, so we use +/// `SortedMap` to store the mapping between local hashes and def indices, which gives us +/// deterministic iteration when encoding crate metadata. For encoding/decoding details see +/// `compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs`. +#[derive(Debug, Default)] +pub struct DefPathToIndexMap { + pub det_part: DefPathHashMap, + pub non_det_part: SortedMap, + non_det_mode: bool, +} + +impl DefPathToIndexMap { + #[inline] + pub fn get(&self, hash: &Hash64) -> Option { + match self.det_part.get(hash) { + Some(index) => Some(index), + None => { + if self.non_det_mode { + self.non_det_part.get(hash).copied() + } else { + None + } + } + } + } + + /// This insert function does not behave like regular `insert` of a `HashMap`, + /// as the return value is used only for printing information about existing + /// def index for local hash before panicking. So we can do not actually insert + /// def index into `det_part` when we are in non-deterministic mode. + #[inline] + pub fn insert(&mut self, hash: &Hash64, index: DefIndex) -> Option { + match self.non_det_mode { + false => self.det_part.insert(hash, &index), + true => { + if let Some(existing) = self.det_part.get(hash) { + return Some(existing); + } + + self.non_det_part.insert(*hash, index) + } + } + } + + #[inline] + pub fn switch_to_non_det_mode(&mut self) { + self.non_det_mode = true; + } +} + #[derive(Debug)] pub struct Definitions { stable_crate_id: StableCrateId, def_id_to_key: IndexVec, // We do only store the local hash, as all the definitions are from the current crate. def_path_hashes: IndexVec, - def_path_hash_to_index: DefPathHashMap, + def_path_hash_to_index: DefPathToIndexMap, } /// A unique identifier that we can use to lookup a definition @@ -249,6 +305,12 @@ pub enum DefPathData { } impl Definitions { + /// This function indicates that def ids allocations are non-deterministic after + /// it was called. + pub fn commit_end_of_determinism(&mut self) { + self.def_path_hash_to_index.switch_to_non_det_mode(); + } + #[inline(always)] pub fn def_key(&self, id: LocalDefId) -> DefKey { self.def_id_to_key[id] @@ -323,7 +385,7 @@ impl Definitions { // Check for hash collisions of DefPathHashes. These should be // exceedingly rare. if let Some(existing) = - self.def_path_hash_to_index.insert(&local_hash, &def_id.local_def_index) + self.def_path_hash_to_index.insert(&local_hash, def_id.local_def_index) { let def_path1 = self.def_path(LocalDefId { local_def_index: existing }); let def_path2 = self.def_path(def_id); @@ -415,7 +477,7 @@ impl Definitions { .map(|local_def_index| LocalDefId { local_def_index }) } - pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap { + pub fn def_path_hash_to_def_index_map(&self) -> &DefPathToIndexMap { &self.def_path_hash_to_index } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2316e80b6e945..8a3a149066e6a 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1099,6 +1099,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // to use `hir_crate_items`. tcx.ensure_done().hir_crate_items(()); + tcx.untracked().definitions.write().commit_end_of_determinism(); + rustc_passes::delegation::check_glob_and_list_delegations_target_expr(tcx); let sess = tcx.sess; diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index a2ef8454ed6a6..cbcbe4a2ac551 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -17,6 +17,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } rustc_fs_util = { path = "../rustc_fs_util" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 949d7630f6736..1092d56a331f6 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -1,5 +1,8 @@ use rustc_data_structures::owned_slice::OwnedSlice; -use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap}; +use rustc_data_structures::sorted_map::SortedMap; +use rustc_hashes::Hash64; +use rustc_hir::def_path_hash_map::Config as HashMapConfig; +use rustc_hir::definitions::DefPathToIndexMap; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_span::def_id::{DefIndex, DefPathHash}; @@ -7,8 +10,8 @@ use crate::rmeta::EncodeContext; use crate::rmeta::decoder::BlobDecodeContext; pub(crate) enum DefPathHashMapRef<'tcx> { - OwnedFromMetadata(odht::HashTable), - BorrowedFromTcx(&'tcx DefPathHashMap), + OwnedFromMetadata(odht::HashTable, SortedMap), + BorrowedFromTcx(&'tcx DefPathToIndexMap), } impl DefPathHashMapRef<'_> { @@ -17,8 +20,14 @@ impl DefPathHashMapRef<'_> { &self, def_path_hash: &DefPathHash, ) -> Option { - match *self { - DefPathHashMapRef::OwnedFromMetadata(ref map) => map.get(&def_path_hash.local_hash()), + match self { + DefPathHashMapRef::OwnedFromMetadata(det_map, non_det_map) => { + let hash = &def_path_hash.local_hash(); + match det_map.get(hash) { + Some(index) => Some(index), + None => non_det_map.get(hash).copied(), + } + } DefPathHashMapRef::BorrowedFromTcx(_) => { panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization") } @@ -29,12 +38,14 @@ impl DefPathHashMapRef<'_> { impl<'a, 'tcx> Encodable> for DefPathHashMapRef<'tcx> { fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) { match *self { - DefPathHashMapRef::BorrowedFromTcx(def_path_hash_map) => { - let bytes = def_path_hash_map.raw_bytes(); + DefPathHashMapRef::BorrowedFromTcx(map) => { + let bytes = map.det_part.raw_bytes(); e.emit_usize(bytes.len()); e.emit_raw_bytes(bytes); + + map.non_det_part.range(..).encode(e); } - DefPathHashMapRef::OwnedFromMetadata(_) => { + DefPathHashMapRef::OwnedFromMetadata(..) => { panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization") } } @@ -55,6 +66,10 @@ impl<'a> Decodable> for DefPathHashMapRef<'static> { let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| { panic!("decode error: {e}"); }); - DefPathHashMapRef::OwnedFromMetadata(inner) + + let elements = Vec::<(Hash64, DefIndex)>::decode(d); + let non_det_map = SortedMap::from_presorted_elements(elements); + + DefPathHashMapRef::OwnedFromMetadata(inner, non_det_map) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9d0b334b63fbd..d5cfaf570bafe 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1377,9 +1377,7 @@ impl<'tcx> TyCtxt<'tcx> { self.untracked.definitions.freeze() } - pub fn def_path_hash_to_def_index_map( - self, - ) -> &'tcx rustc_hir::def_path_hash_map::DefPathHashMap { + pub fn def_path_hash_to_def_index_map(self) -> &'tcx rustc_hir::definitions::DefPathToIndexMap { // Create a dependency to the crate to be sure we re-execute this when the amount of // definitions change. self.ensure_ok().hir_crate_items(()); From c57dbadb03995c00217b91306e416c5fc2de08d7 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 25 Sep 2026 08:40:20 +0300 Subject: [PATCH 03/13] Review: use Option instead of a bool flag, inline `switch_to_non_det_mode` --- compiler/rustc_hir_id/src/definitions.rs | 26 +++++-------------- .../src/rmeta/def_path_hash_map.rs | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index a06e8336db2e4..8f60f8ce3a01c 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -59,8 +59,7 @@ impl LocalDefIdMap { #[derive(Debug, Default)] pub struct DefPathToIndexMap { pub det_part: DefPathHashMap, - pub non_det_part: SortedMap, - non_det_mode: bool, + pub non_det_part: Option>, } impl DefPathToIndexMap { @@ -68,13 +67,7 @@ impl DefPathToIndexMap { pub fn get(&self, hash: &Hash64) -> Option { match self.det_part.get(hash) { Some(index) => Some(index), - None => { - if self.non_det_mode { - self.non_det_part.get(hash).copied() - } else { - None - } - } + None => self.non_det_part.as_ref().and_then(|map| map.get(hash).copied()), } } @@ -84,22 +77,17 @@ impl DefPathToIndexMap { /// def index into `det_part` when we are in non-deterministic mode. #[inline] pub fn insert(&mut self, hash: &Hash64, index: DefIndex) -> Option { - match self.non_det_mode { - false => self.det_part.insert(hash, &index), - true => { + match self.non_det_part.as_mut() { + None => self.det_part.insert(hash, &index), + Some(map) => { if let Some(existing) = self.det_part.get(hash) { return Some(existing); } - self.non_det_part.insert(*hash, index) + map.insert(*hash, index) } } } - - #[inline] - pub fn switch_to_non_det_mode(&mut self) { - self.non_det_mode = true; - } } #[derive(Debug)] @@ -308,7 +296,7 @@ impl Definitions { /// This function indicates that def ids allocations are non-deterministic after /// it was called. pub fn commit_end_of_determinism(&mut self) { - self.def_path_hash_to_index.switch_to_non_det_mode(); + self.def_path_hash_to_index.non_det_part = Some(Default::default()); } #[inline(always)] diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 1092d56a331f6..923c07cd764c9 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -43,7 +43,7 @@ impl<'a, 'tcx> Encodable> for DefPathHashMapRef<'tcx> { e.emit_usize(bytes.len()); e.emit_raw_bytes(bytes); - map.non_det_part.range(..).encode(e); + map.non_det_part.as_ref().unwrap_or(&Default::default()).range(..).encode(e); } DefPathHashMapRef::OwnedFromMetadata(..) => { panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization") From 1b504b3a0b30df3b18224def8e102f815901e3fa Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 25 Sep 2026 08:48:08 +0300 Subject: [PATCH 04/13] Review: use `or_else` instead of matches --- compiler/rustc_hir_id/src/definitions.rs | 7 +++---- compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs | 5 +---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 8f60f8ce3a01c..263ea4a026e2d 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -65,10 +65,9 @@ pub struct DefPathToIndexMap { impl DefPathToIndexMap { #[inline] pub fn get(&self, hash: &Hash64) -> Option { - match self.det_part.get(hash) { - Some(index) => Some(index), - None => self.non_det_part.as_ref().and_then(|map| map.get(hash).copied()), - } + self.det_part + .get(hash) + .or_else(|| self.non_det_part.as_ref().and_then(|map| map.get(hash).copied())) } /// This insert function does not behave like regular `insert` of a `HashMap`, diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 923c07cd764c9..7f625d59fa784 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -23,10 +23,7 @@ impl DefPathHashMapRef<'_> { match self { DefPathHashMapRef::OwnedFromMetadata(det_map, non_det_map) => { let hash = &def_path_hash.local_hash(); - match det_map.get(hash) { - Some(index) => Some(index), - None => non_det_map.get(hash).copied(), - } + det_map.get(hash).or_else(|| non_det_map.get(hash).copied()) } DefPathHashMapRef::BorrowedFromTcx(_) => { panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization") From 956cc84bae470d2a674a3e2a0f2f769173741e50 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Fri, 25 Sep 2026 08:53:18 +0300 Subject: [PATCH 05/13] Review: pass hash by value --- compiler/rustc_hir_id/src/definitions.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 263ea4a026e2d..d177630e7a8fc 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -64,10 +64,10 @@ pub struct DefPathToIndexMap { impl DefPathToIndexMap { #[inline] - pub fn get(&self, hash: &Hash64) -> Option { + pub fn get(&self, hash: Hash64) -> Option { self.det_part - .get(hash) - .or_else(|| self.non_det_part.as_ref().and_then(|map| map.get(hash).copied())) + .get(&hash) + .or_else(|| self.non_det_part.as_ref().and_then(|map| map.get(&hash).copied())) } /// This insert function does not behave like regular `insert` of a `HashMap`, @@ -75,15 +75,15 @@ impl DefPathToIndexMap { /// def index for local hash before panicking. So we can do not actually insert /// def index into `det_part` when we are in non-deterministic mode. #[inline] - pub fn insert(&mut self, hash: &Hash64, index: DefIndex) -> Option { + pub fn insert(&mut self, hash: Hash64, index: DefIndex) -> Option { match self.non_det_part.as_mut() { - None => self.det_part.insert(hash, &index), + None => self.det_part.insert(&hash, &index), Some(map) => { - if let Some(existing) = self.det_part.get(hash) { + if let Some(existing) = self.det_part.get(&hash) { return Some(existing); } - map.insert(*hash, index) + map.insert(hash, index) } } } @@ -372,7 +372,7 @@ impl Definitions { // Check for hash collisions of DefPathHashes. These should be // exceedingly rare. if let Some(existing) = - self.def_path_hash_to_index.insert(&local_hash, def_id.local_def_index) + self.def_path_hash_to_index.insert(local_hash, def_id.local_def_index) { let def_path1 = self.def_path(LocalDefId { local_def_index: existing }); let def_path2 = self.def_path(def_id); @@ -460,7 +460,7 @@ impl Definitions { pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option { debug_assert!(hash.stable_crate_id() == self.stable_crate_id); self.def_path_hash_to_index - .get(&hash.local_hash()) + .get(hash.local_hash()) .map(|local_def_index| LocalDefId { local_def_index }) } From 070652c2496168942d40541a19a0d0f4473ebbee Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 27 Sep 2026 21:34:33 +0000 Subject: [PATCH 06/13] remove `ast::MutTy` --- compiler/rustc_ast/src/ast.rs | 37 ++++++------------- .../rustc_ast/src/expand/autodiff_attrs.rs | 2 +- compiler/rustc_ast/src/util/classify.rs | 8 ++-- compiler/rustc_ast/src/visit.rs | 1 - compiler/rustc_ast_lowering/src/lib.rs | 25 ++++++++----- compiler/rustc_ast_pretty/src/pprust/state.rs | 20 +++++----- compiler/rustc_builtin_macros/src/autodiff.rs | 21 +++++++---- compiler/rustc_expand/src/build.rs | 8 +--- compiler/rustc_lint/src/unused.rs | 4 +- .../rustc_parse/src/parser/diagnostics.rs | 4 +- compiler/rustc_parse/src/parser/ty.rs | 16 ++++---- compiler/rustc_resolve/src/late.rs | 8 ++-- .../rustc_resolve/src/late/diagnostics.rs | 18 ++++----- .../src/needless_arbitrary_self_type.rs | 6 +-- .../src/redundant_static_lifetimes.rs | 10 ++--- .../clippy/clippy_utils/src/ast_utils/mod.rs | 10 ++--- .../clippy_utils/src/check_proc_macro.rs | 6 +-- src/tools/rustfmt/src/types.rs | 28 +++++++------- 18 files changed, 110 insertions(+), 122 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index bd1db99c3766b..6a86e9af71826 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -651,8 +651,8 @@ impl Pat { PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()), // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type. PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned { - Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }), - Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }), + Pinnedness::Not => TyKind::Ref(None, ty, *mutbl), + Pinnedness::Pinned => TyKind::PinnedRef(None, ty, *mutbl), })?, // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array, // when `P` can be reparsed as a type `T`. @@ -1507,7 +1507,7 @@ impl Expr { ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?, ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => { - expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))? + expr.to_ty().map(|ty| TyKind::Ref(None, ty, *mutbl))? } ExprKind::Repeat(expr, expr_len) => { @@ -2336,14 +2336,6 @@ impl LitKind { } } -// N.B., If you change this, you'll probably want to change the corresponding -// type structure in `middle/ty.rs` as well. -#[derive(Clone, Encodable, Decodable, Debug, Walkable)] -pub struct MutTy { - pub ty: Box, - pub mutbl: Mutability, -} - /// Represents a function's signature in a trait declaration, /// trait implementation, or free function. #[derive(Clone, Encodable, Decodable, Debug)] @@ -2470,8 +2462,7 @@ impl From> for Ty { impl Ty { pub fn peel_refs(&self) -> &Self { let mut final_ty = self; - while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind - { + while let TyKind::Ref(_, ty, _) | TyKind::Ptr(ty, ..) = &final_ty.kind { final_ty = ty; } final_ty @@ -2528,13 +2519,13 @@ pub enum TyKind { /// A fixed length array (`[T; n]`). Array(Box, AnonConst), /// A raw pointer (`*const T` or `*mut T`). - Ptr(MutTy), + Ptr(Box, Mutability), /// A reference (`&'a T` or `&'a mut T`). - Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option, MutTy), + Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option, Box, Mutability), /// A pinned reference (`&'a pin const T` or `&'a pin mut T`). /// /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`. - PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option, MutTy), + PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option, Box, Mutability), /// A function pointer type (e.g., `fn(usize) -> bool`). FnPtr(Box), /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`). @@ -2979,12 +2970,10 @@ impl Param { if ident.name == kw::SelfLower { return match self.ty.kind { TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), - TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { + TyKind::Ref(lt, ref ty, mutbl) if ty.kind.is_implicit_self() => { Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) } - TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }) - if ty.kind.is_implicit_self() => - { + TyKind::PinnedRef(lt, ref ty, mutbl) if ty.kind.is_implicit_self() => { Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl))) } _ => Some(respan( @@ -3016,17 +3005,13 @@ impl Param { SelfKind::Value(mutbl) => (mutbl, infer_ty), SelfKind::Region(lt, mutbl) => ( Mutability::Not, - Box::new(Ty { - id: DUMMY_NODE_ID, - kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }), - span, - }), + Box::new(Ty { id: DUMMY_NODE_ID, kind: TyKind::Ref(lt, infer_ty, mutbl), span }), ), SelfKind::Pinned(lt, mutbl) => ( Mutability::Not, Box::new(Ty { id: DUMMY_NODE_ID, - kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }), + kind: TyKind::PinnedRef(lt, infer_ty, mutbl), span, }), ), diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs index c9a3275c4c97f..9db7802f1739f 100644 --- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -160,7 +160,7 @@ pub fn valid_ty_for_activity(ty: &Box, activity: DiffActivity) -> bool { if matches!(activity, Active | ActiveOnly) { return true; } - matches!(ty.kind, TyKind::Ptr(_) | TyKind::Ref(..)) + matches!(ty.kind, TyKind::Ptr(..) | TyKind::Ref(..)) && matches!(activity, Duplicated | DuplicatedOnly) } pub fn valid_input_activity(mode: DiffMode, activity: DiffActivity) -> bool { diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index c4c181743543e..86a4073bd100f 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -262,10 +262,10 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { break (mac.args.delim == Delimiter::Brace).then_some(mac); } - ast::TyKind::Ptr(mut_ty) - | ast::TyKind::Ref(_, mut_ty) - | ast::TyKind::PinnedRef(_, mut_ty) => { - ty = &mut_ty.ty; + ast::TyKind::Ptr(inner_ty, _) + | ast::TyKind::Ref(_, inner_ty, _) + | ast::TyKind::PinnedRef(_, inner_ty, _) => { + ty = inner_ty; } ast::TyKind::UnsafeBinder(binder) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ec77de62607ce..e4813b9588409 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -542,7 +542,6 @@ macro_rules! common_visitor_and_walkers { MethodCall, ModKind, ModSpans, - MutTy, NormalAttr, Parens, ParenthesizedArgs, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4bc61a22b3b3d..395971fc4a36a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1527,14 +1527,14 @@ impl<'hir> LoweringContext<'_, 'hir> { TyKind::Infer => hir::TyKind::Infer(()), TyKind::Err(guar) => hir::TyKind::Err(*guar), TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)), - TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), - TyKind::Ref(region, mt) => { + TyKind::Ptr(ty, mutbl) => hir::TyKind::Ptr(self.lower_mt(ty, *mutbl, itctx)), + TyKind::Ref(region, ty, mutbl) => { let lifetime = self.lower_ty_direct_lifetime(t, *region); - hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx)) + hir::TyKind::Ref(lifetime, self.lower_mt(ty, *mutbl, itctx)) } - TyKind::PinnedRef(region, mt) => { + TyKind::PinnedRef(region, ty, mutbl) => { let lifetime = self.lower_ty_direct_lifetime(t, *region); - let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx)); + let kind = hir::TyKind::Ref(lifetime, self.lower_mt(ty, *mutbl, itctx)); let span = self.lower_span(t.span); let arg = hir::Ty { kind, span, hir_id: self.next_id() }; let args = self.arena.alloc(hir::GenericArgs { @@ -1998,10 +1998,10 @@ impl<'hir> LoweringContext<'_, 'hir> { // Given we are only considering `ImplicitSelf` types, we needn't consider // the case where we have a mutable pattern to a reference as that would // no longer be an `ImplicitSelf`. - TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt) - if mt.ty.kind.is_implicit_self() => + TyKind::Ref(_, ty, mutbl) | TyKind::PinnedRef(_, ty, mutbl) + if ty.kind.is_implicit_self() => { - match mt.mutbl { + match mutbl { hir::Mutability::Not => hir::ImplicitSelfKind::RefImm, hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut, } @@ -2473,8 +2473,13 @@ impl<'hir> LoweringContext<'_, 'hir> { .emit(); } - fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { - hir::MutTy { ty: self.lower_ty_alloc(&mt.ty, itctx), mutbl: mt.mutbl } + fn lower_mt( + &mut self, + ty: &Ty, + mutbl: Mutability, + itctx: ImplTraitContext, + ) -> hir::MutTy<'hir> { + hir::MutTy { ty: self.lower_ty_alloc(ty, itctx), mutbl } } #[instrument(level = "debug", skip(self), ret)] diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3ec9fdef4b0e6..b76502814dbb7 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1346,20 +1346,23 @@ impl<'a> State<'a> { self.print_type(ty); self.word("]"); } - ast::TyKind::Ptr(mt) => { + ast::TyKind::Ptr(ty, mutbl) => { self.word("*"); - self.print_mt(mt, true); + self.print_mutability(*mutbl, true); + self.print_type(ty); } - ast::TyKind::Ref(lifetime, mt) => { + ast::TyKind::Ref(lifetime, ty, mutbl) => { self.word("&"); self.print_opt_lifetime(lifetime); - self.print_mt(mt, false); + self.print_mutability(*mutbl, false); + self.print_type(ty); } - ast::TyKind::PinnedRef(lifetime, mt) => { + ast::TyKind::PinnedRef(lifetime, ty, mutbl) => { self.word("&"); self.print_opt_lifetime(lifetime); self.word("pin "); - self.print_mt(mt, true); + self.print_mutability(*mutbl, true); + self.print_type(ty); } ast::TyKind::Never => { self.word("!"); @@ -2229,11 +2232,6 @@ impl<'a> State<'a> { } } - fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) { - self.print_mutability(mt.mutbl, print_const); - self.print_type(&mt.ty) - } - fn print_param(&mut self, input: &ast::Param, is_closure: bool) { let ib = self.ibox(INDENT_UNIT); diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 083d05d03a070..21f424836e476 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -473,11 +473,11 @@ mod llvm_enzyme { fn assure_mut_ref(ty: &ast::Ty) -> ast::Ty { let mut ty = ty.clone(); match ty.kind { - TyKind::Ptr(ref mut mut_ty) => { - mut_ty.mutbl = ast::Mutability::Mut; + TyKind::Ptr(_, ref mut mutbl) => { + *mutbl = ast::Mutability::Mut; } - TyKind::Ref(_, ref mut mut_ty) => { - mut_ty.mutbl = ast::Mutability::Mut; + TyKind::Ref(_, _, ref mut mutbl) => { + *mutbl = ast::Mutability::Mut; } _ => { panic!("unsupported type: {:?}", ty); @@ -510,10 +510,15 @@ mod llvm_enzyme { .map(|param| { let ty = match ¶m.ty.kind { TyKind::ImplicitSelf => self_ty(), - TyKind::Ref(lt, mt) if matches!(mt.ty.kind, TyKind::ImplicitSelf) => ecx - .ty(span, TyKind::Ref(*lt, ast::MutTy { ty: self_ty(), mutbl: mt.mutbl })), - TyKind::Ptr(mt) if matches!(mt.ty.kind, TyKind::ImplicitSelf) => { - ecx.ty(span, TyKind::Ptr(ast::MutTy { ty: self_ty(), mutbl: mt.mutbl })) + TyKind::Ref(lt, inner_ty, mutbl) + if matches!(inner_ty.kind, TyKind::ImplicitSelf) => + { + ecx.ty(span, TyKind::Ref(*lt, self_ty(), *mutbl)) + } + TyKind::Ptr(inner_ty, mutbl) + if matches!(inner_ty.kind, TyKind::ImplicitSelf) => + { + ecx.ty(span, TyKind::Ptr(self_ty(), *mutbl)) } _ => param.ty.clone(), }; diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 34d4343ba9ba0..2a4089b1213ab 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -77,10 +77,6 @@ impl<'a> ExtCtxt<'a> { }) } - pub fn ty_mt(&self, ty: Box, mutbl: ast::Mutability) -> ast::MutTy { - ast::MutTy { ty, mutbl } - } - pub fn ty(&self, span: Span, kind: ast::TyKind) -> Box { Box::new(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind }) } @@ -127,11 +123,11 @@ impl<'a> ExtCtxt<'a> { lifetime: Option, mutbl: ast::Mutability, ) -> Box { - self.ty(span, ast::TyKind::Ref(lifetime, self.ty_mt(ty, mutbl))) + self.ty(span, ast::TyKind::Ref(lifetime, ty, mutbl)) } pub fn ty_ptr(&self, span: Span, ty: Box, mutbl: ast::Mutability) -> Box { - self.ty(span, ast::TyKind::Ptr(self.ty_mt(ty, mutbl))) + self.ty(span, ast::TyKind::Ptr(ty, mutbl)) } pub fn ty_unit(&self, span: Span) -> Box { diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index e2dff59a92990..361d1768087ea 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1000,7 +1000,7 @@ impl EarlyLintPass for UnusedParens { self.with_self_ty_parens = false; } - ast::TyKind::Ref(_, mut_ty) | ast::TyKind::Ptr(mut_ty) => { + ast::TyKind::Ref(_, inner_ty, _) | ast::TyKind::Ptr(inner_ty, _) => { // If this type itself appears in no-bounds position, we propagate its // potentially tighter constraint or risk a false posive (issue 143653). let own_constraint = self.in_no_bounds_pos.get(&ty.id); @@ -1009,7 +1009,7 @@ impl EarlyLintPass for UnusedParens { Some(NoBoundsException::OneBound) => NoBoundsException::OneBound, None => NoBoundsException::OneBound, }; - self.in_no_bounds_pos.insert(mut_ty.ty.id, constraint); + self.in_no_bounds_pos.insert(inner_ty.id, constraint); } ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => { for i in 0..bounds.len() { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index e7073a4d81978..fd4d012ebe2f9 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1562,8 +1562,8 @@ impl<'a> Parser<'a> { self.bump(); // `+` let _bounds = self.parse_generic_bounds()?; let sub = match &ty.kind { - TyKind::Ref(_lifetime, mut_ty) => { - let lo = mut_ty.ty.span.shrink_to_lo(); + TyKind::Ref(_lifetime, inner_ty, _) => { + let lo = inner_ty.span.shrink_to_lo(); let hi = self.prev_token.span.shrink_to_hi(); BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } } } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 5450d23fbbc2e..29b83e006d195 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,9 +2,9 @@ use rustc_ast::token::{self, IdentKind, MetaVarKind, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnPtrTy, FnRetTy, - GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, - Path, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, - Ty, TyKind, UnsafeBinderTy, + GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, Mutability, Path, + Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, + TyKind, UnsafeBinderTy, }; use rustc_errors::{Applicability, Diag, E0516, PResult}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; @@ -565,7 +565,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ); err.emit(); - Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl })) + Ok(TyKind::Ref(Some(lt), ty, mutbl)) } Err(diag) => { diag.cancel(); @@ -626,7 +626,7 @@ impl<'a> Parser<'a> { ) .emit(); - return Ok(TyKind::Ptr(MutTy { ty, mutbl })); + return Ok(TyKind::Ptr(ty, mutbl)); } // This is unreachable because we always get into if above and return from it unreachable!("this could never happen") @@ -643,7 +643,7 @@ impl<'a> Parser<'a> { Mutability::Not }); let ty = self.parse_ty_no_plus()?; - Ok(TyKind::Ptr(MutTy { ty, mutbl })) + Ok(TyKind::Ptr(ty, mutbl)) } /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type. @@ -761,8 +761,8 @@ impl<'a> Parser<'a> { } let ty = self.parse_ty_no_plus()?; Ok(match pinned { - Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }), - Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }), + Pinnedness::Not => TyKind::Ref(opt_lifetime, ty, mutbl), + Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, ty, mutbl), }) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e1787eadf5fb9..8eb2aea8a2604 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -923,7 +923,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc let prev = self.diag_metadata.current_trait_object; let prev_ty = self.diag_metadata.current_type_path; match &ty.kind { - TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => { + TyKind::Ref(None, ..) | TyKind::PinnedRef(None, ..) => { // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with // NodeId `ty.id`. // This span will be used in case of elision failure. @@ -2116,8 +2116,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { type Result = ControlFlow; fn visit_ty(&mut self, ty: &'ast ast::Ty) -> Self::Result { - if let ast::TyKind::Ref(None, mut_ty) = &ty.kind { - return ControlFlow::Break(mut_ty.ty.span.shrink_to_lo()); + if let ast::TyKind::Ref(None, inner_ty, _) = &ty.kind { + return ControlFlow::Break(inner_ty.span.shrink_to_lo()); } visit::walk_ty(self, ty) } @@ -2656,7 +2656,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &'ra Ty) { trace!("FindReferenceVisitor considering ty={:?}", ty); - if let TyKind::Ref(lt, _) | TyKind::PinnedRef(lt, _) = ty.kind { + if let TyKind::Ref(lt, ..) | TyKind::PinnedRef(lt, ..) = ty.kind { // See if anything inside the &thing contains Self let mut visitor = SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false }; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index cdef92b389265..700226a5c2207 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2924,7 +2924,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn extract_node_id(t: &Ty) -> Option { match t.kind { TyKind::Path(None, _) => Some(t.id), - TyKind::Ref(_, ref mut_ty) => extract_node_id(&mut_ty.ty), + TyKind::Ref(_, ref inner_ty, _) => extract_node_id(inner_ty), // This doesn't handle the remaining `Ty` variants as they are not // that commonly the self_type, it might be interesting to provide // support for those in future. @@ -4472,8 +4472,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .seen .iter() .filter_map(|ty| match &ty.kind { - TyKind::Ref(_, mut_ty) => { - let span = ty.span.with_hi(mut_ty.ty.span.lo()); + TyKind::Ref(_, inner_ty, _) => { + let span = ty.span.with_hi(inner_ty.span.lo()); Some((span, "&'a ".to_string())) } _ => None, @@ -4513,7 +4513,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut ret_lt_finder = LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] }; ret_lt_finder.visit_ty(ret_ty); - if let [Ty { span, kind: TyKind::Ref(_, mut_ty), .. }] = + if let [Ty { span, kind: TyKind::Ref(_, inner_ty, _), .. }] = &ret_lt_finder.seen[..] { // We might have a situation like @@ -4521,7 +4521,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // but `lt.span` only points at `'_`, so to suggest `-> Option<()>` // we need to find a more accurate span to end up with // fn g<'a>(mut x: impl Iterator) -> Option<()> - sugg = vec![(span.with_hi(mut_ty.ty.span.lo()), String::new())]; + sugg = vec![(span.with_hi(inner_ty.span.lo()), String::new())]; owned_sugg = true; } } @@ -4746,10 +4746,10 @@ struct LifetimeFinder<'ast> { impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> { fn visit_ty(&mut self, t: &'ast Ty) { - if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind { + if let TyKind::Ref(_, ty, _) | TyKind::PinnedRef(_, ty, _) = &t.kind { self.seen.push(t); if t.span.lo() == self.lifetime.lo() { - self.found = Some(&mut_ty.ty); + self.found = Some(ty); } } walk_ty(self, t) @@ -4766,10 +4766,10 @@ impl<'ast> Visitor<'ast> for RefPrefixSpanFinder { if self.span.is_some() { return; } - if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind + if let TyKind::Ref(_, inner_ty, _) | TyKind::PinnedRef(_, inner_ty, _) = &t.kind && t.span.lo() == self.lifetime.lo() { - self.span = Some(t.span.with_hi(mut_ty.ty.span.lo())); + self.span = Some(t.span.with_hi(inner_ty.span.lo())); return; } walk_ty(self, t); diff --git a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs index 5517228b6ef21..9d7b3c0d27224 100644 --- a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs +++ b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs @@ -74,11 +74,11 @@ impl EarlyLintPass for NeedlessArbitrarySelfType { TyKind::Path(None, path) if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind => { (path, Mode::Value, mutbl) }, - TyKind::Ref(lifetime, mut_ty) - if let TyKind::Path(None, path) = &mut_ty.ty.kind + TyKind::Ref(lifetime, ty, mutbl) + if let TyKind::Path(None, path) = &ty.kind && let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind => { - (path, Mode::Ref(*lifetime), mut_ty.mutbl) + (path, Mode::Ref(*lifetime), *mutbl) }, _ => return, }; diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs index 273ea7506431e..afbb8c0fa38d3 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs @@ -59,15 +59,15 @@ impl RedundantStaticLifetimes { } }, // This is what we are looking for ! - TyKind::Ref(ref optional_lifetime, ref borrow_type) => { + TyKind::Ref(ref optional_lifetime, ref borrow_type, mutbl) => { // Match the 'static lifetime if let Some(lifetime) = *optional_lifetime { - match borrow_type.ty.kind { + match borrow_type.kind { TyKind::Path(..) | TyKind::Slice(..) | TyKind::Array(..) | TyKind::Tup(..) if lifetime.ident.name == kw::StaticLifetime => { - let snip = snippet(cx, borrow_type.ty.span, ""); - let sugg = format!("&{}{snip}", borrow_type.mutbl.prefix_str()); + let snip = snippet(cx, borrow_type.span, ""); + let sugg = format!("&{}{snip}", mutbl.prefix_str()); span_lint_and_then(cx, REDUNDANT_STATIC_LIFETIMES, lifetime.ident.span, reason, |diag| { diag.span_suggestion( ty.span, @@ -80,7 +80,7 @@ impl RedundantStaticLifetimes { _ => {}, } } - Self::visit_type(&borrow_type.ty, cx, reason); + Self::visit_type(borrow_type, cx, reason); }, _ => {}, } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index 3c398d74ad7b4..0774fa729bc12 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -867,12 +867,12 @@ fn eq_ty(l: &Ty, r: &Ty) -> bool { }, (Slice(l), Slice(r)) => eq_ty(l, r), (Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value), - (Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty), - (Ref(ll, l), Ref(rl, r)) => { - both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) + (Ptr(l_ty, l_mutbl), Ptr(r_ty, r_mutbl)) => l_mutbl == r_mutbl && eq_ty(l_ty, r_ty), + (Ref(ll, l_ty, l_mutbl), Ref(rl, r_ty, r_mutbl)) => { + both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l_mutbl == r_mutbl && eq_ty(l_ty, r_ty) }, - (PinnedRef(ll, l), PinnedRef(rl, r)) => { - both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) + (PinnedRef(ll, l_ty, l_mutbl), PinnedRef(rl, r_ty, r_mutbl)) => { + both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l_mutbl == r_mutbl && eq_ty(l_ty, r_ty) }, (FnPtr(l), FnPtr(r)) => { l.safety == r.safety diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index baff6a99fc9e0..ca79f79403e7d 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -431,12 +431,12 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { } fn ast_ty_search_pat(ty: &ast::Ty) -> (Pat, Pat) { - use ast::{Extern, FnRetTy, MutTy, Safety, TraitObjectSyntax, TyKind}; + use ast::{Extern, FnRetTy, Safety, TraitObjectSyntax, TyKind}; match &ty.kind { TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str("["), Pat::Str("]")), - TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ast_ty_search_pat(ty).1), - TyKind::Ref(_, MutTy { ty, .. }) | TyKind::PinnedRef(_, MutTy { ty, .. }) => { + TyKind::Ptr(ty, ..) => (Pat::Str("*"), ast_ty_search_pat(ty).1), + TyKind::Ref(_, ty, ..) | TyKind::PinnedRef(_, ty, ..) => { (Pat::Str("&"), ast_ty_search_pat(ty).1) }, TyKind::FnPtr(fn_ptr) => ( diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index d119cd50c846a..fcf8321f18994 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -821,17 +821,17 @@ impl Rewrite for ast::Ty { } Ok(format!("{prefix}{res}")) } - ast::TyKind::Ptr(ref mt) => { - let prefix = match mt.mutbl { + ast::TyKind::Ptr(ref ty, mutbl) => { + let prefix = match mutbl { Mutability::Mut => "*mut ", Mutability::Not => "*const ", }; - rewrite_unary_prefix(context, prefix, &*mt.ty, shape) + rewrite_unary_prefix(context, prefix, &*ty, shape) } - ast::TyKind::Ref(ref lifetime, ref mt) - | ast::TyKind::PinnedRef(ref lifetime, ref mt) => { - let mut_str = format_mutability(mt.mutbl); + ast::TyKind::Ref(ref lifetime, ref ty, mutbl) + | ast::TyKind::PinnedRef(ref lifetime, ref ty, mutbl) => { + let mut_str = format_mutability(mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); result.push('&'); @@ -866,12 +866,12 @@ impl Rewrite for ast::Ty { if let ast::TyKind::PinnedRef(..) = self.kind { result.push_str("pin "); - if ast::Mutability::Not == mt.mutbl { + if ast::Mutability::Not == mutbl { result.push_str("const "); } } - if ast::Mutability::Mut == mt.mutbl { + if ast::Mutability::Mut == mutbl { let mut_hi = context.snippet_provider.span_after(self.span(), "mut"); let before_mut_span = mk_sp(cmnt_lo, mut_hi - BytePos::from_usize(3)); if contains_comment(context.snippet(before_mut_span)) { @@ -889,12 +889,12 @@ impl Rewrite for ast::Ty { cmnt_lo = mut_hi; } - let before_ty_span = mk_sp(cmnt_lo, mt.ty.span.lo()); + let before_ty_span = mk_sp(cmnt_lo, ty.span.lo()); if contains_comment(context.snippet(before_ty_span)) { result = combine_strs_with_missing_comments( context, result.trim_end(), - &mt.ty.rewrite_result(context, shape)?, + &ty.rewrite_result(context, shape)?, before_ty_span, shape, true, @@ -905,7 +905,7 @@ impl Rewrite for ast::Ty { .width .checked_sub(used_width) .max_width_error(shape.width, self.span())?; - let ty_str = mt.ty.rewrite_result( + let ty_str = ty.rewrite_result( context, Shape::legacy(budget, shape.indent + used_width), )?; @@ -1333,9 +1333,9 @@ pub(crate) fn can_be_overflowed_type( ) -> bool { match ty.kind { ast::TyKind::Tup(..) => context.use_block_indent() && len == 1, - ast::TyKind::Ref(_, ref mutty) - | ast::TyKind::PinnedRef(_, ref mutty) - | ast::TyKind::Ptr(ref mutty) => can_be_overflowed_type(context, &*mutty.ty, len), + ast::TyKind::Ref(_, ref ty, _) + | ast::TyKind::PinnedRef(_, ref ty, _) + | ast::TyKind::Ptr(ref ty, _) => can_be_overflowed_type(context, &*ty, len), _ => false, } } From ac6f00d948bb31cca5661405e1a96529a7477e75 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 28 Sep 2026 07:35:44 +0000 Subject: [PATCH 07/13] remove `hir::MutTy` --- compiler/rustc_ast_lowering/src/lib.rs | 15 +++---------- .../src/diagnostics/conflict_errors.rs | 6 ++--- .../src/diagnostics/mutability_errors.rs | 5 ++--- .../src/diagnostics/region_name.rs | 11 ++++++---- compiler/rustc_hir/src/hir.rs | 18 +++++---------- compiler/rustc_hir/src/hir/tests.rs | 2 +- compiler/rustc_hir/src/intravisit.rs | 6 ++--- .../src/coherence/builtin/coerce_shared.rs | 6 ++--- .../src/collect/resolve_bound_vars.rs | 4 ++-- .../src/hir_ty_lowering/mod.rs | 8 +++---- compiler/rustc_hir_pretty/src/lib.rs | 15 +++++-------- compiler/rustc_hir_typeck/src/demand.rs | 6 ++--- .../rustc_hir_typeck/src/method/suggest.rs | 5 ++--- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/dangling.rs | 2 +- .../rustc_lint/src/disallowed_pass_by_ref.rs | 2 +- compiler/rustc_lint/src/lifetime_syntax.rs | 4 ++-- compiler/rustc_lint/src/ptr_nulls.rs | 2 +- .../src/raw_borrows_via_references.rs | 2 +- compiler/rustc_mir_transform/src/liveness.rs | 6 ++--- .../rustc_trait_selection/src/diagnostics.rs | 2 +- .../infer/nice_region_error/find_anon_type.rs | 2 +- .../trait_impl_difference.rs | 4 ++-- .../src/error_reporting/traits/suggestions.rs | 18 +++++++-------- .../src/traits/dyn_compatibility.rs | 4 ++-- src/librustdoc/clean/mod.rs | 6 ++--- .../src/casts/as_pointer_underscore.rs | 2 +- .../clippy_lints/src/casts/borrow_as_ptr.rs | 4 ++-- .../src/casts/manual_dangling_ptr.rs | 12 +++++----- .../clippy_lints/src/casts/ptr_as_ptr.rs | 6 ++--- .../src/casts/ptr_cast_constness.rs | 4 ++-- .../clippy_lints/src/casts/ref_as_ptr.rs | 6 ++--- .../src/casts/unnecessary_cast.rs | 6 ++--- .../clippy/clippy_lints/src/casts/zero_ptr.rs | 8 +++---- .../clippy/clippy_lints/src/dereference.rs | 8 +++---- .../clippy_lints/src/functions/ref_option.rs | 2 +- .../src/iter_without_into_iter.rs | 4 ++-- .../src/methods/needless_collect.rs | 2 +- .../src/methods/should_implement_trait.rs | 2 +- src/tools/clippy/clippy_lints/src/mut_mut.rs | 22 +++++++++---------- .../src/needless_pass_by_ref_mut.rs | 4 ++-- .../clippy_lints/src/pass_by_ref_or_value.rs | 4 ++-- .../clippy_lints/src/ptr/mut_from_ref.rs | 4 ++-- .../clippy/clippy_lints/src/ptr/ptr_arg.rs | 4 ++-- .../src/redundant_type_annotations.rs | 8 +++---- .../clippy/clippy_lints/src/ref_option_ref.rs | 8 +++---- .../clippy/clippy_lints/src/trait_bounds.rs | 4 ++-- .../src/transmute/transmute_ptr_to_ref.rs | 4 ++-- .../clippy_lints/src/types/borrowed_box.rs | 14 ++++++++---- .../clippy/clippy_lints/src/types/mod.rs | 12 +++++----- .../src/unnecessary_literal_bound.rs | 4 ++-- .../clippy_utils/src/check_proc_macro.rs | 6 ++--- .../clippy/clippy_utils/src/hir_utils.rs | 18 +++++++-------- src/tools/clippy/clippy_utils/src/lib.rs | 6 ++--- src/tools/clippy/clippy_utils/src/sugg.rs | 7 +++--- 55 files changed, 171 insertions(+), 187 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 395971fc4a36a..e30fdfcebfdb8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1527,14 +1527,14 @@ impl<'hir> LoweringContext<'_, 'hir> { TyKind::Infer => hir::TyKind::Infer(()), TyKind::Err(guar) => hir::TyKind::Err(*guar), TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)), - TyKind::Ptr(ty, mutbl) => hir::TyKind::Ptr(self.lower_mt(ty, *mutbl, itctx)), + TyKind::Ptr(ty, mutbl) => hir::TyKind::Ptr(self.lower_ty_alloc(ty, itctx), *mutbl), TyKind::Ref(region, ty, mutbl) => { let lifetime = self.lower_ty_direct_lifetime(t, *region); - hir::TyKind::Ref(lifetime, self.lower_mt(ty, *mutbl, itctx)) + hir::TyKind::Ref(lifetime, self.lower_ty_alloc(ty, itctx), *mutbl) } TyKind::PinnedRef(region, ty, mutbl) => { let lifetime = self.lower_ty_direct_lifetime(t, *region); - let kind = hir::TyKind::Ref(lifetime, self.lower_mt(ty, *mutbl, itctx)); + let kind = hir::TyKind::Ref(lifetime, self.lower_ty_alloc(ty, itctx), *mutbl); let span = self.lower_span(t.span); let arg = hir::Ty { kind, span, hir_id: self.next_id() }; let args = self.arena.alloc(hir::GenericArgs { @@ -2473,15 +2473,6 @@ impl<'hir> LoweringContext<'_, 'hir> { .emit(); } - fn lower_mt( - &mut self, - ty: &Ty, - mutbl: Mutability, - itctx: ImplTraitContext, - ) -> hir::MutTy<'hir> { - hir::MutTy { ty: self.lower_ty_alloc(ty, itctx), mutbl } - } - #[instrument(level = "debug", skip(self), ret)] fn lower_param_bounds( &mut self, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2de98fd971bda..f7256968c8276 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -4600,7 +4600,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { // `return_region`. Then use the `rustc_hir` type to get only // the lifetime span. match &fn_decl.inputs[index].kind { - hir::TyKind::Ref(lifetime, _) => { + hir::TyKind::Ref(lifetime, ..) => { // With access to the lifetime, we can get // the span of it. arguments.push((*argument, lifetime.ident.span)); @@ -4615,7 +4615,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { .hir_node_by_def_id(alias_to) .expect_item() .expect_impl() - && let hir::TyKind::Ref(lifetime, _) = self_ty.kind + && let hir::TyKind::Ref(lifetime, ..) = self_ty.kind { arguments.push((*argument, lifetime.ident.span)); } @@ -4637,7 +4637,7 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { let return_ty = sig.output().skip_binder(); let mut return_span = fn_decl.output.span(); if let hir::FnRetTy::Return(ty) = &fn_decl.output - && let hir::TyKind::Ref(lifetime, _) = ty.kind + && let hir::TyKind::Ref(lifetime, ..) = ty.kind { return_span = lifetime.ident.span; } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 245e340a7d877..1182cdb5c2c6e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -927,8 +927,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { if let Node::TraitItem(ti) = self.infcx.tcx.hir_node_by_def_id(f_in_trait) && let hir::TraitItemKind::Fn(sig, _) = ti.kind && let Some(ty) = sig.decl.inputs.get(local.index() - 1) - && let hir::TyKind::Ref(_, mut_ty) = ty.kind - && let hir::Mutability::Not = mut_ty.mutbl + && let hir::TyKind::Ref(_, _, hir::Mutability::Not) = ty.kind && sig.decl.implicit_self().has_implicit_self() { Some(ty.span) @@ -2020,7 +2019,7 @@ fn get_mut_span_in_struct_field<'tcx>( // Now we're dealing with the actual struct that we're going to suggest a change to, // we can expect a field that is an immutable reference to a type. && let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.as_local()?) - && let hir::TyKind::Ref(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind + && let hir::TyKind::Ref(lt, ty, hir::Mutability::Not) = field.ty.kind { return Some(lt.ident.span.between(ty.span)); } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 9436d31ba19e8..871b974d28eea 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -621,7 +621,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // // & // - let's call the lifetime of this reference `'1` - (ty::Ref(region, referent_ty, _), hir::TyKind::Ref(_lifetime, referent_hir_ty)) => { + ( + ty::Ref(region, referent_ty, _), + hir::TyKind::Ref(_lifetime, referent_hir_ty, _), + ) => { if region.as_var() == needle_fr { // Just grab the first character, the `&`. let source_map = self.infcx.tcx.sess.source_map(); @@ -631,7 +634,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } // Otherwise, let's descend into the referent types. - search_stack.push((*referent_ty, referent_hir_ty.ty)); + search_stack.push((*referent_ty, referent_hir_ty)); } // Match up something like `Foo<'1>` @@ -669,8 +672,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { search_stack.push((*elem_ty, elem_hir_ty)); } - (ty::RawPtr(mut_ty, _), hir::TyKind::Ptr(mut_hir_ty)) => { - search_stack.push((*mut_ty, mut_hir_ty.ty)); + (ty::RawPtr(inner_ty, _), hir::TyKind::Ptr(hir_ty, _)) => { + search_stack.push((*inner_ty, hir_ty)); } _ => { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5cfce366bbb23..4f4ed83be06a3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2896,14 +2896,6 @@ impl fmt::Display for YieldSource { } } -// N.B., if you change this, you'll probably want to change the corresponding -// type structure in middle/ty.rs as well. -#[derive(Debug, Clone, Copy, StableHash)] -pub struct MutTy<'hir> { - pub ty: &'hir Ty<'hir>, - pub mutbl: Mutability, -} - /// Represents a function's signature in a trait declaration, /// trait implementation, or a free function. #[derive(Debug, Clone, Copy, StableHash)] @@ -3234,7 +3226,7 @@ impl<'hir> Ty<'hir> { impl<'hir> Ty<'hir, AmbigArg> { pub fn peel_refs(&self) -> &Ty<'hir> { let mut final_ty = self.as_unambig_ty(); - while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind { + while let TyKind::Ref(_, ty, _) = &final_ty.kind { final_ty = ty; } final_ty @@ -3244,7 +3236,7 @@ impl<'hir> Ty<'hir, AmbigArg> { impl<'hir> Ty<'hir> { pub fn peel_refs(&self) -> &Self { let mut final_ty = self; - while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind { + while let TyKind::Ref(_, ty, _) = &final_ty.kind { final_ty = ty; } final_ty @@ -3308,7 +3300,7 @@ impl<'hir> Ty<'hir> { ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..)) } TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty), - TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(), + TyKind::Ptr(ty, _) | TyKind::Ref(_, ty, _) => ty.is_suggestable_infer_ty(), TyKind::Path(QPath::TypeRelative(ty, segment)) => { ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args) } @@ -3577,9 +3569,9 @@ pub enum TyKind<'hir, Unambig = ()> { /// A fixed length array (i.e., `[T; n]`). Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>), /// A raw pointer (i.e., `*const T` or `*mut T`). - Ptr(MutTy<'hir>), + Ptr(&'hir Ty<'hir>, Mutability), /// A reference (i.e., `&'a T` or `&'a mut T`). - Ref(&'hir Lifetime, MutTy<'hir>), + Ref(&'hir Lifetime, &'hir Ty<'hir>, Mutability), /// A function pointer (e.g., `fn(usize) -> bool`). FnPtr(&'hir FnPtrTy<'hir>), /// An unsafe binder type (e.g. `unsafe<'a> Foo<'a>`). diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 2ac33a369cbdd..d267533ea3cb1 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -21,7 +21,7 @@ macro_rules! define_tests { define_tests! { cast_never TyKind Never {} cast_tup TyKind Tup { 0: &[Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }] } - cast_ptr TyKind Ptr { 0: MutTy { ty: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, mutbl: Mutability::Not }} + cast_ptr TyKind Ptr { 0: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, 1: Mutability::Not } cast_array TyKind Array { 0: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, 1: &ConstArg { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 5b7555cd73938..ad96fe492e6e7 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1027,10 +1027,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) - match *kind { TyKind::Slice(ref ty) => try_visit!(visitor.visit_ty_unambig(ty)), - TyKind::Ptr(ref mutable_type) => try_visit!(visitor.visit_ty_unambig(mutable_type.ty)), - TyKind::Ref(ref lifetime, ref mutable_type) => { + TyKind::Ptr(ref ty, _) => try_visit!(visitor.visit_ty_unambig(ty)), + TyKind::Ref(ref lifetime, ref ty, _) => { try_visit!(visitor.visit_lifetime(lifetime)); - try_visit!(visitor.visit_ty_unambig(mutable_type.ty)); + try_visit!(visitor.visit_ty_unambig(ty)); } TyKind::Never => {} TyKind::Tup(tuple_element_types) => { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs index 6546e2bf322c0..4d685ec3c6810 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs @@ -130,14 +130,14 @@ fn first_explicit_lifetime_span_in_ambig_ty(ty: &hir::Ty<'_, hir::AmbigArg>) -> fn first_explicit_lifetime_span_in_ty(ty: &hir::Ty<'_>) -> Option { match ty.kind { - hir::TyKind::Ref(lifetime, mut_ty) => first_explicit_lifetime_span(lifetime) - .or_else(|| first_explicit_lifetime_span_in_ty(mut_ty.ty)), + hir::TyKind::Ref(lifetime, ty, _) => first_explicit_lifetime_span(lifetime) + .or_else(|| first_explicit_lifetime_span_in_ty(ty)), hir::TyKind::Slice(ty) | hir::TyKind::Array(ty, _) | hir::TyKind::Pat(ty, _) | hir::TyKind::FieldOf(ty, _) | hir::TyKind::View(ty, _) => first_explicit_lifetime_span_in_ty(ty), - hir::TyKind::Ptr(mut_ty) => first_explicit_lifetime_span_in_ty(mut_ty.ty), + hir::TyKind::Ptr(ty, _) => first_explicit_lifetime_span_in_ty(ty), hir::TyKind::Tup(tys) => tys.iter().find_map(first_explicit_lifetime_span_in_ty), hir::TyKind::Path(qpath) => first_explicit_lifetime_span_in_qpath(qpath), hir::TyKind::TraitObject(bounds, lifetime) => bounds diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index a6cc61d2f7bfe..1dc6c1c96e93e 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -808,13 +808,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { LifetimeKind::Error(..) => {} } } - hir::TyKind::Ref(lifetime_ref, ref mt) => { + hir::TyKind::Ref(lifetime_ref, ref inner_ty, _) => { self.visit_lifetime(lifetime_ref); let scope = Scope::ObjectLifetimeDefault { lifetime: self.rbv.defs.get(&lifetime_ref.hir_id.local_id).copied(), s: self.scope, }; - self.with(scope, |this| this.visit_ty_unambig(mt.ty)); + self.with(scope, |this| this.visit_ty_unambig(inner_ty)); } hir::TyKind::TraitAscription(bounds) => { let scope = Scope::TraitRefBoundary { s: self.scope }; 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 e9dc2a61d698d..fe9a496f1200f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -3195,12 +3195,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let result_ty = match &hir_ty.kind { hir::TyKind::InferDelegation(infer) => self.lower_delegation_ty(*infer), hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)), - hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl), - hir::TyKind::Ref(region, mt) => { + hir::TyKind::Ptr(ty, mutbl) => Ty::new_ptr(tcx, self.lower_ty(ty), *mutbl), + hir::TyKind::Ref(region, ty, mutbl) => { let r = self.lower_lifetime(region, RegionInferReason::Reference); debug!(?r); - let t = self.lower_ty(mt.ty); - Ty::new_ref(tcx, r, t, mt.mutbl) + let t = self.lower_ty(ty); + Ty::new_ref(tcx, r, t, *mutbl) } hir::TyKind::Never => tcx.types.never, hir::TyKind::Tup(fields) => { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index ea2735a2a70c0..d8c57bfbdb56b 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -396,14 +396,16 @@ impl<'a> State<'a> { self.print_type(ty); self.word("]"); } - hir::TyKind::Ptr(ref mt) => { + hir::TyKind::Ptr(ref ty, mutbl) => { self.word("*"); - self.print_mt(mt, true); + self.print_mutability(mutbl, true); + self.print_type(ty); } - hir::TyKind::Ref(lifetime, ref mt) => { + hir::TyKind::Ref(lifetime, ref ty, mutbl) => { self.word("&"); self.print_opt_lifetime(lifetime); - self.print_mt(mt, false); + self.print_mutability(mutbl, false); + self.print_type(ty); } hir::TyKind::Never => { self.word("!"); @@ -2568,11 +2570,6 @@ impl<'a> State<'a> { } } - fn print_mt(&mut self, mt: &hir::MutTy<'_>, print_const: bool) { - self.print_mutability(mt.mutbl, print_const); - self.print_type(mt.ty); - } - fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { match decl.output { hir::FnRetTy::Return(ty) => { diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 11fe876209ef2..76eba93213608 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -894,18 +894,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .inputs .iter() .filter_map(|ty| match ty.kind { - hir::TyKind::Ref(lt, mut_ty) if ty.span == *ty_span => Some((lt, mut_ty)), + hir::TyKind::Ref(lt, inner_ty, mutbl) if ty.span == *ty_span => Some((lt, inner_ty, mutbl)), _ => None, }) .next() { - let mut sugg = if ty_ref.1.mutbl.is_mut() { + let mut sugg = if ty_ref.2.is_mut() { // Leave `&'name mut Ty` and `&mut Ty` as they are (#136028). vec![] } else { // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` vec![( - ty_ref.1.ty.span.shrink_to_lo(), + ty_ref.1.span.shrink_to_lo(), format!("{}mut ", if ty_ref.0.ident.span.is_empty() { "" } else { " " },), )] }; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 86bc6eeebc189..6f4d5bd6c90fe 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -456,11 +456,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::Node::Param(p) = self.tcx.parent_hir_node(b.hir_id) && let Some(decl) = self.tcx.parent_hir_node(p.hir_id).fn_decl() && let Some(ty) = decl.inputs.iter().find(|ty| ty.span == p.ty_span) - && let hir::TyKind::Ref(_, mut_ty) = &ty.kind - && let hir::Mutability::Not = mut_ty.mutbl + && let hir::TyKind::Ref(_, inner_ty, hir::Mutability::Not) = &ty.kind { err.span_suggestion_verbose( - mut_ty.ty.span.shrink_to_lo(), + inner_ty.span.shrink_to_lo(), msg, "mut ", Applicability::MachineApplicable, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 69ac09e650c16..2a6ed40c096be 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2649,7 +2649,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr { match &expr.kind { hir::ExprKind::Cast(expr, ty) => { - if let hir::TyKind::Ptr(_) = ty.kind { + if let hir::TyKind::Ptr(..) = ty.kind { return is_zero(expr) || is_null_ptr(cx, expr); } } diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index d06292d62730f..dbe20dbef3c87 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for DanglingPointers { DanglingPointerSearcher { cx, inside_call_args: false }.visit_body(body); if let FnRetTy::Return(ret_ty) = &fn_decl.output - && let TyKind::Ptr(_) = ret_ty.kind + && let TyKind::Ptr(..) = ret_ty.kind { // get the return type of the function or closure let ty = match cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() { diff --git a/compiler/rustc_lint/src/disallowed_pass_by_ref.rs b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs index 5ecc4d4b07548..71d81e4512ca2 100644 --- a/compiler/rustc_lint/src/disallowed_pass_by_ref.rs +++ b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs @@ -23,7 +23,7 @@ declare_lint_pass!(DisallowedPassByRef => [DISALLOWED_PASS_BY_REF]); impl<'tcx> LateLintPass<'tcx> for DisallowedPassByRef { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) { match &ty.kind { - TyKind::Ref(_, hir::MutTy { ty: inner_ty, mutbl: hir::Mutability::Not }) => { + TyKind::Ref(_, inner_ty, hir::Mutability::Not) => { if cx.tcx.trait_impl_of_assoc(ty.hir_id.owner.to_def_id()).is_some() { return; } diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs index 208965ede2c73..ea09ce79fd49d 100644 --- a/compiler/rustc_lint/src/lifetime_syntax.rs +++ b/compiler/rustc_lint/src/lifetime_syntax.rs @@ -564,8 +564,8 @@ impl<'tcx> Info<'tcx> { // FIXME: Ideally, we'd also remove the lifetime declaration. fn removing_span(&self) -> Span { let mut span = self.lifetime.ident.span; - if let hir::TyKind::Ref(_, mut_ty) = self.ty.kind { - span = span.until(mut_ty.ty.span); + if let hir::TyKind::Ref(_, ty, _) = self.ty.kind { + span = span.until(ty.span); } span } diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 0c4dba0893fc4..c231bd4cc3b30 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -86,7 +86,7 @@ fn useless_check<'a, 'tcx: 'a>( return Some(UselessPtrNullChecksDiag::FnRet { fn_name }); } e = if let ExprKind::Cast(expr, t) = e.kind - && let TyKind::Ptr(_) = t.kind + && let TyKind::Ptr(..) = t.kind { had_at_least_one_cast = true; expr diff --git a/compiler/rustc_lint/src/raw_borrows_via_references.rs b/compiler/rustc_lint/src/raw_borrows_via_references.rs index 4db8f2a243678..74ab9ee39fadc 100644 --- a/compiler/rustc_lint/src/raw_borrows_via_references.rs +++ b/compiler/rustc_lint/src/raw_borrows_via_references.rs @@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for RawBorrowsViaReferences { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) { if let ExprKind::Cast(exp, ty) = expr.kind && let ExprKind::AddrOf(BorrowKind::Ref, mutbl, addr_of_exp) = exp.kind - && let TyKind::Ptr(_) = ty.kind + && let TyKind::Ptr(..) = ty.kind && addr_of_exp.is_syntactic_place_expr() { let suggestion = if let Some(borrow_span) = diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 5a7e9d3e5d0a7..7725daa276cc6 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -293,7 +293,7 @@ fn annotate_mut_binding_to_immutable_binding<'tcx>( local.as_usize() - if tcx.is_closure_like(body_def_id.to_def_id()) { 2 } else { 1 }; let fn_decl = tcx.hir_node_by_def_id(body_def_id).fn_decl()?; let ty = fn_decl.inputs[hir_param_index]; - let hir::TyKind::Ref(lt, mut_ty) = ty.kind else { return None }; + let hir::TyKind::Ref(lt, inner_ty, mutbl) = ty.kind else { return None }; // ... as a binding pattern. let hir_body = tcx.hir_maybe_body_owned_by(body_def_id)?; @@ -312,12 +312,12 @@ fn annotate_mut_binding_to_immutable_binding<'tcx>( // Changes to the parameter's type. let pre = if lt.ident.span.is_empty() { "" } else { " " }; - let ty_span = if mut_ty.mutbl.is_mut() { + let ty_span = if mutbl.is_mut() { // Leave `&'name mut Ty` and `&mut Ty` as they are (#136028). None } else { // `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty` - Some(mut_ty.ty.span.shrink_to_lo()) + Some(inner_ty.span.shrink_to_lo()) }; return Some(diagnostics::UnusedAssignSuggestion { diff --git a/compiler/rustc_trait_selection/src/diagnostics.rs b/compiler/rustc_trait_selection/src/diagnostics.rs index 80ffbba041ccd..09689af889799 100644 --- a/compiler/rustc_trait_selection/src/diagnostics.rs +++ b/compiler/rustc_trait_selection/src/diagnostics.rs @@ -2023,7 +2023,7 @@ pub fn impl_trait_overcapture_suggestion<'tcx>( ("(", ")") } Node::Ty(ty) => match ty.kind { - rustc_hir::TyKind::Ptr(_) | rustc_hir::TyKind::Ref(..) => ("(", ")"), + rustc_hir::TyKind::Ptr(..) | rustc_hir::TyKind::Ref(..) => ("(", ")"), // FIXME: RPITs are not allowed to be nested in `impl Fn() -> ...`, // but we eventually could support that, and that would necessitate // making this more sophisticated. diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index e88038528189e..7079dd39fe64d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -90,7 +90,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { } } - hir::TyKind::Ref(lifetime, _) => { + hir::TyKind::Ref(lifetime, ..) => { // the lifetime of the Ref let hir_id = lifetime.hir_id; match self.tcx.named_bound_var(hir_id) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs index 03baa5c2acbfb..8a14ad3a9c675 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs @@ -268,9 +268,9 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> { fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx, AmbigArg>) { match arg.kind { - hir::TyKind::Ref(_, ref mut_ty) => { + hir::TyKind::Ref(_, ref ty, _) => { // We don't want to suggest looking into borrowing `&T` or `&Self`. - if let Some(ambig_ty) = mut_ty.ty.try_as_ambig_ty() { + if let Some(ambig_ty) = ty.try_as_ambig_ty() { walk_ty(self, ambig_ty); } return; 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 ff9db46445135..47d2b7a8c98d5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2272,9 +2272,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Skipping binder here, remapping below let mut suggested_ty = trait_pred.self_ty().skip_binder(); if let Some(mut hir_ty) = expr_finder.ty_result { - while let hir::TyKind::Ref(_, mut_ty) = &hir_ty.kind { + while let hir::TyKind::Ref(_, ref_ty, _) = &hir_ty.kind { count += 1; - let span = hir_ty.span.until(mut_ty.ty.span); + let span = hir_ty.span.until(ref_ty.span); suggestions.push((span, String::new())); let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else { @@ -2282,7 +2282,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; suggested_ty = *inner_ty; - hir_ty = mut_ty.ty; + hir_ty = ref_ty; if maybe_suggest(suggested_ty, count, suggestions.clone()) { return true; @@ -2311,9 +2311,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn suggest_remove_ref_from_param(&self, param: &hir::Param<'_>, err: &mut Diag<'_>) -> bool { if let Some(decl) = self.tcx.parent_hir_node(param.hir_id).fn_decl() && let Some(input_ty) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span)) - && let hir::TyKind::Ref(_, mut_ty) = input_ty.kind + && let hir::TyKind::Ref(_, ty, _) = input_ty.kind { - let ref_span = input_ty.span.until(mut_ty.ty.span); + let ref_span = input_ty.span.until(ty.span); match self.tcx.sess.source_map().span_to_snippet(ref_span) { Ok(snippet) if snippet.starts_with("&") => { err.span_suggestion_verbose( @@ -6830,11 +6830,11 @@ fn hint_missing_borrow<'tcx>( let mut span = arg.span.shrink_to_lo(); let mut left = found_refs.len() - expected_refs.len(); let mut ty = arg; - while let hir::TyKind::Ref(_, mut_ty) = &ty.kind + while let hir::TyKind::Ref(_, inner_ty, _) = &ty.kind && left > 0 { - span = span.with_hi(mut_ty.ty.span.lo()); - ty = mut_ty.ty; + span = span.with_hi(inner_ty.span.lo()); + ty = inner_ty; left -= 1; } if left == 0 { @@ -7304,7 +7304,7 @@ impl<'v> Visitor<'v> for FindTypeParam { // and suggest `T: ?Sized` regardless of their obligations. This is fine because the errors // in that case should make what happened clear enough. match ty.kind { - hir::TyKind::Ptr(_) | hir::TyKind::Ref(..) | hir::TyKind::TraitObject(..) => {} + hir::TyKind::Ptr(..) | hir::TyKind::Ref(..) | hir::TyKind::TraitObject(..) => {} hir::TyKind::Path(hir::QPath::Resolved(None, path)) if let [segment] = path.segments && segment.ident.name == self.param => diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index c598e0ef8a8bd..449f349aaf886 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -526,10 +526,10 @@ fn virtual_call_violations_for_method<'tcx>( { // If we have `self: &'a Ty`, get `'a`, so that we can suggest `&'a self`. let lt = match sig.decl.inputs[0].kind { - hir::TyKind::Ref(lt, _) if lt.ident.name == kw::UnderscoreLifetime => { + hir::TyKind::Ref(lt, ..) if lt.ident.name == kw::UnderscoreLifetime => { sym::empty } - hir::TyKind::Ref(lt, _) => lt.ident.name, + hir::TyKind::Ref(lt, ..) => lt.ident.name, _ => sym::empty, }; // Get the `Span` for all of `self: Ty`, not just `Ty`. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9b3c3d01557e0..09dbd279988f6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1927,10 +1927,10 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'_>, cx: &mut DocContext<'tcx>) -> Typ match ty.kind { TyKind::Never => Primitive(PrimitiveType::Never), - TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(clean_ty(m.ty, cx))), - TyKind::Ref(l, ref m) => { + TyKind::Ptr(inner_ty, mutbl) => RawPointer(mutbl, Box::new(clean_ty(inner_ty, cx))), + TyKind::Ref(l, inner_ty, mutbl) => { let lifetime = if l.is_anonymous() { None } else { Some(clean_lifetime(l, cx)) }; - BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) } + BorrowedRef { lifetime, mutability: mutbl, type_: Box::new(clean_ty(inner_ty, cx)) } } TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), TyKind::Pat(inner_ty, pat) => { diff --git a/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs b/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs index 3ab6693756f5a..63df64f4edb57 100644 --- a/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs @@ -3,7 +3,7 @@ use rustc_lint::LateContext; use rustc_middle::ty::Ty; pub fn check<'tcx>(cx: &LateContext<'tcx>, ty_into: Ty<'_>, cast_to_hir: &'tcx rustc_hir::Ty<'tcx>) { - if let rustc_hir::TyKind::Ptr(rustc_hir::MutTy { ty, .. }) = cast_to_hir.kind + if let rustc_hir::TyKind::Ptr(ty, _) = cast_to_hir.kind && matches!(ty.kind, rustc_hir::TyKind::Infer(())) { clippy_utils::diagnostics::span_lint_and_sugg( diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs index cb9f7f618d7f9..3db972278a8ad 100644 --- a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs @@ -18,8 +18,8 @@ pub(super) fn check<'tcx>( cast_to: &'tcx Ty<'_>, msrv: Msrv, ) -> bool { - if let TyKind::Ptr(target) = cast_to.kind - && !matches!(target.ty.kind, TyKind::TraitObject(..)) + if let TyKind::Ptr(target, _) = cast_to.kind + && !matches!(target.kind, TyKind::TraitObject(..)) && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind && !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id) // Fix #9884 diff --git a/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs index 2b1b3c1b96fd3..030a22755cfd6 100644 --- a/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/manual_dangling_ptr.rs @@ -11,21 +11,21 @@ use rustc_span::Spanned; use super::MANUAL_DANGLING_PTR; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) { - if let TyKind::Ptr(ref ptr_ty) = to.kind { + if let TyKind::Ptr(ref ptr_ty, mutbl) = to.kind { let init_expr = expr_or_init(cx, from); - if is_expr_const_aligned(cx, init_expr, ptr_ty.ty) + if is_expr_const_aligned(cx, init_expr, ptr_ty) && let Some(std_or_core) = std_or_core(cx) - && let pointee_ty = cx.typeck_results().node_type(ptr_ty.ty.hir_id) + && let pointee_ty = cx.typeck_results().node_type(ptr_ty.hir_id) && pointee_ty.is_sized(cx.tcx, cx.typing_env()) { - let sugg_fn = match ptr_ty.mutbl { + let sugg_fn = match mutbl { Mutability::Not => "ptr::dangling", Mutability::Mut => "ptr::dangling_mut", }; - let sugg = if let TyKind::Infer(()) = ptr_ty.ty.kind { + let sugg = if let TyKind::Infer(()) = ptr_ty.kind { format!("{std_or_core}::{sugg_fn}()") - } else if let Some(mut_ty_snip) = ptr_ty.ty.span.get_text(cx) { + } else if let Some(mut_ty_snip) = ptr_ty.span.get_text(cx) { format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()") } else { return; diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs index 61fe563512b60..bee8478a7bcc8 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs @@ -47,13 +47,13 @@ pub(super) fn check<'tcx>( let mut app = Applicability::MachineApplicable; let turbofish = match &cast_to_hir.kind { TyKind::Infer(()) => String::new(), - TyKind::Ptr(mut_ty) => { - if matches!(mut_ty.ty.kind, TyKind::Infer(())) { + TyKind::Ptr(inner_ty, _) => { + if matches!(inner_ty.kind, TyKind::Infer(())) { String::new() } else { format!( "::<{}>", - snippet_with_applicability(cx, mut_ty.ty.span, "/* type */", &mut app) + snippet_with_applicability(cx, inner_ty.span, "/* type */", &mut app) ) } }, diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs index 5f20efe2e3646..6107a0cb363d0 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs @@ -52,8 +52,8 @@ pub(super) fn check<'tcx>( if msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) { let mut app = Applicability::MachineApplicable; let sugg = if let ExprKind::Cast(nested_from, nested_hir_ty) = cast_from_expr.kind - && let hir::TyKind::Ptr(ptr_ty) = nested_hir_ty.kind - && let hir::TyKind::Infer(()) = ptr_ty.ty.kind + && let hir::TyKind::Ptr(inner_ty, _) = nested_hir_ty.kind + && let hir::TyKind::Infer(()) = inner_ty.kind { // `(foo as *const _).cast_mut()` fails method name resolution // avoid this by `as`-ing the full type diff --git a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs index b850f7f41ed33..0e69445caf5f4 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs @@ -44,13 +44,13 @@ pub(super) fn check<'tcx>( let mut app = Applicability::MachineApplicable; let turbofish = match &cast_to_hir_ty.kind { TyKind::Infer(()) => String::new(), - TyKind::Ptr(mut_ty) => { - if matches!(mut_ty.ty.kind, TyKind::Infer(())) { + TyKind::Ptr(inner_ty, _) => { + if matches!(inner_ty.kind, TyKind::Infer(())) { String::new() } else { format!( "::<{}>", - snippet_with_applicability(cx, mut_ty.ty.span, "/* type */", &mut app) + snippet_with_applicability(cx, inner_ty.span, "/* type */", &mut app) ) } }, diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs index c98fa1a5cba74..0b2ba1428b53a 100644 --- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs @@ -35,13 +35,13 @@ pub(super) fn check<'tcx>( // Ignore casts to e.g. type aliases and infer types // - p as pointer_alias // - p as _ - && let TyKind::Ptr(to_pointee) = cast_to_hir.kind + && let TyKind::Ptr(to_pointee, _) = cast_to_hir.kind { - match to_pointee.ty.kind { + match to_pointee.kind { // Ignore casts to pointers that are aliases or cfg dependant, e.g. // - p as *const std::ffi::c_char (alias) // - p as *const std::os::raw::c_char (cfg dependant) - TyKind::Path(qpath) if is_ty_alias(&qpath) || is_hir_ty_cfg_dependant(cx, to_pointee.ty) => { + TyKind::Path(qpath) if is_ty_alias(&qpath) || is_hir_ty_cfg_dependant(cx, to_pointee) => { return false; }, // Ignore `p as *const _` diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs index 7f63a7336b1b0..8eba292d6fb99 100644 --- a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs @@ -9,19 +9,19 @@ use rustc_lint::LateContext; use super::ZERO_PTR; pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>, msrv: Msrv) { - if let TyKind::Ptr(ref mut_ty) = to.kind + if let TyKind::Ptr(ref ty, mutbl) = to.kind && is_integer_literal(from, 0) && (!is_in_const_context(cx) || msrv.meets(cx, msrvs::PTR_NULL)) && let Some(std_or_core) = std_or_core(cx) { - let (msg, sugg_fn) = match mut_ty.mutbl { + let (msg, sugg_fn) = match mutbl { Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"), Mutability::Not => ("`0 as *const _` detected", "ptr::null"), }; - let sugg = if let TyKind::Infer(()) = mut_ty.ty.kind { + let sugg = if let TyKind::Infer(()) = ty.kind { format!("{std_or_core}::{sugg_fn}()") - } else if let Some(mut_ty_snip) = mut_ty.ty.span.get_text(cx) { + } else if let Some(mut_ty_snip) = ty.span.get_text(cx) { format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()") } else { return; diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 50017eec7cf65..fa544da1ba3bd 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -853,14 +853,14 @@ impl TyCoercionStability { // Here `y1` and `y2` would resolve to different types, so the type `&Box<_>` is not stable when // switching to auto-dereferencing. fn for_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> Self { - let TyKind::Ref(_, ty) = &ty.kind else { + let TyKind::Ref(_, ty, _) = &ty.kind else { return Self::None; }; let mut ty = ty; loop { - break match ty.ty.kind { - TyKind::Ref(_, ref ref_ty) => { + break match ty.kind { + TyKind::Ref(_, ref ref_ty, _) => { ty = ref_ty; continue; }, @@ -887,7 +887,7 @@ impl TyCoercionStability { }, TyKind::Slice(_) | TyKind::Array(..) - | TyKind::Ptr(_) + | TyKind::Ptr(..) | TyKind::FnPtr(_) | TyKind::Pat(..) | TyKind::FieldOf(..) diff --git a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs index 1afec00f94792..733f10b3506f8 100644 --- a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs +++ b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs @@ -16,7 +16,7 @@ fn check_ty<'a>(cx: &LateContext<'a>, param: &hir::Ty<'a>, param_ty: Ty<'a>, fix && let Some(gen_ty) = option_arg_ty(cx, *opt_ty) && !gen_ty.is_ref() // Need to gen the original spans, so first parsing mid, and hir parsing afterward - && let hir::TyKind::Ref(lifetime, hir::MutTy { ty, .. }) = param.kind + && let hir::TyKind::Ref(lifetime, ty, ..) = param.kind && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind && let (Some(first), Some(last)) = (path.segments.first(), path.segments.last()) && let Some(hir::GenericArgs { diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 3c49595f83216..771cdc1e47136 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -126,7 +126,7 @@ fn is_ty_exported(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { impl LateLintPass<'_> for IterWithoutIntoIter { fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) { if let ItemKind::Impl(imp) = item.kind - && let TyKind::Ref(_, self_ty_without_ref) = &imp.self_ty.kind + && let TyKind::Ref(_, self_ty_without_ref, _) = &imp.self_ty.kind && let Some(of_trait) = imp.of_trait && of_trait .trait_ref @@ -178,7 +178,7 @@ impl {self_ty_without_ref} {{ }} }} ", - self_ty_without_ref = snippet(cx, self_ty_without_ref.ty.span, ".."), + self_ty_without_ref = snippet(cx, self_ty_without_ref.span, ".."), ref_self = mtbl.ref_prefix_str(), iter_ty = snippet(cx, iter_assoc_span, ".."), ); diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 5e65c0f6f0c67..24bd9a2f1418d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -262,7 +262,7 @@ fn ty_is_fully_concrete(ty: &rustc_hir::Ty<'_>) -> bool { seg.args .is_none_or(|a| a.args.iter().all(generic_arg_is_fully_concrete)) }), - rustc_hir::TyKind::Ref(_, mut_ty) => ty_is_fully_concrete(mut_ty.ty), + rustc_hir::TyKind::Ref(_, ty, _) => ty_is_fully_concrete(ty), rustc_hir::TyKind::Slice(ty) | rustc_hir::TyKind::Array(ty, _) => ty_is_fully_concrete(ty), rustc_hir::TyKind::Tup(tys) => tys.iter().all(ty_is_fully_concrete), _ => true, diff --git a/src/tools/clippy/clippy_lints/src/methods/should_implement_trait.rs b/src/tools/clippy/clippy_lints/src/methods/should_implement_trait.rs index 9e0d630461915..c233fe3f28ed5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/should_implement_trait.rs +++ b/src/tools/clippy/clippy_lints/src/methods/should_implement_trait.rs @@ -149,7 +149,7 @@ impl OutType { (Self::Unit, &FnRetTy::Return(ty)) if is_unit(ty) => true, (Self::Bool, &FnRetTy::Return(ty)) if is_bool(ty) => true, (Self::Any, &FnRetTy::Return(ty)) if !is_unit(ty) => true, - (Self::Ref, &FnRetTy::Return(ty)) => matches!(ty.kind, hir::TyKind::Ref(_, _)), + (Self::Ref, &FnRetTy::Return(ty)) => matches!(ty.kind, hir::TyKind::Ref(..)), _ => false, } } diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs index 3b83a9ecd55c2..640044e4d6e21 100644 --- a/src/tools/clippy/clippy_lints/src/mut_mut.rs +++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs @@ -98,26 +98,26 @@ impl<'tcx> LateLintPass<'tcx> for MutMut { } fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'_, AmbigArg>) { - if let TyKind::Ref(_, base) = ty.kind - && base.mutbl.is_mut() + if let TyKind::Ref(_, base, base_mutbl) = ty.kind + && base_mutbl.is_mut() && let ctxt = ty.span.ctxt() - && ctxt == base.ty.span.ctxt() + && ctxt == base.span.ctxt() { - if self.skip_id.replace(base.ty.hir_id) == Some(ty.hir_id) { + if self.skip_id.replace(base.hir_id) == Some(ty.hir_id) { return; } - if let TyKind::Ref(_, mut base2) = base.ty.kind - && base2.mutbl.is_mut() + if let TyKind::Ref(_, mut base2, base2_mutbl) = base.kind + && base2_mutbl.is_mut() { - while let TyKind::Ref(_, next) = base2.ty.kind - && next.mutbl.is_mut() - && ctxt == base2.ty.span.ctxt() + while let TyKind::Ref(_, next, next_mutbl) = base2.kind + && next_mutbl.is_mut() + && ctxt == base2.span.ctxt() { base2 = next; } if !ctxt.in_external_macro(cx.tcx.sess.source_map()) - && let Some(sp) = walk_span_to_context(base2.ty.span, ctxt) + && let Some(sp) = walk_span_to_context(base2.span, ctxt) { span_lint_and_then( cx, @@ -126,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for MutMut { "multiple successive mutable references", |diag| { diag.span_suggestion_verbose( - base.ty.span.until(sp), + base.span.until(sp), "use only a single mutable reference", "", Applicability::MaybeIncorrect, diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 5c6030d61f5f0..ce5040372c3cc 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -266,9 +266,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { for input in unused { // If the argument is never used mutably, we emit the warning. let sp = input.span; - if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind { + if let rustc_hir::TyKind::Ref(_, inner_ty, _) = input.kind { let Some(after_mut_span) = cx.tcx.sess.source_map().span_extend_to_prev_str( - inner_ty.ty.span.shrink_to_lo(), + inner_ty.span.shrink_to_lo(), "mut", true, true, diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 70b5adb0a7390..4c541ead3d395 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -11,7 +11,7 @@ use rustc_data_structures::unord::UnordItems; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::intravisit::FnKind; -use rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind}; +use rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, Mutability, Node, PatKind}; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; use rustc_middle::ty::layout::LayoutOf as _; @@ -171,7 +171,7 @@ impl PassByRefOrValue { if is_copy(cx, ty) && let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes()) && size <= self.ref_min_size - && let hir::TyKind::Ref(_, MutTy { ty: decl_ty, .. }) = input.kind + && let hir::TyKind::Ref(_, decl_ty, ..) = input.kind { if let Some(typeck) = cx.typeck_results // Don't lint if a raw pointer is created. diff --git a/src/tools/clippy/clippy_lints/src/ptr/mut_from_ref.rs b/src/tools/clippy/clippy_lints/src/ptr/mut_from_ref.rs index 6cf4c8586f340..bc0fac8684cf1 100644 --- a/src/tools/clippy/clippy_lints/src/ptr/mut_from_ref.rs +++ b/src/tools/clippy/clippy_lints/src/ptr/mut_from_ref.rs @@ -48,8 +48,8 @@ struct LifetimeVisitor<'tcx> { impl<'tcx> Visitor<'tcx> for LifetimeVisitor<'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) { - if let TyKind::Ref(lt, ref m) = ty.kind { - self.result.push((lt, Some(m.mutbl), ty.span)); + if let TyKind::Ref(lt, _, mutbl) = ty.kind { + self.result.push((lt, Some(mutbl), ty.span)); } hir::intravisit::walk_ty(self, ty); } diff --git a/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs b/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs index 4242b7f1f3224..4ead93478a86d 100644 --- a/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs +++ b/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs @@ -207,8 +207,8 @@ fn check_fn_args<'cx, 'tcx: 'cx>( .filter_map(move |(i, (ty, hir_ty))| { if let ty::Ref(_, ty, mutability) = *ty.kind() && let ty::Adt(adt, args) = *ty.kind() - && let TyKind::Ref(lt, ref ty) = hir_ty.kind - && let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind + && let TyKind::Ref(lt, ref inner_ty, _) = hir_ty.kind + && let TyKind::Path(QPath::Resolved(None, path)) = inner_ty.kind // Check that the name as typed matches the actual name of the type. // e.g. `fn foo(_: &Foo)` shouldn't trigger the lint when `Foo` is an alias for `Vec` && let [.., name] = path.segments diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs index b98a4c6b8b9cb..1d0db5d1ebe36 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs @@ -154,9 +154,9 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { let mut ty_kind = &ty.kind; // If the annotation is a ref we "peel" it - if let hir::TyKind::Ref(_, mut_ty) = &ty.kind { + if let hir::TyKind::Ref(_, inner_ty, _) = &ty.kind { is_ref = true; - ty_kind = &mut_ty.ty.kind; + ty_kind = &inner_ty.kind; } if let hir::TyKind::Path(ty_path) = ty_kind @@ -204,8 +204,8 @@ impl LateLintPass<'_> for RedundantTypeAnnotations { // We only lint if the type annotation is an array type (e.g. &[u8; 4]). // If instead it is a slice (e.g. &[u8]) it may not be redundant, so we // don't lint. - if let hir::TyKind::Ref(_, mut_ty) = ty.kind - && matches!(mut_ty.ty.kind, hir::TyKind::Array(..)) + if let hir::TyKind::Ref(_, inner_ty, _) = ty.kind + && matches!(inner_ty.kind, hir::TyKind::Array(..)) { span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation"); } diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs index 013225da010d7..bade37ee8438a 100644 --- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs +++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs @@ -36,9 +36,8 @@ declare_lint_pass!(RefOptionRef => [REF_OPTION_REF]); impl<'tcx> LateLintPass<'tcx> for RefOptionRef { fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) { - if let TyKind::Ref(_, ref mut_ty) = ty.kind - && mut_ty.mutbl == Mutability::Not - && let TyKind::Path(qpath) = &mut_ty.ty.kind + if let TyKind::Ref(_, ref ref_ty, Mutability::Not) = ty.kind + && let TyKind::Path(qpath) = &ref_ty.kind && let last = last_path_segment(qpath) && let Some(def_id) = last.res.opt_def_id() && cx.tcx.is_diagnostic_item(sym::Option, def_id) @@ -48,8 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for RefOptionRef { GenericArg::Type(inner_ty) => Some(inner_ty), _ => None, }) - && let TyKind::Ref(_, ref inner_mut_ty) = inner_ty.kind - && inner_mut_ty.mutbl == Mutability::Not + && let TyKind::Ref(_, _, Mutability::Not) = inner_ty.kind { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 39b2b71a0d56d..58d434dc18e7d 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -178,8 +178,8 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { } fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) { - if let TyKind::Ref(.., mut_ty) = &ty.kind - && let TyKind::TraitObject(bounds, ..) = mut_ty.ty.kind + if let TyKind::Ref(_, inner_ty, _) = &ty.kind + && let TyKind::TraitObject(bounds, ..) = inner_ty.kind && bounds.len() > 2 { // Build up a hash of every trait we've seen diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index 1edd7f8baea96..a68291f06d3dd 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -88,9 +88,9 @@ pub(super) fn check<'tcx>( /// Gets the type `Bar` in `…::transmute`. fn get_explicit_type<'tcx>(path: &'tcx Path<'tcx>) -> Option<&'tcx hir::Ty<'tcx>> { if let GenericArg::Type(ty) = path.segments.last()?.args?.args.get(1)? - && let TyKind::Ref(_, ty) = &ty.kind + && let TyKind::Ref(_, inner_ty, _) = &ty.kind { - Some(ty.ty) + Some(inner_ty) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs index 3dffc164f991a..3aa4224c0e766 100644 --- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs @@ -3,16 +3,22 @@ use clippy_utils::source::snippet; use clippy_utils::sym; use rustc_errors::Applicability; use rustc_hir::{ - self as hir, GenericArg, GenericBounds, GenericParamKind, HirId, Lifetime, MutTy, Mutability, Node, QPath, TyKind, + self as hir, GenericArg, GenericBounds, GenericParamKind, HirId, Lifetime, Mutability, Node, QPath, TyKind, }; use rustc_lint::LateContext; use super::BORROWED_BOX; -pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, mut_ty: &MutTy<'_>) -> bool { +pub(super) fn check( + cx: &LateContext<'_>, + hir_ty: &hir::Ty<'_>, + lt: &Lifetime, + inner_ty: &hir::Ty<'_>, + mutbl: Mutability, +) -> bool { // Ignore `&mut Box` types; see issue #2907 for details. - if mut_ty.mutbl == Mutability::Not - && let TyKind::Path(ref qpath) = mut_ty.ty.kind + if mutbl == Mutability::Not + && let TyKind::Path(ref qpath) = inner_ty.kind && let QPath::Resolved(None, path) = *qpath && let Some(def_id) = path.res.opt_def_id() && Some(def_id) == cx.tcx.lang_items().owned_box() diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 45388800be4b6..f62ca8075f96f 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -14,8 +14,8 @@ use clippy_config::Conf; use rustc_hir as hir; use rustc_hir::intravisit::FnKind; use rustc_hir::{ - Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitFn, - TraitItem, TraitItemKind, TyKind, + Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, QPath, TraitFn, TraitItem, + TraitItemKind, TyKind, }; use rustc_lint::{LateContext, LateLintPass, impl_lint_pass}; use rustc_span::Span; @@ -664,13 +664,13 @@ impl Types { owned_cow::check(cx, qpath, def_id); } }, - TyKind::Ref(lt, ref mut_ty) => { + TyKind::Ref(lt, ref inner_ty, mutbl) => { context.is_nested_call = true; - if !borrowed_box::check(cx, hir_ty, lt, mut_ty) { - self.check_ty(cx, mut_ty.ty, context); + if !borrowed_box::check(cx, hir_ty, lt, inner_ty, mutbl) { + self.check_ty(cx, inner_ty, context); } }, - TyKind::Slice(ty) | TyKind::Array(ty, _) | TyKind::Ptr(MutTy { ty, .. }) => { + TyKind::Slice(ty) | TyKind::Array(ty, _) | TyKind::Ptr(ty, ..) => { context.is_nested_call = true; self.check_ty(cx, ty, context); }, diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_literal_bound.rs b/src/tools/clippy/clippy_lints/src/unnecessary_literal_bound.rs index db920fad53b4e..59987ad7ad817 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_literal_bound.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_literal_bound.rs @@ -4,7 +4,7 @@ use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::intravisit::{FnKind, Visitor}; -use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, Lit, MutTy, Mutability, PrimTy, Ty, TyKind, intravisit}; +use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, Lit, Mutability, PrimTy, Ty, TyKind, intravisit}; use rustc_lint::{LateContext, LateLintPass, declare_lint_pass}; use rustc_span::Span; use rustc_span::def_id::LocalDefId; @@ -55,7 +55,7 @@ declare_clippy_lint! { declare_lint_pass!(UnnecessaryLiteralBound => [UNNECESSARY_LITERAL_BOUND]); fn extract_anonymous_ref<'tcx>(hir_ty: &Ty<'tcx>) -> Option<&'tcx Ty<'tcx>> { - let TyKind::Ref(lifetime, MutTy { ty, mutbl }) = hir_ty.kind else { + let TyKind::Ref(lifetime, ty, mutbl) = hir_ty.kind else { return None; }; diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index ca79f79403e7d..828fb1d3313b4 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -23,7 +23,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{ Block, BlockCheckMode, Body, BoundConstness, BoundPolarity, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl, ImplItem, ImplItemImplKind, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, - MatchSource, MutTy, Node, PatExpr, PatExprKind, PatKind, Path, PolyTraitRef, QPath, Safety, TraitBoundModifiers, + MatchSource, Node, PatExpr, PatExprKind, PatKind, Path, PolyTraitRef, QPath, Safety, TraitBoundModifiers, TraitImplHeader, TraitItem, TraitItemKind, TraitRef, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource, }; @@ -391,8 +391,8 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) { fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { match ty.kind { TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str("["), Pat::Str("]")), - TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1), - TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1), + TyKind::Ptr(ty, ..) => (Pat::Str("*"), ty_search_pat(ty).1), + TyKind::Ref(_, ty, ..) => (Pat::Str("&"), ty_search_pat(ty).1), TyKind::FnPtr(fn_ptr) => ( if fn_ptr.safety.is_unsafe() { Pat::Str("unsafe") diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 04ace1727c82c..4ef0a795b4766 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -903,9 +903,9 @@ impl HirEqInterExpr<'_, '_, '_> { match (&left.kind, &right.kind) { (TyKind::Slice(l_vec), TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec), (TyKind::Array(lt, ll), TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_const_arg(ll, rl), - (TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty), - (TyKind::Ref(_, l_rmut), TyKind::Ref(_, r_rmut)) => { - l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty) + (TyKind::Ptr(l_ty, l_mutbl), TyKind::Ptr(r_ty, r_mutbl)) => l_mutbl == r_mutbl && self.eq_ty(l_ty, r_ty), + (TyKind::Ref(_, l_ty, l_mutbl), TyKind::Ref(_, r_ty, r_mutbl)) => { + l_mutbl == r_mutbl && self.eq_ty(l_ty, r_ty) }, (TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r), (TyKind::Tup(l), TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)), @@ -1617,14 +1617,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } self.hash_name(field.name); }, - TyKind::Ptr(mut_ty) => { - self.hash_ty(mut_ty.ty); - mut_ty.mutbl.hash(&mut self.s); + TyKind::Ptr(ty, mutbl) => { + self.hash_ty(ty); + mutbl.hash(&mut self.s); }, - TyKind::Ref(lifetime, mut_ty) => { + TyKind::Ref(lifetime, ty, mutbl) => { self.hash_lifetime(lifetime); - self.hash_ty(mut_ty.ty); - mut_ty.mutbl.hash(&mut self.s); + self.hash_ty(ty); + mutbl.hash(&mut self.s); }, TyKind::FnPtr(fn_ptr) => { fn_ptr.safety.hash(&mut self.s); diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 9fd934cac7ecf..7a155b5885a8c 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2304,8 +2304,8 @@ pub fn peel_hir_ty_refs<'a>(mut ty: &'a hir::Ty<'a>) -> (&'a hir::Ty<'a>, usize) let mut count = 0; loop { match &ty.kind { - TyKind::Ref(_, ref_ty) => { - ty = ref_ty.ty; + TyKind::Ref(_, inner_ty, _) => { + ty = inner_ty; count += 1; }, _ => break (ty, count), @@ -2316,7 +2316,7 @@ pub fn peel_hir_ty_refs<'a>(mut ty: &'a hir::Ty<'a>) -> (&'a hir::Ty<'a>, usize) /// Returns the base type for HIR references and pointers. pub fn peel_hir_ty_refs_and_ptrs<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> { match &ty.kind { - TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => peel_hir_ty_refs_and_ptrs(mut_ty.ty), + TyKind::Ptr(inner_ty, _) | TyKind::Ref(_, inner_ty, _) => peel_hir_ty_refs_and_ptrs(inner_ty), _ => ty, } } diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index d2045c1346ee5..d05ae0b5c45b5 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -8,7 +8,7 @@ use rustc_ast::util::parser::AssocOp; use rustc_ast::{UnOp, ast}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::{self as hir, Closure, ExprKind, HirId, MatchSource, MutTy, Node, TyKind}; +use rustc_hir::{self as hir, Closure, ExprKind, HirId, MatchSource, Node, TyKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; @@ -815,9 +815,8 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti let closure_body = cx.tcx.hir_body(body); // is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`) // a type annotation is present if param `kind` is different from `TyKind::Infer` - let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind - { - matches!(ty.kind, TyKind::Ref(_, MutTy { .. })) + let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, ty, ..) = fn_decl.inputs[0].kind { + matches!(ty.kind, TyKind::Ref(..)) } else { false }; From 9c7ce013216f186768862b653128050f314efedc Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 28 Sep 2026 08:55:49 +0000 Subject: [PATCH 08/13] lint on `Ident::from_str_and_span` taking a string literal This function is a wrapper around `Symbol::intern`, which is already checked by the `rustc::symbol_intern_string_literal` lint. --- compiler/rustc_ast_lowering/src/contract.rs | 5 +-- compiler/rustc_builtin_macros/src/eii.rs | 2 +- .../src/global_allocator.rs | 4 +-- compiler/rustc_builtin_macros/src/test.rs | 12 ++----- .../rustc_builtin_macros/src/test_harness.rs | 2 +- compiler/rustc_lint/src/diagnostics.rs | 6 ++-- compiler/rustc_lint/src/internal.rs | 34 +++++++++++++------ compiler/rustc_span/src/symbol.rs | 7 ++++ 8 files changed, 43 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index 80bd0f7f4bb95..cbfeda33040e7 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use rustc_attr_ir::lang_items::LangItem; use rustc_attr_ir::target::Target; +use rustc_span::sym; use thin_vec::thin_vec; use crate::LoweringContext; @@ -239,7 +240,7 @@ impl<'hir> LoweringContext<'_, 'hir> { postcond_span: rustc_span::Span, ) -> &'hir rustc_hir::Block<'hir> { let check_ident: rustc_span::Ident = - rustc_span::Ident::from_str_and_span("__ensures_checker", postcond_span); + rustc_span::Ident::new(sym::__ensures_checker, postcond_span); let (check_hir_id, postcond_decl) = { // Set up the postcondition `let` statement. let (checker_pat, check_hir_id) = self.pat_ident_binding_mode_mut( @@ -309,7 +310,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // ret // } // } - let ret_ident: rustc_span::Ident = rustc_span::Ident::from_str_and_span("__ret", span); + let ret_ident: rustc_span::Ident = rustc_span::Ident::new(sym::__ret, span); // Set up the return `let` statement. let (ret_pat, ret_hir_id) = diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index 61b1c50180a6b..ed37599c9e85a 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -331,7 +331,7 @@ fn generate_default_impl( foreign_item_name.span, // prefix self to explicitly escape the const block generated below // NOTE: this is why EIIs can't be used on statements - vec![Ident::from_str_and_span("self", foreign_item_name.span), foreign_item_name], + vec![Ident::new(kw::SelfLower, foreign_item_name.span), foreign_item_name], )), }); diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index d6293f8b015d0..fada1c477ac88 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -131,8 +131,8 @@ impl AllocFnFactory<'_, '_> { // disambiguated somehow. Currently the generated code would // fail to compile with "identifier is bound more than once in // this parameter list". - let size = Ident::from_str_and_span("size", self.span); - let align = Ident::from_str_and_span("align", self.span); + let size = Ident::new(sym::size, self.span); + let align = Ident::new(sym::align, self.span); let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span)); let ty_usize = self.cx.ty_path(usize); diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index b444505027988..8e99d532029db 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -167,11 +167,7 @@ pub(crate) fn expand_test_or_bench( let should_panic_path = |name| { cx.path( sp, - vec![ - test_ident, - Ident::from_str_and_span("ShouldPanic", sp), - Ident::from_str_and_span(name, sp), - ], + vec![test_ident, Ident::new(sym::ShouldPanic, sp), Ident::from_str_and_span(name, sp)], ) }; @@ -179,11 +175,7 @@ pub(crate) fn expand_test_or_bench( let test_type_path = |name| { cx.path( sp, - vec![ - test_ident, - Ident::from_str_and_span("TestType", sp), - Ident::from_str_and_span(name, sp), - ], + vec![test_ident, Ident::new(sym::TestType, sp), Ident::from_str_and_span(name, sp)], ) }; diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index bd2ea5a3e6696..d6167d30558a3 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -324,7 +324,7 @@ fn add_main(cx: &mut TestCtxt<'_>, c: &mut ast::Crate) { // pub fn main() -> ExitCode { ... } let main_ret_ty = if cx.test_runner.is_none() { // Built-in runner has return type `ExitCode`. - let exit_code_path = vec![test_ident, Ident::from_str_and_span("ExitCode", sp)]; + let exit_code_path = vec![test_ident, Ident::new(sym::ExitCode, sp)]; ecx.ty(sp, ast::TyKind::Path(None, ecx.path(sp, exit_code_path))) } else { // User-defined runners have return type `()`. diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 464423b303f4f..ad6ef1053b8a7 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -1238,9 +1238,11 @@ pub(crate) struct QueryUntracked { pub(crate) struct SpanUseEqCtxtDiag; #[derive(Diagnostic)] -#[diag("using `Symbol::intern` on a string literal")] +#[diag("using `{$fn_name}` on a string literal")] #[help("consider adding the symbol to `compiler/rustc_span/src/symbol.rs`")] -pub(crate) struct SymbolInternStringLiteralDiag; +pub(crate) struct SymbolInternStringLiteralDiag { + pub fn_name: &'static str, +} #[derive(Diagnostic)] #[diag("usage of `ty::TyKind::`")] diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index b36326b86ac9a..b32fa2515238a 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -603,10 +603,10 @@ fn is_span_ctxt_call(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { } declare_tool_lint! { - /// The `symbol_intern_string_literal` detects `Symbol::intern` being called on a string literal + /// The `symbol_intern_string_literal` lint detects `Symbol::intern` or `Ident::from_str_and_span` being called on a string literal pub rustc::SYMBOL_INTERN_STRING_LITERAL, Allow, - "Forbid uses of string literals in `Symbol::intern`, suggesting preinterning instead", + "Forbid uses of string literals in `Symbol::intern` or `Ident::from_str_and_span`, suggesting preinterning instead", report_in_external_macro: true } @@ -614,18 +614,30 @@ declare_lint_pass!(SymbolInternStringLiteral => [SYMBOL_INTERN_STRING_LITERAL]); impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) { - if let hir::ExprKind::Call(path, [arg]) = expr.kind + if let hir::ExprKind::Call(path, args) = expr.kind && let hir::ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && cx.tcx.is_diagnostic_item(sym::SymbolIntern, def_id) - && let hir::ExprKind::Lit(kind) = arg.kind - && let rustc_ast::LitKind::Str(_, _) = kind.node { - cx.emit_span_lint( - SYMBOL_INTERN_STRING_LITERAL, - kind.span, - SymbolInternStringLiteralDiag, - ); + let (arg, fn_name) = if cx.tcx.is_diagnostic_item(sym::SymbolIntern, def_id) + && let [arg] = args + { + (arg, "Symbol::intern") + } else if cx.tcx.is_diagnostic_item(sym::ident_from_str_and_span, def_id) + && let [arg, _] = args + { + (arg, "Ident::from_str_and_span") + } else { + return; + }; + if let hir::ExprKind::Lit(kind) = arg.kind + && let rustc_ast::LitKind::Str(_, _) = kind.node + { + cx.emit_span_lint( + SYMBOL_INTERN_STRING_LITERAL, + kind.span, + SymbolInternStringLiteralDiag { fn_name }, + ); + } } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 93a83ddf213c1..a39fd0955c344 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -218,6 +218,7 @@ symbols! { Eq, Equal, Err, + ExitCode, Expected, ExternC, ExternRust, @@ -325,6 +326,7 @@ symbols! { SelfTy, Send, SeqCst, + ShouldPanic, Sized, Slice, SliceIndex, @@ -341,6 +343,7 @@ symbols! { Sync, SyncUnsafeCell, Target, + TestType, This, TokenStream, Transmute, @@ -367,6 +370,8 @@ symbols! { __H, __S, __awaitee, + __ensures_checker, + __ret, __try_var, _t, _task_context, @@ -1126,6 +1131,7 @@ symbols! { i128, i128_type, ident, + ident_from_str_and_span, if_let, if_let_guard, if_let_rescope, @@ -2505,6 +2511,7 @@ impl Ident { } /// Maps a string and a span to an identifier. + #[rustc_diagnostic_item = "ident_from_str_and_span"] pub fn from_str_and_span(string: &str, span: Span) -> Ident { Ident::new(Symbol::intern(string), span) } From 5e0bd1ac99ff370970a30fb2640cac7fc62eccdc Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 12:26:05 +0300 Subject: [PATCH 09/13] Address review comments --- compiler/rustc_hir_id/src/definitions.rs | 38 +++++++++---------- .../src/rmeta/def_path_hash_map.rs | 8 +++- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index d177630e7a8fc..734f149f3bc77 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -47,27 +47,27 @@ impl LocalDefIdMap { } } -/// Struct that contains two maps: `det_part` is used at the earlier stages of compilation -/// (see where `commit_end_of_determinism` is called, at the moment of writing -/// it is after prefetch of `hir_crate_items` in `run_required_analysis`), `non_det_part` is used -/// when def ids are allocated non-deterministically (in parallel compiler), -/// i.e., order of serialized pairs may be different. -/// In order to preserve deterministic output of the compiler we need to deterministically encode this map, so we use -/// `SortedMap` to store the mapping between local hashes and def indices, which gives us -/// deterministic iteration when encoding crate metadata. For encoding/decoding details see -/// `compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs`. #[derive(Debug, Default)] pub struct DefPathToIndexMap { - pub det_part: DefPathHashMap, - pub non_det_part: Option>, + /// Stores mapping from local hash to def indices which are allocated when the order + /// of their allocation is deterministic (see where `commit_end_of_determinism` is called, + /// at the moment of writing it is after prefetch of `hir_crate_items` in `run_required_analysis`). + pub before_parallel_alloc: DefPathHashMap, + + /// Stores the same mapping as previous map but is used after the allocation order of def indices + /// is not deterministic, so when serializing metadata we have a ready to use sorted by stable local + /// hash (which does not change between compiler invocations) mapping. We use it for relatively small number + /// of definitions, so the majority of them would be stored in `DefPathHashMap`, which makes insertion + /// and serialization costs of `SortedMap` acceptable. + pub after_parallel_alloc: Option>, } impl DefPathToIndexMap { #[inline] pub fn get(&self, hash: Hash64) -> Option { - self.det_part + self.before_parallel_alloc .get(&hash) - .or_else(|| self.non_det_part.as_ref().and_then(|map| map.get(&hash).copied())) + .or_else(|| self.after_parallel_alloc.as_ref().and_then(|map| map.get(&hash).copied())) } /// This insert function does not behave like regular `insert` of a `HashMap`, @@ -76,10 +76,10 @@ impl DefPathToIndexMap { /// def index into `det_part` when we are in non-deterministic mode. #[inline] pub fn insert(&mut self, hash: Hash64, index: DefIndex) -> Option { - match self.non_det_part.as_mut() { - None => self.det_part.insert(&hash, &index), + match self.after_parallel_alloc.as_mut() { + None => self.before_parallel_alloc.insert(&hash, &index), Some(map) => { - if let Some(existing) = self.det_part.get(&hash) { + if let Some(existing) = self.before_parallel_alloc.get(&hash) { return Some(existing); } @@ -292,10 +292,10 @@ pub enum DefPathData { } impl Definitions { - /// This function indicates that def ids allocations are non-deterministic after - /// it was called. + /// This function indicates that the order of def id allocations + /// may be non-deterministic after it was called. pub fn commit_end_of_determinism(&mut self) { - self.def_path_hash_to_index.non_det_part = Some(Default::default()); + self.def_path_hash_to_index.after_parallel_alloc = Some(Default::default()); } #[inline(always)] diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 7f625d59fa784..61ec7ad4cf7b3 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -36,11 +36,15 @@ impl<'a, 'tcx> Encodable> for DefPathHashMapRef<'tcx> { fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) { match *self { DefPathHashMapRef::BorrowedFromTcx(map) => { - let bytes = map.det_part.raw_bytes(); + let bytes = map.before_parallel_alloc.raw_bytes(); e.emit_usize(bytes.len()); e.emit_raw_bytes(bytes); - map.non_det_part.as_ref().unwrap_or(&Default::default()).range(..).encode(e); + map.after_parallel_alloc + .as_ref() + .expect("must be set before metadata encoding") + .range(..) + .encode(e); } DefPathHashMapRef::OwnedFromMetadata(..) => { panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization") From 2f77d206ab26535798a3157d0d72646bd6f3655b Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Mon, 28 Sep 2026 13:02:51 +0300 Subject: [PATCH 10/13] Assert that `commit_end_of_determinism` is called only once --- compiler/rustc_hir_id/src/definitions.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 734f149f3bc77..426a4e0109153 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -295,7 +295,10 @@ impl Definitions { /// This function indicates that the order of def id allocations /// may be non-deterministic after it was called. pub fn commit_end_of_determinism(&mut self) { - self.def_path_hash_to_index.after_parallel_alloc = Some(Default::default()); + assert!( + self.def_path_hash_to_index.after_parallel_alloc.replace(Default::default()).is_none(), + "this function should be called only once" + ) } #[inline(always)] From e67d79891ce10bde66cd7d84461dcb209dd24d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 28 Sep 2026 12:55:30 +0200 Subject: [PATCH 11/13] Support also `try-jobs:` to specify custom try jobs --- src/ci/citool/src/main.rs | 10 +++++++--- src/ci/citool/tests/jobs.rs | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index ff55b4df8f3d1..1bb0c2a34b8d1 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -72,10 +72,12 @@ impl GitHubContext { /// The first is a set of patterns of CI jobs that should be executed. /// /// They can be specified in the form of - /// try-job: + /// ``` + /// try-job[s]: /// or - /// try-job: `` + /// try-job[s]: `` /// (to avoid GitHub rendering the glob patterns as Markdown) + /// ``` /// /// # No limit /// The second is a marker that specifies that the limit on the maximum number of allowed try @@ -96,7 +98,9 @@ impl GitHubContext { nolimit = true; continue; } - let Some(pattern) = line.strip_prefix("try-job: ") else { + let Some(pattern) = + line.strip_prefix("try-job: ").or_else(|| line.strip_prefix("try-jobs: ")) + else { continue; }; // Strip backticks if present diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index e45510d62d9af..1b19d97534982 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -27,11 +27,12 @@ fn try_custom_jobs() { r#"This is a test PR try-job: test-aarch64-gnu +try-jobs: test-aarch64-apple try-job: dist-i686-msvc"#, "refs/heads/automation/bors/try", ); insta::assert_snapshot!(stdout, @r#" - jobs=[{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"test-aarch64-gnu","full_name":"try - test-aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true}] + jobs=[{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}},{"name":"test-aarch64-apple","full_name":"try - test-aarch64-apple","os":"macos-15","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DEVELOPER_DIR":"/Applications/Xcode_26.2.app/Contents/Developer","MACOSX_DEPLOYMENT_TARGET":11.0,"MACOSX_STD_DEPLOYMENT_TARGET":11.0,"NO_DEBUG_ASSERTIONS":1,"NO_LLVM_ASSERTIONS":1,"NO_OVERFLOW_CHECKS":1,"RUSTC_RETRY_LINKER_ON_SEGFAULT":1,"RUST_CONFIGURE_ARGS":"--enable-sanitizers --enable-profiler --set build.allocator=jemalloc","SCRIPT":"./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin","TOOLSTATE_PUBLISH":1}},{"name":"test-aarch64-gnu","full_name":"try - test-aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true}] run_type=try "#); } From 199f90342c5682cc1edbdcf7579fb1a3d43a1f7d Mon Sep 17 00:00:00 2001 From: James Barford-Evans Date: Mon, 28 Sep 2026 11:03:13 +0100 Subject: [PATCH 12/13] Allow `#[repr(simd)]` with `f16b` --- compiler/rustc_hir_analysis/src/check/check.rs | 2 ++ tests/ui/parser/f16b-repr-simd.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 tests/ui/parser/f16b-repr-simd.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index ee151399bd849..1e75902884fe1 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1543,6 +1543,8 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { match element_ty.kind() { ty::Param(_) => (), // pass struct([T; 4]) through, let monomorphization catch errors ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _) => (), // struct([u8; 4]) is ok + // So we can create structs like; `struct bfloat16x4_t (f16b x 4);` + ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::F16B) => (), _ => { struct_span_code_err!( tcx.dcx(), diff --git a/tests/ui/parser/f16b-repr-simd.rs b/tests/ui/parser/f16b-repr-simd.rs new file mode 100644 index 0000000000000..36a8c79cba1a8 --- /dev/null +++ b/tests/ui/parser/f16b-repr-simd.rs @@ -0,0 +1,12 @@ +//@ build-pass +//@ compile-flags: --crate-type=lib +#![feature(f16b, repr_simd)] + +extern crate core; + +#[allow(non_camel_case_types)] +type bfloat16_t = core::num::f16b; + +#[repr(simd)] +#[allow(non_camel_case_types)] +pub struct bfloat16x4([bfloat16_t; 4]); From d3d2163b2004565b8d692dc66175f76e6d9fe614 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sat, 19 Sep 2026 18:21:59 +0200 Subject: [PATCH 13/13] dont store arbitrary parsed attributes in thir --- compiler/rustc_codegen_llvm/src/builder.rs | 6 +-- compiler/rustc_codegen_ssa/src/mir/block.rs | 6 +-- .../rustc_codegen_ssa/src/traits/builder.rs | 2 +- compiler/rustc_middle/src/mir/terminator.rs | 2 +- compiler/rustc_middle/src/mir/visit.rs | 2 +- compiler/rustc_middle/src/thir.rs | 4 +- compiler/rustc_mir_build/src/builder/cfg.rs | 2 +- .../src/builder/custom/parse.rs | 2 +- .../rustc_mir_build/src/builder/expr/into.rs | 4 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 18 +++++---- .../rustc_mir_dataflow/src/framework/tests.rs | 2 +- .../src/add_call_guards.rs | 2 +- .../src/add_moves_for_packed_drops.rs | 2 +- .../rustc_mir_transform/src/check_enums.rs | 10 ++--- .../rustc_mir_transform/src/check_pointers.rs | 2 +- .../rustc_mir_transform/src/coroutine/drop.rs | 2 +- .../rustc_mir_transform/src/coroutine/mod.rs | 18 +++++---- .../rustc_mir_transform/src/coverage/tests.rs | 2 +- .../src/early_otherwise_branch.rs | 4 +- .../rustc_mir_transform/src/elaborate_drop.rs | 12 +++++- compiler/rustc_mir_transform/src/inline.rs | 4 +- compiler/rustc_mir_transform/src/patch.rs | 8 ++-- .../rustc_mir_transform/src/promote_consts.rs | 4 +- compiler/rustc_mir_transform/src/shim.rs | 38 ++++++++++++++----- .../src/shim/async_destructor_ctor.rs | 12 ++++-- tests/incremental/cache-lint-expectation.rs | 5 ++- tests/ui/thir-print/str-patterns.stdout | 4 +- .../thir-print/thir-flat-const-variant.stdout | 10 ++--- tests/ui/thir-print/thir-flat.stdout | 2 +- 29 files changed, 116 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 477cc25ee6f26..f9b5d5ef03b76 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -340,14 +340,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn br_with_attrs(&mut self, dest: &'ll BasicBlock, attributes: &[AttributeKind]) { + fn br_with_attrs(&mut self, dest: &'ll BasicBlock, loop_hint_attrs: &[AttributeKind]) { unsafe { let val = llvm::LLVMBuildBr(self.llbuilder, dest); let mut nodes = Vec::new(); - for attribute in attributes { - let AttributeKind::Unroll(unroll) = attribute else { + for loop_hint_attr in loop_hint_attrs { + let AttributeKind::Unroll(unroll) = loop_hint_attr else { continue; }; // UnrollAttr::Count needs a second operand, the provided count, but the other diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 6dbf9185eaebd..8fa044a45de22 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { bx: &mut Bx, target: mir::BasicBlock, mergeable_succ: bool, - attributes: &[AttributeKind], + loop_hint_attrs: &[AttributeKind], ) -> MergingSucc { let (needs_landing_pad, is_cleanupret) = self.llbb_characteristics(fx, target); if mergeable_succ && !needs_landing_pad && !is_cleanupret { @@ -156,7 +156,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // to a trampoline. bx.cleanup_ret(self.funclet(fx).unwrap(), Some(lltarget)); } else { - bx.br_with_attrs(lltarget, attributes); + bx.br_with_attrs(lltarget, loop_hint_attrs); } MergingSucc::False } @@ -1677,7 +1677,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::TerminatorKind::Goto { target } => { - helper.funclet_br(self, bx, target, mergeable_succ(), &terminator.attributes) + helper.funclet_br(self, bx, target, mergeable_succ(), &terminator.loop_hint_attrs) } mir::TerminatorKind::SwitchInt { ref discr, ref targets } => { diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index b6fdcb21bf2d4..59e1f6e9d0098 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -94,7 +94,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn ret_void(&mut self); fn ret(&mut self, v: Self::Value); fn br(&mut self, dest: Self::BasicBlock); - fn br_with_attrs(&mut self, dest: Self::BasicBlock, _attributes: &[AttributeKind]) { + fn br_with_attrs(&mut self, dest: Self::BasicBlock, _loop_hint_attrs: &[AttributeKind]) { self.br(dest) } fn cond_br( diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 2d51f382f0998..540a49aece678 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -419,7 +419,7 @@ impl fmt::Display for AssertKind { pub struct Terminator<'tcx> { pub source_info: SourceInfo, pub kind: TerminatorKind<'tcx>, - pub attributes: ThinVec, + pub loop_hint_attrs: ThinVec, } impl<'tcx> Terminator<'tcx> { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index a6d15ac6458b8..1b45378c86c0a 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -518,7 +518,7 @@ macro_rules! make_mir_visitor { terminator: &$($mutability)? Terminator<'tcx>, location: Location ) { - let Terminator { source_info, kind, attributes: _ } = terminator; + let Terminator { source_info, kind, loop_hint_attrs: _ } = terminator; self.visit_source_info(source_info); match kind { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 69d518bf82786..a3e5168e4f1e9 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -62,7 +62,7 @@ macro_rules! thir_with_elements { #[derive(Debug, StableHash, Clone)] pub struct Thir<'tcx> { pub body_type: BodyTy<'tcx>, - pub attributes: FxIndexMap>, + pub loop_hint_attrs: FxIndexMap>, $( pub $name: IndexVec<$id, $value>, )* @@ -72,7 +72,7 @@ macro_rules! thir_with_elements { pub fn new(body_type: BodyTy<'tcx>) -> Thir<'tcx> { Thir { body_type, - attributes: FxIndexMap::default(), + loop_hint_attrs: FxIndexMap::default(), $( $name: IndexVec::new(), )* diff --git a/compiler/rustc_mir_build/src/builder/cfg.rs b/compiler/rustc_mir_build/src/builder/cfg.rs index 63ccf323fc204..a8e68963ec724 100644 --- a/compiler/rustc_mir_build/src/builder/cfg.rs +++ b/compiler/rustc_mir_build/src/builder/cfg.rs @@ -121,7 +121,7 @@ impl<'tcx> CFG<'tcx> { self.block_data(block) ); self.block_data_mut(block).terminator = - Some(Terminator { source_info, kind, attributes: ThinVec::new() }); + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }); self.block_data_mut(block).terminator.as_mut().unwrap() } diff --git a/compiler/rustc_mir_build/src/builder/custom/parse.rs b/compiler/rustc_mir_build/src/builder/custom/parse.rs index 32284fe5f42bc..73ffbec6685cc 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { data.terminator = Some(Terminator { source_info: SourceInfo { span, scope: self.source_scope }, kind: terminator, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); Ok(data) diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 3a2e750d4904b..6ca12032362be 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -238,8 +238,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let body_block_end = this.expr_into_dest(tmp, body_block, body).into_block(); let goto = this.cfg.goto(body_block_end, source_info, loop_block); - if let Some(attrs) = this.thir.attributes.get(&expr_id) { - goto.attributes = attrs.clone(); + if let Some(attrs) = this.thir.loop_hint_attrs.get(&expr_id) { + goto.loop_hint_attrs = attrs.clone(); } // Loops are only exited by `break` expressions. diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index ce800491b9842..16e92ae2c51e4 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -57,12 +57,14 @@ impl<'tcx> SplattedFunc<'tcx> { } } -fn parsed_attrs(id: HirId, tcx: TyCtxt<'_>) -> ThinVec { +fn filter_loop_hint_attrs(id: HirId, tcx: TyCtxt<'_>) -> ThinVec { HasAttrs::get_attrs(id, &tcx) .into_iter() .filter_map(|attr| match attr { - rustc_attr_ir::Attribute::Parsed(attrkind) => Some(attrkind.clone()), - rustc_attr_ir::Attribute::Unparsed(_) => None, + rustc_attr_ir::Attribute::Parsed(attrkind @ AttributeKind::Unroll(_)) => { + Some(attrkind.clone()) + } + _ => None, }) .collect() } @@ -91,7 +93,7 @@ impl<'tcx> ThirBuildCx<'tcx> { trace!(?expr.ty); - let mut attrs = ThinVec::new(); + let mut loop_hint_attrs = ThinVec::new(); if let hir::ExprKind::Loop(_, _, _, span) = hir_expr.kind { match span.desugaring_kind() { @@ -103,12 +105,12 @@ impl<'tcx> ThirBuildCx<'tcx> { // ignore async for loops if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(expr.hir_id) { std::assert_matches!(expr.kind, hir::ExprKind::DropTemps(..)); - attrs = parsed_attrs(expr.hir_id, self.tcx) + loop_hint_attrs = filter_loop_hint_attrs(expr.hir_id, self.tcx) } } // For loops defined with `loop` and `while`, the expr already has the attrs Some(DesugaringKind::WhileLoop) | None => { - attrs = parsed_attrs(hir_expr.hir_id, self.tcx); + loop_hint_attrs = filter_loop_hint_attrs(hir_expr.hir_id, self.tcx); } _ => (), } @@ -128,8 +130,8 @@ impl<'tcx> ThirBuildCx<'tcx> { let ty = expr.ty; let value = self.thir.exprs.push(expr); - if !attrs.is_empty() { - self.thir.attributes.insert(value, attrs); + if !loop_hint_attrs.is_empty() { + self.thir.loop_hint_attrs.insert(value, loop_hint_attrs); } // Finally, wrap this up in the expr's scope. diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index ee6330bfe1c2c..9646caab241d9 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -22,7 +22,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> { blocks.push(mir::BasicBlockData::new_stmts( std::iter::repeat(&nop).cloned().take(n).collect(), - Some(mir::Terminator { source_info, kind, attributes: ThinVec::new() }), + Some(mir::Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }), false, )) }; diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index b73cb453752e1..01fd042864019 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -92,7 +92,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards { Some(Terminator { source_info, kind: TerminatorKind::Goto { target }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), is_cleanup, ); diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 6b74d53801594..e0c07619efbc6 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -98,7 +98,7 @@ fn add_move_for_packed_drop<'tcx>( Some(Terminator { source_info, kind: TerminatorKind::Goto { target }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), is_cleanup, )); diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index e6bc8949a6cad..8d2178a07c5c6 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -64,7 +64,7 @@ impl<'tcx> crate::MirPass<'tcx> for CheckEnums { basic_blocks[block].terminator = Some(Terminator { source_info, kind: TerminatorKind::Goto { target: new_block }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } EnumCheckType::Direct { source_op, discr, op_size, valid_discrs } => { @@ -395,7 +395,7 @@ fn insert_direct_enum_check<'tcx>( invalid_discr_block, ), }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); // Abort in case of an invalid enum discriminant. @@ -415,7 +415,7 @@ fn insert_direct_enum_check<'tcx>( // make a failing UB check turn into much worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } @@ -461,7 +461,7 @@ fn insert_uninhabited_enum_check<'tcx>( // make a failing UB check turn into much worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } @@ -539,6 +539,6 @@ fn insert_niche_check<'tcx>( // make a failing UB check turn into much worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs index 7c24e3d29c50a..fb6379a25af95 100644 --- a/compiler/rustc_mir_transform/src/check_pointers.rs +++ b/compiler/rustc_mir_transform/src/check_pointers.rs @@ -117,7 +117,7 @@ pub(crate) fn check_pointers<'tcx, F>( // worse UB when we start unwinding. unwind: UnwindAction::Unreachable, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } } diff --git a/compiler/rustc_mir_transform/src/coroutine/drop.rs b/compiler/rustc_mir_transform/src/coroutine/drop.rs index 6b26a1f242cf0..44ea6aef0e02d 100644 --- a/compiler/rustc_mir_transform/src/coroutine/drop.rs +++ b/compiler/rustc_mir_transform/src/coroutine/drop.rs @@ -376,7 +376,7 @@ pub(super) fn create_coroutine_drop_shim_proxy_async<'tcx>( drop: None, }; body.basic_blocks_mut()[call_bb].terminator = - Some(Terminator { source_info, kind, attributes: ThinVec::new() }); + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }); // Run derefer to fix Derefs that are not in the first place deref_finder(tcx, &mut body, false); diff --git a/compiler/rustc_mir_transform/src/coroutine/mod.rs b/compiler/rustc_mir_transform/src/coroutine/mod.rs index a678e94994aa5..1e63dca78adbb 100644 --- a/compiler/rustc_mir_transform/src/coroutine/mod.rs +++ b/compiler/rustc_mir_transform/src/coroutine/mod.rs @@ -256,7 +256,7 @@ impl<'tcx> TransformVisitor<'tcx> { Some(Terminator { source_info, kind: TerminatorKind::Return, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )); @@ -744,14 +744,14 @@ fn insert_switch<'tcx>( body.basic_blocks_mut()[START_BLOCK].terminator = Some(Terminator { source_info: SourceInfo::outermost(body.span), kind: switch, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().push(BasicBlockData::new( - Some(Terminator { source_info, kind, attributes: ThinVec::new() }), + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }), false, )) } @@ -776,7 +776,11 @@ fn insert_poll_ready_block<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> Ba let source_info = SourceInfo::outermost(body.span); body.basic_blocks_mut().push(BasicBlockData::new_stmts( [return_poll_ready_assign(tcx, source_info)].to_vec(), - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, )) } @@ -835,7 +839,7 @@ fn generate_poison_block_and_redirect_unwinds_there<'tcx>( source_info, kind: TerminatorKind::UnwindResume, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), true, )); @@ -851,7 +855,7 @@ fn generate_poison_block_and_redirect_unwinds_there<'tcx>( source_info, kind: TerminatorKind::Goto { target: poison_block }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }; } } else if !block.is_cleanup @@ -1019,7 +1023,7 @@ fn create_cases<'tcx>( source_info, kind: TerminatorKind::Goto { target }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )); diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index ca4fa888a2176..e9876310f112f 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -73,7 +73,7 @@ impl<'tcx> MockBlocks<'tcx> { Some(Terminator { source_info: SourceInfo::outermost(Span::with_root_ctxt(next_lo, next_hi)), kind, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )) diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index b13a4fa16e21d..b1ac4d33445b0 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -175,7 +175,7 @@ impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch { discr: parent_op, targets: eq_targets, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), bbs[parent].is_cleanup, ); @@ -230,7 +230,7 @@ fn evaluate_candidate<'tcx>( let Terminator { kind: TerminatorKind::SwitchInt { targets: child_targets, discr: child_discr }, source_info, - attributes: _, + loop_hint_attrs: _, } = bbs[child].terminator() else { return None; diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index d97441420e63f..9b81f55ab1145 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -1641,7 +1641,11 @@ where #[instrument(level = "trace", skip(self), ret)] fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock { self.elaborator.patch().new_block(BasicBlockData::new( - Some(Terminator { source_info: self.source_info, kind: k, attributes: ThinVec::new() }), + Some(Terminator { + source_info: self.source_info, + kind: k, + loop_hint_attrs: ThinVec::new(), + }), unwind.is_cleanup(), )) } @@ -1655,7 +1659,11 @@ where ) -> BasicBlock { self.elaborator.patch().new_block(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info: self.source_info, kind: k, attributes: ThinVec::new() }), + Some(Terminator { + source_info: self.source_info, + kind: k, + loop_hint_attrs: ThinVec::new(), + }), unwind.is_cleanup(), )) } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index f8df2eabdaf0d..9547b5bb93dff 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -872,7 +872,7 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( Some(Terminator { source_info: terminator.source_info, kind: TerminatorKind::Goto { target: block }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), caller_body[block].is_cleanup, ); @@ -1000,7 +1000,7 @@ fn inline_call<'tcx, I: Inliner<'tcx>>( caller_body[callsite.block].terminator = Some(Terminator { source_info: callsite.source_info, kind: TerminatorKind::Goto { target: integrator.map_block(START_BLOCK) }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); // Copy required constants from the callee_body into the caller_body. Although we are only diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs index bd4cbcd89163c..6a2d5101067e7 100644 --- a/compiler/rustc_mir_transform/src/patch.rs +++ b/compiler/rustc_mir_transform/src/patch.rs @@ -93,7 +93,7 @@ impl<'tcx> MirPatch<'tcx> { Some(Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::UnwindResume, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), true, )); @@ -110,7 +110,7 @@ impl<'tcx> MirPatch<'tcx> { Some(Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::Unreachable, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), true, )); @@ -127,7 +127,7 @@ impl<'tcx> MirPatch<'tcx> { Some(Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::Unreachable, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )); @@ -146,7 +146,7 @@ impl<'tcx> MirPatch<'tcx> { Some(Terminator { source_info: SourceInfo::outermost(self.body_span), kind: TerminatorKind::UnwindTerminate(reason), - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), true, )); diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 43d058c7eef0c..92c2f9a1c20e1 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -757,7 +757,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { Some(Terminator { source_info: SourceInfo::outermost(span), kind: TerminatorKind::Return, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )) @@ -846,7 +846,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { Terminator { source_info: terminator.source_info, kind: mem::replace(&mut terminator.kind, TerminatorKind::Goto { target }), - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), } }; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index a2a9f6c37456f..faf7039d498b1 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -281,7 +281,7 @@ pub fn build_drop_shim<'tcx>( let mut blocks = IndexVec::with_capacity(2); let block = |blocks: &mut IndexVec<_, _>, kind| { blocks.push(BasicBlockData::new( - Some(Terminator { source_info, kind, attributes: ThinVec::new() }), + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }), false, )) }; @@ -338,7 +338,7 @@ pub fn build_drop_shim<'tcx>( call_source: CallSource::Misc, fn_span: span, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }); } else { let patch = { @@ -491,7 +491,11 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Rvalue::ThreadLocalRef(def_id), ))), )], - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, )]); @@ -577,7 +581,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { let source_info = self.source_info(); self.blocks.push(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind, attributes: ThinVec::new() }), + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }), is_cleanup, )) } @@ -923,7 +927,7 @@ fn build_call_shim<'tcx>( let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| { blocks.push(BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind, attributes: ThinVec::new() }), + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }), is_cleanup, )) }; @@ -1050,7 +1054,11 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let start_block = BasicBlockData::new_stmts( vec![statement], - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, ); @@ -1133,7 +1141,11 @@ fn build_fn_ptr_as_ptr_shim<'tcx>( let start_block = BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, ); let source = MirSource::from_shim(ty::ShimKind::FnPtrAsPtr(def_id, self_ty)); @@ -1168,7 +1180,11 @@ fn build_fn_ptr_from_ptr_shim<'tcx>( let start_block = BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, ); let source = MirSource::from_shim(ty::ShimKind::FnPtrFromPtr(def_id, self_ty)); @@ -1266,7 +1282,11 @@ fn build_construct_coroutine_by_move_shim<'tcx>( let statements = vec![stmt]; let start_block = BasicBlockData::new_stmts( statements, - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, ); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 0570895532370..fcc28b20d25a0 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -86,7 +86,7 @@ pub(super) fn build_async_drop_shim<'tcx>( let mut blocks = IndexVec::with_capacity(2); let block = |blocks: &mut IndexVec<_, _>, kind| { blocks.push(BasicBlockData::new( - Some(Terminator { source_info, kind, attributes: ThinVec::new() }), + Some(Terminator { source_info, kind, loop_hint_attrs: ThinVec::new() }), false, )) }; @@ -394,7 +394,7 @@ fn build_adrop_for_adrop_shim<'tcx>( fn_span: span, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )); @@ -419,12 +419,16 @@ fn build_adrop_for_adrop_shim<'tcx>( fn_span: span, }, - attributes: ThinVec::new(), + loop_hint_attrs: ThinVec::new(), }), false, )); blocks.push(BasicBlockData::new( - Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }), + Some(Terminator { + source_info, + kind: TerminatorKind::Return, + loop_hint_attrs: ThinVec::new(), + }), false, )); diff --git a/tests/incremental/cache-lint-expectation.rs b/tests/incremental/cache-lint-expectation.rs index 0fb38008a855a..c05508cbfc934 100644 --- a/tests/incremental/cache-lint-expectation.rs +++ b/tests/incremental/cache-lint-expectation.rs @@ -1,8 +1,11 @@ -// Regression test for #154878 +// Regression test for #154878 and #162811 //@ revisions: bpass1 bpass2 pub fn main() { let x = 42.0; #[expect(invalid_nan_comparisons)] let _b = x == f32::NAN; + + #[allow(dead_code)] + for _ in 0..10 {} } diff --git a/tests/ui/thir-print/str-patterns.stdout b/tests/ui/thir-print/str-patterns.stdout index 61bcbaef5029a..f943eb03675ab 100644 --- a/tests/ui/thir-print/str-patterns.stdout +++ b/tests/ui/thir-print/str-patterns.stdout @@ -3,7 +3,7 @@ Thir { body_type: Fn( fn(&'{erased} str), ), - attributes: {}, + loop_hint_attrs: {}, arms: [ Arm { pattern: Pat { @@ -294,7 +294,7 @@ Thir { body_type: Const( &'{erased} str, ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [], exprs: [ diff --git a/tests/ui/thir-print/thir-flat-const-variant.stdout b/tests/ui/thir-print/thir-flat-const-variant.stdout index 82e197330cca8..e16cda9a7cb47 100644 --- a/tests/ui/thir-print/thir-flat-const-variant.stdout +++ b/tests/ui/thir-print/thir-flat-const-variant.stdout @@ -3,7 +3,7 @@ Thir { body_type: Const( Foo, ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [], exprs: [ @@ -65,7 +65,7 @@ Thir { body_type: Const( Foo, ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [], exprs: [ @@ -127,7 +127,7 @@ Thir { body_type: Const( Foo, ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [], exprs: [ @@ -189,7 +189,7 @@ Thir { body_type: Const( Foo, ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [], exprs: [ @@ -251,7 +251,7 @@ Thir { body_type: Fn( fn(), ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [ Block { diff --git a/tests/ui/thir-print/thir-flat.stdout b/tests/ui/thir-print/thir-flat.stdout index 76df9f4394315..15f63605957c5 100644 --- a/tests/ui/thir-print/thir-flat.stdout +++ b/tests/ui/thir-print/thir-flat.stdout @@ -3,7 +3,7 @@ Thir { body_type: Fn( fn(), ), - attributes: {}, + loop_hint_attrs: {}, arms: [], blocks: [ Block {