From 5aeb2a6c457d21558317612cde19c81396672287 Mon Sep 17 00:00:00 2001 From: JayanAXHF Date: Fri, 20 Mar 2026 10:24:53 +0530 Subject: [PATCH] refactor(attribute parser): move check_custom_mir to attribute parser --- .../src/attributes/prototype.rs | 50 +++++++++++++++++++ .../src/session_diagnostics.rs | 23 +++++++++ compiler/rustc_passes/src/check_attr.rs | 48 +----------------- compiler/rustc_passes/src/errors.rs | 23 --------- 4 files changed, 75 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index ac50fe33839d2..8eb902be34e26 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs @@ -9,6 +9,7 @@ use super::{AttributeOrder, OnDuplicate}; use crate::attributes::SingleAttributeParser; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; +use crate::session_diagnostics; use crate::target_checking::AllowedTargets; use crate::target_checking::Policy::Allow; @@ -57,6 +58,7 @@ impl SingleAttributeParser for CustomMirParser { let dialect = parse_dialect(cx, dialect, &mut failed); let phase = parse_phase(cx, phase, &mut failed); + check_custom_mir(cx, dialect, phase, &mut failed); if failed { return None; @@ -138,3 +140,51 @@ fn parse_phase( Some((phase, span)) } + +fn check_custom_mir( + cx: &mut AcceptContext<'_, '_, S>, + dialect: Option<(MirDialect, Span)>, + phase: Option<(MirPhase, Span)>, + failed: &mut bool, +) { + let attr_span = cx.attr_span; + let Some((dialect, dialect_span)) = dialect else { + if let Some((_, phase_span)) = phase { + *failed = true; + cx.emit_err(session_diagnostics::CustomMirPhaseRequiresDialect { + attr_span, + phase_span, + }); + } + return; + }; + + match dialect { + MirDialect::Analysis => { + if let Some((MirPhase::Optimized, phase_span)) = phase { + *failed = true; + cx.emit_err(session_diagnostics::CustomMirIncompatibleDialectAndPhase { + dialect, + phase: MirPhase::Optimized, + attr_span, + dialect_span, + phase_span, + }); + } + } + + MirDialect::Built => { + if let Some((phase, phase_span)) = phase { + *failed = true; + cx.emit_err(session_diagnostics::CustomMirIncompatibleDialectAndPhase { + dialect, + phase, + attr_span, + dialect_span, + phase_span, + }); + } + } + MirDialect::Runtime => {} + } +} diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 751b8f8646ab0..0694889488687 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -7,6 +7,7 @@ use rustc_errors::{ }; use rustc_feature::AttributeTemplate; use rustc_hir::AttrPath; +use rustc_hir::attrs::{MirDialect, MirPhase}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; use rustc_target::spec::TargetTuple; @@ -1023,3 +1024,25 @@ pub(crate) struct UnsupportedInstructionSet<'a> { pub instruction_set: Symbol, pub current_target: &'a TargetTuple, } + +#[derive(Diagnostic)] +#[diag("`dialect` key required")] +pub(crate) struct CustomMirPhaseRequiresDialect { + #[primary_span] + pub attr_span: Span, + #[label("`phase` argument requires a `dialect` argument")] + pub phase_span: Span, +} + +#[derive(Diagnostic)] +#[diag("the {$dialect} dialect is not compatible with the {$phase} phase")] +pub(crate) struct CustomMirIncompatibleDialectAndPhase { + pub dialect: MirDialect, + pub phase: MirPhase, + #[primary_span] + pub attr_span: Span, + #[label("this dialect...")] + pub dialect_span: Span, + #[label("... is not compatible with this phase")] + pub phase_span: Span, +} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index bec6ab7e83551..a69ff252945cf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -23,7 +23,7 @@ use rustc_feature::{ use rustc_hir::attrs::diagnostic::Directive; use rustc_hir::attrs::{ AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr, - MirDialect, MirPhase, ReprAttr, SanitizerSet, + ReprAttr, SanitizerSet, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; @@ -208,9 +208,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { self.check_may_dangle(hir_id, *attr_span) } - &Attribute::Parsed(AttributeKind::CustomMir(dialect, phase, attr_span)) => { - self.check_custom_mir(dialect, phase, attr_span) - } &Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, rtsan: _, span: attr_span}) => { self.check_sanitize(attr_span, on_set | off_set, span, target); }, @@ -247,6 +244,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Coverage (..) | AttributeKind::CrateName { .. } | AttributeKind::CrateType(..) + | AttributeKind::CustomMir(..) | AttributeKind::DebuggerVisualizer(..) | AttributeKind::DefaultLibAllocator // `#[doc]` is actually a lot more than just doc comments, so is checked below @@ -1856,48 +1854,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.dcx().emit_err(errors::ConstContinueAttr { attr_span, node_span }); }; } - - fn check_custom_mir( - &self, - dialect: Option<(MirDialect, Span)>, - phase: Option<(MirPhase, Span)>, - attr_span: Span, - ) { - let Some((dialect, dialect_span)) = dialect else { - if let Some((_, phase_span)) = phase { - self.dcx() - .emit_err(errors::CustomMirPhaseRequiresDialect { attr_span, phase_span }); - } - return; - }; - - match dialect { - MirDialect::Analysis => { - if let Some((MirPhase::Optimized, phase_span)) = phase { - self.dcx().emit_err(errors::CustomMirIncompatibleDialectAndPhase { - dialect, - phase: MirPhase::Optimized, - attr_span, - dialect_span, - phase_span, - }); - } - } - - MirDialect::Built => { - if let Some((phase, phase_span)) = phase { - self.dcx().emit_err(errors::CustomMirIncompatibleDialectAndPhase { - dialect, - phase, - attr_span, - dialect_span, - phase_span, - }); - } - } - MirDialect::Runtime => {} - } - } } impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 228f21c81b947..b581c65de74af 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -7,7 +7,6 @@ use rustc_errors::{ MultiSpan, msg, }; use rustc_hir::Target; -use rustc_hir::attrs::{MirDialect, MirPhase}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; @@ -1274,28 +1273,6 @@ pub(crate) struct ReprAlignShouldBeAlignStatic { pub item: &'static str, } -#[derive(Diagnostic)] -#[diag("`dialect` key required")] -pub(crate) struct CustomMirPhaseRequiresDialect { - #[primary_span] - pub attr_span: Span, - #[label("`phase` argument requires a `dialect` argument")] - pub phase_span: Span, -} - -#[derive(Diagnostic)] -#[diag("the {$dialect} dialect is not compatible with the {$phase} phase")] -pub(crate) struct CustomMirIncompatibleDialectAndPhase { - pub dialect: MirDialect, - pub phase: MirPhase, - #[primary_span] - pub attr_span: Span, - #[label("this dialect...")] - pub dialect_span: Span, - #[label("... is not compatible with this phase")] - pub phase_span: Span, -} - #[derive(Diagnostic)] #[diag("`eii_macro_for` is only valid on functions")] pub(crate) struct EiiImplNotFunction {