Auto merge of #74724 - Manishearth:rollup-plbt8fe, r=Manishearth

Rollup of 8 pull requests

Successful merges:

 - #72954 (revise RwLock for HermitCore)
 - #74367 (Rearrange the pipeline of `pow` to gain efficiency)
 - #74491 (Optimize away BitAnd and BitOr when possible)
 - #74639 (Downgrade glibc to 2.11.1 for ppc, ppc64 and s390x)
 - #74661 (Refactor `region_name`: add `RegionNameHighlight`)
 - #74692 (delay_span_bug instead of silent ignore)
 - #74698 (fixed error reporting for mismatched traits)
 - #74715 (Add a system for creating diffs across multiple mir optimizations.)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-07-24 18:03:55 +00:00
commit fe07ece978
37 changed files with 961 additions and 720 deletions

View File

@ -1242,9 +1242,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.14"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909"
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
dependencies = [
"compiler_builtins",
"libc",

View File

@ -238,7 +238,7 @@ For targets: `powerpc-unknown-linux-gnu`
- Target options > Emit assembly for CPU = powerpc -- pure 32-bit PowerPC
- Operating System > Target OS = linux
- Operating System > Linux kernel version = 2.6.32.68 -- ~RHEL6 kernel
- C-library > glibc version = 2.12.2 -- ~RHEL6 glibc
- C-library > glibc version = 2.11.1 -- ~SLE11-SP4 glibc
- C compiler > gcc version = 5.2.0
- C compiler > C++ = ENABLE -- to cross compile LLVM
@ -255,7 +255,7 @@ For targets: `powerpc64-unknown-linux-gnu`
- Target options > Tune for CPU = power6 -- (+)
- Operating System > Target OS = linux
- Operating System > Linux kernel version = 2.6.32.68 -- ~RHEL6 kernel
- C-library > glibc version = 2.12.2 -- ~RHEL6 glibc
- C-library > glibc version = 2.11.1 -- ~SLE11-SP4 glibc
- C compiler > gcc version = 5.2.0
- C compiler > C++ = ENABLE -- to cross compile LLVM
@ -272,7 +272,7 @@ For targets: `s390x-unknown-linux-gnu`
- Target options > Bitness = 64-bit
- Operating System > Target OS = linux
- Operating System > Linux kernel version = 2.6.32.68 -- ~RHEL6 kernel
- C-library > glibc version = 2.12.2 -- ~RHEL6 glibc
- C-library > glibc version = 2.11.1 -- ~SLE11-SP4 glibc
- C compiler > gcc version = 5.2.0
- C compiler > gcc extra config = --with-arch=z10 -- LLVM's minimum support
- C compiler > C++ = ENABLE -- to cross compile LLVM

View File

@ -290,7 +290,7 @@ CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
# C-library
#
CT_LIBC="glibc"
CT_LIBC_VERSION="2.12.2"
CT_LIBC_VERSION="2.11.1"
CT_LIBC_glibc=y
# CT_LIBC_musl is not set
# CT_LIBC_uClibc is not set
@ -309,9 +309,9 @@ CT_THREADS="nptl"
# CT_LIBC_GLIBC_V_2_14_1 is not set
# CT_LIBC_GLIBC_V_2_14 is not set
# CT_LIBC_GLIBC_V_2_13 is not set
CT_LIBC_GLIBC_V_2_12_2=y
# CT_LIBC_GLIBC_V_2_12_2 is not set
# CT_LIBC_GLIBC_V_2_12_1 is not set
# CT_LIBC_GLIBC_V_2_11_1 is not set
CT_LIBC_GLIBC_V_2_11_1=y
# CT_LIBC_GLIBC_V_2_11 is not set
# CT_LIBC_GLIBC_V_2_10_1 is not set
# CT_LIBC_GLIBC_V_2_9 is not set

View File

@ -290,7 +290,7 @@ CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
# C-library
#
CT_LIBC="glibc"
CT_LIBC_VERSION="2.12.2"
CT_LIBC_VERSION="2.11.1"
CT_LIBC_glibc=y
# CT_LIBC_musl is not set
# CT_LIBC_uClibc is not set
@ -309,9 +309,9 @@ CT_THREADS="nptl"
# CT_LIBC_GLIBC_V_2_14_1 is not set
# CT_LIBC_GLIBC_V_2_14 is not set
# CT_LIBC_GLIBC_V_2_13 is not set
CT_LIBC_GLIBC_V_2_12_2=y
# CT_LIBC_GLIBC_V_2_12_2 is not set
# CT_LIBC_GLIBC_V_2_12_1 is not set
# CT_LIBC_GLIBC_V_2_11_1 is not set
CT_LIBC_GLIBC_V_2_11_1=y
# CT_LIBC_GLIBC_V_2_11 is not set
# CT_LIBC_GLIBC_V_2_10_1 is not set
# CT_LIBC_GLIBC_V_2_9 is not set

View File

@ -270,7 +270,7 @@ CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
# C-library
#
CT_LIBC="glibc"
CT_LIBC_VERSION="2.12.2"
CT_LIBC_VERSION="2.11.1"
CT_LIBC_glibc=y
# CT_LIBC_musl is not set
# CT_LIBC_uClibc is not set
@ -289,9 +289,9 @@ CT_THREADS="nptl"
# CT_LIBC_GLIBC_V_2_14_1 is not set
# CT_LIBC_GLIBC_V_2_14 is not set
# CT_LIBC_GLIBC_V_2_13 is not set
CT_LIBC_GLIBC_V_2_12_2=y
# CT_LIBC_GLIBC_V_2_12_2 is not set
# CT_LIBC_GLIBC_V_2_12_1 is not set
# CT_LIBC_GLIBC_V_2_11_1 is not set
CT_LIBC_GLIBC_V_2_11_1=y
# CT_LIBC_GLIBC_V_2_11 is not set
# CT_LIBC_GLIBC_V_2_10_1 is not set
# CT_LIBC_GLIBC_V_2_9 is not set

View File

@ -1095,6 +1095,9 @@ $EndFeature, "
without modifying the original"]
#[inline]
pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
if exp == 0 {
return Some(1);
}
let mut base = self;
let mut acc: Self = 1;
@ -1105,15 +1108,11 @@ $EndFeature, "
exp /= 2;
base = try_opt!(base.checked_mul(base));
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
acc = try_opt!(acc.checked_mul(base));
}
Some(acc)
Some(try_opt!(acc.checked_mul(base)))
}
}
@ -1622,6 +1621,9 @@ $EndFeature, "
without modifying the original"]
#[inline]
pub const fn wrapping_pow(self, mut exp: u32) -> Self {
if exp == 0 {
return 1;
}
let mut base = self;
let mut acc: Self = 1;
@ -1633,14 +1635,11 @@ $EndFeature, "
base = base.wrapping_mul(base);
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
acc = acc.wrapping_mul(base);
}
acc
acc.wrapping_mul(base)
}
}
@ -1989,6 +1988,9 @@ $EndFeature, "
without modifying the original"]
#[inline]
pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
if exp == 0 {
return (1,false);
}
let mut base = self;
let mut acc: Self = 1;
let mut overflown = false;
@ -2007,16 +2009,13 @@ $EndFeature, "
overflown |= r.1;
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
r = acc.overflowing_mul(base);
acc = r.0;
overflown |= r.1;
}
(acc, overflown)
r = acc.overflowing_mul(base);
r.1 |= overflown;
r
}
}
@ -2040,6 +2039,9 @@ $EndFeature, "
#[inline]
#[rustc_inherit_overflow_checks]
pub const fn pow(self, mut exp: u32) -> Self {
if exp == 0 {
return 1;
}
let mut base = self;
let mut acc = 1;
@ -2051,14 +2053,11 @@ $EndFeature, "
base = base * base;
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
acc = acc * base;
}
acc
acc * base
}
}
@ -3295,6 +3294,9 @@ assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);", $EndFeature, "
without modifying the original"]
#[inline]
pub const fn checked_pow(self, mut exp: u32) -> Option<Self> {
if exp == 0 {
return Some(1);
}
let mut base = self;
let mut acc: Self = 1;
@ -3306,14 +3308,12 @@ assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);", $EndFeature, "
base = try_opt!(base.checked_mul(base));
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
acc = try_opt!(acc.checked_mul(base));
}
Some(acc)
Some(try_opt!(acc.checked_mul(base)))
}
}
@ -3704,6 +3704,9 @@ assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
without modifying the original"]
#[inline]
pub const fn wrapping_pow(self, mut exp: u32) -> Self {
if exp == 0 {
return 1;
}
let mut base = self;
let mut acc: Self = 1;
@ -3715,14 +3718,11 @@ assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
base = base.wrapping_mul(base);
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
acc = acc.wrapping_mul(base);
}
acc
acc.wrapping_mul(base)
}
}
@ -4029,6 +4029,9 @@ assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
without modifying the original"]
#[inline]
pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
if exp == 0{
return (1,false);
}
let mut base = self;
let mut acc: Self = 1;
let mut overflown = false;
@ -4047,16 +4050,14 @@ assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
overflown |= r.1;
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
r = acc.overflowing_mul(base);
acc = r.0;
overflown |= r.1;
}
r = acc.overflowing_mul(base);
r.1 |= overflown;
(acc, overflown)
r
}
}
@ -4077,6 +4078,9 @@ Basic usage:
#[inline]
#[rustc_inherit_overflow_checks]
pub const fn pow(self, mut exp: u32) -> Self {
if exp == 0 {
return 1;
}
let mut base = self;
let mut acc = 1;
@ -4088,14 +4092,11 @@ Basic usage:
base = base * base;
}
// since exp!=0, finally the exp must be 1.
// Deal with the final bit of the exponent separately, since
// squaring the base afterwards is not necessary and may cause a
// needless overflow.
if exp == 1 {
acc = acc * base;
}
acc
acc * base
}
}

