Merge from rustc

This commit is contained in:
Ralf Jung 2023-10-20 08:03:38 +02:00
commit 20fe485c57
385 changed files with 1762 additions and 754 deletions

View File

@ -4271,7 +4271,6 @@ dependencies = [
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_session",

View File

@ -23,7 +23,7 @@ use crate::{
use rustc_lint_defs::pluralize;
use derive_setters::Setters;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend, Lrc};
use rustc_error_messages::{FluentArgs, SpanLabel};
use rustc_span::hygiene::{ExpnKind, MacroKind};
@ -370,7 +370,7 @@ pub trait Emitter: Translate {
}
fn render_multispan_macro_backtrace(&self, span: &mut MultiSpan, always_backtrace: bool) {
let mut new_labels: Vec<(Span, String)> = vec![];
let mut new_labels = FxIndexSet::default();
for &sp in span.primary_spans() {
if sp.is_dummy() {
@ -387,7 +387,7 @@ pub trait Emitter: Translate {
}
if always_backtrace {
new_labels.push((
new_labels.insert((
trace.def_site,
format!(
"in this expansion of `{}`{}",
@ -431,7 +431,7 @@ pub trait Emitter: Translate {
format!("this {} desugaring", kind.descr()).into()
}
};
new_labels.push((
new_labels.insert((
trace.call_site,
format!(
"in {}{}",

View File

@ -26,7 +26,6 @@ use rustc_infer::infer::{
RegionVariableOrigin,
};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::util::supertraits;
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
@ -40,7 +39,7 @@ use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplem
use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{
FulfillmentError, Obligation, ObligationCause, ObligationCauseCode,
supertraits, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode,
};
use std::borrow::Cow;

View File

@ -2,7 +2,7 @@ use smallvec::smallvec;
use crate::infer::outlives::components::{push_outlives_components, Component};
use crate::traits::{self, Obligation, PredicateObligation};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::Ident;
use rustc_span::Span;
@ -76,7 +76,13 @@ impl<'tcx> Extend<ty::Predicate<'tcx>> for PredicateSet<'tcx> {
pub struct Elaborator<'tcx, O> {
stack: Vec<O>,
visited: PredicateSet<'tcx>,
only_self: bool,
mode: Filter,
}
enum Filter {
All,
OnlySelf,
OnlySelfThatDefines(Ident),
}
/// Describes how to elaborate an obligation into a sub-obligation.
@ -224,7 +230,7 @@ pub fn elaborate<'tcx, O: Elaboratable<'tcx>>(
obligations: impl IntoIterator<Item = O>,
) -> Elaborator<'tcx, O> {
let mut elaborator =
Elaborator { stack: Vec::new(), visited: PredicateSet::new(tcx), only_self: false };
Elaborator { stack: Vec::new(), visited: PredicateSet::new(tcx), mode: Filter::All };
elaborator.extend_deduped(obligations);
elaborator
}
@ -242,7 +248,13 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
/// Filter to only the supertraits of trait predicates, i.e. only the predicates
/// that have `Self` as their self type, instead of all implied predicates.
pub fn filter_only_self(mut self) -> Self {
self.only_self = true;
self.mode = Filter::OnlySelf;
self
}
/// Filter to only the supertraits of trait predicates that define the assoc_ty.
pub fn filter_only_self_that_defines(mut self, assoc_ty: Ident) -> Self {
self.mode = Filter::OnlySelfThatDefines(assoc_ty);
self
}
@ -257,10 +269,12 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
return;
}
// Get predicates implied by the trait, or only super predicates if we only care about self predicates.
let predicates = if self.only_self {
tcx.super_predicates_of(data.def_id())
} else {
tcx.implied_predicates_of(data.def_id())
let predicates = match self.mode {
Filter::All => tcx.implied_predicates_of(data.def_id()),
Filter::OnlySelf => tcx.super_predicates_of(data.def_id()),
Filter::OnlySelfThatDefines(ident) => {
tcx.super_predicates_that_define_assoc_item((data.def_id(), ident))
}
};
let obligations =
@ -409,14 +423,14 @@ impl<'tcx, O: Elaboratable<'tcx>> Iterator for Elaborator<'tcx, O> {
pub fn supertraits<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
) -> FilterToTraits<Elaborator<'tcx, ty::Predicate<'tcx>>> {
elaborate(tcx, [trait_ref.to_predicate(tcx)]).filter_only_self().filter_to_traits()
}
pub fn transitive_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
) -> FilterToTraits<Elaborator<'tcx, ty::Predicate<'tcx>>> {
elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.to_predicate(tcx)))
.filter_only_self()
.filter_to_traits()
@ -429,31 +443,12 @@ pub fn transitive_bounds<'tcx>(
/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
pub fn transitive_bounds_that_define_assoc_item<'tcx>(
tcx: TyCtxt<'tcx>,
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
assoc_name: Ident,
) -> impl Iterator<Item = ty::PolyTraitRef<'tcx>> {
let mut stack: Vec<_> = bounds.collect();
let mut visited = FxIndexSet::default();
std::iter::from_fn(move || {
while let Some(trait_ref) = stack.pop() {
let anon_trait_ref = tcx.anonymize_bound_vars(trait_ref);
if visited.insert(anon_trait_ref) {
let super_predicates =
tcx.super_predicates_that_define_assoc_item((trait_ref.def_id(), assoc_name));
for (super_predicate, _) in super_predicates.predicates {
let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref);
if let Some(binder) = subst_predicate.as_trait_clause() {
stack.push(binder.map_bound(|t| t.trait_ref));
}
}
return Some(trait_ref);
}
}
return None;
})
) -> FilterToTraits<Elaborator<'tcx, ty::Predicate<'tcx>>> {
elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.to_predicate(tcx)))
.filter_only_self_that_defines(assoc_name)
.filter_to_traits()
}
///////////////////////////////////////////////////////////////////////////

View File

@ -4,9 +4,10 @@ use crate::{
};
use rustc_hir as hir;
use rustc_middle::{traits::util::supertraits, ty};
use rustc_middle::ty;
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_span::sym;
use rustc_trait_selection::traits::supertraits;
declare_lint! {
/// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the

View File

@ -3,9 +3,10 @@ use rustc_data_structures::fx::FxHashSet;
use crate::ty::{PolyTraitRef, TyCtxt};
/// Given a PolyTraitRef, get the PolyTraitRefs of the trait's (transitive) supertraits.
///
/// A simplified version of the same function at `rustc_infer::traits::util::supertraits`.
pub fn supertraits<'tcx>(
/// This only exists in `rustc_middle` because the more powerful elaborator depends on
/// `rustc_infer` for elaborating outlives bounds -- this should only be used for pretty
/// printing.
pub fn supertraits_for_pretty_printing<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: PolyTraitRef<'tcx>,
) -> impl Iterator<Item = PolyTraitRef<'tcx>> {

View File

@ -1,6 +1,7 @@
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::query::IntoQueryParam;
use crate::query::Providers;
use crate::traits::util::supertraits_for_pretty_printing;
use crate::ty::{
self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@ -1150,14 +1151,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
entry.has_fn_once = true;
return;
} else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() {
let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();
fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
return;
} else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() {
let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();

View File

@ -13,7 +13,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_hir = { path = "../rustc_hir" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_session = { path = "../rustc_session" }

View File

@ -27,8 +27,6 @@ monomorphize_type_length_limit = reached the type-length limit while instantiati
monomorphize_unknown_cgu_collection_mode =
unknown codegen-item collection mode '{$mode}', falling back to 'lazy' mode
monomorphize_unknown_partition_strategy = unknown partitioning strategy
monomorphize_unused_generic_params = item has unused generic parameters
monomorphize_written_to_path = the full type name has been written to '{$path}'

View File

@ -173,7 +173,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, GlobalAlloc, Scalar};
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
use rustc_middle::mir::visit::Visitor as MirVisitor;
use rustc_middle::mir::{self, Local, Location};
use rustc_middle::mir::{self, Location};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
use rustc_middle::ty::print::with_no_trimmed_paths;
@ -874,14 +874,6 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
self.super_operand(operand, location);
self.check_operand_move_size(operand, location);
}
fn visit_local(
&mut self,
_place_local: Local,
_context: mir::visit::PlaceContext,
_location: Location,
) {
}
}
fn visit_drop_use<'tcx>(
@ -1220,7 +1212,7 @@ impl<'v> RootCollector<'_, 'v> {
}
fn is_root(&self, def_id: LocalDefId) -> bool {
!item_requires_monomorphization(self.tcx, def_id)
!self.tcx.generics_of(def_id).requires_monomorphization(self.tcx)
&& match self.mode {
MonoItemCollectionMode::Eager => true,
MonoItemCollectionMode::Lazy => {
@ -1283,11 +1275,6 @@ impl<'v> RootCollector<'_, 'v> {
}
}
fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
let generics = tcx.generics_of(def_id);
generics.requires_monomorphization(tcx)
}
#[instrument(level = "debug", skip(tcx, output))]
fn create_mono_items_for_default_impls<'tcx>(
tcx: TyCtxt<'tcx>,
@ -1394,17 +1381,6 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
}
}
fn add_assoc_fn<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: Option<DefId>,
fn_ident: Ident,
skip_move_check_fns: &mut Vec<DefId>,
) {
if let Some(def_id) = def_id.and_then(|def_id| assoc_fn_of_type(tcx, def_id, fn_ident)) {
skip_move_check_fns.push(def_id);
}
}
fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option<DefId> {
for impl_def_id in tcx.inherent_impls(def_id) {
if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
@ -1420,26 +1396,16 @@ fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) ->
}
fn build_skip_move_check_fns(tcx: TyCtxt<'_>) -> Vec<DefId> {
let mut skip_move_check_fns = vec![];
add_assoc_fn(
tcx,
tcx.lang_items().owned_box(),
Ident::from_str("new"),
&mut skip_move_check_fns,
);
add_assoc_fn(
tcx,
tcx.get_diagnostic_item(sym::Arc),
Ident::from_str("new"),
&mut skip_move_check_fns,
);
add_assoc_fn(
tcx,
tcx.get_diagnostic_item(sym::Rc),
Ident::from_str("new"),
&mut skip_move_check_fns,
);
skip_move_check_fns
let fns = [
(tcx.lang_items().owned_box(), "new"),
(tcx.get_diagnostic_item(sym::Rc), "new"),
(tcx.get_diagnostic_item(sym::Arc), "new"),
];
fns.into_iter()
.filter_map(|(def_id, fn_name)| {
def_id.and_then(|def_id| assoc_fn_of_type(tcx, def_id, Ident::from_str(fn_name)))
})
.collect::<Vec<_>>()
}
/// Scans the MIR in order to find function calls, closures, and drop-glue.

