Skip to content

Mapping to black_box crashes compiler #98299

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
SUPERCILEX opened this issue Jun 20, 2022 · 5 comments · Fixed by #98329
Closed

Mapping to black_box crashes compiler #98299

SUPERCILEX opened this issue Jun 20, 2022 · 5 comments · Fixed by #98329
Assignees
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-medium Medium priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@SUPERCILEX
Copy link
Contributor

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
@SUPERCILEX SUPERCILEX added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 20, 2022
@SUPERCILEX
Copy link
Contributor Author

Removing .map(|cstr| black_box(cstr)); seems to fix it.

@SNCPlay42
Copy link
Contributor

Reduced, with no nightly features (playground):

use std::convert::TryFrom;

pub fn test_usage(p: ()) {
    SmallCString::try_from(p).map(|cstr| cstr);
}

pub struct SmallCString<const N: usize> {}

impl<const N: usize> TryFrom<()> for SmallCString<N> {
    type Error = ();

    fn try_from(path: ()) -> Result<Self, Self::Error> {
        unimplemented!();
    }
}

Output on stable and beta:

error[E0282]: type annotations needed
 --> <source>:4:31
  |
4 |     SmallCString::try_from(p).map(|cstr| cstr);
  |                               ^^^ cannot infer type for enum `Result<SmallCString<{_: usize}>, ()>`

@rustbot label regression-from-stable-to-nightly

@rustbot rustbot added regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jun 20, 2022
@apiraino
Copy link
Contributor

bisection cc: @oli-obk

searched nightlies: from nightly-2022-01-01 to nightly-2022-06-20
regressed nightly: nightly-2022-06-09
searched commit range: 5435ed6...7466d54
regressed commit: b17e9d7

bisected with cargo-bisect-rustc v0.6.3

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start=2022-01-01 --regress ice 

@apiraino
Copy link
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-medium

@rustbot rustbot added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jun 20, 2022
@oli-obk oli-obk self-assigned this Jun 20, 2022
@JohnTitor
Copy link
Member

Another snippet from #98300 (comment):

struct S<const K: usize> {
    xs: Vec<[u8; K]>,
}

impl<const K: usize> S<K> {
    fn f(&self, a: [u8; K], cs: i32) -> S<K> {
        g(a).map(|ws| S{xs: ws.to_vec()})
    }
}

fn main() {}

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-medium Medium priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants