about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/liballoc/boxed.rs10
-rw-r--r--src/librustc_interface/util.rs2
-rw-r--r--src/librustc_metadata/creader.rs2
-rw-r--r--src/librustc_metadata/dynamic_lib.rs47
-rw-r--r--src/librustc_metadata/dynamic_lib/tests.rs30
-rw-r--r--src/librustc_middle/mir/interpret/error.rs10
-rw-r--r--src/librustc_middle/mir/interpret/value.rs7
-rw-r--r--src/librustc_mir/transform/generator.rs34
-rw-r--r--src/librustc_plugin_impl/load.rs2
-rw-r--r--src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut.rs27
-rw-r--r--src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir30
-rw-r--r--src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir34
-rw-r--r--src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.c.Inline.after.mir22
-rw-r--r--src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.d.Inline.after.mir26
-rw-r--r--src/test/run-make-fulldeps/extern-fn-reachable/main.rs2
-rw-r--r--src/test/ui-fulldeps/auxiliary/linkage-visibility.rs35
-rw-r--r--src/test/ui-fulldeps/linkage-visibility.rs13
-rw-r--r--src/test/ui/box-into-boxed-slice-fail.rs15
-rw-r--r--src/test/ui/box-into-boxed-slice-fail.stderr43
-rw-r--r--src/test/ui/box-into-boxed-slice.rs11
20 files changed, 263 insertions, 139 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 3d657396a9f..b3a771a721d 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -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]> {
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 367dc4dee7e..72c25270a5d 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -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);
     });
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index e7a863c63cc..6168f6e1e5c 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 3e78a585235..ce19240a009 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<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());
diff --git a/src/librustc_metadata/dynamic_lib/tests.rs b/src/librustc_metadata/dynamic_lib/tests.rs
index cbf2b181e3c..7090bbf61c7 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 4b5c6177b25..e6557c9fbd5 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<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
+            ),
         }
     }
 }
diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs
index f3c1c87dad4..6e013f75ed7 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<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)
             }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 8e7302dae44..611d03405e2 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -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,
diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs
index f41bc44d177..f48d2b6c8b5 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 00000000000..317705f7612
--- /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<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));
+}
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 00000000000..c5d44cbafac
--- /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 00000000000..8384b949b95
--- /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<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
+    }
+}
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 00000000000..5adb4a68312
--- /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 00000000000..d4d62dd788e
--- /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>) -> &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
+    }
+}
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 a9d28d1bebe..c1de6477585 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::<isize>("fun1").is_ok());
         assert!(a.symbol::<isize>("fun2").is_ok());
         assert!(a.symbol::<isize>("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 837ed1f002f..00000000000
--- 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<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());
-    }
-}
diff --git a/src/test/ui-fulldeps/linkage-visibility.rs b/src/test/ui-fulldeps/linkage-visibility.rs
deleted file mode 100644
index ae46fbc4e8a..00000000000
--- 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::<isize>();
-    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 00000000000..5f8a3fd9d6a
--- /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<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
+}
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 00000000000..dfc4999958a
--- /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 <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`.
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 00000000000..61b3d915253
--- /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);
+}