diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 491be052bca2..8a72382cf90d 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -2123,20 +2123,27 @@ function preLoadCss(cssUrl) {
return;
}
but.onclick = () => {
- // Most page titles are '- in - Rust', except
- // modules (which don't have the first part) and keywords/primitives
- // (which don't have a module path)
- const titleElement = document.querySelector("title");
- const title = titleElement && titleElement.textContent ?
- titleElement.textContent.replace(" - Rust", "") : "";
- const [item, module] = title.split(" in ");
- const path = [item];
- if (module !== undefined) {
- path.unshift(module);
- }
+ // We get the path from the "breadcrumbs" and the actual item name.
+ let path = "";
+ // @ts-expect-error
+ const heading = document.getElementById(MAIN_ID).querySelector(".main-heading");
- copyContentToClipboard(path.join("::"));
- copyButtonAnimation(but);
+ if (heading) {
+ const breadcrumbs = heading.querySelector(".rustdoc-breadcrumbs");
+ if (breadcrumbs) {
+ // @ts-expect-error
+ path = breadcrumbs.innerText;
+ if (path.length > 0) {
+ path += "::";
+ }
+ }
+
+ // @ts-expect-error
+ path += heading.querySelector("h1 > span").innerText;
+
+ copyContentToClipboard(path);
+ copyButtonAnimation(but);
+ }
};
/**
diff --git a/tests/rustdoc-gui/copy-path.goml b/tests/rustdoc-gui/copy-path.goml
index e8766688f8d5..61e63d7822c7 100644
--- a/tests/rustdoc-gui/copy-path.goml
+++ b/tests/rustdoc-gui/copy-path.goml
@@ -18,3 +18,19 @@ assert-size: ("#copy-path.clicked", {"width": |width|, "height": |height|})
wait-for: "#copy-path:not(.clicked)"
// We check that the size is still the same.
assert-size: ("#copy-path:not(.clicked)", {"width": |width|, "height": |height|})
+
+// Check the path for a module.
+go-to: "file://" + |DOC_PATH| + "/test_docs/foreign_impl_order/index.html"
+click: "#copy-path"
+// We wait for the new text to appear.
+wait-for: "#copy-path.clicked"
+// We check that the clipboard value is the expected one.
+assert-clipboard: "test_docs::foreign_impl_order"
+
+// Check the path for the crate.
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+click: "#copy-path"
+// We wait for the new text to appear.
+wait-for: "#copy-path.clicked"
+// We check that the clipboard value is the expected one.
+assert-clipboard: "test_docs"