View File

@ -255,12 +255,43 @@ macro_rules! int_module {
#[test]
fn test_pow() {
let mut r = 2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(0), 1 as $T);
assert_eq!(r.wrapping_pow(2), 4 as $T);
assert_eq!(r.wrapping_pow(0), 1 as $T);
assert_eq!(r.checked_pow(2), Some(4 as $T));
assert_eq!(r.checked_pow(0), Some(1 as $T));
assert_eq!(r.overflowing_pow(2), (4 as $T, false));
assert_eq!(r.overflowing_pow(0), (1 as $T, false));
assert_eq!(r.saturating_pow(2), 4 as $T);
assert_eq!(r.saturating_pow(0), 1 as $T);
r = MAX;
// use `^` to represent .pow() with no overflow.
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
// thussaturating_pow the overflowing result is exactly 1.
assert_eq!(r.wrapping_pow(2), 1 as $T);
assert_eq!(r.checked_pow(2), None);
assert_eq!(r.overflowing_pow(2), (1 as $T, true));
assert_eq!(r.saturating_pow(2), MAX);
//test for negative exponent.
r = -2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(3), -8 as $T);
assert_eq!(r.pow(0), 1 as $T);
assert_eq!(r.wrapping_pow(2), 4 as $T);
assert_eq!(r.wrapping_pow(3), -8 as $T);
assert_eq!(r.wrapping_pow(0), 1 as $T);
assert_eq!(r.checked_pow(2), Some(4 as $T));
assert_eq!(r.checked_pow(3), Some(-8 as $T));
assert_eq!(r.checked_pow(0), Some(1 as $T));
assert_eq!(r.overflowing_pow(2), (4 as $T, false));
assert_eq!(r.overflowing_pow(3), (-8 as $T, false));
assert_eq!(r.overflowing_pow(0), (1 as $T, false));
assert_eq!(r.saturating_pow(2), 4 as $T);
assert_eq!(r.saturating_pow(3), -8 as $T);
assert_eq!(r.saturating_pow(0), 1 as $T);
}
}
};

View File

@ -184,6 +184,31 @@ macro_rules! uint_module {
assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
}
#[test]
fn test_pow() {
let mut r = 2 as $T;
assert_eq!(r.pow(2), 4 as $T);
assert_eq!(r.pow(0), 1 as $T);
assert_eq!(r.wrapping_pow(2), 4 as $T);
assert_eq!(r.wrapping_pow(0), 1 as $T);
assert_eq!(r.checked_pow(2), Some(4 as $T));
assert_eq!(r.checked_pow(0), Some(1 as $T));
assert_eq!(r.overflowing_pow(2), (4 as $T, false));
assert_eq!(r.overflowing_pow(0), (1 as $T, false));
assert_eq!(r.saturating_pow(2), 4 as $T);
assert_eq!(r.saturating_pow(0), 1 as $T);
r = MAX;
// use `^` to represent .pow() with no overflow.
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
// thussaturating_pow the overflowing result is exactly 1.
assert_eq!(r.wrapping_pow(2), 1 as $T);
assert_eq!(r.checked_pow(2), None);
assert_eq!(r.overflowing_pow(2), (1 as $T, true));
assert_eq!(r.saturating_pow(2), MAX);
}
}
};
}

View File

@ -1402,8 +1402,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
debug!("note_type_err(diag={:?})", diag);
enum Mismatch<'a> {
Variable(ty::error::ExpectedFound<Ty<'a>>),
Fixed(&'static str),
}
let (expected_found, exp_found, is_simple_error) = match values {
None => (None, None, false),
None => (None, Mismatch::Fixed("type"), false),
Some(values) => {
let (is_simple_error, exp_found) = match values {
ValuePairs::Types(exp_found) => {
@ -1417,9 +1421,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
)
.report(diag);
(is_simple_err, Some(exp_found))
(is_simple_err, Mismatch::Variable(exp_found))
}
_ => (false, None),
ValuePairs::TraitRefs(_) => (false, Mismatch::Fixed("trait")),
_ => (false, Mismatch::Fixed("type")),
};
let vals = match self.values_str(&values) {
Some((expected, found)) => Some((expected, found)),
@ -1445,8 +1450,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
};
if let Some((expected, found)) = expected_found {
let expected_label = exp_found.map_or("type".into(), |ef| ef.expected.prefix_string());
let found_label = exp_found.map_or("type".into(), |ef| ef.found.prefix_string());
let expected_label = match exp_found {
Mismatch::Variable(ef) => ef.expected.prefix_string(),
Mismatch::Fixed(s) => s.into(),
};
let found_label = match exp_found {
Mismatch::Variable(ef) => ef.found.prefix_string(),
Mismatch::Fixed(s) => s.into(),
};
let exp_found = match exp_found {
Mismatch::Variable(exp_found) => Some(exp_found),
Mismatch::Fixed(_) => None,
};
match (&terr, expected == found) {
(TypeError::Sorts(values), extra) => {
let sort_string = |ty: Ty<'tcx>| match (extra, &ty.kind) {
@ -1499,6 +1514,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
}
let exp_found = match exp_found {
Mismatch::Variable(exp_found) => Some(exp_found),
Mismatch::Fixed(_) => None,
};
if let Some(exp_found) = exp_found {
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
}

View File

@ -60,9 +60,7 @@ impl OutlivesSuggestionBuilder {
// Don't give suggestions for upvars, closure return types, or other unnamable
// regions.
RegionNameSource::SynthesizedFreeEnvRegion(..)
| RegionNameSource::CannotMatchHirTy(..)
| RegionNameSource::MatchedHirTy(..)
| RegionNameSource::MatchedAdtAndSegment(..)
| RegionNameSource::AnonRegionFromArgument(..)
| RegionNameSource::AnonRegionFromUpvar(..)
| RegionNameSource::AnonRegionFromOutput(..)
| RegionNameSource::AnonRegionFromYieldTy(..)

View File

@ -19,7 +19,7 @@ use crate::borrow_check::{
MirBorrowckCtxt,
};
use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource};
use super::{OutlivesSuggestionBuilder, RegionName};
impl ConstraintDescription for ConstraintCategory {
fn description(&self) -> &'static str {
@ -396,18 +396,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
diag.span_label(upvar_span, "variable captured here");
}
match self.give_region_a_name(*outlived_fr).unwrap().source {
RegionNameSource::NamedEarlyBoundRegion(fr_span)
| RegionNameSource::NamedFreeRegion(fr_span)
| RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _)
| RegionNameSource::CannotMatchHirTy(fr_span, _)
| RegionNameSource::MatchedHirTy(fr_span)
| RegionNameSource::MatchedAdtAndSegment(fr_span)
| RegionNameSource::AnonRegionFromUpvar(fr_span, _)
| RegionNameSource::AnonRegionFromOutput(fr_span, _, _) => {
diag.span_label(fr_span, "inferred to be a `FnMut` closure");
}
_ => {}
if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() {
diag.span_label(fr_span, "inferred to be a `FnMut` closure");
}
diag.note(

View File

@ -34,13 +34,8 @@ crate enum RegionNameSource {
Static,
/// The free region corresponding to the environment of a closure.
SynthesizedFreeEnvRegion(Span, String),
/// The region name corresponds to a region where the type annotation is completely missing
/// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
CannotMatchHirTy(Span, String),
/// The region name corresponds a reference that was found by traversing the type in the HIR.
MatchedHirTy(Span),
/// A region name from the generics list of a struct/enum/union.
MatchedAdtAndSegment(Span),
/// The region corresponding to an argument.
AnonRegionFromArgument(RegionNameHighlight),
/// The region corresponding to a closure upvar.
AnonRegionFromUpvar(Span, String),
/// The region corresponding to the return type of a closure.
@ -51,6 +46,19 @@ crate enum RegionNameSource {
AnonRegionFromAsyncFn(Span),
}
/// Describes what to highlight to explain to the user that we're giving an anonymous region a
/// synthesized name, and how to highlight it.
#[derive(Debug, Clone)]
crate enum RegionNameHighlight {
/// The anonymous region corresponds to a reference that was found by traversing the type in the HIR.
MatchedHirTy(Span),
/// The anonymous region corresponds to a `'_` in the generics list of a struct/enum/union.
MatchedAdtAndSegment(Span),
/// The anonymous region corresponds to a region where the type annotation is completely missing
/// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
CannotMatchHirTy(Span, String),
}
impl RegionName {
crate fn was_named(&self) -> bool {
match self.source {
@ -58,9 +66,7 @@ impl RegionName {
| RegionNameSource::NamedFreeRegion(..)
| RegionNameSource::Static => true,
RegionNameSource::SynthesizedFreeEnvRegion(..)
| RegionNameSource::CannotMatchHirTy(..)
| RegionNameSource::MatchedHirTy(..)
| RegionNameSource::MatchedAdtAndSegment(..)
| RegionNameSource::AnonRegionFromArgument(..)
| RegionNameSource::AnonRegionFromUpvar(..)
| RegionNameSource::AnonRegionFromOutput(..)
| RegionNameSource::AnonRegionFromYieldTy(..)
@ -68,6 +74,24 @@ impl RegionName {
}
}
crate fn span(&self) -> Option<Span> {
match self.source {
RegionNameSource::Static => None,
RegionNameSource::NamedEarlyBoundRegion(span)
| RegionNameSource::NamedFreeRegion(span)
| RegionNameSource::SynthesizedFreeEnvRegion(span, _)
| RegionNameSource::AnonRegionFromUpvar(span, _)
| RegionNameSource::AnonRegionFromOutput(span, _, _)
| RegionNameSource::AnonRegionFromYieldTy(span, _)
| RegionNameSource::AnonRegionFromAsyncFn(span) => Some(span),
RegionNameSource::AnonRegionFromArgument(ref highlight) => match *highlight {
RegionNameHighlight::MatchedHirTy(span)
| RegionNameHighlight::MatchedAdtAndSegment(span)
| RegionNameHighlight::CannotMatchHirTy(span, _) => Some(span),
},
}
}
crate fn highlight_region_name(&self, diag: &mut DiagnosticBuilder<'_>) {
match &self.source {
RegionNameSource::NamedFreeRegion(span)
@ -81,17 +105,22 @@ impl RegionName {
);
diag.note(&note);
}
RegionNameSource::CannotMatchHirTy(span, type_name) => {
RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::CannotMatchHirTy(
span,
type_name,
)) => {
diag.span_label(*span, format!("has type `{}`", type_name));
}
RegionNameSource::MatchedHirTy(span)
RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::MatchedHirTy(span))
| RegionNameSource::AnonRegionFromAsyncFn(span) => {
diag.span_label(
*span,
format!("let's call the lifetime of this reference `{}`", self),
);
}
RegionNameSource::MatchedAdtAndSegment(span) => {
RegionNameSource::AnonRegionFromArgument(
RegionNameHighlight::MatchedAdtAndSegment(span),
) => {
diag.span_label(*span, format!("let's call this `{}`", self));
}
RegionNameSource::AnonRegionFromUpvar(span, upvar_name) => {
@ -307,21 +336,31 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let arg_ty = self.regioncx.universal_regions().unnormalized_input_tys
[implicit_inputs + argument_index];
if let Some(region_name) =
self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index)
{
return Some(region_name);
}
let (_, span) = self.regioncx.get_argument_name_and_span_for_region(
&self.body,
&self.local_names,
argument_index,
);
self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty)
self.get_argument_hir_ty_for_highlighting(argument_index)
.and_then(|arg_hir_ty| self.highlight_if_we_can_match_hir_ty(fr, arg_ty, arg_hir_ty))
.or_else(|| {
// `highlight_if_we_cannot_match_hir_ty` needs to know the number we will give to
// the anonymous region. If it succeeds, the `synthesize_region_name` call below
// will increment the counter, "reserving" the number we just used.
let counter = *self.next_region_name.try_borrow().unwrap();
self.highlight_if_we_cannot_match_hir_ty(fr, arg_ty, span, counter)
})
.map(|highlight| RegionName {
name: self.synthesize_region_name(),
source: RegionNameSource::AnonRegionFromArgument(highlight),
})
}
fn give_name_if_we_can_match_hir_ty_from_argument(
fn get_argument_hir_ty_for_highlighting(
&self,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
argument_index: usize,
) -> Option<RegionName> {
) -> Option<&hir::Ty<'tcx>> {
let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id);
let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?;
let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?;
@ -333,7 +372,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
// (`give_name_if_anonymous_region_appears_in_arguments`).
hir::TyKind::Infer => None,
_ => self.give_name_if_we_can_match_hir_ty(needle_fr, argument_ty, argument_hir_ty),
_ => Some(argument_hir_ty),
}
}
@ -348,42 +387,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// | | has type `&'1 u32`
/// | has type `&'2 u32`
/// ```
fn give_name_if_we_cannot_match_hir_ty(
fn highlight_if_we_cannot_match_hir_ty(
&self,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
) -> Option<RegionName> {
let counter = *self.next_region_name.try_borrow().unwrap();
ty: Ty<'tcx>,
span: Span,
counter: usize,
) -> Option<RegionNameHighlight> {
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, counter);
let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0;
let type_name = self.infcx.extract_type_name(&ty, Some(highlight)).0;
debug!(
"give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
"highlight_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
type_name, needle_fr
);
let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
if type_name.find(&format!("'{}", counter)).is_some() {
// Only add a label if we can confirm that a region was labelled.
let argument_index =
self.regioncx.get_argument_index_for_region(self.infcx.tcx, needle_fr)?;
let (_, span) = self.regioncx.get_argument_name_and_span_for_region(
&self.body,
&self.local_names,
argument_index,
);
Some(RegionName {
// This counter value will already have been used, so this function will increment
// it so the next value will be used next and return the region name that would
// have been used.
name: self.synthesize_region_name(),
source: RegionNameSource::CannotMatchHirTy(span, type_name),
})
Some(RegionNameHighlight::CannotMatchHirTy(span, type_name))
} else {
None
};
assigned_region_name
}
}
/// Attempts to highlight the specific part of a type annotation
@ -395,9 +420,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// | - let's call the lifetime of this reference `'1`
/// ```
///
/// the way this works is that we match up `argument_ty`, which is
/// the way this works is that we match up `ty`, which is
/// a `Ty<'tcx>` (the internal form of the type) with
/// `argument_hir_ty`, a `hir::Ty` (the syntax of the type
/// `hir_ty`, a `hir::Ty` (the syntax of the type
/// annotation). We are descending through the types stepwise,
/// looking in to find the region `needle_fr` in the internal
/// type. Once we find that, we can use the span of the `hir::Ty`
@ -407,18 +432,17 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
/// keep track of the **closest** type we've found. If we fail to
/// find the exact `&` or `'_` to highlight, then we may fall back
/// to highlighting that closest type instead.
fn give_name_if_we_can_match_hir_ty(
fn highlight_if_we_can_match_hir_ty(
&self,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
argument_hir_ty: &hir::Ty<'_>,
) -> Option<RegionName> {
let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty<'_>)> =
&mut vec![(argument_ty, argument_hir_ty)];
ty: Ty<'tcx>,
hir_ty: &hir::Ty<'_>,
) -> Option<RegionNameHighlight> {
let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty<'_>)> = &mut vec![(ty, hir_ty)];
while let Some((ty, hir_ty)) = search_stack.pop() {
match (&ty.kind, &hir_ty.kind) {
// Check if the `argument_ty` is `&'X ..` where `'X`
// Check if the `ty` is `&'X ..` where `'X`
// is the region we are looking for -- if so, and we have a `&T`
// on the RHS, then we want to highlight the `&` like so:
//
@ -429,16 +453,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir::TyKind::Rptr(_lifetime, referent_hir_ty),
) => {
if region.to_region_vid() == needle_fr {
let region_name = self.synthesize_region_name();
// Just grab the first character, the `&`.
let source_map = self.infcx.tcx.sess.source_map();
let ampersand_span = source_map.start_point(hir_ty.span);
return Some(RegionName {
name: region_name,
source: RegionNameSource::MatchedHirTy(ampersand_span),
});
return Some(RegionNameHighlight::MatchedHirTy(ampersand_span));
}
// Otherwise, let's descend into the referent types.
@ -458,13 +477,13 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
Res::Def(DefKind::TyAlias, _) => (),
_ => {
if let Some(last_segment) = path.segments.last() {
if let Some(name) = self.match_adt_and_segment(
if let Some(highlight) = self.match_adt_and_segment(
substs,
needle_fr,
last_segment,
search_stack,
) {
return Some(name);
return Some(highlight);
}
}
}
@ -507,7 +526,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
needle_fr: RegionVid,
last_segment: &'hir hir::PathSegment<'hir>,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<RegionName> {
) -> Option<RegionNameHighlight> {
// Did the user give explicit arguments? (e.g., `Foo<..>`)
let args = last_segment.args.as_ref()?;
let lifetime =
@ -517,12 +536,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
| hir::LifetimeName::Error
| hir::LifetimeName::Static
| hir::LifetimeName::Underscore => {
let region_name = self.synthesize_region_name();
let ampersand_span = lifetime.span;
Some(RegionName {
name: region_name,
source: RegionNameSource::MatchedAdtAndSegment(ampersand_span),
})
let lifetime_span = lifetime.span;
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
}
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => {

View File

@ -28,9 +28,9 @@ use rustc_trait_selection::traits;
use crate::const_eval::error_to_const_error;
use crate::interpret::{
self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx, LocalState,
LocalValue, MemPlace, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer,
ScalarMaybeUninit, StackPopCleanup,
self, compile_time_machine, truncate, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx,
LocalState, LocalValue, MemPlace, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy,
Pointer, ScalarMaybeUninit, StackPopCleanup,
};
use crate::transform::{MirPass, MirSource};
@ -527,11 +527,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
right: &Operand<'tcx>,
source_info: SourceInfo,
) -> Option<()> {
let r =
self.use_ecx(|this| this.ecx.read_immediate(this.ecx.eval_operand(right, None)?))?;
let r = self.use_ecx(|this| this.ecx.read_immediate(this.ecx.eval_operand(right, None)?));
let l = self.use_ecx(|this| this.ecx.read_immediate(this.ecx.eval_operand(left, None)?));
// Check for exceeding shifts *even if* we cannot evaluate the LHS.
if op == BinOp::Shr || op == BinOp::Shl {
let r = r?;
// We need the type of the LHS. We cannot use `place_layout` as that is the type
// of the result, which for checked binops is not the same!
let left_ty = left.ty(&self.local_decls, self.tcx);
@ -564,21 +564,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
}
let l = l?;
// The remaining operators are handled through `overflowing_binary_op`.
if self.use_ecx(|this| {
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?;
Ok(overflow)
})? {
self.report_assert_as_lint(
lint::builtin::ARITHMETIC_OVERFLOW,
source_info,
"this arithmetic operation will overflow",
AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
)?;
if let (Some(l), Some(r)) = (l, r) {
// The remaining operators are handled through `overflowing_binary_op`.
if self.use_ecx(|this| {
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?;
Ok(overflow)
})? {
self.report_assert_as_lint(
lint::builtin::ARITHMETIC_OVERFLOW,
source_info,
"this arithmetic operation will overflow",
AssertKind::Overflow(op, l.to_const_int(), r.to_const_int()),
)?;
}
}
Some(())
}
@ -659,9 +658,74 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None;
}
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
self.eval_rvalue_with_identities(rvalue, place)
} else {
self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place))
}
}
// Attempt to use albegraic identities to eliminate constant expressions
fn eval_rvalue_with_identities(
&mut self,
rvalue: &Rvalue<'tcx>,
place: Place<'tcx>,
) -> Option<()> {
self.use_ecx(|this| {
trace!("calling eval_rvalue_into_place(rvalue = {:?}, place = {:?})", rvalue, place);
this.ecx.eval_rvalue_into_place(rvalue, place)?;
match rvalue {
Rvalue::BinaryOp(op, left, right) | Rvalue::CheckedBinaryOp(op, left, right) => {
let l = this.ecx.eval_operand(left, None);
let r = this.ecx.eval_operand(right, None);
let const_arg = match (l, r) {
(Ok(x), Err(_)) | (Err(_), Ok(x)) => this.ecx.read_immediate(x)?,
(Err(e), Err(_)) => return Err(e),
(Ok(_), Ok(_)) => {
this.ecx.eval_rvalue_into_place(rvalue, place)?;
return Ok(());
}
};
let arg_value =
this.ecx.force_bits(const_arg.to_scalar()?, const_arg.layout.size)?;
let dest = this.ecx.eval_place(place)?;
match op {
BinOp::BitAnd => {
if arg_value == 0 {
this.ecx.write_immediate(*const_arg, dest)?;
}
}
BinOp::BitOr => {
if arg_value == truncate(u128::MAX, const_arg.layout.size)
|| (const_arg.layout.ty.is_bool() && arg_value == 1)
{
this.ecx.write_immediate(*const_arg, dest)?;
}
}
BinOp::Mul => {
if const_arg.layout.ty.is_integral() && arg_value == 0 {
if let Rvalue::CheckedBinaryOp(_, _, _) = rvalue {
let val = Immediate::ScalarPair(
const_arg.to_scalar()?.into(),
Scalar::from_bool(false).into(),
);
this.ecx.write_immediate(val, dest)?;
} else {
this.ecx.write_immediate(*const_arg, dest)?;
}
}
}
_ => {
this.ecx.eval_rvalue_into_place(rvalue, place)?;
}
}
}
_ => {
this.ecx.eval_rvalue_into_place(rvalue, place)?;
}
}
Ok(())
})
}

View File

@ -1506,18 +1506,24 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
pat.walk(&mut |pat| {
debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind);
match pat.kind {
// In tuple struct patterns ignore the invalid `ident @ ...`.
// It will be handled as an error by the AST lowering.
PatKind::Ident(bmode, ident, ref sub)
if !(is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some()) =>
{
// First try to resolve the identifier as some existing entity,
// then fall back to a fresh binding.
let has_sub = sub.is_some();
let res = self
.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
.unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings));
self.r.record_partial_res(pat.id, PartialRes::new(res));
PatKind::Ident(bmode, ident, ref sub) => {
if is_tuple_struct_pat && sub.as_ref().filter(|p| p.is_rest()).is_some() {
// In tuple struct patterns ignore the invalid `ident @ ...`.
// It will be handled as an error by the AST lowering.
self.r
.session
.delay_span_bug(ident.span, "ident in tuple pattern is invalid");
} else {
// First try to resolve the identifier as some existing entity,
// then fall back to a fresh binding.
let has_sub = sub.is_some();
let res = self
.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
.unwrap_or_else(|| {
self.fresh_binding(ident, pat.id, pat_src, bindings)
});
self.r.record_partial_res(pat.id, PartialRes::new(res));
}
}
PatKind::TupleStruct(ref path, ..) => {
self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct(pat.span));

View File

@ -40,7 +40,7 @@ dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] }
fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
[target.'cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_os = "hermit"))'.dependencies]
hermit-abi = { version = "0.1.14", features = ['rustc-dep-of-std'] }
hermit-abi = { version = "0.1.15", features = ['rustc-dep-of-std'] }
[target.wasm32-wasi.dependencies]
wasi = { version = "0.9.0", features = ['rustc-dep-of-std'], default-features = false }

View File

@ -1,60 +1,64 @@
use crate::cmp;
use crate::ffi::c_void;
use crate::ptr;
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use crate::sys::hermit::abi;
use crate::sys::mutex::Mutex;
use crate::time::Duration;
// The implementation is inspired by Andrew D. Birrell's paper
// "Implementing Condition Variables with Semaphores"
pub struct Condvar {
identifier: usize,
counter: AtomicUsize,
sem1: *const c_void,
sem2: *const c_void,
}
unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}
impl Condvar {
pub const fn new() -> Condvar {
Condvar { identifier: 0 }
Condvar { counter: AtomicUsize::new(0), sem1: ptr::null(), sem2: ptr::null() }
}
pub unsafe fn init(&mut self) {
let _ = abi::init_queue(self.id());
let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0);
let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0);
}
pub unsafe fn notify_one(&self) {
let _ = abi::notify(self.id(), 1);
if self.counter.load(SeqCst) > 0 {
self.counter.fetch_sub(1, SeqCst);
abi::sem_post(self.sem1);
abi::sem_timedwait(self.sem2, 0);
}
}
#[inline]
pub unsafe fn notify_all(&self) {
let _ = abi::notify(self.id(), -1 /* =all */);
let counter = self.counter.swap(0, SeqCst);
for _ in 0..counter {
abi::sem_post(self.sem1);
}
for _ in 0..counter {
abi::sem_timedwait(self.sem2, 0);
}
}
pub unsafe fn wait(&self, mutex: &Mutex) {
// add current task to the wait queue
let _ = abi::add_queue(self.id(), -1 /* no timeout */);
self.counter.fetch_add(1, SeqCst);
mutex.unlock();
let _ = abi::wait(self.id());
abi::sem_timedwait(self.sem1, 0);
abi::sem_post(self.sem2);
mutex.lock();
}
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
let nanos = dur.as_nanos();
let nanos = cmp::min(i64::MAX as u128, nanos);
// add current task to the wait queue
let _ = abi::add_queue(self.id(), nanos as i64);
mutex.unlock();
// If the return value is !0 then a timeout happened, so we return
// `false` as we weren't actually notified.
let ret = abi::wait(self.id()) == 0;
mutex.lock();
ret
pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool {
panic!("wait_timeout not supported on hermit");
}
pub unsafe fn destroy(&self) {
let _ = abi::destroy_queue(self.id());
}
#[inline]
fn id(&self) -> usize {
&self.identifier as *const usize as usize
let _ = abi::sem_destroy(self.sem1);
let _ = abi::sem_destroy(self.sem2);
}
}

View File

@ -1,49 +1,144 @@
use super::mutex::Mutex;
use crate::cell::UnsafeCell;
use crate::sys::condvar::Condvar;
use crate::sys::mutex::Mutex;
pub struct RWLock {
mutex: Mutex,
lock: Mutex,
cond: Condvar,
state: UnsafeCell<State>,
}
enum State {
Unlocked,
Reading(usize),
Writing,
}
unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}
// This rwlock implementation is a relatively simple implementation which has a
// condition variable for readers/writers as well as a mutex protecting the
// internal state of the lock. A current downside of the implementation is that
// unlocking the lock will notify *all* waiters rather than just readers or just
// writers. This can cause lots of "thundering stampede" problems. While
// hopefully correct this implementation is very likely to want to be changed in
// the future.
impl RWLock {
pub const fn new() -> RWLock {
RWLock { mutex: Mutex::new() }
RWLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
}
#[inline]
pub unsafe fn read(&self) {
self.mutex.lock();
self.lock.lock();
while !(*self.state.get()).inc_readers() {
self.cond.wait(&self.lock);
}
self.lock.unlock();
}
#[inline]
pub unsafe fn try_read(&self) -> bool {
self.mutex.try_lock()
self.lock.lock();
let ok = (*self.state.get()).inc_readers();
self.lock.unlock();
return ok;
}
#[inline]
pub unsafe fn write(&self) {
self.mutex.lock();
self.lock.lock();
while !(*self.state.get()).inc_writers() {
self.cond.wait(&self.lock);
}
self.lock.unlock();
}
#[inline]
pub unsafe fn try_write(&self) -> bool {
self.mutex.try_lock()
self.lock.lock();
let ok = (*self.state.get()).inc_writers();
self.lock.unlock();
return ok;
}
#[inline]
pub unsafe fn read_unlock(&self) {
self.mutex.unlock();
self.lock.lock();
let notify = (*self.state.get()).dec_readers();
self.lock.unlock();
if notify {
// FIXME: should only wake up one of these some of the time
self.cond.notify_all();
}
}
#[inline]
pub unsafe fn write_unlock(&self) {
self.mutex.unlock();
self.lock.lock();
(*self.state.get()).dec_writers();
self.lock.unlock();
// FIXME: should only wake up one of these some of the time
self.cond.notify_all();
}
#[inline]
pub unsafe fn destroy(&self) {
self.mutex.destroy();
self.lock.destroy();
self.cond.destroy();
}
}
impl State {
fn inc_readers(&mut self) -> bool {
match *self {
State::Unlocked => {
*self = State::Reading(1);
true
}
State::Reading(ref mut cnt) => {
*cnt += 1;
true
}
State::Writing => false,
}
}
fn inc_writers(&mut self) -> bool {
match *self {
State::Unlocked => {
*self = State::Writing;
true
}
State::Reading(_) | State::Writing => false,
}
}
fn dec_readers(&mut self) -> bool {
let zero = match *self {
State::Reading(ref mut cnt) => {
*cnt -= 1;
*cnt == 0
}
State::Unlocked | State::Writing => invalid(),
};
if zero {
*self = State::Unlocked;
}
zero
}
fn dec_writers(&mut self) {
match *self {
State::Writing => {}
State::Unlocked | State::Reading(_) => invalid(),
}
*self = State::Unlocked;
}
}
fn invalid() -> ! {
panic!("inconsistent rwlock");
}

View File

@ -0,0 +1,10 @@
// compile-flags: -O -Zmir-opt-level=3
// EMIT_MIR rustc.test.ConstProp.diff
pub fn test(x: bool, y: bool) -> bool {
(y | true) & (x & false)
}
fn main() {
test(true, false);
}

View File

@ -0,0 +1,53 @@
- // MIR for `test` before ConstProp
+ // MIR for `test` after ConstProp
fn test(_1: bool, _2: bool) -> bool {
debug x => _1; // in scope 0 at $DIR/boolean_identities.rs:4:13: 4:14
debug y => _2; // in scope 0 at $DIR/boolean_identities.rs:4:22: 4:23
let mut _0: bool; // return place in scope 0 at $DIR/boolean_identities.rs:4:34: 4:38
let mut _3: bool; // in scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
let mut _4: bool; // in scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
let mut _5: bool; // in scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
let mut _6: bool; // in scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
bb0: {
StorageLive(_3); // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
StorageLive(_4); // scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
_4 = _2; // scope 0 at $DIR/boolean_identities.rs:5:6: 5:7
- _3 = BitOr(move _4, const true); // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
+ _3 = const true; // scope 0 at $DIR/boolean_identities.rs:5:5: 5:15
// ty::Const
// + ty: bool
// + val: Value(Scalar(0x01))
// mir::Constant
- // + span: $DIR/boolean_identities.rs:5:10: 5:14
+ // + span: $DIR/boolean_identities.rs:5:5: 5:15
// + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
StorageDead(_4); // scope 0 at $DIR/boolean_identities.rs:5:14: 5:15
StorageLive(_5); // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
StorageLive(_6); // scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
_6 = _1; // scope 0 at $DIR/boolean_identities.rs:5:19: 5:20
- _5 = BitAnd(move _6, const false); // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
+ _5 = const false; // scope 0 at $DIR/boolean_identities.rs:5:18: 5:29
// ty::Const
// + ty: bool
// + val: Value(Scalar(0x00))
// mir::Constant
- // + span: $DIR/boolean_identities.rs:5:23: 5:28
+ // + span: $DIR/boolean_identities.rs:5:18: 5:29
// + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_6); // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
- _0 = BitAnd(move _3, move _5); // scope 0 at $DIR/boolean_identities.rs:5:5: 5:29
+ _0 = const false; // scope 0 at $DIR/boolean_identities.rs:5:5: 5:29
+ // ty::Const
+ // + ty: bool
+ // + val: Value(Scalar(0x00))
+ // mir::Constant
+ // + span: $DIR/boolean_identities.rs:5:5: 5:29
+ // + literal: Const { ty: bool, val: Value(Scalar(0x00)) }
StorageDead(_5); // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
StorageDead(_3); // scope 0 at $DIR/boolean_identities.rs:5:28: 5:29
return; // scope 0 at $DIR/boolean_identities.rs:6:2: 6:2
}
}

View File

@ -0,0 +1,10 @@
// compile-flags: -O -Zmir-opt-level=3
// EMIT_MIR rustc.test.ConstProp.diff
fn test(x : i32) -> i32 {
x * 0
}
fn main() {
test(10);
}

View File

@ -0,0 +1,25 @@
- // MIR for `test` before ConstProp
+ // MIR for `test` after ConstProp
fn test(_1: i32) -> i32 {
debug x => _1; // in scope 0 at $DIR/mult_by_zero.rs:4:9: 4:10
let mut _0: i32; // return place in scope 0 at $DIR/mult_by_zero.rs:4:21: 4:24
let mut _2: i32; // in scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
bb0: {
StorageLive(_2); // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
_2 = _1; // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:4
- _0 = Mul(move _2, const 0_i32); // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:8
+ _0 = const 0_i32; // scope 0 at $DIR/mult_by_zero.rs:5:3: 5:8
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000000))
// mir::Constant
- // + span: $DIR/mult_by_zero.rs:5:7: 5:8
+ // + span: $DIR/mult_by_zero.rs:5:3: 5:8
// + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) }
StorageDead(_2); // scope 0 at $DIR/mult_by_zero.rs:5:7: 5:8
return; // scope 0 at $DIR/mult_by_zero.rs:6:2: 6:2
}
}

