Auto merge of #101318 - GuillaumeGomez:rollup-qsr51z4, r=GuillaumeGomez

Rollup of 9 pull requests

Successful merges:

 - #97739 (Uplift the `let_underscore` lints from clippy into rustc.)
 - #99583 (Add additional methods to the Demand type)
 - #100147 (optimization of access level table construction)
 - #100552 (rustc_target: Add a compatibility layer to separate internal and user-facing linker flavors)
 - #100827 (Simplify MIR opt tests)
 - #101166 (Generate error index with mdbook instead of raw HTML pages)
 - #101294 (Fix #100844 rebase accident)
 - #101298 (rustdoc: remove unused CSS `#main-content > .since`)
 - #101304 (Add autolabels for `A-query-system`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-09-02 10:55:24 +00:00
commit 9353538c7b
104 changed files with 2757 additions and 2289 deletions

View File

@ -1259,7 +1259,7 @@ dependencies = [
name = "error_index_generator"
version = "0.0.0"
dependencies = [
"rustdoc",
"mdbook",
]
[[package]]

View File

@ -1173,13 +1173,6 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// only the linker flavor is known; use the default linker for the selected flavor
(None, Some(flavor)) => Some((
PathBuf::from(match flavor {
LinkerFlavor::Em => {
if cfg!(windows) {
"emcc.bat"
} else {
"emcc"
}
}
LinkerFlavor::Gcc => {
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
// On historical Solaris systems, "cc" may have
@ -1194,11 +1187,17 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
}
}
LinkerFlavor::Ld => "ld",
LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::Lld(_) => "lld",
LinkerFlavor::PtxLinker => "rust-ptx-linker",
LinkerFlavor::BpfLinker => "bpf-linker",
LinkerFlavor::L4Bender => "l4-bender",
LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::EmCc => {
if cfg!(windows) {
"emcc.bat"
} else {
"emcc"
}
}
LinkerFlavor::Bpf => "bpf-linker",
LinkerFlavor::Ptx => "rust-ptx-linker",
}),
flavor,
)),
@ -1208,7 +1207,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
});
let flavor = if stem == "emcc" {
LinkerFlavor::Em
LinkerFlavor::EmCc
} else if stem == "gcc"
|| stem.ends_with("-gcc")
|| stem == "clang"
@ -1236,7 +1235,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// linker and linker flavor specified via command line have precedence over what the target
// specification specifies
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
let linker_flavor = sess.opts.cg.linker_flavor.map(LinkerFlavor::from_cli);
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
return ret;
}
@ -2113,11 +2113,11 @@ fn add_order_independent_options(
});
}
if flavor == LinkerFlavor::PtxLinker {
if flavor == LinkerFlavor::Ptx {
// Provide the linker with fallback to internal `target-cpu`.
cmd.arg("--fallback-arch");
cmd.arg(&codegen_results.crate_info.target_cpu);
} else if flavor == LinkerFlavor::BpfLinker {
} else if flavor == LinkerFlavor::Bpf {
cmd.arg("--cpu");
cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.arg("--cpu-features");

View File

@ -126,29 +126,26 @@ pub fn get_linker<'a>(
// to the linker args construction.
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
match flavor {
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
}
LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Gcc => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
as Box<dyn Linker>
}
LinkerFlavor::Ld if sess.target.os == "l4re" => {
Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
}
LinkerFlavor::Lld(LldFlavor::Ld)
| LinkerFlavor::Lld(LldFlavor::Ld64)
| LinkerFlavor::Ld => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
as Box<dyn Linker>
}
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
}
LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::L4Bender => Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>,
LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
}
}

View File

@ -11,6 +11,8 @@ privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interfac
.label = can't leak {$vis_descr} {$kind}
.visibility_label = `{$descr}` declared as {$vis_descr}
privacy_report_access_level = {$descr}
privacy_from_private_dep_in_public_interface =
{$kind} `{$descr}` from private dependency '{$krate}' in public interface

View File

@ -758,6 +758,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Internal attributes, Testing:
// ==========================================================================
rustc_attr!(TEST, rustc_access_level, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_outlives, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word), WarnFollowing),

View File

@ -21,10 +21,8 @@ use rustc_session::{build_session, getopts, DiagnosticOutput, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
use rustc_span::SourceFileHashAlgorithm;
use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy};
use rustc_target::spec::{
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel,
};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
use std::collections::{BTreeMap, BTreeSet};
use std::iter::FromIterator;
@ -552,7 +550,7 @@ fn test_codegen_options_tracking_hash() {
untracked!(link_args, vec![String::from("abc"), String::from("def")]);
untracked!(link_self_contained, Some(true));
untracked!(linker, Some(PathBuf::from("linker")));
untracked!(linker_flavor, Some(LinkerFlavor::Gcc));
untracked!(linker_flavor, Some(LinkerFlavorCli::Gcc));
untracked!(no_stack_check, true);
untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")]));
untracked!(rpath, true);

View File

@ -0,0 +1,175 @@
use crate::{LateContext, LateLintPass, LintContext};
use rustc_errors::{Applicability, LintDiagnosticBuilder, MultiSpan};
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_span::Symbol;
declare_lint! {
/// The `let_underscore_drop` lint checks for statements which don't bind
/// an expression which has a non-trivial Drop implementation to anything,
/// causing the expression to be dropped immediately instead of at end of
/// scope.
///
/// ### Example
/// ```
/// struct SomeStruct;
/// impl Drop for SomeStruct {
/// fn drop(&mut self) {
/// println!("Dropping SomeStruct");
/// }
/// }
///
/// fn main() {
/// #[warn(let_underscore_drop)]
/// // SomeStuct is dropped immediately instead of at end of scope,
/// // so "Dropping SomeStruct" is printed before "end of main".
/// // The order of prints would be reversed if SomeStruct was bound to
/// // a name (such as "_foo").
/// let _ = SomeStruct;
/// println!("end of main");
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Statements which assign an expression to an underscore causes the
/// expression to immediately drop instead of extending the expression's
/// lifetime to the end of the scope. This is usually unintended,
/// especially for types like `MutexGuard`, which are typically used to
/// lock a mutex for the duration of an entire scope.
///
/// If you want to extend the expression's lifetime to the end of the scope,
/// assign an underscore-prefixed name (such as `_foo`) to the expression.
/// If you do actually want to drop the expression immediately, then
/// calling `std::mem::drop` on the expression is clearer and helps convey
/// intent.
pub LET_UNDERSCORE_DROP,
Allow,
"non-binding let on a type that implements `Drop`"
}
declare_lint! {
/// The `let_underscore_lock` lint checks for statements which don't bind
/// a mutex to anything, causing the lock to be released immediately instead
/// of at end of scope, which is typically incorrect.
///
/// ### Example
/// ```compile_fail
/// use std::sync::{Arc, Mutex};
/// use std::thread;
/// let data = Arc::new(Mutex::new(0));
///
/// thread::spawn(move || {
/// // The lock is immediately released instead of at the end of the
/// // scope, which is probably not intended.
/// let _ = data.lock().unwrap();
/// println!("doing some work");
/// let mut lock = data.lock().unwrap();
/// *lock += 1;
/// });
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Statements which assign an expression to an underscore causes the
/// expression to immediately drop instead of extending the expression's
/// lifetime to the end of the scope. This is usually unintended,
/// especially for types like `MutexGuard`, which are typically used to
/// lock a mutex for the duration of an entire scope.
///
/// If you want to extend the expression's lifetime to the end of the scope,
/// assign an underscore-prefixed name (such as `_foo`) to the expression.
/// If you do actually want to drop the expression immediately, then
/// calling `std::mem::drop` on the expression is clearer and helps convey
/// intent.
pub LET_UNDERSCORE_LOCK,
Deny,
"non-binding let on a synchronization lock"
}
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK]);
const SYNC_GUARD_SYMBOLS: [Symbol; 3] = [
rustc_span::sym::MutexGuard,
rustc_span::sym::RwLockReadGuard,
rustc_span::sym::RwLockWriteGuard,
];
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
if !matches!(local.pat.kind, hir::PatKind::Wild) {
return;
}
if let Some(init) = local.init {
let init_ty = cx.typeck_results().expr_ty(init);
// If the type has a trivial Drop implementation, then it doesn't
// matter that we drop the value immediately.
if !init_ty.needs_drop(cx.tcx, cx.param_env) {
return;
}
let is_sync_lock = match init_ty.kind() {
ty::Adt(adt, _) => SYNC_GUARD_SYMBOLS
.iter()
.any(|guard_symbol| cx.tcx.is_diagnostic_item(*guard_symbol, adt.did())),
_ => false,
};
if is_sync_lock {
let mut span = MultiSpan::from_spans(vec![local.pat.span, init.span]);
span.push_span_label(
local.pat.span,
"this lock is not assigned to a binding and is immediately dropped".to_string(),
);
span.push_span_label(
init.span,
"this binding will immediately drop the value assigned to it".to_string(),
);
cx.struct_span_lint(LET_UNDERSCORE_LOCK, span, |lint| {
build_and_emit_lint(
lint,
local,
init.span,
"non-binding let on a synchronization lock",
)
})
} else {
cx.struct_span_lint(LET_UNDERSCORE_DROP, local.span, |lint| {
build_and_emit_lint(
lint,
local,
init.span,
"non-binding let on a type that implements `Drop`",
);
})
}
}
}
}
fn build_and_emit_lint(
lint: LintDiagnosticBuilder<'_, ()>,
local: &hir::Local<'_>,
init_span: rustc_span::Span,
msg: &str,
) {
lint.build(msg)
.span_suggestion_verbose(
local.pat.span,
"consider binding to an unused variable to avoid immediately dropping the value",
"_unused",
Applicability::MachineApplicable,
)
.multipart_suggestion(
"consider immediately dropping the value",
vec![
(local.span.until(init_span), "drop(".to_string()),
(init_span.shrink_to_hi(), ")".to_string()),
],
Applicability::MachineApplicable,
)
.emit();
}

View File

