Closed
Description
Code
https://godbolt.org/z/fhv5voE5E
#![feature(core_intrinsics)]
#![feature(untagged_unions)]
#![feature(bench_black_box)]
use std::convert::{TryFrom, TryInto};
use std::error::Error;
use std::ffi::{CStr, CString};
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ops::Deref;
use std::path::Path;
use std::slice;
use std::{io, mem, ptr};
use std::os::unix::ffi::OsStrExt;
use std::hint::black_box;
fn test_usage(p: &Path) {
SmallCString::try_from(p).map(|cstr| black_box(cstr));
}
// Make sure to stay under 4096 so the compiler doesn't insert a probe frame:
// https://docs.rs/compiler_builtins/latest/compiler_builtins/probestack/index.html
#[cfg(not(target_os = "espidf"))]
const MAX_STACK_ALLOCATION: usize = 384;
#[cfg(target_os = "espidf")]
const MAX_STACK_ALLOCATION: usize = 32;
union Data<const N: usize> {
stack: MaybeUninit<[u8; N]>,
heap: ManuallyDrop<CString>,
}
#[derive(Debug)]
pub struct UnexpectedNulError {}
impl<E: Error> From<E> for UnexpectedNulError {
fn from(_: E) -> Self {
UnexpectedNulError {}
}
}
impl From<UnexpectedNulError> for io::Error {
fn from(_: UnexpectedNulError) -> Self {
todo!()
}
}
/// Fast, immutable CStr view allocated on the stack when possible with a fallback heap allocation.
pub struct SmallCString<const N: usize = MAX_STACK_ALLOCATION> {
len: usize,
data: Data<N>,
}
impl<const N: usize> TryFrom<&Path> for SmallCString<N> {
type Error = UnexpectedNulError;
fn try_from(path: &Path) -> Result<Self, Self::Error> {
path.as_os_str().as_bytes().try_into()
}
}
impl<const N: usize> TryFrom<&[u8]> for SmallCString<N> {
type Error = UnexpectedNulError;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
if bytes.len() >= N {
return Self::alloc_cstring(bytes);
}
// Validate the bytes
if bytes.iter().any(|b|*b == 0) {
return Self::invalid_bytes_err();
}
let mut buf = MaybeUninit::uninit();
let buf_ptr = buf.as_mut_ptr() as *mut u8;
unsafe {
ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
buf_ptr.add(bytes.len()).write(0);
}
Ok(SmallCString { data: Data { stack: buf }, len: bytes.len() + 1 })
}
}
impl<const N: usize> SmallCString<N> {
#[cold]
#[inline(never)]
fn alloc_cstring(bytes: &[u8]) -> Result<SmallCString<N>, UnexpectedNulError> {
Ok(SmallCString {
data: Data { heap: ManuallyDrop::new(CString::new(bytes)?) },
len: bytes.len() + 1,
})
}
#[cold]
#[inline(never)]
fn invalid_bytes_err() -> Result<SmallCString<N>, UnexpectedNulError> {
Err(UnexpectedNulError {})
}
}
impl Deref for SmallCString {
type Target = CStr;
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
impl<const N: usize> AsRef<CStr> for SmallCString<N> {
fn as_ref(&self) -> &CStr {
unsafe {
if self.len <= N {
let path = slice::from_raw_parts(self.data.stack.as_ptr() as *const u8, self.len);
// SAFETY: the bytes were validated in ::new with memchr
CStr::from_bytes_with_nul_unchecked(mem::transmute(path))
} else {
self.data.heap.as_c_str()
}
}
}
}
impl<const N: usize> Drop for SmallCString<N> {
fn drop(&mut self) {
unsafe {
if self.len > N {
ManuallyDrop::drop(&mut self.data.heap)
}
}
}
}
Error output
error: internal compiler error: /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/compiler/rustc_infer/src/infer/nll_relate/mod.rs:665:17: unexpected inference var Const { ty: usize, kind: Infer(Var(_#0c)) }
thread 'rustc' panicked at 'Box<dyn Any>', /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/compiler/rustc_errors/src/lib.rs:1391:9
stack backtrace:
0: 0x7ffbeacfbfad - std::backtrace_rs::backtrace::libunwind::trace::h72e50fb92da0949e
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
1: 0x7ffbeacfbfad - std::backtrace_rs::backtrace::trace_unsynchronized::hbae920ae073134bd
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x7ffbeacfbfad - std::sys_common::backtrace::_print_fmt::h75c75895c2dc7a02
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/sys_common/backtrace.rs:66:5
3: 0x7ffbeacfbfad - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h22f51d8130e18285
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/sys_common/backtrace.rs:45:22
4: 0x7ffbead57d7c - core::fmt::write::h34460b9cb19018a8
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/core/src/fmt/mod.rs:1196:17
5: 0x7ffbeaced6d1 - std::io::Write::write_fmt::hdf3a96965a9806fb
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/io/mod.rs:1654:15
6: 0x7ffbeacfec85 - std::sys_common::backtrace::_print::h1bcfb7d99cf40e04
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/sys_common/backtrace.rs:48:5
7: 0x7ffbeacfec85 - std::sys_common::backtrace::print::h65fadbbd0f516d99
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/sys_common/backtrace.rs:35:9
8: 0x7ffbeacfec85 - std::panicking::default_hook::{{closure}}::h20497521a47f65d6
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/panicking.rs:295:22
9: 0x7ffbeacfe9a6 - std::panicking::default_hook::h9d02598e8fa9348e
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/panicking.rs:314:9
10: 0x7ffbeb4d7d41 - rustc_driver[5d44a3b446ca22b6]::DEFAULT_HOOK::{closure#0}::{closure#0}
11: 0x7ffbeacff35a - std::panicking::rust_panic_with_hook::ha09262393f7932d5
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/panicking.rs:702:17
12: 0x7ffbec5899f1 - std[3d85facbacbebd2b]::panicking::begin_panic::<rustc_errors[3cd36318e3613d20]::ExplicitBug>::{closure#0}
13: 0x7ffbec5894d6 - std[3d85facbacbebd2b]::sys_common::backtrace::__rust_end_short_backtrace::<std[3d85facbacbebd2b]::panicking::begin_panic<rustc_errors[3cd36318e3613d20]::ExplicitBug>::{closure#0}, !>
14: 0x7ffbec5005a6 - std[3d85facbacbebd2b]::panicking::begin_panic::<rustc_errors[3cd36318e3613d20]::ExplicitBug>
15: 0x7ffbec51b2f6 - std[3d85facbacbebd2b]::panic::panic_any::<rustc_errors[3cd36318e3613d20]::ExplicitBug>
16: 0x7ffbec51b205 - <rustc_errors[3cd36318e3613d20]::HandlerInner>::bug::<&alloc[4ac2d0ae555384fc]::string::String>
17: 0x7ffbec51af60 - <rustc_errors[3cd36318e3613d20]::Handler>::bug::<&alloc[4ac2d0ae555384fc]::string::String>
18: 0x7ffbec59866d - rustc_middle[4273fc7dbb432e13]::ty::context::tls::with_opt::<rustc_middle[4273fc7dbb432e13]::util::bug::opt_span_bug_fmt<rustc_span[77aaf738596ebdf0]::span_encoding::Span>::{closure#0}, ()>
19: 0x7ffbec5987a6 - rustc_middle[4273fc7dbb432e13]::util::bug::opt_span_bug_fmt::<rustc_span[77aaf738596ebdf0]::span_encoding::Span>
20: 0x7ffbec598723 - rustc_middle[4273fc7dbb432e13]::util::bug::bug_fmt
21: 0x7ffbeb869f1d - <rustc_infer[3a3407b7085d6b2d]::infer::nll_relate::TypeRelating<rustc_infer[3a3407b7085d6b2d]::infer::canonical::query_response::QueryTypeRelatingDelegate> as rustc_middle[4273fc7dbb432e13]::ty::relate::TypeRelation>::consts
22: 0x7ffbeb88d14c - <rustc_infer[3a3407b7085d6b2d]::infer::InferCtxt>::instantiate_nll_query_response_and_region_obligations::<alloc[4ac2d0ae555384fc]::vec::Vec<rustc_middle[4273fc7dbb432e13]::traits::query::OutlivesBound>>
23: 0x7ffbecac2bee - <rustc_infer[3a3407b7085d6b2d]::infer::outlives::env::OutlivesEnvironment as rustc_typeck[51fdd47d43b4ce75]::check::regionck::OutlivesEnvironmentExt>::add_implied_bounds
24: 0x7ffbecb77e91 - <rustc_typeck[51fdd47d43b4ce75]::check::regionck::RegionCtxt>::visit_fn_body
25: 0x7ffbecb7bbba - <rustc_typeck[51fdd47d43b4ce75]::check::regionck::RegionCtxt as rustc_hir[a7fd3971f7dac1b2]::intravisit::Visitor>::visit_expr
26: 0x7ffbecb7a7d9 - <rustc_typeck[51fdd47d43b4ce75]::check::regionck::RegionCtxt as rustc_hir[a7fd3971f7dac1b2]::intravisit::Visitor>::visit_expr
27: 0x7ffbecb7a4ae - <rustc_typeck[51fdd47d43b4ce75]::check::regionck::RegionCtxt as rustc_hir[a7fd3971f7dac1b2]::intravisit::Visitor>::visit_expr
28: 0x7ffbecb7823e - <rustc_typeck[51fdd47d43b4ce75]::check::regionck::RegionCtxt>::visit_fn_body
29: 0x7ffbecb3658f - <rustc_infer[3a3407b7085d6b2d]::infer::InferCtxtBuilder>::enter::<&rustc_middle[4273fc7dbb432e13]::ty::context::TypeckResults, <rustc_typeck[51fdd47d43b4ce75]::check::inherited::InheritedBuilder>::enter<rustc_typeck[51fdd47d43b4ce75]::check::typeck_with_fallback<rustc_typeck[51fdd47d43b4ce75]::check::typeck::{closure#0}>::{closure#1}, &rustc_middle[4273fc7dbb432e13]::ty::context::TypeckResults>::{closure#0}>
30: 0x7ffbecae09da - rustc_typeck[51fdd47d43b4ce75]::check::typeck
31: 0x7ffbed0854e4 - rustc_query_system[5d3fbf9a023977e0]::query::plumbing::try_execute_query::<rustc_query_impl[5a39a0883fba8866]::plumbing::QueryCtxt, rustc_query_system[5d3fbf9a023977e0]::query::caches::DefaultCache<rustc_span[77aaf738596ebdf0]::def_id::LocalDefId, &rustc_middle[4273fc7dbb432e13]::ty::context::TypeckResults>>
32: 0x7ffbed05ba6e - <rustc_query_impl[5a39a0883fba8866]::Queries as rustc_middle[4273fc7dbb432e13]::ty::query::QueryEngine>::typeck
33: 0x7ffbecae0b6f - rustc_typeck[51fdd47d43b4ce75]::check::typeck
34: 0x7ffbed0854e4 - rustc_query_system[5d3fbf9a023977e0]::query::plumbing::try_execute_query::<rustc_query_impl[5a39a0883fba8866]::plumbing::QueryCtxt, rustc_query_system[5d3fbf9a023977e0]::query::caches::DefaultCache<rustc_span[77aaf738596ebdf0]::def_id::LocalDefId, &rustc_middle[4273fc7dbb432e13]::ty::context::TypeckResults>>
35: 0x7ffbed05ba6e - <rustc_query_impl[5a39a0883fba8866]::Queries as rustc_middle[4273fc7dbb432e13]::ty::query::QueryEngine>::typeck
36: 0x7ffbecb905c8 - <rustc_middle[4273fc7dbb432e13]::hir::map::Map>::par_body_owners::<rustc_typeck[51fdd47d43b4ce75]::check::typeck_item_bodies::{closure#0}>
37: 0x7ffbed93794c - rustc_typeck[51fdd47d43b4ce75]::check::typeck_item_bodies
38: 0x7ffbedc2979c - rustc_query_system[5d3fbf9a023977e0]::query::plumbing::try_execute_query::<rustc_query_impl[5a39a0883fba8866]::plumbing::QueryCtxt, rustc_query_system[5d3fbf9a023977e0]::query::caches::DefaultCache<(), ()>>
39: 0x7ffbedc56271 - rustc_query_system[5d3fbf9a023977e0]::query::plumbing::get_query::<rustc_query_impl[5a39a0883fba8866]::queries::typeck_item_bodies, rustc_query_impl[5a39a0883fba8866]::plumbing::QueryCtxt>
40: 0x7ffbed972be3 - <rustc_session[eca3025ea6d0d057]::session::Session>::time::<(), rustc_typeck[51fdd47d43b4ce75]::check_crate::{closure#7}>
41: 0x7ffbed94ef43 - rustc_typeck[51fdd47d43b4ce75]::check_crate
42: 0x7ffbed6bfdc7 - rustc_interface[60df96b8be8199a0]::passes::analysis
43: 0x7ffbedc1eccf - rustc_query_system[5d3fbf9a023977e0]::query::plumbing::try_execute_query::<rustc_query_impl[5a39a0883fba8866]::plumbing::QueryCtxt, rustc_query_system[5d3fbf9a023977e0]::query::caches::DefaultCache<(), core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>>
44: 0x7ffbedc687ce - rustc_query_system[5d3fbf9a023977e0]::query::plumbing::get_query::<rustc_query_impl[5a39a0883fba8866]::queries::analysis, rustc_query_impl[5a39a0883fba8866]::plumbing::QueryCtxt>
45: 0x7ffbed6a3a37 - <rustc_interface[60df96b8be8199a0]::passes::QueryContext>::enter::<rustc_driver[5d44a3b446ca22b6]::run_compiler::{closure#1}::{closure#2}::{closure#3}, core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>
46: 0x7ffbed68dbff - <rustc_interface[60df96b8be8199a0]::interface::Compiler>::enter::<rustc_driver[5d44a3b446ca22b6]::run_compiler::{closure#1}::{closure#2}, core[9a54cb3e01ba0ce9]::result::Result<core[9a54cb3e01ba0ce9]::option::Option<rustc_interface[60df96b8be8199a0]::queries::Linker>, rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>
47: 0x7ffbed6871cf - rustc_span[77aaf738596ebdf0]::with_source_map::<core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>, rustc_interface[60df96b8be8199a0]::interface::create_compiler_and_run<core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>, rustc_driver[5d44a3b446ca22b6]::run_compiler::{closure#1}>::{closure#1}>
48: 0x7ffbed68ea92 - <scoped_tls[c0f8d1e57fdb1e9d]::ScopedKey<rustc_span[77aaf738596ebdf0]::SessionGlobals>>::set::<rustc_interface[60df96b8be8199a0]::interface::run_compiler<core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>, rustc_driver[5d44a3b446ca22b6]::run_compiler::{closure#1}>::{closure#0}, core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>
49: 0x7ffbed6a40bf - std[3d85facbacbebd2b]::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface[60df96b8be8199a0]::util::run_in_thread_pool_with_globals<rustc_interface[60df96b8be8199a0]::interface::run_compiler<core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>, rustc_driver[5d44a3b446ca22b6]::run_compiler::{closure#1}>::{closure#0}, core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>::{closure#0}, core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>
50: 0x7ffbed6a4229 - <<std[3d85facbacbebd2b]::thread::Builder>::spawn_unchecked_<rustc_interface[60df96b8be8199a0]::util::run_in_thread_pool_with_globals<rustc_interface[60df96b8be8199a0]::interface::run_compiler<core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>, rustc_driver[5d44a3b446ca22b6]::run_compiler::{closure#1}>::{closure#0}, core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>::{closure#0}, core[9a54cb3e01ba0ce9]::result::Result<(), rustc_errors[3cd36318e3613d20]::ErrorGuaranteed>>::{closure#1} as core[9a54cb3e01ba0ce9]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
51: 0x7ffbead09293 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hed131aa6d8ddd60e
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/alloc/src/boxed.rs:1951:9
52: 0x7ffbead09293 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h5cfd39886a9bb055
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/alloc/src/boxed.rs:1951:9
53: 0x7ffbead09293 - std::sys::unix::thread::Thread::new::thread_start::h3f6b40ab851a8ecd
at /rustc/21e9336fe81a1fce364349bb7a35a0347c369f34/library/std/src/sys/unix/thread.rs:108:17
54: 0x7ffbeac33609 - start_thread
55: 0x7ffbeab56163 - clone
56: 0x0 - <unknown>
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
note: rustc 1.63.0-nightly (21e9336fe 2022-06-18) running on x86_64-unknown-linux-gnu
note: compiler flags: -C debuginfo=1 -C llvm-args=--x86-asm-syntax=intel --crate-type rlib -C opt-level=3
query stack during panic:
#0 [typeck] type-checking `test_usage`
#1 [typeck] type-checking `test_usage::{closure#0}`
#2 [typeck_item_bodies] type-checking all item bodies
#3 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error
Compiler returned: 101