Port rustc_mir to attribute parser
This commit is contained in:
parent
46c86aef65
commit
b668057d79
13 changed files with 186 additions and 161 deletions
|
|
@ -4338,11 +4338,11 @@ dependencies = [
|
|||
"polonius-engine",
|
||||
"regex",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_graphviz",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
|
||||
use rustc_hir::attrs::RustcLayoutType;
|
||||
use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcLayoutType, RustcMirKind};
|
||||
use rustc_session::errors;
|
||||
|
||||
use super::prelude::*;
|
||||
|
|
@ -357,7 +359,6 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
|
|||
|
||||
const TEMPLATE: AttributeTemplate =
|
||||
template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]);
|
||||
|
||||
fn extend(
|
||||
cx: &mut AcceptContext<'_, '_, S>,
|
||||
args: &ArgParser,
|
||||
|
|
@ -397,6 +398,94 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RustcMirParser;
|
||||
|
||||
impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
|
||||
const PATH: &[rustc_span::Symbol] = &[sym::rustc_mir];
|
||||
|
||||
type Item = RustcMirKind;
|
||||
|
||||
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcMir(items);
|
||||
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
]);
|
||||
|
||||
const TEMPLATE: AttributeTemplate = template!(List: &["arg1, arg2, ..."]);
|
||||
|
||||
fn extend(
|
||||
cx: &mut AcceptContext<'_, '_, S>,
|
||||
args: &ArgParser,
|
||||
) -> impl IntoIterator<Item = Self::Item> {
|
||||
let Some(list) = args.list() else {
|
||||
cx.expected_list(cx.attr_span, args);
|
||||
return ThinVec::new();
|
||||
};
|
||||
|
||||
list.mixed()
|
||||
.filter_map(|arg| arg.meta_item())
|
||||
.filter_map(|mi| {
|
||||
if let Some(ident) = mi.ident() {
|
||||
match ident.name {
|
||||
sym::rustc_peek_maybe_init => Some(RustcMirKind::PeekMaybeInit),
|
||||
sym::rustc_peek_maybe_uninit => Some(RustcMirKind::PeekMaybeUninit),
|
||||
sym::rustc_peek_liveness => Some(RustcMirKind::PeekLiveness),
|
||||
sym::stop_after_dataflow => Some(RustcMirKind::StopAfterDataflow),
|
||||
sym::borrowck_graphviz_postflow => {
|
||||
let Some(nv) = mi.args().name_value() else {
|
||||
cx.expected_name_value(
|
||||
mi.span(),
|
||||
Some(sym::borrowck_graphviz_postflow),
|
||||
);
|
||||
return None;
|
||||
};
|
||||
let Some(path) = nv.value_as_str() else {
|
||||
cx.expected_string_literal(nv.value_span, None);
|
||||
return None;
|
||||
};
|
||||
let path = PathBuf::from(path.to_string());
|
||||
if path.file_name().is_some() {
|
||||
Some(RustcMirKind::BorrowckGraphvizPostflow { path })
|
||||
} else {
|
||||
cx.expected_filename_literal(nv.value_span);
|
||||
None
|
||||
}
|
||||
}
|
||||
sym::borrowck_graphviz_format => {
|
||||
let Some(nv) = mi.args().name_value() else {
|
||||
cx.expected_name_value(
|
||||
mi.span(),
|
||||
Some(sym::borrowck_graphviz_format),
|
||||
);
|
||||
return None;
|
||||
};
|
||||
let Some(format) = nv.value_as_ident() else {
|
||||
cx.expected_identifier(nv.value_span);
|
||||
return None;
|
||||
};
|
||||
match format.name {
|
||||
sym::two_phase => Some(RustcMirKind::BorrowckGraphvizFormat {
|
||||
format: BorrowckGraphvizFormatKind::TwoPhase,
|
||||
}),
|
||||
_ => {
|
||||
cx.expected_specific_argument(format.span, &[sym::two_phase]);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
pub(crate) struct RustcNonConstTraitMethodParser;
|
||||
|
||||
impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ use crate::attributes::rustc_internal::{
|
|||
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser,
|
||||
RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser,
|
||||
RustcLintQueryInstabilityParser, RustcLintUntrackedQueryInformationParser, RustcMainParser,
|
||||
RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
|
||||
RustcMirParser, RustcMustImplementOneOfParser, RustcNeverReturnsNullPointerParser,
|
||||
RustcNoImplicitAutorefsParser, RustcNonConstTraitMethodParser, RustcNounwindParser,
|
||||
RustcObjectLifetimeDefaultParser, RustcOffloadKernelParser, RustcScalableVectorParser,
|
||||
RustcSimdMonomorphizeLaneLimitParser,
|
||||
|
|
@ -202,6 +202,7 @@ attribute_parsers!(
|
|||
Combine<LinkParser>,
|
||||
Combine<ReprParser>,
|
||||
Combine<RustcLayoutParser>,
|
||||
Combine<RustcMirParser>,
|
||||
Combine<TargetFeatureParser>,
|
||||
Combine<UnstableFeatureBoundParser>,
|
||||
// tidy-alphabetical-end
|
||||
|
|
@ -517,6 +518,11 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Error that a filename string literal was expected.
|
||||
pub(crate) fn expected_filename_literal(&self, span: Span) {
|
||||
self.emit_parse_error(span, AttributeParseErrorReason::ExpectedFilenameLiteral);
|
||||
}
|
||||
|
||||
pub(crate) fn expected_integer_literal(&self, span: Span) -> ErrorGuaranteed {
|
||||
self.emit_parse_error(span, AttributeParseErrorReason::ExpectedIntegerLiteral)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -524,6 +524,7 @@ pub(crate) enum AttributeParseErrorReason<'a> {
|
|||
ExpectedStringLiteral {
|
||||
byte_string: Option<Span>,
|
||||
},
|
||||
ExpectedFilenameLiteral,
|
||||
ExpectedIntegerLiteral,
|
||||
ExpectedIntegerLiteralInRange {
|
||||
lower_bound: isize,
|
||||
|
|
@ -597,6 +598,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
|
|||
diag.span_label(self.span, "expected a string literal here");
|
||||
}
|
||||
}
|
||||
AttributeParseErrorReason::ExpectedFilenameLiteral => {
|
||||
diag.span_label(self.span, "expected a filename string literal here");
|
||||
}
|
||||
AttributeParseErrorReason::ExpectedIntegerLiteral => {
|
||||
diag.span_label(self.span, "expected an integer literal here");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -699,6 +699,21 @@ pub enum RustcLayoutType {
|
|||
Debug,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute, PartialEq, Eq)]
|
||||
pub enum RustcMirKind {
|
||||
PeekMaybeInit,
|
||||
PeekMaybeUninit,
|
||||
PeekLiveness,
|
||||
StopAfterDataflow,
|
||||
BorrowckGraphvizPostflow { path: PathBuf },
|
||||
BorrowckGraphvizFormat { format: BorrowckGraphvizFormatKind },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute, PartialEq, Eq)]
|
||||
pub enum BorrowckGraphvizFormatKind {
|
||||
TwoPhase,
|
||||
}
|
||||
|
||||
/// Represents parsed *built-in* inert attributes.
|
||||
///
|
||||
/// ## Overview
|
||||
|
|
@ -1090,6 +1105,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[rustc_main]`.
|
||||
RustcMain,
|
||||
|
||||
/// Represents `#[rustc_mir]`.
|
||||
RustcMir(ThinVec<RustcMirKind>),
|
||||
|
||||
/// Represents `#[rustc_must_implement_one_of]`
|
||||
RustcMustImplementOneOf { attr_span: Span, fn_names: ThinVec<Ident> },
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ impl AttributeKind {
|
|||
RustcLintUntrackedQueryInformation => Yes,
|
||||
RustcMacroTransparency(..) => Yes,
|
||||
RustcMain => No,
|
||||
RustcMir(..) => Yes,
|
||||
RustcMustImplementOneOf { .. } => No,
|
||||
RustcNeverReturnsNullPointer => Yes,
|
||||
RustcNoImplicitAutorefs => Yes,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::num::NonZero;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use rustc_abi::Align;
|
||||
use rustc_ast::attr::data_structures::CfgEntry;
|
||||
|
|
@ -96,7 +97,15 @@ impl<T: PrintAttribute> PrintAttribute for FxIndexMap<T, Span> {
|
|||
p.word("]");
|
||||
}
|
||||
}
|
||||
impl PrintAttribute for PathBuf {
|
||||
fn should_render(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn print_attribute(&self, p: &mut Printer) {
|
||||
p.word(self.display().to_string());
|
||||
}
|
||||
}
|
||||
macro_rules! print_skip {
|
||||
($($t: ty),* $(,)?) => {$(
|
||||
impl PrintAttribute for $t {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ edition = "2024"
|
|||
polonius-engine = "0.13.0"
|
||||
regex = "1"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
rustc_graphviz = { path = "../rustc_graphviz" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
mir_dataflow_duplicate_values_for =
|
||||
duplicate values for `{$name}`
|
||||
|
||||
mir_dataflow_path_must_end_in_filename =
|
||||
path must end in a filename
|
||||
|
||||
mir_dataflow_peek_argument_not_a_local =
|
||||
rustc_peek: argument was not a local
|
||||
|
||||
|
|
@ -19,11 +13,5 @@ mir_dataflow_peek_must_be_not_temporary =
|
|||
mir_dataflow_peek_must_be_place_or_ref_place =
|
||||
rustc_peek: argument expression must be either `place` or `&place`
|
||||
|
||||
mir_dataflow_requires_an_argument =
|
||||
`{$name}` requires an argument
|
||||
|
||||
mir_dataflow_stop_after_dataflow_ended_compilation =
|
||||
stop_after_dataflow ended compilation
|
||||
|
||||
mir_dataflow_unknown_formatter =
|
||||
unknown formatter
|
||||
|
|
|
|||
|
|
@ -1,35 +1,5 @@
|
|||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_path_must_end_in_filename)]
|
||||
pub(crate) struct PathMustEndInFilename {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_unknown_formatter)]
|
||||
pub(crate) struct UnknownFormatter {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_duplicate_values_for)]
|
||||
pub(crate) struct DuplicateValuesFor {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_requires_an_argument)]
|
||||
pub(crate) struct RequiresAnArgument {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
use rustc_span::Span;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_dataflow_stop_after_dataflow_ended_compilation)]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ use std::sync::OnceLock;
|
|||
use std::{io, ops, str};
|
||||
|
||||
use regex::Regex;
|
||||
use rustc_graphviz as dot;
|
||||
use rustc_hir::attrs::{AttributeKind, BorrowckGraphvizFormatKind, RustcMirKind};
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_index::bit_set::DenseBitSet;
|
||||
use rustc_middle::mir::{
|
||||
self, BasicBlock, Body, Location, MirDumper, graphviz_safe_def_name, traversal,
|
||||
|
|
@ -14,17 +17,12 @@ use rustc_middle::mir::{
|
|||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{Symbol, sym};
|
||||
use tracing::debug;
|
||||
use {rustc_ast as ast, rustc_graphviz as dot};
|
||||
|
||||
use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext};
|
||||
use super::{
|
||||
Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor, visit_results,
|
||||
};
|
||||
use crate::errors::{
|
||||
DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter,
|
||||
};
|
||||
|
||||
/// Writes a DOT file containing the results of a dataflow analysis if the user requested it via
|
||||
/// `rustc_mir` attributes and `-Z dump-mir-dataflow`. The `Result` in and the `Results` out are
|
||||
|
|
@ -43,10 +41,7 @@ where
|
|||
use std::io::Write;
|
||||
|
||||
let def_id = body.source.def_id();
|
||||
let Ok(attrs) = RustcMirAttrs::parse(tcx, def_id) else {
|
||||
// Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
|
||||
return Ok(());
|
||||
};
|
||||
let attrs = RustcMirAttrs::parse(tcx, def_id);
|
||||
|
||||
let file = try {
|
||||
match attrs.output_path(A::NAME) {
|
||||
|
|
@ -72,10 +67,7 @@ where
|
|||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let style = match attrs.formatter {
|
||||
Some(sym::two_phase) => OutputStyle::BeforeAndAfter,
|
||||
_ => OutputStyle::AfterOnly,
|
||||
};
|
||||
let style = attrs.formatter.unwrap_or(OutputStyle::AfterOnly);
|
||||
|
||||
let mut buf = Vec::new();
|
||||
|
||||
|
|
@ -98,71 +90,33 @@ where
|
|||
#[derive(Default)]
|
||||
struct RustcMirAttrs {
|
||||
basename_and_suffix: Option<PathBuf>,
|
||||
formatter: Option<Symbol>,
|
||||
formatter: Option<OutputStyle>,
|
||||
}
|
||||
|
||||
impl RustcMirAttrs {
|
||||
fn parse(tcx: TyCtxt<'_>, def_id: DefId) -> Result<Self, ()> {
|
||||
let mut result = Ok(());
|
||||
fn parse(tcx: TyCtxt<'_>, def_id: DefId) -> Self {
|
||||
let mut ret = RustcMirAttrs::default();
|
||||
|
||||
let rustc_mir_attrs = tcx
|
||||
.get_attrs(def_id, sym::rustc_mir)
|
||||
.flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter()));
|
||||
|
||||
for attr in rustc_mir_attrs {
|
||||
let attr_result = match attr.name() {
|
||||
Some(name @ sym::borrowck_graphviz_postflow) => {
|
||||
Self::set_field(&mut ret.basename_and_suffix, tcx, name, &attr, |s| {
|
||||
let path = PathBuf::from(s.to_string());
|
||||
match path.file_name() {
|
||||
Some(_) => Ok(path),
|
||||
None => {
|
||||
tcx.dcx().emit_err(PathMustEndInFilename { span: attr.span() });
|
||||
Err(())
|
||||
let attrs = tcx.get_all_attrs(def_id);
|
||||
if let Some(rustc_mir_attrs) = find_attr!(attrs, AttributeKind::RustcMir(kind) => kind) {
|
||||
for attr in rustc_mir_attrs {
|
||||
match attr {
|
||||
RustcMirKind::BorrowckGraphvizPostflow { path } => {
|
||||
ret.basename_and_suffix = Some(path.clone());
|
||||
}
|
||||
RustcMirKind::BorrowckGraphvizFormat { format } => {
|
||||
ret.formatter = match format {
|
||||
BorrowckGraphvizFormatKind::TwoPhase => {
|
||||
Some(OutputStyle::BeforeAndAfter)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Some(name @ sym::borrowck_graphviz_format) => {
|
||||
Self::set_field(&mut ret.formatter, tcx, name, &attr, |s| match s {
|
||||
sym::two_phase => Ok(s),
|
||||
_ => {
|
||||
tcx.dcx().emit_err(UnknownFormatter { span: attr.span() });
|
||||
Err(())
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => Ok(()),
|
||||
};
|
||||
|
||||
result = result.and(attr_result);
|
||||
};
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
result.map(|()| ret)
|
||||
}
|
||||
|
||||
fn set_field<T>(
|
||||
field: &mut Option<T>,
|
||||
tcx: TyCtxt<'_>,
|
||||
name: Symbol,
|
||||
attr: &ast::MetaItemInner,
|
||||
mapper: impl FnOnce(Symbol) -> Result<T, ()>,
|
||||
) -> Result<(), ()> {
|
||||
if field.is_some() {
|
||||
tcx.dcx().emit_err(DuplicateValuesFor { span: attr.span(), name });
|
||||
|
||||
return Err(());
|
||||
}
|
||||
|
||||
if let Some(s) = attr.value_str() {
|
||||
*field = Some(mapper(s)?);
|
||||
Ok(())
|
||||
} else {
|
||||
tcx.dcx()
|
||||
.emit_err(RequiresAnArgument { span: attr.span(), name: attr.name().unwrap() });
|
||||
Err(())
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
/// Returns the path where dataflow results should be written, or `None`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_ast::MetaItem;
|
||||
use rustc_hir::attrs::{AttributeKind, RustcMirKind};
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_middle::mir::{self, Body, Local, Location};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_span::{Span, sym};
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::errors::{
|
||||
|
|
@ -14,52 +14,37 @@ use crate::impls::{MaybeInitializedPlaces, MaybeLiveLocals, MaybeUninitializedPl
|
|||
use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
|
||||
use crate::{Analysis, JoinSemiLattice, ResultsCursor};
|
||||
|
||||
fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<MetaItem> {
|
||||
for attr in tcx.get_attrs(def_id, sym::rustc_mir) {
|
||||
let items = attr.meta_item_list();
|
||||
for item in items.iter().flat_map(|l| l.iter()) {
|
||||
match item.meta_item() {
|
||||
Some(mi) if mi.has_name(name) => return Some(mi.clone()),
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
let def_id = body.source.def_id();
|
||||
if !tcx.has_attr(def_id, sym::rustc_mir) {
|
||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
||||
return;
|
||||
} else {
|
||||
let attrs = tcx.get_all_attrs(def_id);
|
||||
if let Some(kind) = find_attr!(attrs, AttributeKind::RustcMir(kind) => kind) {
|
||||
let move_data = MoveData::gather_moves(body, tcx, |_| true);
|
||||
debug!("running rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
||||
}
|
||||
if kind.contains(&RustcMirKind::PeekMaybeInit) {
|
||||
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
|
||||
.iterate_to_fixpoint(tcx, body, None)
|
||||
.into_results_cursor(body);
|
||||
sanity_check_via_rustc_peek(tcx, flow_inits);
|
||||
}
|
||||
|
||||
let move_data = MoveData::gather_moves(body, tcx, |_| true);
|
||||
if kind.contains(&RustcMirKind::PeekMaybeUninit) {
|
||||
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
|
||||
.iterate_to_fixpoint(tcx, body, None)
|
||||
.into_results_cursor(body);
|
||||
sanity_check_via_rustc_peek(tcx, flow_uninits);
|
||||
}
|
||||
|
||||
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
|
||||
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
|
||||
.iterate_to_fixpoint(tcx, body, None)
|
||||
.into_results_cursor(body);
|
||||
sanity_check_via_rustc_peek(tcx, flow_inits);
|
||||
}
|
||||
if kind.contains(&RustcMirKind::PeekLiveness) {
|
||||
let flow_liveness =
|
||||
MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body);
|
||||
sanity_check_via_rustc_peek(tcx, flow_liveness);
|
||||
}
|
||||
|
||||
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_uninit).is_some() {
|
||||
let flow_uninits = MaybeUninitializedPlaces::new(tcx, body, &move_data)
|
||||
.iterate_to_fixpoint(tcx, body, None)
|
||||
.into_results_cursor(body);
|
||||
sanity_check_via_rustc_peek(tcx, flow_uninits);
|
||||
}
|
||||
|
||||
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_liveness).is_some() {
|
||||
let flow_liveness =
|
||||
MaybeLiveLocals.iterate_to_fixpoint(tcx, body, None).into_results_cursor(body);
|
||||
sanity_check_via_rustc_peek(tcx, flow_liveness);
|
||||
}
|
||||
|
||||
if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
|
||||
tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation);
|
||||
if kind.contains(&RustcMirKind::StopAfterDataflow) {
|
||||
tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation);
|
||||
}
|
||||
} else {
|
||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| AttributeKind::RustcLintUntrackedQueryInformation
|
||||
| AttributeKind::RustcMacroTransparency(_)
|
||||
| AttributeKind::RustcMain
|
||||
| AttributeKind::RustcMir(_)
|
||||
| AttributeKind::RustcNeverReturnsNullPointer
|
||||
| AttributeKind::RustcNoImplicitAutorefs
|
||||
| AttributeKind::RustcNonConstTraitMethod
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue