about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-16 14:24:14 +0000
committerbors <bors@rust-lang.org>2022-04-16 14:24:14 +0000
commitd9b3ff7d34335c5bc0b2afed640b65d64a85fe03 (patch)
tree5e6cfdb26695ef535ca98195430c9f1ddbebede8
parentfebce1fc316f5618d5bb8f05d19e2e3ba868c007 (diff)
parent4ed76271170ed781f0fc079ead9a5997a96f984f (diff)
downloadrust-d9b3ff7d34335c5bc0b2afed640b65d64a85fe03.tar.gz
rust-d9b3ff7d34335c5bc0b2afed640b65d64a85fe03.zip
Auto merge of #96117 - Dylan-DPC:rollup-5traczf, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #95887 (resolve: Create dummy bindings for all unresolved imports)
 - #96023 (couple of clippy::perf fixes)
 - #96035 (Update GitHub Actions actions/checkout Version v2 -> v3)
 - #96038 (docs: add link from zip to unzip)
 - #96047 (:arrow_up: rust-analyzer)
 - #96059 (clarify doc(cfg) wording)
 - #96081 (Make some `usize`-typed masks definitions agnostic to the size of `usize`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--.github/workflows/ci.yml8
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs1
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs2
-rw-r--r--compiler/rustc_resolve/src/imports.rs58
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--library/core/benches/ascii/is_ascii.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs4
-rw-r--r--library/core/src/num/mod.rs21
-rw-r--r--library/core/src/slice/ascii.rs2
-rw-r--r--library/core/src/slice/memchr.rs8
-rw-r--r--library/core/src/str/count.rs6
-rw-r--r--library/core/src/str/validations.rs3
-rw-r--r--src/ci/github-actions/ci.yml4
-rw-r--r--src/doc/unstable-book/src/language-features/doc-cfg.md2
-rw-r--r--src/librustdoc/clean/cfg.rs9
-rw-r--r--src/librustdoc/clean/cfg/tests.rs40
-rw-r--r--src/librustdoc/passes/html_tags.rs2
-rw-r--r--src/test/rustdoc-gui/item-info-overflow.goml4
-rw-r--r--src/test/rustdoc-gui/item-info-width.goml2
-rw-r--r--src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs6
-rw-r--r--src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr11
-rw-r--r--src/test/rustdoc/doc-cfg.rs22
-rw-r--r--src/test/rustdoc/duplicate-cfg.rs18
-rw-r--r--src/test/ui/use/use-super-global-path.rs2
-rw-r--r--src/test/ui/use/use-super-global-path.stderr16
m---------src/tools/rust-analyzer47
28 files changed, 152 insertions, 156 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ff3a8326315..451116f320d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -56,7 +56,7 @@ jobs:
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: configure the PR in which the error message will be posted
@@ -454,7 +454,7 @@ jobs:
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: configure the PR in which the error message will be posted
@@ -567,7 +567,7 @@ jobs:
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: configure the PR in which the error message will be posted
@@ -670,7 +670,7 @@ jobs:
     if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'"
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: publish toolstate
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index 31bb9ed3185..d6e2c8ccdf4 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -372,7 +372,6 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
 
     // Build the type node for each field.
     let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range
