Auto merge of #71593 - Dylan-DPC:rollup-ms7j94u, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #71421 (Add a function to turn Box<T> into Box<[T]>) - #71537 (Remove support for self-opening) - #71551 (Minor refactoring around IndexVec usage in generator transformation) - #71569 ([miri] Throw UB if target size and data size don't match) - #71576 (check that `AsRef` and `AsMut` are inlined) Failed merges: - #71558 (Cleanup and document `-Z tls-model` ) r? @ghost
This commit is contained in:
commit
e83f756349
@ -239,6 +239,16 @@ impl<T> Box<T> {
|
||||
pub fn pin(x: T) -> Pin<Box<T>> {
|
||||
(box x).into()
|
||||
}
|
||||
|
||||
/// Converts a `Box<T>` into a `Box<[T]>`
|
||||
///
|
||||
/// This conversion does not allocate on the heap and happens in place.
|
||||
///
|
||||
#[unstable(feature = "box_into_boxed_slice", issue = "71582")]
|
||||
pub fn into_boxed_slice(boxed: Box<T>) -> Box<[T]> {
|
||||
// *mut T and *mut [T; 1] have the same size and alignment
|
||||
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut [T; 1] as *mut [T]) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Box<[T]> {
|
||||
|
@ -205,7 +205,7 @@ pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
|
||||
}
|
||||
|
||||
fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
|
||||
let lib = DynamicLibrary::open(Some(path)).unwrap_or_else(|err| {
|
||||
let lib = DynamicLibrary::open(path).unwrap_or_else(|err| {
|
||||
let err = format!("couldn't load codegen backend {:?}: {:?}", path, err);
|
||||
early_error(ErrorOutputType::default(), &err);
|
||||
});
|
||||
|
@ -591,7 +591,7 @@ impl<'a> CrateLoader<'a> {
|
||||
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
let path = env::current_dir().unwrap().join(path);
|
||||
let lib = match DynamicLibrary::open(Some(&path)) {
|
||||
let lib = match DynamicLibrary::open(&path) {
|
||||
Ok(lib) => lib,
|
||||
Err(err) => self.sess.span_fatal(span, &err),
|
||||
};
|
||||
|
@ -16,10 +16,9 @@ impl Drop for DynamicLibrary {
|
||||
}
|
||||
|
||||
impl DynamicLibrary {
|
||||
/// Lazily open a dynamic library. When passed None it gives a
|
||||
/// handle to the calling process
|
||||
pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
|
||||
let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
|
||||
/// Lazily open a dynamic library.
|
||||
pub fn open(filename: &Path) -> Result<DynamicLibrary, String> {
|
||||
let maybe_library = dl::open(filename.as_os_str());
|
||||
|
||||
// The dynamic library must not be constructed if there is
|
||||
// an error opening the library so the destructor does not
|
||||
@ -57,24 +56,13 @@ mod dl {
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
|
||||
pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
|
||||
pub(super) fn open(filename: &OsStr) -> Result<*mut u8, String> {
|
||||
check_for_errors_in(|| unsafe {
|
||||
match filename {
|
||||
Some(filename) => open_external(filename),
|
||||
None => open_internal(),
|
||||
}
|
||||
let s = CString::new(filename.as_bytes()).unwrap();
|
||||
libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn open_external(filename: &OsStr) -> *mut u8 {
|
||||
let s = CString::new(filename.as_bytes()).unwrap();
|
||||
libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
|
||||
}
|
||||
|
||||
unsafe fn open_internal() -> *mut u8 {
|
||||
libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8
|
||||
}
|
||||
|
||||
fn check_for_errors_in<T, F>(f: F) -> Result<T, String>
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
@ -124,10 +112,10 @@ mod dl {
|
||||
|
||||
use winapi::shared::minwindef::HMODULE;
|
||||
use winapi::um::errhandlingapi::SetThreadErrorMode;
|
||||
use winapi::um::libloaderapi::{FreeLibrary, GetModuleHandleExW, GetProcAddress, LoadLibraryW};
|
||||
use winapi::um::libloaderapi::{FreeLibrary, GetProcAddress, LoadLibraryW};
|
||||
use winapi::um::winbase::SEM_FAILCRITICALERRORS;
|
||||
|
||||
pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
|
||||
pub(super) fn open(filename: &OsStr) -> Result<*mut u8, String> {
|
||||
// disable "dll load failed" error dialog.
|
||||
let prev_error_mode = unsafe {
|
||||
let new_error_mode = SEM_FAILCRITICALERRORS;
|
||||
@ -139,22 +127,9 @@ mod dl {
|
||||
prev_error_mode
|
||||
};
|
||||
|
||||
let result = match filename {
|
||||
Some(filename) => {
|
||||
let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect();
|
||||
let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8;
|
||||
ptr_result(result)
|
||||
}
|
||||
None => {
|
||||
let mut handle = ptr::null_mut();
|
||||
let succeeded = unsafe { GetModuleHandleExW(0, ptr::null(), &mut handle) };
|
||||
if succeeded == 0 {
|
||||
Err(io::Error::last_os_error().to_string())
|
||||
} else {
|
||||
Ok(handle as *mut u8)
|
||||
}
|
||||
}
|
||||
};
|
||||
let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect();
|
||||
let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8;
|
||||
let result = ptr_result(result);
|
||||
|
||||
unsafe {
|
||||
SetThreadErrorMode(prev_error_mode, ptr::null_mut());
|
||||
|
@ -1,32 +1,4 @@
|
||||
use super::*;
|
||||
use std::mem;
|
||||
|
||||
#[test]
|
||||
fn test_loading_atoi() {
|
||||
if cfg!(windows) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The C library does not need to be loaded since it is already linked in
|
||||
let lib = match DynamicLibrary::open(None) {
|
||||
Err(error) => panic!("Could not load self as module: {}", error),
|
||||
Ok(lib) => lib,
|
||||
};
|
||||
|
||||
let atoi: extern "C" fn(*const libc::c_char) -> libc::c_int = unsafe {
|
||||
match lib.symbol("atoi") {
|
||||
Err(error) => panic!("Could not load function atoi: {}", error),
|
||||
Ok(atoi) => mem::transmute::<*mut u8, _>(atoi),
|
||||
}
|
||||
};
|
||||
|
||||
let argument = CString::new("1383428980").unwrap();
|
||||
let expected_result = 0x52757374;
|
||||
let result = atoi(argument.as_ptr());
|
||||
if result != expected_result {
|
||||
panic!("atoi({:?}) != {} but equaled {} instead", argument, expected_result, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_errors_do_not_crash() {
|
||||
@ -39,7 +11,7 @@ fn test_errors_do_not_crash() {
|
||||
// Open /dev/null as a library to get an error, and make sure
|
||||
// that only causes an error, and not a crash.
|
||||
let path = Path::new("/dev/null");
|
||||
match DynamicLibrary::open(Some(&path)) {
|
||||
match DynamicLibrary::open(&path) {
|
||||
Err(_) => {}
|
||||
Ok(_) => panic!("Successfully opened the empty library."),
|
||||
}
|
||||
|
@ -360,6 +360,11 @@ pub enum UndefinedBehaviorInfo {
|
||||
InvalidUndefBytes(Option<Pointer>),
|
||||
/// Working with a local that is not currently live.
|
||||
DeadLocal,
|
||||
/// Data size is not equal to target size.
|
||||
ScalarSizeMismatch {
|
||||
target_size: u64,
|
||||
data_size: u64,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Debug for UndefinedBehaviorInfo {
|
||||
@ -421,6 +426,11 @@ impl fmt::Debug for UndefinedBehaviorInfo {
|
||||
"using uninitialized data, but this operation requires initialized memory"
|
||||
),
|
||||
DeadLocal => write!(f, "accessing a dead local variable"),
|
||||
ScalarSizeMismatch { target_size, data_size } => write!(
|
||||
f,
|
||||
"scalar size mismatch: expected {} bytes but got {} bytes instead",
|
||||
target_size, data_size
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -393,7 +393,12 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
|
||||
match self {
|
||||
Scalar::Raw { data, size } => {
|
||||
assert_eq!(target_size.bytes(), u64::from(size));
|
||||
if target_size.bytes() != u64::from(size) {
|
||||
throw_ub!(ScalarSizeMismatch {
|
||||
target_size: target_size.bytes(),
|
||||
data_size: u64::from(size),
|
||||
});
|
||||
}
|
||||
Scalar::check_data(data, size);
|
||||
Ok(data)
|
||||
}
|
||||
|
@ -210,8 +210,7 @@ struct TransformVisitor<'tcx> {
|
||||
remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
|
||||
|
||||
// A map from a suspension point in a block to the locals which have live storage at that point
|
||||
// FIXME(eddyb) This should use `IndexVec<BasicBlock, Option<_>>`.
|
||||
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
||||
storage_liveness: IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
|
||||
|
||||
// A list of suspension points, generated during the transform
|
||||
suspension_points: Vec<SuspensionPoint<'tcx>>,
|
||||
@ -338,7 +337,7 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
|
||||
resume,
|
||||
resume_arg,
|
||||
drop,
|
||||
storage_liveness: self.storage_liveness.get(&block).unwrap().clone(),
|
||||
storage_liveness: self.storage_liveness[block].clone().unwrap(),
|
||||
});
|
||||
|
||||
VariantIdx::new(state)
|
||||
@ -404,8 +403,7 @@ fn replace_local<'tcx>(
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::Other,
|
||||
};
|
||||
let new_local = Local::new(body.local_decls.len());
|
||||
body.local_decls.push(new_decl);
|
||||
let new_local = body.local_decls.push(new_decl);
|
||||
body.local_decls.swap(local, new_local);
|
||||
|
||||
RenameLocalVisitor { from: local, to: new_local, tcx }.visit_body(body);
|
||||
@ -431,7 +429,7 @@ struct LivenessInfo {
|
||||
|
||||
/// For every suspending block, the locals which are storage-live across
|
||||
/// that suspension point.
|
||||
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
||||
storage_liveness: IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
|
||||
}
|
||||
|
||||
fn locals_live_across_suspend_points(
|
||||
@ -472,7 +470,7 @@ fn locals_live_across_suspend_points(
|
||||
let mut liveness = liveness::liveness_of_locals(body);
|
||||
liveness::dump_mir(tcx, "generator_liveness", source, body_ref, &liveness);
|
||||
|
||||
let mut storage_liveness_map = FxHashMap::default();
|
||||
let mut storage_liveness_map = IndexVec::from_elem(None, body.basic_blocks());
|
||||
let mut live_locals_at_suspension_points = Vec::new();
|
||||
|
||||
for (block, data) in body.basic_blocks().iter_enumerated() {
|
||||
@ -502,7 +500,7 @@ fn locals_live_across_suspend_points(
|
||||
|
||||
// Store the storage liveness for later use so we can restore the state
|
||||
// after a suspension point
|
||||
storage_liveness_map.insert(block, storage_liveness);
|
||||
storage_liveness_map[block] = Some(storage_liveness);
|
||||
|
||||
requires_storage_cursor.seek_before(loc);
|
||||
let storage_required = requires_storage_cursor.get().clone();
|
||||
@ -690,7 +688,7 @@ fn compute_layout<'tcx>(
|
||||
) -> (
|
||||
FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
|
||||
GeneratorLayout<'tcx>,
|
||||
FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
||||
IndexVec<BasicBlock, Option<liveness::LiveVarSet>>,
|
||||
) {
|
||||
// Use a liveness analysis to compute locals which are live across a suspension point
|
||||
let LivenessInfo {
|
||||
@ -925,14 +923,12 @@ fn create_generator_drop_shim<'tcx>(
|
||||
}
|
||||
|
||||
fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock {
|
||||
let term_block = BasicBlock::new(body.basic_blocks().len());
|
||||
let source_info = source_info(body);
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: Vec::new(),
|
||||
terminator: Some(Terminator { source_info, kind }),
|
||||
is_cleanup: false,
|
||||
});
|
||||
term_block
|
||||
})
|
||||
}
|
||||
|
||||
fn insert_panic_block<'tcx>(
|
||||
@ -1030,9 +1026,8 @@ fn create_generator_resume_function<'tcx>(
|
||||
|
||||
// Poison the generator when it unwinds
|
||||
if can_unwind {
|
||||
let poison_block = BasicBlock::new(body.basic_blocks().len());
|
||||
let source_info = source_info(body);
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
let poison_block = body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)],
|
||||
terminator: Some(Terminator { source_info, kind: TerminatorKind::Resume }),
|
||||
is_cleanup: true,
|
||||
@ -1105,21 +1100,19 @@ fn source_info(body: &Body<'_>) -> SourceInfo {
|
||||
fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock {
|
||||
let return_block = insert_term_block(body, TerminatorKind::Return);
|
||||
|
||||
// Create a block to destroy an unresumed generators. This can only destroy upvars.
|
||||
let drop_clean = BasicBlock::new(body.basic_blocks().len());
|
||||
let term = TerminatorKind::Drop {
|
||||
location: Place::from(SELF_ARG),
|
||||
target: return_block,
|
||||
unwind: None,
|
||||
};
|
||||
let source_info = source_info(body);
|
||||
|
||||
// Create a block to destroy an unresumed generators. This can only destroy upvars.
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: Vec::new(),
|
||||
terminator: Some(Terminator { source_info, kind: term }),
|
||||
is_cleanup: false,
|
||||
});
|
||||
|
||||
drop_clean
|
||||
})
|
||||
}
|
||||
|
||||
/// An operation that can be performed on a generator.
|
||||
@ -1151,7 +1144,6 @@ fn create_cases<'tcx>(
|
||||
.filter_map(|point| {
|
||||
// Find the target for this suspension point, if applicable
|
||||
operation.target_block(point).map(|target| {
|
||||
let block = BasicBlock::new(body.basic_blocks().len());
|
||||
let mut statements = Vec::new();
|
||||
|
||||
// Create StorageLive instructions for locals with live storage
|
||||
@ -1186,7 +1178,7 @@ fn create_cases<'tcx>(
|
||||
}
|
||||
|
||||
// Then jump to the real target
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
let block = body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements,
|
||||
terminator: Some(Terminator {
|
||||
source_info,
|
||||
|
@ -76,7 +76,7 @@ fn dylink_registrar(
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
let path = env::current_dir().unwrap().join(&path);
|
||||
|
||||
let lib = match DynamicLibrary::open(Some(&path)) {
|
||||
let lib = match DynamicLibrary::open(&path) {
|
||||
Ok(lib) => lib,
|
||||
// this is fatal: there are almost certainly macros we need
|
||||
// inside this crate, so continue would spew "macro undefined"
|
||||
|
27
src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs
Normal file
27
src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs
Normal file
@ -0,0 +1,27 @@
|
||||
// EMIT_MIR rustc.a.Inline.after.mir
|
||||
pub fn a<T>(x: &mut [T]) -> &mut [T] {
|
||||
x.as_mut()
|
||||
}
|
||||
|
||||
// EMIT_MIR rustc.b.Inline.after.mir
|
||||
pub fn b<T>(x: &mut Box<T>) -> &mut T {
|
||||
x.as_mut()
|
||||
}
|
||||
|
||||
// EMIT_MIR rustc.c.Inline.after.mir
|
||||
pub fn c<T>(x: &[T]) -> &[T] {
|
||||
x.as_ref()
|
||||
}
|
||||
|
||||
// EMIT_MIR rustc.d.Inline.after.mir
|
||||
pub fn d<T>(x: &Box<T>) -> &T {
|
||||
x.as_ref()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut boxed = Box::new(1);
|
||||
println!("{:?}", a(&mut [1]));
|
||||
println!("{:?}", b(&mut boxed));
|
||||
println!("{:?}", c(&[1]));
|
||||
println!("{:?}", d(&boxed));
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
// MIR for `a` after Inline
|
||||
|
||||
fn a(_1: &mut [T]) -> &mut [T] {
|
||||
debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:2:13: 2:14
|
||||
let mut _0: &mut [T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:2:29: 2:37
|
||||
let mut _2: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
let mut _3: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6
|
||||
scope 1 {
|
||||
debug self => _4; // in scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
let mut _5: &mut [T]; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // bb0[0]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
StorageLive(_3); // bb0[1]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
StorageLive(_4); // bb0[2]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6
|
||||
_4 = &mut (*_1); // bb0[3]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6
|
||||
StorageLive(_5); // bb0[4]: scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
_5 = _4; // bb0[5]: scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
_3 = _5; // bb0[6]: scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
StorageDead(_5); // bb0[7]: scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
_2 = &mut (*_3); // bb0[8]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
StorageDead(_4); // bb0[9]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:14: 3:15
|
||||
_0 = &mut (*_2); // bb0[10]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15
|
||||
StorageDead(_3); // bb0[11]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:1: 4:2
|
||||
StorageDead(_2); // bb0[12]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:1: 4:2
|
||||
return; // bb0[13]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:2: 4:2
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// MIR for `b` after Inline
|
||||
|
||||
fn b(_1: &mut std::boxed::Box<T>) -> &mut T {
|
||||
debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:7:13: 7:14
|
||||
let mut _0: &mut T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:7:32: 7:38
|
||||
let mut _2: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
let mut _3: &mut T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
let mut _4: &mut std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:6
|
||||
scope 1 {
|
||||
debug self => _4; // in scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
let mut _5: &mut T; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
let mut _6: &mut T; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // bb0[0]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
StorageLive(_3); // bb0[1]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
StorageLive(_4); // bb0[2]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:6
|
||||
_4 = &mut (*_1); // bb0[3]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:6
|
||||
StorageLive(_5); // bb0[4]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
StorageLive(_6); // bb0[5]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_6 = &mut (*(*_4)); // bb0[6]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_5 = _6; // bb0[7]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_3 = _5; // bb0[8]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
StorageDead(_6); // bb0[9]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
StorageDead(_5); // bb0[10]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_2 = &mut (*_3); // bb0[11]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
StorageDead(_4); // bb0[12]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:14: 8:15
|
||||
_0 = &mut (*_2); // bb0[13]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15
|
||||
StorageDead(_3); // bb0[14]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:1: 9:2
|
||||
StorageDead(_2); // bb0[15]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:1: 9:2
|
||||
return; // bb0[16]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:2: 9:2
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
// MIR for `c` after Inline
|
||||
|
||||
fn c(_1: &[T]) -> &[T] {
|
||||
debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:12:13: 12:14
|
||||
let mut _0: &[T]; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:12:25: 12:29
|
||||
let _2: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15
|
||||
let mut _3: &[T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:6
|
||||
scope 1 {
|
||||
debug self => _3; // in scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // bb0[0]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15
|
||||
StorageLive(_3); // bb0[1]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:6
|
||||
_3 = &(*_1); // bb0[2]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:6
|
||||
_2 = _3; // bb0[3]: scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL
|
||||
_0 = &(*_2); // bb0[4]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:5: 13:15
|
||||
StorageDead(_3); // bb0[5]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:13:14: 13:15
|
||||
StorageDead(_2); // bb0[6]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:14:1: 14:2
|
||||
return; // bb0[7]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:14:2: 14:2
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
// MIR for `d` after Inline
|
||||
|
||||
fn d(_1: &std::boxed::Box<T>) -> &T {
|
||||
debug x => _1; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:17:13: 17:14
|
||||
let mut _0: &T; // return place in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:17:28: 17:30
|
||||
let _2: &T; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
|
||||
let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:6
|
||||
scope 1 {
|
||||
debug self => _3; // in scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
let _4: &T; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // bb0[0]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
|
||||
StorageLive(_3); // bb0[1]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:6
|
||||
_3 = &(*_1); // bb0[2]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:6
|
||||
StorageLive(_4); // bb0[3]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_4 = &(*(*_3)); // bb0[4]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_2 = _4; // bb0[5]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
StorageDead(_4); // bb0[6]: scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL
|
||||
_0 = &(*_2); // bb0[7]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15
|
||||
StorageDead(_3); // bb0[8]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:14: 18:15
|
||||
StorageDead(_2); // bb0[9]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:1: 19:2
|
||||
return; // bb0[10]: scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:2: 19:2
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ use std::path::Path;
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let path = Path::new("libdylib.so");
|
||||
let a = DynamicLibrary::open(Some(&path)).unwrap();
|
||||
let a = DynamicLibrary::open(&path).unwrap();
|
||||
assert!(a.symbol::<isize>("fun1").is_ok());
|
||||
assert!(a.symbol::<isize>("fun2").is_ok());
|
||||
assert!(a.symbol::<isize>("fun3").is_ok());
|
||||
|
@ -1,35 +0,0 @@
|
||||
// ignore-musl - dlsym doesn't see symbols without "-C link-arg=-Wl,--export-dynamic"
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate rustc_metadata;
|
||||
|
||||
use rustc_metadata::dynamic_lib::DynamicLibrary;
|
||||
|
||||
#[no_mangle]
|
||||
pub fn foo() {
|
||||
bar();
|
||||
}
|
||||
|
||||
pub fn foo2<T>() {
|
||||
fn bar2() {
|
||||
bar();
|
||||
}
|
||||
bar2();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn bar() {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[no_mangle]
|
||||
fn baz() {}
|
||||
|
||||
pub fn test() {
|
||||
let lib = DynamicLibrary::open(None).unwrap();
|
||||
unsafe {
|
||||
assert!(lib.symbol::<isize>("foo").is_ok());
|
||||
assert!(lib.symbol::<isize>("baz").is_ok());
|
||||
assert!(lib.symbol::<isize>("bar").is_ok());
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
// run-pass
|
||||
// aux-build:linkage-visibility.rs
|
||||
// ignore-android: FIXME(#10356)
|
||||
// ignore-windows: std::dynamic_lib does not work on Windows well
|
||||
// ignore-emscripten no dynamic linking
|
||||
|
||||
extern crate linkage_visibility as foo;
|
||||
|
||||
pub fn main() {
|
||||
foo::test();
|
||||
foo::foo2::<isize>();
|
||||
foo::foo();
|
||||
}
|
15
src/test/ui/box-into-boxed-slice-fail.rs
Normal file
15
src/test/ui/box-into-boxed-slice-fail.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// ignore-tidy-linelength
|
||||
#![feature(box_into_boxed_slice)]
|
||||
|
||||
use std::boxed::Box;
|
||||
use std::fmt::Debug;
|
||||
fn main() {
|
||||
let boxed_slice = Box::new([1,2,3]) as Box<[u8]>;
|
||||
let _ = Box::into_boxed_slice(boxed_slice);
|
||||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
//~^^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
let boxed_trait: Box<dyn Debug> = Box::new(5u8);
|
||||
let _ = Box::into_boxed_slice(boxed_trait);
|
||||
//~^ ERROR the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time
|
||||
//~^^ ERROR the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time
|
||||
}
|
43
src/test/ui/box-into-boxed-slice-fail.stderr
Normal file
43
src/test/ui/box-into-boxed-slice-fail.stderr
Normal file
@ -0,0 +1,43 @@
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/box-into-boxed-slice-fail.rs:8:35
|
||||
|
|
||||
LL | let _ = Box::into_boxed_slice(boxed_slice);
|
||||
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
= note: required by `std::boxed::Box::<T>::into_boxed_slice`
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/box-into-boxed-slice-fail.rs:8:13
|
||||
|
|
||||
LL | let _ = Box::into_boxed_slice(boxed_slice);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
= note: slice and array elements must have `Sized` type
|
||||
|
||||
error[E0277]: the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time
|
||||
--> $DIR/box-into-boxed-slice-fail.rs:12:35
|
||||
|
|
||||
LL | let _ = Box::into_boxed_slice(boxed_trait);
|
||||
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `dyn std::fmt::Debug`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
= note: required by `std::boxed::Box::<T>::into_boxed_slice`
|
||||
|
||||
error[E0277]: the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time
|
||||
--> $DIR/box-into-boxed-slice-fail.rs:12:13
|
||||
|
|
||||
LL | let _ = Box::into_boxed_slice(boxed_trait);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `dyn std::fmt::Debug`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
= note: slice and array elements must have `Sized` type
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
11
src/test/ui/box-into-boxed-slice.rs
Normal file
11
src/test/ui/box-into-boxed-slice.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// run-pass
|
||||
#![feature(box_into_boxed_slice)]
|
||||
|
||||
use std::boxed::Box;
|
||||
fn main() {
|
||||
assert_eq!(Box::into_boxed_slice(Box::new(5u8)), Box::new([5u8]) as Box<[u8]>);
|
||||
assert_eq!(Box::into_boxed_slice(Box::new([25u8])), Box::new([[25u8]]) as Box<[[u8; 1]]>);
|
||||
let a: Box<[Box<[u8; 1]>]> = Box::into_boxed_slice(Box::new(Box::new([5u8])));
|
||||
let b: Box<[Box<[u8; 1]>]> = Box::new([Box::new([5u8])]);
|
||||
assert_eq!(a, b);
|
||||
}
|
Loading…
Reference in New Issue
Block a user