1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
use std::{ fmt::{self, Display}, marker::PhantomData, mem, ops::Deref, }; use crate::std_types::RStr; pub use self::inner::StaticStr; // A type-level assertion that &[u8] is 2 usizes large. type Assertions = [u8; { const USIZE_SIZE: usize = mem::size_of::<usize>(); const SAME_SIZE: bool = 2 * USIZE_SIZE == mem::size_of::<&'static str>(); const SAME_ALIGN: bool = mem::align_of::<[usize; 2]>() == mem::align_of::<&'static str>(); ((SAME_SIZE & SAME_ALIGN) as usize) - 1 }]; mod inner { use super::*; /// Wrapper type around `&'static str` as a workaround for the /// non-stable-constness of str::len. #[derive(Copy, Clone, StableAbi)] #[sabi(inside_abi_stable_crate)] #[repr(C)] pub struct StaticStr { #[sabi(unsafe_opaque_field)] s: &'static str, #[sabi(unsafe_opaque_field)] conversion: RStrFromStaticStr, _private_initializer: PhantomData<Assertions>, } impl StaticStr { /// Creates a StaticStr from a `&'static str` #[inline] pub const fn new(s: &'static str) -> Self { StaticStr { s, conversion: RStrFromStaticStr::NEW, _private_initializer: PhantomData, } } /// Gets the `&'static str` back. #[inline] pub fn as_str(&self) -> &'static str { self.as_rstr().into() } /// Converts the internal `&'static str` into a `RStr<'static>`. #[inline] pub fn as_rstr(&self) -> RStr<'static> { let s = (&self.s) as *const &'static str as *const [usize; 2]; unsafe { (self.conversion.conversion)(s) } } } #[derive(Copy, Clone)] #[repr(transparent)] pub struct RStrFromStaticStr { conversion: unsafe extern "C" fn(*const [usize; 2]) -> RStr<'static>, } impl RStrFromStaticStr { const NEW: Self = { RStrFromStaticStr { conversion: str_conversion, } }; } } #[doc(hidden)] /* This is the error that not marking this as pub causes: error: internal compiler error: src/librustc_mir/monomorphize/collector.rs:747: Cannot create local mono-item for DefId(16/0:21 ~ abi_stable[af95]::static_str[0]::str_conversion[0]) thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:588:9 note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. stack backtrace: 0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39 1: std::sys_common::backtrace::_print at src/libstd/sys_common/backtrace.rs:70 2: std::panicking::default_hook::{{closure}} at src/libstd/sys_common/backtrace.rs:58 at src/libstd/panicking.rs:200 3: std::panicking::default_hook at src/libstd/panicking.rs:215 4: rustc::util::common::panic_hook 5: core::ops::function::Fn::call 6: proc_macro::bridge::client::<impl proc_macro::bridge::Bridge<'_>>::enter::{{closure}}::{{closure}} at src/libproc_macro/bridge/client.rs:301 7: std::panicking::rust_panic_with_hook at src/libstd/panicking.rs:482 8: std::panicking::begin_panic 9: rustc_errors::Handler::bug 10: rustc::util::bug::opt_span_bug_fmt::{{closure}} 11: rustc::ty::context::tls::with_opt::{{closure}} 12: rustc::ty::context::tls::with_context_opt 13: rustc::ty::context::tls::with_opt 14: rustc::util::bug::opt_span_bug_fmt 15: rustc::util::bug::bug_fmt 16: rustc_mir::monomorphize::collector::should_monomorphize_locally 17: rustc_mir::monomorphize::collector::collect_miri 18: rustc_mir::monomorphize::collector::collect_miri 19: rustc_mir::monomorphize::collector::collect_miri 20: rustc_mir::monomorphize::collector::collect_const 21: <rustc_mir::monomorphize::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_const 22: <rustc_mir::monomorphize::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_rvalue 23: rustc_mir::monomorphize::collector::collect_items_rec 24: rustc_mir::monomorphize::collector::collect_items_rec 25: rustc_mir::monomorphize::collector::collect_items_rec 26: rustc_mir::monomorphize::collector::collect_items_rec 27: rustc_mir::monomorphize::collector::collect_items_rec 28: rustc_mir::monomorphize::collector::collect_items_rec 29: rustc_mir::monomorphize::collector::collect_items_rec 30: rustc_mir::monomorphize::collector::collect_items_rec 31: rustc_mir::monomorphize::collector::collect_crate_mono_items::{{closure}} 32: rustc::util::common::time 33: rustc_mir::monomorphize::collector::collect_crate_mono_items 34: rustc::util::common::time 35: rustc_mir::monomorphize::partitioning::collect_and_partition_mono_items 36: rustc::ty::query::__query_compute::collect_and_partition_mono_items 37: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::collect_and_partition_mono_items<'tcx>>::compute 38: rustc::dep_graph::graph::DepGraph::with_task_impl 39: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with 40: rustc_codegen_ssa::base::codegen_crate 41: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_utils::codegen_backend::CodegenBackend>::codegen_crate 42: rustc::util::common::time 43: rustc_driver::driver::phase_4_codegen 44: rustc_driver::driver::compile_input::{{closure}} 45: <std::thread::local::LocalKey<T>>::with 46: rustc::ty::context::TyCtxt::create_and_enter 47: rustc_driver::driver::compile_input 48: rustc_driver::run_compiler_with_pool 49: <scoped_tls::ScopedKey<T>>::set 50: rustc_driver::run_compiler 51: <scoped_tls::ScopedKey<T>>::set query stack during panic: #0 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack error: aborting due to previous error note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports note: rustc 1.33.0 (2aa4c46cf 2019-02-28) running on i686-unknown-linux-gnu note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin note: some of the compiler flags provided by cargo are hidden error: Could not compile `abi_stable`. */ pub unsafe extern "C" fn str_conversion(s: *const [usize; 2]) -> RStr<'static> { let str_: &'static str = *(s as *const &'static str); RStr::from(str_) } impl Deref for StaticStr { type Target = str; fn deref(&self) -> &str { self.as_str() } } impl Display for StaticStr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Display::fmt(&**self, f) } } shared_impls! { mod=slice_impls new_type=StaticStr[][], original_type=str, }