-        .clone()
         .map(|variant_index| {
             let variant_struct_type_di_node = super::build_generator_variant_struct_type_di_node(
                 cx,
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index cfad1fc01ab..416bc4e2e3b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1208,7 +1208,7 @@ impl HandlerInner {
             (0, 0) => return,
             (0, _) => self.emitter.emit_diagnostic(&Diagnostic::new(
                 Level::Warning,
-                DiagnosticMessage::Str(warnings.to_owned()),
+                DiagnosticMessage::Str(warnings),
             )),
             (_, 0) => {
                 let _ = self.fatal(&errors);
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 63aac64989d..8f260e1cdb5 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -590,7 +590,7 @@ impl TtParser {
                 (_, 0) => {
                     // Dump all possible `next_mps` into `cur_mps` for the next iteration. Then
                     // process the next token.
-                    self.cur_mps.extend(self.next_mps.drain(..));
+                    self.cur_mps.append(&mut self.next_mps);
                     parser.to_mut().bump();
                 }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 44caa2ac076..58e484e413d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -844,7 +844,7 @@ fn non_exhaustive_match<'p, 'tcx>(
                     format!(
                         "{}{}{} => todo!()",
                         comma,
-                        snippet.strip_prefix(",").unwrap_or(&snippet),
+                        snippet.strip_prefix(',').unwrap_or(&snippet),
                         pattern
                     ),
                 ));
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index aab0c1f9771..01dc727737a 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -310,18 +310,23 @@ impl<'a> Resolver<'a> {
         t
     }
 
-    // Define a "dummy" resolution containing a Res::Err as a placeholder for a
-    // failed resolution
+    // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed resolution,
+    // also mark such failed imports as used to avoid duplicate diagnostics.
     fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
-        if let ImportKind::Single { target, .. } = import.kind {
+        if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
+            if target_bindings.iter().any(|binding| binding.get().is_some()) {
+                return; // Has resolution, do not create the dummy binding
+            }
             let dummy_binding = self.dummy_binding;
             let dummy_binding = self.import(dummy_binding, import);
             self.per_ns(|this, ns| {
                 let key = this.new_key(target, ns);
                 let _ = this.try_define(import.parent_scope.module, key, dummy_binding);
             });
-            // Consider erroneous imports used to avoid duplicate diagnostics.
             self.record_use(target, dummy_binding, false);
+        } else if import.imported_module.get().is_none() {
+            import.used.set(true);
+            self.used_imports.insert(import.id);
         }
     }
 }
@@ -386,7 +391,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             .map(|i| (false, i))
             .chain(indeterminate_imports.into_iter().map(|i| (true, i)))
         {
-            if let Some(err) = self.finalize_import(import) {
+            let unresolved_import_error = self.finalize_import(import);
+
+            // If this import is unresolved then create a dummy import
+            // resolution for it so that later resolve stages won't complain.
+            self.r.import_dummy_binding(import);
+
+            if let Some(err) = unresolved_import_error {
                 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
                     if source.name == kw::SelfLower {
                         // Silence `unresolved import` error if E0429 is already emitted
@@ -396,9 +407,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     }
                 }
 
-                // If the error is a single failed import then create a "fake" import
-                // resolution for it so that later resolve stages won't complain.
-                self.r.import_dummy_binding(import);
                 if prev_root_id.as_u32() != 0
                     && prev_root_id.as_u32() != import.root_id.as_u32()
                     && !errors.is_empty()
@@ -418,8 +426,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     prev_root_id = import.root_id;
                 }
             } else if is_indeterminate {
-                // Consider erroneous imports used to avoid duplicate diagnostics.
-                self.r.used_imports.insert(import.id);
                 let path = import_path_to_string(
                     &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
                     &import.kind,
@@ -553,26 +559,23 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     Err(Undetermined) => indeterminate = true,
                     // Don't update the resolution, because it was never added.
                     Err(Determined) if target.name == kw::Underscore => {}
-                    Err(Determined) => {
+                    Ok(binding) if binding.is_importable() => {
+                        let imported_binding = this.import(binding, import);
+                        target_bindings[ns].set(Some(imported_binding));
+                        this.define(parent, target, ns, imported_binding);
+                    }
+                    source_binding @ (Ok(..) | Err(Determined)) => {
+                        if source_binding.is_ok() {
+                            let msg = format!("`{}` is not directly importable", target);
+                            struct_span_err!(this.session, import.span, E0253, "{}", &msg)
+                                .span_label(import.span, "cannot be imported directly")
+                                .emit();
+                        }
                         let key = this.new_key(target, ns);
                         this.update_resolution(parent, key, |_, resolution| {
                             resolution.single_imports.remove(&Interned::new_unchecked(import));
                         });
                     }
-                    Ok(binding) if !binding.is_importable() => {
-                        let msg = format!("`{}` is not directly importable", target);
-                        struct_span_err!(this.session, import.span, E0253, "{}", &msg)
-                            .span_label(import.span, "cannot be imported directly")
-                            .emit();
-                        // Do not import this illegal binding. Import a dummy binding and pretend
-                        // everything is fine
-                        this.import_dummy_binding(import);
-                    }
-                    Ok(binding) => {
-                        let imported_binding = this.import(binding, import);
-                        target_bindings[ns].set(Some(imported_binding));
-                        this.define(parent, target, ns, imported_binding);
-                    }
                 }
             }
         });
@@ -605,10 +608,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         );
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
         import.vis.set(orig_vis);
-        if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
-            // Consider erroneous imports used to avoid duplicate diagnostics.
-            self.r.used_imports.insert(import.id);
-        }
         let module = match path_res {
             PathResult::Module(module) => {
                 // Consistency checks, analogous to `finalize_macro_resolutions`.
@@ -872,7 +871,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 })
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
-                self.r.import_dummy_binding(import);
                 None
             };
         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index ead1f0126c4..7485c082f4e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2724,9 +2724,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 &format!(
                     "consider annotating `{}` with `#[derive({})]`",
                     trait_pred.skip_binder().self_ty(),
-                    diagnostic_name.to_string(),
+                    diagnostic_name,
                 ),