View File

@ -9,8 +9,7 @@
// all of the bindings for that scope.
// * No drop flags are used.
// EMIT_MIR rustc.complicated_match.SimplifyCfg-initial.after.mir
// EMIT_MIR rustc.complicated_match.ElaborateDrops.after.mir
// EMIT_MIR rustc.complicated_match SimplifyCfg-initial.after ElaborateDrops.after
fn complicated_match(cond: bool, items: (bool, bool, String)) -> i32 {
match items {
(false, a, s) | (a, false, s) if if cond { return 3 } else { a } => 1,

View File

@ -1,235 +0,0 @@
// MIR for `complicated_match` after ElaborateDrops
fn complicated_match(_1: bool, _2: (bool, bool, std::string::String)) -> i32 {
debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:14:22: 14:26
debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:14:34: 14:39
let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:14:66: 14:69
let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:17:16: 17:17
let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:17:19: 17:20
scope 1 {
debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:16:17: 16:18
debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:16:17: 16:18
debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:16:20: 16:21
debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:16:20: 16:21
}
scope 2 {
debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:17:16: 17:17
debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:17:19: 17:20
}
bb0: {
switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:16:10: 16:15
}
bb1 (cleanup): {
resume; // scope 0 at $DIR/match-arm-scopes.rs:14:1: 19:2
}
bb2: {
switchInt((_2.1: bool)) -> [false: bb14, otherwise: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:16:29: 16:34
}
bb3: {
switchInt((_2.0: bool)) -> [false: bb4, otherwise: bb21]; // scope 0 at $DIR/match-arm-scopes.rs:17:10: 17:14
}
bb4: {
StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:17:32: 17:33
_15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:17:32: 17:33
StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:17:35: 17:36
_16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:17:35: 17:36
goto -> bb20; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb5: {
_0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:16:77: 16:78
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000001))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:77: 16:78
// + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
drop(_7) -> [return: bb19, unwind: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
}
bb6: {
StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
_6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
_8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
_10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
switchInt(_10) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb7: {
_9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:16:70: 16:71
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
switchInt(move _9) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb8: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:16:59: 16:60
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000003))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:59: 16:60
// + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb11; // scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
}
bb9: {
return; // scope 0 at $DIR/match-arm-scopes.rs:19:2: 19:2
}
bb10 (cleanup): {
goto -> bb25; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb11: {
drop(_2) -> [return: bb9, unwind: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb12: {
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
_5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
_7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
goto -> bb5; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb13: {
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb2; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb14: {
StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
_6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
_8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
_13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
switchInt(_13) -> [false: bb15, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb15: {
_12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:16:70: 16:71
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
switchInt(move _12) -> [false: bb18, otherwise: bb17]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb16: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:16:59: 16:60
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000003))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:59: 16:60
// + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb11; // scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
}
bb17: {
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
_5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
_7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
goto -> bb5; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb18: {
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb3; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb19: {
StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb20: {
_0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:17:41: 17:42
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000002))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:17:41: 17:42
// + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
drop(_16) -> [return: bb22, unwind: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:17:41: 17:42
}
bb21: {
StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:17:16: 17:17
_15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:17:16: 17:17
StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:17:19: 17:20
_16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:17:19: 17:20
goto -> bb20; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb22: {
StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:17:41: 17:42
StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:17:41: 17:42
goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb23: {
goto -> bb29; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb24 (cleanup): {
goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb25 (cleanup): {
goto -> bb24; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb26: {
goto -> bb9; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb27 (cleanup): {
goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb28 (cleanup): {
goto -> bb27; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb29: {
goto -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
}

View File

@ -0,0 +1,313 @@
- // MIR for `complicated_match` after SimplifyCfg-initial
+ // MIR for `complicated_match` after ElaborateDrops
fn complicated_match(_1: bool, _2: (bool, bool, std::string::String)) -> i32 {
debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:13:22: 13:26
debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:13:34: 13:39
let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:13:66: 13:69
let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:17: 15:18
let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:17: 15:18
let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:15:20: 15:21
let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:15:20: 15:21
let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:15:52: 15:60
let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:15:52: 15:60
let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:16: 16:17
let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:16:19: 16:20
scope 1 {
debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:15:17: 15:18
debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:15:17: 15:18
debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:15:20: 15:21
debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:15:20: 15:21
}
scope 2 {
debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:16:16: 16:17
debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:16:19: 16:20
}
bb0: {
- FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
- switchInt((_2.0: bool)) -> [false: bb2, otherwise: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:15:10: 15:15
+ switchInt((_2.0: bool)) -> [false: bb6, otherwise: bb2]; // scope 0 at $DIR/match-arm-scopes.rs:15:10: 15:15
}
bb1 (cleanup): {
resume; // scope 0 at $DIR/match-arm-scopes.rs:13:1: 18:2
}
bb2: {
- falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:15:9: 15:22
+ switchInt((_2.1: bool)) -> [false: bb14, otherwise: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:15:29: 15:34
}
bb3: {
- switchInt((_2.1: bool)) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:15:29: 15:34
+ switchInt((_2.0: bool)) -> [false: bb4, otherwise: bb21]; // scope 0 at $DIR/match-arm-scopes.rs:16:10: 16:14
}
bb4: {
- falseEdge -> [real: bb18, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:15:25: 15:38
- }
-
- bb5: {
- switchInt((_2.0: bool)) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:16:10: 16:14
- }
-
- bb6: {
- falseEdge -> [real: bb26, imaginary: bb7]; // scope 0 at $DIR/match-arm-scopes.rs:16:9: 16:21
- }
-
- bb7: {
StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:16:32: 16:33
_15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:32: 16:33
StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:16:35: 16:36
_16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:35: 16:36
- goto -> bb25; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
+ goto -> bb20; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
}
- bb8: {
+ bb5: {
_0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:15:77: 15:78
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000001))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:15:77: 15:78
// + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
- drop(_7) -> [return: bb24, unwind: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
+ drop(_7) -> [return: bb19, unwind: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
}
- bb9: {
+ bb6: {
StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:17: 15:18
_6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:17: 15:18
StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:20: 15:21
_8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:15:20: 15:21
- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
_10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
- FakeRead(ForMatchedPlace, _10); // scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
- switchInt(_10) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
+ switchInt(_10) -> [false: bb7, otherwise: bb8]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
}
- bb10: {
- falseEdge -> [real: bb12, imaginary: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
- }
-
- bb11: {
+ bb7: {
_9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:15:70: 15:71
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- switchInt(move _9) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
+ switchInt(move _9) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
}
- bb12: {
+ bb8: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000003))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:15:59: 15:60
// + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- goto -> bb15; // scope 0 at $DIR/match-arm-scopes.rs:15:52: 15:60
+ goto -> bb11; // scope 0 at $DIR/match-arm-scopes.rs:15:52: 15:60
}
- bb13: {
+ bb9: {
return; // scope 0 at $DIR/match-arm-scopes.rs:18:2: 18:2
}
- bb14 (cleanup): {
- drop(_2) -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ bb10 (cleanup): {
+ goto -> bb25; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
}
- bb15: {
- drop(_2) -> [return: bb13, unwind: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ bb11: {
+ drop(_2) -> [return: bb9, unwind: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
}
- bb16: {
+ bb12: {
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:15:17: 15:18
_5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:17: 15:18
StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:15:20: 15:21
_7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:15:20: 15:21
- goto -> bb8; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
+ goto -> bb5; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
}
- bb17: {
+ bb13: {
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- falseEdge -> [real: bb3, imaginary: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
+ goto -> bb2; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
}
- bb18: {
+ bb14: {
StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:26: 15:27
_6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:26: 15:27
StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:36: 15:37
_8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:15:36: 15:37
- _3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
- _4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:14:11: 14:16
StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
_13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
- FakeRead(ForMatchedPlace, _13); // scope 0 at $DIR/match-arm-scopes.rs:15:45: 15:49
- switchInt(_13) -> [false: bb20, otherwise: bb19]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
+ switchInt(_13) -> [false: bb15, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
}
- bb19: {
- falseEdge -> [real: bb21, imaginary: bb20]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
- }
-
- bb20: {
+ bb15: {
_12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:15:70: 15:71
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- switchInt(move _12) -> [false: bb23, otherwise: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
+ switchInt(move _12) -> [false: bb18, otherwise: bb17]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
}
- bb21: {
+ bb16: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000003))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:15:59: 15:60
// + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- goto -> bb15; // scope 0 at $DIR/match-arm-scopes.rs:15:52: 15:60
+ goto -> bb11; // scope 0 at $DIR/match-arm-scopes.rs:15:52: 15:60
}
- bb22: {
+ bb17: {
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
- FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:15:26: 15:27
_5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:26: 15:27
StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:15:36: 15:37
_7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:15:36: 15:37
- goto -> bb8; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
+ goto -> bb5; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
}
- bb23: {
+ bb18: {
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- falseEdge -> [real: bb5, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
+ goto -> bb3; // scope 0 at $DIR/match-arm-scopes.rs:15:42: 15:73
}
- bb24: {
+ bb19: {
StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
- goto -> bb28; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
+ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
}
- bb25: {
+ bb20: {
_0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:16:41: 16:42
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000002))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:41: 16:42
// + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
- drop(_16) -> [return: bb27, unwind: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:16:41: 16:42
+ drop(_16) -> [return: bb22, unwind: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:16:41: 16:42
}
- bb26: {
+ bb21: {
StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:16:16: 16:17
_15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:16: 16:17
StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:16:19: 16:20
_16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:19: 16:20
- goto -> bb25; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
+ goto -> bb20; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
}
- bb27: {
+ bb22: {
StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:16:41: 16:42
StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:16:41: 16:42
- goto -> bb28; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
+ goto -> bb23; // scope 0 at $DIR/match-arm-scopes.rs:14:5: 17:6
}
- bb28: {
- drop(_2) -> [return: bb13, unwind: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ bb23: {
+ goto -> bb29; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ }
+
+ bb24 (cleanup): {
+ goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ }
+
+ bb25 (cleanup): {
+ goto -> bb24; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ }
+
+ bb26: {
+ goto -> bb9; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ }
+
+ bb27 (cleanup): {
+ goto -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ }
+
+ bb28 (cleanup): {
+ goto -> bb27; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
+ }
+
+ bb29: {
+ goto -> bb26; // scope 0 at $DIR/match-arm-scopes.rs:18:1: 18:2
}
}

View File

@ -1,246 +0,0 @@
// MIR for `complicated_match` after SimplifyCfg-initial
fn complicated_match(_1: bool, _2: (bool, bool, std::string::String)) -> i32 {
debug cond => _1; // in scope 0 at $DIR/match-arm-scopes.rs:14:22: 14:26
debug items => _2; // in scope 0 at $DIR/match-arm-scopes.rs:14:34: 14:39
let mut _0: i32; // return place in scope 0 at $DIR/match-arm-scopes.rs:14:66: 14:69
let mut _3: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
let mut _4: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
let _5: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
let _6: &bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
let _7: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
let _8: &std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
let mut _9: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
let mut _10: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
let mut _11: !; // in scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
let mut _12: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
let mut _13: bool; // in scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
let mut _14: !; // in scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
let _15: bool; // in scope 0 at $DIR/match-arm-scopes.rs:17:16: 17:17
let _16: std::string::String; // in scope 0 at $DIR/match-arm-scopes.rs:17:19: 17:20
scope 1 {
debug a => _5; // in scope 1 at $DIR/match-arm-scopes.rs:16:17: 16:18
debug a => _6; // in scope 1 at $DIR/match-arm-scopes.rs:16:17: 16:18
debug s => _7; // in scope 1 at $DIR/match-arm-scopes.rs:16:20: 16:21
debug s => _8; // in scope 1 at $DIR/match-arm-scopes.rs:16:20: 16:21
}
scope 2 {
debug b => _15; // in scope 2 at $DIR/match-arm-scopes.rs:17:16: 17:17
debug t => _16; // in scope 2 at $DIR/match-arm-scopes.rs:17:19: 17:20
}
bb0: {
FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
switchInt((_2.0: bool)) -> [false: bb2, otherwise: bb3]; // scope 0 at $DIR/match-arm-scopes.rs:16:10: 16:15
}
bb1 (cleanup): {
resume; // scope 0 at $DIR/match-arm-scopes.rs:14:1: 19:2
}
bb2: {
falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:16:9: 16:22
}
bb3: {
switchInt((_2.1: bool)) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/match-arm-scopes.rs:16:29: 16:34
}
bb4: {
falseEdge -> [real: bb18, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:16:25: 16:38
}
bb5: {
switchInt((_2.0: bool)) -> [false: bb7, otherwise: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:17:10: 17:14
}
bb6: {
falseEdge -> [real: bb26, imaginary: bb7]; // scope 0 at $DIR/match-arm-scopes.rs:17:9: 17:21
}
bb7: {
StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:17:32: 17:33
_15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:17:32: 17:33
StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:17:35: 17:36
_16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:17:35: 17:36
goto -> bb25; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb8: {
_0 = const 1_i32; // scope 1 at $DIR/match-arm-scopes.rs:16:77: 16:78
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000001))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:77: 16:78
// + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) }
drop(_7) -> [return: bb24, unwind: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
}
bb9: {
StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
_6 = &(_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
_8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
_3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
_4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
StorageLive(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
StorageLive(_10); // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
_10 = _1; // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
FakeRead(ForMatchedPlace, _10); // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
switchInt(_10) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb10: {
falseEdge -> [real: bb12, imaginary: bb11]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb11: {
_9 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:16:70: 16:71
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
switchInt(move _9) -> [false: bb17, otherwise: bb16]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb12: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:16:59: 16:60
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000003))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:59: 16:60
// + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_10); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb15; // scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
}
bb13: {
return; // scope 0 at $DIR/match-arm-scopes.rs:19:2: 19:2
}
bb14 (cleanup): {
drop(_2) -> bb1; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb15: {
drop(_2) -> [return: bb13, unwind: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
bb16: {
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
_5 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:17: 16:18
StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
_7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:20: 16:21
goto -> bb8; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb17: {
StorageDead(_9); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
falseEdge -> [real: bb3, imaginary: bb4]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb18: {
StorageLive(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
_6 = &(_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
StorageLive(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
_8 = &(_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
_3 = &shallow (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
_4 = &shallow (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:15:11: 15:16
StorageLive(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
StorageLive(_13); // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
_13 = _1; // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
FakeRead(ForMatchedPlace, _13); // scope 0 at $DIR/match-arm-scopes.rs:16:45: 16:49
switchInt(_13) -> [false: bb20, otherwise: bb19]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb19: {
falseEdge -> [real: bb21, imaginary: bb20]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb20: {
_12 = (*_6); // scope 0 at $DIR/match-arm-scopes.rs:16:70: 16:71
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
switchInt(move _12) -> [false: bb23, otherwise: bb22]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb21: {
_0 = const 3_i32; // scope 0 at $DIR/match-arm-scopes.rs:16:59: 16:60
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000003))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:16:59: 16:60
// + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) }
StorageDead(_13); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb15; // scope 0 at $DIR/match-arm-scopes.rs:16:52: 16:60
}
bb22: {
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
FakeRead(ForMatchGuard, _3); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
FakeRead(ForGuardBinding, _8); // scope 0 at $DIR/match-arm-scopes.rs:16:72: 16:73
StorageLive(_5); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
_5 = (_2.0: bool); // scope 0 at $DIR/match-arm-scopes.rs:16:26: 16:27
StorageLive(_7); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
_7 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:16:36: 16:37
goto -> bb8; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb23: {
StorageDead(_12); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
falseEdge -> [real: bb5, imaginary: bb6]; // scope 0 at $DIR/match-arm-scopes.rs:16:42: 16:73
}
bb24: {
StorageDead(_7); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_5); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_8); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
StorageDead(_6); // scope 0 at $DIR/match-arm-scopes.rs:16:77: 16:78
goto -> bb28; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb25: {
_0 = const 2_i32; // scope 2 at $DIR/match-arm-scopes.rs:17:41: 17:42
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x00000002))
// mir::Constant
// + span: $DIR/match-arm-scopes.rs:17:41: 17:42
// + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) }
drop(_16) -> [return: bb27, unwind: bb14]; // scope 0 at $DIR/match-arm-scopes.rs:17:41: 17:42
}
bb26: {
StorageLive(_15); // scope 0 at $DIR/match-arm-scopes.rs:17:16: 17:17
_15 = (_2.1: bool); // scope 0 at $DIR/match-arm-scopes.rs:17:16: 17:17
StorageLive(_16); // scope 0 at $DIR/match-arm-scopes.rs:17:19: 17:20
_16 = move (_2.2: std::string::String); // scope 0 at $DIR/match-arm-scopes.rs:17:19: 17:20
goto -> bb25; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb27: {
StorageDead(_16); // scope 0 at $DIR/match-arm-scopes.rs:17:41: 17:42
StorageDead(_15); // scope 0 at $DIR/match-arm-scopes.rs:17:41: 17:42
goto -> bb28; // scope 0 at $DIR/match-arm-scopes.rs:15:5: 18:6
}
bb28: {
drop(_2) -> [return: bb13, unwind: bb1]; // scope 0 at $DIR/match-arm-scopes.rs:19:1: 19:2
}
}

View File

@ -1,7 +1,7 @@
// build-fail
// Regression test for #66975
#![warn(const_err)]
#![warn(const_err, unconditional_panic)]
#![feature(never_type)]
struct PrintName<T>(T);
@ -9,6 +9,7 @@ struct PrintName<T>(T);
impl<T> PrintName<T> {
const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
//~^ WARN any use of this value will cause an error
}
fn f<T>() {

View File

@ -9,11 +9,11 @@ LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
note: the lint level is defined here
--> $DIR/index-out-of-bounds-never-type.rs:4:9
|
LL | #![warn(const_err)]
LL | #![warn(const_err, unconditional_panic)]
| ^^^^^^^^^
error: erroneous constant encountered
--> $DIR/index-out-of-bounds-never-type.rs:15:13
--> $DIR/index-out-of-bounds-never-type.rs:16:13
|
LL | let _ = PrintName::<T>::VOID;
| ^^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,12 @@
trait DynEq {}
impl<'a> PartialEq for &'a (dyn DynEq + 'static) {
fn eq(&self, _other: &Self) -> bool {
true
}
}
impl Eq for &dyn DynEq {} //~ ERROR E0308
fn main() {
}

View File

@ -0,0 +1,18 @@
error[E0308]: mismatched types
--> $DIR/E0308-2.rs:9:6
|
LL | impl Eq for &dyn DynEq {}
| ^^ lifetime mismatch
|
= note: expected trait `std::cmp::PartialEq`
found trait `std::cmp::PartialEq`
note: the lifetime `'_` as defined on the impl at 9:13...
--> $DIR/E0308-2.rs:9:13
|
LL | impl Eq for &dyn DynEq {}
| ^
= note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -3135,14 +3135,47 @@ impl<'test> TestCx<'test> {
}
for l in test_file_contents.lines() {
if l.starts_with("// EMIT_MIR ") {
let test_name = l.trim_start_matches("// EMIT_MIR ");
let expected_file = test_dir.join(test_name);
let test_name = l.trim_start_matches("// EMIT_MIR ").trim();
let mut test_names = test_name.split(' ');
// sometimes we specify two files so that we get a diff between the two files
let test_name = test_names.next().unwrap();
let expected_file;
let from_file;
let to_file;
let dumped_string = if test_name.ends_with(".diff") {
let test_name = test_name.trim_end_matches(".diff");
let before = format!("{}.before.mir", test_name);
let after = format!("{}.after.mir", test_name);
let before = self.get_mir_dump_dir().join(before);
if test_name.ends_with(".diff") {
let trimmed = test_name.trim_end_matches(".diff");
let test_against = format!("{}.after.mir", trimmed);
from_file = format!("{}.before.mir", trimmed);
expected_file = test_name.to_string();
assert!(
test_names.next().is_none(),
"two mir pass names specified for MIR diff"
);
to_file = Some(test_against);
} else if let Some(first_pass) = test_names.next() {
let second_pass = test_names.next().unwrap();
assert!(
test_names.next().is_none(),
"three mir pass names specified for MIR diff"
);
expected_file = format!("{}.{}-{}.diff", test_name, first_pass, second_pass);
let second_file = format!("{}.{}.mir", test_name, second_pass);
from_file = format!("{}.{}.mir", test_name, first_pass);
to_file = Some(second_file);
} else {
expected_file = test_name.to_string();
from_file = test_name.to_string();
assert!(
test_names.next().is_none(),
"two mir pass names specified for MIR dump"
);
to_file = None;
};
let expected_file = test_dir.join(expected_file);
let dumped_string = if let Some(after) = to_file {
let before = self.get_mir_dump_dir().join(from_file);
let after = self.get_mir_dump_dir().join(after);
debug!(
"comparing the contents of: {} with {}",
@ -3166,7 +3199,7 @@ impl<'test> TestCx<'test> {
} else {
let mut output_file = PathBuf::new();
output_file.push(self.get_mir_dump_dir());
output_file.push(test_name);
output_file.push(&from_file);
debug!(
"comparing the contents of: {} with {}",
output_file.display(),
@ -3179,7 +3212,7 @@ impl<'test> TestCx<'test> {
output_file.parent().unwrap().display()
);
}
self.check_mir_test_timestamp(test_name, &output_file);
self.check_mir_test_timestamp(&from_file, &output_file);
let dumped_string = fs::read_to_string(&output_file).unwrap();
self.normalize_output(&dumped_string, &[])
};