about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_driver_impl/messages.ftl2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs41
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs5
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs7
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp2
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs10
-rw-r--r--library/core/src/ops/try_trait.rs2
-rw-r--r--library/std/src/sys/pal/hermit/fd.rs5
-rw-r--r--library/std/src/sys/pal/hermit/fs.rs339
-rw-r--r--library/std/src/sys/pal/hermit/time.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/utils.rs37
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr2
-rw-r--r--tests/codegen/vecdeque_pop_push.rs67
-rw-r--r--tests/ui/feature-gates/feature-gate-type_privacy_lints.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr14
-rw-r--r--tests/ui/privacy/unnameable_types.rs1
-rw-r--r--tests/ui/privacy/unnameable_types.stderr8
28 files changed, 403 insertions, 203 deletions
diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl
index 1b69a6e2fbe..62391daecd0 100644
--- a/compiler/rustc_driver_impl/messages.ftl
+++ b/compiler/rustc_driver_impl/messages.ftl
@@ -2,7 +2,7 @@ driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
 driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
 driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly
 driver_impl_ice_bug_report_outdated =
-    it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the mean time
+    it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the meantime
     .update = please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
     .url = if the problem still persists, we would appreciate a bug report: {$bug_report_url}
 driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index a83f9f56beb..1eee11604ce 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -355,6 +355,8 @@ declare_features! (
     (accepted, type_alias_enum_variants, "1.37.0", Some(49683)),
     /// Allows macros to appear in the type position.
     (accepted, type_macros, "1.13.0", Some(27245)),
+    /// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`).
+    (accepted, type_privacy_lints, "CURRENT_RUSTC_VERSION", Some(48054)),
     /// Allows `const _: TYPE = VALUE`.
     (accepted, underscore_const_names, "1.37.0", Some(54912)),
     /// Allows `use path as _;` and `extern crate c as _;`.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 6fe51c62936..a9f206d9e34 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -615,8 +615,6 @@ declare_features! (
     /// Allows creation of instances of a struct by moving fields that have
     /// not changed from prior instances of the same struct (RFC #2528)
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
-    /// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`).
-    (unstable, type_privacy_lints, "1.72.0", Some(48054)),
     /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
     (unstable, unix_sigpipe, "1.65.0", Some(97889)),
     /// Allows unnamed fields of struct and union type
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index c948b6343b7..07d64918e8b 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -40,17 +40,19 @@ use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::cast::{CastKind, CastTy};
 use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::TyCtxt;
 use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
 use rustc_session::lint;
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::DUMMY_SP;
 use rustc_trait_selection::infer::InferCtxtExt;
 
 /// Reifies a cast check to be checked once we have full type information for
 /// a function context.
 #[derive(Debug)]
-pub struct CastCheck<'tcx> {
+pub(crate) struct CastCheck<'tcx> {
     /// The expression whose value is being casted
     expr: &'tcx hir::Expr<'tcx>,
     /// The source type for the cast expression
@@ -60,8 +62,6 @@ pub struct CastCheck<'tcx> {
     cast_ty: Ty<'tcx>,
     cast_span: Span,
     span: Span,
-    /// whether the cast is made in a const context or not.
-    pub constness: hir::Constness,
 }
 
 /// The kind of pointer and associated metadata (thin, length or vtable) - we
@@ -194,18 +194,45 @@ fn make_invalid_casting_error<'a, 'tcx>(
     )
 }
 
+/// If a cast from `from_ty` to `to_ty` is valid, returns a `Some` containing the kind
+/// of the cast.
+///
+/// This is a helper used from clippy.
+pub fn check_cast<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    e: &'tcx hir::Expr<'tcx>,
+    from_ty: Ty<'tcx>,
+    to_ty: Ty<'tcx>,
+) -> Option<CastKind> {
+    let hir_id = e.hir_id;
+    let local_def_id = hir_id.owner.def_id;
+
+    let root_ctxt = crate::TypeckRootCtxt::new(tcx, local_def_id);
+    let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, local_def_id);
+
+    if let Ok(check) = CastCheck::new(
+        &fn_ctxt, e, from_ty, to_ty,
+        // We won't show any errors to the user, so the span is irrelevant here.
+        DUMMY_SP, DUMMY_SP,
+    ) {
+        check.do_check(&fn_ctxt).ok()
+    } else {
+        None
+    }
+}
+
 impl<'a, 'tcx> CastCheck<'tcx> {