View File

@ -75,10 +75,6 @@ pub struct LargeAssignmentsLint {
pub limit: u64,
}
#[derive(Diagnostic)]
#[diag(monomorphize_unknown_partition_strategy)]
pub struct UnknownPartitionStrategy;
#[derive(Diagnostic)]
#[diag(monomorphize_symbol_already_defined)]
pub struct SymbolAlreadyDefined {

View File

@ -2,7 +2,8 @@ mod buffer;
use crate::fmt;
use crate::io::{
self, BorrowedCursor, BufRead, IoSliceMut, Read, Seek, SeekFrom, SizeHint, DEFAULT_BUF_SIZE,
self, uninlined_slow_read_byte, BorrowedCursor, BufRead, IoSliceMut, Read, Seek, SeekFrom,
SizeHint, SpecReadByte, DEFAULT_BUF_SIZE,
};
use buffer::Buffer;
@ -259,6 +260,22 @@ impl<R: ?Sized + Seek> BufReader<R> {
}
}
impl<R> SpecReadByte for BufReader<R>
where
Self: Read,
{
#[inline]
fn spec_read_byte(&mut self) -> Option<io::Result<u8>> {
let mut byte = 0;
if self.buf.consume_with(1, |claimed| byte = claimed[0]) {
return Some(Ok(byte));
}
// Fallback case, only reached once per buffer refill.
uninlined_slow_read_byte(self)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<R: ?Sized + Read> Read for BufReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@ -269,10 +286,8 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
self.discard_buffer();
return self.inner.read(buf);
}
let nread = {
let mut rem = self.fill_buf()?;
rem.read(buf)?
};
let mut rem = self.fill_buf()?;
let nread = rem.read(buf)?;
self.consume(nread);
Ok(nread)
}

