diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 3d657396a9feb..b3a771a721d22 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -239,6 +239,16 @@ impl Box { pub fn pin(x: T) -> Pin> { (box x).into() } + + /// Converts a `Box` 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) -> 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 Box<[T]> { diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 367dc4dee7ee0..72c25270a5d69 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -205,7 +205,7 @@ pub fn spawn_thread_pool R + Send, R: Send>( } fn load_backend_from_dylib(path: &Path) -> fn() -> Box { - 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); }); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index e7a863c63ccaa..6168f6e1e5c88 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -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), }; diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index 3e78a5852354f..ce19240a009d0 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -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 { - let maybe_library = dl::open(filename.map(|path| path.as_os_str())); + /// Lazily open a dynamic library. + pub fn open(filename: &Path) -> Result { + 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(f: F) -> Result 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()); diff --git a/src/librustc_metadata/dynamic_lib/tests.rs b/src/librustc_metadata/dynamic_lib/tests.rs index cbf2b181e3c2a..7090bbf61c794 100644 --- a/src/librustc_metadata/dynamic_lib/tests.rs +++ b/src/librustc_metadata/dynamic_lib/tests.rs @@ -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."), } diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index 4b5c6177b2532..e6557c9fbd59d 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -360,6 +360,11 @@ pub enum UndefinedBehaviorInfo { InvalidUndefBytes(Option), /// 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 + ), } } } diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs index f3c1c87dad484..6e013f75ed759 100644 --- a/src/librustc_middle/mir/interpret/value.rs +++ b/src/librustc_middle/mir/interpret/value.rs @@ -393,7 +393,12 @@ impl<'tcx, Tag> Scalar { 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) } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 8e7302dae449e..611d03405e2c8 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -210,8 +210,7 @@ struct TransformVisitor<'tcx> { remap: FxHashMap, 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>`. - storage_liveness: FxHashMap, + storage_liveness: IndexVec>, // A list of suspension points, generated during the transform suspension_points: Vec>, @@ -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, + storage_liveness: IndexVec>, } 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, VariantIdx, usize)>, GeneratorLayout<'tcx>, - FxHashMap, + IndexVec>, ) { // 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, diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs index f41bc44d17705..f48d2b6c8b5e6 100644 --- a/src/librustc_plugin_impl/load.rs +++ b/src/librustc_plugin_impl/load.rs @@ -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" diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs new file mode 100644 index 0000000000000..317705f761212 --- /dev/null +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs @@ -0,0 +1,27 @@ +// EMIT_MIR rustc.a.Inline.after.mir +pub fn a(x: &mut [T]) -> &mut [T] { + x.as_mut() +} + +// EMIT_MIR rustc.b.Inline.after.mir +pub fn b(x: &mut Box) -> &mut T { + x.as_mut() +} + +// EMIT_MIR rustc.c.Inline.after.mir +pub fn c(x: &[T]) -> &[T] { + x.as_ref() +} + +// EMIT_MIR rustc.d.Inline.after.mir +pub fn d(x: &Box) -> &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)); +} diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir new file mode 100644 index 0000000000000..c5d44cbafac41 --- /dev/null +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir @@ -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 + } +} diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir new file mode 100644 index 0000000000000..8384b949b954b --- /dev/null +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir @@ -0,0 +1,34 @@ +// MIR for `b` after Inline + +fn b(_1: &mut std::boxed::Box) -> &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; // 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 + } +} diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.c.Inline.after.mir b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.c.Inline.after.mir new file mode 100644 index 0000000000000..5adb4a6831257 --- /dev/null +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.c.Inline.after.mir @@ -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 + } +} diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.d.Inline.after.mir b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.d.Inline.after.mir new file mode 100644 index 0000000000000..d4d62dd788e00 --- /dev/null +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.d.Inline.after.mir @@ -0,0 +1,26 @@ +// MIR for `d` after Inline + +fn d(_1: &std::boxed::Box) -> &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; // 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 + } +} diff --git a/src/test/run-make-fulldeps/extern-fn-reachable/main.rs b/src/test/run-make-fulldeps/extern-fn-reachable/main.rs index a9d28d1bebeb7..c1de647758585 100644 --- a/src/test/run-make-fulldeps/extern-fn-reachable/main.rs +++ b/src/test/run-make-fulldeps/extern-fn-reachable/main.rs @@ -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::("fun1").is_ok()); assert!(a.symbol::("fun2").is_ok()); assert!(a.symbol::("fun3").is_ok()); diff --git a/src/test/ui-fulldeps/auxiliary/linkage-visibility.rs b/src/test/ui-fulldeps/auxiliary/linkage-visibility.rs deleted file mode 100644 index 837ed1f002fc9..0000000000000 --- a/src/test/ui-fulldeps/auxiliary/linkage-visibility.rs +++ /dev/null @@ -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() { - 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::("foo").is_ok()); - assert!(lib.symbol::("baz").is_ok()); - assert!(lib.symbol::("bar").is_ok()); - } -} diff --git a/src/test/ui-fulldeps/linkage-visibility.rs b/src/test/ui-fulldeps/linkage-visibility.rs deleted file mode 100644 index ae46fbc4e8a03..0000000000000 --- a/src/test/ui-fulldeps/linkage-visibility.rs +++ /dev/null @@ -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::(); - foo::foo(); -} diff --git a/src/test/ui/box-into-boxed-slice-fail.rs b/src/test/ui/box-into-boxed-slice-fail.rs new file mode 100644 index 0000000000000..5f8a3fd9d6a54 --- /dev/null +++ b/src/test/ui/box-into-boxed-slice-fail.rs @@ -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 = 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 +} diff --git a/src/test/ui/box-into-boxed-slice-fail.stderr b/src/test/ui/box-into-boxed-slice-fail.stderr new file mode 100644 index 0000000000000..dfc4999958a57 --- /dev/null +++ b/src/test/ui/box-into-boxed-slice-fail.stderr @@ -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 + = note: required by `std::boxed::Box::::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 + = 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 + = note: required by `std::boxed::Box::::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 + = 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`. diff --git a/src/test/ui/box-into-boxed-slice.rs b/src/test/ui/box-into-boxed-slice.rs new file mode 100644 index 0000000000000..61b3d91525347 --- /dev/null +++ b/src/test/ui/box-into-boxed-slice.rs @@ -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); +}