-    pub fn new(
+    pub(crate) fn new(
         fcx: &FnCtxt<'a, 'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
         expr_ty: Ty<'tcx>,
         cast_ty: Ty<'tcx>,
         cast_span: Span,
         span: Span,
-        constness: hir::Constness,
     ) -> Result<CastCheck<'tcx>, ErrorGuaranteed> {
         let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span);
-        let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, constness };
+        let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span };
 
         // For better error messages, check for some obviously unsized
         // cases now. We do a more thorough check at the end, once
@@ -644,7 +671,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     /// Checks a cast, and report an error if one exists. In some cases, this
     /// can return Ok and create type errors in the fcx rather than returning
     /// directly. coercion-cast is handled in check instead of here.
-    pub fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
+    fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError> {
         use rustc_middle::ty::cast::CastTy::*;
         use rustc_middle::ty::cast::IntTy::*;
 
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 44b19318d5d..51d01afc4eb 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1318,6 +1318,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 }
 
+/// Check whether `ty` can be coerced to `output_ty`.
+/// Used from clippy.
+pub fn can_coerce<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    body_id: LocalDefId,
+    ty: Ty<'tcx>,
+    output_ty: Ty<'tcx>,
+) -> bool {
+    let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id);
+    let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id);
+    fn_ctxt.can_coerce(ty, output_ty)
+}
+
 /// CoerceMany encapsulates the pattern you should use when you have
 /// many expressions that are all getting coerced to a common
 /// type. This arises, for example, when you have a match (the result
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 4da45303d12..d3df3dd3885 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1390,15 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             // Defer other checks until we're done type checking.
             let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