View File

@ -2777,17 +2777,10 @@ pub struct Bytes<R> {
impl<R: Read> Iterator for Bytes<R> {
type Item = Result<u8>;
#[inline]
// Not `#[inline]`. This function gets inlined even without it, but having
// the inline annotation can result in worse code generation. See #116785.
fn next(&mut self) -> Option<Result<u8>> {
let mut byte = 0;
loop {
return match self.inner.read(slice::from_mut(&mut byte)) {
Ok(0) => None,
Ok(..) => Some(Ok(byte)),
Err(ref e) if e.is_interrupted() => continue,
Err(e) => Some(Err(e)),
};
}
SpecReadByte::spec_read_byte(&mut self.inner)
}
#[inline]
@ -2796,6 +2789,43 @@ impl<R: Read> Iterator for Bytes<R> {
}
}
/// For the specialization of `Bytes::next`.
trait SpecReadByte {
fn spec_read_byte(&mut self) -> Option<Result<u8>>;
}
impl<R> SpecReadByte for R
where
Self: Read,
{
#[inline]
default fn spec_read_byte(&mut self) -> Option<Result<u8>> {
inlined_slow_read_byte(self)
}
}
/// Read a single byte in a slow, generic way. This is used by the default
/// `spec_read_byte`.
#[inline]
fn inlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> {
let mut byte = 0;
loop {
return match reader.read(slice::from_mut(&mut byte)) {
Ok(0) => None,
Ok(..) => Some(Ok(byte)),
Err(ref e) if e.is_interrupted() => continue,
Err(e) => Some(Err(e)),
};
}
}
// Used by `BufReader::spec_read_byte`, for which the `inline(ever)` is
// important.
#[inline(never)]
fn uninlined_slow_read_byte<R: Read>(reader: &mut R) -> Option<Result<u8>> {
inlined_slow_read_byte(reader)
}
trait SizeHint {
fn lower_bound(&self) -> usize;

View File

@ -0,0 +1,24 @@
# `remap-path-scope`
The tracking issue for this feature is: [#111540](https://github.com/rust-lang/rust/issues/111540).
------------------------
When the `--remap-path-prefix` option is passed to rustc, source path prefixes in all output will be affected by default.
The `--remap-path-scope` argument can be used in conjunction with `--remap-path-prefix` to determine paths in which output context should be affected.
This flag accepts a comma-separated list of values and may be specified multiple times, in which case the scopes are aggregated together. The valid scopes are:
- `macro` - apply remappings to the expansion of `std::file!()` macro. This is where paths in embedded panic messages come from
- `diagnostics` - apply remappings to printed compiler diagnostics
- `unsplit-debuginfo` - apply remappings to debug information only when they are written to compiled executables or libraries, but not when they are in split debuginfo files
- `split-debuginfo` - apply remappings to debug information only when they are written to split debug information files, but not in compiled executables or libraries
- `split-debuginfo-path` - apply remappings to the paths pointing to split debug information files. Does nothing when these files are not generated.
- `object` - an alias for `macro,unsplit-debuginfo,split-debuginfo-path`. This ensures all paths in compiled executables or libraries are remapped, but not elsewhere.
- `all` and `true` - an alias for all of the above, also equivalent to supplying only `--remap-path-prefix` without `--remap-path-scope`.
## Example
```sh
# This would produce an absolute path to main.rs in build outputs of
# "./main.rs".
rustc --remap-path-prefix=$(PWD)=/remapped -Zremap-path-prefix=object main.rs
```

View File

@ -225,7 +225,8 @@ impl SourceCollector<'_, '_> {
cur.push(&fname);
let title = format!("{} - source", src_fname.to_string_lossy());
let desc = format!("Source of the Rust file `{}`.", filename.prefer_remapped());
let desc =
format!("Source of the Rust file `{}`.", filename.prefer_remapped_unconditionaly());
let page = layout::Page {
title: &title,
css_class: "src",

View File

@ -494,7 +494,7 @@ impl SerializableSpan {
let loc: Loc = cx.sess().source_map().lookup_char_pos(span.lo());
Self {
path: format!("{}", loc.file.name.prefer_remapped()),
path: format!("{}", loc.file.name.prefer_remapped_unconditionaly()),
line: loc.line,
}
}

View File

@ -15,6 +15,7 @@ use crate::json;
use crate::read2::{read2_abbreviated, Truncated};
use crate::util::{add_dylib_path, dylib_env_var, logv, PathBufExt};
use crate::ColorConfig;
use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
use regex::{Captures, Regex};
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@ -229,6 +230,7 @@ enum Emit {
None,
Metadata,
LlvmIr,
Mir,
Asm,
LinkArgsAsm,
}
@ -2506,6 +2508,9 @@ impl<'test> TestCx<'test> {
Emit::LlvmIr => {
rustc.args(&["--emit", "llvm-ir"]);
}
Emit::Mir => {
rustc.args(&["--emit", "mir"]);
}
Emit::Asm => {
rustc.args(&["--emit", "asm"]);
}
@ -3984,11 +3989,17 @@ impl<'test> TestCx<'test> {
fn run_mir_opt_test(&self) {
let pm = self.pass_mode();
let should_run = self.should_run(pm);
let emit_metadata = self.should_emit_metadata(pm);
let passes = self.get_passes();
let proc_res = self.compile_test_with_passes(should_run, emit_metadata, passes);
self.check_mir_dump();
let mut test_info = files_for_miropt_test(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
let passes = std::mem::take(&mut test_info.passes);
let proc_res = self.compile_test_with_passes(should_run, Emit::Mir, passes);
self.check_mir_dump(test_info);
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}
@ -4002,37 +4013,12 @@ impl<'test> TestCx<'test> {
}
}
fn get_passes(&self) -> Vec<String> {
let files = miropt_test_tools::files_for_miropt_test(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
let mut out = Vec::new();
for miropt_test_tools::MiroptTestFiles {
from_file: _,
to_file: _,
expected_file: _,
passes,
} in files
{
out.extend(passes);
}
out
}
fn check_mir_dump(&self) {
fn check_mir_dump(&self, test_info: MiroptTest) {
let test_dir = self.testpaths.file.parent().unwrap();
let test_crate =
self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace("-", "_");
let suffix = miropt_test_tools::output_file_suffix(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
let MiroptTest { run_filecheck, suffix, files, passes: _ } = test_info;
if self.config.bless {
for e in
@ -4047,14 +4033,7 @@ impl<'test> TestCx<'test> {
}
}
let files = miropt_test_tools::files_for_miropt_test(
&self.testpaths.file,
self.config.get_pointer_width(),
self.config.target_cfg().panic.for_miropt_test_tools(),
);
for miropt_test_tools::MiroptTestFiles { from_file, to_file, expected_file, passes: _ } in
files
{
for MiroptTestFile { from_file, to_file, expected_file } in files {
let dumped_string = if let Some(after) = to_file {
self.diff_mir_files(from_file.into(), after.into())
} else {
@ -4095,6 +4074,14 @@ impl<'test> TestCx<'test> {
}
}
}
if run_filecheck {
let output_path = self.output_base_name().with_extension("mir");
let proc_res = self.verify_with_filecheck(&output_path);
if !proc_res.status.success() {
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
}
}
}
fn diff_mir_files(&self, before: PathBuf, after: PathBuf) -> String {

View File

@ -135,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.tcx.sess.source_map().lookup_char_pos(BytePos(offset.bytes().try_into().unwrap()));
let name = fn_instance.to_string();
let filename = lo.file.name.prefer_remapped().to_string();
let filename = lo.file.name.prefer_remapped_unconditionaly().to_string();
Ok((fn_instance, lo, name, filename))
}

View File

@ -1,10 +1,16 @@
use std::fs;
use std::path::Path;
pub struct MiroptTestFiles {
pub struct MiroptTestFile {
pub expected_file: std::path::PathBuf,
pub from_file: String,
pub to_file: Option<String>,
}
pub struct MiroptTest {
pub run_filecheck: bool,
pub suffix: String,
pub files: Vec<MiroptTestFile>,
/// Vec of passes under test to be dumped
pub passes: Vec<String>,
}
@ -14,11 +20,7 @@ pub enum PanicStrategy {
Abort,
}
pub fn output_file_suffix(
testfile: &Path,
bit_width: u32,
panic_strategy: PanicStrategy,
) -> String {
fn output_file_suffix(testfile: &Path, bit_width: u32, panic_strategy: PanicStrategy) -> String {
let mut each_bit_width = false;
let mut each_panic_strategy = false;
for line in fs::read_to_string(testfile).unwrap().lines() {
@ -47,7 +49,7 @@ pub fn files_for_miropt_test(
testfile: &std::path::Path,
bit_width: u32,
panic_strategy: PanicStrategy,
) -> Vec<MiroptTestFiles> {
) -> MiroptTest {
let mut out = Vec::new();
let test_file_contents = fs::read_to_string(&testfile).unwrap();
@ -55,8 +57,14 @@ pub fn files_for_miropt_test(
let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_");
let suffix = output_file_suffix(testfile, bit_width, panic_strategy);
let mut run_filecheck = true;
let mut passes = Vec::new();
for l in test_file_contents.lines() {
if l.starts_with("// skip-filecheck") {
run_filecheck = false;
continue;
}
if l.starts_with("// EMIT_MIR ") {
let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
let mut test_names = test_name.split(' ');
@ -65,7 +73,6 @@ pub fn files_for_miropt_test(
let mut expected_file;
let from_file;
let to_file;
let mut passes = Vec::new();
if test_name.ends_with(".diff") {
let trimmed = test_name.trim_end_matches(".diff");
@ -114,9 +121,9 @@ pub fn files_for_miropt_test(
}
let expected_file = test_dir.join(expected_file);
out.push(MiroptTestFiles { expected_file, from_file, to_file, passes });
out.push(MiroptTestFile { expected_file, from_file, to_file });
}
}
out
MiroptTest { run_filecheck, suffix, files: out, passes }
}

View File

@ -26,7 +26,8 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) {
for file in rs_files {
for bw in [32, 64] {
for ps in [PanicStrategy::Unwind, PanicStrategy::Abort] {
for output_file in miropt_test_tools::files_for_miropt_test(&file, bw, ps) {
let mir_opt_test = miropt_test_tools::files_for_miropt_test(&file, bw, ps);
for output_file in mir_opt_test.files {
output_files.remove(&output_file.expected_file);
}
}

View File

@ -49,3 +49,21 @@ This exists mainly for completeness and is rarely useful.
```
// EMIT_MIR $file_name_of_some_mir_dump.before.mir
```
# FileCheck directives
The LLVM FileCheck tool is used to verify the contents of output MIR against `CHECK` directives
present in the test file. This works on the runtime MIR, generated by `--emit=mir`, and not
on the output of a individual passes.
Use `// skip-filecheck` to prevent FileCheck from running.
To check MIR for function `foo`, start with a `// CHECK-LABEL fn foo(` directive.
`{{regex}}` syntax allows to match `regex`.
`[[name:regex]]` syntax allows to bind `name` to a string matching `regex`, and refer to it
as `[[name]]` in later directives, `regex` should be written not to match a leading space.
Use `[[my_local:_.*]]` to name a local, and `[[my_bb:bb.*]]` to name a block.
Documentation for FileCheck is available here: https://www.llvm.org/docs/CommandGuide/FileCheck.html

View File

@ -1,36 +1,36 @@
// MIR for `address_of_reborrow` after SimplifyCfg-initial
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:7:5: 7:18, inferred_ty: *const [i32; 10]
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:9:5: 9:25, inferred_ty: *const dyn std::marker::Send
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:13:12: 13:20, inferred_ty: *const [i32; 10]
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:14:12: 14:28, inferred_ty: *const [i32; 10]
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:15:12: 15:27, inferred_ty: *const dyn std::marker::Send
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32]
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:16:12: 16:24, inferred_ty: *const [i32]
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:18:5: 18:18, inferred_ty: *const [i32; 10]
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:20:5: 20:25, inferred_ty: *const dyn std::marker::Send
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:23:12: 23:20, inferred_ty: *const [i32; 10]
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:24:12: 24:28, inferred_ty: *const [i32; 10]
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:25:12: 25:27, inferred_ty: *const dyn std::marker::Send
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32]
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:26:12: 26:24, inferred_ty: *const [i32]
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:28:5: 28:16, inferred_ty: *mut [i32; 10]
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:30:5: 30:23, inferred_ty: *mut dyn std::marker::Send
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:33:12: 33:18, inferred_ty: *mut [i32; 10]
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:34:12: 34:26, inferred_ty: *mut [i32; 10]
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:35:12: 35:25, inferred_ty: *mut dyn std::marker::Send
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32]
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:36:12: 36:22, inferred_ty: *mut [i32]
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:8:5: 8:18, inferred_ty: *const [i32; 10]
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:10:5: 10:25, inferred_ty: *const dyn std::marker::Send
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:19:5: 19:18, inferred_ty: *const [i32; 10]
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:21:5: 21:25, inferred_ty: *const dyn std::marker::Send
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:29:5: 29:16, inferred_ty: *mut [i32; 10]
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:31:5: 31:23, inferred_ty: *mut dyn std::marker::Send
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
fn address_of_reborrow() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR address_of.address_of_reborrow.SimplifyCfg-initial.after.mir
fn address_of_reborrow() {

View File

@ -1,3 +1,4 @@
// unit-test: SimplifyCfg-elaborate-drops
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// Retagging (from Stacked Borrows) relies on the array index being a fresh
// temporary, so that side-effects cannot change it.
@ -11,6 +12,12 @@ unsafe fn foo(z: *mut usize) -> u32 {
// EMIT_MIR array_index_is_temporary.main.SimplifyCfg-elaborate-drops.after.mir
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug x => [[x:_.*]];
// CHECK: debug y => [[y:_.*]];
// CHECK: [[y]] = const 1_usize;
// CHECK: [[tmp:_.*]] = [[y]];
// CHECK: [[x]][[[tmp]]] =
let mut x = [42, 43, 44];
let mut y = 1;
let z: *mut usize = &mut y;

View File

@ -9,6 +9,9 @@
// EMIT_MIR asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
fn main() {
// CHECK-LABEL: fn main(
// CHECK: asm!(
// CHECK-SAME: unwind terminate(abi)
unsafe {
std::arch::asm!("", options(may_unwind));
}

View File

@ -1,8 +1,8 @@
// MIR for `main` after SimplifyCfg-initial
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:20:17: 20:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 1: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:20:17: 20:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 0: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 1: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
fn main() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// unit-test: ElaborateDrops
// needs-unwind
// this tests move up progration, which is not yet implemented
@ -10,6 +11,23 @@
// destruction.
fn main() {
// CHECK-LABEL: fn main(
// CHECK: debug nodrop_x => [[nodrop_x:_.*]];
// CHECK: debug nodrop_y => [[nodrop_y:_.*]];
// CHECK: debug drop_x => [[drop_x:_.*]];
// CHECK: debug drop_y => [[drop_y:_.*]];
// CHECK-NOT: drop([[nodrop_x]])
// CHECK-NOT: drop([[nodrop_y]])
// CHECK-NOT: drop([[drop_x]])
// CHECK: [[drop_tmp:_.*]] = move [[drop_x]];
// CHECK-NOT: drop([[drop_x]])
// CHECK-NOT: drop([[drop_tmp]])
// CHECK: [[drop_y]] = move [[drop_tmp]];
// CHECK-NOT: drop([[drop_x]])
// CHECK-NOT: drop([[drop_tmp]])
// CHECK: drop([[drop_y]])
// CHECK-NOT: drop([[drop_x]])
// CHECK-NOT: drop([[drop_tmp]])
let nodrop_x = false;
let nodrop_y;

View File

@ -1,28 +0,0 @@
// unit-test: InstSimplify
// EMIT_MIR bool_compare.opt1.InstSimplify.diff
fn opt1(x: bool) -> u32 {
if x != true { 0 } else { 1 }
}
// EMIT_MIR bool_compare.opt2.InstSimplify.diff
fn opt2(x: bool) -> u32 {
if true != x { 0 } else { 1 }
}
// EMIT_MIR bool_compare.opt3.InstSimplify.diff
fn opt3(x: bool) -> u32 {
if x == false { 0 } else { 1 }
}
// EMIT_MIR bool_compare.opt4.InstSimplify.diff
fn opt4(x: bool) -> u32 {
if false == x { 0 } else { 1 }
}
fn main() {
opt1(false);
opt2(false);
opt3(false);
opt4(false);
}

View File

@ -1,71 +0,0 @@
// MIR for `main` before ElaborateDrops
fn main() -> () {
let mut _0: ();
let _1: std::boxed::Box<S>;
let mut _2: usize;
let mut _3: usize;
let mut _4: *mut u8;
let mut _5: std::boxed::Box<S>;
let _6: ();
let mut _7: std::boxed::Box<S>;
scope 1 {
debug x => _1;
}
scope 2 {
}
bb0: {
StorageLive(_1);
_2 = SizeOf(S);
_3 = AlignOf(S);
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind: bb9];
}
bb1: {
StorageLive(_5);
_5 = ShallowInitBox(move _4, S);
(*_5) = S::new() -> [return: bb2, unwind: bb8];
}
bb2: {
_1 = move _5;
drop(_5) -> [return: bb3, unwind: bb9];
}
bb3: {
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
_7 = move _1;
_6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6];
}
bb4: {
StorageDead(_7);
StorageDead(_6);
_0 = const ();
drop(_1) -> [return: bb5, unwind: bb9];
}
bb5: {
StorageDead(_1);
return;
}
bb6 (cleanup): {
drop(_7) -> [return: bb7, unwind terminate(cleanup)];
}
bb7 (cleanup): {
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
}
bb8 (cleanup): {
drop(_5) -> [return: bb9, unwind terminate(cleanup)];
}
bb9 (cleanup): {
resume;
}
}

View File

@ -1,71 +0,0 @@
// MIR for `main` before ElaborateDrops
fn main() -> () {
let mut _0: ();
let _1: std::boxed::Box<S>;
let mut _2: usize;
let mut _3: usize;
let mut _4: *mut u8;
let mut _5: std::boxed::Box<S>;
let _6: ();
let mut _7: std::boxed::Box<S>;
scope 1 {
debug x => _1;
}
scope 2 {
}
bb0: {
StorageLive(_1);
_2 = SizeOf(S);
_3 = AlignOf(S);
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
}
bb1: {
StorageLive(_5);
_5 = ShallowInitBox(move _4, S);
(*_5) = S::new() -> [return: bb2, unwind: bb8];
}
bb2: {
_1 = move _5;
drop(_5) -> [return: bb3, unwind continue];
}
bb3: {
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
_7 = move _1;
_6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6];
}
bb4: {
StorageDead(_7);
StorageDead(_6);
_0 = const ();
drop(_1) -> [return: bb5, unwind continue];
}
bb5: {
StorageDead(_1);
return;
}
bb6 (cleanup): {
drop(_7) -> [return: bb7, unwind terminate(cleanup)];
}
bb7 (cleanup): {
drop(_1) -> [return: bb9, unwind terminate(cleanup)];
}
bb8 (cleanup): {
drop(_5) -> [return: bb9, unwind terminate(cleanup)];
}
bb9 (cleanup): {
resume;
}
}

View File

@ -0,0 +1,89 @@
- // MIR for `main` before ElaborateDrops
+ // MIR for `main` after ElaborateDrops
fn main() -> () {
let mut _0: ();
let _1: std::boxed::Box<S>;
let mut _2: usize;
let mut _3: usize;
let mut _4: *mut u8;
let mut _5: std::boxed::Box<S>;
let _6: ();
let mut _7: std::boxed::Box<S>;
+ let mut _8: &mut std::boxed::Box<S>;
+ let mut _9: ();
scope 1 {
debug x => _1;
}
scope 2 {
}
bb0: {
StorageLive(_1);
_2 = SizeOf(S);
_3 = AlignOf(S);
_4 = alloc::alloc::exchange_malloc(move _2, move _3) -> [return: bb1, unwind continue];
}
bb1: {
StorageLive(_5);
_5 = ShallowInitBox(move _4, S);
(*_5) = S::new() -> [return: bb2, unwind: bb8];
}
bb2: {
_1 = move _5;
- drop(_5) -> [return: bb3, unwind continue];
+ goto -> bb3;
}
bb3: {
StorageDead(_5);
StorageLive(_6);
StorageLive(_7);
_7 = move _1;
_6 = std::mem::drop::<Box<S>>(move _7) -> [return: bb4, unwind: bb6];
}
bb4: {
StorageDead(_7);
StorageDead(_6);
_0 = const ();
- drop(_1) -> [return: bb5, unwind continue];
+ goto -> bb5;
}
bb5: {
StorageDead(_1);
return;
}
bb6 (cleanup): {
- drop(_7) -> [return: bb7, unwind terminate(cleanup)];
+ goto -> bb7;
}
bb7 (cleanup): {
- drop(_1) -> [return: bb9, unwind terminate(cleanup)];
+ goto -> bb9;
}
bb8 (cleanup): {
- drop(_5) -> [return: bb9, unwind terminate(cleanup)];
+ goto -> bb11;
}
bb9 (cleanup): {
resume;
+ }
+
+ bb10 (cleanup): {
+ _8 = &mut _5;
+ _9 = <Box<S> as Drop>::drop(move _8) -> [return: bb9, unwind terminate(cleanup)];
+ }
+
+ bb11 (cleanup): {
+ goto -> bb10;
}
}

View File

@ -1,9 +1,22 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ElaborateDrops
// needs-unwind
#![feature(rustc_attrs, stmt_expr_attributes)]
// EMIT_MIR box_expr.main.ElaborateDrops.before.mir
// EMIT_MIR box_expr.main.ElaborateDrops.diff
fn main() {
// CHECK-LABEL: fn main(
// CHECK: [[box:_.*]] = ShallowInitBox(
// CHECK: [[ptr:_.*]] = ((([[box]].0: std::ptr::Unique<S>).0: std::ptr::NonNull<S>).0: *const S);
// CHECK: (*[[ptr]]) = S::new() -> [return: [[ret:bb.*]], unwind: [[unwind:bb.*]]];
// CHECK: [[ret]]: {
// CHECK: [[box2:_.*]] = move [[box]];
// CHECK: [[box3:_.*]] = move [[box2]];
// CHECK: std::mem::drop::<Box<S>>(move [[box3]])
// CHECK: [[unwind]] (cleanup): {
// CHECK: [[boxref:_.*]] = &mut [[box]];
// CHECK: <Box<S> as Drop>::drop(move [[boxref]])
let x = #[rustc_box]
Box::new(S::new());
drop(x);

View File

@ -9,7 +9,7 @@
storage_conflicts: BitMatrix(0x0) {},
} */
fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>, _2: &mut Context<'_>) -> Poll<()> {
fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _4;
let mut _0: std::task::Poll<()>;
let mut _3: ();
@ -17,7 +17,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>
let mut _5: u32;
bb0: {
_5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16})));
_5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16})));
switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5];
}
@ -29,7 +29,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>
bb2: {
_0 = Poll::<()>::Ready(move _3);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}))) = 1;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}))) = 1;
return;
}

View File

@ -14,7 +14,7 @@
Static,
),
source_info: SourceInfo {
span: $DIR/async_await.rs:15:9: 15:14 (#8),
span: $DIR/async_await.rs:16:9: 16:14 (#8),
scope: scope[0],
},
ignore_for_traits: false,
@ -32,7 +32,7 @@
Static,
),
source_info: SourceInfo {
span: $DIR/async_await.rs:16:9: 16:14 (#10),
span: $DIR/async_await.rs:17:9: 17:14 (#10),
scope: scope[0],
},
ignore_for_traits: false,
@ -51,19 +51,19 @@
},
} */
fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, _2: &mut Context<'_>) -> Poll<()> {
fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, _2: &mut Context<'_>) -> Poll<()> {
debug _task_context => _38;
let mut _0: std::task::Poll<()>;
let _3: ();
let mut _4: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _5: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _6: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _4: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _5: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _6: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _7: ();
let _8: ();
let mut _9: std::task::Poll<()>;
let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
let mut _11: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _12: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>;
let mut _11: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _12: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _13: &mut std::task::Context<'_>;
let mut _14: &mut std::task::Context<'_>;
let mut _15: &mut std::task::Context<'_>;
@ -71,14 +71,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
let mut _18: !;
let mut _19: &mut std::task::Context<'_>;
let mut _20: ();
let mut _21: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _22: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _23: {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _21: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _22: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _23: {async fn body@$DIR/async_await.rs:12:14: 12:16};
let _24: ();
let mut _25: std::task::Poll<()>;
let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
let mut _27: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _28: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>;
let mut _27: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _28: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16};
let mut _29: &mut std::task::Context<'_>;
let mut _30: &mut std::task::Context<'_>;
let mut _31: &mut std::task::Context<'_>;
@ -90,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
let mut _38: &mut std::task::Context<'_>;
let mut _39: u32;
scope 1 {
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
let _17: ();
scope 2 {
}
@ -99,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
}
scope 4 {
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
let _33: ();
scope 5 {
}
@ -109,7 +109,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
bb0: {
_39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})));
_39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})));
switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30];
}
@ -122,13 +122,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
bb2: {
_4 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
_4 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
}
bb3: {
StorageDead(_5);
nop;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _4;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _4;
goto -> bb4;
}
@ -138,9 +138,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_10);
StorageLive(_11);
StorageLive(_12);
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
_12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
_11 = &mut (*_12);
_10 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
_10 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
}
bb5: {
@ -156,7 +156,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
bb6: {
_13 = &mut (*_14);
StorageDead(_15);
_9 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
_9 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
}
bb7: {
@ -176,7 +176,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_20);
_20 = ();
_0 = Poll::<()>::Pending;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2}))) = 3;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3;
return;
}
@ -193,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageDead(_12);
StorageDead(_9);
StorageDead(_8);
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb12, unwind unreachable];
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb12, unwind unreachable];
}
bb11: {
@ -218,13 +218,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
}
bb14: {
_21 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
_21 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
}
bb15: {
StorageDead(_22);
nop;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _21;
(((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _21;
goto -> bb16;
}
@ -234,9 +234,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_26);
StorageLive(_27);
StorageLive(_28);
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
_28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16});
_27 = &mut (*_28);
_26 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
_26 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
}
bb17: {
@ -252,7 +252,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
bb18: {
_29 = &mut (*_30);
StorageDead(_31);
_25 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
_25 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
}
bb19: {
@ -272,7 +272,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageLive(_36);
_36 = ();
_0 = Poll::<()>::Pending;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2}))) = 4;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4;
return;
}
@ -285,7 +285,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
StorageDead(_28);
StorageDead(_25);
StorageDead(_24);
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb23, unwind unreachable];
drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb23, unwind unreachable];
}
bb22: {
@ -308,7 +308,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
bb25: {
_0 = Poll::<()>::Ready(move _37);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2}))) = 1;
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 1;
return;
}