@ -55,6 +55,7 @@ mod expect;
pub mod hidden_unicode_codepoints;
mod internal;
mod late;
mod let_underscore;
mod levels;
mod methods;
mod non_ascii_idents;
@ -86,6 +87,7 @@ use builtin::*;
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
use hidden_unicode_codepoints::*;
use internal::*;
use let_underscore::*;
use methods::*;
use non_ascii_idents::*;
use non_fmt_panic::NonPanicFmt;
@ -189,6 +191,7 @@ macro_rules! late_lint_mod_passes {
VariantSizeDifferences: VariantSizeDifferences,
BoxPointers: BoxPointers,
PathStatements: PathStatements,
LetUnderscore: LetUnderscore,
// Depends on referenced function signatures in expressions
UnusedResults: UnusedResults,
NonUpperCaseGlobals: NonUpperCaseGlobals,
@ -315,6 +318,8 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
REDUNDANT_SEMICOLONS
);
add_lint_group!("let_underscore", LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK);
add_lint_group!(
"rust_2018_idioms",
BARE_TRAIT_OBJECTS,

View File

@ -12,7 +12,7 @@ use quote::{format_ident, quote};
use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
use syn::{spanned::Spanned, Meta, MetaList, MetaNameValue, NestedMeta, Path};
use syn::{spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path};
use synstructure::{BindingInfo, Structure, VariantInfo};
/// Which kind of suggestion is being created?
@ -28,8 +28,41 @@ enum SubdiagnosticSuggestionKind {
Verbose,
}
impl FromStr for SubdiagnosticSuggestionKind {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"" => Ok(SubdiagnosticSuggestionKind::Normal),
"_short" => Ok(SubdiagnosticSuggestionKind::Short),
"_hidden" => Ok(SubdiagnosticSuggestionKind::Hidden),
"_verbose" => Ok(SubdiagnosticSuggestionKind::Verbose),
_ => Err(()),
}
}
}
impl SubdiagnosticSuggestionKind {
pub fn to_suggestion_style(&self) -> TokenStream {
match self {
SubdiagnosticSuggestionKind::Normal => {
quote! { rustc_errors::SuggestionStyle::ShowCode }
}
SubdiagnosticSuggestionKind::Short => {
quote! { rustc_errors::SuggestionStyle::HideCodeInline }
}
SubdiagnosticSuggestionKind::Hidden => {
quote! { rustc_errors::SuggestionStyle::HideCodeAlways }
}
SubdiagnosticSuggestionKind::Verbose => {
quote! { rustc_errors::SuggestionStyle::ShowAlways }
}
}
}
}
/// Which kind of subdiagnostic is being created from a variant?
#[derive(Clone, Copy)]
#[derive(Clone)]
enum SubdiagnosticKind {
/// `#[label(...)]`
Label,
@ -40,31 +73,9 @@ enum SubdiagnosticKind {
/// `#[warning(...)]`
Warn,
/// `#[suggestion{,_short,_hidden,_verbose}]`
Suggestion(SubdiagnosticSuggestionKind),
}
impl FromStr for SubdiagnosticKind {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"label" => Ok(SubdiagnosticKind::Label),
"note" => Ok(SubdiagnosticKind::Note),
"help" => Ok(SubdiagnosticKind::Help),
"warning" => Ok(SubdiagnosticKind::Warn),
"suggestion" => Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal)),
"suggestion_short" => {
Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short))
}
"suggestion_hidden" => {
Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Hidden))
}
"suggestion_verbose" => {
Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Verbose))
}
_ => Err(()),
}
}
Suggestion { suggestion_kind: SubdiagnosticSuggestionKind, code: TokenStream },
/// `#[multipart_suggestion{,_short,_hidden,_verbose}]`
MultipartSuggestion { suggestion_kind: SubdiagnosticSuggestionKind },
}
impl quote::IdentFragment for SubdiagnosticKind {
@ -74,17 +85,9 @@ impl quote::IdentFragment for SubdiagnosticKind {
SubdiagnosticKind::Note => write!(f, "note"),
SubdiagnosticKind::Help => write!(f, "help"),
SubdiagnosticKind::Warn => write!(f, "warn"),
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal) => {
write!(f, "suggestion")
}
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short) => {
write!(f, "suggestion_short")
}
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Hidden) => {
write!(f, "suggestion_hidden")
}
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Verbose) => {
write!(f, "suggestion_verbose")
SubdiagnosticKind::Suggestion { .. } => write!(f, "suggestion_with_style"),
SubdiagnosticKind::MultipartSuggestion { .. } => {
write!(f, "multipart_suggestion_with_style")
}
}
}
@ -148,11 +151,9 @@ impl<'a> SessionSubdiagnosticDerive<'a> {
variant,
span,
fields: fields_map,
kinds: Vec::new(),
slugs: Vec::new(),
code: None,
span_field: None,
applicability: None,
has_suggestion_parts: false,
};
builder.into_tokens().unwrap_or_else(|v| v.to_compile_error())
});
@ -193,21 +194,15 @@ struct SessionSubdiagnosticDeriveBuilder<'a> {
/// derive builder.
fields: HashMap<String, TokenStream>,
/// Subdiagnostic kind of the type/variant.
kinds: Vec<(SubdiagnosticKind, proc_macro::Span)>,
/// Slugs of the subdiagnostic - corresponds to the Fluent identifier for the message - from the
/// `#[kind(slug)]` attribute on the type or variant.
slugs: Vec<(Path, proc_macro::Span)>,
/// If a suggestion, the code to suggest as a replacement - from the `#[kind(code = "...")]`
/// attribute on the type or variant.
code: Option<(TokenStream, proc_macro::Span)>,
/// Identifier for the binding to the `#[primary_span]` field.
span_field: Option<(proc_macro2::Ident, proc_macro::Span)>,
/// If a suggestion, the identifier for the binding to the `#[applicability]` field or a
/// `rustc_errors::Applicability::*` variant directly.
applicability: Option<(TokenStream, proc_macro::Span)>,
/// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error
/// during finalization if still `false`.
has_suggestion_parts: bool,
}
impl<'a> HasFieldMap for SessionSubdiagnosticDeriveBuilder<'a> {
@ -216,22 +211,79 @@ impl<'a> HasFieldMap for SessionSubdiagnosticDeriveBuilder<'a> {
}
}
/// Provides frequently-needed information about the diagnostic kinds being derived for this type.
#[derive(Clone, Copy, Debug)]
struct KindsStatistics {
has_multipart_suggestion: bool,
all_multipart_suggestions: bool,
has_normal_suggestion: bool,
}
impl<'a> FromIterator<&'a SubdiagnosticKind> for KindsStatistics {
fn from_iter<T: IntoIterator<Item = &'a SubdiagnosticKind>>(kinds: T) -> Self {
let mut ret = Self {
has_multipart_suggestion: false,
all_multipart_suggestions: true,
has_normal_suggestion: false,
};
for kind in kinds {
if let SubdiagnosticKind::MultipartSuggestion { .. } = kind {
ret.has_multipart_suggestion = true;
} else {
ret.all_multipart_suggestions = false;
}
if let SubdiagnosticKind::Suggestion { .. } = kind {
ret.has_normal_suggestion = true;
}
}
ret
}
}
impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
fn identify_kind(&mut self) -> Result<(), DiagnosticDeriveError> {
for (i, attr) in self.variant.ast().attrs.iter().enumerate() {
fn identify_kind(&mut self) -> Result<Vec<(SubdiagnosticKind, Path)>, DiagnosticDeriveError> {
let mut kind_slugs = vec![];
for attr in self.variant.ast().attrs {
let span = attr.span().unwrap();
let name = attr.path.segments.last().unwrap().ident.to_string();
let name = name.as_str();
let meta = attr.parse_meta()?;
let kind = match meta {
Meta::List(MetaList { ref nested, .. }) => {
let Meta::List(MetaList { ref nested, .. }) = meta else {
throw_invalid_attr!(attr, &meta);
};
let mut kind = match name {
"label" => SubdiagnosticKind::Label,
"note" => SubdiagnosticKind::Note,
"help" => SubdiagnosticKind::Help,
"warning" => SubdiagnosticKind::Warn,
_ => {
if let Some(suggestion_kind) =
name.strip_prefix("suggestion").and_then(|s| s.parse().ok())
{
SubdiagnosticKind::Suggestion { suggestion_kind, code: TokenStream::new() }
} else if let Some(suggestion_kind) =
name.strip_prefix("multipart_suggestion").and_then(|s| s.parse().ok())
{
SubdiagnosticKind::MultipartSuggestion { suggestion_kind }
} else {
throw_invalid_attr!(attr, &meta);
}
}
};
let mut slug = None;
let mut code = None;
let mut nested_iter = nested.into_iter();
if let Some(nested_attr) = nested_iter.next() {
match nested_attr {
NestedMeta::Meta(Meta::Path(path)) => {
self.slugs.push((path.clone(), span));
slug.set_once((path.clone(), span));
}
NestedMeta::Meta(meta @ Meta::NameValue(_))
if matches!(
@ -239,7 +291,7 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
"code" | "applicability"
) =>
{
// don't error for valid follow-up attributes
// Don't error for valid follow-up attributes.
}
nested_attr => {
throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
@ -262,79 +314,59 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
let nested_name = meta.path().segments.last().unwrap().ident.to_string();
let nested_name = nested_name.as_str();
match meta {
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
let value = match meta {
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) => value,
Meta::Path(_) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
diag.help("a diagnostic slug must be the first argument to the attribute")
}),
_ => throw_invalid_nested_attr!(attr, &nested_attr),
};
match nested_name {
"code" => {
let formatted_str = self.build_format(&s.value(), s.span());
self.code.set_once((formatted_str, span));
if matches!(kind, SubdiagnosticKind::Suggestion { .. }) {
let formatted_str = self.build_format(&value.value(), value.span());
code.set_once((formatted_str, span));
} else {
span_err(
span,
&format!(
"`code` is not a valid nested attribute of a `{}` attribute",
name
),
)
.emit();
}
}
"applicability" => {
let value = match Applicability::from_str(&s.value()) {
Ok(v) => v,
Err(()) => {
if matches!(
kind,
SubdiagnosticKind::Suggestion { .. }
| SubdiagnosticKind::MultipartSuggestion { .. }
) {
let value =
Applicability::from_str(&value.value()).unwrap_or_else(|()| {
span_err(span, "invalid applicability").emit();
Applicability::Unspecified
}
};
});
self.applicability.set_once((quote! { #value }, span));
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
diag.help(
"only `code` and `applicability` are valid nested \
attributes",
)
}),
}
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
if matches!(meta, Meta::Path(_)) {
diag.help(
"a diagnostic slug must be the first argument to the \
attribute",
)
} else {
diag
}
}),
}
}
let Ok(kind) = SubdiagnosticKind::from_str(name) else {
throw_invalid_attr!(attr, &meta)
};
kind
}
_ => throw_invalid_attr!(attr, &meta),
};
if matches!(
kind,
SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note
) && self.code.is_some()
{
throw_span_err!(
span,
&format!("`code` is not a valid nested attribute of a `{}` attribute", name)
);
}
if matches!(
kind,
SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note
) && self.applicability.is_some()
{
throw_span_err!(
span_err(
span,
&format!(
"`applicability` is not a valid nested attribute of a `{}` attribute",
name
)
);
).emit();
}
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
diag.help("only `code` and `applicability` are valid nested attributes")
}),
}
}
if self.slugs.len() != i + 1 {
let Some((slug, _)) = slug else {
throw_span_err!(
span,
&format!(
@ -342,146 +374,334 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
name
)
);
}
self.kinds.push((kind, span));
}
Ok(())
}
fn generate_field_code(
&mut self,
binding: &BindingInfo<'_>,
have_suggestion: bool,
) -> Result<TokenStream, DiagnosticDeriveError> {
let ast = binding.ast();
let inner_ty = FieldInnerTy::from_type(&ast.ty);
let info = FieldInfo {
binding: binding,
ty: inner_ty.inner_type().unwrap_or(&ast.ty),
span: &ast.span(),
};
for attr in &ast.attrs {
let name = attr.path.segments.last().unwrap().ident.to_string();
let name = name.as_str();
let span = attr.span().unwrap();
let meta = attr.parse_meta()?;
match meta {
Meta::Path(_) => match name {
"primary_span" => {
report_error_if_not_applied_to_span(attr, &info)?;
self.span_field.set_once((binding.binding.clone(), span));
return Ok(quote! {});
}
"applicability" if have_suggestion => {
report_error_if_not_applied_to_applicability(attr, &info)?;
let binding = binding.binding.clone();
self.applicability.set_once((quote! { #binding }, span));
return Ok(quote! {});
}
"applicability" => {
span_err(span, "`#[applicability]` is only valid on suggestions").emit();
return Ok(quote! {});
}
"skip_arg" => {
return Ok(quote! {});
}
_ => throw_invalid_attr!(attr, &meta, |diag| {
diag.help(
"only `primary_span`, `applicability` and `skip_arg` are valid field \
attributes",
)
}),
},
_ => throw_invalid_attr!(attr, &meta),
match kind {
SubdiagnosticKind::Suggestion { code: ref mut code_field, .. } => {
let Some((code, _)) = code else {
throw_span_err!(span, "suggestion without `code = \"...\"`");
};
*code_field = code;
}
SubdiagnosticKind::Label
| SubdiagnosticKind::Note
| SubdiagnosticKind::Help
| SubdiagnosticKind::Warn
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
}
let ident = ast.ident.as_ref().unwrap();
kind_slugs.push((kind, slug))
}
Ok(kind_slugs)
}
/// Generates the code for a field with no attributes.
fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream {
let ast = binding.ast();
assert_eq!(ast.attrs.len(), 0, "field with attribute used as diagnostic arg");
let diag = &self.diag;
let generated = quote! {
let ident = ast.ident.as_ref().unwrap();
quote! {
#diag.set_arg(
stringify!(#ident),
#binding
);
};
Ok(inner_ty.with(binding, generated))
}
}
fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
self.identify_kind()?;
if self.kinds.is_empty() {
/// Generates the necessary code for all attributes on a field.
fn generate_field_attr_code(
&mut self,
binding: &BindingInfo<'_>,
kind_stats: KindsStatistics,
) -> TokenStream {
let ast = binding.ast();
assert!(ast.attrs.len() > 0, "field without attributes generating attr code");
// Abstract over `Vec<T>` and `Option<T>` fields using `FieldInnerTy`, which will
// apply the generated code on each element in the `Vec` or `Option`.
let inner_ty = FieldInnerTy::from_type(&ast.ty);
ast.attrs
.iter()
.map(|attr| {
let info = FieldInfo {
binding,
ty: inner_ty.inner_type().unwrap_or(&ast.ty),
span: &ast.span(),
};
let generated = self
.generate_field_code_inner(kind_stats, attr, info)
.unwrap_or_else(|v| v.to_compile_error());
inner_ty.with(binding, generated)
})
.collect()
}
fn generate_field_code_inner(
&mut self,
kind_stats: KindsStatistics,
attr: &Attribute,
info: FieldInfo<'_>,
) -> Result<TokenStream, DiagnosticDeriveError> {
let meta = attr.parse_meta()?;
match meta {
Meta::Path(path) => self.generate_field_code_inner_path(kind_stats, attr, info, path),
Meta::List(list @ MetaList { .. }) => {
self.generate_field_code_inner_list(kind_stats, attr, info, list)
}
_ => throw_invalid_attr!(attr, &meta),
}
}
/// Generates the code for a `[Meta::Path]`-like attribute on a field (e.g. `#[primary_span]`).
fn generate_field_code_inner_path(
&mut self,
kind_stats: KindsStatistics,
attr: &Attribute,
info: FieldInfo<'_>,
path: Path,
) -> Result<TokenStream, DiagnosticDeriveError> {
let span = attr.span().unwrap();
let ident = &path.segments.last().unwrap().ident;
let name = ident.to_string();
let name = name.as_str();
match name {
"skip_arg" => Ok(quote! {}),
"primary_span" => {
if kind_stats.has_multipart_suggestion {
throw_invalid_attr!(attr, &Meta::Path(path), |diag| {
diag.help(
"multipart suggestions use one or more `#[suggestion_part]`s rather \
than one `#[primary_span]`",
)
})
}
report_error_if_not_applied_to_span(attr, &info)?;
let binding = info.binding.binding.clone();
self.span_field.set_once((binding, span));
Ok(quote! {})
}
"suggestion_part" => {
self.has_suggestion_parts = true;
if kind_stats.has_multipart_suggestion {
span_err(span, "`#[suggestion_part(...)]` attribute without `code = \"...\"`")
.emit();
Ok(quote! {})
} else {
throw_invalid_attr!(attr, &Meta::Path(path), |diag| {
diag.help(
"`#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead",
)
});
}
}
"applicability" => {
if kind_stats.has_multipart_suggestion || kind_stats.has_normal_suggestion {
report_error_if_not_applied_to_applicability(attr, &info)?;
let binding = info.binding.binding.clone();
self.applicability.set_once((quote! { #binding }, span));
} else {
span_err(span, "`#[applicability]` is only valid on suggestions").emit();
}
Ok(quote! {})
}
_ => throw_invalid_attr!(attr, &Meta::Path(path), |diag| {
let mut span_attrs = vec![];
if kind_stats.has_multipart_suggestion {
span_attrs.push("suggestion_part");
}
if !kind_stats.all_multipart_suggestions {
span_attrs.push("primary_span")
}
diag.help(format!(
"only `{}`, `applicability` and `skip_arg` are valid field attributes",
span_attrs.join(", ")
))
}),
}
}
/// Generates the code for a `[Meta::List]`-like attribute on a field (e.g.
/// `#[suggestion_part(code = "...")]`).
fn generate_field_code_inner_list(
&mut self,
kind_stats: KindsStatistics,
attr: &Attribute,
info: FieldInfo<'_>,
list: MetaList,
) -> Result<TokenStream, DiagnosticDeriveError> {
let span = attr.span().unwrap();
let ident = &list.path.segments.last().unwrap().ident;
let name = ident.to_string();
let name = name.as_str();
match name {
"suggestion_part" => {
if !kind_stats.has_multipart_suggestion {
throw_invalid_attr!(attr, &Meta::List(list), |diag| {
diag.help(
"`#[suggestion_part(...)]` is only valid in multipart suggestions",
)
})
}
self.has_suggestion_parts = true;
report_error_if_not_applied_to_span(attr, &info)?;
let mut code = None;
for nested_attr in list.nested.iter() {
let NestedMeta::Meta(ref meta) = nested_attr else {
throw_invalid_nested_attr!(attr, &nested_attr);
};
let span = meta.span().unwrap();
let nested_name = meta.path().segments.last().unwrap().ident.to_string();
let nested_name = nested_name.as_str();
let Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) = meta else {
throw_invalid_nested_attr!(attr, &nested_attr);
};
match nested_name {
"code" => {
let formatted_str = self.build_format(&value.value(), value.span());
code.set_once((formatted_str, span));
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
diag.help("`code` is the only valid nested attribute")
}),
}
}
let Some((code, _)) = code else {
span_err(span, "`#[suggestion_part(...)]` attribute without `code = \"...\"`")
.emit();
return Ok(quote! {});
};
let binding = info.binding;
Ok(quote! { suggestions.push((#binding, #code)); })
}
_ => throw_invalid_attr!(attr, &Meta::List(list), |diag| {
let mut span_attrs = vec![];
if kind_stats.has_multipart_suggestion {
span_attrs.push("suggestion_part");
}
if !kind_stats.all_multipart_suggestions {
span_attrs.push("primary_span")
}
diag.help(format!(
"only `{}`, `applicability` and `skip_arg` are valid field attributes",
span_attrs.join(", ")
))
}),
}
}
pub fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
let kind_slugs = self.identify_kind()?;
if kind_slugs.is_empty() {
throw_span_err!(
self.variant.ast().ident.span().unwrap(),
"subdiagnostic kind not specified"
);
};
let have_suggestion =
self.kinds.iter().any(|(k, _)| matches!(k, SubdiagnosticKind::Suggestion(_)));
let mut args = TokenStream::new();
for binding in self.variant.bindings() {
let arg = self
.generate_field_code(binding, have_suggestion)
.unwrap_or_else(|v| v.to_compile_error());
args.extend(arg);
}
let mut tokens = TokenStream::new();
for ((kind, _), (slug, _)) in self.kinds.iter().zip(&self.slugs) {
let code = match self.code.as_ref() {
Some((code, _)) => Some(quote! { #code }),
None if have_suggestion => {
span_err(self.span, "suggestion without `code = \"...\"`").emit();
Some(quote! { /* macro error */ "..." })
}
None => None,
let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect();
let init = if kind_stats.has_multipart_suggestion {
quote! { let mut suggestions = Vec::new(); }
} else {
quote! {}
};
let attr_args: TokenStream = self
.variant
.bindings()
.iter()
.filter(|binding| !binding.ast().attrs.is_empty())
.map(|binding| self.generate_field_attr_code(binding, kind_stats))
.collect();
let span_field = self.span_field.as_ref().map(|(span, _)| span);
let applicability = match self.applicability.clone() {
Some((applicability, _)) => Some(applicability),
None if have_suggestion => {
span_err(self.span, "suggestion without `applicability`").emit();
Some(quote! { rustc_errors::Applicability::Unspecified })
}
None => None,
};
let applicability = self.applicability.take().map_or_else(
|| quote! { rustc_errors::Applicability::Unspecified },
|(applicability, _)| applicability,
);
let diag = &self.diag;
let mut calls = TokenStream::new();
for (kind, slug) in kind_slugs {
let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
let message = quote! { rustc_errors::fluent::#slug };
let call = if matches!(kind, SubdiagnosticKind::Suggestion(..)) {
let call = match kind {
SubdiagnosticKind::Suggestion { suggestion_kind, code } => {
if let Some(span) = span_field {
quote! { #diag.#name(#span, #message, #code, #applicability); }
let style = suggestion_kind.to_suggestion_style();
quote! { #diag.#name(#span, #message, #code, #applicability, #style); }
} else {
span_err(self.span, "suggestion without `#[primary_span]` field").emit();
quote! { unreachable!(); }
}
} else if matches!(kind, SubdiagnosticKind::Label) {
}
SubdiagnosticKind::MultipartSuggestion { suggestion_kind } => {
if !self.has_suggestion_parts {
span_err(
self.span,
"multipart suggestion without any `#[suggestion_part(...)]` fields",
)
.emit();
}
let style = suggestion_kind.to_suggestion_style();
quote! { #diag.#name(#message, suggestions, #applicability, #style); }
}
SubdiagnosticKind::Label => {
if let Some(span) = span_field {
quote! { #diag.#name(#span, #message); }
} else {
span_err(self.span, "label without `#[primary_span]` field").emit();
quote! { unreachable!(); }
}
} else {
}
_ => {
if let Some(span) = span_field {
quote! { #diag.#name(#span, #message); }
} else {
quote! { #diag.#name(#message); }
}
}
};
tokens.extend(quote! {
#call
#args
});
calls.extend(call);
}
Ok(tokens)
let plain_args: TokenStream = self
.variant
.bindings()
.iter()
.filter(|binding| binding.ast().attrs.is_empty())
.map(|binding| self.generate_field_set_arg(binding))
.collect();
Ok(quote! {
#init
#attr_args
#calls
#plain_args
})
}
}

View File

@ -75,6 +75,14 @@ pub struct InPublicInterface<'a> {
pub vis_span: Span,
}
#[derive(SessionDiagnostic)]
#[diag(privacy::report_access_level)]
pub struct ReportAccessLevel {
#[primary_span]
pub span: Span,
pub descr: String,
}
#[derive(LintDiagnostic)]
#[diag(privacy::from_private_dep_in_public_interface)]
pub struct FromPrivateDependencyInPublicInterface<'a> {

View File

@ -33,7 +33,7 @@ use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::hygiene::Transparency;
use rustc_span::symbol::{kw, Ident};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use std::marker::PhantomData;
@ -42,7 +42,8 @@ use std::{cmp, fmt, mem};
use errors::{
FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, UnnamedItemIsPrivate,
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportAccessLevel,
UnnamedItemIsPrivate,
};
////////////////////////////////////////////////////////////////////////////////
@ -907,6 +908,60 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
}
}
////////////////////////////////////////////////////////////////////////////////
/// Visitor, used for AccessLevels table checking
////////////////////////////////////////////////////////////////////////////////
pub struct TestReachabilityVisitor<'tcx, 'a> {
tcx: TyCtxt<'tcx>,
access_levels: &'a AccessLevels,
}
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_access_level) {
let access_level = format!("{:?}", self.access_levels.map.get(&def_id));
let span = self.tcx.def_span(def_id.to_def_id());
self.tcx.sess.emit_err(ReportAccessLevel { span, descr: access_level });
}
}
}
impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
self.access_level_diagnostic(item.def_id);
match item.kind {
hir::ItemKind::Enum(ref def, _) => {
for variant in def.variants.iter() {
let variant_id = self.tcx.hir().local_def_id(variant.id);
self.access_level_diagnostic(variant_id);
for field in variant.data.fields() {
let def_id = self.tcx.hir().local_def_id(field.hir_id);
self.access_level_diagnostic(def_id);
}
}
}
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
for field in def.fields() {
let def_id = self.tcx.hir().local_def_id(field.hir_id);
self.access_level_diagnostic(def_id);
}
}
_ => {}
}
}
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
self.access_level_diagnostic(item.def_id);
}
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
self.access_level_diagnostic(item.def_id);
}
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
self.access_level_diagnostic(item.def_id);
}
}
//////////////////////////////////////////////////////////////////////////////////////
/// Name privacy visitor, checks privacy and reports violations.
/// Most of name privacy checks are performed during the main resolution phase,
@ -2045,6 +2100,9 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
}
}
let mut check_visitor = TestReachabilityVisitor { tcx, access_levels: &visitor.access_levels };
tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
tcx.arena.alloc(visitor.access_levels)
}

View File

@ -1,25 +1,21 @@
use crate::imports::ImportKind;
use crate::NameBinding;
use crate::NameBindingKind;
use crate::Resolver;
use rustc_ast::ast;
use rustc_ast::visit;
use rustc_ast::visit::Visitor;
use rustc_ast::Crate;
use rustc_ast::EnumDef;
use rustc_ast::ForeignMod;
use rustc_ast::NodeId;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::ty::Visibility;
use rustc_middle::ty::DefIdTree;
use rustc_span::sym;
use crate::imports::ImportKind;
use crate::BindingKey;
use crate::NameBinding;
use crate::NameBindingKind;
use crate::Resolver;
pub struct AccessLevelsVisitor<'r, 'a> {
r: &'r mut Resolver<'a>,
prev_level: Option<AccessLevel>,
changed: bool,
}
@ -28,11 +24,10 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
/// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
/// need access to a TyCtxt for that.
pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
let mut visitor =
AccessLevelsVisitor { r, changed: false, prev_level: Some(AccessLevel::Public) };
let mut visitor = AccessLevelsVisitor { r, changed: false };
visitor.set_access_level_def_id(CRATE_DEF_ID, Some(AccessLevel::Public));
visitor.set_exports_access_level(CRATE_DEF_ID);
visitor.set_bindings_access_level(CRATE_DEF_ID);
while visitor.changed {
visitor.reset();
@ -44,15 +39,17 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
fn reset(&mut self) {
self.changed = false;
self.prev_level = Some(AccessLevel::Public);
}
/// Update the access level of the exports of the given module accordingly. The module access
/// Update the access level of the bindings in the given module accordingly. The module access
/// level has to be Exported or Public.
/// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level).
fn set_exports_access_level(&mut self, module_id: LocalDefId) {
fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
assert!(self.r.module_map.contains_key(&&module_id.to_def_id()));
let module_level = self.r.access_levels.map.get(&module_id).copied();
if !module_level.is_some() {
return;
}
// Set the given binding access level to `AccessLevel::Public` and
// sets the rest of the `use` chain to `AccessLevel::Exported` until
// we hit the actual exported item.
@ -72,28 +69,20 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
}
};
let module_level = self.r.access_levels.map.get(&module_id).copied();
assert!(module_level >= Some(AccessLevel::Exported));
if let Some(exports) = self.r.reexport_map.get(&module_id) {
let pub_exports = exports
.iter()
.filter(|ex| ex.vis == Visibility::Public)
.cloned()
.collect::<Vec<_>>();
let module = self.r.get_module(module_id.to_def_id()).unwrap();
for export in pub_exports.into_iter() {
if let Some(export_def_id) = export.res.opt_def_id().and_then(|id| id.as_local()) {
self.set_access_level_def_id(export_def_id, Some(AccessLevel::Exported));
}
let resolutions = self.r.resolutions(module);
if let Some(ns) = export.res.ns() {
let key = BindingKey { ident: export.ident, ns, disambiguator: 0 };
let name_res = self.r.resolution(module, key);
if let Some(binding) = name_res.borrow().binding() {
set_import_binding_access_level(self, binding, module_level)
}
for (.., name_resolution) in resolutions.borrow().iter() {
if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() {
let access_level = match binding.is_import() {
true => {
set_import_binding_access_level(self, binding, module_level);
Some(AccessLevel::Exported)
},
false => module_level,
};
if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
self.set_access_level_def_id(def_id, access_level);
}
}
}
@ -127,97 +116,59 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
fn visit_item(&mut self, item: &'ast ast::Item) {
let inherited_item_level = match item.kind {
let def_id = self.r.local_def_id(item.id);
// Set access level of nested items.
// If it's a mod, also make the visitor walk all of its items
match item.kind {
// Resolved in rustc_privacy when types are available
ast::ItemKind::Impl(..) => return,
// Only exported `macro_rules!` items are public, but they always are
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
let is_macro_export =
item.attrs.iter().any(|attr| attr.has_name(sym::macro_export));
if is_macro_export { Some(AccessLevel::Public) } else { None }
}
// Foreign modules inherit level from parents.
ast::ItemKind::ForeignMod(..) => self.prev_level,
// Other `pub` items inherit levels from parents.
ast::ItemKind::ExternCrate(..)
| ast::ItemKind::Use(..)
| ast::ItemKind::Static(..)
| ast::ItemKind::Const(..)
| ast::ItemKind::Fn(..)
| ast::ItemKind::Mod(..)
| ast::ItemKind::GlobalAsm(..)
| ast::ItemKind::TyAlias(..)
| ast::ItemKind::Enum(..)
| ast::ItemKind::Struct(..)
| ast::ItemKind::Union(..)
| ast::ItemKind::Trait(..)
| ast::ItemKind::TraitAlias(..)
| ast::ItemKind::MacroDef(..) => {
if item.vis.kind.is_pub() {
self.prev_level
} else {
None
}
}
// Should be unreachable at this stage
ast::ItemKind::MacCall(..) => panic!(
"ast::ItemKind::MacCall encountered, this should not anymore appear at this stage"
),
};
let access_level = self.set_access_level(item.id, inherited_item_level);
// Foreign modules inherit level from parents.
ast::ItemKind::ForeignMod(..) => {
let parent_level =
self.r.access_levels.map.get(&self.r.local_parent(def_id)).copied();
self.set_access_level(item.id, parent_level);
}
// Only exported `macro_rules!` items are public, but they always are
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
if item.attrs.iter().any(|attr| attr.has_name(sym::macro_export)) {
self.set_access_level(item.id, Some(AccessLevel::Public));
}
}
// Set access level of nested items.
// If it's a mod, also make the visitor walk all of its items
match item.kind {
ast::ItemKind::Mod(..) => {
if access_level.is_some() {
self.set_exports_access_level(self.r.local_def_id(item.id));
}
let orig_level = std::mem::replace(&mut self.prev_level, access_level);
self.set_bindings_access_level(def_id);
visit::walk_item(self, item);
self.prev_level = orig_level;
}
ast::ItemKind::ForeignMod(ForeignMod { ref items, .. }) => {
for nested in items {
if nested.vis.kind.is_pub() {
self.set_access_level(nested.id, access_level);
}
}
}
ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
self.set_bindings_access_level(def_id);
for variant in variants {
let variant_level = self.set_access_level(variant.id, access_level);
if let Some(ctor_id) = variant.data.ctor_id() {
self.set_access_level(ctor_id, access_level);
}
let variant_def_id = self.r.local_def_id(variant.id);
let variant_level = self.r.access_levels.map.get(&variant_def_id).copied();
for field in variant.data.fields() {
self.set_access_level(field.id, variant_level);
}
}
}
ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
if let Some(ctor_id) = def.ctor_id() {
self.set_access_level(ctor_id, access_level);
}
ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
let inherited_level = self.r.access_levels.map.get(&def_id).copied();
for field in def.fields() {
if field.vis.kind.is_pub() {
self.set_access_level(field.id, access_level);
self.set_access_level(field.id, inherited_level);
}
}
}
ast::ItemKind::Trait(ref trait_kind) => {
for nested in trait_kind.items.iter() {
self.set_access_level(nested.id, access_level);
}
ast::ItemKind::Trait(..) => {
self.set_bindings_access_level(def_id);
}
ast::ItemKind::ExternCrate(..)
@ -229,9 +180,6 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
| ast::ItemKind::TraitAlias(..)
| ast::ItemKind::MacroDef(..)
| ast::ItemKind::Fn(..) => return,
// Unreachable kinds
ast::ItemKind::Impl(..) | ast::ItemKind::MacCall(..) => unreachable!(),
}
}
}

View File

@ -1133,16 +1133,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
if let Some(def_id) = module.opt_def_id() {
let mut reexports = Vec::new();
module.for_each_child(self.r, |_, ident, _, binding| {
// FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
// into the crate root to actual `NameBindingKind::Import`.
if binding.is_import()
|| matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
{
let res = binding.res().expect_non_local();
// Ambiguous imports are treated as errors at this point and are
// not exposed to other crates (see #36837 for more details).
if res != def::Res::Err && !binding.is_ambiguity() {
module.for_each_child(self.r, |this, ident, _, binding| {
if let Some(res) = this.is_reexport(binding) {
reexports.push(ModChild {
ident,
res,
@ -1151,7 +1143,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
macro_rules: false,
});
}
}
});
if !reexports.is_empty() {

View File

@ -2020,6 +2020,24 @@ impl<'a> Resolver<'a> {
}
self.main_def = Some(MainDefinition { res, is_import, span });
}
// Items that go to reexport table encoded to metadata and visible through it to other crates.
fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> {
// FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
// into the crate root to actual `NameBindingKind::Import`.
if binding.is_import()
|| matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
{
let res = binding.res().expect_non_local();
// Ambiguous imports are treated as errors at this point and are
// not exposed to other crates (see #36837 for more details).
if res != def::Res::Err && !binding.is_ambiguity() {
return Some(res);
}
}
return None;
}
}
fn names_to_string(names: &[Symbol]) -> String {

View File

@ -12,8 +12,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::ToStableHashKey;
use rustc_target::abi::{Align, TargetDataLayout};
use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings};
use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS};
use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
use crate::parse::{CrateCheckConfig, CrateConfig};
use rustc_feature::UnstableFeatures;
@ -2379,16 +2379,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
}
if cg.linker_flavor == Some(LinkerFlavor::L4Bender)
&& !nightly_options::is_unstable_enabled(matches)
{
early_error(
error_format,
"`l4-bender` linker flavor is unstable, `-Z unstable-options` \
flag must also be passed to explicitly use it",
);
}
let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format);
let cg = cg;

View File

@ -5,7 +5,7 @@ use crate::lint;
use crate::search_paths::SearchPath;
use crate::utils::NativeLib;
use rustc_errors::LanguageIdentifier;
use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet};
use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet};
use rustc_target::spec::{
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
};
@ -382,7 +382,7 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
pub const parse_instrument_coverage: &str =
@ -763,8 +763,8 @@ mod parse {
true
}
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
match v.and_then(LinkerFlavor::from_str) {
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
match v.and_then(LinkerFlavorCli::from_str) {
Some(lf) => *slot = Some(lf),
_ => return false,
}
@ -1139,7 +1139,7 @@ options! {
on C toolchain installed in the system"),
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
"system linker to link outputs with"),
linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
"linker flavor"),
linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
parse_linker_plugin_lto, [TRACKED],

View File

@ -223,6 +223,7 @@ symbols! {
LinkedList,
LintPass,
Mutex,
MutexGuard,
N,
NonZeroI128,
NonZeroI16,
@ -271,6 +272,8 @@ symbols! {
Rust,
RustcDecodable,
RustcEncodable,
RwLockReadGuard,
RwLockWriteGuard,
Send,
SeqCst,
SessionDiagnostic,
@ -1206,6 +1209,7 @@ symbols! {
rust_eh_unregister_frames,
rust_oom,
rustc,
rustc_access_level,
rustc_allocator,
rustc_allocator_nounwind,
rustc_allocator_zeroed,

View File

@ -2,6 +2,6 @@ use super::{wasm32_unknown_emscripten, LinkerFlavor, Target};
pub fn target() -> Target {
let mut target = wasm32_unknown_emscripten::target();
target.add_post_link_args(LinkerFlavor::Em, &["-sWASM=0", "--memory-init-file", "0"]);
target.add_post_link_args(LinkerFlavor::EmCc, &["-sWASM=0", "--memory-init-file", "0"]);
target
}

View File

@ -5,7 +5,7 @@ pub fn opts(endian: Endian) -> TargetOptions {
TargetOptions {
allow_asm: true,
endian,
linker_flavor: LinkerFlavor::BpfLinker,
linker_flavor: LinkerFlavor::Bpf,
atomic_cas: false,
dynamic_linking: true,
no_builtins: true,

View File

@ -4,7 +4,7 @@ pub fn opts() -> TargetOptions {
TargetOptions {
os: "l4re".into(),
env: "uclibc".into(),
linker_flavor: LinkerFlavor::L4Bender,
linker_flavor: LinkerFlavor::Ld,
panic_strategy: PanicStrategy::Abort,
linker: Some("l4-bender".into()),
linker_is_gnu: false,

View File

@ -92,14 +92,24 @@ mod windows_uwp_msvc_base;
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LinkerFlavor {
Em,
Gcc,
L4Bender,
Ld,
Msvc,
Lld(LldFlavor),
PtxLinker,
Msvc,
EmCc,
Bpf,
Ptx,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LinkerFlavorCli {
Gcc,
Ld,
Lld(LldFlavor),
Msvc,
Em,
BpfLinker,
PtxLinker,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@ -137,19 +147,40 @@ impl ToJson for LldFlavor {
}
}
impl ToJson for LinkerFlavor {
fn to_json(&self) -> Json {
self.desc().to_json()
impl LinkerFlavor {
pub fn from_cli(cli: LinkerFlavorCli) -> LinkerFlavor {
match cli {
LinkerFlavorCli::Gcc => LinkerFlavor::Gcc,
LinkerFlavorCli::Ld => LinkerFlavor::Ld,
LinkerFlavorCli::Lld(lld_flavor) => LinkerFlavor::Lld(lld_flavor),
LinkerFlavorCli::Msvc => LinkerFlavor::Msvc,
LinkerFlavorCli::Em => LinkerFlavor::EmCc,
LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf,
LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx,
}
}
fn to_cli(self) -> LinkerFlavorCli {
match self {
LinkerFlavor::Gcc => LinkerFlavorCli::Gcc,
LinkerFlavor::Ld => LinkerFlavorCli::Ld,
LinkerFlavor::Lld(lld_flavor) => LinkerFlavorCli::Lld(lld_flavor),
LinkerFlavor::Msvc => LinkerFlavorCli::Msvc,
LinkerFlavor::EmCc => LinkerFlavorCli::Em,
LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker,
LinkerFlavor::Ptx => LinkerFlavorCli::PtxLinker,
}
}
}
macro_rules! flavor_mappings {
($((($($flavor:tt)*), $string:expr),)*) => (
impl LinkerFlavor {
macro_rules! linker_flavor_cli_impls {
($(($($flavor:tt)*) $string:literal)*) => (
impl LinkerFlavorCli {
pub const fn one_of() -> &'static str {
concat!("one of: ", $($string, " ",)*)
}
pub fn from_str(s: &str) -> Option<Self> {
pub fn from_str(s: &str) -> Option<LinkerFlavorCli> {
Some(match s {
$($string => $($flavor)*,)*
_ => return None,
@ -165,18 +196,23 @@ macro_rules! flavor_mappings {
)
}
flavor_mappings! {
((LinkerFlavor::Em), "em"),
((LinkerFlavor::Gcc), "gcc"),
((LinkerFlavor::L4Bender), "l4-bender"),
((LinkerFlavor::Ld), "ld"),
((LinkerFlavor::Msvc), "msvc"),
((LinkerFlavor::PtxLinker), "ptx-linker"),
((LinkerFlavor::BpfLinker), "bpf-linker"),
((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"),
((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"),
((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"),
((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"),
linker_flavor_cli_impls! {
(LinkerFlavorCli::Gcc) "gcc"
(LinkerFlavorCli::Ld) "ld"
(LinkerFlavorCli::Lld(LldFlavor::Ld)) "ld.lld"
(LinkerFlavorCli::Lld(LldFlavor::Ld64)) "ld64.lld"
(LinkerFlavorCli::Lld(LldFlavor::Link)) "lld-link"
(LinkerFlavorCli::Lld(LldFlavor::Wasm)) "wasm-ld"
(LinkerFlavorCli::Msvc) "msvc"
(LinkerFlavorCli::Em) "em"
(LinkerFlavorCli::BpfLinker) "bpf-linker"
(LinkerFlavorCli::PtxLinker) "ptx-linker"
}
impl ToJson for LinkerFlavorCli {
fn to_json(&self) -> Json {
self.desc().to_json()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
@ -467,6 +503,7 @@ impl fmt::Display for LinkOutputKind {
}
pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<StaticCow<str>>>;
pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>;
/// Which kind of debuginfo does the target use?
///
@ -1210,19 +1247,21 @@ pub struct TargetOptions {
pub abi: StaticCow<str>,
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
pub vendor: StaticCow<str>,
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
/// on the command line. Defaults to `LinkerFlavor::Gcc`.
pub linker_flavor: LinkerFlavor,
/// Linker to invoke
pub linker: Option<StaticCow<str>>,
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
/// on the command line. Defaults to `LinkerFlavor::Gcc`.
pub linker_flavor: LinkerFlavor,
linker_flavor_json: LinkerFlavorCli,
/// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker
/// without clarifying its flavor in any way.
/// FIXME: Merge this into `LinkerFlavor`.
pub lld_flavor: LldFlavor,
/// Whether the linker support GNU-like arguments such as -O. Defaults to true.
/// FIXME: Merge this into `LinkerFlavor`.
pub linker_is_gnu: bool,
/// Linker arguments that are passed *before* any user-defined libraries.
pub pre_link_args: LinkArgs,
/// Objects to link before and after all other object code.
pub pre_link_objects: CrtObjects,
pub post_link_objects: CrtObjects,
@ -1231,24 +1270,31 @@ pub struct TargetOptions {
pub post_link_objects_self_contained: CrtObjects,
pub link_self_contained: LinkSelfContainedDefault,
/// Linker arguments that are passed *before* any user-defined libraries.
pub pre_link_args: LinkArgs,
pre_link_args_json: LinkArgsCli,
/// Linker arguments that are unconditionally passed after any
/// user-defined but before post-link objects. Standard platform
/// libraries that should be always be linked to, usually go here.
pub late_link_args: LinkArgs,
late_link_args_json: LinkArgsCli,
/// Linker arguments used in addition to `late_link_args` if at least one
/// Rust dependency is dynamically linked.
pub late_link_args_dynamic: LinkArgs,
late_link_args_dynamic_json: LinkArgsCli,
/// Linker arguments used in addition to `late_link_args` if all Rust
/// dependencies are statically linked.
pub late_link_args_static: LinkArgs,
late_link_args_static_json: LinkArgsCli,
/// Linker arguments that are unconditionally passed *after* any
/// user-defined libraries.
pub post_link_args: LinkArgs,
post_link_args_json: LinkArgsCli,
/// Optional link script applied to `dylib` and `executable` crate types.
/// This is a string containing the script, not a path. Can only be applied
/// to linkers where `linker_is_gnu` is true.
pub link_script: Option<StaticCow<str>>,
/// Environment variables to be set for the linker invocation.
pub link_env: StaticCow<[(StaticCow<str>, StaticCow<str>)]>,
/// Environment variables to be removed for the linker invocation.
@ -1333,8 +1379,6 @@ pub struct TargetOptions {
/// Default supported version of DWARF on this platform.
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
pub default_dwarf_version: u32,
/// Whether the linker support GNU-like arguments such as -O. Defaults to true.
pub linker_is_gnu: bool,
/// The MinGW toolchain has a known issue that prevents it from correctly
/// handling COFF object files with more than 2<sup>15</sup> sections. Since each weak
/// symbol needs its own COMDAT section, weak linkage implies a large
@ -1532,11 +1576,7 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati
LinkerFlavor::Lld(lld_flavor) => {
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
}
LinkerFlavor::Gcc
| LinkerFlavor::Em
| LinkerFlavor::L4Bender
| LinkerFlavor::BpfLinker
| LinkerFlavor::PtxLinker => {}
LinkerFlavor::Gcc | LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {}
}
}
@ -1554,6 +1594,36 @@ impl TargetOptions {
fn add_post_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) {
add_link_args(&mut self.post_link_args, flavor, args);
}
fn update_from_cli(&mut self) {
self.linker_flavor = LinkerFlavor::from_cli(self.linker_flavor_json);
for (args, args_json) in [
(&mut self.pre_link_args, &self.pre_link_args_json),
(&mut self.late_link_args, &self.late_link_args_json),
(&mut self.late_link_args_dynamic, &self.late_link_args_dynamic_json),
(&mut self.late_link_args_static, &self.late_link_args_static_json),
(&mut self.post_link_args, &self.post_link_args_json),
] {
*args = args_json
.iter()
.map(|(flavor, args)| (LinkerFlavor::from_cli(*flavor), args.clone()))
.collect();
}
}
fn update_to_cli(&mut self) {
self.linker_flavor_json = self.linker_flavor.to_cli();
for (args, args_json) in [
(&self.pre_link_args, &mut self.pre_link_args_json),
(&self.late_link_args, &mut self.late_link_args_json),
(&self.late_link_args_dynamic, &mut self.late_link_args_dynamic_json),
(&self.late_link_args_static, &mut self.late_link_args_static_json),
(&self.post_link_args, &mut self.post_link_args_json),
] {
*args_json =
args.iter().map(|(flavor, args)| (flavor.to_cli(), args.clone())).collect();
}
}
}
impl Default for TargetOptions {
@ -1568,11 +1638,11 @@ impl Default for TargetOptions {
env: "".into(),
abi: "".into(),
vendor: "unknown".into(),
linker_flavor: LinkerFlavor::Gcc,
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()),
linker_flavor: LinkerFlavor::Gcc,
linker_flavor_json: LinkerFlavorCli::Gcc,
lld_flavor: LldFlavor::Ld,
pre_link_args: LinkArgs::new(),
post_link_args: LinkArgs::new(),
linker_is_gnu: true,
link_script: None,
asm_args: cvs![],
cpu: "generic".into(),
@ -1599,7 +1669,6 @@ impl Default for TargetOptions {
is_like_msvc: false,
is_like_wasm: false,
default_dwarf_version: 4,
linker_is_gnu: true,
allows_weak_linkage: true,
has_rpath: false,
no_default_libraries: true,
@ -1612,9 +1681,16 @@ impl Default for TargetOptions {
pre_link_objects_self_contained: Default::default(),
post_link_objects_self_contained: Default::default(),
link_self_contained: LinkSelfContainedDefault::False,
pre_link_args: LinkArgs::new(),
pre_link_args_json: LinkArgsCli::new(),
late_link_args: LinkArgs::new(),
late_link_args_json: LinkArgsCli::new(),
late_link_args_dynamic: LinkArgs::new(),
late_link_args_dynamic_json: LinkArgsCli::new(),
late_link_args_static: LinkArgs::new(),
late_link_args_static_json: LinkArgsCli::new(),
post_link_args: LinkArgs::new(),
post_link_args_json: LinkArgsCli::new(),
link_env: cvs![],
link_env_remove: cvs![],
archive_format: "gnu".into(),
@ -2019,13 +2095,13 @@ impl Target {
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, LinkerFlavor) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match LinkerFlavor::from_str(s) {
($key_name:ident = $json_name:expr, LinkerFlavor) => ( {
let name = $json_name;
obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
match LinkerFlavorCli::from_str(s) {
Some(linker_flavor) => base.$key_name = linker_flavor,
_ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \
Use {}", s, LinkerFlavor::one_of()))),
Use {}", s, LinkerFlavorCli::one_of()))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
@ -2106,14 +2182,14 @@ impl Target {
base.$key_name = args;
}
} );
($key_name:ident, link_args) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(val) = obj.remove(&name) {
($key_name:ident = $json_name:expr, link_args) => ( {
let name = $json_name;
if let Some(val) = obj.remove(name) {
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
JSON object with fields per linker-flavor.", name))?;
let mut args = LinkArgs::new();
let mut args = LinkArgsCli::new();
for (k, v) in obj {
let flavor = LinkerFlavor::from_str(&k).ok_or_else(|| {
let flavor = LinkerFlavorCli::from_str(&k).ok_or_else(|| {
format!("{}: '{}' is not a valid value for linker-flavor. \
Use 'em', 'gcc', 'ld' or 'msvc'", name, k)
})?;
@ -2199,19 +2275,20 @@ impl Target {
key!(env);
key!(abi);
key!(vendor);
key!(linker_flavor, LinkerFlavor)?;
key!(linker, optional);
key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?;
key!(lld_flavor, LldFlavor)?;
key!(linker_is_gnu, bool);
key!(pre_link_objects = "pre-link-objects", link_objects);
key!(post_link_objects = "post-link-objects", link_objects);
key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
key!(link_self_contained = "crt-objects-fallback", link_self_contained)?;
key!(pre_link_args, link_args);
key!(late_link_args, link_args);
key!(late_link_args_dynamic, link_args);
key!(late_link_args_static, link_args);
key!(post_link_args, link_args);
key!(pre_link_args_json = "pre-link-args", link_args);
key!(late_link_args_json = "late-link-args", link_args);
key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args);
key!(late_link_args_static_json = "late-link-args-static", link_args);
key!(post_link_args_json = "post-link-args", link_args);
key!(link_script, optional);
key!(link_env, env);
key!(link_env_remove, list);
@ -2239,7 +2316,6 @@ impl Target {
key!(is_like_msvc, bool);
key!(is_like_wasm, bool);
key!(default_dwarf_version, u32);
key!(linker_is_gnu, bool);
key!(allows_weak_linkage, bool);
key!(has_rpath, bool);
key!(no_default_libraries, bool);
@ -2296,6 +2372,8 @@ impl Target {
// This can cause unfortunate ICEs later down the line.
return Err("may not set is_builtin for targets not built-in".into());
}
base.update_from_cli();
// Each field should have been read using `Json::remove` so any keys remaining are unused.
let remaining_keys = obj.keys();
Ok((
@ -2387,42 +2465,44 @@ impl ToJson for Target {
fn to_json(&self) -> Json {
let mut d = serde_json::Map::new();
let default: TargetOptions = Default::default();
let mut target = self.clone();
target.update_to_cli();
macro_rules! target_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
d.insert(name, self.$attr.to_json());
d.insert(name, target.$attr.to_json());
}};
}
macro_rules! target_option_val {
($attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != self.$attr {
d.insert(name, self.$attr.to_json());
if default.$attr != target.$attr {
d.insert(name, target.$attr.to_json());
}
}};
($attr:ident, $key_name:expr) => {{
let name = $key_name;
if default.$attr != self.$attr {
d.insert(name.into(), self.$attr.to_json());
($attr:ident, $json_name:expr) => {{
let name = $json_name;
if default.$attr != target.$attr {
d.insert(name.into(), target.$attr.to_json());
}
}};
(link_args - $attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != self.$attr {
let obj = self
(link_args - $attr:ident, $json_name:expr) => {{
let name = $json_name;
if default.$attr != target.$attr {
let obj = target
.$attr
.iter()
.map(|(k, v)| (k.desc().to_string(), v.clone()))
.collect::<BTreeMap<_, _>>();
d.insert(name, obj.to_json());
d.insert(name.to_string(), obj.to_json());
}
}};
(env - $attr:ident) => {{
let name = (stringify!($attr)).replace("_", "-");
if default.$attr != self.$attr {
let obj = self
if default.$attr != target.$attr {
let obj = target
.$attr
.iter()
.map(|&(ref k, ref v)| format!("{k}={v}"))
@ -2444,19 +2524,20 @@ impl ToJson for Target {
target_option_val!(env);
target_option_val!(abi);
target_option_val!(vendor);
target_option_val!(linker_flavor);
target_option_val!(linker);
target_option_val!(linker_flavor_json, "linker-flavor");
target_option_val!(lld_flavor);
target_option_val!(linker_is_gnu);
target_option_val!(pre_link_objects);
target_option_val!(post_link_objects);
target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback");
target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback");
target_option_val!(link_self_contained, "crt-objects-fallback");
target_option_val!(link_args - pre_link_args);
target_option_val!(link_args - late_link_args);
target_option_val!(link_args - late_link_args_dynamic);
target_option_val!(link_args - late_link_args_static);
target_option_val!(link_args - post_link_args);
target_option_val!(link_args - pre_link_args_json, "pre-link-args");
target_option_val!(link_args - late_link_args_json, "late-link-args");
target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic");
target_option_val!(link_args - late_link_args_static_json, "late-link-args-static");
target_option_val!(link_args - post_link_args_json, "post-link-args");
target_option_val!(link_script);
target_option_val!(env - link_env);
target_option_val!(link_env_remove);
@ -2485,7 +2566,6 @@ impl ToJson for Target {
target_option_val!(is_like_msvc);
target_option_val!(is_like_wasm);
target_option_val!(default_dwarf_version);
target_option_val!(linker_is_gnu);
target_option_val!(allows_weak_linkage);
target_option_val!(has_rpath);
target_option_val!(no_default_libraries);

View File

@ -10,7 +10,7 @@ pub fn target() -> Target {
options: TargetOptions {
os: "cuda".into(),
vendor: "nvidia".into(),
linker_flavor: LinkerFlavor::PtxLinker,
linker_flavor: LinkerFlavor::Ptx,
// The linker can be installed from `crates.io`.
linker: Some("rust-ptx-linker".into()),
linker_is_gnu: false,

View File

@ -2,9 +2,11 @@ use super::super::*;
use std::assert_matches::assert_matches;
// Test target self-consistency and JSON encoding/decoding roundtrip.
pub(super) fn test_target(target: Target, triple: &str) {
pub(super) fn test_target(mut target: Target, triple: &str) {
let recycled_target = Target::from_json(target.to_json()).map(|(j, _)| j);
target.update_to_cli();
target.check_consistency(triple);
assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target));
assert_eq!(recycled_target, Ok(target));
}
impl Target {
@ -22,10 +24,9 @@ impl Target {
assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64));
assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link));
assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm));
assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender));
assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em));
assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker));
assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker));
assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::EmCc));
assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf));
assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx));
for args in [
&self.pre_link_args,
@ -65,17 +66,14 @@ impl Target {
LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
)
}
(LinkerFlavor::L4Bender, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::L4Bender)
(LinkerFlavor::EmCc, LldFlavor::Wasm) => {
assert_matches!(flavor, LinkerFlavor::EmCc)
}
(LinkerFlavor::Em, LldFlavor::Wasm) => {
assert_matches!(flavor, LinkerFlavor::Em)
(LinkerFlavor::Bpf, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::Bpf)
}
(LinkerFlavor::BpfLinker, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::BpfLinker)
}
(LinkerFlavor::PtxLinker, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::PtxLinker)
(LinkerFlavor::Ptx, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::Ptx)
}
flavors => unreachable!("unexpected flavor combination: {:?}", flavors),
}

View File

@ -5,13 +5,13 @@ pub fn target() -> Target {
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
let pre_link_args = LinkArgs::new();
let post_link_args = TargetOptions::link_args(
LinkerFlavor::Em,
LinkerFlavor::EmCc,
&["-sABORTING_MALLOC=0", "-Wl,--fatal-warnings"],
);
let opts = TargetOptions {
os: "emscripten".into(),
linker_flavor: LinkerFlavor::Em,
linker_flavor: LinkerFlavor::EmCc,
// emcc emits two files - a .js file to instantiate the wasm and supply platform
// functionality, and a .wasm file.
exe_suffix: ".js".into(),

View File

@ -796,7 +796,7 @@ pub trait Provider {
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_ref::<str>(&self.field)
/// .provide_value::<i32>(|| self.num_field);
/// .provide_value::<i32>(self.num_field);
/// }
/// }
/// ```
@ -881,28 +881,55 @@ impl<'a> Demand<'a> {
///
/// # Examples
///
/// Provides an `u8`.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: u8 }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_value::<u8>(self.field);
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn provide_value<T>(&mut self, value: T) -> &mut Self
where
T: 'static,
{
self.provide::<tags::Value<T>>(value)
}
/// Provide a value or other type with only static lifetimes computed using a closure.
///
/// # Examples
///
/// Provides a `String` by cloning.
///
/// ```rust
/// # #![feature(provide_any)]
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: String }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_value::<String>(|| self.field.clone());
/// demand.provide_value_with::<String>(|| self.field.clone());
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn provide_value<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
where
T: 'static,
{
self.provide_with::<tags::Value<T>>(fulfil)
}
/// Provide a reference, note that the referee type must be bounded by `'static`,
/// Provide a reference. The referee type must be bounded by `'static`,
/// but may be unsized.
///
/// # Examples
@ -910,7 +937,8 @@ impl<'a> Demand<'a> {
/// Provides a reference to a field as a `&str`.
///
/// ```rust
/// # #![feature(provide_any)]
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { field: String }
///
@ -925,6 +953,40 @@ impl<'a> Demand<'a> {
self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
}
/// Provide a reference computed using a closure. The referee type
/// must be bounded by `'static`, but may be unsized.
///
/// # Examples
///
/// Provides a reference to a field as a `&str`.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
/// # struct SomeConcreteType { business: String, party: String }
/// # fn today_is_a_weekday() -> bool { true }
///
/// impl Provider for SomeConcreteType {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// demand.provide_ref_with::<str>(|| {
/// if today_is_a_weekday() {
/// &self.business
/// } else {
/// &self.party
/// }
/// });
/// }
/// }
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn provide_ref_with<T: ?Sized + 'static>(
&mut self,
fulfil: impl FnOnce() -> &'a T,
) -> &mut Self {
self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
}
/// Provide a value with the given `Type` tag.
fn provide<I>(&mut self, value: I::Reified) -> &mut Self
where
@ -946,6 +1008,156 @@ impl<'a> Demand<'a> {
}
self
}
/// Check if the `Demand` would be satisfied if provided with a
/// value of the specified type. If the type does not match or has
/// already been provided, returns false.
///
/// # Examples
///
/// Check if an `u8` still needs to be provided and then provides
/// it.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
///
/// struct Parent(Option<u8>);
///
/// impl Provider for Parent {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// if let Some(v) = self.0 {
/// demand.provide_value::<u8>(v);
/// }
/// }
/// }
///
/// struct Child {
/// parent: Parent,
/// }
///
/// impl Child {
/// // Pretend that this takes a lot of resources to evaluate.
/// fn an_expensive_computation(&self) -> Option<u8> {
/// Some(99)
/// }
/// }
///
/// impl Provider for Child {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// // In general, we don't know if this call will provide
/// // an `u8` value or not...
/// self.parent.provide(demand);
///
/// // ...so we check to see if the `u8` is needed before
/// // we run our expensive computation.
/// if demand.would_be_satisfied_by_value_of::<u8>() {
/// if let Some(v) = self.an_expensive_computation() {
/// demand.provide_value::<u8>(v);
/// }
/// }
///
/// // The demand will be satisfied now, regardless of if
/// // the parent provided the value or we did.
/// assert!(!demand.would_be_satisfied_by_value_of::<u8>());
/// }
/// }
///
/// let parent = Parent(Some(42));
/// let child = Child { parent };
/// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
///
/// let parent = Parent(None);
/// let child = Child { parent };
/// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
where
T: 'static,
{
self.would_be_satisfied_by::<tags::Value<T>>()
}
/// Check if the `Demand` would be satisfied if provided with a
/// reference to a value of the specified type. If the type does
/// not match or has already been provided, returns false.
///
/// # Examples
///
/// Check if a `&str` still needs to be provided and then provides
/// it.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
///
/// struct Parent(Option<String>);
///
/// impl Provider for Parent {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// if let Some(v) = &self.0 {
/// demand.provide_ref::<str>(v);
/// }
/// }
/// }
///
/// struct Child {
/// parent: Parent,
/// name: String,
/// }
///
/// impl Child {
/// // Pretend that this takes a lot of resources to evaluate.
/// fn an_expensive_computation(&self) -> Option<&str> {
/// Some(&self.name)
/// }
/// }
///
/// impl Provider for Child {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// // In general, we don't know if this call will provide
/// // a `str` reference or not...
/// self.parent.provide(demand);
///
/// // ...so we check to see if the `&str` is needed before
/// // we run our expensive computation.
/// if demand.would_be_satisfied_by_ref_of::<str>() {
/// if let Some(v) = self.an_expensive_computation() {
/// demand.provide_ref::<str>(v);
/// }
/// }
///
/// // The demand will be satisfied now, regardless of if
/// // the parent provided the reference or we did.
/// assert!(!demand.would_be_satisfied_by_ref_of::<str>());
/// }
/// }
///
/// let parent = Parent(Some("parent".into()));
/// let child = Child { parent, name: "child".into() };
/// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
///
/// let parent = Parent(None);
/// let child = Child { parent, name: "child".into() };
/// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
where
T: ?Sized + 'static,
{
self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
}
fn would_be_satisfied_by<I>(&self) -> bool
where
I: tags::Type<'a>,
{
matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
}
}
#[unstable(feature = "provide_any", issue = "96024")]
@ -1050,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a {
/// Returns some reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
where
I: tags::Type<'a>,
{
if self.tag_id() == TypeId::of::<I>() {
// SAFETY: Just checked whether we're pointing to an I.
Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
} else {
None
}
}
/// Returns some mutable reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
where
I: tags::Type<'a>,

View File

@ -142,7 +142,7 @@ impl Provider for SomeConcreteType {
demand
.provide_ref::<String>(&self.some_string)
.provide_ref::<str>(&self.some_string)
.provide_value::<String>(|| "bye".to_owned());
.provide_value_with::<String>(|| "bye".to_owned());
}
}

View File

@ -192,6 +192,7 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
and cause Futures to not implement `Send`"]
#[stable(feature = "rust1", since = "1.0.0")]
#[clippy::has_significant_drop]
#[cfg_attr(not(test), rustc_diagnostic_item = "MutexGuard")]
pub struct MutexGuard<'a, T: ?Sized + 'a> {
lock: &'a Mutex<T>,
poison: poison::Guard,

View File

@ -101,6 +101,7 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
and cause Futures to not implement `Send`"]
#[stable(feature = "rust1", since = "1.0.0")]
#[clippy::has_significant_drop]
#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockReadGuard")]
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
// NB: we use a pointer instead of `&'a T` to avoid `noalias` violations, because a
// `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
@ -130,6 +131,7 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
and cause Future's to not implement `Send`"]
#[stable(feature = "rust1", since = "1.0.0")]
#[clippy::has_significant_drop]
#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockWriteGuard")]
pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
lock: &'a RwLock<T>,
poison: poison::Guard,

View File

@ -793,7 +793,7 @@ impl Step for ErrorIndex {
t!(fs::create_dir_all(&out));
let mut index = tool::ErrorIndex::command(builder);
index.arg("html");
index.arg(out.join("error-index.html"));
index.arg(out);
index.arg(&builder.version);
builder.run(&mut index);

View File

@ -215,7 +215,6 @@ details.rustdoc-toggle > summary::before,
div.impl-items > div:not(.docblock):not(.item-info),
.content ul.crate a.crate,
a.srclink,
#main-content > .since,
#help-button > button,
details.rustdoc-toggle.top-doc > summary,
details.rustdoc-toggle.top-doc > summary::before,

View File

@ -1,4 +1,6 @@
// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
// unit-test: EarlyOtherwiseBranch
// FIXME: This test was broken by the derefer change.
// example from #68867
type CSSFloat = f32;
@ -11,7 +13,6 @@ pub enum ViewportPercentageLength {
}
// EMIT_MIR early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
// EMIT_MIR early_otherwise_branch_68867.try_sum EarlyOtherwiseBranch.before SimplifyConstCondition-final.after
#[no_mangle]
pub extern "C" fn try_sum(
x: &ViewportPercentageLength,

View File

@ -1,322 +0,0 @@
- // MIR for `try_sum` before EarlyOtherwiseBranch
+ // MIR for `try_sum` after SimplifyConstCondition-final
fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> Result<ViewportPercentageLength, ()> {
debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+1:5: +1:6
debug other => _2; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+2:5: +2:10
let mut _0: std::result::Result<ViewportPercentageLength, ()>; // return place in scope 0 at $DIR/early_otherwise_branch_68867.rs:+3:6: +3:42
let mut _3: ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
let mut _4: (&ViewportPercentageLength, &ViewportPercentageLength); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _5: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
let mut _6: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
let mut _7: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:21: +6:30
let mut _8: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:21: +7:30
let mut _9: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:23: +8:34
let mut _10: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:23: +9:34
let mut _11: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:11: +6:18
let _12: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
let _13: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
let mut _14: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
let mut _15: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
let mut _16: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
let _17: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
let _18: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
let mut _19: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
let mut _20: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
let mut _21: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
let _22: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
let _23: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
let mut _24: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
let mut _25: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
let mut _26: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
let _27: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
let _28: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
let mut _29: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
let mut _30: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:14: +10:28
let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
scope 1 {
- debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ debug one => _15; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ debug other => _16; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
}
scope 2 {
- debug one => _17; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- debug other => _18; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ debug one => _20; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ debug other => _21; // in scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
}
scope 3 {
- debug one => _22; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- debug other => _23; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ debug one => _25; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ debug other => _26; // in scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
}
scope 4 {
- debug one => _27; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- debug other => _28; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ debug one => _30; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ debug other => _31; // in scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
- StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
- _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +11:6
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
+ (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:15: +5:16
StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
_6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:18: +5:23
Deinit(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
(_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
_34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb11]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb1: {
_35 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb2: {
StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
bb3: {
_36 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb4: {
_37 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb5: {
_38 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb6: {
- StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
_39 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
- StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ _15 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:14: +6:17
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
_40 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
- StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
- StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
- _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
- StorageLive(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
- _16 = _13; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
- _14 = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
- StorageDead(_16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
- StorageDead(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
- Deinit(_3); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
- ((_3 as Vw).0: f32) = move _14; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
- discriminant(_3) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ _16 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:24: +6:29
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:41
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:44: +6:49
+ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:38: +6:49
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:48: +6:49
+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:35: +6:50
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+6:49: +6:50
}
bb7: {
- StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
_41 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
- StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ _20 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:14: +7:17
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
_42 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
- StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
- StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
- _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
- StorageLive(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
- _21 = _18; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
- _19 = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
- StorageDead(_21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
- StorageDead(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
- Deinit(_3); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
- ((_3 as Vh).0: f32) = move _19; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
- discriminant(_3) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ _21 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:24: +7:29
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:41
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:44: +7:49
+ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:38: +7:49
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:48: +7:49
+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:35: +7:50
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+7:49: +7:50
}
bb8: {
- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
_43 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:16: +8:19
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
_44 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
- StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
- StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
- _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
- StorageLive(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
- _26 = _23; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
- _24 = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
- StorageDead(_26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
- StorageDead(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
- Deinit(_3); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
- ((_3 as Vmin).0: f32) = move _24; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
- discriminant(_3) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:28: +8:33
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:47
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:50: +8:55
+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:44: +8:55
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:54: +8:55
+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:39: +8:56
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+8:55: +8:56
}
bb9: {
- StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
_45 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
- StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:16: +9:19
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
_46 = deref_copy (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
- StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
- StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
- _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
- StorageLive(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
- _31 = _28; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
- _29 = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
- StorageDead(_31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
- StorageDead(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
- Deinit(_3); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
- ((_3 as Vmax).0: f32) = move _29; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
- discriminant(_3) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:28: +9:33
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:47
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:50: +9:55
+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:44: +9:55
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:54: +9:55
+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:39: +9:56
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+9:55: +9:56
}
bb10: {
Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
bb11: {
unreachable; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
}

View File

@ -80,7 +80,7 @@
StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:23: +5:24
_34 = deref_copy (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
_11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:14: +5:24
switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb11]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:8: +5:24
}
bb1: {
@ -91,14 +91,14 @@
bb2: {
StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
Deinit(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:25: +10:27
Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
((_0 as Err).0: ()) = move _33; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:21: +10:28
StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+10:27: +10:28
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
bb3: {
@ -221,11 +221,11 @@
discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+5:5: +11:7
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+11:6: +11:7
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:1: +12:2
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
bb11: {
unreachable; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:+12:2: +12:2
}
}

View File

@ -10,4 +10,3 @@ fn main() {
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff
// EMIT_MIR issue_73223.main.PreCodegen.diff

View File

@ -1,117 +0,0 @@
- // MIR for `main` before PreCodegen
+ // MIR for `main` after PreCodegen
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 1 {
debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
scope 3 {
debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 4 {
debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 5 {
debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
}
}
}
scope 2 {
debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
_3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
_1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
_7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb1: {
StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
}
bb2: {
StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
}
}

View File

@ -1,117 +0,0 @@
- // MIR for `main` before PreCodegen
+ // MIR for `main` after PreCodegen
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/issue-73223.rs:+0:11: +0:11
let _1: i32; // in scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
let _3: i32; // in scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _12: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _14: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _19: std::option::Option<std::fmt::Arguments>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 1 {
debug split => _1; // in scope 1 at $DIR/issue-73223.rs:+1:9: +1:14
let _4: std::option::Option<i32>; // in scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
scope 3 {
debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:+6:9: +6:14
let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 4 {
debug left_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
debug right_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let _13: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
scope 5 {
debug kind => _13; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
}
}
}
scope 2 {
debug v => _3; // in scope 2 at $DIR/issue-73223.rs:+2:14: +2:15
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/issue-73223.rs:+1:9: +1:14
StorageLive(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
Deinit(_2); // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:+1:23: +1:30
StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
_3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:+2:14: +2:15
_1 = _3; // scope 2 at $DIR/issue-73223.rs:+2:20: +2:21
StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:+2:20: +2:21
StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:+4:6: +4:7
StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:+6:9: +6:14
StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
_7 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_5.1: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_8 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_9 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_12 = (*_8); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_11 = Eq(move _12, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_10 = Not(move _11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
switchInt(move _10) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb1: {
StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_18 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
Deinit(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_14 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option<Arguments<'t0>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
// + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
}
bb2: {
StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:+8:1: +8:2
StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:+8:1: +8:2
return; // scope 0 at $DIR/issue-73223.rs:+8:2: +8:2
}
}

View File

@ -1,66 +0,0 @@
- // MIR for `array_bound` before InstCombine
+ // MIR for `array_bound` after InstCombine
fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- _7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _7 = _2; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
_11 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
_6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
- _5 = Len((*_11)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
}
bb1: {
StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
_8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
_10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
}
bb2: {
_0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
}
bb3: {
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
}
bb4: {
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
}
}

View File

@ -1,70 +0,0 @@
- // MIR for `array_bound` before SimplifyLocals
+ // MIR for `array_bound` after SimplifyLocals
fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:36: +0:41
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:50: +0:55
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:70: +0:72
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let mut _11: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
_5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
}
bb1: {
- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
}
bb2: {
- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
}
bb3: {
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:11
goto -> bb4; // scope 0 at $DIR/lower_array_len.rs:+1:5: +5:6
}
bb4: {
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+5:5: +5:6
return; // scope 0 at $DIR/lower_array_len.rs:+6:2: +6:2
}
}

View File

@ -1,79 +0,0 @@
- // MIR for `array_bound_mut` before InstCombine
+ // MIR for `array_bound_mut` after InstCombine
fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
_7 = &(*_2); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
_14 = _7; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
_6 = move _7 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
- _5 = Len((*_14)); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ _5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
}
bb1: {
StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
_8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _9 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
_10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
}
bb2: {
_0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
}
bb3: {
StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
_11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
- _12 = Len((*_2)); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
_13 = Lt(_11, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
}
bb4: {
(*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
}
bb5: {
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
}
}

View File

@ -1,93 +0,0 @@
- // MIR for `array_bound_mut` before SimplifyLocals
+ // MIR for `array_bound_mut` after SimplifyLocals
fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
debug index => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:40: +0:45
debug slice => _2; // in scope 0 at $DIR/lower_array_len.rs:+0:54: +0:59
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len.rs:+0:78: +0:80
let mut _3: bool; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _6: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let mut _7: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- let _8: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- let mut _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let mut _10: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- let _11: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
- let mut _12: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- let mut _13: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- let mut _14: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
+ let _6: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ let mut _7: usize; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let mut _8: bool; // in scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ let _9: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ let mut _10: usize; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ let mut _11: bool; // in scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
_4 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:13
StorageLive(_5); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_7); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageLive(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_7); // scope 0 at $DIR/lower_array_len.rs:+1:20: +1:21
_5 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_14); // scope 0 at $DIR/lower_array_len.rs:+1:16: +1:27
- StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
StorageDead(_5); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:26: +1:27
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len.rs:+1:8: +1:27
}
bb1: {
- StorageLive(_8); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _8 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
- _9 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- _10 = Lt(_8, _9); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageLive(_6); // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _6 = _1; // scope 0 at $DIR/lower_array_len.rs:+2:15: +2:20
+ _7 = const N; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ _8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
}
bb2: {
- _0 = (*_2)[_8]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
- StorageDead(_8); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
+ _0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len.rs:+2:9: +2:21
+ StorageDead(_6); // scope 0 at $DIR/lower_array_len.rs:+3:5: +3:6
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
}
bb3: {
- StorageLive(_11); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
- _11 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
- _12 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- _13 = Lt(const 0_usize, _12); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ StorageLive(_9); // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ _9 = const 0_usize; // scope 0 at $DIR/lower_array_len.rs:+4:15: +4:16
+ _10 = const N; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ _11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
+ assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:17
}
bb4: {
- (*_2)[_11] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
- StorageDead(_11); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
+ (*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+4:9: +4:22
+ StorageDead(_9); // scope 0 at $DIR/lower_array_len.rs:+4:22: +4:23
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len.rs:+6:9: +6:11
goto -> bb5; // scope 0 at $DIR/lower_array_len.rs:+1:5: +7:6
}
bb5: {
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+7:5: +7:6
return; // scope 0 at $DIR/lower_array_len.rs:+8:2: +8:2
}
}

View File

@ -1,27 +0,0 @@
- // MIR for `array_len` before InstCombine
+ // MIR for `array_len` after InstCombine
fn array_len(_1: &[u8; N]) -> usize {
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
bb0: {
StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- _3 = &(*_1); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _3 = _1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
_4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
_2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
}
}

View File

@ -1,22 +0,0 @@
- // MIR for `array_len` before SimplifyLocals
+ // MIR for `array_len` after SimplifyLocals
fn array_len(_1: &[u8; N]) -> usize {
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:34: +0:37
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:52: +0:57
- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
bb0: {
- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
_0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
}
}

View File

@ -1,26 +0,0 @@
- // MIR for `array_len_by_value` before InstCombine
+ // MIR for `array_len_by_value` after InstCombine
fn array_len_by_value(_1: [u8; N]) -> usize {
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
bb0: {
StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
_3 = &_1; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
_4 = _3; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
_2 = move _3 as &[u8] (Pointer(Unsize)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
- _0 = Len((*_4)); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
+ _0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
}
}

View File

@ -1,22 +0,0 @@
- // MIR for `array_len_by_value` before SimplifyLocals
+ // MIR for `array_len_by_value` after SimplifyLocals
fn array_len_by_value(_1: [u8; N]) -> usize {
debug arr => _1; // in scope 0 at $DIR/lower_array_len.rs:+0:43: +0:46
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len.rs:+0:60: +0:65
- let mut _2: &[u8]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _3: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- let mut _4: &[u8; N]; // in scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
bb0: {
- StorageLive(_2); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_3); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageLive(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:+1:7: +1:8
_0 = const N; // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_4); // scope 0 at $DIR/lower_array_len.rs:+1:5: +1:14
- StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:+1:13: +1:14
return; // scope 0 at $DIR/lower_array_len.rs:+2:2: +2:2
}
}

View File

@ -1,8 +1,7 @@
// compile-flags: -Z mir-opt-level=4
// unit-test: NormalizeArrayLen
// compile-flags: -Zmir-enable-passes=+LowerSliceLenCalls
// EMIT_MIR lower_array_len.array_bound.NormalizeArrayLen.diff
// EMIT_MIR lower_array_len.array_bound.SimplifyLocals.diff
// EMIT_MIR lower_array_len.array_bound.InstCombine.diff
pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
if index < slice.len() {
slice[index]
@ -12,8 +11,6 @@ pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
}
// EMIT_MIR lower_array_len.array_bound_mut.NormalizeArrayLen.diff
// EMIT_MIR lower_array_len.array_bound_mut.SimplifyLocals.diff
// EMIT_MIR lower_array_len.array_bound_mut.InstCombine.diff
pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
if index < slice.len() {
slice[index]
@ -25,15 +22,11 @@ pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8
}
// EMIT_MIR lower_array_len.array_len.NormalizeArrayLen.diff
// EMIT_MIR lower_array_len.array_len.SimplifyLocals.diff
// EMIT_MIR lower_array_len.array_len.InstCombine.diff
pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
arr.len()
}
// EMIT_MIR lower_array_len.array_len_by_value.NormalizeArrayLen.diff
// EMIT_MIR lower_array_len.array_len_by_value.SimplifyLocals.diff
// EMIT_MIR lower_array_len.array_len_by_value.InstCombine.diff
pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
arr.len()
}

View File

@ -0,0 +1,49 @@
// MIR for `array_bound` after PreCodegen
fn array_bound(_1: usize, _2: &[u8; N]) -> u8 {
debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:36: +0:41
debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:50: +0:55
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:70: +0:72
let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
let _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
let mut _7: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
let mut _8: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
_4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
_5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
}
bb1: {
StorageLive(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
_6 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
_7 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
_8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
}
bb2: {
_0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
StorageDead(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+3:5: +3:6
goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
}
bb3: {
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:11
goto -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +5:6
}
bb4: {
StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+5:5: +5:6
return; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:2: +6:2
}
}

View File

@ -0,0 +1,62 @@
// MIR for `array_bound_mut` after PreCodegen
fn array_bound_mut(_1: usize, _2: &mut [u8; N]) -> u8 {
debug index => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:40: +0:45
debug slice => _2; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:54: +0:59
let mut _0: u8; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:78: +0:80
let mut _3: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
let mut _4: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
let mut _5: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
let _6: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
let mut _7: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
let mut _8: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
let _9: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
let mut _10: usize; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
let mut _11: bool; // in scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
bb0: {
StorageLive(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
StorageLive(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
_4 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:13
StorageLive(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
_5 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:16: +1:27
_3 = Lt(move _4, move _5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
StorageDead(_5); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
StorageDead(_4); // scope 0 at $DIR/lower_array_len_e2e.rs:+1:26: +1:27
switchInt(move _3) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:8: +1:27
}
bb1: {
StorageLive(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
_6 = _1; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:15: +2:20
_7 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
_8 = Lt(_6, _7); // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb2; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
}
bb2: {
_0 = (*_2)[_6]; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:9: +2:21
StorageDead(_6); // scope 0 at $DIR/lower_array_len_e2e.rs:+3:5: +3:6
goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
}
bb3: {
StorageLive(_9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
_9 = const 0_usize; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:15: +4:16
_10 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
_11 = Lt(const 0_usize, _10); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, const 0_usize) -> bb4; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:17
}
bb4: {
(*_2)[_9] = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+4:9: +4:22
StorageDead(_9); // scope 0 at $DIR/lower_array_len_e2e.rs:+4:22: +4:23
_0 = const 42_u8; // scope 0 at $DIR/lower_array_len_e2e.rs:+6:9: +6:11
goto -> bb5; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +7:6
}
bb5: {
StorageDead(_3); // scope 0 at $DIR/lower_array_len_e2e.rs:+7:5: +7:6
return; // scope 0 at $DIR/lower_array_len_e2e.rs:+8:2: +8:2
}
}

View File

@ -0,0 +1,11 @@
// MIR for `array_len` after PreCodegen
fn array_len(_1: &[u8; N]) -> usize {
debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:34: +0:37
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:52: +0:57
bb0: {
_0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14
return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,11 @@
// MIR for `array_len_by_value` after PreCodegen
fn array_len_by_value(_1: [u8; N]) -> usize {
debug arr => _1; // in scope 0 at $DIR/lower_array_len_e2e.rs:+0:43: +0:46
let mut _0: usize; // return place in scope 0 at $DIR/lower_array_len_e2e.rs:+0:60: +0:65
bb0: {
_0 = const N; // scope 0 at $DIR/lower_array_len_e2e.rs:+1:5: +1:14
return; // scope 0 at $DIR/lower_array_len_e2e.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,39 @@
// compile-flags: -Z mir-opt-level=4
// EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir
pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
if index < slice.len() {
slice[index]
} else {
42
}
}
// EMIT_MIR lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
pub fn array_bound_mut<const N: usize>(index: usize, slice: &mut [u8; N]) -> u8 {
if index < slice.len() {
slice[index]
} else {
slice[0] = 42;
42
}
}
// EMIT_MIR lower_array_len_e2e.array_len.PreCodegen.after.mir
pub fn array_len<const N: usize>(arr: &[u8; N]) -> usize {
arr.len()
}
// EMIT_MIR lower_array_len_e2e.array_len_by_value.PreCodegen.after.mir
pub fn array_len_by_value<const N: usize>(arr: [u8; N]) -> usize {
arr.len()
}
fn main() {
let _ = array_bound(3, &[0, 1, 2, 3]);
let mut tmp = [0, 1, 2, 3, 4];
let _ = array_bound_mut(3, &mut [0, 1, 2, 3]);
let _ = array_len(&[0]);
let _ = array_len_by_value([0, 2]);
}

View File

@ -7,7 +7,7 @@
bb0: {
- _0 = std::intrinsics::min_align_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:19:5: 19:40
- // + span: $DIR/lower_intrinsics.rs:21:5: 21:40
- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::min_align_of::<T>}, val: Value(<ZST>) }
+ _0 = AlignOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:42

View File

@ -31,7 +31,7 @@
_3 = &(*_4); // scope 0 at $DIR/lower_intrinsics.rs:+1:42: +1:44
- _2 = discriminant_value::<T>(move _3) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:74:5: 74:41
- // + span: $DIR/lower_intrinsics.rs:49:5: 49:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r T) -> <T as DiscriminantKind>::Discriminant {discriminant_value::<T>}, val: Value(<ZST>) }
+ _2 = discriminant((*_3)); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:45
@ -46,13 +46,13 @@
StorageLive(_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
_19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:75:42: 75:44
// + span: $DIR/lower_intrinsics.rs:50:42: 50:44
// + literal: Const { ty: &i32, val: Unevaluated(discriminant, [T], Some(promoted[2])) }
_7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
_6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:+2:42: +2:44
- _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:75:5: 75:41
- // + span: $DIR/lower_intrinsics.rs:50:5: 50:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r i32) -> <i32 as DiscriminantKind>::Discriminant {discriminant_value::<i32>}, val: Value(<ZST>) }
+ _5 = discriminant((*_6)); // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
+ goto -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:+2:5: +2:45
@ -67,13 +67,13 @@
StorageLive(_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
_18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:76:42: 76:45
// + span: $DIR/lower_intrinsics.rs:51:42: 51:45
// + literal: Const { ty: &(), val: Unevaluated(discriminant, [T], Some(promoted[1])) }
_11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
_10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:+3:42: +3:45
- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:76:5: 76:41
- // + span: $DIR/lower_intrinsics.rs:51:5: 51:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r ()) -> <() as DiscriminantKind>::Discriminant {discriminant_value::<()>}, val: Value(<ZST>) }
+ _9 = discriminant((*_10)); // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
+ goto -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:+3:5: +3:46
@ -88,13 +88,13 @@
StorageLive(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
_17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:77:42: 77:47
// + span: $DIR/lower_intrinsics.rs:52:42: 52:47
// + literal: Const { ty: &E, val: Unevaluated(discriminant, [T], Some(promoted[0])) }
_15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
_14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:42: +4:47
- _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:77:5: 77:41
- // + span: $DIR/lower_intrinsics.rs:52:5: 52:41
- // + literal: Const { ty: for<'r> extern "rust-intrinsic" fn(&'r E) -> <E as DiscriminantKind>::Discriminant {discriminant_value::<E>}, val: Value(<ZST>) }
+ _13 = discriminant((*_14)); // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
+ goto -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:+4:5: +4:48
@ -105,11 +105,15 @@
StorageDead(_15); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49
StorageDead(_13); // scope 0 at $DIR/lower_intrinsics.rs:+4:48: +4:49
_0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+0:30: +5:2
drop(_1) -> bb5; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2
drop(_1) -> [return: bb5, unwind: bb6]; // scope 0 at $DIR/lower_intrinsics.rs:+5:1: +5:2
}
bb5: {
return; // scope 0 at $DIR/lower_intrinsics.rs:+5:2: +5:2
}
bb6 (cleanup): {
resume; // scope 0 at $DIR/lower_intrinsics.rs:+0:1: +5:2
}
}

View File

@ -11,7 +11,7 @@
_2 = move _1; // scope 0 at $DIR/lower_intrinsics.rs:+1:30: +1:31
- _0 = std::intrinsics::forget::<T>(move _2) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:24:5: 24:29
- // + span: $DIR/lower_intrinsics.rs:26:5: 26:29
- // + literal: Const { ty: extern "rust-intrinsic" fn(T) {std::intrinsics::forget::<T>}, val: Value(<ZST>) }
+ _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:32

View File

@ -13,7 +13,7 @@
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+2:9: +2:18
_1 = std::intrinsics::size_of::<T>; // scope 0 at $DIR/lower_intrinsics.rs:+2:21: +2:51
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:62:21: 62:51
// + span: $DIR/lower_intrinsics.rs:37:21: 37:51
// + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14
_2 = _1; // scope 1 at $DIR/lower_intrinsics.rs:+3:5: +3:14

View File

@ -1,4 +1,6 @@
// compile-flags: -Cpanic=abort
// unit-test: LowerIntrinsics
// ignore-wasm32 compiled with panic=abort by default
#![feature(core_intrinsics)]
#![crate_type = "lib"]
@ -29,33 +31,6 @@ pub fn unreachable() -> ! {
unsafe { core::intrinsics::unreachable() };
}
// EMIT_MIR lower_intrinsics.f_unit.PreCodegen.before.mir
pub fn f_unit() {
f_dispatch(());
}
// EMIT_MIR lower_intrinsics.f_u64.PreCodegen.before.mir
pub fn f_u64() {
f_dispatch(0u64);
}
#[inline(always)]
pub fn f_dispatch<T>(t: T) {
if std::mem::size_of::<T>() == 0 {
f_zst(t);
} else {
f_non_zst(t);
}
}
#[inline(never)]
pub fn f_zst<T>(_t: T) {
}
#[inline(never)]
pub fn f_non_zst<T>(_t: T) {}
// EMIT_MIR lower_intrinsics.non_const.LowerIntrinsics.diff
pub fn non_const<T>() -> usize {
// Check that lowering works with non-const operand as a func.

View File

@ -7,7 +7,7 @@
bb0: {
- _0 = std::intrinsics::size_of::<T>() -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:14:5: 14:35
- // + span: $DIR/lower_intrinsics.rs:16:5: 16:35
- // + literal: Const { ty: extern "rust-intrinsic" fn() -> usize {std::intrinsics::size_of::<T>}, val: Value(<ZST>) }
+ _0 = SizeOf(T); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:37

View File

@ -14,7 +14,7 @@
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
- _3 = std::intrinsics::unreachable(); // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:29:14: 29:43
- // + span: $DIR/lower_intrinsics.rs:31:14: 31:43
- // + literal: Const { ty: unsafe extern "rust-intrinsic" fn() -> ! {std::intrinsics::unreachable}, val: Value(<ZST>) }
+ unreachable; // scope 1 at $DIR/lower_intrinsics.rs:+1:14: +1:45
}

View File

@ -32,7 +32,7 @@
_5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:+1:48: +1:49
- _3 = wrapping_add::<i32>(move _4, move _5) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:7:14: 7:44
- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::<i32>}, val: Value(<ZST>) }
+ _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
+ goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:50
@ -48,7 +48,7 @@
_8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:+2:48: +2:49
- _6 = wrapping_sub::<i32>(move _7, move _8) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:8:14: 8:44
- // + span: $DIR/lower_intrinsics.rs:10:14: 10:44
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::<i32>}, val: Value(<ZST>) }
+ _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
+ goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:50
@ -64,7 +64,7 @@
_11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:+3:48: +3:49
- _9 = wrapping_mul::<i32>(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
- // mir::Constant
- // + span: $DIR/lower_intrinsics.rs:9:14: 9:44
- // + span: $DIR/lower_intrinsics.rs:11:14: 11:44
- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::<i32>}, val: Value(<ZST>) }
+ _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50
+ goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:50

View File

@ -1,32 +1,32 @@
// MIR for `f_u64` before PreCodegen
// MIR for `f_u64` after PreCodegen
fn f_u64() -> () {
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:16: +0:16
let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics.rs:40:5: 40:21
debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:44:22: 44:23
let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:48:9: 48:21
let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics.rs:48:19: 48:20
scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16
let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21
debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
let mut _3: u64; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
_1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:48:9: 48:21
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:48:19: 48:20
_3 = move _1; // scope 1 at $DIR/lower_intrinsics.rs:48:19: 48:20
_2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:48:9: 48:21
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
_1 = const 0_u64; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
_3 = move _1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:19: 23:20
_2 = f_non_zst::<u64>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:48:9: 48:18
// + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18
// + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:48:20: 48:21
StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:48:21: 48:22
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:5: +1:21
return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:20: 23:21
StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:21: 23:22
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21
return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
}
}

View File

@ -1,30 +1,30 @@
// MIR for `f_unit` before PreCodegen
// MIR for `f_unit` after PreCodegen
fn f_unit() -> () {
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:17: +0:17
let mut _1: (); // in scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18
scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics.rs:34:5: 34:19
debug t => _1; // in scope 1 at $DIR/lower_intrinsics.rs:44:22: 44:23
let _2: (); // in scope 1 at $DIR/lower_intrinsics.rs:46:9: 46:17
let mut _3: (); // in scope 1 at $DIR/lower_intrinsics.rs:46:15: 46:16
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics.rs:45:8: 45:32
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:17: +0:17
let mut _1: (); // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19
debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
let mut _3: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:15: 21:16
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:16: +1:18
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics.rs:46:9: 46:17
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics.rs:46:15: 46:16
_2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics.rs:46:9: 46:17
StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:16: +1:18
StorageLive(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
StorageLive(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:15: 21:16
_2 = f_zst::<()>(move _3) -> bb1; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:46:9: 46:14
// + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14
// + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics.rs:46:16: 46:17
StorageDead(_2); // scope 1 at $DIR/lower_intrinsics.rs:46:17: 46:18
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics.rs:+1:18: +1:19
return; // scope 0 at $DIR/lower_intrinsics.rs:+2:2: +2:2
StorageDead(_3); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:16: 21:17
StorageDead(_2); // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:17: 21:18
StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:18: +1:19
return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,32 @@
// Checks that we do not have any branches in the MIR for the two tested functions.
// compile-flags: -Cpanic=abort
#![feature(core_intrinsics)]
#![crate_type = "lib"]
// EMIT_MIR lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
pub fn f_unit() {
f_dispatch(());
}
// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
pub fn f_u64() {
f_dispatch(0u64);
}
#[inline(always)]
pub fn f_dispatch<T>(t: T) {
if std::mem::size_of::<T>() == 0 {
f_zst(t);
} else {
f_non_zst(t);
}
}
#[inline(never)]
pub fn f_zst<T>(_t: T) {
}
#[inline(never)]
pub fn f_non_zst<T>(_t: T) {}

View File

@ -41,7 +41,7 @@
- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- }
-
@ -54,7 +54,7 @@
+ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21
- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
- }
-

View File

@ -41,7 +41,7 @@
- _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+16:13: +16:22
- _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+17:13: +17:22
- _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+18:13: +18:21
- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+19:13: +19:15
- }
-
@ -54,7 +54,7 @@
+ _3 = Eq(_11, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:+9:13: +9:21
_4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:+10:13: +10:22
_5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:+11:13: +11:21
- nop; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
Deinit(_6); // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
- goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:+12:13: +12:15
- }
-

View File

@ -4,26 +4,51 @@
fn foo(_1: Option<()>) -> () {
debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
+ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
+ let mut _4: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb1: {
StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _4 = move _3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb1: {
- _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb2: {
- _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb3: {
+ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb4: {
Deinit(_0); // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
}
- bb5: {
+ bb2: {
_0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
}
- bb6: {
+ bb3: {
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
}
}

View File

@ -4,26 +4,51 @@
fn foo(_1: Option<()>) -> () {
debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
let mut _2: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
+ let mut _3: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:22: +1:26
+ let mut _4: isize; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
- switchInt(move _2) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb1: {
StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:17: +1:20
- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _4 = move _3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _2 = Eq(_4, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
}
bb1: {
- _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb2: {
- _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- goto -> bb3; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb3: {
+ StorageLive(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ _3 = move _2; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+ StorageDead(_3); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- switchInt(move _2) -> [false: bb5, otherwise: bb4]; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
- }
-
- bb4: {
Deinit(_0); // scope 0 at $DIR/matches_reduce_branches.rs:+2:9: +2:11
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
}
- bb5: {
+ bb2: {
_0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:+3:6: +3:6
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+1:5: +3:6
}
- bb6: {
+ bb3: {
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+3:5: +3:6
return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
}
}

View File

@ -1,10 +0,0 @@
// MIR for `foo` before PreCodegen
fn foo(_1: Option<()>) -> () {
debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
bb0: {
return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
}
}

View File

@ -1,10 +0,0 @@
// MIR for `foo` before PreCodegen
fn foo(_1: Option<()>) -> () {
debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:+0:8: +0:11
let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:25
bb0: {
return; // scope 0 at $DIR/matches_reduce_branches.rs:+4:2: +4:2
}
}

View File

@ -4,36 +4,107 @@
fn match_nested_if() -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
let mut _2: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
scope 1 {
debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
_2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
Deinit(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
_6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- }
-
- bb1: {
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
- }
-
- bb2: {
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
- }
-
- bb3: {
+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _7 = move _6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
+ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
- }
-
- bb4: {
- _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
- }
-
- bb5: {
- _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
- }
-
- bb6: {
+ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ _8 = move _5; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
+ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
- }
-
- bb7: {
- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
- }
-
- bb8: {
- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
- }
-
- bb9: {
- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
- }
-
- bb10: {
+ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ _9 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
+ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- }
-
- bb11: {
- StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
- StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- }
-
- bb12: {
+ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
_0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2

View File

@ -4,36 +4,107 @@
fn match_nested_if() -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:+0:25: +0:29
let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
let mut _2: (); // in scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
scope 1 {
debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+1:9: +1:12
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
_2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
Deinit(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+1:21: +1:23
StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
_6 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
- }
-
- bb1: {
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- _5 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:31: +2:35
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
- }
-
- bb2: {
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- _5 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
- }
-
- bb3: {
+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _7 = move _6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
+ _5 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:45: +2:50
+ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:+2:24: +2:28
StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:+2:51: +2:52
- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
- }
-
- bb4: {
- _4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+2:55: +2:59
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
- }
-
- bb5: {
- _4 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
- }
-
- bb6: {
+ StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ _8 = move _5; // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
+ _4 = Ne(_8, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+2:69: +2:74
+ StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:+2:21: +2:52
StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:+2:75: +2:76
- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
- }
-
- bb7: {
- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+3:13: +3:17
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
- }
-
- bb8: {
- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
- }
-
- bb9: {
- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
- }
-
- bb10: {
+ StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ _9 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ _3 = Ne(_9, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+5:13: +5:18
+ StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:+2:18: +2:76
+ StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
+ _10 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+8:13: +8:17
- }
-
- bb11: {
- StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
- StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:+6:9: +6:10
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
- }
-
- bb12: {
+ _1 = Ne(_10, const false); // scope 0 at $DIR/matches_reduce_branches.rs:+10:14: +10:19
+ StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:+2:15: +6:10
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:+11:6: +11:7
_0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:+12:5: +12:8
StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:+13:1: +13:2
return; // scope 0 at $DIR/matches_reduce_branches.rs:+13:2: +13:2

View File

@ -1,6 +1,7 @@
// unit-test: MatchBranchSimplification
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff
// EMIT_MIR matches_reduce_branches.foo.PreCodegen.before.mir
// EMIT_MIR matches_reduce_branches.bar.MatchBranchSimplification.diff
// EMIT_MIR matches_reduce_branches.match_nested_if.MatchBranchSimplification.diff

View File

@ -1,3 +1,5 @@
// unit-test: MatchBranchSimplification
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR matches_u8.exhaustive_match.MatchBranchSimplification.diff
// EMIT_MIR matches_u8.exhaustive_match_i8.MatchBranchSimplification.diff

View File

@ -15,7 +15,7 @@
scope 1 {
debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
scope 2 {
scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:29:8: 29:10
scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:25:8: 25:10
debug residual => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
let _16: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
let mut _17: i32; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
@ -34,7 +34,7 @@
scope 4 {
}
}
scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:29:8: 29:10
scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:25:8: 25:10
debug self => _4; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
let mut _10: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
let _11: i32; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL

View File

@ -4,8 +4,6 @@
use std::ops::ControlFlow;
// EMIT_MIR separate_const_switch.too_complex.SeparateConstSwitch.diff
// EMIT_MIR separate_const_switch.too_complex.ConstProp.diff
// EMIT_MIR separate_const_switch.too_complex.PreCodegen.after.mir
fn too_complex(x: Result<i32, usize>) -> Option<i32> {
// The pass should break the outer match into
// two blocks that only have one parent each.
@ -23,8 +21,6 @@ fn too_complex(x: Result<i32, usize>) -> Option<i32> {
}
// EMIT_MIR separate_const_switch.identity.SeparateConstSwitch.diff
// EMIT_MIR separate_const_switch.identity.ConstProp.diff
// EMIT_MIR separate_const_switch.identity.PreCodegen.after.mir
fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
Ok(x?)
}

View File

@ -4,6 +4,9 @@
// compile-flags: -Zmir-opt-level=3
// EMIT_MIR_FOR_EACH_BIT_WIDTH
// This pass is broken since deaggregation changed
// ignore-test
enum Src {
Foo(u8),
Bar,

View File

@ -6,6 +6,9 @@
// EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff
// EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff
// This pass is broken since deaggregation changed
// ignore-test
fn id(o: Option<u8>) -> Option<u8> {
match o {
Some(v) => Some(v),

View File

@ -1,4 +1,4 @@
// compile-flags: -Zunsound-mir-opts
// unit-test: SimplifyLocals
fn map(x: Option<Box<()>>) -> Option<Box<()>> {
match x {

View File

@ -1,46 +0,0 @@
- // MIR for `id` before SimplifyArmIdentity
+ // MIR for `id` after SimplifyArmIdentity
fn id(_1: Option<u8>) -> Option<u8> {
debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8
let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35
let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16
let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26
scope 1 {
debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
}
bb1: {
Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
}
bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
}
bb3: {
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
_3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
_4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
}
bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
}
}

View File

@ -1,46 +0,0 @@
- // MIR for `id` before SimplifyBranchSame
+ // MIR for `id` after SimplifyBranchSame
fn id(_1: Option<u8>) -> Option<u8> {
debug o => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:7: +0:8
let mut _0: std::option::Option<u8>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:25: +0:35
let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:16
let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:25: +2:26
scope 1 {
debug v => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:14: +2:15
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
switchInt(move _2) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
}
bb1: {
Deinit(_0); // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
discriminant(_0) = 0; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:17: +3:21
}
bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
}
bb3: {
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
_3 = ((_1 as Some).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:14: +2:15
StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
_4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:25: +2:26
Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
((_0 as Some).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
discriminant(_0) = 1; // scope 1 at $DIR/simplify-arm.rs:+2:20: +2:27
StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:26: +2:27
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:26: +2:27
}
bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
}
}

View File

@ -1,58 +0,0 @@
- // MIR for `id_result` before SimplifyArmIdentity
+ // MIR for `id_result` after SimplifyArmIdentity
fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> {
debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15
let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52
let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14
let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22
let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24
scope 1 {
debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13
}
scope 2 {
debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
}
bb1: {
StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
_5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
_6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25
StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
}
bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
}
bb3: {
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
_3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
_4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
}
bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
}
}

View File

@ -1,58 +0,0 @@
- // MIR for `id_result` before SimplifyBranchSame
+ // MIR for `id_result` after SimplifyBranchSame
fn id_result(_1: Result<u8, i32>) -> Result<u8, i32> {
debug r => _1; // in scope 0 at $DIR/simplify-arm.rs:+0:14: +0:15
let mut _0: std::result::Result<u8, i32>; // return place in scope 0 at $DIR/simplify-arm.rs:+0:37: +0:52
let mut _2: isize; // in scope 0 at $DIR/simplify-arm.rs:+2:9: +2:14
let _3: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
let mut _4: u8; // in scope 0 at $DIR/simplify-arm.rs:+2:21: +2:22
let _5: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
let mut _6: i32; // in scope 0 at $DIR/simplify-arm.rs:+3:23: +3:24
scope 1 {
debug x => _3; // in scope 1 at $DIR/simplify-arm.rs:+2:12: +2:13
}
scope 2 {
debug y => _5; // in scope 2 at $DIR/simplify-arm.rs:+3:13: +3:14
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-arm.rs:+1:5: +1:12
}
bb1: {
StorageLive(_5); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
_5 = ((_1 as Err).0: i32); // scope 0 at $DIR/simplify-arm.rs:+3:13: +3:14
StorageLive(_6); // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
_6 = _5; // scope 2 at $DIR/simplify-arm.rs:+3:23: +3:24
Deinit(_0); // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
((_0 as Err).0: i32) = move _6; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
discriminant(_0) = 1; // scope 2 at $DIR/simplify-arm.rs:+3:19: +3:25
StorageDead(_6); // scope 2 at $DIR/simplify-arm.rs:+3:24: +3:25
StorageDead(_5); // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+3:24: +3:25
}
bb2: {
unreachable; // scope 0 at $DIR/simplify-arm.rs:+1:11: +1:12
}
bb3: {
StorageLive(_3); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
_3 = ((_1 as Ok).0: u8); // scope 0 at $DIR/simplify-arm.rs:+2:12: +2:13
StorageLive(_4); // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
_4 = _3; // scope 1 at $DIR/simplify-arm.rs:+2:21: +2:22
Deinit(_0); // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
((_0 as Ok).0: u8) = move _4; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
discriminant(_0) = 0; // scope 1 at $DIR/simplify-arm.rs:+2:18: +2:23
StorageDead(_4); // scope 1 at $DIR/simplify-arm.rs:+2:22: +2:23
StorageDead(_3); // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
goto -> bb4; // scope 0 at $DIR/simplify-arm.rs:+2:22: +2:23
}
bb4: {
return; // scope 0 at $DIR/simplify-arm.rs:+5:2: +5:2
}
}

View File

@ -1,61 +0,0 @@
- // MIR for `main` before SimplifyArmIdentity
+ // MIR for `main` after SimplifyArmIdentity
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11
let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20
let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
scope 1 {
debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
scope 2 {
}
scope 3 {
debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
_3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25
}
bb1: {
Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
}
bb2: {
unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
}
bb3: {
StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
_4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
_5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
}
bb4: {
StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7
nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2
StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2
return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2
}
}

View File

@ -1,61 +0,0 @@
- // MIR for `main` before SimplifyArmIdentity
+ // MIR for `main` after SimplifyArmIdentity
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +0:11
let _1: Src; // in scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
let mut _2: Dst; // in scope 0 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
let mut _3: isize; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:9: +3:20
let mut _5: u8; // in scope 0 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
scope 1 {
debug e => _1; // in scope 1 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
let _4: u8; // in scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
scope 2 {
}
scope 3 {
debug x => _4; // in scope 3 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:9: +1:10
Deinit(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
((_1 as Foo).0: u8) = const 0_u8; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
discriminant(_1) = 0; // scope 0 at $DIR/simplify-arm-identity.rs:+1:18: +1:29
StorageLive(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +5:6
_3 = const 0_isize; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
goto -> bb3; // scope 1 at $DIR/simplify-arm-identity.rs:+2:18: +2:25
}
bb1: {
Deinit(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
((_2 as Foo).0: u8) = const 0_u8; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+4:21: +4:32
}
bb2: {
unreachable; // scope 1 at $DIR/simplify-arm-identity.rs:+2:24: +2:25
}
bb3: {
StorageLive(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
_4 = ((_1 as Foo).0: u8); // scope 1 at $DIR/simplify-arm-identity.rs:+3:18: +3:19
StorageLive(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
_5 = _4; // scope 3 at $DIR/simplify-arm-identity.rs:+3:33: +3:34
Deinit(_2); // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
((_2 as Foo).0: u8) = move _5; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
discriminant(_2) = 0; // scope 3 at $DIR/simplify-arm-identity.rs:+3:24: +3:35
StorageDead(_5); // scope 3 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
StorageDead(_4); // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:+3:34: +3:35
}
bb4: {
StorageDead(_2); // scope 1 at $DIR/simplify-arm-identity.rs:+5:6: +5:7
nop; // scope 0 at $DIR/simplify-arm-identity.rs:+0:11: +6:2
StorageDead(_1); // scope 0 at $DIR/simplify-arm-identity.rs:+6:1: +6:2
return; // scope 0 at $DIR/simplify-arm-identity.rs:+6:2: +6:2
}
}

View File

@ -5,24 +5,32 @@
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
scope 1 {
debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
}
bb0: {
- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
_2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
}
bb1: {
((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
_3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
_4 = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
}
@ -37,6 +45,7 @@
}
bb4: {
- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
}
}

View File

@ -5,24 +5,32 @@
debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:8: +0:9
let mut _0: std::option::Option<std::boxed::Box<()>>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+0:31: +0:46
let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+2:9: +2:13
- let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
- let mut _5: bool; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
- let mut _7: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
scope 1 {
debug x => ((_0 as Some).0: std::boxed::Box<()>); // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
}
bb0: {
- _5 = const false; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
- _5 = const true; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
_2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:11: +1:12
switchInt(move _2) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+1:5: +1:12
}
bb1: {
((_0 as Some).0: std::boxed::Box<()>) = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
StorageLive(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
_3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:14: +3:15
StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
_4 = move _3; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:25: +3:26
Deinit(_0); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
discriminant(_0) = 1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:20: +3:27
StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
StorageDead(_3); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
goto -> bb4; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+3:26: +3:27
}
@ -37,6 +45,7 @@
}
bb4: {
- _6 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:1: +5:2
return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:+5:2: +5:2
}
}

View File

@ -1,30 +0,0 @@
// compile-flags: -Zunsound-mir-opts
// EMIT_MIR simplify_try.try_identity.SimplifyArmIdentity.diff
// EMIT_MIR simplify_try.try_identity.SimplifyBranchSame.after.mir
// EMIT_MIR simplify_try.try_identity.SimplifyLocals.after.mir
// EMIT_MIR simplify_try.try_identity.DestinationPropagation.diff
fn into_result<T, E>(r: Result<T, E>) -> Result<T, E> {
r
}
fn from_error<T, E>(e: E) -> Result<T, E> {
Err(e)
}
// This was written to the `?` from `try_trait`, but `try_trait_v2` uses a different structure,
// so the relevant desugar is copied inline in order to keep the test testing the same thing.
// FIXME(#85133): while this might be useful for `r#try!`, it would be nice to have a MIR
// optimization that picks up the `?` desugaring, as `SimplifyArmIdentity` does not.
fn try_identity(x: Result<u32, i32>) -> Result<u32, i32> {
let y = match into_result(x) {
Err(e) => return from_error(From::from(e)),
Ok(v) => v,
};
Ok(y)
}
fn main() {
let _ = try_identity(Ok(0));
}

View File

@ -0,0 +1,96 @@
// MIR for `new` after PreCodegen
fn new(_1: Result<T, E>) -> Result<T, E> {
debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
let mut _2: T; // in scope 0 at $DIR/try_identity_e2e.rs:+2:9: +10:10
let mut _3: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
let mut _4: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
let _5: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
let mut _6: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:48: +4:49
let _7: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
let mut _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:46: +5:47
let mut _9: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
let _10: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
let _11: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
let mut _12: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:49: +9:50
scope 1 {
debug v => _5; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
}
scope 2 {
debug e => _7; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22
}
scope 3 {
debug v => _10; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36
}
scope 4 {
debug e => _11; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +10:10
StorageLive(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
_4 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
switchInt(move _4) -> [0_isize: bb2, 1_isize: bb1, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20
}
bb1: {
StorageLive(_7); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
_7 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
StorageLive(_8); // scope 2 at $DIR/try_identity_e2e.rs:+5:46: +5:47
_8 = move _7; // scope 2 at $DIR/try_identity_e2e.rs:+5:46: +5:47
Deinit(_3); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
((_3 as Break).0: E) = move _8; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
discriminant(_3) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
StorageDead(_8); // scope 2 at $DIR/try_identity_e2e.rs:+5:47: +5:48
StorageDead(_7); // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48
_9 = discriminant(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
switchInt(move _9) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
}
bb2: {
StorageLive(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
_5 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
StorageLive(_6); // scope 1 at $DIR/try_identity_e2e.rs:+4:48: +4:49
_6 = move _5; // scope 1 at $DIR/try_identity_e2e.rs:+4:48: +4:49
Deinit(_3); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
((_3 as Continue).0: T) = move _6; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
discriminant(_3) = 0; // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
StorageDead(_6); // scope 1 at $DIR/try_identity_e2e.rs:+4:49: +4:50
StorageDead(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50
_9 = discriminant(_3); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
switchInt(move _9) -> [0_isize: bb5, 1_isize: bb3, otherwise: bb4]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
}
bb3: {
StorageLive(_11); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
_11 = move ((_3 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
StorageLive(_12); // scope 4 at $DIR/try_identity_e2e.rs:+9:49: +9:50
_12 = move _11; // scope 4 at $DIR/try_identity_e2e.rs:+9:49: +9:50
Deinit(_0); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
((_0 as Err).0: E) = move _12; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
discriminant(_0) = 1; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
StorageDead(_12); // scope 4 at $DIR/try_identity_e2e.rs:+9:50: +9:51
StorageDead(_11); // scope 0 at $DIR/try_identity_e2e.rs:+9:50: +9:51
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+11:5: +11:6
StorageDead(_3); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
}
bb4: {
unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
}
bb5: {
StorageLive(_10); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
_10 = move ((_3 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
_2 = move _10; // scope 3 at $DIR/try_identity_e2e.rs:+8:41: +8:42
StorageDead(_10); // scope 0 at $DIR/try_identity_e2e.rs:+8:41: +8:42
Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
((_0 as Ok).0: T) = move _2; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+11:5: +11:6
StorageDead(_3); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
}
}

View File

@ -0,0 +1,53 @@
// MIR for `old` after PreCodegen
fn old(_1: Result<T, E>) -> Result<T, E> {
debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
let mut _2: T; // in scope 0 at $DIR/try_identity_e2e.rs:+2:9: +5:10
let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
let _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
let _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
let mut _6: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:34: +4:35
scope 1 {
debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
}
scope 2 {
debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +5:10
_3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
switchInt(move _3) -> [0_isize: bb3, 1_isize: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16
}
bb1: {
StorageLive(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
_5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
StorageLive(_6); // scope 2 at $DIR/try_identity_e2e.rs:+4:34: +4:35
_6 = move _5; // scope 2 at $DIR/try_identity_e2e.rs:+4:34: +4:35
Deinit(_0); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
((_0 as Err).0: E) = move _6; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
discriminant(_0) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
StorageDead(_6); // scope 2 at $DIR/try_identity_e2e.rs:+4:35: +4:36
StorageDead(_5); // scope 0 at $DIR/try_identity_e2e.rs:+4:35: +4:36
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+6:5: +6:6
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
}
bb2: {
unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
}
bb3: {
StorageLive(_4); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
_4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
_2 = move _4; // scope 1 at $DIR/try_identity_e2e.rs:+3:22: +3:23
StorageDead(_4); // scope 0 at $DIR/try_identity_e2e.rs:+3:22: +3:23
Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
((_0 as Ok).0: T) = move _2; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+6:5: +6:6
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
}
}

View File

@ -0,0 +1,34 @@
// Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings
// of that syntax.
use std::ops::ControlFlow;
// EMIT_MIR try_identity_e2e.new.PreCodegen.after.mir
fn new<T, E>(x: Result<T, E>) -> Result<T, E> {
Ok(
match {
match x {
Ok(v) => ControlFlow::Continue(v),
Err(e) => ControlFlow::Break(e),
}
} {
ControlFlow::Continue(v) => v,
ControlFlow::Break(e) => return Err(e),
}
)
}
// EMIT_MIR try_identity_e2e.old.PreCodegen.after.mir
fn old<T, E>(x: Result<T, E>) -> Result<T, E> {
Ok(
match x {
Ok(v) => v,
Err(e) => return Err(e),
}
)
}
fn main() {
let _ = new::<(), ()>(Ok(()));
let _ = old::<(), ()>(Ok(()));
}

View File

@ -167,8 +167,8 @@ enum P {
#[derive(SessionSubdiagnostic)]
enum Q {
#[bar]
//~^ ERROR `#[bar]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
//~^ ERROR `#[bar]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@ -179,8 +179,8 @@ enum Q {
#[derive(SessionSubdiagnostic)]
enum R {
#[bar = "..."]
//~^ ERROR `#[bar = ...]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
//~^ ERROR `#[bar = ...]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@ -191,8 +191,8 @@ enum R {
#[derive(SessionSubdiagnostic)]
enum S {
#[bar = 4]
//~^ ERROR `#[bar = ...]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
//~^ ERROR `#[bar = ...]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@ -203,8 +203,8 @@ enum S {
#[derive(SessionSubdiagnostic)]
enum T {
#[bar("...")]
//~^ ERROR `#[bar("...")]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
//~^ ERROR `#[bar(...)]` is not a valid attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
@ -215,7 +215,7 @@ enum T {
#[derive(SessionSubdiagnostic)]
enum U {
#[label(code = "...")]
//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
A {
#[primary_span]
span: Span,
@ -232,7 +232,7 @@ enum V {
var: String,
},
B {
//~^ ERROR subdiagnostic kind not specified
//~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
var: String,
@ -307,6 +307,14 @@ union AC {
b: u64
}
#[derive(SessionSubdiagnostic)]
#[label(parser::add_paren)]
#[label(parser::add_paren)]
struct AD {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[label(parser::add_paren, parser::add_paren)]
//~^ ERROR `#[label(parser::add_paren)]` is not a valid attribute
@ -319,16 +327,16 @@ struct AE {
#[label(parser::add_paren)]
struct AF {
#[primary_span]
//~^ NOTE previously specified here
//~^ NOTE previously specified here
span_a: Span,
#[primary_span]
//~^ ERROR specified multiple times
//~^ ERROR specified multiple times
span_b: Span,
}
#[derive(SessionSubdiagnostic)]
struct AG {
//~^ ERROR subdiagnostic kind not specified
//~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
}
@ -380,27 +388,25 @@ struct AK {
#[primary_span]
span: Span,
#[applicability]
//~^ NOTE previously specified here
//~^ NOTE previously specified here
applicability_a: Applicability,
#[applicability]
//~^ ERROR specified multiple times
//~^ ERROR specified multiple times
applicability_b: Applicability,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `applicability`
struct AL {
#[primary_span]
span: Span,
#[applicability]
//~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability`
//~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability`
applicability: Span,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `applicability`
struct AM {
#[primary_span]
span: Span,
@ -436,8 +442,7 @@ struct AQ;
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `applicability`
//~^^ ERROR suggestion without `#[primary_span]` field
//~^ ERROR suggestion without `#[primary_span]` field
struct AR {
var: String,
}
@ -507,3 +512,120 @@ struct AZ {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(parser::add_paren, code = "...")]
//~^ ERROR suggestion without `#[primary_span]` field
struct BA {
#[suggestion_part]
//~^ ERROR `#[suggestion_part]` is not a valid attribute
span: Span,
#[suggestion_part(code = "...")]
//~^ ERROR `#[suggestion_part(...)]` is not a valid attribute
span2: Span,
#[applicability]
applicability: Applicability,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
//~| ERROR `code` is not a valid nested attribute of a `multipart_suggestion` attribute
struct BBa {
var: String,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
struct BBb {
#[suggestion_part]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
span1: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
struct BBc {
#[suggestion_part()]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
span1: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren)]
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
struct BC {
#[primary_span]
//~^ ERROR `#[primary_span]` is not a valid attribute
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren)]
struct BD {
#[suggestion_part]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
span1: Span,
#[suggestion_part()]
//~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."`
span2: Span,
#[suggestion_part(foo = "bar")]
//~^ ERROR `#[suggestion_part(foo = ...)]` is not a valid attribute
span4: Span,
#[suggestion_part(code = "...")]
//~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
s1: String,
#[suggestion_part()]
//~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
s2: String,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
struct BE {
#[suggestion_part(code = "...", code = ",,,")]
//~^ ERROR specified multiple times
//~| NOTE previously specified here
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
struct BF {
#[suggestion_part(code = "(")]
first: Span,
#[suggestion_part(code = ")")]
second: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren)]
struct BG {
#[applicability]
appl: Applicability,
#[suggestion_part(code = "(")]
first: Span,
#[suggestion_part(code = ")")]
second: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
//~^ NOTE previously specified here
struct BH {
#[applicability]
//~^ ERROR specified multiple times
appl: Applicability,
#[suggestion_part(code = "(")]
first: Span,
#[suggestion_part(code = ")")]
second: Span,
}
#[derive(SessionSubdiagnostic)]
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
struct BI {
#[suggestion_part(code = "")]
spans: Vec<Span>,
}

View File

@ -65,16 +65,16 @@ LL | #[label()]
| ^^^^^^^^^^
error: `code` is not a valid nested attribute of a `label` attribute
--> $DIR/subdiagnostic-derive.rs:137:1
--> $DIR/subdiagnostic-derive.rs:137:28
|
LL | #[label(parser::add_paren, code = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
error: `applicability` is not a valid nested attribute of a `label` attribute
--> $DIR/subdiagnostic-derive.rs:146:1
--> $DIR/subdiagnostic-derive.rs:146:28
|
LL | #[label(parser::add_paren, applicability = "machine-applicable")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsupported type attribute for subdiagnostic enum
--> $DIR/subdiagnostic-derive.rs:155:1
@ -100,13 +100,11 @@ error: `#[bar = ...]` is not a valid attribute
LL | #[bar = 4]
| ^^^^^^^^^^
error: `#[bar("...")]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:205:11
error: `#[bar(...)]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:205:5
|
LL | #[bar("...")]
| ^^^^^
|
= help: first argument of the attribute should be the diagnostic slug
| ^^^^^^^^^^^^^
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
--> $DIR/subdiagnostic-derive.rs:217:5
@ -163,6 +161,8 @@ error: `#[bar(...)]` is not a valid attribute
|
LL | #[bar("...")]
| ^^^^^^^^^^^^^
|
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
error: unexpected unsupported untagged union
--> $DIR/subdiagnostic-derive.rs:304:1
@ -175,7 +175,7 @@ LL | | }
| |_^
error: `#[label(parser::add_paren)]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:311:28
--> $DIR/subdiagnostic-derive.rs:319:28
|
LL | #[label(parser::add_paren, parser::add_paren)]
| ^^^^^^^^^^^^^^^^^
@ -183,134 +183,226 @@ LL | #[label(parser::add_paren, parser::add_paren)]
= help: a diagnostic slug must be the first argument to the attribute
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:324:5
--> $DIR/subdiagnostic-derive.rs:332:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:321:5
--> $DIR/subdiagnostic-derive.rs:329:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: subdiagnostic kind not specified
--> $DIR/subdiagnostic-derive.rs:330:8
--> $DIR/subdiagnostic-derive.rs:338:8
|
LL | struct AG {
| ^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:367:47
--> $DIR/subdiagnostic-derive.rs:375:47
|
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
| ^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:367:33
--> $DIR/subdiagnostic-derive.rs:375:33
|
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
| ^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:385:5
--> $DIR/subdiagnostic-derive.rs:393:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:382:5
--> $DIR/subdiagnostic-derive.rs:390:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
--> $DIR/subdiagnostic-derive.rs:396:5
--> $DIR/subdiagnostic-derive.rs:403:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: suggestion without `applicability`
--> $DIR/subdiagnostic-derive.rs:391:1
|
LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | | struct AL {
LL | | #[primary_span]
... |
LL | | applicability: Span,
LL | | }
| |_^
error: suggestion without `applicability`
--> $DIR/subdiagnostic-derive.rs:402:1
|
LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | | struct AM {
LL | | #[primary_span]
LL | | span: Span,
LL | | }
| |_^
error: suggestion without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:410:1
--> $DIR/subdiagnostic-derive.rs:416:1
|
LL | / #[suggestion(parser::add_paren)]
LL | |
LL | | struct AN {
LL | | #[primary_span]
... |
LL | | applicability: Applicability,
LL | | }
| |_^
LL | #[suggestion(parser::add_paren)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid applicability
--> $DIR/subdiagnostic-derive.rs:420:46
--> $DIR/subdiagnostic-derive.rs:426:46
|
LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^
error: suggestion without `applicability`
--> $DIR/subdiagnostic-derive.rs:438:1
|
LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | |
LL | | struct AR {
LL | | var: String,
LL | | }
| |_^
error: suggestion without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:438:1
--> $DIR/subdiagnostic-derive.rs:444:1
|
LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | |
LL | | struct AR {
LL | | var: String,
LL | | }
| |_^
error: unsupported type attribute for subdiagnostic enum
--> $DIR/subdiagnostic-derive.rs:453:1
--> $DIR/subdiagnostic-derive.rs:458:1
|
LL | #[label]
| ^^^^^^^^
error: `var` doesn't refer to a field on this type
--> $DIR/subdiagnostic-derive.rs:473:39
--> $DIR/subdiagnostic-derive.rs:478:39
|
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
| ^^^^^^^
error: `var` doesn't refer to a field on this type
--> $DIR/subdiagnostic-derive.rs:492:43
--> $DIR/subdiagnostic-derive.rs:497:43
|
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
| ^^^^^^^
error: `#[suggestion_part]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:520:5
|
LL | #[suggestion_part]
| ^^^^^^^^^^^^^^^^^^
|
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
error: `#[suggestion_part(...)]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:523:5
|
LL | #[suggestion_part(code = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions
error: suggestion without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:517:1
|
LL | / #[suggestion(parser::add_paren, code = "...")]
LL | |
LL | | struct BA {
LL | | #[suggestion_part]
... |
LL | | var: String,
LL | | }
| |_^
error: `code` is not a valid nested attribute of a `multipart_suggestion` attribute
--> $DIR/subdiagnostic-derive.rs:532:43
|
LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
| ^^^^^^^^^^^^
error: multipart suggestion without any `#[suggestion_part(...)]` fields
--> $DIR/subdiagnostic-derive.rs:532:1
|
LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
LL | |
LL | |
LL | | struct BBa {
LL | | var: String,
LL | | }
| |_^
error: `#[suggestion_part(...)]` attribute without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:542:5
|
LL | #[suggestion_part]
| ^^^^^^^^^^^^^^^^^^
error: `#[suggestion_part(...)]` attribute without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:550:5
|
LL | #[suggestion_part()]
| ^^^^^^^^^^^^^^^^^^^^
error: `#[primary_span]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:559:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
|
= help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
error: multipart suggestion without any `#[suggestion_part(...)]` fields
--> $DIR/subdiagnostic-derive.rs:556:1
|
LL | / #[multipart_suggestion(parser::add_paren)]
LL | |
LL | | struct BC {
LL | | #[primary_span]
LL | |
LL | | span: Span,
LL | | }
| |_^
error: `#[suggestion_part(...)]` attribute without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:567:5
|
LL | #[suggestion_part]
| ^^^^^^^^^^^^^^^^^^
error: `#[suggestion_part(...)]` attribute without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:570:5
|
LL | #[suggestion_part()]
| ^^^^^^^^^^^^^^^^^^^^
error: `#[suggestion_part(foo = ...)]` is not a valid attribute
--> $DIR/subdiagnostic-derive.rs:573:23
|
LL | #[suggestion_part(foo = "bar")]
| ^^^^^^^^^^^
|
= help: `code` is the only valid nested attribute
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
--> $DIR/subdiagnostic-derive.rs:576:5
|
LL | #[suggestion_part(code = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
--> $DIR/subdiagnostic-derive.rs:579:5
|
LL | #[suggestion_part()]
| ^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:587:37
|
LL | #[suggestion_part(code = "...", code = ",,,")]
| ^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:587:23
|
LL | #[suggestion_part(code = "...", code = ",,,")]
| ^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:617:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:614:43
|
LL | #[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot find attribute `foo` in this scope
--> $DIR/subdiagnostic-derive.rs:63:3
|
@ -371,6 +463,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
LL | #[label(slug)]
| ^^^^ not found in `rustc_errors::fluent`
error: aborting due to 50 previous errors
error: aborting due to 63 previous errors
For more information about this error, try `rustc --explain E0425`.

View File

@ -0,0 +1,14 @@
// check-pass
#![warn(let_underscore_drop)]
struct NontrivialDrop;
impl Drop for NontrivialDrop {
fn drop(&mut self) {
println!("Dropping!");
}
}
fn main() {
let _ = NontrivialDrop; //~WARNING non-binding let on a type that implements `Drop`
}

View File

@ -0,0 +1,22 @@
warning: non-binding let on a type that implements `Drop`
--> $DIR/let_underscore_drop.rs:13:5
|
LL | let _ = NontrivialDrop;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/let_underscore_drop.rs:2:9
|
LL | #![warn(let_underscore_drop)]
| ^^^^^^^^^^^^^^^^^^^
help: consider binding to an unused variable to avoid immediately dropping the value
|
LL | let _unused = NontrivialDrop;
| ~~~~~~~
help: consider immediately dropping the value
|
LL | drop(NontrivialDrop);
| ~~~~~ +
warning: 1 warning emitted

View File

@ -0,0 +1,7 @@
// check-fail
use std::sync::{Arc, Mutex};
fn main() {
let data = Arc::new(Mutex::new(0));
let _ = data.lock().unwrap(); //~ERROR non-binding let on a synchronization lock
}

View File

@ -0,0 +1,20 @@
error: non-binding let on a synchronization lock
--> $DIR/let_underscore_lock.rs:6:9
|
LL | let _ = data.lock().unwrap();
| ^ ^^^^^^^^^^^^^^^^^^^^ this binding will immediately drop the value assigned to it
| |
| this lock is not assigned to a binding and is immediately dropped
|
= note: `#[deny(let_underscore_lock)]` on by default
help: consider binding to an unused variable to avoid immediately dropping the value
|
LL | let _unused = data.lock().unwrap();
| ~~~~~~~
help: consider immediately dropping the value
|
LL | drop(data.lock().unwrap());
| ~~~~~ +
error: aborting due to previous error

View File

@ -0,0 +1,49 @@
#![feature(rustc_attrs)]
#[rustc_access_level] mod outer { //~ ERROR None
#[rustc_access_level] pub mod inner { //~ ERROR Some(Exported)
#[rustc_access_level]
extern "C" { //~ ERROR Some(Exported)
#[rustc_access_level] static a: u8; //~ ERROR None
#[rustc_access_level] pub fn b(); //~ ERROR Some(Exported)
}
#[rustc_access_level]
pub trait Trait { //~ ERROR Some(Exported)
#[rustc_access_level] const A: i32; //~ ERROR Some(Exported)
#[rustc_access_level] type B; //~ ERROR Some(Exported)
}
#[rustc_access_level]
pub struct Struct { //~ ERROR Some(Exported)
#[rustc_access_level] a: u8, //~ ERROR None
#[rustc_access_level] pub b: u8, //~ ERROR Some(Exported)
}
#[rustc_access_level]
pub union Union { //~ ERROR Some(Exported)
#[rustc_access_level] a: u8, //~ ERROR None
#[rustc_access_level] pub b: u8, //~ ERROR Some(Exported)
}
#[rustc_access_level]
pub enum Enum { //~ ERROR Some(Exported)
#[rustc_access_level] A( //~ ERROR Some(Exported)
#[rustc_access_level] Struct, //~ ERROR Some(Exported)
#[rustc_access_level] Union, //~ ERROR Some(Exported)
),
}
}
#[rustc_access_level] macro_rules! none_macro { //~ ERROR None
() => {};
}
#[macro_export]
#[rustc_access_level] macro_rules! public_macro { //~ ERROR Some(Public)
() => {};
}
}
pub use outer::inner;
fn main() {}

View File

@ -0,0 +1,125 @@
error: None
--> $DIR/access_levels.rs:3:23
|
LL | #[rustc_access_level] mod outer {
| ^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:4:27
|
LL | #[rustc_access_level] pub mod inner {
| ^^^^^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:6:9
|
LL | / extern "C" {
LL | | #[rustc_access_level] static a: u8;
LL | | #[rustc_access_level] pub fn b();
LL | | }
| |_________^
error: Some(Exported)
--> $DIR/access_levels.rs:11:9
|
LL | pub trait Trait {
| ^^^^^^^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:17:9
|
LL | pub struct Struct {
| ^^^^^^^^^^^^^^^^^
error: None
--> $DIR/access_levels.rs:18:35
|
LL | #[rustc_access_level] a: u8,
| ^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:19:35
|
LL | #[rustc_access_level] pub b: u8,
| ^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:23:9
|
LL | pub union Union {
| ^^^^^^^^^^^^^^^
error: None
--> $DIR/access_levels.rs:24:35
|
LL | #[rustc_access_level] a: u8,
| ^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:25:35
|
LL | #[rustc_access_level] pub b: u8,
| ^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:29:9
|
LL | pub enum Enum {
| ^^^^^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:30:35
|
LL | #[rustc_access_level] A(
| ^
error: Some(Exported)
--> $DIR/access_levels.rs:31:39
|
LL | #[rustc_access_level] Struct,
| ^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:32:39
|
LL | #[rustc_access_level] Union,
| ^^^^^
error: None
--> $DIR/access_levels.rs:37:27
|
LL | #[rustc_access_level] macro_rules! none_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: Some(Public)
--> $DIR/access_levels.rs:42:27
|
LL | #[rustc_access_level] macro_rules! public_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:12:35
|
LL | #[rustc_access_level] const A: i32;
| ^^^^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:13:35
|
LL | #[rustc_access_level] type B;
| ^^^^^^
error: None
--> $DIR/access_levels.rs:7:35
|
LL | #[rustc_access_level] static a: u8;
| ^^^^^^^^^^^^
error: Some(Exported)
--> $DIR/access_levels.rs:8:35
|
LL | #[rustc_access_level] pub fn b();
| ^^^^^^^^^^
error: aborting due to 20 previous errors

View File

@ -4,7 +4,7 @@ version = "0.0.0"
edition = "2021"
[dependencies]
rustdoc = { path = "../../librustdoc" }
mdbook = { version = "0.4", default-features = false, features = ["search"] }
[[bin]]
name = "error_index_generator"

View File

@ -0,0 +1,19 @@
[book]
title = "Error codes index"
description = "Book listing all Rust error codes"
src = ""
[output.html]
git-repository-url = "https://github.com/rust-lang/rust/"
additional-css = ["error-index.css"]
additional-js = ["error-index.js"]
[output.html.search]
enable = true
limit-results = 20
use-boolean-and = true
boost-title = 2
boost-hierarchy = 2
boost-paragraph = 1
expand = true
heading-split-level = 0

View File

@ -0,0 +1,38 @@
code.compile_fail {
border-left: 2px solid red;
}
pre .tooltip {
position: absolute;
left: -25px;
top: 0;
z-index: 1;
color: red;
cursor: pointer;
}
pre .tooltip::after {
display: none;
content: "This example deliberately fails to compile";
background-color: #000;
color: #fff;
border-color: #000;
text-align: center;
padding: 5px 3px 3px 3px;
border-radius: 6px;
margin-left: 5px;
}
pre .tooltip::before {
display: none;
border-color: transparent black transparent transparent;
content: " ";
position: absolute;
top: 50%;
left: 16px;
margin-top: -5px;
border-width: 5px;
border-style: solid;
}
pre .tooltip:hover::before, pre .tooltip:hover::after {
display: inline;
}

View File

@ -0,0 +1,9 @@
for (const elem of document.querySelectorAll("pre.playground")) {
if (elem.querySelector(".compile_fail") === null) {
continue;
}
const child = document.createElement("div");
child.className = "tooltip";
child.textContent = "ⓘ";
elem.appendChild(child);
}

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