-            match cast::CastCheck::new(
-                self,
-                e,
-                t_expr,
-                t_cast,
-                t.span,
-                expr.span,
-                hir::Constness::NotConst,
-            ) {
+            match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
                 Ok(cast_check) => {
                     debug!(
                         "check_expr_cast: deferring cast from {:?} to {:?}: {:?}",
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 05e7c5b2b41..0b69c7a2431 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -38,7 +38,7 @@ use std::ops::Deref;
 ///
 /// [`ItemCtxt`]: rustc_hir_analysis::collect::ItemCtxt
 /// [`InferCtxt`]: infer::InferCtxt
-pub struct FnCtxt<'a, 'tcx> {
+pub(crate) struct FnCtxt<'a, 'tcx> {
     pub(super) body_id: LocalDefId,
 
     /// The parameter environment used for proving trait obligations
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 80fd4be53e1..700dde184f2 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -42,8 +42,9 @@ mod typeck_root_ctxt;
 mod upvar;
 mod writeback;
 
-pub use fn_ctxt::FnCtxt;
-pub use typeck_root_ctxt::TypeckRootCtxt;
+pub use coercion::can_coerce;
+use fn_ctxt::FnCtxt;
+use typeck_root_ctxt::TypeckRootCtxt;
 
 use crate::check::check_fn;
 use crate::coercion::DynamicCoerceMany;
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index e493e6a0a7e..88777bf5b02 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -27,7 +27,7 @@ use std::ops::Deref;
 /// `bar()` will each have their own `FnCtxt`, but they will
 /// share the inference context, will process obligations together,
 /// can access each other's local types (scoping permitted), etc.
-pub struct TypeckRootCtxt<'tcx> {
+pub(crate) struct TypeckRootCtxt<'tcx> {
     pub(super) infcx: InferCtxt<'tcx>,
 
     pub(super) typeck_results: RefCell<ty::TypeckResults<'tcx>>,
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 70c7aff3f20..8b974a461d4 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1337,8 +1337,9 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
 }
 
 declare_lint! {
-    /// The `unreachable_pub` lint triggers for `pub` items not reachable from
-    /// the crate root.
+    /// The `unreachable_pub` lint triggers for `pub` items not reachable from other crates - that
+    /// means neither directly accessible, nor reexported, nor leaked through things like return
+    /// types.
     ///
     /// ### Example
     ///
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index cf825be7a55..ec7954536be 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -20,7 +20,7 @@ declare_lint! {
     /// This functionality was removed in #97346, but then rolled back in #99860
     /// because it caused regressions.
     ///
-    /// We plan on reintroducing this as a hard error, but in the mean time,
+    /// We plan on reintroducing this as a hard error, but in the meantime,
     /// this lint serves to warn and suggest fixes for any use-cases which rely
     /// on this behavior.
     ///
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 30522628f46..53b5273803c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4311,7 +4311,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,compile_fail
-    /// # #![feature(type_privacy_lints)]
     /// # #![allow(unused)]
     /// #![deny(unnameable_types)]
     /// mod m {
@@ -4328,10 +4327,14 @@ declare_lint! {
     ///
     /// It is often expected that if you can obtain an object of type `T`, then
     /// you can name the type `T` as well, this lint attempts to enforce this rule.
+    /// The recommended action is to either reexport the type properly to make it nameable,
+    /// or document that users are not supposed to be able to name it for one reason or another.
+    ///
+    /// Besides types, this lint applies to traits because traits can also leak through signatures,
+    /// and you may obtain objects of their `dyn Trait` or `impl Trait` types.
     pub UNNAMEABLE_TYPES,
     Allow,
     "effective visibility of a type is larger than the area in which it can be named",
-    @feature_gate = sym::type_privacy_lints;
 }
 
 declare_lint! {
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index 40723ff9f5e..64e6c18092f 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -147,7 +147,7 @@ LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef Child, size_t *Size) {
   Expected<StringRef> NameOrErr = Child->getName();
   if (!NameOrErr) {
     // rustc_codegen_llvm currently doesn't use this error string, but it might be
-    // useful in the future, and in the mean time this tells LLVM that the
+    // useful in the future, and in the meantime this tells LLVM that the
     // error was not ignored and that it shouldn't abort the process.
     LLVMRustSetLastError(toString(NameOrErr.takeError()).c_str());
     return nullptr;
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index e2fc320f280..693ecb0b6b4 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1614,7 +1614,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
             let old_head = self.head;
             self.head = self.to_physical_idx(1);
             self.len -= 1;
-            Some(unsafe { self.buffer_read(old_head) })
+            unsafe {
+                core::hint::assert_unchecked(self.len < self.capacity());
+                Some(self.buffer_read(old_head))
+            }
         }
     }
 
@@ -1638,7 +1641,10 @@ impl<T, A: Allocator> VecDeque<T, A> {
             None
         } else {
             self.len -= 1;
-            Some(unsafe { self.buffer_read(self.to_physical_idx(self.len)) })
+            unsafe {
+                core::hint::assert_unchecked(self.len < self.capacity());
+                Some(self.buffer_read(self.to_physical_idx(self.len)))
+            }
         }
     }
 
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
index 3f8c8efd416..483f55b2070 100644
--- a/library/core/src/ops/try_trait.rs
+++ b/library/core/src/ops/try_trait.rs
@@ -310,7 +310,7 @@ pub trait FromResidual<R = <Self as Try>::Residual> {
     /// This should be implemented consistently with the `branch` method such
     /// that applying the `?` operator will get back an equivalent residual:
     /// `FromResidual::from_residual(r).branch() --> ControlFlow::Break(r)`.
-    /// (It must not be an *identical* residual when interconversion is involved.)
+    /// (The residual is not mandated to be *identical* when interconversion is involved.)
     ///
     /// # Examples
     ///
diff --git a/library/std/src/sys/pal/hermit/fd.rs b/library/std/src/sys/pal/hermit/fd.rs
index 5eb828fea1f..962577bb1ed 100644
--- a/library/std/src/sys/pal/hermit/fd.rs
+++ b/library/std/src/sys/pal/hermit/fd.rs
@@ -48,6 +48,11 @@ impl FileDesc {
     pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
         unsupported()
     }
+
+    pub fn fstat(&self, stat: *mut abi::stat) -> io::Result<()> {
+        cvt(unsafe { abi::fstat(self.fd.as_raw_fd(), stat) })?;
+        Ok(())
+    }
 }
 
 impl<'a> Read for &'a FileDesc {
diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs
index d4da53fd3df..6519cc22f1f 100644
--- a/library/std/src/sys/pal/hermit/fs.rs
+++ b/library/std/src/sys/pal/hermit/fs.rs
@@ -1,12 +1,17 @@
-use super::abi::{self, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
+use super::abi::{
+    self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
+    O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
+};
 use super::fd::FileDesc;
-use crate::ffi::{CStr, OsString};
+use crate::ffi::{CStr, OsStr, OsString};
 use crate::fmt;
-use crate::hash::{Hash, Hasher};
 use crate::io::{self, Error, ErrorKind};
 use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom};
+use crate::mem;
+use crate::os::hermit::ffi::OsStringExt;
 use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
 use crate::path::{Path, PathBuf};
+use crate::sync::Arc;
 use crate::sys::common::small_c_string::run_path_with_cstr;
 use crate::sys::cvt;
 use crate::sys::time::SystemTime;
@@ -14,16 +19,53 @@ use crate::sys::unsupported;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
 pub use crate::sys_common::fs::{copy, try_exists};
-//pub use crate::sys_common::fs::remove_dir_all;
 
 #[derive(Debug)]
 pub struct File(FileDesc);
+#[derive(Clone)]
+pub struct FileAttr {
+    stat_val: stat_struct,
+}
 
-pub struct FileAttr(!);
+impl FileAttr {
+    fn from_stat(stat_val: stat_struct) -> Self {
+        Self { stat_val }
+    }
+}
 
-pub struct ReadDir(!);
+// all DirEntry's will have a reference to this struct
+struct InnerReadDir {
+    root: PathBuf,
+    dir: Vec<u8>,
+}
 
-pub struct DirEntry(!);
+impl InnerReadDir {
+    pub fn new(root: PathBuf, dir: Vec<u8>) -> Self {
+        Self { root, dir }
+    }
+}
+
+pub struct ReadDir {
+    inner: Arc<InnerReadDir>,
+    pos: i64,
+}
+
+impl ReadDir {
+    fn new(inner: InnerReadDir) -> Self {
+        Self { inner: Arc::new(inner), pos: 0 }
+    }
+}
+
+pub struct DirEntry {
+    /// path to the entry
+    root: PathBuf,
+    /// 64-bit inode number
+    ino: u64,
+    /// File type
+    type_: u32,
+    /// name of the entry
+    name: OsString,
+}
 
 #[derive(Clone, Debug)]
 pub struct OpenOptions {
@@ -41,72 +83,87 @@ pub struct OpenOptions {
 #[derive(Copy, Clone, Debug, Default)]
 pub struct FileTimes {}
 
-pub struct FilePermissions(!);
-
-pub struct FileType(!);
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct FilePermissions {
+    mode: u32,
+}
 
-#[derive(Debug)]
-pub struct DirBuilder {}
+#[derive(Copy, Clone, Eq, Debug)]
+pub struct FileType {
+    mode: u32,
+}
 
-impl FileAttr {
-    pub fn size(&self) -> u64 {
-        self.0
+impl PartialEq for FileType {
+    fn eq(&self, other: &Self) -> bool {
+        self.mode == other.mode
     }
+}
 
-    pub fn perm(&self) -> FilePermissions {
-        self.0
+impl core::hash::Hash for FileType {
+    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
+        self.mode.hash(state);
     }
+}
 
-    pub fn file_type(&self) -> FileType {
-        self.0
-    }
+#[derive(Debug)]
+pub struct DirBuilder {
+    mode: u32,
+}
 
+impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
-        self.0
+        Ok(SystemTime::new(
+            self.stat_val.st_mtime.try_into().unwrap(),
+            self.stat_val.st_mtime_nsec.try_into().unwrap(),
+        ))
     }
 
     pub fn accessed(&self) -> io::Result<SystemTime> {
-        self.0
+        Ok(SystemTime::new(
+            self.stat_val.st_atime.try_into().unwrap(),
+            self.stat_val.st_atime_nsec.try_into().unwrap(),
+        ))
     }
 
     pub fn created(&self) -> io::Result<SystemTime> {
-        self.0
+        Ok(SystemTime::new(
+            self.stat_val.st_ctime.try_into().unwrap(),
+            self.stat_val.st_ctime_nsec.try_into().unwrap(),
+        ))
     }
-}
 
-impl Clone for FileAttr {
-    fn clone(&self) -> FileAttr {
-        self.0
+    pub fn size(&self) -> u64 {
+        self.stat_val.st_size as u64
     }
-}
-
-impl FilePermissions {
-    pub fn readonly(&self) -> bool {
-        self.0
+    pub fn perm(&self) -> FilePermissions {
+        FilePermissions { mode: (self.stat_val.st_mode) }
     }
 
-    pub fn set_readonly(&mut self, _readonly: bool) {
-        self.0
+    pub fn file_type(&self) -> FileType {
+        let masked_mode = self.stat_val.st_mode & S_IFMT;
+        let mode = match masked_mode {
+            S_IFDIR => DT_DIR,
+            S_IFLNK => DT_LNK,
+            S_IFREG => DT_REG,
+            _ => DT_UNKNOWN,
+        };
+        FileType { mode: mode }
     }
 }
 
-impl Clone for FilePermissions {
-    fn clone(&self) -> FilePermissions {
-        self.0
+impl FilePermissions {
+    pub fn readonly(&self) -> bool {
+        // check if any class (owner, group, others) has write permission
+        self.mode & 0o222 == 0
     }
-}
 
-impl PartialEq for FilePermissions {
-    fn eq(&self, _other: &FilePermissions) -> bool {
-        self.0
+    pub fn set_readonly(&mut self, _readonly: bool) {
+        unimplemented!()
     }
-}
-
-impl Eq for FilePermissions {}
 
-impl fmt::Debug for FilePermissions {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0
+    #[allow(dead_code)]
+    pub fn mode(&self) -> u32 {
+        self.mode as u32
     }
 }
 
@@ -117,49 +174,21 @@ impl FileTimes {
 
 impl FileType {
     pub fn is_dir(&self) -> bool {
-        self.0
+        self.mode == DT_DIR
     }
-
     pub fn is_file(&self) -> bool {
-        self.0
+        self.mode == DT_REG
     }
-
     pub fn is_symlink(&self) -> bool {
-        self.0
-    }
-}
-
-impl Clone for FileType {
-    fn clone(&self) -> FileType {
-        self.0
-    }
-}
-
-impl Copy for FileType {}
-
-impl PartialEq for FileType {
-    fn eq(&self, _other: &FileType) -> bool {
-        self.0
-    }
-}
-
-impl Eq for FileType {}
-
-impl Hash for FileType {
-    fn hash<H: Hasher>(&self, _h: &mut H) {
-        self.0
-    }
-}
-
-impl fmt::Debug for FileType {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0
+        self.mode == DT_LNK
     }
 }
 
 impl fmt::Debug for ReadDir {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
+        // Thus the result will be e.g. 'ReadDir("/home")'
+        fmt::Debug::fmt(&*self.inner.root, f)
     }
 }
 
@@ -167,25 +196,78 @@ impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
 
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
-        self.0
+        let mut counter: usize = 0;
+        let mut offset: i64 = 0;
+
+        // loop over all directory entries and search the entry for the current position
+        loop {
+            // leave function, if the loop reaches the of the buffer (with all entries)
+            if offset >= self.inner.dir.len().try_into().unwrap() {
+                return None;
+            }
+
+            let dir = unsafe {
+                &*(self.inner.dir.as_ptr().offset(offset.try_into().unwrap()) as *const dirent64)
+            };
+
+            if counter == self.pos.try_into().unwrap() {
+                self.pos += 1;
+
+                // After dirent64, the file name is stored. d_reclen represents the length of the dirent64
+                // plus the length of the file name. Consequently, file name has a size of d_reclen minus
+                // the size of dirent64. The file name is always a C string and terminated by `\0`.
+                // Consequently, we are able to ignore the last byte.
+                let name_bytes = unsafe {
+                    core::slice::from_raw_parts(
+                        &dir.d_name as *const _ as *const u8,
+                        dir.d_reclen as usize - core::mem::size_of::<dirent64>() - 1,
+                    )
+                    .to_vec()
+                };
+                let entry = DirEntry {
+                    root: self.inner.root.clone(),
+                    ino: dir.d_ino,
+                    type_: dir.d_type as u32,
+                    name: OsString::from_vec(name_bytes),
+                };
+
+                return Some(Ok(entry));
+            }
+
+            counter += 1;
+
+            // move to the next dirent64, which is directly stored after the previous one
+            offset = offset + dir.d_off;
+        }
     }
 }
 
 impl DirEntry {
     pub fn path(&self) -> PathBuf {
-        self.0
+        self.root.join(self.file_name_os_str())
     }
 
     pub fn file_name(&self) -> OsString {
-        self.0
+        self.file_name_os_str().to_os_string()
     }
 
     pub fn metadata(&self) -> io::Result<FileAttr> {
-        self.0
+        let mut path = self.path();
+        path.set_file_name(self.file_name_os_str());
+        lstat(&path)
     }
 
     pub fn file_type(&self) -> io::Result<FileType> {
-        self.0
+        Ok(FileType { mode: self.type_ as u32 })
+    }
+
+    #[allow(dead_code)]
+    pub fn ino(&self) -> u64 {
+        self.ino
+    }
+
+    pub fn file_name_os_str(&self) -> &OsStr {
+        self.name.as_os_str()
     }
 }
 
@@ -288,7 +370,9 @@ impl File {
     }
 
     pub fn file_attr(&self) -> io::Result<FileAttr> {
-        Err(Error::from_raw_os_error(22))
+        let mut stat_val: stat_struct = unsafe { mem::zeroed() };
+        self.0.fstat(&mut stat_val)?;
+        Ok(FileAttr::from_stat(stat_val))
     }
 
     pub fn fsync(&self) -> io::Result<()> {
@@ -357,11 +441,18 @@ impl File {
 
 impl DirBuilder {
     pub fn new() -> DirBuilder {
-        DirBuilder {}
+        DirBuilder { mode: 0o777 }
     }
 
-    pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
-        unsupported()
+    pub fn mkdir(&self, path: &Path) -> io::Result<()> {
+        run_path_with_cstr(path, &|path| {
+            cvt(unsafe { abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
+        })
+    }
+
+    #[allow(dead_code)]
+    pub fn set_mode(&mut self, mode: u32) {
+        self.mode = mode as u32;
     }
 }
 
@@ -416,8 +507,43 @@ impl FromRawFd for File {
     }
 }
 
-pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
-    unsupported()
+pub fn readdir(path: &Path) -> io::Result<ReadDir> {
+    let fd_raw = run_path_with_cstr(path, &|path| cvt(unsafe { abi::opendir(path.as_ptr()) }))?;
+    let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
+    let root = path.to_path_buf();
+
+    // read all director entries
+    let mut vec: Vec<u8> = Vec::new();
+    let mut sz = 512;
+    loop {
+        // reserve memory to receive all directory entries
+        vec.resize(sz, 0);
+
+        let readlen =
+            unsafe { abi::getdents64(fd.as_raw_fd(), vec.as_mut_ptr() as *mut dirent64, sz) };
+        if readlen > 0 {
+            // shrink down to the minimal size
+            vec.resize(readlen.try_into().unwrap(), 0);
+            break;
+        }
+
+        // if the buffer is too small, getdents64 returns EINVAL
+        // otherwise, getdents64 returns an error number
+        if readlen != (-abi::errno::EINVAL).into() {
+            return Err(Error::from_raw_os_error(readlen.try_into().unwrap()));
+        }
+
+        // we don't have enough memory => try to increase the vector size
+        sz = sz * 2;
+
+        // 1 MB for directory entries should be enough
+        // stop here to avoid an endless loop
+        if sz > 0x100000 {
+            return Err(Error::from(ErrorKind::Uncategorized));
+        }
+    }
+
+    Ok(ReadDir::new(InnerReadDir::new(root, vec)))
 }
 
 pub fn unlink(path: &Path) -> io::Result<()> {
@@ -428,17 +554,16 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
     unsupported()
 }
 
-pub fn set_perm(_p: &Path, perm: FilePermissions) -> io::Result<()> {
-    match perm.0 {}
+pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
+    Err(Error::from_raw_os_error(22))
 }
 
-pub fn rmdir(_p: &Path) -> io::Result<()> {
-    unsupported()
+pub fn rmdir(path: &Path) -> io::Result<()> {
+    run_path_with_cstr(path, &|path| cvt(unsafe { abi::rmdir(path.as_ptr()) }).map(|_| ()))
 }
 
 pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
-    //unsupported()
-    Ok(())
+    unsupported()
 }
 
 pub fn readlink(_p: &Path) -> io::Result<PathBuf> {
@@ -453,12 +578,20 @@ pub fn link(_original: &Path, _link: &Path) -> io::Result<()> {
     unsupported()
 }
 
-pub fn stat(_p: &Path) -> io::Result<FileAttr> {
-    unsupported()
+pub fn stat(path: &Path) -> io::Result<FileAttr> {
+    run_path_with_cstr(path, &|path| {
+        let mut stat_val: stat_struct = unsafe { mem::zeroed() };
+        cvt(unsafe { abi::stat(path.as_ptr(), &mut stat_val) })?;
+        Ok(FileAttr::from_stat(stat_val))
+    })
 }
 
-pub fn lstat(_p: &Path) -> io::Result<FileAttr> {
-    unsupported()
+pub fn lstat(path: &Path) -> io::Result<FileAttr> {
+    run_path_with_cstr(path, &|path| {
+        let mut stat_val: stat_struct = unsafe { mem::zeroed() };
+        cvt(unsafe { abi::lstat(path.as_ptr(), &mut stat_val) })?;
+        Ok(FileAttr::from_stat(stat_val))
+    })
 }
 
 pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs
index 319b835a768..d6f9e4c1476 100644
--- a/library/std/src/sys/pal/hermit/time.rs
+++ b/library/std/src/sys/pal/hermit/time.rs
@@ -18,6 +18,12 @@ impl Timespec {
         Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } }
     }
 
+    const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
+        assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64);
+        // SAFETY: The assert above checks tv_nsec is within the valid range
+        Timespec { t: timespec { tv_sec: tv_sec, tv_nsec: tv_nsec } }
+    }
+
     fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
         if self >= other {
             Ok(if self.t.tv_nsec >= other.t.tv_nsec {
@@ -195,6 +201,10 @@ pub struct SystemTime(Timespec);
 pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero());
 
 impl SystemTime {
+    pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime {
+        SystemTime(Timespec::new(tv_sec, tv_nsec))
+    }
+
     pub fn now() -> SystemTime {
         let mut time: Timespec = Timespec::zero();
         let _ = unsafe { abi::clock_gettime(CLOCK_REALTIME, core::ptr::addr_of_mut!(time.t)) };
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 23fc323446e..d3347466be9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -12,7 +12,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
-use rustc_hir_typeck::{FnCtxt, TypeckRootCtxt};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::mir::Mutability;
@@ -437,9 +436,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
             Node::Item(item) => {
                 if let ItemKind::Fn(_, _, body_id) = &item.kind
                     && let output_ty = return_ty(cx, item.owner_id)
-                    && let root_ctxt = TypeckRootCtxt::new(cx.tcx, item.owner_id.def_id)
-                    && let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, item.owner_id.def_id)
-                    && fn_ctxt.can_coerce(ty, output_ty)
+                    && rustc_hir_typeck::can_coerce(cx.tcx, cx.param_env, item.owner_id.def_id, ty, output_ty)
                 {
                     if has_lifetime(output_ty) && has_lifetime(ty) {
                         return false;
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index f5ce8dd29b1..3cf054e7207 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -66,7 +66,7 @@ declare_clippy_lint! {
     ///
     /// ### Known problems
     /// The lint does not work properly with desugaring and
-    /// macro, it has been allowed in the mean time.
+    /// macro, it has been allowed in the meantime.
     ///
     /// ### Example
     /// ```no_run
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index 6f5ac625e35..a6a6e9a3bac 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -1,4 +1,4 @@
-use super::utils::check_cast;
+use rustc_hir_typeck::cast::check_cast;
 use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::sugg::Sugg;
@@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(
 ) -> bool {
     use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};
     let mut app = Applicability::MachineApplicable;
-    let mut sugg = match check_cast(cx, e, from_ty, to_ty) {
+    let mut sugg = match check_cast(cx.tcx, cx.param_env, e, from_ty, to_ty) {
         Some(FnPtrAddrCast | PtrAddrCast) if const_context => return false,
         Some(PtrPtrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) => {
             Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
index 15f1890aa39..e8ccd35b4da 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs
@@ -1,10 +1,5 @@
-use rustc_hir as hir;
-use rustc_hir::Expr;
-use rustc_hir_typeck::{cast, FnCtxt, TypeckRootCtxt};
 use rustc_lint::LateContext;
-use rustc_middle::ty::cast::CastKind;
 use rustc_middle::ty::Ty;
-use rustc_span::DUMMY_SP;
 
 // check if the component types of the transmuted collection and the result have different ABI,
 // size or alignment
@@ -20,35 +15,3 @@ pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx
         false
     }
 }
-
-/// If a cast from `from_ty` to `to_ty` is valid, returns an Ok containing the kind of
-/// the cast. In certain cases, including some invalid casts from array references
-/// to pointers, this may cause additional errors to be emitted and/or ICE error
-/// messages. This function will panic if that occurs.
-pub(super) fn check_cast<'tcx>(
-    cx: &LateContext<'tcx>,
-    e: &'tcx Expr<'_>,
-    from_ty: Ty<'tcx>,
-    to_ty: Ty<'tcx>,
-) -> Option<CastKind> {
-    let hir_id = e.hir_id;
-    let local_def_id = hir_id.owner.def_id;
-
-    let root_ctxt = TypeckRootCtxt::new(cx.tcx, local_def_id);
-    let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, local_def_id);
-
-    if let Ok(check) = cast::CastCheck::new(
-        &fn_ctxt,
-        e,
-        from_ty,
-        to_ty,
-        // We won't show any error to the user, so we don't care what the span is here.
-        DUMMY_SP,
-        DUMMY_SP,
-        hir::Constness::NotConst,
-    ) {
-        check.do_check(&fn_ctxt).ok()
-    } else {
-        None
-    }
-}
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
index b84f4e87e07..763ce59ba1d 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -4,7 +4,7 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 error: the compiler unexpectedly panicked. this is a bug.
 
-note: it seems that this compiler <version> is outdated, a newer nightly should have been released in the mean time
+note: it seems that this compiler <version> is outdated, a newer nightly should have been released in the meantime
   |
   = note: please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
   = note: if the problem still persists, we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml
diff --git a/tests/codegen/vecdeque_pop_push.rs b/tests/codegen/vecdeque_pop_push.rs
new file mode 100644
index 00000000000..040d5a279dc
--- /dev/null
+++ b/tests/codegen/vecdeque_pop_push.rs
@@ -0,0 +1,67 @@
+//@ compile-flags: -O
+
+#![crate_type = "lib"]
+
+use std::collections::VecDeque;
+
+#[no_mangle]
+// CHECK-LABEL: @noop_back(
+pub fn noop_back(v: &mut VecDeque<u8>) {
+    // CHECK-NOT: grow
+    // CHECK: tail call void @llvm.assume
+    // CHECK-NOT: grow
+    // CHECK: ret
+    if let Some(x) = v.pop_back() {
+        v.push_back(x);
+    }
+}
+
+#[no_mangle]
+// CHECK-LABEL: @noop_front(
+pub fn noop_front(v: &mut VecDeque<u8>) {
+    // CHECK-NOT: grow
+    // CHECK: tail call void @llvm.assume
+    // CHECK-NOT: grow
+    // CHECK: ret
+    if let Some(x) = v.pop_front() {
+        v.push_front(x);
+    }
+}
+
+#[no_mangle]
+// CHECK-LABEL: @move_byte_front_to_back(
+pub fn move_byte_front_to_back(v: &mut VecDeque<u8>) {
+    // CHECK-NOT: grow
+    // CHECK: tail call void @llvm.assume
+    // CHECK-NOT: grow
+    // CHECK: ret
+    if let Some(x) = v.pop_front() {
+        v.push_back(x);
+    }
+}
+
+#[no_mangle]
+// CHECK-LABEL: @move_byte_back_to_front(
+pub fn move_byte_back_to_front(v: &mut VecDeque<u8>) {
+    // CHECK-NOT: grow
+    // CHECK: tail call void @llvm.assume
+    // CHECK-NOT: grow
+    // CHECK: ret
+    if let Some(x) = v.pop_back() {
+        v.push_front(x);
+    }
+}
+
+#[no_mangle]
+// CHECK-LABEL: @push_back_byte(
+pub fn push_back_byte(v: &mut VecDeque<u8>) {
+    // CHECK: call {{.*}}grow
+    v.push_back(3);
+}
+
+#[no_mangle]
+// CHECK-LABEL: @push_front_byte(
+pub fn push_front_byte(v: &mut VecDeque<u8>) {
+    // CHECK: call {{.*}}grow
+    v.push_front(3);
+}
diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs b/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs
deleted file mode 100644
index c537fc419f6..00000000000
--- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ check-pass
-
-#![warn(unnameable_types)] //~ WARN unknown lint
-fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr b/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr
deleted file mode 100644
index 72ac3792fff..00000000000
--- a/tests/ui/feature-gates/feature-gate-type_privacy_lints.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-warning: unknown lint: `unnameable_types`
-  --> $DIR/feature-gate-type_privacy_lints.rs:3:1
-   |
-LL | #![warn(unnameable_types)]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: the `unnameable_types` lint is unstable
-   = note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
-   = help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = note: `#[warn(unknown_lints)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs
index c6c5561c3c4..e82bfd0477f 100644
--- a/tests/ui/privacy/unnameable_types.rs
+++ b/tests/ui/privacy/unnameable_types.rs
@@ -1,4 +1,3 @@
-#![feature(type_privacy_lints)]
 #![deny(unnameable_types)]
 
 mod m {
diff --git a/tests/ui/privacy/unnameable_types.stderr b/tests/ui/privacy/unnameable_types.stderr
index d68a11c9728..a1bc60ef9c2 100644
--- a/tests/ui/privacy/unnameable_types.stderr
+++ b/tests/ui/privacy/unnameable_types.stderr
@@ -1,23 +1,23 @@
 error: struct `PubStruct` is reachable but cannot be named
-  --> $DIR/unnameable_types.rs:5:5
+  --> $DIR/unnameable_types.rs:4:5
    |
 LL |     pub struct PubStruct(pub i32);
    |     ^^^^^^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
    |
 note: the lint level is defined here
-  --> $DIR/unnameable_types.rs:2:9
+  --> $DIR/unnameable_types.rs:1:9
    |
 LL | #![deny(unnameable_types)]
    |         ^^^^^^^^^^^^^^^^
 
 error: enum `PubE` is reachable but cannot be named
-  --> $DIR/unnameable_types.rs:7:5
+  --> $DIR/unnameable_types.rs:6:5
    |
 LL |     pub enum PubE {
    |     ^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
 
 error: trait `PubTr` is reachable but cannot be named
-  --> $DIR/unnameable_types.rs:11:5
+  --> $DIR/unnameable_types.rs:10:5
    |
 LL |     pub trait PubTr {
    |     ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`