about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs6
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs16
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/derive.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs2
-rw-r--r--compiler/rustc_expand/src/expand.rs6
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs2
-rw-r--r--compiler/rustc_expand/src/placeholders.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs6
-rw-r--r--compiler/rustc_lint/src/builtin.rs18
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs8
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs21
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/imports.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--src/bootstrap/bin/rustc.rs2
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/bootstrap/builder.rs2
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh2
-rwxr-xr-xsrc/ci/pgo.sh38
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/test/ui/hidden-doc-associated-item.rs15
-rw-r--r--src/test/ui/let-else/issue-89960.rs7
-rw-r--r--src/test/ui/let-else/issue-89960.stderr12
-rw-r--r--src/test/ui/let-else/let-else-if.rs10
-rw-r--r--src/test/ui/let-else/let-else-if.stderr18
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed4
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs4
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr9
34 files changed, 176 insertions, 60 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 5f17008bdc2..927d7c6aaf6 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -62,7 +62,7 @@ impl NestedMetaItem {
         self.meta_item().and_then(|meta_item| meta_item.ident())
     }
     pub fn name_or_empty(&self) -> Symbol {
-        self.ident().unwrap_or_else(Ident::invalid).name
+        self.ident().unwrap_or_else(Ident::empty).name
     }
 
     /// Gets the string value if `self` is a `MetaItem` and the `MetaItem` is a
