Auto merge of #111493 - matthiaskrgr:rollup-iw1z59b, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #111179 (Fix instrument-coverage tests by using Python to sort instantiation groups)
 - #111393 (bump windows crate 0.46 -> 0.48)
 - #111441 (Verify copies of mutable pointers in 2 stages in ReferencePropagation)
 - #111456 (Update cargo)
 - #111490 (Don't ICE in layout computation for placeholder types)
 - #111492 (use by ref TokenTree iterator to avoid a few clones)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-05-12 07:31:18 +00:00
commit 0b795044c6
31 changed files with 474 additions and 137 deletions

View File

@ -741,7 +741,7 @@ dependencies = [
"tracing-subscriber",
"unified-diff",
"walkdir",
"windows 0.46.0",
"windows",
]
[[package]]
@ -1647,7 +1647,7 @@ dependencies = [
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows 0.48.0",
"windows",
]
[[package]]
@ -3259,7 +3259,7 @@ dependencies = [
"tempfile",
"thorin-dwp",
"tracing",
"windows 0.46.0",
"windows",
]
[[package]]
@ -3315,7 +3315,7 @@ dependencies = [
"tempfile",
"thin-vec",
"tracing",
"windows 0.46.0",
"windows",
]
[[package]]
@ -3376,7 +3376,7 @@ dependencies = [
"rustc_ty_utils",
"serde_json",
"tracing",
"windows 0.46.0",
"windows",
]
[[package]]
@ -3426,7 +3426,7 @@ dependencies = [
"termize",
"tracing",
"unicode-width",
"windows 0.46.0",
"windows",
]
[[package]]
@ -4096,7 +4096,7 @@ dependencies = [
"smallvec",
"termize",
"tracing",
"windows 0.46.0",
"windows",
]
[[package]]
@ -5498,15 +5498,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows"
version = "0.48.0"

View File

@ -19,7 +19,7 @@ pub fn expand_concat_idents<'cx>(
}
let mut res_str = String::new();
for (i, e) in tts.into_trees().enumerate() {
for (i, e) in tts.trees().enumerate() {
if i & 1 == 1 {
match e {
TokenTree::Token(Token { kind: token::Comma, .. }, _) => {}

View File

@ -8,7 +8,7 @@ pub fn expand_trace_macros(
sp: Span,
tt: TokenStream,
) -> Box<dyn base::MacResult + 'static> {
let mut cursor = tt.into_trees();
let mut cursor = tt.trees();
let mut err = false;
let value = match &cursor.next() {
Some(TokenTree::Token(token, _)) if token.is_keyword(kw::True) => true,

View File

@ -51,5 +51,5 @@ default-features = false
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"]
[target.'cfg(windows)'.dependencies.windows]
version = "0.46.0"
version = "0.48.0"
features = ["Win32_Globalization"]

View File

@ -37,7 +37,7 @@ itertools = "0.10.1"
version = "0.11"
[target.'cfg(windows)'.dependencies.windows]
version = "0.46.0"
version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_Storage_FileSystem",

View File

@ -865,14 +865,16 @@ cfg_if! {
use std::mem;
use windows::{
Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
// FIXME: change back to K32GetProcessMemoryInfo when windows crate
// updated to 0.49.0+ to drop dependency on psapi.dll
Win32::System::ProcessStatus::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS},
Win32::System::Threading::GetCurrentProcess,
};
let mut pmc = PROCESS_MEMORY_COUNTERS::default();
let pmc_size = mem::size_of_val(&pmc);
unsafe {
K32GetProcessMemoryInfo(
GetProcessMemoryInfo(
GetCurrentProcess(),
&mut pmc,
pmc_size as u32,

View File

@ -57,7 +57,7 @@ rustc_mir_transform = { path = "../rustc_mir_transform" }
libc = "0.2"
[target.'cfg(windows)'.dependencies.windows]
version = "0.46.0"
version = "0.48.0"
features = [
"Win32_System_Diagnostics_Debug",
]

View File

@ -27,12 +27,11 @@ serde = { version = "1.0.125", features = [ "derive" ] }
serde_json = "1.0.59"
[target.'cfg(windows)'.dependencies.windows]
version = "0.46.0"
version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_System_WindowsProgramming",
]
[features]

View File

@ -19,8 +19,7 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
use windows::{
core::PCSTR,
Win32::Foundation::{CloseHandle, HANDLE, WAIT_ABANDONED, WAIT_OBJECT_0},
Win32::System::Threading::{CreateMutexA, ReleaseMutex, WaitForSingleObject},
Win32::System::WindowsProgramming::INFINITE,
Win32::System::Threading::{CreateMutexA, ReleaseMutex, WaitForSingleObject, INFINITE},
};
struct Handle(HANDLE);

View File

@ -1882,8 +1882,8 @@ declare_lint_pass!(
struct UnderMacro(bool);
impl KeywordIdents {
fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) {
for tt in tokens.into_trees() {
fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: &TokenStream) {
for tt in tokens.trees() {
match tt {
// Only report non-raw idents.
TokenTree::Token(token, _) => {
@ -1944,10 +1944,10 @@ impl KeywordIdents {
impl EarlyLintPass for KeywordIdents {
fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) {
self.check_tokens(cx, mac_def.body.tokens.clone());
self.check_tokens(cx, &mac_def.body.tokens);
}
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) {
self.check_tokens(cx, mac.args.tokens.clone());
self.check_tokens(cx, &mac.args.tokens);
}
fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
self.check_ident_token(cx, UnderMacro(false), ident);

View File

@ -2366,13 +2366,11 @@ impl<'tcx> Ty<'tcx> {
ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),
ty::Alias(..) | ty::Param(_) => false,
ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false,
ty::Infer(ty::TyVar(_)) => false,
ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
ty::Bound(..) | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
}
}

View File

@ -85,7 +85,9 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let ssa = SsaLocals::new(body);
let mut replacer = compute_replacement(tcx, body, &ssa);
debug!(?replacer.targets, ?replacer.allowed_replacements, ?replacer.storage_to_remove);
debug!(?replacer.targets);
debug!(?replacer.allowed_replacements);
debug!(?replacer.storage_to_remove);
replacer.visit_body_preserves_cfg(body);
@ -190,8 +192,11 @@ fn compute_replacement<'tcx>(
continue;
}
// Whether the current local is subject to the uniqueness rule.
let needs_unique = ty.is_mutable_ptr();
// If this a mutable reference that we cannot fully replace, mark it as unknown.
if ty.is_mutable_ptr() && !fully_replacable_locals.contains(local) {
if needs_unique && !fully_replacable_locals.contains(local) {
debug!("not fully replaceable");
continue;
}
@ -203,13 +208,14 @@ fn compute_replacement<'tcx>(
// have been visited before.
Rvalue::Use(Operand::Copy(place) | Operand::Move(place))
| Rvalue::CopyForDeref(place) => {
if let Some(rhs) = place.as_local() {
if let Some(rhs) = place.as_local() && ssa.is_ssa(rhs) {
let target = targets[rhs];
if matches!(target, Value::Pointer(..)) {
// Only see through immutable reference and pointers, as we do not know yet if
// mutable references are fully replaced.
if !needs_unique && matches!(target, Value::Pointer(..)) {
targets[local] = target;
} else if ssa.is_ssa(rhs) {
let refmut = body.local_decls[rhs].ty.is_mutable_ptr();
targets[local] = Value::Pointer(tcx.mk_place_deref(rhs.into()), refmut);
} else {
targets[local] = Value::Pointer(tcx.mk_place_deref(rhs.into()), needs_unique);
}
}
}
@ -217,10 +223,10 @@ fn compute_replacement<'tcx>(
let mut place = *place;
// Try to see through `place` in order to collapse reborrow chains.
if place.projection.first() == Some(&PlaceElem::Deref)
&& let Value::Pointer(target, refmut) = targets[place.local]
&& let Value::Pointer(target, inner_needs_unique) = targets[place.local]
// Only see through immutable reference and pointers, as we do not know yet if
// mutable references are fully replaced.
&& !refmut
&& !inner_needs_unique
// Only collapse chain if the pointee is definitely live.
&& can_perform_opt(target, location)
{
@ -228,7 +234,7 @@ fn compute_replacement<'tcx>(
}
assert_ne!(place.local, local);
if is_constant_place(place) {
targets[local] = Value::Pointer(place, ty.is_mutable_ptr());
targets[local] = Value::Pointer(place, needs_unique);
}
}
// We do not know what to do, so keep as not-a-pointer.
@ -276,16 +282,35 @@ fn compute_replacement<'tcx>(
return;
}
if let Value::Pointer(target, refmut) = self.targets[place.local]
&& place.projection.first() == Some(&PlaceElem::Deref)
{
let perform_opt = (self.can_perform_opt)(target, loc);
if perform_opt {
self.allowed_replacements.insert((target.local, loc));
} else if refmut {
// This mutable reference is not fully replacable, so drop it.
self.targets[place.local] = Value::Unknown;
if place.projection.first() != Some(&PlaceElem::Deref) {
// This is not a dereference, nothing to do.
return;
}
let mut place = place.as_ref();
loop {
if let Value::Pointer(target, needs_unique) = self.targets[place.local] {
let perform_opt = (self.can_perform_opt)(target, loc);
debug!(?place, ?target, ?needs_unique, ?perform_opt);
// This a reborrow chain, recursively allow the replacement.
//
// This also allows to detect cases where `target.local` is not replacable,
// and mark it as such.
if let &[PlaceElem::Deref] = &target.projection[..] {
assert!(perform_opt);
self.allowed_replacements.insert((target.local, loc));
place.local = target.local;
continue;
} else if perform_opt {
self.allowed_replacements.insert((target.local, loc));
} else if needs_unique {
// This mutable reference is not fully replacable, so drop it.
self.targets[place.local] = Value::Unknown;
}
}
break;
}
}
}
@ -326,18 +351,23 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
}
fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
if let Value::Pointer(target, _) = self.targets[place.local]
&& place.projection.first() == Some(&PlaceElem::Deref)
{
let perform_opt = matches!(ctxt, PlaceContext::NonUse(_))
|| self.allowed_replacements.contains(&(target.local, loc));
if place.projection.first() != Some(&PlaceElem::Deref) {
return;
}
if perform_opt {
*place = target.project_deeper(&place.projection[1..], self.tcx);
self.any_replacement = true;
loop {
if let Value::Pointer(target, _) = self.targets[place.local] {
let perform_opt = matches!(ctxt, PlaceContext::NonUse(_))
|| self.allowed_replacements.contains(&(target.local, loc));
if perform_opt {
*place = target.project_deeper(&place.projection[1..], self.tcx);
self.any_replacement = true;
continue;
}
}
} else {
self.super_place(place, ctxt, loc);
break;
}
}

View File

@ -25,7 +25,7 @@ termize = "0.1.1"
libc = "0.2"
[target.'cfg(windows)'.dependencies.windows]
version = "0.46.0"
version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_System_LibraryLoader",

View File

@ -135,13 +135,13 @@ fn current_dll_path() -> Result<PathBuf, String> {
use windows::{
core::PCWSTR,
Win32::Foundation::HINSTANCE,
Win32::Foundation::HMODULE,
Win32::System::LibraryLoader::{
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
},
};
let mut module = HINSTANCE::default();
let mut module = HMODULE::default();
unsafe {
GetModuleHandleExW(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,

@ -1 +1 @@
Subproject commit 26b73d15a68fb94579f6d3590585ec0e9d81d3d5
Subproject commit 13413c64ff88dd6c2824e9eb9374fc5f10895d28

View File

@ -28,7 +28,7 @@ libc = "0.2"
miow = "0.5"
[target.'cfg(windows)'.dependencies.windows]
version = "0.46.0"
version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_System_Diagnostics_Debug",

View File

@ -6,47 +6,53 @@ use std::path::Path;
/// These are licenses that are allowed for all crates, including the runtime,
/// rustc, tools, etc.
#[rustfmt::skip]
const LICENSES: &[&str] = &[
"MIT/Apache-2.0",
"MIT / Apache-2.0",
"Apache-2.0/MIT",
// tidy-alphabetical-start
"(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident
"0BSD OR MIT OR Apache-2.0", // adler license
"0BSD",
"Apache-2.0 / MIT",
"MIT OR Apache-2.0",
"Apache-2.0 OR MIT",
"Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license
"MIT",
"Apache-2.0/MIT",
"ISC",
"Unlicense/MIT",
"MIT / Apache-2.0",
"MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
"MIT OR Apache-2.0",
"MIT OR Zlib OR Apache-2.0", // miniz_oxide
"MIT",
"MIT/Apache-2.0",
"Unicode-DFS-2016", // tinystr and icu4x
"Unlicense OR MIT",
"0BSD",
"0BSD OR MIT OR Apache-2.0", // adler license
"Zlib OR Apache-2.0 OR MIT", // tinyvec
"MIT OR Apache-2.0 OR Zlib", // tinyvec_macros
"MIT OR Zlib OR Apache-2.0", // miniz_oxide
"(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident
"Unicode-DFS-2016", // tinystr and icu4x
"Unlicense/MIT",
"Zlib OR Apache-2.0 OR MIT", // tinyvec
// tidy-alphabetical-end
];
/// These are exceptions to Rust's permissive licensing policy, and
/// should be considered bugs. Exceptions are only allowed in Rust
/// tooling. It is _crucial_ that no exception crates be dependencies
/// of the Rust runtime (std/test).
#[rustfmt::skip]
const EXCEPTIONS: &[(&str, &str)] = &[
// tidy-alphabetical-start
("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
("mdbook", "MPL-2.0"), // mdbook
("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku
("colored", "MPL-2.0"), // rustfmt
("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target. FIXME: this dependency violates the documentation comment above.
("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
("mdbook", "MPL-2.0"), // mdbook
("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde)
("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku
("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot
("snap", "BSD-3-Clause"), // rustc
("fluent-langneg", "Apache-2.0"), // rustc (fluent translations)
("self_cell", "Apache-2.0"), // rustc (fluent translations)
// FIXME: this dependency violates the documentation comment above:
("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target
("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
("self_cell", "Apache-2.0"), // rustc (fluent translations)
("snap", "BSD-3-Clause"), // rustc
// tidy-alphabetical-end
];
const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
// tidy-alphabetical-start
("bitmaps", "MPL-2.0+"),
("bytesize", "Apache-2.0"),
("dunce", "CC0-1.0 OR MIT-0"),
@ -62,9 +68,11 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
("sized-chunks", "MPL-2.0+"),
("subtle", "BSD-3-Clause"),
("unicode-bom", "Apache-2.0"),
// tidy-alphabetical-end
];
const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
// tidy-alphabetical-start
("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"),
("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"),
("cranelift-codegen-meta", "Apache-2.0 WITH LLVM-exception"),
@ -80,6 +88,7 @@ const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
("regalloc2", "Apache-2.0 WITH LLVM-exception"),
("target-lexicon", "Apache-2.0 WITH LLVM-exception"),
("wasmtime-jit-icache-coherence", "Apache-2.0 WITH LLVM-exception"),
// tidy-alphabetical-end
];
const EXCEPTIONS_BOOTSTRAP: &[(&str, &str)] = &[
@ -95,6 +104,7 @@ const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort",
/// This list is here to provide a speed-bump to adding a new dependency to
/// rustc. Please check with the compiler team before adding an entry.
const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
// tidy-alphabetical-start
"addr2line",
"adler",
"ahash",
@ -113,8 +123,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"chalk-engine",
"chalk-ir",
"chalk-solve",
"convert_case", // dependency of derive_more
"compiler_builtins",
"convert_case", // dependency of derive_more
"cpufeatures",
"crc32fast",
"crossbeam-channel",
@ -187,8 +197,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"ppv-lite86",
"proc-macro-hack",
"proc-macro2",
"pulldown-cmark",
"psm",
"pulldown-cmark",
"punycode",
"quote",
"rand",
@ -227,6 +237,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"tempfile",
"termcolor",
"termize",
"thin-vec",
"thiserror",
"thiserror-impl",
"thorin-dwp",
@ -234,7 +245,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"tinystr",
"tinyvec",
"tinyvec_macros",
"thin-vec",
"tracing",
"tracing-attributes",
"tracing-core",
@ -263,29 +273,37 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"valuable",
"version_check",
"wasi",
"windows",
"winapi",
"winapi-i686-pc-windows-gnu",
"winapi-util",
"winapi-x86_64-pc-windows-gnu",
"windows",
"windows-targets",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"writeable",
// this is a false-positive: it's only used by rustfmt, but because it's enabled through a
// feature, tidy thinks it's used by rustc as well.
"yansi-term",
"yansi-term", // this is a false-positive: it's only used by rustfmt, but because it's enabled through a feature, tidy thinks it's used by rustc as well.
"yoke",
"yoke-derive",
"zerofrom",
"zerofrom-derive",
"zerovec",
"zerovec-derive",
// tidy-alphabetical-end
];
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
// tidy-alphabetical-start
"ahash",
"anyhow",
"autocfg",
"bumpalo",
"bitflags",
"bumpalo",
"byteorder",
"cfg-if",
"cranelift-bforest",
@ -324,6 +342,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
"windows-sys",
// tidy-alphabetical-end
];
/// Dependency checks.

View File

@ -0,0 +1,74 @@
- // MIR for `mut_raw_then_mut_shr` before ReferencePropagation
+ // MIR for `mut_raw_then_mut_shr` after ReferencePropagation
fn mut_raw_then_mut_shr() -> (i32, i32) {
let mut _0: (i32, i32); // return place in scope 0 at $DIR/reference_prop.rs:+0:30: +0:40
let mut _1: i32; // in scope 0 at $DIR/reference_prop.rs:+1:9: +1:14
let mut _4: *mut i32; // in scope 0 at $DIR/reference_prop.rs:+3:16: +3:36
let mut _5: &mut i32; // in scope 0 at $DIR/reference_prop.rs:+3:16: +3:26
let _8: (); // in scope 0 at $DIR/reference_prop.rs:+7:5: +7:26
let mut _9: i32; // in scope 0 at $DIR/reference_prop.rs:+8:6: +8:7
let mut _10: i32; // in scope 0 at $DIR/reference_prop.rs:+8:9: +8:10
scope 1 {
debug x => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:14
let _2: &mut i32; // in scope 1 at $DIR/reference_prop.rs:+2:9: +2:13
scope 2 {
debug xref => _2; // in scope 2 at $DIR/reference_prop.rs:+2:9: +2:13
let _3: *mut i32; // in scope 2 at $DIR/reference_prop.rs:+3:9: +3:13
scope 3 {
debug xraw => _3; // in scope 3 at $DIR/reference_prop.rs:+3:9: +3:13
let _6: &i32; // in scope 3 at $DIR/reference_prop.rs:+4:9: +4:13
scope 4 {
debug xshr => _6; // in scope 4 at $DIR/reference_prop.rs:+4:9: +4:13
let _7: i32; // in scope 4 at $DIR/reference_prop.rs:+6:9: +6:10
scope 5 {
debug a => _7; // in scope 5 at $DIR/reference_prop.rs:+6:9: +6:10
scope 6 {
}
}
}
}
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:14
_1 = const 2_i32; // scope 0 at $DIR/reference_prop.rs:+1:17: +1:18
- StorageLive(_2); // scope 1 at $DIR/reference_prop.rs:+2:9: +2:13
_2 = &mut _1; // scope 1 at $DIR/reference_prop.rs:+2:16: +2:22
StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:9: +3:13
- StorageLive(_4); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36
- StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
- _5 = &mut (*_2); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
- _4 = &raw mut (*_5); // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
+ _4 = &raw mut _1; // scope 2 at $DIR/reference_prop.rs:+3:16: +3:26
_3 = _4; // scope 2 at $DIR/reference_prop.rs:+3:16: +3:36
- StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+3:36: +3:37
- StorageDead(_4); // scope 2 at $DIR/reference_prop.rs:+3:36: +3:37
StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+4:9: +4:13
- _6 = &(*_2); // scope 3 at $DIR/reference_prop.rs:+4:16: +4:22
+ _6 = &_1; // scope 3 at $DIR/reference_prop.rs:+4:16: +4:22
StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:10
- _7 = (*_6); // scope 4 at $DIR/reference_prop.rs:+6:13: +6:18
- StorageLive(_8); // scope 5 at $DIR/reference_prop.rs:+7:5: +7:26
- (*_3) = const 4_i32; // scope 6 at $DIR/reference_prop.rs:+7:14: +7:23
- _8 = const (); // scope 6 at $DIR/reference_prop.rs:+7:5: +7:26
- StorageDead(_8); // scope 5 at $DIR/reference_prop.rs:+7:25: +7:26
+ _7 = _1; // scope 4 at $DIR/reference_prop.rs:+6:13: +6:18
+ _1 = const 4_i32; // scope 6 at $DIR/reference_prop.rs:+7:14: +7:23
StorageLive(_9); // scope 5 at $DIR/reference_prop.rs:+8:6: +8:7
_9 = _7; // scope 5 at $DIR/reference_prop.rs:+8:6: +8:7
StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+8:9: +8:10
_10 = _1; // scope 5 at $DIR/reference_prop.rs:+8:9: +8:10
_0 = (move _9, move _10); // scope 5 at $DIR/reference_prop.rs:+8:5: +8:11
StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+8:10: +8:11
StorageDead(_9); // scope 5 at $DIR/reference_prop.rs:+8:10: +8:11
StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+9:1: +9:2
StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+9:1: +9:2
StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+9:1: +9:2
- StorageDead(_2); // scope 1 at $DIR/reference_prop.rs:+9:1: +9:2
StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+9:1: +9:2
return; // scope 0 at $DIR/reference_prop.rs:+9:2: +9:2
}
}

View File

@ -9,15 +9,14 @@
let mut _5: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
bb0: {
_2 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:25
- _2 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:25
- _3 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
- _4 = &raw mut (*_2); // scope 0 at $DIR/reference_prop.rs:+12:13: +12:30
- _5 = &raw mut (*_3); // scope 0 at $DIR/reference_prop.rs:+13:13: +13:30
- _0 = (*_4); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
- _0 = (*_5); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
+ _3 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
+ _0 = (*_2); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
+ _0 = (*_3); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
+ _0 = (*_1); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
+ _0 = (*_1); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
return; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:21
}
}

View File

@ -433,6 +433,29 @@ fn maybe_dead(m: bool) {
)
}
fn mut_raw_then_mut_shr() -> (i32, i32) {
let mut x = 2;
let xref = &mut x;
let xraw = &mut *xref as *mut _;
let xshr = &*xref;
// Verify that we completely replace with `x` in both cases.
let a = *xshr;
unsafe { *xraw = 4; }
(a, x)
}
fn unique_with_copies() {
let y = {
let mut a = 0;
let x = &raw mut a;
// `*y` is not replacable below, so we must not replace `*x`.
unsafe { opaque(*x) };
x
};
// But rewriting as `*x` is ok.
unsafe { opaque(*y) };
}
fn main() {
let mut x = 5_usize;
let mut y = 7_usize;
@ -444,6 +467,8 @@ fn main() {
multiple_storage();
dominate_storage();
maybe_dead(true);
mut_raw_then_mut_shr();
unique_with_copies();
}
// EMIT_MIR reference_prop.reference_propagation.ReferencePropagation.diff
@ -454,3 +479,5 @@ fn main() {
// EMIT_MIR reference_prop.multiple_storage.ReferencePropagation.diff
// EMIT_MIR reference_prop.dominate_storage.ReferencePropagation.diff
// EMIT_MIR reference_prop.maybe_dead.ReferencePropagation.diff
// EMIT_MIR reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
// EMIT_MIR reference_prop.unique_with_copies.ReferencePropagation.diff

View File

@ -0,0 +1,66 @@
- // MIR for `unique_with_copies` before ReferencePropagation
+ // MIR for `unique_with_copies` after ReferencePropagation
fn unique_with_copies() -> () {
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:25: +0:25
let _1: *mut i32; // in scope 0 at $DIR/reference_prop.rs:+1:9: +1:10
let mut _2: i32; // in scope 0 at $DIR/reference_prop.rs:+2:13: +2:18
let _4: (); // in scope 0 at $DIR/reference_prop.rs:+5:18: +5:28
let mut _5: i32; // in scope 0 at $DIR/reference_prop.rs:+5:25: +5:27
let _6: (); // in scope 0 at $DIR/reference_prop.rs:+9:14: +9:24
let mut _7: i32; // in scope 0 at $DIR/reference_prop.rs:+9:21: +9:23
scope 1 {
debug y => _1; // in scope 1 at $DIR/reference_prop.rs:+1:9: +1:10
scope 5 {
}
}
scope 2 {
debug a => _2; // in scope 2 at $DIR/reference_prop.rs:+2:13: +2:18
let _3: *mut i32; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
scope 3 {
debug x => _3; // in scope 3 at $DIR/reference_prop.rs:+3:13: +3:14
scope 4 {
}
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+1:9: +1:10
StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+2:13: +2:18
_2 = const 0_i32; // scope 0 at $DIR/reference_prop.rs:+2:21: +2:22
- StorageLive(_3); // scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
_3 = &raw mut _2; // scope 2 at $DIR/reference_prop.rs:+3:17: +3:27
StorageLive(_4); // scope 3 at $DIR/reference_prop.rs:+5:9: +5:30
StorageLive(_5); // scope 4 at $DIR/reference_prop.rs:+5:25: +5:27
_5 = (*_3); // scope 4 at $DIR/reference_prop.rs:+5:25: +5:27
_4 = opaque::<i32>(move _5) -> bb1; // scope 4 at $DIR/reference_prop.rs:+5:18: +5:28
// mir::Constant
// + span: $DIR/reference_prop.rs:452:18: 452:24
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_5); // scope 4 at $DIR/reference_prop.rs:+5:27: +5:28
StorageDead(_4); // scope 3 at $DIR/reference_prop.rs:+5:30: +5:31
_1 = _3; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:10
- StorageDead(_3); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
StorageLive(_6); // scope 1 at $DIR/reference_prop.rs:+9:5: +9:26
StorageLive(_7); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23
- _7 = (*_1); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23
+ _7 = (*_3); // scope 5 at $DIR/reference_prop.rs:+9:21: +9:23
_6 = opaque::<i32>(move _7) -> bb2; // scope 5 at $DIR/reference_prop.rs:+9:14: +9:24
// mir::Constant
// + span: $DIR/reference_prop.rs:456:14: 456:20
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb2: {
StorageDead(_7); // scope 5 at $DIR/reference_prop.rs:+9:23: +9:24
StorageDead(_6); // scope 1 at $DIR/reference_prop.rs:+9:26: +9:27
_0 = const (); // scope 0 at $DIR/reference_prop.rs:+0:25: +10:2
StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+10:1: +10:2
return; // scope 0 at $DIR/reference_prop.rs:+10:2: +10:2
}
}

View File

@ -138,6 +138,7 @@ endif
) \
2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
| "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
| "$(PYTHON)" $(BASEDIR)/sort_subviews.py \
> "$(TMPDIR)"/actual_show_coverage.$@.txt || \
( status=$$? ; \
>&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
@ -158,23 +159,15 @@ ifdef RUSTC_BLESS_TEST
else
# Compare the show coverage output (`--bless` refreshes `typical` files).
#
# FIXME(richkadel): None of the Rust test source samples have the
# `// ignore-llvm-cov-show-diffs` anymore. This directive exists to work around a limitation
# with `llvm-cov show`. When reporting coverage for multiple instantiations of a generic function,
# with different type substitutions, `llvm-cov show` prints these in a non-deterministic order,
# breaking the `diff` comparison.
# `llvm-cov show` normally prints instantiation groups in an unpredictable
# order, but we have used `sort_subviews.py` to sort them, so we can still
# check the output directly with `diff`.
#
# A partial workaround is implemented below, with `diff --ignore-matching-lines=RE`
# to ignore each line prefixing each generic instantiation coverage code region.
#
# This workaround only works if the coverage counts are identical across all reported
# instantiations. If there is no way to ensure this, you may need to apply the
# `// ignore-llvm-cov-show-diffs` directive, and check for differences using the
# `.json` files to validate that results have not changed. (Until then, the JSON
# files are redundant, so there is no need to generate `expected_*.json` files or
# compare actual JSON results.)
# Some of the test cases are currently not working (since #110393) and have
# been marked with `// ignore-llvm-cov-show-diffs` so that they don't fail
# the build.
$(DIFF) --ignore-matching-lines='^ \| .*::<.*>.*:$$' --ignore-matching-lines='^ \| <.*>::.*:$$' \
$(DIFF) \
expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
>&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \

View File

@ -41,9 +41,9 @@
41| 1| // executed asynchronously.
42| 1| match x {
43| 1| y if c(x).await == y + 1 => { d().await; }
^0 ^0 ^0 ^0
^0 ^0 ^0 ^0
44| 1| y if f().await == y + 1 => (),
^0 ^0 ^0
^0 ^0 ^0
45| 1| _ => (),
46| | }
47| 1|}

View File

@ -0,0 +1,49 @@
1| |// compile-flags: --edition=2021
2| |
3| |// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
4| |// predictable order, while preserving their heterogeneous contents.
5| |
6| 1|fn main() {
7| 1| let cond = std::env::args().len() > 1;
8| 1| generic_fn::<()>(cond);
9| 1| generic_fn::<&'static str>(!cond);
10| 1| if false {
11| 0| generic_fn::<char>(cond);
12| 1| }
13| 1| generic_fn::<i32>(cond);
14| 1| other_fn();
15| 1|}
16| |
17| 3|fn generic_fn<T>(cond: bool) {
18| 3| if cond {
19| 1| println!("{}", std::any::type_name::<T>());
20| 2| }
21| 3|}
------------------
| Unexecuted instantiation: sort_groups::generic_fn::<char>
------------------
| sort_groups::generic_fn::<&str>:
| 17| 1|fn generic_fn<T>(cond: bool) {
| 18| 1| if cond {
| 19| 1| println!("{}", std::any::type_name::<T>());
| 20| 1| }
| ^0
| 21| 1|}
------------------
| sort_groups::generic_fn::<()>:
| 17| 1|fn generic_fn<T>(cond: bool) {
| 18| 1| if cond {
| 19| 0| println!("{}", std::any::type_name::<T>());
| 20| 1| }
| 21| 1|}
------------------
| sort_groups::generic_fn::<i32>:
| 17| 1|fn generic_fn<T>(cond: bool) {
| 18| 1| if cond {
| 19| 0| println!("{}", std::any::type_name::<T>());
| 20| 1| }
| 21| 1|}
------------------
22| |
23| 1|fn other_fn() {}

View File

@ -19,29 +19,29 @@
18| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
19| 2|}
------------------
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
| Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
------------------
| used_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
| Unexecuted instantiation: used_crate::used_only_from_bin_crate_generic_function::<_>
| used_crate::used_only_from_bin_crate_generic_function::<&str>:
| 17| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 18| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 19| 1|}
------------------
20| |// Expect for above function: `Unexecuted instantiation` (see below)
21| 2|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
22| 2| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
23| 2|}
------------------
| used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
| 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 23| 1|}
------------------
| used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
| used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 21| 1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
| 22| 1| println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
| 23| 1|}
@ -51,12 +51,12 @@
26| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
27| 2|}
------------------
| used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 27| 1|}
------------------
| used_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
| used_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 25| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 26| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 27| 1|}

View File

@ -42,6 +42,8 @@
40| 2| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
41| 2|}
------------------
| Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
------------------
| used_inline_crate::used_only_from_bin_crate_generic_function::<&alloc::vec::Vec<i32>>:
| 39| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
@ -51,8 +53,6 @@
| 39| 1|pub fn used_only_from_bin_crate_generic_function<T: Debug>(arg: T) {
| 40| 1| println!("used_only_from_bin_crate_generic_function with {:?}", arg);
| 41| 1|}
------------------
| Unexecuted instantiation: used_inline_crate::used_only_from_bin_crate_generic_function::<_>
------------------
42| |// Expect for above function: `Unexecuted instantiation` (see notes in `used_crate.rs`)
43| |
@ -77,15 +77,15 @@
51| 3| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
52| 3|}
------------------
| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 52| 1|}
------------------
| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<&str>:
| 50| 2|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 51| 2| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 52| 2|}
------------------
| used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
| 50| 1|pub fn used_from_bin_crate_and_lib_crate_generic_function<T: Debug>(arg: T) {
| 51| 1| println!("used_from_bin_crate_and_lib_crate_generic_function with {:?}", arg);
| 52| 1|}
------------------
53| |
54| |#[inline(always)]

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
# `llvm-cov show` prints grouped subviews (e.g. for generic functions) in an
# unstable order, which is inconvenient when checking output snapshots with
# `diff`. To work around that, this script detects consecutive subviews in its
# piped input, and sorts them while preserving their contents.
from __future__ import print_function
import sys
def main():
subviews = []
def flush_subviews():
if not subviews:
return
# The last "subview" should be just a boundary line on its own, so
# temporarily remove it before sorting the accumulated subviews.
terminator = subviews.pop()
subviews.sort()
subviews.append(terminator)
for view in subviews:
for line in view:
print(line, end="")
subviews.clear()
for line in sys.stdin:
if line.startswith(" ------------------"):
# This is a subview boundary line, so start a new subview.
subviews.append([line])
elif line.startswith(" |"):
# Add this line to the current subview.
subviews[-1].append(line)
else:
# This line is not part of a subview, so sort and print any
# accumulated subviews, and then print the line as-is.
flush_subviews()
print(line, end="")
flush_subviews()
assert not subviews
if __name__ == "__main__":
main()

View File

@ -0,0 +1,23 @@
// compile-flags: --edition=2021
// Demonstrate that `sort_subviews.py` can sort instantiation groups into a
// predictable order, while preserving their heterogeneous contents.
fn main() {
let cond = std::env::args().len() > 1;
generic_fn::<()>(cond);
generic_fn::<&'static str>(!cond);
if false {
generic_fn::<char>(cond);
}
generic_fn::<i32>(cond);
other_fn();
}
fn generic_fn<T>(cond: bool) {
if cond {
println!("{}", std::any::type_name::<T>());
}
}
fn other_fn() {}

View File

@ -1,5 +1,5 @@
error[E0277]: `&T` needs to have the same ABI as a pointer
--> $DIR/check-size-at-cast-polymorphic-bad.rs:11:15
--> $DIR/check-size-at-cast-polymorphic-bad.rs:14:15
|
LL | dyn_debug(t);
| ^ `&T` needs to be a pointer-like type

View File

@ -0,0 +1,15 @@
error[E0277]: `&T` needs to have the same ABI as a pointer
--> $DIR/check-size-at-cast-polymorphic-bad.rs:14:15
|
LL | dyn_debug(t);
| ^ `&T` needs to be a pointer-like type
|
= help: the trait `PointerLike` is not implemented for `&T`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn polymorphic<T: Debug + ?Sized>(t: &T) where &T: PointerLike {
| +++++++++++++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,3 +1,6 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(dyn_star)]
#![allow(incomplete_features)]