diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 28072f153a479..2f55fac30b5a4 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -489,7 +489,7 @@ pub enum NestedMetaItem {
     /// A literal.
     ///
     /// E.g., `"foo"`, `64`, `true`.
-    Literal(Lit),
+    Lit(MetaItemLit),
 }
 
 /// A spanned compile-time attribute item.
@@ -518,7 +518,7 @@ pub enum MetaItemKind {
     /// Name value meta item.
     ///
     /// E.g., `feature = "foo"` as in `#[feature = "foo"]`.
-    NameValue(Lit),
+    NameValue(MetaItemLit),
 }
 
 /// A block (`{ .. }`).
@@ -1571,12 +1571,12 @@ pub enum AttrArgs {
 }
 
 // The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro
-// expansion is completed, all cases end up either as a literal, which is the
-// form used after lowering to HIR, or as an error.
+// expansion is completed, all cases end up either as a meta item literal,
+// which is the form used after lowering to HIR, or as an error.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub enum AttrArgsEq {
     Ast(P<Expr>),
-    Hir(Lit),
+    Hir(MetaItemLit),
 }
 
 impl AttrArgs {
@@ -1698,19 +1698,18 @@ pub enum StrStyle {
     Raw(u8),
 }
 
-/// An AST literal.
+/// A literal in a meta item.
 #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
-pub struct Lit {
+pub struct MetaItemLit {
     /// The original literal token as written in source code.
     pub token_lit: token::Lit,
     /// The "semantic" representation of the literal lowered from the original tokens.
     /// Strings are unescaped, hexadecimal forms are eliminated, etc.
-    /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
     pub kind: LitKind,
     pub span: Span,
 }
 
-/// Same as `Lit`, but restricted to string literals.
+/// Similar to `MetaItemLit`, but restricted to string literals.
 #[derive(Clone, Copy, Encodable, Decodable, Debug)]
 pub struct StrLit {
     /// The original literal token as written in source code.
@@ -1719,7 +1718,6 @@ pub struct StrLit {
     pub suffix: Option<Symbol>,
     pub span: Span,
     /// The unescaped "semantic" representation of the literal lowered from the original token.
-    /// FIXME: Remove this and only create the semantic representation during lowering to HIR.
     pub symbol_unescaped: Symbol,
 }
 
@@ -1755,6 +1753,8 @@ pub enum LitFloatType {
     Unsuffixed,
 }
 
+/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
+///
 /// Note that the entire literal (including the suffix) is considered when
 /// deciding the `LitKind`. This means that float literals like `1f32` are
 /// classified by this type as `Float`. This is different to `token::LitKind`
@@ -3068,9 +3068,9 @@ mod size_asserts {
     static_assert_size!(Impl, 184);
     static_assert_size!(Item, 184);
     static_assert_size!(ItemKind, 112);
-    static_assert_size!(Lit, 48);
     static_assert_size!(LitKind, 24);
     static_assert_size!(Local, 72);
+    static_assert_size!(MetaItemLit, 48);
     static_assert_size!(Param, 40);
     static_assert_size!(Pat, 88);
     static_assert_size!(Path, 24);
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 3e0129531150c..1b58c4b1a1841 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -2,7 +2,7 @@
 
 use crate::ast;
 use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
-use crate::ast::{DelimArgs, Lit, LitKind};
+use crate::ast::{DelimArgs, LitKind, MetaItemLit};
 use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
 use crate::ast::{Path, PathSegment};
 use crate::ptr::P;
@@ -50,10 +50,10 @@ impl NestedMetaItem {
         }
     }
 
-    /// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s.
-    pub fn literal(&self) -> Option<&Lit> {
+    /// Returns the `MetaItemLit` if `self` is a `NestedMetaItem::Literal`s.
+    pub fn lit(&self) -> Option<&MetaItemLit> {
         match self {
-            NestedMetaItem::Literal(lit) => Some(lit),
+            NestedMetaItem::Lit(lit) => Some(lit),
             _ => None,
         }
     }
@@ -78,12 +78,12 @@ impl NestedMetaItem {
     }
 
     /// Returns a name and single literal value tuple of the `MetaItem`.
-    pub fn name_value_literal(&self) -> Option<(Symbol, &Lit)> {
+    pub fn name_value_literal(&self) -> Option<(Symbol, &MetaItemLit)> {
         self.meta_item().and_then(|meta_item| {
             meta_item.meta_item_list().and_then(|meta_item_list| {
                 if meta_item_list.len() == 1
                     && let Some(ident) = meta_item.ident()
-                    && let Some(lit) = meta_item_list[0].literal()
+                    && let Some(lit) = meta_item_list[0].lit()
                 {
                     return Some((ident.name, lit));
                 }
@@ -177,7 +177,7 @@ impl MetaItem {
     // Example:
     //     #[attribute(name = "value")]
     //                 ^^^^^^^^^^^^^^
-    pub fn name_value_literal(&self) -> Option<&Lit> {
+    pub fn name_value_literal(&self) -> Option<&MetaItemLit> {
         match &self.kind {
             MetaItemKind::NameValue(v) => Some(v),
             _ => None,
@@ -332,7 +332,7 @@ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> Meta
 }
 
 pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
-    let lit = Lit::from_lit_kind(lit_kind, lit_span);
+    let lit = MetaItemLit::from_lit_kind(lit_kind, lit_span);
     let span = ident.span.to(lit_span);
     MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) }
 }
@@ -602,7 +602,7 @@ impl MetaItemKind {
                 MetaItemKind::name_value_from_tokens(&mut inner_tokens.into_trees())
             }
             Some(TokenTree::Token(token, _)) => {
-                Lit::from_token(&token).map(MetaItemKind::NameValue)
+                MetaItemLit::from_token(&token).map(MetaItemKind::NameValue)
             }
             _ => None,
         }
@@ -620,7 +620,7 @@ impl MetaItemKind {
             AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind {
                 ast::ExprKind::Lit(token_lit) => {
                     // Turn failures to `None`, we'll get parse errors elsewhere.
-                    Lit::from_token_lit(token_lit, expr.span)
+                    MetaItemLit::from_token_lit(token_lit, expr.span)
                         .ok()
                         .map(|lit| MetaItemKind::NameValue(lit))
                 }
@@ -653,14 +653,14 @@ impl NestedMetaItem {
     pub fn span(&self) -> Span {
         match self {
             NestedMetaItem::MetaItem(item) => item.span,
-            NestedMetaItem::Literal(lit) => lit.span,
+            NestedMetaItem::Lit(lit) => lit.span,
         }
     }
 
     fn token_trees(&self) -> Vec<TokenTree> {
         match self {
             NestedMetaItem::MetaItem(item) => item.token_trees(),
-            NestedMetaItem::Literal(lit) => {
+            NestedMetaItem::Lit(lit) => {
                 vec![TokenTree::Token(lit.to_token(), Spacing::Alone)]
             }
         }
@@ -672,10 +672,10 @@ impl NestedMetaItem {
     {
         match tokens.peek() {
             Some(TokenTree::Token(token, _))
-                if let Some(lit) = Lit::from_token(token) =>
+                if let Some(lit) = MetaItemLit::from_token(token) =>
             {
                 tokens.next();
-                return Some(NestedMetaItem::Literal(lit));
+                return Some(NestedMetaItem::Lit(lit));
             }
             Some(TokenTree::Delimited(_, Delimiter::Invisible, inner_tokens)) => {
                 let inner_tokens = inner_tokens.clone();
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index a5b24c403dd37..b24f3bd1a5be2 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -628,7 +628,7 @@ pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T
 pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
     match li {
         NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi),
-        NestedMetaItem::Literal(_lit) => {}
+        NestedMetaItem::Lit(_lit) => {}
     }
 }
 
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index db2ac9626afd5..42cba07fcef8d 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -1,8 +1,7 @@
 //! Code related to parsing literals.
 
-use crate::ast::{self, Lit, LitKind};
+use crate::ast::{self, LitKind, MetaItemLit};
 use crate::token::{self, Token};
-use rustc_data_structures::sync::Lrc;
 use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
@@ -196,33 +195,26 @@ impl LitKind {
     }
 }
 
-impl Lit {
-    /// Converts literal token into an AST literal.
-    pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<Lit, LitError> {
-        Ok(Lit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
+impl MetaItemLit {
+    /// Converts token literal into a meta item literal.
+    pub fn from_token_lit(token_lit: token::Lit, span: Span) -> Result<MetaItemLit, LitError> {
+        Ok(MetaItemLit { token_lit, kind: LitKind::from_token_lit(token_lit)?, span })
     }
 
-    /// Converts an arbitrary token into an AST literal.
-    pub fn from_token(token: &Token) -> Option<Lit> {
+    /// Converts an arbitrary token into meta item literal.
+    pub fn from_token(token: &Token) -> Option<MetaItemLit> {
         token::Lit::from_token(token)
-            .and_then(|token_lit| Lit::from_token_lit(token_lit, token.span).ok())
+            .and_then(|token_lit| MetaItemLit::from_token_lit(token_lit, token.span).ok())
     }
 
-    /// Attempts to recover an AST literal from semantic literal.
+    /// Attempts to create a meta item literal from a `LitKind`.
     /// This function is used when the original token doesn't exist (e.g. the literal is created
     /// by an AST-based macro) or unavailable (e.g. from HIR pretty-printing).
-    pub fn from_lit_kind(kind: LitKind, span: Span) -> Lit {
-        Lit { token_lit: kind.to_token_lit(), kind, span }
+    pub fn from_lit_kind(kind: LitKind, span: Span) -> MetaItemLit {
+        MetaItemLit { token_lit: kind.to_token_lit(), kind, span }
     }
 
-    /// Recovers an AST literal from a string of bytes produced by `include_bytes!`.
-    /// This requires ASCII-escaping the string, which can result in poor performance
-    /// for very large strings of bytes.
-    pub fn from_included_bytes(bytes: &Lrc<[u8]>, span: Span) -> Lit {
-        Self::from_lit_kind(LitKind::ByteStr(bytes.clone()), span)
-    }
-
-    /// Losslessly convert an AST literal into a token.
+    /// Losslessly convert a meta item literal into a token.
     pub fn to_token(&self) -> Token {
         let kind = match self.token_lit.kind {
             token::Bool => token::Ident(self.token_lit.symbol, false),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d1666dfbf6444..787ec041baae6 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -941,17 +941,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => {
                 // In valid code the value always ends up as a single literal. Otherwise, a dummy
                 // literal suffices because the error is handled elsewhere.
-                let lit = if let ExprKind::Lit(token_lit) = expr.kind {
-                    match Lit::from_token_lit(token_lit, expr.span) {
-                        Ok(lit) => lit,
-                        Err(_err) => Lit {
-                            token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
-                            kind: LitKind::Err,
-                            span: DUMMY_SP,
-                        },
-                    }
+                let lit = if let ExprKind::Lit(token_lit) = expr.kind
+                    && let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span)
+                {
+                    lit
                 } else {
-                    Lit {
+                    MetaItemLit {
                         token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
                         kind: LitKind::Err,
                         span: DUMMY_SP,
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 991f6e0ba2243..7a9243c511b92 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -371,7 +371,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         }
     }
 
-    fn print_literal(&mut self, lit: &ast::Lit) {
+    fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) {
         self.print_token_literal(lit.token_lit, lit.span)
     }
 
@@ -488,7 +488,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                 self.print_path(&item.path, false, 0);
                 self.space();
                 self.word_space("=");
-                let token_str = self.literal_to_string(lit);
+                let token_str = self.meta_item_lit_to_string(lit);
                 self.word(token_str);
             }
         }
@@ -498,7 +498,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
     fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
         match item {
             ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi),
-            ast::NestedMetaItem::Literal(ref lit) => self.print_literal(lit),
+            ast::NestedMetaItem::Lit(ref lit) => self.print_meta_item_lit(lit),
         }
     }
 
@@ -510,7 +510,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                 self.print_path(&item.path, false, 0);
                 self.space();
                 self.word_space("=");
-                self.print_literal(value);
+                self.print_meta_item_lit(value);
             }
             ast::MetaItemKind::List(ref items) => {
                 self.print_path(&item.path, false, 0);
@@ -825,8 +825,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         Self::to_string(|s| s.print_expr(e))
     }
 
-    fn literal_to_string(&self, lit: &ast::Lit) -> String {
-        Self::to_string(|s| s.print_literal(lit))
+    fn meta_item_lit_to_string(&self, lit: &ast::MetaItemLit) -> String {
+        Self::to_string(|s| s.print_meta_item_lit(lit))
     }
 
     fn tt_to_string(&self, tt: &TokenTree) -> String {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 4b37fa027f53b..396e1d33f2de4 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -328,8 +328,8 @@ impl<'a> State<'a> {
                 self.print_token_literal(token_lit, expr.span);
             }
             ast::ExprKind::IncludedBytes(ref bytes) => {
-                let lit = ast::Lit::from_included_bytes(bytes, expr.span);
-                self.print_literal(&lit)
+                let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit();
+                self.print_token_literal(lit, expr.span)
             }
             ast::ExprKind::Cast(ref expr, ref ty) => {
                 let prec = AssocOp::As.precedence() as i8;
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 753f62dd589d0..13b48d8f89ab4 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -1,7 +1,7 @@
 //! Parsing and validation of builtin attributes
 
 use rustc_ast as ast;
-use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId};
+use rustc_ast::{Attribute, LitKind, MetaItem, MetaItemKind, MetaItemLit, NestedMetaItem, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
 use rustc_macros::HashStable_Generic;
@@ -486,7 +486,7 @@ where
                                     continue 'outer;
                                 }
                             },
-                            NestedMetaItem::Literal(lit) => {
+                            NestedMetaItem::Lit(lit) => {
                                 handle_errors(
                                     &sess.parse_sess,
                                     lit.span,
@@ -658,11 +658,11 @@ pub fn eval_condition(
         ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => {
             try_gate_cfg(sym::version, cfg.span, sess, features);
             let (min_version, span) = match &mis[..] {
-                [NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
+                [NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
                     (sym, span)
                 }
                 [
-                    NestedMetaItem::Literal(Lit { span, .. })
+                    NestedMetaItem::Lit(MetaItemLit { span, .. })
                     | NestedMetaItem::MetaItem(MetaItem { span, .. }),
                 ] => {
                     sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
@@ -899,7 +899,7 @@ where
                                 continue 'outer;
                             }
                         },
-                        NestedMetaItem::Literal(lit) => {
+                        NestedMetaItem::Lit(lit) => {
                             handle_errors(
                                 &sess.parse_sess,
                                 lit.span,
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index 01f237e6ab5fa..c8a2fca00e800 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -48,9 +48,9 @@ impl MultiItemModifier for Expander {
                     .into_iter()
                     .filter_map(|nested_meta| match nested_meta {
                         NestedMetaItem::MetaItem(meta) => Some(meta),
-                        NestedMetaItem::Literal(lit) => {
+                        NestedMetaItem::Lit(lit) => {
                             // Reject `#[derive("Debug")]`.
-                            report_unexpected_literal(sess, &lit);
+                            report_unexpected_meta_item_lit(sess, &lit);
                             None
                         }
                     })
@@ -127,7 +127,7 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
     bad_target
 }
 
-fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
+fn report_unexpected_meta_item_lit(sess: &Session, lit: &ast::MetaItemLit) {
     let help_msg = match lit.token_lit.kind {
         token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => {
             format!("try using `#[derive({})]`", lit.token_lit.symbol)
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 2e832deeecda0..7616579611711 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -526,11 +526,8 @@ impl server::TokenStream for Rustc<'_, '_> {
                 Ok(tokenstream::TokenStream::token_alone(token::Literal(*token_lit), expr.span))
             }
             ast::ExprKind::IncludedBytes(bytes) => {
-                let lit = ast::Lit::from_included_bytes(bytes, expr.span);
-                Ok(tokenstream::TokenStream::token_alone(
-                    token::TokenKind::Literal(lit.token_lit),
-                    expr.span,
-                ))
+                let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit();
+                Ok(tokenstream::TokenStream::token_alone(token::TokenKind::Literal(lit), expr.span))
             }
             ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind {
                 ast::ExprKind::Lit(token_lit) => match token_lit {
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 4c1d95a452d5e..638dd6d756b58 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -2145,7 +2145,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 }
 
 fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
-    use rustc_ast::{Lit, LitIntType, LitKind};
+    use rustc_ast::{LitIntType, LitKind, MetaItemLit};
     if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" {
         feature_err(
             &tcx.sess.parse_sess,
@@ -2158,7 +2158,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
     let meta_item_list = attr.meta_item_list();
     let meta_item_list = meta_item_list.as_deref();
     let sole_meta_list = match meta_item_list {
-        Some([item]) => item.literal(),
+        Some([item]) => item.lit(),
         Some(_) => {
             tcx.sess
                 .struct_span_err(attr.span, "incorrect number of arguments to `#[link_ordinal]`")
@@ -2168,7 +2168,9 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
         }
         _ => None,
     };
-    if let Some(Lit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = sole_meta_list {
+    if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
+        sole_meta_list
+    {
         // According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
         // the ordinal must fit into 16 bits.  Similarly, the Ordinal field in COFFShortExport (defined
         // in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 99c934862c480..4c22ab68a5681 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -194,7 +194,7 @@ pub fn parse_check_cfg(specs: Vec<String>) -> CheckCfg {
 
                                         for val in values {
                                             if let Some(LitKind::Str(s, _)) =
-                                                val.literal().map(|lit| &lit.kind)
+                                                val.lit().map(|lit| &lit.kind)
                                             {
                                                 ident_values.insert(s.to_string());
                                             } else {
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 11e4650cb4b64..c99dc72aeaa9b 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -466,8 +466,8 @@ impl LateLintPass<'_> for BadOptAccess {
                 let Some(attr) = cx.tcx.get_attr(field.did, sym::rustc_lint_opt_deny_field_access) &&
                 let Some(items) = attr.meta_item_list()  &&
                 let Some(item) = items.first()  &&
-                let Some(literal) = item.literal()  &&
-                let ast::LitKind::Str(val, _) = literal.kind
+                let Some(lit) = item.lit()  &&
+                let ast::LitKind::Str(val, _) = lit.kind
             {
                 cx.struct_span_lint(BAD_OPT_ACCESS, expr.span, val.as_str(), |lint|
                     lint
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index b5327ad0cecc6..c14dfeadb8c48 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1187,8 +1187,9 @@ impl<'tcx> TyCtxt<'tcx> {
             debug!("layout_scalar_valid_range: attr={:?}", attr);
             if let Some(
                 &[
-                    ast::NestedMetaItem::Literal(ast::Lit {
-                        kind: ast::LitKind::Int(a, _), ..
+                    ast::NestedMetaItem::Lit(ast::MetaItemLit {
+                        kind: ast::LitKind::Int(a, _),
+                        ..
                     }),
                 ],
             ) = attr.meta_item_list().as_deref()
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 0ed24fe849c07..c7d239b647f35 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -315,8 +315,9 @@ impl<'a> Parser<'a> {
         Ok(attrs)
     }
 
-    pub(crate) fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> {
-        let lit = self.parse_ast_lit()?;
+    // Note: must be unsuffixed.
+    pub(crate) fn parse_unsuffixed_meta_item_lit(&mut self) -> PResult<'a, ast::MetaItemLit> {
+        let lit = self.parse_meta_item_lit()?;
         debug!("checking if {:?} is unsuffixed", lit);
 
         if !lit.kind.is_unsuffixed() {
@@ -391,7 +392,7 @@ impl<'a> Parser<'a> {
 
     pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
         Ok(if self.eat(&token::Eq) {
-            ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
+            ast::MetaItemKind::NameValue(self.parse_unsuffixed_meta_item_lit()?)
         } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
             // Matches `meta_seq = ( COMMASEP(meta_item_inner) )`.
             let (list, _) = self.parse_paren_comma_seq(|p| p.parse_meta_item_inner())?;
@@ -403,8 +404,8 @@ impl<'a> Parser<'a> {
 
     /// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`.
     fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
-        match self.parse_unsuffixed_lit() {
-            Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)),
+        match self.parse_unsuffixed_meta_item_lit() {
+            Ok(lit) => return Ok(ast::NestedMetaItem::Lit(lit)),
             Err(err) => err.cancel(),
         }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 9f2267efb8287..e0443a697b504 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -33,10 +33,10 @@ use rustc_ast::util::case::Case;
 use rustc_ast::util::classify;
 use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
 use rustc_ast::visit::Visitor;
-use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp, DUMMY_NODE_ID};
+use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, UnOp, DUMMY_NODE_ID};
 use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
 use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
-use rustc_ast::{ClosureBinder, StmtKind};
+use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
 use rustc_ast_pretty::pprust;
 use rustc_errors::{
     Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult,
@@ -1631,7 +1631,7 @@ impl<'a> Parser<'a> {
         &self,
         lifetime: Ident,
         err: impl FnOnce(&Self) -> DiagnosticBuilder<'a, ErrorGuaranteed>,
-    ) -> ast::Lit {
+    ) -> ast::MetaItemLit {
         if let Some(mut diag) =
             self.sess.span_diagnostic.steal_diagnostic(lifetime.span, StashKey::LifetimeIsChar)
         {
@@ -1653,7 +1653,7 @@ impl<'a> Parser<'a> {
                 .emit();
         }
         let name = lifetime.without_first_quote().name;
-        ast::Lit {
+        ast::MetaItemLit {
             token_lit: token::Lit::new(token::LitKind::Char, name, None),
             kind: ast::LitKind::Char(name.as_str().chars().next().unwrap_or('_')),
             span: lifetime.span,
@@ -1768,8 +1768,8 @@ impl<'a> Parser<'a> {
     /// Returns a string literal if the next token is a string literal.
     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
     /// and returns `None` if the next token is not literal at all.
-    pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
-        match self.parse_opt_ast_lit() {
+    pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<MetaItemLit>> {
+        match self.parse_opt_meta_item_lit() {
             Some(lit) => match lit.kind {
                 ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
                     style,
@@ -1784,7 +1784,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn handle_missing_lit(&mut self) -> PResult<'a, Lit> {
+    fn handle_missing_lit(&mut self) -> PResult<'a, MetaItemLit> {
         if let token::Interpolated(inner) = &self.token.kind {
             let expr = match inner.as_ref() {
                 token::NtExpr(expr) => Some(expr),
@@ -1820,8 +1820,8 @@ impl<'a> Parser<'a> {
             .or_else(|()| self.handle_missing_lit().map(|lit| (lit.token_lit, lit.span)))
     }
 
-    pub(super) fn parse_ast_lit(&mut self) -> PResult<'a, Lit> {
-        self.parse_opt_ast_lit().ok_or(()).or_else(|()| self.handle_missing_lit())
+    pub(super) fn parse_meta_item_lit(&mut self) -> PResult<'a, MetaItemLit> {
+        self.parse_opt_meta_item_lit().ok_or(()).or_else(|()| self.handle_missing_lit())
     }
 
     fn recover_after_dot(&mut self) -> Option<Token> {
@@ -1867,12 +1867,12 @@ impl<'a> Parser<'a> {
 
     /// Matches `lit = true | false | token_lit`.
     /// Returns `None` if the next token is not a literal.
-    pub(super) fn parse_opt_ast_lit(&mut self) -> Option<Lit> {
+    pub(super) fn parse_opt_meta_item_lit(&mut self) -> Option<MetaItemLit> {
         let recovered = self.recover_after_dot();
         let token = recovered.as_ref().unwrap_or(&self.token);
         match token::Lit::from_token(token) {
             Some(token_lit) => {
-                match Lit::from_token_lit(token_lit, token.span) {
+                match MetaItemLit::from_token_lit(token_lit, token.span) {
                     Ok(lit) => {
                         self.bump();
                         Some(lit)
@@ -1889,7 +1889,10 @@ impl<'a> Parser<'a> {
                         let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
                         let symbol = Symbol::intern(&suffixless_lit.to_string());
                         let lit = token::Lit::new(token::Err, symbol, lit.suffix);
-                        Some(Lit::from_token_lit(lit, span).unwrap_or_else(|_| unreachable!()))
+                        Some(
+                            MetaItemLit::from_token_lit(lit, span)
+                                .unwrap_or_else(|_| unreachable!()),
+                        )
                     }
                 }
             }
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 1b56cd72db079..ff1ddfd97dfc6 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
     /// report error for `let 1x = 123`
     pub fn report_invalid_identifier_error(&mut self) -> PResult<'a, ()> {
         if let token::Literal(lit) = self.token.uninterpolate().kind &&
-            rustc_ast::Lit::from_token(&self.token).is_none() &&
+            rustc_ast::MetaItemLit::from_token(&self.token).is_none() &&
             (lit.kind == token::LitKind::Integer || lit.kind == token::LitKind::Float) &&
             self.look_ahead(1, |t| matches!(t.kind, token::Eq) || matches!(t.kind, token::Colon ) ) {
                 return Err(self.sess.create_err(InvalidIdentiferStartsWithNumber { span: self.token.span }));
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index e2f95d74a3d22..59e564114e5cf 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -51,7 +51,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
             }
             AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
                 if let ast::ExprKind::Lit(token_lit) = expr.kind
-                    && let Ok(lit) = ast::Lit::from_token_lit(token_lit, expr.span)
+                    && let Ok(lit) = ast::MetaItemLit::from_token_lit(token_lit, expr.span)
                 {
                     if token_lit.suffix.is_some() {
                         let mut err = sess.span_diagnostic.struct_span_err(
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index acb9bd8e78a4a..2e2874dbccb9e 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -8,7 +8,7 @@ use crate::errors::{
     self, AttrApplication, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel, ObjectLifetimeErr,
     OnlyHasEffectOn, TransparentIncompatible, UnrecognizedReprHint,
 };
-use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{fluent, Applicability, MultiSpan};
 use rustc_expand::base::resolve_path;
@@ -715,7 +715,7 @@ impl CheckAttrVisitor<'_> {
         if let Some(values) = meta.meta_item_list() {
             let mut errors = 0;
             for v in values {
-                match v.literal() {
+                match v.lit() {
                     Some(l) => match l.kind {
                         LitKind::Str(s, _) => {
                             if !self.check_doc_alias_value(v, s, hir_id, target, true, aliases) {
@@ -1355,7 +1355,7 @@ impl CheckAttrVisitor<'_> {
             return false;
         };
 
-        if matches!(&list[..], &[NestedMetaItem::Literal(Lit { kind: LitKind::Int(..), .. })]) {
+        if matches!(&list[..], &[NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Int(..), .. })]) {
             true
         } else {
             self.tcx.sess.emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span });
@@ -1418,7 +1418,7 @@ impl CheckAttrVisitor<'_> {
         let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128;
         let mut invalid_args = vec![];
         for meta in list {
-            if let Some(LitKind::Int(val, _)) = meta.literal().map(|lit| &lit.kind) {
+            if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) {
                 if *val >= arg_count {
                     let span = meta.span();
                     self.tcx.sess.emit_err(errors::RustcLegacyConstGenericsIndexExceed {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index f9ae3b5817272..747fc1d45b018 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1984,7 +1984,7 @@ impl<'a> Resolver<'a> {
                     .find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
                 let mut ret = Vec::new();
                 for meta in attr.meta_item_list()? {
-                    match meta.literal()?.kind {
+                    match meta.lit()?.kind {
                         LitKind::Int(a, _) => ret.push(a as usize),
                         _ => panic!("invalid arg index"),
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index c0edbebed54ee..e46441001b54d 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -605,8 +605,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     {
         debug!(?obligation, "confirm_fn_pointer_candidate");
 
-        // Okay to skip binder; it is reintroduced below.
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
+        let self_ty = self
+            .infcx
+            .shallow_resolve(obligation.self_ty().no_bound_vars())
+            .expect("fn pointer should not capture bound vars from predicate");
         let sig = self_ty.fn_sig(self.tcx());
         let trait_ref = closure_trait_ref_and_return_type(
             self.tcx(),
@@ -621,15 +623,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
         let cause = obligation.derived_cause(BuiltinDerivedObligation);
-        // The binder on the Fn obligation is "less" important than the one on
-        // the signature, as evidenced by how we treat it during projection.
-        // The safe thing to do here is to liberate it, though, which should
-        // have no worse effect than skipping the binder here.
-        let liberated_fn_ty =
-            self.infcx.replace_bound_vars_with_placeholders(obligation.predicate.rebind(self_ty));
-        let output_ty = self
-            .infcx
-            .replace_bound_vars_with_placeholders(liberated_fn_ty.fn_sig(self.tcx()).output());
+        let output_ty = self.infcx.replace_bound_vars_with_placeholders(sig.output());
         let output_ty = normalize_with_depth_to(
             self,
             obligation.param_env,
@@ -693,16 +687,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let gen_sig = substs.as_generator().poly_sig();
 
-        // (1) Feels icky to skip the binder here, but OTOH we know
-        // that the self-type is an generator type and hence is
+        // NOTE: The self-type is a generator type and hence is
         // in fact unparameterized (or at least does not reference any
-        // regions bound in the obligation). Still probably some
-        // refactoring could make this nicer.
+        // regions bound in the obligation).
+        let self_ty = obligation
+            .predicate
+            .self_ty()
+            .no_bound_vars()
+            .expect("unboxed closure type should not capture bound vars from the predicate");
 
         let trait_ref = super::util::generator_trait_ref_and_outputs(
             self.tcx(),
             obligation.predicate.def_id(),
-            obligation.predicate.skip_binder().self_ty(), // (1)
+            self_ty,
             gen_sig,
         )
         .map_bound(|(trait_ref, ..)| trait_ref);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 9fe13fe296a16..2a1494e8952a1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2271,15 +2271,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         debug!(?closure_sig);
 
-        // (1) Feels icky to skip the binder here, but OTOH we know
-        // that the self-type is an unboxed closure type and hence is
+        // NOTE: The self-type is an unboxed closure type and hence is
         // in fact unparameterized (or at least does not reference any
-        // regions bound in the obligation). Still probably some
-        // refactoring could make this nicer.
+        // regions bound in the obligation).
+        let self_ty = obligation
+            .predicate
+            .self_ty()
+            .no_bound_vars()
+            .expect("unboxed closure type should not capture bound vars from the predicate");
+
         closure_trait_ref_and_return_type(
             self.tcx(),
             obligation.predicate.def_id(),
-            obligation.predicate.skip_binder().self_ty(), // (1)
+            self_ty,
             closure_sig,
             util::TupleArgumentsFlag::No,
         )
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 20d8a7a742c3a..a496cea0b005b 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -298,11 +298,11 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
     sig: ty::PolyFnSig<'tcx>,
     tuple_arguments: TupleArgumentsFlag,
 ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> {
+    assert!(!self_ty.has_escaping_bound_vars());
     let arguments_tuple = match tuple_arguments {
         TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
         TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
     };
-    debug_assert!(!self_ty.has_escaping_bound_vars());
     let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]);
     sig.map_bound(|sig| (trait_ref, sig.output()))
 }
@@ -313,7 +313,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>(
     self_ty: Ty<'tcx>,
     sig: ty::PolyGenSig<'tcx>,
 ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
-    debug_assert!(!self_ty.has_escaping_bound_vars());
+    assert!(!self_ty.has_escaping_bound_vars());
     let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]);
     sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
 }
@@ -324,7 +324,7 @@ pub fn future_trait_ref_and_outputs<'tcx>(
     self_ty: Ty<'tcx>,
     sig: ty::PolyGenSig<'tcx>,
 ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> {
-    debug_assert!(!self_ty.has_escaping_bound_vars());
+    assert!(!self_ty.has_escaping_bound_vars());
     let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty]);
     sig.map_bound(|sig| (trait_ref, sig.return_ty))
 }
diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs
index 9e5123be98990..af49826ff30a3 100644
--- a/library/alloc/tests/boxed.rs
+++ b/library/alloc/tests/boxed.rs
@@ -102,8 +102,18 @@ unsafe impl const Allocator for ConstAllocator {
 
         let new_ptr = self.allocate(new_layout)?;
         if new_layout.size() > 0 {
-            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
-            self.deallocate(ptr, old_layout);
+            // Safety: `new_ptr` is valid for writes and `ptr` for reads of
+            // `old_layout.size()`, because `new_layout.size() >=
+            // old_layout.size()` (which is an invariant that must be upheld by
+            // callers).
+            unsafe {
+                new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), old_layout.size());
+            }
+            // Safety: `ptr` is never used again is also an invariant which must
+            // be upheld by callers.
+            unsafe {
+                self.deallocate(ptr, old_layout);
+            }
         }
         Ok(new_ptr)
     }
@@ -114,12 +124,21 @@ unsafe impl const Allocator for ConstAllocator {
         old_layout: Layout,
         new_layout: Layout,
     ) -> Result<NonNull<[u8]>, AllocError> {
-        let new_ptr = self.grow(ptr, old_layout, new_layout)?;
+        // Safety: Invariants of `grow_zeroed` and `grow` are the same, and must
+        // be enforced by callers.
+        let new_ptr = unsafe { self.grow(ptr, old_layout, new_layout)? };
         if new_layout.size() > 0 {
             let old_size = old_layout.size();
             let new_size = new_layout.size();
             let raw_ptr = new_ptr.as_mut_ptr();
-            raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+            // Safety:
+            // - `grow` returned Ok, so the returned pointer must be valid for
+            //   `new_size` bytes
+            // - `new_size` must be larger than `old_size`, which is an
+            //   invariant which must be upheld by callers.
+            unsafe {
+                raw_ptr.add(old_size).write_bytes(0, new_size - old_size);
+            }
         }
         Ok(new_ptr)
     }
@@ -137,8 +156,18 @@ unsafe impl const Allocator for ConstAllocator {
 
         let new_ptr = self.allocate(new_layout)?;
         if new_layout.size() > 0 {
-            new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
-            self.deallocate(ptr, old_layout);
+            // Safety: `new_ptr` and `ptr` are valid for reads/writes of
+            // `new_layout.size()` because of the invariants of shrink, which
+            // include `new_layout.size()` being smaller than (or equal to)
+            // `old_layout.size()`.
+            unsafe {
+                new_ptr.as_mut_ptr().copy_from_nonoverlapping(ptr.as_ptr(), new_layout.size());
+            }
+            // Safety: `ptr` is never used again is also an invariant which must
+            // be upheld by callers.
+            unsafe {
+                self.deallocate(ptr, old_layout);
+            }
         }
         Ok(new_ptr)
     }
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index d066ec03ee57e..d6d2b055b2395 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -48,6 +48,7 @@
 #![feature(once_cell)]
 #![feature(drain_keep_rest)]
 #![deny(fuzzy_provenance_casts)]
+#![deny(unsafe_op_in_unsafe_fn)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index e027118704478..7ebed0d5ca699 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1089,7 +1089,8 @@ fn test_into_iter_drop_allocator() {
         }
 
         unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
-            System.deallocate(ptr, layout)
+            // Safety: Invariants passed to caller.
+            unsafe { System.deallocate(ptr, layout) }
         }
     }
 
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 2fef7f65827dd..a274d7b9aa1d3 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1191,7 +1191,6 @@ impl Step for Clippy {
 
         let mut tarball = Tarball::new(builder, "clippy", &target.triple);
         tarball.set_overlay(OverlayKind::Clippy);
-        tarball.is_preview(true);
         tarball.add_file(clippy, "bin", 0o755);
         tarball.add_file(cargoclippy, "bin", 0o755);
         tarball.add_legal_and_readme_to("share/doc/clippy");
@@ -1289,7 +1288,6 @@ impl Step for Rustfmt {
             .expect("cargo fmt expected to build - essential tool");
         let mut tarball = Tarball::new(builder, "rustfmt", &target.triple);
         tarball.set_overlay(OverlayKind::Rustfmt);
-        tarball.is_preview(true);
         tarball.add_file(rustfmt, "bin", 0o755);
         tarball.add_file(cargofmt, "bin", 0o755);
         tarball.add_legal_and_readme_to("share/doc/rustfmt");
@@ -1550,8 +1548,6 @@ impl Step for Extended {
                     format!("{}-{}", name, target.triple)
                 } else if name == "rust-analyzer" {
                     "rust-analyzer-preview".to_string()
-                } else if name == "clippy" {
-                    "clippy-preview".to_string()
                 } else if name == "rust-demangler" {
                     "rust-demangler-preview".to_string()
                 } else if name == "miri" {
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
index d0f389df97344..430b3496d007c 100644
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -326,6 +326,8 @@ impl Config {
         }
 
         let filename = format!("rustfmt-{version}-{build}.tar.xz", build = host.triple);
+        // cfg(bootstrap): will need to be changed from `rustfmt-preview` to `rustfmt` the next time you run `bump-stage0`.
+        // See <https://github.com/rust-lang/rust/pull/103648>
         self.download_component(DownloadSource::Dist, filename, "rustfmt-preview", &date, "stage0");
 
         self.fix_bin_or_dylib(&bin_root.join("bin").join("rustfmt"));
diff --git a/src/doc/unstable-book/src/language-features/abi-efiapi.md b/src/doc/unstable-book/src/language-features/abi-efiapi.md
new file mode 100644
index 0000000000000..11ef0cfdb1422
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/abi-efiapi.md
@@ -0,0 +1,23 @@
+# `abi_efiapi`
+
+The tracking issue for this feature is: [#65815]
+
+[#65815]: https://github.com/rust-lang/rust/issues/65815
+
+------------------------
+
+The `efiapi` calling convention can be used for defining a function with
+an ABI compatible with the UEFI Interfaces as defined in the [UEFI
+Specification].
+
+Example:
+
+```rust
+#![feature(abi_efiapi)]
+
+extern "efiapi" { fn f1(); }
+
+extern "efiapi" fn f2() { todo!() }
+```
+
+[UEFI Specification]: https://uefi.org/specs/UEFI/2.10/
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index f33f5d27d1a9f..1843a21205cfa 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -50,7 +50,7 @@ impl Cfg {
     ) -> Result<Option<Cfg>, InvalidCfgError> {
         match nested_cfg {
             NestedMetaItem::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude),
-            NestedMetaItem::Literal(ref lit) => {
+            NestedMetaItem::Lit(ref lit) => {
                 Err(InvalidCfgError { msg: "unexpected literal", span: lit.span })
             }
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b5d4ab55b4a83..b646b25935144 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -893,7 +893,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
         .filter(|a| a.has_name(sym::rustc_legacy_const_generics))
         .filter_map(|a| a.meta_item_list())
     {
-        for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.literal()).enumerate() {
+        for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.lit()).enumerate() {
             match literal.kind {
                 ast::LitKind::Int(a, _) => {
                     let gen = func.generics.params.remove(0);
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 340d6d7df180f..d29875ca39ed8 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1306,7 +1306,7 @@ impl Attributes {
         for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) {
             if let Some(values) = attr.meta_item_list() {
                 for l in values {
-                    match l.literal().unwrap().kind {
+                    match l.lit().unwrap().kind {
                         ast::LitKind::Str(s, _) => {
                             aliases.insert(s);
                         }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 9b07fc90f6f05..c1f7a8338342d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1343,6 +1343,13 @@ a.test-arrow:hover {
 	border-bottom: 1px solid var(--border-color);
 	margin-bottom: 6px;
 }
+#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
+	background-color: var(--source-sidebar-background-hover);
+}
+#source-sidebar div.files > a.selected {
+	background-color: var(--source-sidebar-background-selected);
+}
 #sidebar-toggle > button {
 	font-size: inherit;
 	font-weight: bold;
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index eb66377670c6b..de7db7d438c9f 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -84,6 +84,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 	--crate-search-div-hover-filter: invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg)
 		brightness(113%) contrast(76%);
 	--crate-search-hover-border: #e0e0e0;
+	--source-sidebar-background-selected: #14191f;
+	--source-sidebar-background-hover: #14191f;
 }
 
 h1, h2, h3, h4 {
@@ -208,12 +210,8 @@ pre.rust .kw-2, pre.rust .prelude-ty {}
 	color: #fff;
 }
 #source-sidebar div.files > a:hover, details.dir-entry summary:hover,
-#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
-	background-color: #14191f;
-	color: #ffb44c;
-}
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus,
 #source-sidebar div.files > a.selected {
-	background-color: #14191f;
 	color: #ffb44c;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 44598a6b77866..d8929f3233864 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -79,6 +79,8 @@
 	--crate-search-div-hover-filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg)
 		brightness(100%) contrast(91%);
 	--crate-search-hover-border: #2196f3;
+	--source-sidebar-background-selected: #333;
+	--source-sidebar-background-hover: #444;
 }
 
 .content .item-info::before { color: #ccc; }
@@ -105,14 +107,6 @@ details.rustdoc-toggle > summary::before {
 	color: #888;
 }
 
-#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
-#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
-	background-color: #444;
-}
-#source-sidebar div.files > a.selected {
-	background-color: #333;
-}
-
 .scraped-example-list .scrape-help {
 	border-color: #aaa;
 	color: #eee;
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index f0db14fd59f53..ff6c68635338c 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -76,6 +76,8 @@
 	--crate-search-div-hover-filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg)
 		brightness(96%) contrast(93%);
 	--crate-search-hover-border: #717171;
+	--source-sidebar-background-selected: #fff;
+	--source-sidebar-background-hover: #e0e0e0;
 }
 
 .content .item-info::before { color: #ccc; }
@@ -98,13 +100,6 @@ body.source .example-wrap pre.rust a {
 	color: #888;
 }
 
-#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
-#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
-	background-color: #E0E0E0;
-}
-#source-sidebar div.files > a.selected {
-	background-color: #fff;
-}
 .scraped-example-list .scrape-help {
 	border-color: #555;
 	color: #333;
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
index abf8af77715c9..40ae4af81be45 100644
--- a/src/test/rustdoc-gui/sidebar-source-code-display.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -43,16 +43,24 @@ define-function: (
             "#source-sidebar details[open] > .files a.selected",
             {"color": |color_hover|, "background-color": |background|},
         )),
+
         // Without hover or focus.
         ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})),
         // With focus.
         ("focus", "#sidebar-toggle > button"),
-        ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
+        ("assert-css", (
+            "#sidebar-toggle > button:focus",
+            {"background-color": |background_toggle_hover|},
+        )),
         ("focus", ".search-input"),
         // With hover.
         ("move-cursor-to", "#sidebar-toggle > button"),
-        ("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
-        // Without hover.
+        ("assert-css", (
+            "#sidebar-toggle > button:hover",
+            {"background-color": |background_toggle_hover|},
+        )),
+
+        // Without hover or focus.
         ("assert-css", (
             "#source-sidebar details[open] > .files a:not(.selected)",
             {"color": |color|, "background-color": |background_toggle|},
@@ -60,17 +68,37 @@ define-function: (
         // With focus.
         ("focus", "#source-sidebar details[open] > .files a:not(.selected)"),
         ("wait-for-css", (
-            "#source-sidebar details[open] > .files a:not(.selected)",
+            "#source-sidebar details[open] > .files a:not(.selected):focus",
             {"color": |color_hover|, "background-color": |background_hover|},
         )),
         ("focus", ".search-input"),
         // With hover.
         ("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"),
         ("assert-css", (
-            "#source-sidebar details[open] > .files a:not(.selected)",
+            "#source-sidebar details[open] > .files a:not(.selected):hover",
             {"color": |color_hover|, "background-color": |background_hover|},
         )),
-        // Without hover.
+
+        // Without hover or focus.
+        ("assert-css", (
+            "#source-sidebar .dir-entry summary",
+            {"color": |color|, "background-color": |background_toggle|},
+        )),
+        // With focus.
+        ("focus", "#source-sidebar .dir-entry summary"),
+        ("wait-for-css", (
+            "#source-sidebar .dir-entry summary:focus",
+            {"color": |color_hover|, "background-color": |background_hover|},
+        )),
+        ("focus", ".search-input"),
+        // With hover.
+        ("move-cursor-to", "#source-sidebar .dir-entry summary"),
+        ("assert-css", (
+            "#source-sidebar .dir-entry summary:hover",
+            {"color": |color_hover|, "background-color": |background_hover|},
+        )),
+
+        // Without hover or focus.
         ("assert-css", (
             "#source-sidebar details[open] > .folders > details > summary",
             {"color": |color|, "background-color": |background_toggle|},
@@ -78,14 +106,14 @@ define-function: (
         // With focus.
         ("focus", "#source-sidebar details[open] > .folders > details > summary"),
         ("wait-for-css", (
-            "#source-sidebar details[open] > .folders > details > summary",
+            "#source-sidebar details[open] > .folders > details > summary:focus",
             {"color": |color_hover|, "background-color": |background_hover|},
         )),
         ("focus", ".search-input"),
         // With hover.
         ("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"),
         ("assert-css", (
-            "#source-sidebar details[open] > .folders > details > summary",
+            "#source-sidebar details[open] > .folders > details > summary:hover",
             {"color": |color_hover|, "background-color": |background_hover|},
         )),
     ],
diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs
index dde9745afb785..66e6982d6b4d3 100644
--- a/src/tools/build-manifest/src/versions.rs
+++ b/src/tools/build-manifest/src/versions.rs
@@ -49,10 +49,10 @@ pkg_type! {
     Cargo = "cargo",
     HtmlDocs = "rust-docs",
     RustAnalysis = "rust-analysis",
+    Clippy = "clippy",
+    Rustfmt = "rustfmt",
     Rls = "rls"; preview = true,
     RustAnalyzer = "rust-analyzer"; preview = true,
-    Clippy = "clippy"; preview = true,
-    Rustfmt = "rustfmt"; preview = true,
     LlvmTools = "llvm-tools"; preview = true,
     Miri = "miri"; preview = true,
     JsonDocs = "rust-docs-json"; preview = true,
diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs
index aa346daf7e5f3..388203ee4637f 100644
--- a/src/tools/bump-stage0/src/main.rs
+++ b/src/tools/bump-stage0/src/main.rs
@@ -6,7 +6,7 @@ use std::convert::TryInto;
 
 const PATH: &str = "src/stage0.json";
 const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo"];
-const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview"];
+const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt"];
 
 struct Tool {
     config: Config,
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index ecf8e83375dbf..018f10f258867 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -6,7 +6,7 @@ use clippy_utils::msrvs;
 use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
 use clippy_utils::{extract_msrv_attr, meets_msrv};
 use if_chain::if_chain;
-use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
 use rustc_errors::Applicability;
 use rustc_hir::{
     Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
@@ -576,7 +576,7 @@ fn check_attrs(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribut
     }
 }
 
-fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) {
+fn check_semver(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
     if let LitKind::Str(is, _) = lit.kind {
         if Version::parse(is.as_str()).is_ok() {
             return;
diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs
index 23f55db773e6c..2ac703b957b86 100644
--- a/src/tools/rustfmt/src/attr.rs
+++ b/src/tools/rustfmt/src/attr.rs
@@ -260,9 +260,7 @@ impl Rewrite for ast::NestedMetaItem {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         match self {
             ast::NestedMetaItem::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
-            ast::NestedMetaItem::Literal(ref l) => {
-                rewrite_literal(context, l.token_lit, l.span, shape)
-            }
+            ast::NestedMetaItem::Lit(ref l) => rewrite_literal(context, l.token_lit, l.span, shape),
         }
     }
 }
@@ -527,14 +525,19 @@ pub(crate) trait MetaVisitor<'ast> {
 
     fn visit_meta_word(&mut self, _meta_item: &'ast ast::MetaItem) {}
 
-    fn visit_meta_name_value(&mut self, _meta_item: &'ast ast::MetaItem, _lit: &'ast ast::Lit) {}
+    fn visit_meta_name_value(
+        &mut self,
+        _meta_item: &'ast ast::MetaItem,
+        _lit: &'ast ast::MetaItemLit,
+    ) {
+    }
 
     fn visit_nested_meta_item(&mut self, nm: &'ast ast::NestedMetaItem) {
         match nm {
             ast::NestedMetaItem::MetaItem(ref meta_item) => self.visit_meta_item(meta_item),
-            ast::NestedMetaItem::Literal(ref lit) => self.visit_literal(lit),
+            ast::NestedMetaItem::Lit(ref lit) => self.visit_meta_item_lit(lit),
         }
     }
 
-    fn visit_literal(&mut self, _lit: &'ast ast::Lit) {}
+    fn visit_meta_item_lit(&mut self, _lit: &'ast ast::MetaItemLit) {}
 }
diff --git a/src/tools/rustfmt/src/modules/visitor.rs b/src/tools/rustfmt/src/modules/visitor.rs
index ea67977c17a2b..48431693332a6 100644
--- a/src/tools/rustfmt/src/modules/visitor.rs
+++ b/src/tools/rustfmt/src/modules/visitor.rs
@@ -84,15 +84,19 @@ impl PathVisitor {
 }
 
 impl<'ast> MetaVisitor<'ast> for PathVisitor {
-    fn visit_meta_name_value(&mut self, meta_item: &'ast ast::MetaItem, lit: &'ast ast::Lit) {
+    fn visit_meta_name_value(
+        &mut self,
+        meta_item: &'ast ast::MetaItem,
+        lit: &'ast ast::MetaItemLit,
+    ) {
         if meta_item.has_name(Symbol::intern("path")) && lit.kind.is_str() {
-            self.paths.push(lit_to_str(lit));
+            self.paths.push(meta_item_lit_to_str(lit));
         }
     }
 }
 
 #[cfg(not(windows))]
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn meta_item_lit_to_str(lit: &ast::MetaItemLit) -> String {
     match lit.kind {
         ast::LitKind::Str(symbol, ..) => symbol.to_string(),
         _ => unreachable!(),
@@ -100,7 +104,7 @@ fn lit_to_str(lit: &ast::Lit) -> String {
 }
 
 #[cfg(windows)]
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn meta_item_lit_to_str(lit: &ast::MetaItemLit) -> String {
     match lit.kind {
         ast::LitKind::Str(symbol, ..) => symbol.as_str().replace("/", "\\"),
         _ => unreachable!(),
diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs
index 6bf8cd0c70be0..af0b95430a197 100644
--- a/src/tools/rustfmt/src/overflow.rs
+++ b/src/tools/rustfmt/src/overflow.rs
@@ -125,7 +125,7 @@ impl<'a> OverflowableItem<'a> {
             OverflowableItem::MacroArg(MacroArg::Keyword(..)) => true,
             OverflowableItem::MacroArg(MacroArg::Expr(expr)) => is_simple_expr(expr),
             OverflowableItem::NestedMetaItem(nested_meta_item) => match nested_meta_item {
-                ast::NestedMetaItem::Literal(..) => true,
+                ast::NestedMetaItem::Lit(..) => true,
                 ast::NestedMetaItem::MetaItem(ref meta_item) => {
                     matches!(meta_item.kind, ast::MetaItemKind::Word)
                 }
@@ -169,7 +169,7 @@ impl<'a> OverflowableItem<'a> {
             },
             OverflowableItem::NestedMetaItem(nested_meta_item) if len == 1 => {
                 match nested_meta_item {
-                    ast::NestedMetaItem::Literal(..) => false,
+                    ast::NestedMetaItem::Lit(..) => false,
                     ast::NestedMetaItem::MetaItem(..) => true,
                 }
             }
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index 136a2c7fce24a..3e884419f1a32 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -263,7 +263,7 @@ fn is_skip(meta_item: &MetaItem) -> bool {
 fn is_skip_nested(meta_item: &NestedMetaItem) -> bool {
     match meta_item {
         NestedMetaItem::MetaItem(ref mi) => is_skip(mi),
-        NestedMetaItem::Literal(_) => false,
+        NestedMetaItem::Lit(_) => false,
     }
 }