about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-17 22:30:51 +0000
committerbors <bors@rust-lang.org>2020-09-17 22:30:51 +0000
commit755064bef62d3c1a6793ef9d87e112489ad579c9 (patch)
tree4d076899f3bcbe930611df8d0b79676bfb0d706d
parentaa30bf3442be752e9f8dc9ff7fe70c258d41ac6b (diff)
parent557e2bc101285c2e30e8125a3d7e8bfb796575a3 (diff)
Auto merge of #76852 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports

* Ignore rustc_private items from std docs #76571
* Fix HashMap visualizers in Visual Studio (Code) #76389
* Account for version number in NtIdent hack #76331
* Account for async functions when suggesting new named lifetime #75867
* Fix loading pretty-printers in rust-lldb script #76015

This also bumps to the released stable compiler.
-rw-r--r--src/bootstrap/dist.rs1
-rw-r--r--src/etc/lldb_commands1
-rw-r--r--src/etc/natvis/libstd.natvis4
-rwxr-xr-xsrc/etc/rust-lldb5
-rw-r--r--src/librustc_ast/token.rs16
-rw-r--r--src/librustc_resolve/late/diagnostics.rs3
-rw-r--r--src/librustdoc/clean/inline.rs19
-rw-r--r--src/stage0.txt4
-rw-r--r--src/test/rustdoc/auxiliary/real_gimli.rs13
-rw-r--r--src/test/rustdoc/auxiliary/realcore.rs15
-rw-r--r--src/test/rustdoc/issue-75588.rs18
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs31
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout5
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs7
-rw-r--r--src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs7
-rw-r--r--src/test/ui/regions/regions-name-undeclared.rs8
-rw-r--r--src/test/ui/regions/regions-name-undeclared.stderr40
-rw-r--r--src/tools/linkchecker/main.rs10
18 files changed, 170 insertions, 37 deletions
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index f0b2254be9e..d021feafbe4 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -647,6 +647,7 @@ impl Step for DebuggerScripts {
 
             cp_debugger_script("lldb_lookup.py");
             cp_debugger_script("lldb_providers.py");
+            cp_debugger_script("lldb_commands")
         }
     }
 }
diff --git a/src/etc/lldb_commands b/src/etc/lldb_commands
index f470c62d899..979f2fa7ae8 100644
--- a/src/etc/lldb_commands
+++ b/src/etc/lldb_commands
@@ -1,4 +1,3 @@
-command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_lookup.py\"
 type synthetic add -l lldb_lookup.synthetic_lookup -x \".*\" --category Rust
 type summary add -F lldb_lookup.summary_lookup  -e -x -h \"^(alloc::([a-z_]+::)+)String$\" --category Rust
 type summary add -F lldb_lookup.summary_lookup  -e -x -h \"^&str$\" --category Rust
diff --git a/src/etc/natvis/libstd.natvis b/src/etc/natvis/libstd.natvis
index 4e81173d3d0..f791979800f 100644
--- a/src/etc/natvis/libstd.natvis
+++ b/src/etc/natvis/libstd.natvis
@@ -41,7 +41,7 @@
           <If Condition="(base.table.ctrl.pointer[i] &amp; 0x80) == 0">
             <!-- Bucket is populated -->
             <Exec>n--</Exec>
-            <Item Name="{static_cast&lt;tuple&lt;$T1, $T2&gt;*&gt;(base.table.ctrl.pointer)[-(i + 1)].__0}">static_cast&lt;tuple&lt;$T1, $T2&gt;*&gt;(base.table.ctrl.pointer)[-(i + 1)].__1</Item>
+            <Item Name="{((tuple&lt;$T1, $T2&gt;*)base.table.ctrl.pointer)[-(i + 1)].__0}">((tuple&lt;$T1, $T2&gt;*)base.table.ctrl.pointer)[-(i + 1)].__1</Item>
           </If>
           <Exec>i++</Exec>
         </Loop>
@@ -65,7 +65,7 @@
           <If Condition="(map.base.table.ctrl.pointer[i] &amp; 0x80) == 0">
             <!-- Bucket is populated -->
             <Exec>n--</Exec>