-                format!("#[derive({})]\n", diagnostic_name.to_string()),
+                format!("#[derive({})]\n", diagnostic_name),
                 Applicability::MaybeIncorrect,
             );
         }
diff --git a/library/core/benches/ascii/is_ascii.rs b/library/core/benches/ascii/is_ascii.rs
index 729b0a04eb6..a42a1dcfe39 100644
--- a/library/core/benches/ascii/is_ascii.rs
+++ b/library/core/benches/ascii/is_ascii.rs
@@ -77,6 +77,6 @@ fn is_ascii_align_to_unrolled(bytes: &[u8]) -> bool {
 
 #[inline]
 fn contains_nonascii(v: usize) -> bool {
-    const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
+    const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; core::mem::size_of::<usize>()]);
     (NONASCII_MASK & v) != 0
 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 53fbe4cbc42..69f06fb06ef 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -470,6 +470,10 @@ pub trait Iterator {
     /// it will first try to advance the first iterator at most one time and if it still yielded an item
     /// try to advance the second iterator at most one time.
     ///
+    /// To 'undo' the result of zipping up two iterators, see [`unzip`].
+    ///
+    /// [`unzip`]: Iterator::unzip
+    ///
     /// # Examples
     ///
     /// Basic usage:
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 8b93cd39d5d..66193eaf5da 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -890,6 +890,27 @@ impl usize {
     widening_impl! { usize, u128, 64, unsigned }
 }
 
+impl usize {
+    /// Returns an `usize` where every byte is equal to `x`.
+    #[inline]
+    pub(crate) const fn repeat_u8(x: u8) -> usize {
+        usize::from_ne_bytes([x; mem::size_of::<usize>()])
+    }
+
+    /// Returns an `usize` where every byte pair is equal to `x`.
+    #[inline]
+    pub(crate) const fn repeat_u16(x: u16) -> usize {
+        let mut r = 0usize;
+        let mut i = 0;
+        while i < mem::size_of::<usize>() {
+            // Use `wrapping_shl` to make it work on targets with 16-bit `usize`
+            r = r.wrapping_shl(16) | (x as usize);
+            i += 2;
+        }
+        r
+    }
+}
+
 /// A classification of floating point numbers.
 ///
 /// This `enum` is used as the return type for [`f32::classify`] and [`f64::classify`]. See
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 9aa5c88a62c..63715a6b86b 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -235,7 +235,7 @@ impl<'a> fmt::Debug for EscapeAscii<'a> {
 /// from `../str/mod.rs`, which does something similar for utf8 validation.
 #[inline]
 fn contains_nonascii(v: usize) -> bool {
-    const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
+    const NONASCII_MASK: usize = usize::repeat_u8(0x80);
     (NONASCII_MASK & v) != 0
 }
 
diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs
index 6da99055f2d..dffeaf6a834 100644
--- a/library/core/src/slice/memchr.rs
+++ b/library/core/src/slice/memchr.rs
@@ -4,12 +4,8 @@
 use crate::cmp;
 use crate::mem;
 
-const LO_U64: u64 = 0x0101010101010101;
-const HI_U64: u64 = 0x8080808080808080;
-
-// Use truncation.
-const LO_USIZE: usize = LO_U64 as usize;
-const HI_USIZE: usize = HI_U64 as usize;
+const LO_USIZE: usize = usize::repeat_u8(0x01);
+const HI_USIZE: usize = usize::repeat_u8(0x80);
 const USIZE_BYTES: usize = mem::size_of::<usize>();
 
 /// Returns `true` if `x` contains any zero byte.
diff --git a/library/core/src/str/count.rs b/library/core/src/str/count.rs
index 5abc2b34c07..28567a7e753 100644
--- a/library/core/src/str/count.rs
+++ b/library/core/src/str/count.rs
@@ -112,7 +112,7 @@ fn do_count_chars(s: &str) -> usize {
 // true)
 #[inline]
 fn contains_non_continuation_byte(w: usize) -> usize {
-    const LSB: usize = 0x0101_0101_0101_0101u64 as usize;
+    const LSB: usize = usize::repeat_u8(0x01);
     ((!w >> 7) | (w >> 6)) & LSB
 }
 
@@ -120,8 +120,8 @@ fn contains_non_continuation_byte(w: usize) -> usize {
 // more efficient.
 #[inline]
 fn sum_bytes_in_usize(values: usize) -> usize {
-    const LSB_SHORTS: usize = 0x0001_0001_0001_0001_u64 as usize;
-    const SKIP_BYTES: usize = 0x00ff_00ff_00ff_00ff_u64 as usize;
+    const LSB_SHORTS: usize = usize::repeat_u16(0x0001);
+    const SKIP_BYTES: usize = usize::repeat_u16(0x00ff);
 
     let pair_sum: usize = (values & SKIP_BYTES) + ((values >> 8) & SKIP_BYTES);
     pair_sum.wrapping_mul(LSB_SHORTS) >> ((USIZE_SIZE - 2) * 8)
diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs
index 0d3dc856be5..04bc665233e 100644
--- a/library/core/src/str/validations.rs
+++ b/library/core/src/str/validations.rs
@@ -112,8 +112,7 @@ where
     Some(ch)
 }
 
-// use truncation to fit u64 into usize
-const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize;
+const NONASCII_MASK: usize = usize::repeat_u8(0x80);
 
 /// Returns `true` if any byte in the word `x` is nonascii (>= 128).
 #[inline]
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 5622422d50f..173ee170c9f 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -99,7 +99,7 @@ x--expand-yaml-anchors--remove:
         run: git config --global core.autocrlf false
 
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
 
@@ -703,7 +703,7 @@ jobs:
     if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
 
diff --git a/src/doc/unstable-book/src/language-features/doc-cfg.md b/src/doc/unstable-book/src/language-features/doc-cfg.md
index e75f1aea992..b15f5ee66ab 100644
--- a/src/doc/unstable-book/src/language-features/doc-cfg.md
+++ b/src/doc/unstable-book/src/language-features/doc-cfg.md
@@ -7,7 +7,7 @@ The tracking issue for this feature is: [#43781]
 The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
 This attribute has two effects:
 
-1. In the annotated item's documentation, there will be a message saying "This is supported on
+1. In the annotated item's documentation, there will be a message saying "Available on
     (platform) only".
 
 2. The item's doc-tests will only run on the specific platform.
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index b72d2624177..0d213a5a2de 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -171,11 +171,8 @@ impl Cfg {
     pub(crate) fn render_long_html(&self) -> String {
         let on = if self.should_use_with_in_description() { "with" } else { "on" };
 
-        let mut msg = format!(
-            "This is supported {} <strong>{}</strong>",
-            on,
-            Display(self, Format::LongHtml)
-        );
+        let mut msg =
+            format!("Available {on} <strong>{}</strong>", Display(self, Format::LongHtml));
         if self.should_append_only_to_description() {
             msg.push_str(" only");
         }
@@ -187,7 +184,7 @@ impl Cfg {
     pub(crate) fn render_long_plain(&self) -> String {
         let on = if self.should_use_with_in_description() { "with" } else { "on" };
 
-        let mut msg = format!("This is supported {} {}", on, Display(self, Format::LongPlain));
+        let mut msg = format!("Available {on} {}", Display(self, Format::LongPlain));
         if self.should_append_only_to_description() {
             msg.push_str(" only");
         }
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 275d1b3ebd9..ece3fcb18b6 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -359,81 +359,73 @@ fn test_render_short_html() {
 #[test]
 fn test_render_long_html() {
     create_default_session_globals_then(|| {
-        assert_eq!(
-            word_cfg("unix").render_long_html(),
-            "This is supported on <strong>Unix</strong> only."
-        );
+        assert_eq!(word_cfg("unix").render_long_html(), "Available on <strong>Unix</strong> only.");
         assert_eq!(
             name_value_cfg("target_os", "macos").render_long_html(),
-            "This is supported on <strong>macOS</strong> only."
+            "Available on <strong>macOS</strong> only."
         );
         assert_eq!(
             name_value_cfg("target_os", "wasi").render_long_html(),
-            "This is supported on <strong>WASI</strong> only."
+            "Available on <strong>WASI</strong> only."
         );
         assert_eq!(
             name_value_cfg("target_pointer_width", "16").render_long_html(),
-            "This is supported on <strong>16-bit</strong> only."
+            "Available on <strong>16-bit</strong> only."
         );
         assert_eq!(
             name_value_cfg("target_endian", "little").render_long_html(),
-            "This is supported on <strong>little-endian</strong> only."
+            "Available on <strong>little-endian</strong> only."
         );
         assert_eq!(
             (!word_cfg("windows")).render_long_html(),
-            "This is supported on <strong>non-Windows</strong> only."
+            "Available on <strong>non-Windows</strong> only."
         );
         assert_eq!(
             (word_cfg("unix") & word_cfg("windows")).render_long_html(),
-            "This is supported on <strong>Unix and Windows</strong> only."
+            "Available on <strong>Unix and Windows</strong> only."
         );
         assert_eq!(
             (word_cfg("unix") | word_cfg("windows")).render_long_html(),
-            "This is supported on <strong>Unix or Windows</strong> only."
+            "Available on <strong>Unix or Windows</strong> only."
         );
         assert_eq!(
             (word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions"))
                 .render_long_html(),
-            "This is supported on <strong>Unix and Windows and debug-assertions enabled\
-             </strong> only."
+            "Available on <strong>Unix and Windows and debug-assertions enabled</strong> only."
         );
         assert_eq!(
             (word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions"))
                 .render_long_html(),
-            "This is supported on <strong>Unix or Windows or debug-assertions enabled\
-             </strong> only."
+            "Available on <strong>Unix or Windows or debug-assertions enabled</strong> only."
         );
         assert_eq!(
             (!(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")))
                 .render_long_html(),
-            "This is supported on <strong>neither Unix nor Windows nor debug-assertions \
-             enabled</strong>."
+            "Available on <strong>neither Unix nor Windows nor debug-assertions enabled</strong>."
         );
         assert_eq!(
             ((word_cfg("unix") & name_value_cfg("target_arch", "x86_64"))
                 | (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")))
             .render_long_html(),
-            "This is supported on <strong>Unix and x86-64, or Windows and 64-bit</strong> only."
+            "Available on <strong>Unix and x86-64, or Windows and 64-bit</strong> only."
         );
         assert_eq!(
             (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(),
-            "This is supported on <strong>not (Unix and Windows)</strong>."
+            "Available on <strong>not (Unix and Windows)</strong>."
         );
         assert_eq!(
             ((word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix"))
                 .render_long_html(),
-            "This is supported on <strong>(debug-assertions enabled or Windows) and Unix\
-             </strong> only."
+            "Available on <strong>(debug-assertions enabled or Windows) and Unix</strong> only."
         );
         assert_eq!(
             name_value_cfg("target_feature", "sse2").render_long_html(),
-            "This is supported with <strong>target feature <code>sse2</code></strong> only."
+            "Available with <strong>target feature <code>sse2</code></strong> only."
         );
         assert_eq!(
             (name_value_cfg("target_arch", "x86_64") & name_value_cfg("target_feature", "sse2"))
                 .render_long_html(),
-            "This is supported on <strong>x86-64 and target feature \
-             <code>sse2</code></strong> only."
+            "Available on <strong>x86-64 and target feature <code>sse2</code></strong> only."
         );
     })
 }
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 00e10c6d5a7..a620ffa9878 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -215,7 +215,7 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
                     // We don't try to detect stuff `<like, this>` because that's not valid HTML,
                     // and we don't try to detect stuff `<like this>` because that's not valid Rust.
                     if let Some(Some(generics_start)) = (is_open_tag
-                        && dox[..range.end].ends_with(">"))
+                        && dox[..range.end].ends_with('>'))
                     .then(|| extract_path_backwards(&dox, range.start))
                     {
                         let generics_sp = match super::source_span_for_markdown_range(
diff --git a/src/test/rustdoc-gui/item-info-overflow.goml b/src/test/rustdoc-gui/item-info-overflow.goml
index 4ff719bfb7d..d6385e2acb8 100644
--- a/src/test/rustdoc-gui/item-info-overflow.goml
+++ b/src/test/rustdoc-gui/item-info-overflow.goml
@@ -8,7 +8,7 @@ assert-property: (".item-info", {"scrollWidth": "890"})
 // Just to be sure we're comparing the correct "item-info":
 assert-text: (
     ".item-info",
-    "This is supported on Android or Linux or Emscripten or DragonFly BSD",
+    "Available on Android or Linux or Emscripten or DragonFly BSD",
     STARTS_WITH,
 )
 
@@ -23,6 +23,6 @@ assert-property: ("#impl-SimpleTrait .item-info", {"scrollWidth": "866"})
 // Just to be sure we're comparing the correct "item-info":
 assert-text: (
     "#impl-SimpleTrait .item-info",
-    "This is supported on Android or Linux or Emscripten or DragonFly BSD",
+    "Available on Android or Linux or Emscripten or DragonFly BSD",
     STARTS_WITH,
 )
diff --git a/src/test/rustdoc-gui/item-info-width.goml b/src/test/rustdoc-gui/item-info-width.goml
index 7a32d902910..8b6d355a8f1 100644
--- a/src/test/rustdoc-gui/item-info-width.goml
+++ b/src/test/rustdoc-gui/item-info-width.goml
@@ -4,5 +4,5 @@ goto: file://|DOC_PATH|/lib2/struct.Foo.html
 size: (1100, 800)
 // We check that ".item-info" is bigger than its content.
 assert-css: (".item-info", {"width": "790px"})
-assert-css: (".item-info .stab", {"width": "340px"})
+assert-css: (".item-info .stab", {"width": "289px"})
 assert-position: (".item-info .stab", {"x": 295})
diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs
new file mode 100644
index 00000000000..c71e5bee12e
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs
@@ -0,0 +1,6 @@
+// Regression test for issue #95879.
+
+use unresolved_crate::module::Name; //~ ERROR failed to resolve
+
+/// [Name]
+pub struct S;
diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
new file mode 100644
index 00000000000..b60ab6050d7
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
@@ -0,0 +1,11 @@
+error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`?
+  --> $DIR/unresolved-import-recovery.rs:3:5
+   |
+LL | use unresolved_crate::module::Name;
+   |     ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`?
+
+error: Compilation failed, aborting rustdoc
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs
index 9465c8a35c8..4cddb0b76d4 100644
--- a/src/test/rustdoc/doc-cfg.rs
+++ b/src/test/rustdoc/doc-cfg.rs
@@ -4,21 +4,21 @@
 // @has doc_cfg/struct.Portable.html
 // @!has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' ''
 // @has - '//*[@id="method.unix_and_arm_only_function"]' 'fn unix_and_arm_only_function()'
-// @has - '//*[@class="stab portability"]' 'This is supported on Unix and ARM only.'
+// @has - '//*[@class="stab portability"]' 'Available on Unix and ARM only.'
 // @has - '//*[@id="method.wasi_and_wasm32_only_function"]' 'fn wasi_and_wasm32_only_function()'
-// @has - '//*[@class="stab portability"]' 'This is supported on WASI and WebAssembly only.'
+// @has - '//*[@class="stab portability"]' 'Available on WASI and WebAssembly only.'
 pub struct Portable;
 
 // @has doc_cfg/unix_only/index.html \
 //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-//  'This is supported on Unix only.'
+//  'Available on Unix only.'
 // @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\AARM\Z'
 // @count - '//*[@class="stab portability"]' 2
 #[doc(cfg(unix))]
 pub mod unix_only {
     // @has doc_cfg/unix_only/fn.unix_only_function.html \
     //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-    //  'This is supported on Unix only.'
+    //  'Available on Unix only.'
     // @count - '//*[@class="stab portability"]' 1
     pub fn unix_only_function() {
         content::should::be::irrelevant();
@@ -26,7 +26,7 @@ pub mod unix_only {
 
     // @has doc_cfg/unix_only/trait.ArmOnly.html \
     //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-    //  'This is supported on Unix and ARM only.'
+    //  'Available on Unix and ARM only.'
     // @count - '//*[@class="stab portability"]' 1
     #[doc(cfg(target_arch = "arm"))]
     pub trait ArmOnly {
@@ -41,14 +41,14 @@ pub mod unix_only {
 
 // @has doc_cfg/wasi_only/index.html \
 //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-//  'This is supported on WASI only.'
+//  'Available on WASI only.'
 // @matches - '//*[@class="item-left module-item"]//*[@class="stab portability"]' '\AWebAssembly\Z'
 // @count - '//*[@class="stab portability"]' 2
 #[doc(cfg(target_os = "wasi"))]
 pub mod wasi_only {
     // @has doc_cfg/wasi_only/fn.wasi_only_function.html \
     //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-    //  'This is supported on WASI only.'
+    //  'Available on WASI only.'
     // @count - '//*[@class="stab portability"]' 1
     pub fn wasi_only_function() {
         content::should::be::irrelevant();
@@ -56,7 +56,7 @@ pub mod wasi_only {
 
     // @has doc_cfg/wasi_only/trait.Wasm32Only.html \
     //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-    //  'This is supported on WASI and WebAssembly only.'
+    //  'Available on WASI and WebAssembly only.'
     // @count - '//*[@class="stab portability"]' 1
     #[doc(cfg(target_arch = "wasm32"))]
     pub trait Wasm32Only {
@@ -78,7 +78,7 @@ pub mod wasi_only {
 
 // @has doc_cfg/fn.uses_target_feature.html
 // @has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-//        'This is supported with target feature avx only.'
+//        'Available with target feature avx only.'
 #[target_feature(enable = "avx")]
 pub unsafe fn uses_target_feature() {
     content::should::be::irrelevant();
@@ -86,7 +86,7 @@ pub unsafe fn uses_target_feature() {
 
 // @has doc_cfg/fn.uses_cfg_target_feature.html
 // @has - '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-//        'This is supported with target feature avx only.'
+//        'Available with target feature avx only.'
 #[doc(cfg(target_feature = "avx"))]
 pub fn uses_cfg_target_feature() {
     uses_target_feature();
@@ -95,7 +95,7 @@ pub fn uses_cfg_target_feature() {
 // multiple attributes should be allowed
 // @has doc_cfg/fn.multiple_attrs.html \
 //  '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \
-//  'This is supported on x and y and z only.'
+//  'Available on x and y and z only.'
 #[doc(cfg(x))]
 #[doc(cfg(y), cfg(z))]
 pub fn multiple_attrs() {}
diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs
index 886ec675030..18f3900b263 100644
--- a/src/test/rustdoc/duplicate-cfg.rs
+++ b/src/test/rustdoc/duplicate-cfg.rs
@@ -3,7 +3,7 @@
 
 // @has 'foo/index.html'
 // @matches '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]' '^sync$'
-// @has '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate feature `sync` only'
+// @has '-' '//*[@class="item-left module-item"]//*[@class="stab portability"]/@title' 'Available on crate feature `sync` only'
 
 // @has 'foo/struct.Foo.html'
 // @has '-' '//*[@class="stab portability"]' 'sync'
@@ -13,41 +13,41 @@
 pub struct Foo;
 
 // @has 'foo/bar/index.html'
-// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.'
+// @has '-' '//*[@class="stab portability"]' 'Available on crate feature sync only.'
 #[doc(cfg(feature = "sync"))]
 pub mod bar {
     // @has 'foo/bar/struct.Bar.html'
-    // @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.'
+    // @has '-' '//*[@class="stab portability"]' 'Available on crate feature sync only.'
     #[doc(cfg(feature = "sync"))]
     pub struct Bar;
 }
 
 // @has 'foo/baz/index.html'
-// @has '-' '//*[@class="stab portability"]' 'This is supported on crate features sync and send only.'
+// @has '-' '//*[@class="stab portability"]' 'Available on crate features sync and send only.'
 #[doc(cfg(all(feature = "sync", feature = "send")))]
 pub mod baz {
     // @has 'foo/baz/struct.Baz.html'
-    // @has '-' '//*[@class="stab portability"]' 'This is supported on crate features sync and send only.'
+    // @has '-' '//*[@class="stab portability"]' 'Available on crate features sync and send only.'
     #[doc(cfg(feature = "sync"))]
     pub struct Baz;
 }
 
 // @has 'foo/qux/index.html'
-// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.'
+// @has '-' '//*[@class="stab portability"]' 'Available on crate feature sync only.'
 #[doc(cfg(feature = "sync"))]
 pub mod qux {
     // @has 'foo/qux/struct.Qux.html'
-    // @has '-' '//*[@class="stab portability"]' 'This is supported on crate features sync and send only.'
+    // @has '-' '//*[@class="stab portability"]' 'Available on crate features sync and send only.'
     #[doc(cfg(all(feature = "sync", feature = "send")))]
     pub struct Qux;
 }
 
 // @has 'foo/quux/index.html'
-// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send and foo only.'
+// @has '-' '//*[@class="stab portability"]' 'Available on crate feature sync and crate feature send and foo only.'
 #[doc(cfg(all(feature = "sync", feature = "send", foo)))]
 pub mod quux {
     // @has 'foo/quux/struct.Quux.html'
-    // @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send and foo and bar only.'
+    // @has '-' '//*[@class="stab portability"]' 'Available on crate feature sync and crate feature send and foo and bar only.'
     #[doc(cfg(all(feature = "send", feature = "sync", bar)))]
     pub struct Quux;
 }
diff --git a/src/test/ui/use/use-super-global-path.rs b/src/test/ui/use/use-super-global-path.rs
index 27a4a653b49..64bfd14b7e7 100644
--- a/src/test/ui/use/use-super-global-path.rs
+++ b/src/test/ui/use/use-super-global-path.rs
@@ -9,7 +9,7 @@ mod foo {
 
     pub fn g() {
         use ::super::main; //~ ERROR global paths cannot start with `super`
-        main(); //~ ERROR cannot find function `main` in this scope
+        main();
     }
 }
 
diff --git a/src/test/ui/use/use-super-global-path.stderr b/src/test/ui/use/use-super-global-path.stderr
index edde26c1fc1..7014a12e9dd 100644
--- a/src/test/ui/use/use-super-global-path.stderr
+++ b/src/test/ui/use/use-super-global-path.stderr
@@ -16,18 +16,6 @@ error[E0433]: failed to resolve: global paths cannot start with `super`
 LL |         use ::super::main;
    |               ^^^^^ global paths cannot start with `super`
 
-error[E0425]: cannot find function `main` in this scope
-  --> $DIR/use-super-global-path.rs:12:9
-   |
-LL |         main();
-   |         ^^^^ not found in this scope
-   |
-help: consider importing this function
-   |
-LL |     use main;
-   |
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0425, E0433.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject 46d7ee68f26285db26b2640f2c07d6332380c75
+Subproject 24cf957627d5ede1b395f92ff871fd7a281d49a