View File

@ -1,3 +1,4 @@
// skip-filecheck
// This test makes sure that the generator MIR pass eliminates all calls to
// `get_context`, and that the MIR argument type for an async fn and all locals
// related to `yield` are `&mut Context`, and its return type is `Poll`.

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics, inline_const)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics, inline_const)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: --crate-type=lib
#![feature(custom_mir, core_intrinsics, inline_const)]
use std::intrinsics::mir::*;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR enum_cast.foo.built.after.mir
// EMIT_MIR enum_cast.bar.built.after.mir
// EMIT_MIR enum_cast.boo.built.after.mir

View File

@ -1,8 +1,8 @@
// MIR for `main` after built
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
| 1: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:3:12: 3:22, inferred_ty: std::option::Option<u8>
| 0: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
| 1: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
|
fn main() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR issue_101867.main.built.after.mir
fn main() {
let x: Option<u8> = Some(1);

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR issue_110508.{impl#0}-BAR.built.after.mir
// EMIT_MIR issue_110508.{impl#0}-SELF_BAR.built.after.mir

View File

@ -1,6 +1,6 @@
// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR` after built
// MIR for `<impl at $DIR/issue_110508.rs:9:1: 9:9>::BAR` after built
const <impl at $DIR/issue_110508.rs:8:1: 8:9>::BAR: Foo = {
const <impl at $DIR/issue_110508.rs:9:1: 9:9>::BAR: Foo = {
let mut _0: Foo;
let mut _1: ();

View File

@ -1,6 +1,6 @@
// MIR for `<impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR` after built
// MIR for `<impl at $DIR/issue_110508.rs:9:1: 9:9>::SELF_BAR` after built
const <impl at $DIR/issue_110508.rs:8:1: 8:9>::SELF_BAR: Foo = {
const <impl at $DIR/issue_110508.rs:9:1: 9:9>::SELF_BAR: Foo = {
let mut _0: Foo;
let mut _1: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// We must mark a variable whose initialization fails due to an
// abort statement as StorageDead.

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -Z validate-mir
#![feature(let_chains)]
struct Droppy(u8);

View File

@ -1,3 +1,4 @@
// skip-filecheck
fn guard() -> bool {
false
}

View File

@ -1,10 +1,10 @@
// MIR for `main` after built
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:14:14: 14:23, inferred_ty: *mut Test
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:18:18: 18:31, inferred_ty: &&&&*mut Test
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
fn main() -> () {
let mut _0: ();

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR receiver_ptr_mutability.main.built.after.mir
#![feature(arbitrary_self_types)]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -C debug-assertions=yes
// EMIT_MIR shifts.shift_signed.built.after.mir

View File

@ -1,3 +1,4 @@
// skip-filecheck
// Test that we don't generate unnecessarily large MIR for very simple matches

View File

@ -1,3 +1,4 @@
// skip-filecheck
// Check that when we compile the static `XXX` into MIR, we do not
// generate `StorageStart` or `StorageEnd` statements.

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(stmt_expr_attributes, rustc_attrs)]
// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -Z mir-opt-level=0
// EMIT_MIR byte_slice.main.SimplifyCfg-elaborate-drops.after.mir

View File

@ -1,14 +0,0 @@
// MIR for `redundant` after PreCodegen
fn redundant(_1: *const &u8) -> *const &u8 {
debug x => _1;
let mut _0: *const &u8;
scope 1 (inlined generic_cast::<&u8, &u8>) {
debug x => _1;
}
bb0: {
_0 = _1;
return;
}
}

View File

@ -1,15 +0,0 @@
// MIR for `roundtrip` after PreCodegen
fn roundtrip(_1: *const u8) -> *const u8 {
debug x => _1;
let mut _0: *const u8;
let mut _2: *mut u8;
bb0: {
StorageLive(_2);
_2 = _1 as *mut u8 (PtrToPtr);
_0 = move _2 as *const u8 (PointerCoercion(MutToConstPointer));
StorageDead(_2);
return;
}
}

View File

@ -1,17 +0,0 @@
#![crate_type = "lib"]
// EMIT_MIR casts.redundant.InstSimplify.diff
// EMIT_MIR casts.redundant.PreCodegen.after.mir
pub fn redundant<'a, 'b: 'a>(x: *const &'a u8) -> *const &'a u8 {
generic_cast::<&'a u8, &'b u8>(x) as *const &'a u8
}
#[inline]
fn generic_cast<T, U>(x: *const T) -> *const U {
x as *const U
}
// EMIT_MIR casts.roundtrip.PreCodegen.after.mir
pub fn roundtrip(x: *const u8) -> *const u8 {
x as *mut u8 as *const u8
}

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// ignore-endian-big
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// compile-flags: -C overflow-checks=no -Zunsound-mir-opts
struct Point {

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstGoto
pub enum Foo {

View File

@ -1,3 +1,4 @@
// skip-filecheck
#![feature(min_const_generics)]
#![crate_type = "lib"]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstGoto
// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// ignore-endian-big
extern "C" {
static X: i32;

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR address_of_pair.fn0.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -O

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// EMIT_MIR bad_op_div_by_zero.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR bad_op_mod_by_zero.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -O -Zmir-opt-level=4

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -O
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR cast.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -C overflow-checks=on

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
#[inline(never)]

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Zmir-opt-level=1

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -O

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -C overflow-checks=on

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Zmir-enable-passes=+Inline

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// compile-flags: -Zmir-enable-passes=+RemoveZsts
// Verify that we can pretty print invalid constants.

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Z mir-opt-level=3

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp
// compile-flags: -Z mir-opt-level=3

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// EMIT_MIR_FOR_EACH_BIT_WIDTH

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mult_by_zero.test.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mutable_variable.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mutable_variable_aggregate.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
// EMIT_MIR mutable_variable_aggregate_mut_ref.main.ConstProp.diff

View File

@ -1,3 +1,4 @@
// skip-filecheck
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// unit-test: ConstProp

View File

@ -1,3 +1,4 @@
// skip-filecheck
// unit-test: ConstProp
static mut STATIC: u32 = 0x42424242;

Some files were not shown because too many files have changed in this diff Show More