@@ -131,7 +131,7 @@ impl Attribute {
         }
     }
     pub fn name_or_empty(&self) -> Symbol {
-        self.ident().unwrap_or_else(Ident::invalid).name
+        self.ident().unwrap_or_else(Ident::empty).name
     }
 
     pub fn value_str(&self) -> Option<Symbol> {
@@ -166,7 +166,7 @@ impl MetaItem {
         if self.path.segments.len() == 1 { Some(self.path.segments[0].ident) } else { None }
     }
     pub fn name_or_empty(&self) -> Symbol {
-        self.ident().unwrap_or_else(Ident::invalid).name
+        self.ident().unwrap_or_else(Ident::empty).name
     }
 
     // Example:
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index ba86036577a..f673ab2f3ef 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1060,7 +1060,7 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
         let item_vis =
             Visibility { kind: VisibilityKind::Public, span: span.shrink_to_lo(), tokens: None };
         let item = P(Item {
-            ident: Ident::invalid(),
+            ident: Ident::empty(),
             attrs,
             id: DUMMY_NODE_ID,
             vis: item_vis,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 245199e3751..92b482e90ee 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1435,7 +1435,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         trace!("registering opaque type with id {:#?}", opaque_ty_id);
         let opaque_ty_item = hir::Item {
             def_id: opaque_ty_id,
-            ident: Ident::invalid(),
+            ident: Ident::empty(),
             kind: opaque_ty_item_kind,
             vis: respan(self.lower_span(span.shrink_to_lo()), hir::VisibilityKind::Inherited),
             span: self.lower_span(opaque_ty_span),
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 246d2e3208c..d5ff4c6766f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -45,12 +45,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let item_msg;
         let reason;
         let mut opt_source = None;
-        let access_place_desc = self.describe_place(access_place.as_ref());
+        let access_place_desc = self.describe_any_place(access_place.as_ref());
         debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
 
         match the_place_err {
             PlaceRef { local, projection: [] } => {
-                item_msg = format!("`{}`", access_place_desc.unwrap());
+                item_msg = access_place_desc;
                 if access_place.as_local().is_some() {
                     reason = ", as it is not declared as mutable".to_string();
                 } else {
@@ -83,7 +83,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     // If we deref an immutable ref then the suggestion here doesn't help.
                     return;
                 } else {
-                    item_msg = format!("`{}`", access_place_desc.unwrap());
+                    item_msg = access_place_desc;
                     if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
                         reason = ", as it is not declared as mutable".to_string();
                     } else {
@@ -96,17 +96,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             PlaceRef { local, projection: [ProjectionElem::Deref] }
                 if self.body.local_decls[local].is_ref_for_guard() =>
             {
-                item_msg = format!("`{}`", access_place_desc.unwrap());
+                item_msg = access_place_desc;
                 reason = ", as it is immutable for the pattern guard".to_string();
             }
             PlaceRef { local, projection: [ProjectionElem::Deref] }
                 if self.body.local_decls[local].is_ref_to_static() =>
             {
                 if access_place.projection.len() == 1 {
-                    item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
+                    item_msg = format!("immutable static item {}", access_place_desc);
                     reason = String::new();
                 } else {
-                    item_msg = format!("`{}`", access_place_desc.unwrap());
+                    item_msg = access_place_desc;
                     let local_info = &self.body.local_decls[local].local_info;
                     if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
                         let static_name = &self.infcx.tcx.item_name(def_id);
@@ -121,7 +121,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     && proj_base.is_empty()
                     && !self.upvars.is_empty()
                 {
-                    item_msg = format!("`{}`", access_place_desc.unwrap());
+                    item_msg = access_place_desc;
                     debug_assert!(
                         self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_region_ptr()
                     );
@@ -147,7 +147,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     });
                     let pointer_type = source.describe_for_immutable_place(self.infcx.tcx);
                     opt_source = Some(source);
-                    if let Some(desc) = access_place_desc {
+                    if let Some(desc) = self.describe_place(access_place.as_ref()) {
                         item_msg = format!("`{}`", desc);
                         reason = match error_access {
                             AccessKind::Mutate => format!(", which is behind {}", pointer_type),
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index c032364c008..198287f608e 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -812,7 +812,7 @@ pub fn expand_global_asm<'cx>(
         Ok(args) => {
             if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
                 MacEager::items(smallvec![P(ast::Item {
-                    ident: Ident::invalid(),
+                    ident: Ident::empty(),
                     attrs: Vec::new(),
                     id: ast::DUMMY_NODE_ID,
                     kind: ast::ItemKind::GlobalAsm(inline_asm),
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index 241c90c1571..31a35b9b7b4 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -85,7 +85,7 @@ impl MultiItemModifier for Expander {
 fn dummy_annotatable() -> Annotatable {
     Annotatable::GenericParam(ast::GenericParam {
         id: ast::DUMMY_NODE_ID,
-        ident: Ident::invalid(),
+        ident: Ident::empty(),
         attrs: Default::default(),
         bounds: Default::default(),
         is_placeholder: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index cd78c016caa..a225b328ab6 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -724,7 +724,7 @@ impl<'a> TraitDef<'a> {
 
         cx.item(
             self.span,
-            Ident::invalid(),
+            Ident::empty(),
             a,
             ast::ItemKind::Impl(Box::new(ast::ImplKind {
                 unsafety,
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index bcf95719db5..fa389a51115 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -178,7 +178,7 @@ fn inject_impl_of_structural_trait(
 
     let newitem = cx.item(
         span,
-        Ident::invalid(),
+        Ident::empty(),
         attrs,
         ItemKind::Impl(Box::new(ImplKind {
             unsafety: ast::Unsafe::No,
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index e0d57267525..e106f6014a3 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -77,7 +77,7 @@ pub fn inject(
 
     let use_item = cx.item(
         span,
-        Ident::invalid(),
+        Ident::empty(),
         vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
         ast::ItemKind::Use(ast::UseTree {
             prefix: cx.path(span, import_path),
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index f548e2848a7..65f0719ba99 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -383,7 +383,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 Unsafe::No,
                 ModKind::Loaded(krate.items, Inline::Yes, krate.span)
             ),
-            ident: Ident::invalid(),
+            ident: Ident::empty(),
             id: ast::DUMMY_NODE_ID,
             vis: ast::Visibility {
                 span: krate.span.shrink_to_lo(),
@@ -1426,7 +1426,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                     _ => unreachable!(),
                 })
             }
-            ast::ItemKind::Mod(_, ref mut mod_kind) if ident != Ident::invalid() => {
+            ast::ItemKind::Mod(_, ref mut mod_kind) if ident != Ident::empty() => {
                 let (file_path, dir_path, dir_ownership) = match mod_kind {
                     ModKind::Loaded(_, inline, _) => {
                         // Inline `mod foo { ... }`, but we still need to push directories.
@@ -1508,7 +1508,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
             _ => {
                 item.attrs = attrs;
                 // The crate root is special - don't assign an ID to it.
-                if !(matches!(item.kind, ast::ItemKind::Mod(..)) && ident == Ident::invalid()) {
+                if !(matches!(item.kind, ast::ItemKind::Mod(..)) && ident == Ident::empty()) {
                     assign_id!(self, &mut item.id, || noop_flat_map_item(item, self))
                 } else {
                     noop_flat_map_item(item, self)
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index 363cc72b52c..dedc6c618b9 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -204,7 +204,7 @@ fn parse_tree(
                         pprust::token_to_string(&token),
                     );
                     sess.span_diagnostic.span_err(token.span, &msg);
-                    TokenTree::MetaVar(token.span, Ident::invalid())
+                    TokenTree::MetaVar(token.span, Ident::empty())
                 }
 
                 // There are no more tokens. Just return the `$` we already have.
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index 8e78fcbb8db..12b6bc7bbe7 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -23,7 +23,7 @@ pub fn placeholder(
         }
     }
 
-    let ident = Ident::invalid();
+    let ident = Ident::empty();
     let attrs = Vec::new();
     let vis = vis.unwrap_or(ast::Visibility {
         span: DUMMY_SP,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 11d0178e93b..f0ee21645f3 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -121,7 +121,7 @@ impl LifetimeName {
         match *self {
             LifetimeName::ImplicitObjectLifetimeDefault
             | LifetimeName::Implicit
-            | LifetimeName::Error => Ident::invalid(),
+            | LifetimeName::Error => Ident::empty(),
             LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
             LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
             LifetimeName::Param(param_name) => param_name.ident(),
@@ -233,7 +233,7 @@ impl<'hir> PathSegment<'hir> {
     }
 
     pub fn invalid() -> Self {
-        Self::from_ident(Ident::invalid())
+        Self::from_ident(Ident::empty())
     }
 
     pub fn args(&self) -> &GenericArgs<'hir> {
@@ -310,7 +310,7 @@ impl GenericArg<'_> {
     }
 
     pub fn is_synthetic(&self) -> bool {
-        matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::invalid())
+        matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::empty())
     }
 
     pub fn descr(&self) -> &'static str {
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 57c1c8f3ecb..c228ecb03fd 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -657,6 +657,24 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             return;
         }
 
+        // If the method is an impl for an item with docs_hidden, don't doc.
+        if method_context(cx, impl_item.hir_id()) == MethodLateContext::PlainImpl {
+            let parent = cx.tcx.hir().get_parent_did(impl_item.hir_id());
+            let impl_ty = cx.tcx.type_of(parent);
+            let outerdef = match impl_ty.kind() {
+                ty::Adt(def, _) => Some(def.did),
+                ty::Foreign(def_id) => Some(*def_id),
+                _ => None,
+            };
+            let is_hidden = match outerdef {
+                Some(id) => cx.tcx.is_doc_hidden(id),
+                None => false,
+            };
+            if is_hidden {
+                return;
+            }
+        }
+
         let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
         self.check_missing_docs_attrs(cx, impl_item.def_id, impl_item.span, article, desc);
     }
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index e6f56b0be93..c30ab4c957a 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -443,7 +443,7 @@ impl<'hir> Map<'hir> {
     pub fn body_param_names(&self, id: BodyId) -> impl Iterator<Item = Ident> + 'hir {
         self.body(id).params.iter().map(|arg| match arg.pat.kind {
             PatKind::Binding(_, _, ident, _) => ident,
-            _ => Ident::new(kw::Empty, rustc_span::DUMMY_SP),
+            _ => Ident::empty(),
         })
     }
 
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 624390a406f..1d9c3a4f3cf 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -216,7 +216,7 @@ impl<'a> Parser<'a> {
                 return Err(e);
             }
 
-            (Ident::invalid(), ItemKind::Use(tree))
+            (Ident::empty(), ItemKind::Use(tree))
         } else if self.check_fn_front_matter(def_final) {
             // FUNCTION ITEM
             let (ident, sig, generics, body) = self.parse_fn(attrs, req_name, lo)?;
@@ -287,7 +287,7 @@ impl<'a> Parser<'a> {
             return Ok(None);
         } else if macros_allowed && self.check_path() {
             // MACRO INVOCATION ITEM
-            (Ident::invalid(), ItemKind::MacCall(self.parse_item_macro(vis)?))
+            (Ident::empty(), ItemKind::MacCall(self.parse_item_macro(vis)?))
         } else {
             return Ok(None);
         };
@@ -586,7 +586,7 @@ impl<'a> Parser<'a> {
             }
         };
 
-        Ok((Ident::invalid(), item_kind))
+        Ok((Ident::empty(), item_kind))
     }
 
     fn parse_item_list<T>(
@@ -933,7 +933,7 @@ impl<'a> Parser<'a> {
         let abi = self.parse_abi(); // ABI?
         let items = self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?;
         let module = ast::ForeignMod { unsafety, abi, items };
-        Ok((Ident::invalid(), ItemKind::ForeignMod(module)))
+        Ok((Ident::empty(), ItemKind::ForeignMod(module)))
     }
 
     /// Parses a foreign item (one in an `extern { ... }` block).
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index c4569c07db4..01e751ea8b5 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -16,7 +16,7 @@ use rustc_ast::{
 };
 use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt};
 use rustc_ast::{StmtKind, DUMMY_NODE_ID};
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::symbol::{kw, sym};
 
@@ -300,6 +300,12 @@ impl<'a> Parser<'a> {
             None => LocalKind::Decl,
             Some(init) => {
                 if self.eat_keyword(kw::Else) {
+                    if self.token.is_keyword(kw::If) {
+                        // `let...else if`. Emit the same error that `parse_block()` would,
+                        // but explicitly point out that this pattern is not allowed.
+                        let msg = "conditional `else if` is not supported for `let...else`";
+                        return Err(self.error_block_no_opening_brace_msg(msg));
+                    }
                     let els = self.parse_block()?;
                     self.check_let_else_init_bool_expr(&init);
                     self.check_let_else_init_trailing_brace(&init);
@@ -392,10 +398,9 @@ impl<'a> Parser<'a> {
         Ok(block)
     }
 
-    fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
+    fn error_block_no_opening_brace_msg(&mut self, msg: &str) -> DiagnosticBuilder<'a> {
         let sp = self.token.span;
-        let tok = super::token_descr(&self.token);
-        let mut e = self.struct_span_err(sp, &format!("expected `{{`, found {}", tok));
+        let mut e = self.struct_span_err(sp, msg);
         let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
 
         // Check to see if the user has written something like
@@ -435,7 +440,13 @@ impl<'a> Parser<'a> {
             _ => {}
         }
         e.span_label(sp, "expected `{`");
-        Err(e)
+        e
+    }
+
+    fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
+        let tok = super::token_descr(&self.token);
+        let msg = format!("expected `{{`, found {}", tok);
+        Err(self.error_block_no_opening_brace_msg(&msg))
     }
 
     /// Parses a block. Inner attributes are allowed.
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 05675e086d7..38fb1c760bd 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1327,7 +1327,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 if fst.ident.span.rust_2018() && !fst.ident.is_path_segment_keyword() =>
             {
                 // Insert a placeholder that's later replaced by `self`/`super`/etc.
-                path.insert(0, Segment::from_ident(Ident::invalid()));
+                path.insert(0, Segment::from_ident(Ident::empty()));
             }
             _ => return None,
         }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 515b2c3fd27..936ab81914a 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -978,7 +978,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
                     // 2 segments, so the `resolve_path` above won't trigger it.
                     let mut full_path = import.module_path.clone();
-                    full_path.push(Segment::from_ident(Ident::invalid()));
+                    full_path.push(Segment::from_ident(Ident::empty()));
                     self.r.lint_if_path_starts_with_module(
                         import.crate_lint(),
                         &full_path,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index fddb225345f..ae148624a90 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1453,7 +1453,7 @@ impl Ident {
     }
 
     #[inline]
-    pub fn invalid() -> Ident {
+    pub fn empty() -> Ident {
         Ident::with_dummy_span(kw::Empty)
     }
 
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index ac8bbfe102d..ed53a98e9a5 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -146,7 +146,7 @@ fn main() {
     }
 
     let is_test = args.iter().any(|a| a == "--test");
-    if verbose > 1 {
+    if verbose > 2 {
         let rust_env_vars =
             env::vars().filter(|(k, _)| k.starts_with("RUST") || k.starts_with("CARGO"));
         let prefix = if is_test { "[RUSTC-SHIM] rustc --test" } else { "[RUSTC-SHIM] rustc" };
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index dc1447b4ae4..0c5a0cbc06e 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -980,7 +980,7 @@ class RustBuild(object):
                 self.cargo()))
         args = [self.cargo(), "build", "--manifest-path",
                 os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")]
-        for _ in range(1, self.verbose):
+        for _ in range(0, self.verbose):
             args.append("--verbose")
         if self.use_locked_deps:
             args.append("--locked")
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 6750f7a549d..ac1841b6913 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1483,7 +1483,7 @@ impl<'a> Builder<'a> {
             cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
         }
 
-        for _ in 1..self.verbosity {
+        for _ in 0..self.verbosity {
             cargo.arg("-v");
         }
 
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
index ed5edfec4e1..562be752f84 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
@@ -4,7 +4,7 @@ set -ex
 
 source shared.sh
 
-LLVM=llvmorg-12.0.1
+LLVM=llvmorg-13.0.0
 
 mkdir llvm-project
 cd llvm-project
diff --git a/src/ci/pgo.sh b/src/ci/pgo.sh
index e35e3e670cc..29ef13a60fb 100755
--- a/src/ci/pgo.sh
+++ b/src/ci/pgo.sh
@@ -4,9 +4,13 @@ set -euxo pipefail
 
 rm -rf /tmp/rustc-pgo
 
+# We collect LLVM profiling information and rustc profiling information in
+# separate phases. This increases build time -- though not by a huge amount --
+# but prevents any problems from arising due to different profiling runtimes
+# being simultaneously linked in.
+
 python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
     --stage 2 library/std \
-    --rust-profile-generate=/tmp/rustc-pgo \
     --llvm-profile-generate
 
 # Profile libcore compilation in opt-level=0 and opt-level=3
@@ -15,6 +19,29 @@ RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
 RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
     --crate-type=lib -Copt-level=3 ../library/core/src/lib.rs
 
+# Merge the profile data we gathered for LLVM
+# Note that this uses the profdata from the clang we used to build LLVM,
+# which likely has a different version than our in-tree clang.
+/rustroot/bin/llvm-profdata \
+    merge -o /tmp/llvm-pgo.profdata ./build/$PGO_HOST/llvm/build/profiles
+
+# Rustbuild currently doesn't support rebuilding LLVM when PGO options
+# change (or any other llvm-related options); so just clear out the relevant
+# directories ourselves.
+rm -r ./build/$PGO_HOST/llvm ./build/$PGO_HOST/lld
+
+# Okay, LLVM profiling is done, switch to rustc PGO.
+
+python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
+    --stage 2 library/std \
+    --rust-profile-generate=/tmp/rustc-pgo
+
+# Profile libcore compilation in opt-level=0 and opt-level=3
+RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
+    --crate-type=lib ../library/core/src/lib.rs
+RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
+    --crate-type=lib -Copt-level=3 ../library/core/src/lib.rs
+
 cp -r /tmp/rustc-perf ./
 chown -R $(whoami): ./rustc-perf
 cd rustc-perf
@@ -46,18 +73,13 @@ cd /checkout/obj
 ./build/$PGO_HOST/llvm/bin/llvm-profdata \
     merge -o /tmp/rustc-pgo.profdata /tmp/rustc-pgo
 
-# Merge the profile data we gathered for LLVM
-# Note that this uses the profdata from the clang we used to build LLVM,
-# which likely has a different version than our in-tree clang.
-/rustroot/bin/llvm-profdata \
-    merge -o /tmp/llvm-pgo.profdata ./build/$PGO_HOST/llvm/build/profiles
-
 # Rustbuild currently doesn't support rebuilding LLVM when PGO options
 # change (or any other llvm-related options); so just clear out the relevant
 # directories ourselves.
 rm -r ./build/$PGO_HOST/llvm ./build/$PGO_HOST/lld
 
-# This produces the actual final set of artifacts.
+# This produces the actual final set of artifacts, using both the LLVM and rustc
+# collected profiling data.
 $@ \
     --rust-profile-use=/tmp/rustc-pgo.profdata \
     --llvm-profile-use=/tmp/llvm-pgo.profdata
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index d4cea8b4a9d..9dab0023ba3 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1450,6 +1450,10 @@ crate enum Type {
     ImplTrait(Vec<GenericBound>),
 }
 
+// `Type` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+rustc_data_structures::static_assert_size!(Type, 72);
+
 crate trait GetDefId {
     /// Use this method to get the [`DefId`] of a [`clean`] AST node.
     /// This will return [`None`] when called on a primitive [`clean::Type`].
diff --git a/src/test/ui/hidden-doc-associated-item.rs b/src/test/ui/hidden-doc-associated-item.rs
new file mode 100644
index 00000000000..d431f9e899c
--- /dev/null
+++ b/src/test/ui/hidden-doc-associated-item.rs
@@ -0,0 +1,15 @@
+// check-pass
+// See issue #85526.
+// This test should produce no warnings.
+
+#![deny(missing_docs)]
+//! Crate docs
+
+#[doc(hidden)]
+pub struct Foo;
+
+impl Foo {
+    pub fn bar() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/let-else/issue-89960.rs b/src/test/ui/let-else/issue-89960.rs
new file mode 100644
index 00000000000..8fd55adbfd4
--- /dev/null
+++ b/src/test/ui/let-else/issue-89960.rs
@@ -0,0 +1,7 @@
+#![feature(let_else)]
+
+fn main() {
+    // FIXME: more precise diagnostics
+    let Some(ref mut meow) = Some(()) else { return };
+    //~^ ERROR: cannot borrow value as mutable, as `val` is not declared as mutable
+}
diff --git a/src/test/ui/let-else/issue-89960.stderr b/src/test/ui/let-else/issue-89960.stderr
new file mode 100644
index 00000000000..697f04d6d27
--- /dev/null
+++ b/src/test/ui/let-else/issue-89960.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow value as mutable, as `val` is not declared as mutable
+  --> $DIR/issue-89960.rs:5:14
+   |
+LL |     let Some(ref mut meow) = Some(()) else { return };
+   |     ---------^^^^^^^^^^^^-----------------------------
+   |     |        |
+   |     |        cannot borrow as mutable
+   |     help: consider changing this to be mutable: `mut val`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/let-else/let-else-if.rs b/src/test/ui/let-else/let-else-if.rs
new file mode 100644
index 00000000000..c3a17330d6e
--- /dev/null
+++ b/src/test/ui/let-else/let-else-if.rs
@@ -0,0 +1,10 @@
+#![feature(let_else)]
+
+fn main() {
+    let Some(_) = Some(()) else if true {
+        //~^ ERROR conditional `else if` is not supported for `let...else`
+        return;
+    } else {
+        return;
+    };
+}
diff --git a/src/test/ui/let-else/let-else-if.stderr b/src/test/ui/let-else/let-else-if.stderr
new file mode 100644
index 00000000000..38c739fd850
--- /dev/null
+++ b/src/test/ui/let-else/let-else-if.stderr
@@ -0,0 +1,18 @@
+error: conditional `else if` is not supported for `let...else`
+  --> $DIR/let-else-if.rs:4:33
+   |
+LL |     let Some(_) = Some(()) else if true {
+   |                                 ^^ expected `{`
+   |
+help: try placing this code inside a block
+   |
+LL ~     let Some(_) = Some(()) else { if true {
+LL +
+LL +         return;
+LL +     } else {
+LL +         return;
+LL ~     } };
+   |
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
index 2ec0efe4c10..95b8c6dfe89 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
@@ -11,6 +11,6 @@ fn main() {
     Symbol::intern("foo") == rustc_span::sym::clippy;
     Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower;
     Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper;
-    Ident::invalid().name == rustc_span::sym::clippy;
-    rustc_span::sym::clippy == Ident::invalid().name;
+    Ident::empty().name == rustc_span::sym::clippy;
+    rustc_span::sym::clippy == Ident::empty().name;
 }
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
index 87e1b3a2ee7..ad6937cf60a 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
@@ -11,6 +11,6 @@ fn main() {
     Symbol::intern("foo").as_str() == "clippy";
     Symbol::intern("foo").to_string() == "self";
     Symbol::intern("foo").to_ident_string() != "Self";
-    &*Ident::invalid().as_str() == "clippy";
-    "clippy" == Ident::invalid().to_string();
+    &*Ident::empty().as_str() == "clippy";
+    "clippy" == Ident::empty().to_string();
 }
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
index b1284b7c8ff..8e04d447fbc 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
@@ -26,14 +26,13 @@ LL |     Symbol::intern("foo").to_ident_string() != "Self";
 error: unnecessary `Symbol` to string conversion
   --> $DIR/unnecessary_symbol_str.rs:14:5
    |
-LL |     &*Ident::invalid().as_str() == "clippy";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::invalid().name == rustc_span::sym::clippy`
+LL |     &*Ident::empty().as_str() == "clippy";
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy`
 
 error: unnecessary `Symbol` to string conversion
   --> $DIR/unnecessary_symbol_str.rs:15:5
    |
-LL |     "clippy" == Ident::invalid().to_string();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::invalid().name`
+LL |     "clippy" == Ident::empty().to_string();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name`
 
 error: aborting due to 5 previous errors
-