Open
Description
I tried this code:
Command
rustc -C opt-level=0 /home/interesting/hang_10.rs
Code
#![allow(dead_code)]
#![feature(array_zip, maybe_uninit_array_assume_init, maybe_uninit_uninit_array)]
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::{rngs::OsRng, Rng};
use std::mem::MaybeUninit;
macro_rules! defbenches {
($c:ident, $fn:path, $intype:ty, [$($len:literal),+$(,)?]) => {{
$(defbenches!(@ops $c, $fn, $intype, $len);)+
}};
(@ops $c:ident, $fn:path, $intype:ty, $len:literal) => {{
let a: [$intype; $len] = OsRng.gen();
let b: [$intype; $len] = OsRng.gen();
defbenches!(@final $c, $fn, $intype, $len, +, a, b);
defbenches!(@final $c, $fn, $intype, $len, -, a, b);
defbenches!(@final $c, $fn, $intype, $len, *, a, b);
defbenches!(@final $c, $fn, $intype, $len, &, a, b);
defbenches!(@final $c, $fn, $intype, $len, |, a, b);
defbenches!(@final $c, $fn, $intype, $len, ^, a, b);
}};
(@final $c:ident, $fn:path, $intype:ty, $len:literal, $op:tt, $a:ident, $b:ident) => {{
$c.bench_function(
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|| black_box($fn($a, $b, |a, b| b $op a)),
|| black_box($fn($a, $b, |a, b| a $op b)),
|b| {
b.iter(|| black_box($fn($a, $b, |a, b| a $op b)));
},
);
}};
}
fn benchmark_primitives(c: &mut Criterion) {
defbenches!(c, zip_with, u8, [8, 16, 32, 64, 128]);
defbenches!(c, zip_map_std, u8, [8, 16, 32, 64, 128]);
defbenches!(c, zip_map_fl, u8, [8, 16, 32, 64, 128]);
defbenches!(c, zip_with, u16, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_map_std, u16, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_map_fl, u16, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_with, u32, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_map_std, u32, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_map_fl, u32, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_with, u64, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_map_std, u64, [8, 16, 32, 64, 128, 256, 512]);
defbenches!(c, zip_map_fl, u64, [8, 16, 32, 64, 128, 256, 512]);
}
struct ZipWithGuard<T, U, const N: usize> {
a: *mut [T; N],
b: *mut [U; N],
moved: usize,
}
impl<T, U, const N: usize> Drop for ZipWithGuard<T, U, N> {
fn drop(&mut self) {
if needs_drop::<T>() || needs_drop::<U>() {
for i in self.moved + 1..N {
unsafe {
drop(self.a.cast::<T>().add(i).read());
drop(self.b.cast::<U>().add(i).read());
}
}
}
}
}
pub fn zip_with<T, U, V, F: FnMut(T, U) -> V, const N: usize>(
a: [T; N],
b: [U; N],
mut f: F,
) -> [V; N] {
let aref = &a as *const _ as *mut [ManuallyDrop<T>; N];
forget(a);
let bref = &b as *const _ as *mut [ManuallyDrop<U>; N];
forget(b);
let mut guard = ZipWithGuard {
a: aref,
b: bref,
moved: 0,
};
let mut out: MaybeUninit<[V; N]> = unsafe { MaybeUninit::uninit().assume_init() };
let out_ptr = out.as_mut_ptr().cast::<MaybeUninit<V>>();
while guard.moved < N {
let i = guard.moved;
unsafe {
*out_ptr.add(i) = MaybeUninit::new(f(
guard.a.cast::<T>().add(i).read(),
guard.b.cast::<U>().add(i).read(),
));
}
guard.moved += 1;
}
unsafe { out.assume_init() }
}
fn zip_map_fl<T: Copy, U: Copy, V, F: FnMut(T, U) -> V, const N: usize>(
a: [T; N],
b: [U; N],
mut f: F,
) -> [V; N] {
let mut out: [MaybeUninit<V>; N] = MaybeUninit::uninit_array();
for i in 0..N {
out[i] = MaybeUninit::new(f(a[i], b[i]));
}
unsafe { MaybeUninit::array_assume_init(out) }
}
fn zip_map_std<T, U, V, F: Fn(T, U) -> V, const N: usize>(a: [T; N], b: [U; N], f: F) -> [V; N] {
a.zip(b).map(|(a, b)| f(a, b))
}
criterion_group! {
name = benches;
config = Criterion::default();
targets = benchmark_primitives
}
criterion_main! {
benches
}
I expected to see this happen: The compiler compiles successfully or outputs an error message.
Instead, this happened: The code, as provided below, appears to encounter a hang
Meta
rustc --version --verbose
:
rustc 1.73.0 (cc66ad468 2023-10-03)
binary: rustc
commit-hash: cc66ad468955717ab92600c770da8c1601a4ff33
commit-date: 2023-10-03
host: x86_64-unknown-linux-gnu
release: 1.73.0
LLVM version: 17.0.2
The same problem is reproduced on the nightly version(1.75.0-nightly (d627cf0 2023-10-10)) as well. (and -Ztrait-solver=next
cannot solve it)
what's more, to get more information,I also tried '-Z time-passes' (using nighly version):
$ rustc -C opt-level=0 -Ztime-passes -Ztrait-solver=next /home/interesting/hang_10.rs
time: 0.002; rss: 30MB -> 32MB ( +2MB) parse_crate
time: 0.000; rss: 35MB -> 35MB ( +1MB) setup_global_ctxt
time: 0.072; rss: 35MB -> 75MB ( +40MB) expand_crate
time: 0.072; rss: 35MB -> 75MB ( +40MB) macro_expand_crate
error[E0433]: failed to resolve: maybe a missing crate `rand`?
--> /home/interesting/hang_10.rs:4:5
|
4 | use rand::{rngs::OsRng, Rng};
| ^^^^ maybe a missing crate `rand`?
|
= help: consider adding `extern crate rand` to use the `rand` crate
error[E0432]: unresolved import `criterion`
--> /home/interesting/hang_10.rs:3:5
|
3 | use criterion::{black_box, criterion_group, criterion_main, Criterion};
| ^^^^^^^^^ maybe a missing crate `criterion`?
|
= help: consider adding `extern crate criterion` to use the `criterion` crate
error[E0432]: unresolved import `rand`
--> /home/interesting/hang_10.rs:4:5
|
4 | use rand::{rngs::OsRng, Rng};
| ^^^^ maybe a missing crate `rand`?
|
= help: consider adding `extern crate rand` to use the `rand` crate
time: 0.010; rss: 75MB -> 90MB ( +15MB) finalize_imports
error: cannot determine resolution for the macro `criterion_group`
--> /home/interesting/hang_10.rs:118:1
|
118 | criterion_group! {
| ^^^^^^^^^^^^^^^
|
= note: import resolution is stuck, try simplifying macro imports
error: cannot determine resolution for the macro `criterion_main`
--> /home/interesting/hang_10.rs:123:1
|
123 | criterion_main! {
| ^^^^^^^^^^^^^^
|
= note: import resolution is stuck, try simplifying macro imports
time: 0.004; rss: 90MB -> 94MB ( +4MB) finalize_macro_resolutions
time: 0.038; rss: 94MB -> 103MB ( +9MB) late_resolve_crate
error[E0425]: cannot find function `needs_drop` in this scope
--> /home/interesting/hang_10.rs:66:12
|
66 | if needs_drop::<T>() || needs_drop::<U>() {
| ^^^^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use std::mem::needs_drop;
|
error[E0425]: cannot find function `needs_drop` in this scope
--> /home/interesting/hang_10.rs:66:33
|
66 | if needs_drop::<T>() || needs_drop::<U>() {
| ^^^^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use std::mem::needs_drop;
|
error[E0412]: cannot find type `ManuallyDrop` in this scope
--> /home/interesting/hang_10.rs:81:40
|
81 | let aref = &a as *const _ as *mut [ManuallyDrop<T>; N];
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use std::mem::ManuallyDrop;
|
error[E0425]: cannot find function `forget` in this scope
--> /home/interesting/hang_10.rs:82:5
|
82 | forget(a);
| ^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use std::mem::forget;
|
error[E0412]: cannot find type `ManuallyDrop` in this scope
--> /home/interesting/hang_10.rs:83:40
|
83 | let bref = &b as *const _ as *mut [ManuallyDrop<U>; N];
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use std::mem::ManuallyDrop;
|
error[E0425]: cannot find function `forget` in this scope
--> /home/interesting/hang_10.rs:84:5
|
84 | forget(b);
| ^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use std::mem::forget;
|
time: 0.060; rss: 75MB -> 103MB ( +27MB) resolve_crate
time: 0.008; rss: 124MB -> 124MB ( +0MB) drop_ast
error[E0601]: `main` function not found in crate `hang_10`
--> /home/interesting/hang_10.rs:125:2
|
125 | }
| ^ consider adding a `main` function to `/home/interesting/hang_10.rs`
time: 0.080; rss: 103MB -> 124MB ( +21MB) looking_for_entry_point
error[E0635]: unknown feature `array_zip`
--> /home/interesting/hang_10.rs:2:12
|
2 | #![feature(array_zip, maybe_uninit_array_assume_init, maybe_uninit_uninit_array)]
| ^^^^^^^^^
time: 0.106; rss: 103MB -> 124MB ( +21MB) misc_checking_1
time: 0.024; rss: 124MB -> 127MB ( +3MB) type_collecting
time: 0.002; rss: 127MB -> 130MB ( +3MB) wf_checking
Backtrace
<backtrace>