mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 06:22:00 +00:00
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:
commit
9353538c7b
@ -1259,7 +1259,7 @@ dependencies = [
|
||||
name = "error_index_generator"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustdoc",
|
||||
"mdbook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -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");
|
||||
|
@ -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>,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
175
compiler/rustc_lint/src/let_underscore.rs
Normal file
175
compiler/rustc_lint/src/let_underscore.rs
Normal 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();
|
||||
}
|
@ -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,
|
||||
|
@ -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,125 +211,162 @@ 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 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));
|
||||
}
|
||||
NestedMeta::Meta(meta @ Meta::NameValue(_))
|
||||
if matches!(
|
||||
meta.path().segments.last().unwrap().ident.to_string().as_str(),
|
||||
"code" | "applicability"
|
||||
) =>
|
||||
{
|
||||
// don't error for valid follow-up attributes
|
||||
}
|
||||
nested_attr => {
|
||||
throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
|
||||
diag.help(
|
||||
"first argument of the attribute should be the diagnostic \
|
||||
slug",
|
||||
)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for nested_attr in nested_iter {
|
||||
let meta = match nested_attr {
|
||||
NestedMeta::Meta(ref meta) => meta,
|
||||
_ => 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();
|
||||
|
||||
match meta {
|
||||
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => {
|
||||
match nested_name {
|
||||
"code" => {
|
||||
let formatted_str = self.build_format(&s.value(), s.span());
|
||||
self.code.set_once((formatted_str, span));
|
||||
}
|
||||
"applicability" => {
|
||||
let value = match Applicability::from_str(&s.value()) {
|
||||
Ok(v) => v,
|
||||
Err(()) => {
|
||||
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),
|
||||
let Meta::List(MetaList { ref nested, .. }) = meta else {
|
||||
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)
|
||||
);
|
||||
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)) => {
|
||||
slug.set_once((path.clone(), span));
|
||||
}
|
||||
NestedMeta::Meta(meta @ Meta::NameValue(_))
|
||||
if matches!(
|
||||
meta.path().segments.last().unwrap().ident.to_string().as_str(),
|
||||
"code" | "applicability"
|
||||
) =>
|
||||
{
|
||||
// Don't error for valid follow-up attributes.
|
||||
}
|
||||
nested_attr => {
|
||||
throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
|
||||
diag.help(
|
||||
"first argument of the attribute should be the diagnostic \
|
||||
slug",
|
||||
)
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if matches!(
|
||||
kind,
|
||||
SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note
|
||||
) && self.applicability.is_some()
|
||||
{
|
||||
throw_span_err!(
|
||||
span,
|
||||
&format!(
|
||||
"`applicability` is not a valid nested attribute of a `{}` attribute",
|
||||
name
|
||||
)
|
||||
);
|
||||
for nested_attr in nested_iter {
|
||||
let meta = match nested_attr {
|
||||
NestedMeta::Meta(ref meta) => meta,
|
||||
_ => 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 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" => {
|
||||
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" => {
|
||||
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));
|
||||
} else {
|
||||
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
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
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 { .. } => {}
|
||||
}
|
||||
|
||||
self.kinds.push((kind, span));
|
||||
kind_slugs.push((kind, slug))
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(kind_slugs)
|
||||
}
|
||||
|
||||
fn generate_field_code(
|
||||
&mut self,
|
||||
binding: &BindingInfo<'_>,
|
||||
have_suggestion: bool,
|
||||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
/// Generates the code for a field with no attributes.
|
||||
fn generate_field_set_arg(&mut self, binding: &BindingInfo<'_>) -> TokenStream {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
let ident = ast.ident.as_ref().unwrap();
|
||||
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 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 kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect();
|
||||
|
||||
let diag = &self.diag;
|
||||
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 = 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(..)) {
|
||||
if let Some(span) = span_field {
|
||||
quote! { #diag.#name(#span, #message, #code, #applicability); }
|
||||
} else {
|
||||
span_err(self.span, "suggestion without `#[primary_span]` field").emit();
|
||||
quote! { unreachable!(); }
|
||||
let call = match kind {
|
||||
SubdiagnosticKind::Suggestion { suggestion_kind, code } => {
|
||||
if let Some(span) = span_field {
|
||||
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) {
|
||||
if let Some(span) = span_field {
|
||||
quote! { #diag.#name(#span, #message); }
|
||||
} else {
|
||||
span_err(self.span, "label without `#[primary_span]` field").emit();
|
||||
quote! { unreachable!(); }
|
||||
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); }
|
||||
}
|
||||
} else {
|
||||
if let Some(span) = span_field {
|
||||
quote! { #diag.#name(#span, #message); }
|
||||
} else {
|
||||
quote! { #diag.#name(#message); }
|
||||
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!(); }
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
let module = self.r.get_module(module_id.to_def_id()).unwrap();
|
||||
let resolutions = self.r.resolutions(module);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1133,24 +1133,15 @@ 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() {
|
||||
reexports.push(ModChild {
|
||||
ident,
|
||||
res,
|
||||
vis: binding.vis,
|
||||
span: binding.span,
|
||||
macro_rules: false,
|
||||
});
|
||||
}
|
||||
module.for_each_child(self.r, |this, ident, _, binding| {
|
||||
if let Some(res) = this.is_reexport(binding) {
|
||||
reexports.push(ModChild {
|
||||
ident,
|
||||
res,
|
||||
vis: binding.vis,
|
||||
span: binding.span,
|
||||
macro_rules: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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],
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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>,
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
39
src/test/mir-opt/lower_array_len_e2e.rs
Normal file
39
src/test/mir-opt/lower_array_len_e2e.rs
Normal 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]);
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
32
src/test/mir-opt/lower_intrinsics_e2e.rs
Normal file
32
src/test/mir-opt/lower_intrinsics_e2e.rs
Normal 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) {}
|
@ -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
|
||||
- }
|
||||
-
|
||||
|
@ -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
|
||||
- }
|
||||
-
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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?)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -1,4 +1,4 @@
|
||||
// compile-flags: -Zunsound-mir-opts
|
||||
// unit-test: SimplifyLocals
|
||||
|
||||
fn map(x: Option<Box<()>>) -> Option<Box<()>> {
|
||||
match x {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
96
src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
Normal file
96
src/test/mir-opt/try_identity_e2e.new.PreCodegen.after.mir
Normal 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
|
||||
}
|
||||
}
|
53
src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
Normal file
53
src/test/mir-opt/try_identity_e2e.old.PreCodegen.after.mir
Normal 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
|
||||
}
|
||||
}
|
34
src/test/mir-opt/try_identity_e2e.rs
Normal file
34
src/test/mir-opt/try_identity_e2e.rs
Normal 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(()));
|
||||
}
|
@ -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>,
|
||||
}
|
||||
|
@ -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`.
|
||||
|
14
src/test/ui/lint/let_underscore/let_underscore_drop.rs
Normal file
14
src/test/ui/lint/let_underscore/let_underscore_drop.rs
Normal 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`
|
||||
}
|
22
src/test/ui/lint/let_underscore/let_underscore_drop.stderr
Normal file
22
src/test/ui/lint/let_underscore/let_underscore_drop.stderr
Normal 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
|
||||
|
7
src/test/ui/lint/let_underscore/let_underscore_lock.rs
Normal file
7
src/test/ui/lint/let_underscore/let_underscore_lock.rs
Normal 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
|
||||
}
|
20
src/test/ui/lint/let_underscore/let_underscore_lock.stderr
Normal file
20
src/test/ui/lint/let_underscore/let_underscore_lock.stderr
Normal 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
|
||||
|
49
src/test/ui/privacy/access_levels.rs
Normal file
49
src/test/ui/privacy/access_levels.rs
Normal 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() {}
|
125
src/test/ui/privacy/access_levels.stderr
Normal file
125
src/test/ui/privacy/access_levels.stderr
Normal 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
|
||||
|
@ -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"
|
||||
|
19
src/tools/error_index_generator/book_config.toml
Normal file
19
src/tools/error_index_generator/book_config.toml
Normal 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
|
38
src/tools/error_index_generator/error-index.css
Normal file
38
src/tools/error_index_generator/error-index.css
Normal 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;
|
||||
}
|
9
src/tools/error_index_generator/error-index.js
Normal file
9
src/tools/error_index_generator/error-index.js
Normal 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
Loading…
Reference in New Issue
Block a user