Rollup merge of #154126 - JayanAXHF:refactor/custom_mir_parser, r=JonathanBrouwer

refactor(attribute parser): move check_custom_mir to attribute parser

Part of rust-lang/rust#153101

r? @JonathanBrouwer
This commit is contained in:
Jonathan Brouwer
2026-03-20 13:24:27 +01:00
committed by GitHub
4 changed files with 75 additions and 69 deletions
@@ -9,6 +9,7 @@
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 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
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<S: Stage>(
Some((phase, span))
}
fn check_custom_mir<S: Stage>(
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 => {}
}
}
@@ -7,6 +7,7 @@
};
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,
}
+2 -46
View File
@@ -23,7 +23,7 @@
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;
@@ -212,9 +212,6 @@ fn check_attributes(
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);
},
@@ -254,6 +251,7 @@ fn check_attributes(
| 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
@@ -1913,48 +1911,6 @@ fn check_const_continue(&self, hir_id: HirId, attr_span: Span, target: Target) {
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> {
-23
View File
@@ -7,7 +7,6 @@
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 {