-            <Item>static_cast&lt;$T1*&gt;(map.base.table.ctrl.pointer)[-(i + 1)]</Item>
+            <Item>(($T1*)map.base.table.ctrl.pointer)[-(i + 1)]</Item>
           </If>
           <Exec>i++</Exec>
         </Loop>
diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb
index 28b32ef1ad5..bce72f1bad6 100755
--- a/src/etc/rust-lldb
+++ b/src/etc/rust-lldb
@@ -30,5 +30,8 @@ EOF
     fi
 fi
 
+script_import="command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_lookup.py\""
+commands_file="$RUSTC_SYSROOT/lib/rustlib/etc/lldb_commands"
+
 # Call LLDB with the commands added to the argument list
-exec "$lldb" --source-before-file ./lldb_commands "$@"
+exec "$lldb" --one-line-before-file "$script_import" --source-before-file "$commands_file" "$@"
diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs
index 4a8bf6b4f19..7e58aab5a7a 100644
--- a/src/librustc_ast/token.rs
+++ b/src/librustc_ast/token.rs
@@ -821,9 +821,19 @@ impl Nonterminal {
             if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind {
                 let filename = source_map.span_to_filename(orig_span);
                 if let FileName::Real(RealFileName::Named(path)) = filename {
-                    if (path.ends_with("time-macros-impl/src/lib.rs")
-                        && macro_name == sym::impl_macros)
-                        || (path.ends_with("js-sys/src/lib.rs") && macro_name == sym::arrays)
+                    let matches_prefix = |prefix| {
+                        // Check for a path that ends with 'prefix*/src/lib.rs'
+                        let mut iter = path.components().rev();
+                        iter.next().and_then(|p| p.as_os_str().to_str()) == Some("lib.rs")
+                            && iter.next().and_then(|p| p.as_os_str().to_str()) == Some("src")
+                            && iter
+                                .next()
+                                .and_then(|p| p.as_os_str().to_str())
+                                .map_or(false, |p| p.starts_with(prefix))
+                    };
+
+                    if (macro_name == sym::impl_macros && matches_prefix("time-macros-impl"))
+                        || (macro_name == sym::arrays && matches_prefix("js-sys"))
                     {
                         let snippet = source_map.span_to_snippet(orig_span);
                         if snippet.as_deref() == Ok("$name") {
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 2549aee52ad..d392967af38 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -1222,6 +1222,9 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                                 synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
                                 ..
                             } => false,
+                            hir::GenericParamKind::Lifetime {
+                                kind: hir::LifetimeParamKind::Elided,
+                            } => false,
                             _ => true,
                         }) {
                         (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref))
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 38fa8a402c4..f67b689bb0e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -337,18 +337,13 @@ pub fn build_impl(
     // reachable in rustdoc generated documentation
     if !did.is_local() {
         if let Some(traitref) = associated_trait {
-            if !cx.renderinfo.borrow().access_levels.is_public(traitref.def_id) {
+            let did = traitref.def_id;
+            if !cx.renderinfo.borrow().access_levels.is_public(did) {
                 return;
             }
-        }
 
-        // Skip foreign unstable traits from lists of trait implementations and
-        // such. This helps prevent dependencies of the standard library, for
-        // example, from getting documented as "traits `u32` implements" which
-        // isn't really too helpful.
-        if let Some(trait_did) = associated_trait {
-            if let Some(stab) = cx.tcx.lookup_stability(trait_did.def_id) {
-                if stab.level.is_unstable() {
+            if let Some(stab) = tcx.lookup_stability(did) {
+                if stab.level.is_unstable() && stab.feature == sym::rustc_private {
                     return;
                 }
             }
@@ -372,6 +367,12 @@ pub fn build_impl(
             if !cx.renderinfo.borrow().access_levels.is_public(did) {
                 return;
             }
+
+            if let Some(stab) = tcx.lookup_stability(did) {
+                if stab.level.is_unstable() && stab.feature == sym::rustc_private {
+                    return;
+                }
+            }
         }
     }
 
diff --git a/src/stage0.txt b/src/stage0.txt
index ab9da4dd822..67c19a3380c 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.(x+1).0` for Cargo where they were released on `date`.
 
-date: 2020-08-24
+date: 2020-08-27
 rustc: 1.46.0
 cargo: 0.47.0
 
@@ -40,4 +40,4 @@ cargo: 0.47.0
 # looking at a beta source tarball and it's uncommented we'll shortly comment it
 # out.
 
-dev: 1
+#dev: 1
diff --git a/src/test/rustdoc/auxiliary/real_gimli.rs b/src/test/rustdoc/auxiliary/real_gimli.rs
new file mode 100644
index 00000000000..80d5c4ba8bb
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/real_gimli.rs
@@ -0,0 +1,13 @@
+// aux-build:realcore.rs
+
+#![crate_name = "real_gimli"]
+#![feature(staged_api, extremely_unstable)]
+#![unstable(feature = "rustc_private", issue = "none")]
+
+extern crate realcore;
+
+#[unstable(feature = "rustc_private", issue = "none")]
+pub struct EndianSlice;
+
+#[unstable(feature = "rustc_private", issue = "none")]
+impl realcore::Deref for EndianSlice {}
diff --git a/src/test/rustdoc/auxiliary/realcore.rs b/src/test/rustdoc/auxiliary/realcore.rs
new file mode 100644
index 00000000000..e0a906df002
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/realcore.rs
@@ -0,0 +1,15 @@
+#![crate_name = "realcore"]
+#![feature(staged_api)]
+#![unstable(feature = "extremely_unstable", issue = "none")]
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+pub struct Foo {}
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+pub trait Join {}
+
+#[unstable(feature = "extremely_unstable_foo", issue = "none")]
+impl Join for Foo {}
+
+#[stable(feature = "faked_deref", since = "1.47.0")]
+pub trait Deref {}
diff --git a/src/test/rustdoc/issue-75588.rs b/src/test/rustdoc/issue-75588.rs
new file mode 100644
index 00000000000..835ed02ac00
--- /dev/null
+++ b/src/test/rustdoc/issue-75588.rs
@@ -0,0 +1,18 @@
+// ignore-tidy-linelength
+// aux-build:realcore.rs
+// aux-build:real_gimli.rs
+
+// Ensure unstably exported traits have their Implementors sections.
+
+#![crate_name = "foo"]
+#![feature(extremely_unstable_foo)]
+
+extern crate realcore;
+extern crate real_gimli;
+
+// issue #74672
+// @!has foo/trait.Deref.html '//*[@id="impl-Deref-for-EndianSlice"]//code' 'impl Deref for EndianSlice'
+pub use realcore::Deref;
+
+// @has foo/trait.Join.html '//*[@id="impl-Join-for-Foo"]//code' 'impl Join for Foo'
+pub use realcore::Join;
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
index 35c101587de..bc82a2ff196 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
@@ -13,18 +13,37 @@ extern crate std;
 // place of a `None`-delimited group. This allows us to maintain
 // backwards compatibility for older versions of these crates.
 
-include!("js-sys/src/lib.rs");
-include!("time-macros-impl/src/lib.rs");
+mod no_version {
+    include!("js-sys/src/lib.rs");
+    include!("time-macros-impl/src/lib.rs");
 
-macro_rules! other {
-    ($name:ident) => {
-        #[my_macro] struct Three($name);
+    macro_rules! other {
+        ($name:ident) => {
+            #[my_macro] struct Three($name);
+        }
     }
+
+    struct Foo;
+    impl_macros!(Foo);
+    arrays!(Foo);
+    other!(Foo);
 }
 
-fn main() {
+mod with_version {
+    include!("js-sys-0.3.17/src/lib.rs");
+    include!("time-macros-impl-0.1.0/src/lib.rs");
+
+    macro_rules! other {
+        ($name:ident) => {
+            #[my_macro] struct Three($name);
+        }
+    }
+
     struct Foo;
     impl_macros!(Foo);
     arrays!(Foo);
     other!(Foo);
 }
+
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
index d519daab1f2..e7645280a75 100644
--- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
+++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
@@ -1,3 +1,6 @@
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl/src/lib.rs:5:21: 5:27 (#5) }, Ident { ident: "One", span: $DIR/time-macros-impl/src/lib.rs:5:28: 5:31 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:27:18: 27:21 (#0) }], span: $DIR/time-macros-impl/src/lib.rs:5:31: 5:38 (#5) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl/src/lib.rs:5:38: 5:39 (#5) }]
 Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#9) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#9) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:28:13: 28:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#9) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#9) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:21:21: 21:27 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:21:28: 21:33 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:21:34: 21:39 (#13) }], span: $DIR/group-compat-hack.rs:21:33: 21:40 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:21:40: 21:41 (#13) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:22:25: 22:31 (#13) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:22:32: 22:37 (#13) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:12: 29:15 (#0) }], span: $DIR/group-compat-hack.rs:22:38: 22:43 (#13) }], span: $DIR/group-compat-hack.rs:22:37: 22:44 (#13) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:22:44: 22:45 (#13) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#19) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#19) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:43:18: 43:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#19) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#19) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#23) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#23) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:13: 44:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#23) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#23) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:38:25: 38:31 (#27) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:38:32: 38:37 (#27) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:45:12: 45:15 (#0) }], span: $DIR/group-compat-hack.rs:38:38: 38:43 (#27) }], span: $DIR/group-compat-hack.rs:38:37: 38:44 (#27) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:38:44: 38:45 (#27) }]
diff --git a/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs
new file mode 100644
index 00000000000..d1a66940ebf
--- /dev/null
+++ b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs
@@ -0,0 +1,7 @@
+// ignore-test this is not a test
+
+macro_rules! arrays {
+    ($name:ident) => {
+        #[my_macro] struct Two($name);
+    }
+}
diff --git a/src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs b/src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs
new file mode 100644
index 00000000000..c94c3579209
--- /dev/null
+++ b/src/test/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs
@@ -0,0 +1,7 @@
+// ignore-test this is not a test
+
+macro_rules! impl_macros {
+    ($name:ident) => {
+        #[my_macro] struct One($name);
+    }
+}
diff --git a/src/test/ui/regions/regions-name-undeclared.rs b/src/test/ui/regions/regions-name-undeclared.rs
index 044c6889772..b8f50a40c45 100644
--- a/src/test/ui/regions/regions-name-undeclared.rs
+++ b/src/test/ui/regions/regions-name-undeclared.rs
@@ -1,3 +1,4 @@
+// edition:2018
 // Check that lifetime resolver enforces the lifetime name scoping
 // rules correctly in various scenarios.
 
@@ -47,4 +48,11 @@ fn fn_types(a: &'a isize, //~ ERROR undeclared lifetime
 {
 }
 
+struct Bug {}
+impl Bug {
+    async fn buggy(&self) -> &'a str { //~ ERROR use of undeclared lifetime name `'a`
+        todo!()
+    }
+}
+
 pub fn main() {}
diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr
index 57d39d59c8b..ad0e7bd5afb 100644
--- a/src/test/ui/regions/regions-name-undeclared.stderr
+++ b/src/test/ui/regions/regions-name-undeclared.stderr
@@ -1,5 +1,5 @@
 error[E0261]: use of undeclared lifetime name `'b`
-  --> $DIR/regions-name-undeclared.rs:15:24
+  --> $DIR/regions-name-undeclared.rs:16:24
    |
 LL |     fn m4(&self, arg: &'b isize) { }
    |                        ^^ undeclared lifetime
@@ -15,7 +15,7 @@ LL |     fn m4<'b>(&self, arg: &'b isize) { }
    |          ^^^^
 
 error[E0261]: use of undeclared lifetime name `'b`
-  --> $DIR/regions-name-undeclared.rs:16:12
+  --> $DIR/regions-name-undeclared.rs:17:12
    |
 LL |     fn m5(&'b self) { }
    |            ^^ undeclared lifetime
@@ -31,7 +31,7 @@ LL |     fn m5<'b>(&'b self) { }
    |          ^^^^
 
 error[E0261]: use of undeclared lifetime name `'b`
-  --> $DIR/regions-name-undeclared.rs:17:27
+  --> $DIR/regions-name-undeclared.rs:18:27
    |
 LL |     fn m6(&self, arg: Foo<'b>) { }
    |                           ^^ undeclared lifetime
@@ -47,7 +47,7 @@ LL |     fn m6<'b>(&self, arg: Foo<'b>) { }
    |          ^^^^
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/regions-name-undeclared.rs:25:22
+  --> $DIR/regions-name-undeclared.rs:26:22
    |
 LL |     type X = Option<&'a isize>;
    |           -          ^^ undeclared lifetime
@@ -57,7 +57,7 @@ LL |     type X = Option<&'a isize>;
    = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/regions-name-undeclared.rs:27:13
+  --> $DIR/regions-name-undeclared.rs:28:13
    |
 LL |     enum E {
    |           - help: consider introducing lifetime `'a` here: `<'a>`
@@ -67,7 +67,7 @@ LL |         E1(&'a isize)
    = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/regions-name-undeclared.rs:30:13
+  --> $DIR/regions-name-undeclared.rs:31:13
    |
 LL |     struct S {
    |             - help: consider introducing lifetime `'a` here: `<'a>`
@@ -77,7 +77,7 @@ LL |         f: &'a isize
    = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/regions-name-undeclared.rs:32:14
+  --> $DIR/regions-name-undeclared.rs:33:14
    |
 LL |     fn f(a: &'a isize) { }
    |         -    ^^ undeclared lifetime
@@ -87,7 +87,7 @@ LL |     fn f(a: &'a isize) { }
    = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/regions-name-undeclared.rs:40:17
+  --> $DIR/regions-name-undeclared.rs:41:17
    |
 LL | fn fn_types(a: &'a isize,
    |            -    ^^ undeclared lifetime
@@ -97,7 +97,7 @@ LL | fn fn_types(a: &'a isize,
    = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
 
 error[E0261]: use of undeclared lifetime name `'b`
-  --> $DIR/regions-name-undeclared.rs:42:36
+  --> $DIR/regions-name-undeclared.rs:43:36
    |
 LL | ...                   &'b isize,
    |                        ^^ undeclared lifetime
@@ -114,7 +114,7 @@ LL |             b: Box<dyn for<'a, 'b> FnOnce(&'a isize,
    |                              ^^^^
 
 error[E0261]: use of undeclared lifetime name `'b`
-  --> $DIR/regions-name-undeclared.rs:45:36
+  --> $DIR/regions-name-undeclared.rs:46:36
    |
 LL | ...                   &'b isize)>,
    |                        ^^ undeclared lifetime
@@ -131,7 +131,7 @@ LL |             b: Box<dyn for<'a, 'b> FnOnce(&'a isize,
    |                              ^^^^
 
 error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/regions-name-undeclared.rs:46:17
+  --> $DIR/regions-name-undeclared.rs:47:17
    |
 LL | fn fn_types(a: &'a isize,
    |            - help: consider introducing lifetime `'a` here: `<'a>`
@@ -141,6 +141,22 @@ LL |             c: &'a isize)
    |
    = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
 
-error: aborting due to 11 previous errors
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/regions-name-undeclared.rs:53:31
+   |
+LL |     async fn buggy(&self) -> &'a str {
+   |                               ^^ undeclared lifetime
+   |
+   = help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
+help: consider introducing lifetime `'a` here
+   |
+LL | impl<'a> Bug {
+   |     ^^^^
+help: consider introducing lifetime `'a` here
+   |
+LL |     async fn buggy<'a>(&self) -> &'a str {
+   |                   ^^^^
+
+error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0261`.
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index b7ceba1e282..d83fd7b2922 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -141,6 +141,16 @@ fn is_exception(file: &Path, link: &str) -> bool {
     if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) {
         entry.1.contains(&link)
     } else {
+        // FIXME(#63351): Concat trait in alloc/slice reexported in primitive page
+        //
+        // NOTE: This cannot be added to `LINKCHECK_EXCEPTIONS` because the resolved path
+        // calculated in `check` function is outside `build/<triple>/doc` dir.
+        // So the `strip_prefix` method just returns the old absolute broken path.
+        if file.ends_with("std/primitive.slice.html") {
+            if link.ends_with("primitive.slice.html") {
+                return true;
+            }
+        }
         false
     }
 }