about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs6
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs5
-rw-r--r--library/core/src/num/nonzero.rs21
-rw-r--r--library/std/src/os/unix/net/ancillary.rs8
-rwxr-xr-xsrc/ci/docker/scripts/fuchsia-test-runner.py237
-rw-r--r--src/doc/rustc/src/platform-support/fuchsia.md19
-rw-r--r--src/librustdoc/html/static/js/main.js10
-rw-r--r--src/librustdoc/html/static/js/search.js44
-rw-r--r--tests/mir-opt/spanview_block.main.built.after.html3
-rw-r--r--tests/mir-opt/spanview_statement.main.built.after.html3
-rw-r--r--tests/mir-opt/spanview_terminator.main.built.after.html3
-rw-r--r--tests/rustdoc-gui/setting-go-to-only-result.goml9
-rw-r--r--tests/ui/asm/parse-error.rs (renamed from tests/ui/asm/x86_64/parse-error.rs)34
-rw-r--r--tests/ui/asm/parse-error.stderr (renamed from tests/ui/asm/x86_64/parse-error.stderr)175
-rw-r--r--tests/ui/asm/x86_64/x86_64_parse_error.rs21
-rw-r--r--tests/ui/asm/x86_64/x86_64_parse_error.stderr44
16 files changed, 355 insertions, 287 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 5217e317adf..9734fc2b36d 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -379,16 +379,12 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
     }
 
     let mut new_abis = Vec::new();
-    loop {
+    while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
         match p.parse_str_lit() {
             Ok(str_lit) => {
                 new_abis.push((str_lit.symbol_unescaped, str_lit.span));
             }
             Err(opt_lit) => {
-                // If the non-string literal is a closing paren then it's the end of the list and is fine
-                if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
-                    break;
-                }
                 let span = opt_lit.map_or(p.token.span, |lit| lit.span);
                 let mut err =
                     p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index 6b036194381..730c551576a 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -15,8 +15,9 @@ const ANNOTATION_LEFT_BRACKET: char = '\u{298a}'; // Unicode `Z NOTATION RIGHT B
 const ANNOTATION_RIGHT_BRACKET: char = '\u{2989}'; // Unicode `Z NOTATION LEFT BINDING BRACKET`
 const NEW_LINE_SPAN: &str = "</span>\n<span class=\"line\">";
 const HEADER: &str = r#"<!DOCTYPE html>
-<html>
-<head>"#;
+<html lang="en">
+<head>
+<meta charset="utf-8">"#;
 const START_BODY: &str = r#"</head>
 <body>"#;
 const FOOTER: &str = r#"</body>
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 7f06e170ad0..5939dedbd1d 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -348,7 +348,7 @@ macro_rules! nonzero_unsigned_operations {
                 }
 
                 /// Adds an unsigned integer to a non-zero value.
-                #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
+                #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
                 ///
                 /// # Examples
                 ///
@@ -579,7 +579,7 @@ macro_rules! nonzero_signed_operations {
 
                 /// Checked absolute value.
                 /// Checks for overflow and returns [`None`] if
-                #[doc = concat!("`self == ", stringify!($Int), "::MIN`.")]
+                #[doc = concat!("`self == ", stringify!($Ty), "::MIN`.")]
                 /// The result cannot be zero.
                 ///
                 /// # Example
@@ -800,7 +800,8 @@ macro_rules! nonzero_signed_operations {
                     self.get().is_negative()
                 }
 
-                /// Checked negation. Computes `-self`, returning `None` if `self == i32::MIN`.
+                /// Checked negation. Computes `-self`,
+                #[doc = concat!("returning `None` if `self == ", stringify!($Ty), "::MIN`.")]
                 ///
                 /// # Example
                 ///
@@ -859,8 +860,10 @@ macro_rules! nonzero_signed_operations {
                     ((unsafe { $Ty::new_unchecked(result) }), overflow)
                 }
 
-                /// Saturating negation. Computes `-self`, returning `MAX` if
-                /// `self == i32::MIN` instead of overflowing.
+                /// Saturating negation. Computes `-self`,
+                #[doc = concat!("returning [`", stringify!($Ty), "::MAX`]")]
+                #[doc = concat!("if `self == ", stringify!($Ty), "::MIN`")]
+                /// instead of overflowing.
                 ///
                 /// # Example
                 ///
@@ -993,7 +996,7 @@ macro_rules! nonzero_unsigned_signed_operations {
                 }
 
                 /// Multiplies two non-zero integers together.
-                #[doc = concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")]
+                #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
                 ///
                 /// # Examples
                 ///
@@ -1102,11 +1105,11 @@ macro_rules! nonzero_unsigned_signed_operations {
                 #[doc = sign_dependent_expr!{
                     $signedness ?
                     if signed {
-                        concat!("Return [`", stringify!($Int), "::MIN`] ",
-                                    "or [`", stringify!($Int), "::MAX`] on overflow.")
+                        concat!("Return [`", stringify!($Ty), "::MIN`] ",
+                                    "or [`", stringify!($Ty), "::MAX`] on overflow.")
                     }
                     if unsigned {
-                        concat!("Return [`", stringify!($Int), "::MAX`] on overflow.")
+                        concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")
                     }
                 }]
                 ///
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 814f1c7c283..218536689fd 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -11,7 +11,13 @@ use crate::slice::from_raw_parts;
 use crate::sys::net::Socket;
 
 // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
-#[cfg(all(doc, not(target_os = "linux"), not(target_os = "android"), not(target_os = "netbsd")))]
+#[cfg(all(
+    doc,
+    not(target_os = "linux"),
+    not(target_os = "android"),
+    not(target_os = "netbsd"),
+    not(target_os = "freebsd")
+))]
 #[allow(non_camel_case_types)]
 mod libc {
     pub use libc::c_int;
diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py
index 78a8a6662ea..73cf3de6a46 100755
--- a/src/ci/docker/scripts/fuchsia-test-runner.py
+++ b/src/ci/docker/scripts/fuchsia-test-runner.py
@@ -25,13 +25,9 @@ from typing import ClassVar, List, Optional
 
 @dataclass
 class TestEnvironment:
-    rust_dir: str
+    rust_build_dir: str
     sdk_dir: str
     target: str
-    package_server_pid: Optional[int] = None
-    emu_addr: Optional[str] = None
-    libstd_name: Optional[str] = None
-    libtest_name: Optional[str] = None
     verbose: bool = False
 
     @staticmethod
@@ -57,7 +53,7 @@ class TestEnvironment:
     @classmethod
     def from_args(cls, args):
         return cls(
-            os.path.abspath(args.rust),
+            os.path.abspath(args.rust_build),
             os.path.abspath(args.sdk),
             args.target,
             verbose=args.verbose,
@@ -68,13 +64,9 @@ class TestEnvironment:
         with open(cls.env_file_path(), encoding="utf-8") as f:
             test_env = json.loads(f.read())
             return cls(
-                test_env["rust_dir"],
+                test_env["rust_build_dir"],
                 test_env["sdk_dir"],
                 test_env["target"],
-                libstd_name=test_env["libstd_name"],
-                libtest_name=test_env["libtest_name"],
-                emu_addr=test_env["emu_addr"],
-                package_server_pid=test_env["package_server_pid"],
                 verbose=test_env["verbose"],
             )
 
@@ -82,18 +74,6 @@ class TestEnvironment:
         with open(self.env_file_path(), "w", encoding="utf-8") as f:
             f.write(json.dumps(self.__dict__))
 
-    def ssh_dir(self):
-        return os.path.join(self.tmp_dir(), "ssh")
-
-    def ssh_keyfile_path(self):
-        return os.path.join(self.ssh_dir(), "fuchsia_ed25519")
-
-    def ssh_authfile_path(self):
-        return os.path.join(self.ssh_dir(), "fuchsia_authorized_keys")
-
-    def vdl_output_path(self):
-        return os.path.join(self.tmp_dir(), "vdl_output")
-
     def package_server_log_path(self):
         return os.path.join(self.tmp_dir(), "package_server_log")
 
@@ -113,7 +93,9 @@ class TestEnvironment:
 
     def libs_dir(self):
         return os.path.join(
-            self.rust_dir,
+            self.rust_build_dir,
+            "host",
+            "stage2",
             "lib",
         )
 
@@ -212,21 +194,19 @@ class TestEnvironment:
         # Set configs
         configs = {
             "log.enabled": "true",
-            "ssh.pub": self.ssh_authfile_path(),
-            "ssh.priv": self.ssh_keyfile_path(),
             "test.is_isolated": "true",
             "test.experimental_structured_output": "true",
         }
         for key, value in configs.items():
             subprocess.check_call(
                 [
-                    self.tool_path("ffx"),
+                    ffx_path,
                     "config",
                     "set",
                     key,
                     value,
                 ],
-                env=self.ffx_cmd_env(),
+                env=ffx_env,
                 stdout=self.subprocess_output(),
                 stderr=self.subprocess_output(),
             )
@@ -248,6 +228,7 @@ class TestEnvironment:
                 self.tool_path("ffx"),
                 "daemon",
                 "stop",
+                "-w",
             ],
             env=self.ffx_cmd_env(),
             stdout=self.subprocess_output(),
@@ -275,87 +256,62 @@ class TestEnvironment:
         elif len(os.listdir(self.tmp_dir())) != 0:
             raise Exception(f"Temp directory is not clean (in {self.tmp_dir()})")
 
-        os.mkdir(self.ssh_dir())
         os.mkdir(self.output_dir())
 
-        # Find libstd and libtest
-        libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
-        libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
-
-        if not libstd_paths:
-            raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
-
-        if not libtest_paths:
-            raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
+        ffx_path = self.tool_path("ffx")
+        ffx_env = self.ffx_cmd_env()
 
-        self.libstd_name = os.path.basename(libstd_paths[0])
-        self.libtest_name = os.path.basename(libtest_paths[0])
+        # Start ffx isolation
+        self.log_info("Starting ffx isolation...")
+        self.start_ffx_isolation()
 
-        # Generate SSH keys for the emulator to use
-        self.log_info("Generating SSH keys...")
+        # Stop any running emulators (there shouldn't be any)
         subprocess.check_call(
             [
-                "ssh-keygen",
-                "-N",
-                "",
-                "-t",
-                "ed25519",
-                "-f",
-                self.ssh_keyfile_path(),
-                "-C",
-                "Generated by fuchsia-test-runner.py",
+                ffx_path,
+                "emu",
+                "stop",
+                "--all",
             ],
+            env=ffx_env,
             stdout=self.subprocess_output(),
             stderr=self.subprocess_output(),
         )
-        authfile_contents = subprocess.check_output(
+
+        # Start emulator
+        self.log_info("Starting emulator...")
+        product_bundle = "terminal.qemu-" + self.triple_to_arch(self.target)
+        subprocess.check_call(
             [
-                "ssh-keygen",
-                "-y",
-                "-f",
-                self.ssh_keyfile_path(),
+                ffx_path,
+                "product-bundle",
+                "get",
+                product_bundle,
             ],
+            env=ffx_env,
+            stdout=self.subprocess_output(),
             stderr=self.subprocess_output(),
         )
-        with open(self.ssh_authfile_path(), "wb") as authfile:
-            authfile.write(authfile_contents)
-
-        # Start ffx isolation
-        self.log_info("Starting ffx isolation...")
-        self.start_ffx_isolation()
-
-        # Start emulator (this will generate the vdl output)
-        self.log_info("Starting emulator...")
+        # FIXME: condition --accel hyper on target arch matching host arch
         subprocess.check_call(
             [
-                self.tool_path("fvdl"),
-                "--sdk",
+                ffx_path,
+                "emu",
                 "start",
-                "--tuntap",
+                product_bundle,
                 "--headless",
-                "--nointeractive",
-                "--ssh",
-                self.ssh_dir(),
-                "--vdl-output",
-                self.vdl_output_path(),
-                "--emulator-log",
+                "--log",
                 self.emulator_log_path(),
-                "--image-name",
-                "qemu-" + self.triple_to_arch(self.target),
+                "--net",
+                "tap",
+                "--accel",
+                "hyper",
             ],
+            env=ffx_env,
             stdout=self.subprocess_output(),
             stderr=self.subprocess_output(),
         )
 
-        # Parse vdl output for relevant information
-        with open(self.vdl_output_path(), encoding="utf-8") as f:
-            vdl_content = f.read()
-            matches = re.search(
-                r'network_address:\s+"\[([0-9a-f]{1,4}:(:[0-9a-f]{1,4}){4}%qemu)\]"',
-                vdl_content,
-            )
-            self.emu_addr = matches.group(1)
-
         # Create new package repo
         self.log_info("Creating package repo...")
         subprocess.check_call(
@@ -369,55 +325,40 @@ class TestEnvironment:
             stderr=self.subprocess_output(),
         )
 
-        # Start package server
-        self.log_info("Starting package server...")
-        with open(
-            self.package_server_log_path(), "w", encoding="utf-8"
-        ) as package_server_log:
-            # We want this to be a long-running process that persists after the script finishes
-            # pylint: disable=consider-using-with
-            self.package_server_pid = subprocess.Popen(
-                [
-                    self.tool_path("pm"),
-                    "serve",
-                    "-vt",
-                    "-repo",
-                    self.repo_dir(),
-                    "-l",
-                    ":8084",
-                ],
-                stdout=package_server_log,
-                stderr=package_server_log,
-            ).pid
-
-        # Register package server with emulator
-        self.log_info("Registering package server...")
-        ssh_client = subprocess.check_output(
+        # Add repo
+        subprocess.check_call(
             [
-                "ssh",
-                "-i",
-                self.ssh_keyfile_path(),
-                "-o",
-                "StrictHostKeyChecking=accept-new",
-                self.emu_addr,
-                "-f",
-                "echo $SSH_CLIENT",
+                ffx_path,
+                "repository",
+                "add-from-pm",
+                self.repo_dir(),
+                "--repository",
+                self.TEST_REPO_NAME,
             ],
-            text=True,
+            env=ffx_env,
+            stdout=self.subprocess_output(),
+            stderr=self.subprocess_output(),
         )
-        repo_addr = ssh_client.split()[0].replace("%", "%25")
-        repo_url = f"http://[{repo_addr}]:8084/config.json"
+
+        # Start repository server
+        subprocess.check_call(
+            [ffx_path, "repository", "server", "start", "--address", "[::]:0"],
+            env=ffx_env,
+            stdout=self.subprocess_output(),
+            stderr=self.subprocess_output(),
+        )
+
+        # Register with newly-started emulator
         subprocess.check_call(
             [
-                "ssh",
-                "-i",
-                self.ssh_keyfile_path(),
-                "-o",
-                "StrictHostKeyChecking=accept-new",
-                self.emu_addr,
-                "-f",
-                f"pkgctl repo add url -f 1 -n {self.TEST_REPO_NAME} {repo_url}",
+                ffx_path,
+                "target",
+                "repository",
+                "register",
+                "--repository",
+                self.TEST_REPO_NAME,
             ],
+            env=ffx_env,
             stdout=self.subprocess_output(),
             stderr=self.subprocess_output(),
         )
@@ -471,8 +412,8 @@ class TestEnvironment:
     meta/package={package_dir}/meta/package
     meta/{package_name}.cm={package_dir}/meta/{package_name}.cm
     bin/{exe_name}={bin_path}
-    lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
-    lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
+    lib/{libstd_name}={libstd_path}
+    lib/{libtest_name}={libtest_path}
     lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
     lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
     """
@@ -502,6 +443,16 @@ class TestEnvironment:
 
         bin_path = os.path.abspath(args.bin_path)
 
+        # Find libstd and libtest
+        libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
+        libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
+
+        if not libstd_paths:
+            raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
+
+        if not libtest_paths:
+            raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
+
         # Build a unique, deterministic name for the test using the name of the
         # binary and the last 6 hex digits of the hash of the full path
         def path_checksum(path):
@@ -604,11 +555,12 @@ class TestEnvironment:
                         exe_name=exe_name,
                         package_dir=package_dir,
                         package_name=package_name,
-                        rust_dir=self.rust_dir,
-                        rustlib_dir=self.target,
+                        target=self.target,
                         sdk_dir=self.sdk_dir,
-                        libstd_name=self.libstd_name,
-                        libtest_name=self.libtest_name,
+                        libstd_name=os.path.basename(libstd_paths[0]),
+                        libtest_name=os.path.basename(libtest_paths[0]),
+                        libstd_path=libstd_paths[0],
+                        libtest_path=libtest_paths[0],
                         target_arch=self.triple_to_arch(self.target),
                     )
                 )
@@ -779,20 +731,15 @@ class TestEnvironment:
         else:
             self.log_debug("No ffx daemon log found")
 
-        # Stop package server
-        self.log_info("Stopping package server...")
-        os.kill(self.package_server_pid, signal.SIGTERM)
-
         # Shut down the emulator
         self.log_info("Stopping emulator...")
         subprocess.check_call(
             [
-                self.tool_path("fvdl"),
-                "--sdk",
-                "kill",
-                "--launched-proto",
-                self.vdl_output_path(),
+                self.tool_path("ffx"),
+                "emu",
+                "stop",
             ],
+            env=self.ffx_cmd_env(),
             stdout=self.subprocess_output(),
             stderr=self.subprocess_output(),
         )
@@ -969,8 +916,8 @@ def main():
         "start", help="initializes the testing environment"
     )
     start_parser.add_argument(
-        "--rust",
-        help="the directory of the installed Rust compiler for Fuchsia",
+        "--rust-build",
+        help="the current compiler build directory (`$RUST_SRC/build` by default)",
         required=True,
     )
     start_parser.add_argument(
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 4d97b8c6cb9..f7cce35b123 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -681,12 +681,9 @@ local Rust source checkout:
 cd ${RUST_SRC_PATH}
 ```
 
-To run the Rust test suite on an emulated Fuchsia device, you must install the
-Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)"
-for the steps to build locally.
-
-You'll also need to download a copy of the Fuchsia SDK. The current minimum
-supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version].
+To run the Rust test suite on an emulated Fuchsia device, you'll also need to
+download a copy of the Fuchsia SDK. The current minimum supported SDK version is
+[10.20221207.2.89][minimum_supported_sdk_version].
 
 [minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89
 
@@ -695,13 +692,13 @@ Fuchsia's test runner interacts with the Fuchsia emulator and is located at
 test environment with:
 
 ```sh
-src/ci/docker/scripts/fuchsia-test-runner.py start
-    --rust ${RUST_SRC_PATH}/install
-    --sdk ${SDK_PATH}
-    --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
+src/ci/docker/scripts/fuchsia-test-runner.py start                            \
+    --rust-build ${RUST_SRC_PATH}/build                                       \
+    --sdk ${SDK_PATH}                                                         \
+    --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}                 \
 ```
 
-Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
+Where `${RUST_SRC_PATH}/build` is the `build-dir` set in `config.toml` and
 `${SDK_PATH}` is the path to the downloaded and unzipped SDK.
 
 Once our environment is started, we can run our tests using `x.py` as usual. The
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index a184b7b705e..f5296abaee6 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -277,14 +277,18 @@ function preLoadCss(cssUrl) {
             searchState.mouseMovedAfterSearch = false;
             document.title = searchState.title;
         },
-        hideResults: () => {
-            switchDisplayedElement(null);
+        removeQueryParameters: () => {
+            // We change the document title.
             document.title = searchState.titleBeforeSearch;
-            // We also remove the query parameter from the URL.
             if (browserSupportsHistoryApi()) {
                 history.replaceState(null, "", getNakedUrl() + window.location.hash);
             }
         },
+        hideResults: () => {
+            switchDisplayedElement(null);
+            // We also remove the query parameter from the URL.
+            searchState.removeQueryParameters();
+        },
         getQueryStringParams: () => {
             const params = {};
             window.location.search.substring(1).split("&").
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index e724bf1601a..3059dac8207 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2071,6 +2071,20 @@ function initSearch(rawSearchIndex) {
         if (go_to_first || (results.others.length === 1
             && getSettingValue("go-to-only-result") === "true")
         ) {
+            // Needed to force re-execution of JS when coming back to a page. Let's take this
+            // scenario as example:
+            //
+            // 1. You have the "Directly go to item in search if there is only one result" option
+            //    enabled.
+            // 2. You make a search which results only one result, leading you automatically to
+            //    this result.
+            // 3. You go back to previous page.
+            //
+            // Now, without the call below, the JS will not be re-executed and the previous state
+            // will be used, starting search again since the search input is not empty, leading you
+            // back to the previous page again.
+            window.onunload = () => {};
+            searchState.removeQueryParameters();
             const elem = document.createElement("a");
             elem.href = results.others[0].href;
             removeClass(elem, "active");
@@ -2185,6 +2199,18 @@ function initSearch(rawSearchIndex) {
         printTab(currentTab);
     }
 
+    function updateSearchHistory(url) {
+        if (!browserSupportsHistoryApi()) {
+            return;
+        }
+        const params = searchState.getQueryStringParams();
+        if (!history.state && !params.search) {
+            history.pushState(null, "", url);
+        } else {
+            history.replaceState(null, "", url);
+        }
+    }
+
     /**
      * Perform a search based on the current state of the search input element
      * and display the results.
@@ -2195,7 +2221,6 @@ function initSearch(rawSearchIndex) {
         if (e) {
             e.preventDefault();
         }
-
         const query = parseQuery(searchState.input.value.trim());
         let filterCrates = getFilterCrates();
 
@@ -2221,15 +2246,7 @@ function initSearch(rawSearchIndex) {
 
         // Because searching is incremental by character, only the most
         // recent search query is added to the browser history.
-        if (browserSupportsHistoryApi()) {
-            const newURL = buildUrl(query.original, filterCrates);
-
-            if (!history.state && !params.search) {
-                history.pushState(null, "", newURL);
-            } else {
-                history.replaceState(null, "", newURL);
-            }
-        }
+        updateSearchHistory(buildUrl(query.original, filterCrates));
 
         showResults(
             execQuery(query, searchWords, filterCrates, window.currentCrate),
@@ -2695,13 +2712,8 @@ function initSearch(rawSearchIndex) {
     function updateCrate(ev) {
         if (ev.target.value === "all crates") {
             // If we don't remove it from the URL, it'll be picked up again by the search.
-            const params = searchState.getQueryStringParams();
             const query = searchState.input.value.trim();
-            if (!history.state && !params.search) {
-                history.pushState(null, "", buildUrl(query, null));
-            } else {
-                history.replaceState(null, "", buildUrl(query, null));
-            }
+            updateSearchHistory(buildUrl(query, null));
         }
         // In case you "cut" the entry from the search input, then change the crate filter
         // before paste back the previous search, you get the old search results without
diff --git a/tests/mir-opt/spanview_block.main.built.after.html b/tests/mir-opt/spanview_block.main.built.after.html
index b962d80c59e..56f4e4f9370 100644
--- a/tests/mir-opt/spanview_block.main.built.after.html
+++ b/tests/mir-opt/spanview_block.main.built.after.html
@@ -1,6 +1,7 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
+<meta charset="utf-8">
 <title>spanview_block.main.built.after</title>
 <style>
     .line {
diff --git a/tests/mir-opt/spanview_statement.main.built.after.html b/tests/mir-opt/spanview_statement.main.built.after.html
index 43bff7d096e..91af08d80a8 100644
--- a/tests/mir-opt/spanview_statement.main.built.after.html
+++ b/tests/mir-opt/spanview_statement.main.built.after.html
@@ -1,6 +1,7 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
+<meta charset="utf-8">
 <title>spanview_statement.main.built.after</title>
 <style>
     .line {
diff --git a/tests/mir-opt/spanview_terminator.main.built.after.html b/tests/mir-opt/spanview_terminator.main.built.after.html
index aa7e44c1571..1f42faedd1e 100644
--- a/tests/mir-opt/spanview_terminator.main.built.after.html
+++ b/tests/mir-opt/spanview_terminator.main.built.after.html
@@ -1,6 +1,7 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
+<meta charset="utf-8">
 <title>spanview_terminator.main.built.after</title>
 <style>
     .line {
diff --git a/tests/rustdoc-gui/setting-go-to-only-result.goml b/tests/rustdoc-gui/setting-go-to-only-result.goml
index c5720b4bf1a..45e0b349051 100644
--- a/tests/rustdoc-gui/setting-go-to-only-result.goml
+++ b/tests/rustdoc-gui/setting-go-to-only-result.goml
@@ -34,7 +34,14 @@ go-to: "file://" + |DOC_PATH| + "/lib2/index.html"
 // We enter it into the search.
 write: (".search-input", "HasALongTraitWithParams")
 wait-for-document-property: {"title": "HasALongTraitWithParams in lib2 - Rust"}
-assert-document-property: ({"URL": "/lib2/struct.HasALongTraitWithParams.html"}, ENDS_WITH)
+assert-window-property: ({"location": "/lib2/struct.HasALongTraitWithParams.html"}, ENDS_WITH)
+
+// Regression test for <https://github.com/rust-lang/rust/issues/112676>.
+// If "go-to-only-result" is enabled and you go back to history, it should not lead you back to the
+// page result again automatically.
+history-go-back:
+wait-for-document-property: {"title": "lib2 - Rust"}
+assert-window-property: ({"location": "/lib2/index.html"}, ENDS_WITH)
 
 // We try again to see if it goes to the only result
 go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=HasALongTraitWithParams"
diff --git a/tests/ui/asm/x86_64/parse-error.rs b/tests/ui/asm/parse-error.rs
index 2e714d464ae..9e002b1550f 100644
--- a/tests/ui/asm/x86_64/parse-error.rs
+++ b/tests/ui/asm/parse-error.rs
@@ -1,4 +1,4 @@
-// only-x86_64
+// needs-asm-support
 
 #![feature(asm_const)]
 
@@ -38,6 +38,9 @@ fn main() {
         //~^ ERROR expected one of
         asm!("{}", options(), const foo);
         //~^ ERROR attempt to use a non-constant value in a constant
+
+        // test that asm!'s clobber_abi doesn't accept non-string literals
+        // see also https://github.com/rust-lang/rust/issues/112635
         asm!("", clobber_abi());
         //~^ ERROR at least one abi must be provided
         asm!("", clobber_abi(foo));
@@ -46,6 +49,25 @@ fn main() {
         //~^ ERROR expected one of `)` or `,`, found `foo`
         asm!("", clobber_abi("C", foo));
         //~^ ERROR expected string literal
+        asm!("", clobber_abi(1));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(()));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(uwu));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi({}));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(loop {}));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(if));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(do));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(<));
+        //~^ ERROR expected string literal
+        asm!("", clobber_abi(.));
+        //~^ ERROR expected string literal
+
         asm!("{}", clobber_abi("C"), const foo);
         //~^ ERROR attempt to use a non-constant value in a constant
         asm!("", options(), clobber_abi("C"));
@@ -56,15 +78,7 @@ fn main() {
         //~^^ ERROR argument never used
         //~^^^ ERROR attempt to use a non-constant value in a constant
         //~^^^^ ERROR attempt to use a non-constant value in a constant
-        asm!("", a = in("eax") foo);
-        //~^ ERROR explicit register arguments cannot have names
-        asm!("{a}", in("eax") foo, a = const bar);
-        //~^ ERROR attempt to use a non-constant value in a constant
-        asm!("{a}", in("eax") foo, a = const bar);
-        //~^ ERROR attempt to use a non-constant value in a constant
-        asm!("{1}", in("eax") foo, const bar);
-        //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
-        //~^^ ERROR attempt to use a non-constant value in a constant
+
         asm!("", options(), "");
         //~^ ERROR expected one of
         asm!("{}", in(reg) foo, "{}", out(reg) foo);
diff --git a/tests/ui/asm/x86_64/parse-error.stderr b/tests/ui/asm/parse-error.stderr
index 0c9d6f71529..075d28e176a 100644
--- a/tests/ui/asm/x86_64/parse-error.stderr
+++ b/tests/ui/asm/parse-error.stderr
@@ -83,31 +83,85 @@ LL |         asm!("", options(nomem, foo));
    |                                 ^^^ expected one of 10 possible tokens
 
 error: at least one abi must be provided as an argument to `clobber_abi`
-  --> $DIR/parse-error.rs:41:30
+  --> $DIR/parse-error.rs:44:30
    |
 LL |         asm!("", clobber_abi());
    |                              ^
 
 error: expected string literal
-  --> $DIR/parse-error.rs:43:30
+  --> $DIR/parse-error.rs:46:30
    |
 LL |         asm!("", clobber_abi(foo));
    |                              ^^^ not a string literal
 
 error: expected one of `)` or `,`, found `foo`
-  --> $DIR/parse-error.rs:45:34
+  --> $DIR/parse-error.rs:48:34
    |
 LL |         asm!("", clobber_abi("C" foo));
    |                                  ^^^ expected one of `)` or `,`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:47:35
+  --> $DIR/parse-error.rs:50:35
    |
 LL |         asm!("", clobber_abi("C", foo));
    |                                   ^^^ not a string literal
 
+error: expected string literal
+  --> $DIR/parse-error.rs:52:30
+   |
+LL |         asm!("", clobber_abi(1));
+   |                              ^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:54:30
+   |
+LL |         asm!("", clobber_abi(()));
+   |                              ^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:56:30
+   |
+LL |         asm!("", clobber_abi(uwu));
+   |                              ^^^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:58:30
+   |
+LL |         asm!("", clobber_abi({}));
+   |                              ^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:60:30
+   |
+LL |         asm!("", clobber_abi(loop {}));
+   |                              ^^^^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:62:30
+   |
+LL |         asm!("", clobber_abi(if));
+   |                              ^^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:64:30
+   |
+LL |         asm!("", clobber_abi(do));
+   |                              ^^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:66:30
+   |
+LL |         asm!("", clobber_abi(<));
+   |                              ^ not a string literal
+
+error: expected string literal
+  --> $DIR/parse-error.rs:68:30
+   |
+LL |         asm!("", clobber_abi(.));
+   |                              ^ not a string literal
+
 error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:54:36
+  --> $DIR/parse-error.rs:76:36
    |
 LL |         asm!("{a}", a = const foo, a = const bar);
    |                     -------------  ^^^^^^^^^^^^^ duplicate argument
@@ -115,41 +169,27 @@ LL |         asm!("{a}", a = const foo, a = const bar);
    |                     previously here
 
 error: argument never used
-  --> $DIR/parse-error.rs:54:36
+  --> $DIR/parse-error.rs:76:36
    |
 LL |         asm!("{a}", a = const foo, a = const bar);
    |                                    ^^^^^^^^^^^^^ argument never used
    |
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
-error: explicit register arguments cannot have names
-  --> $DIR/parse-error.rs:59:18
-   |
-LL |         asm!("", a = in("eax") foo);
-   |                  ^^^^^^^^^^^^^^^^^
-
-error: positional arguments cannot follow named arguments or explicit register arguments
-  --> $DIR/parse-error.rs:65:36
-   |
-LL |         asm!("{1}", in("eax") foo, const bar);
-   |                     -------------  ^^^^^^^^^ positional argument
-   |                     |
-   |                     explicit register argument
-
 error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
-  --> $DIR/parse-error.rs:68:29
+  --> $DIR/parse-error.rs:82:29
    |
 LL |         asm!("", options(), "");
    |                             ^^ expected one of 9 possible tokens
 
 error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
-  --> $DIR/parse-error.rs:70:33
+  --> $DIR/parse-error.rs:84:33
    |
 LL |         asm!("{}", in(reg) foo, "{}", out(reg) foo);
    |                                 ^^^^ expected one of 9 possible tokens
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:72:14
+  --> $DIR/parse-error.rs:86:14
    |
 LL |         asm!(format!("{{{}}}", 0), in(reg) foo);
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +197,7 @@ LL |         asm!(format!("{{{}}}", 0), in(reg) foo);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:74:21
+  --> $DIR/parse-error.rs:88:21
    |
 LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
    |                     ^^^^^^^^^^^^^^^^^^^^
@@ -165,121 +205,121 @@ LL |         asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: _ cannot be used for input operands
-  --> $DIR/parse-error.rs:76:28
+  --> $DIR/parse-error.rs:90:28
    |
 LL |         asm!("{}", in(reg) _);
    |                            ^
 
 error: _ cannot be used for input operands
-  --> $DIR/parse-error.rs:78:31
+  --> $DIR/parse-error.rs:92:31
    |
 LL |         asm!("{}", inout(reg) _);
    |                               ^
 
 error: _ cannot be used for input operands
-  --> $DIR/parse-error.rs:80:35
+  --> $DIR/parse-error.rs:94:35
    |
 LL |         asm!("{}", inlateout(reg) _);
    |                                   ^
 
 error: requires at least a template string argument
-  --> $DIR/parse-error.rs:87:1
+  --> $DIR/parse-error.rs:101:1
    |
 LL | global_asm!();
    | ^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:89:13
+  --> $DIR/parse-error.rs:103:13
    |
 LL | global_asm!(FOO);
    |             ^^^
 
 error: expected token: `,`
-  --> $DIR/parse-error.rs:91:18
+  --> $DIR/parse-error.rs:105:18
    |
 LL | global_asm!("{}" FOO);
    |                  ^^^ expected `,`
 
 error: expected operand, options, or additional template string
-  --> $DIR/parse-error.rs:93:19
+  --> $DIR/parse-error.rs:107:19
    |
 LL | global_asm!("{}", FOO);
    |                   ^^^ expected operand, options, or additional template string
 
 error: expected expression, found end of macro arguments
-  --> $DIR/parse-error.rs:95:24
+  --> $DIR/parse-error.rs:109:24
    |
 LL | global_asm!("{}", const);
    |                        ^ expected expression
 
 error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
-  --> $DIR/parse-error.rs:97:30
+  --> $DIR/parse-error.rs:111:30
    |
 LL | global_asm!("{}", const(reg) FOO);
    |                              ^^^ expected one of `,`, `.`, `?`, or an operator
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
-  --> $DIR/parse-error.rs:99:25
+  --> $DIR/parse-error.rs:113:25
    |
 LL | global_asm!("", options(FOO));
    |                         ^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:101:25
+  --> $DIR/parse-error.rs:115:25
    |
 LL | global_asm!("", options(nomem FOO));
    |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
-  --> $DIR/parse-error.rs:103:25
+  --> $DIR/parse-error.rs:117:25
    |
 LL | global_asm!("", options(nomem, FOO));
    |                         ^^^^^ expected one of `)`, `att_syntax`, or `raw`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:106:29
+  --> $DIR/parse-error.rs:120:29
    |
 LL | global_asm!("", clobber_abi(FOO));
    |                             ^^^ not a string literal
 
 error: expected one of `)` or `,`, found `FOO`
-  --> $DIR/parse-error.rs:108:33
+  --> $DIR/parse-error.rs:122:33
    |
 LL | global_asm!("", clobber_abi("C" FOO));
    |                                 ^^^ expected one of `)` or `,`
 
 error: expected string literal
-  --> $DIR/parse-error.rs:110:34
+  --> $DIR/parse-error.rs:124:34
    |
 LL | global_asm!("", clobber_abi("C", FOO));
    |                                  ^^^ not a string literal
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:112:19
+  --> $DIR/parse-error.rs:126:19
    |
 LL | global_asm!("{}", clobber_abi("C"), const FOO);
    |                   ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:114:28
+  --> $DIR/parse-error.rs:128:28
    |
 LL | global_asm!("", options(), clobber_abi("C"));
    |                            ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:116:30
+  --> $DIR/parse-error.rs:130:30
    |
 LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
    |                              ^^^^^^^^^^^^^^^^
 
 error: `clobber_abi` cannot be used with `global_asm!`
-  --> $DIR/parse-error.rs:118:17
+  --> $DIR/parse-error.rs:132:17
    |
 LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
    |                 ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^
 
 error: duplicate argument named `a`
-  --> $DIR/parse-error.rs:120:35
+  --> $DIR/parse-error.rs:134:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    -------------  ^^^^^^^^^^^^^ duplicate argument
@@ -287,7 +327,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                    previously here
 
 error: argument never used
-  --> $DIR/parse-error.rs:120:35
+  --> $DIR/parse-error.rs:134:35
    |
 LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |                                   ^^^^^^^^^^^^^ argument never used
@@ -295,19 +335,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
 error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
-  --> $DIR/parse-error.rs:123:28
+  --> $DIR/parse-error.rs:137:28
    |
 LL | global_asm!("", options(), "");
    |                            ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
-  --> $DIR/parse-error.rs:125:30
+  --> $DIR/parse-error.rs:139:30
    |
 LL | global_asm!("{}", const FOO, "{}", const FOO);
    |                              ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:127:13
+  --> $DIR/parse-error.rs:141:13
    |
 LL | global_asm!(format!("{{{}}}", 0), const FOO);
    |             ^^^^^^^^^^^^^^^^^^^^
@@ -315,7 +355,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO);
    = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: asm template must be a string literal
-  --> $DIR/parse-error.rs:129:20
+  --> $DIR/parse-error.rs:143:20
    |
 LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
    |                    ^^^^^^^^^^^^^^^^^^^^
@@ -332,7 +372,7 @@ LL |         asm!("{}", options(), const foo);
    |                                     ^^^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:49:44
+  --> $DIR/parse-error.rs:71:44
    |
 LL |     let mut foo = 0;
    |     ----------- help: consider using `const` instead of `let`: `const foo`
@@ -341,7 +381,7 @@ LL |         asm!("{}", clobber_abi("C"), const foo);
    |                                            ^^^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:52:55
+  --> $DIR/parse-error.rs:74:55
    |
 LL |     let mut foo = 0;
    |     ----------- help: consider using `const` instead of `let`: `const foo`
@@ -350,7 +390,7 @@ LL |         asm!("{}", options(), clobber_abi("C"), const foo);
    |                                                       ^^^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:54:31
+  --> $DIR/parse-error.rs:76:31
    |
 LL |     let mut foo = 0;
    |     ----------- help: consider using `const` instead of `let`: `const foo`
@@ -359,7 +399,7 @@ LL |         asm!("{a}", a = const foo, a = const bar);
    |                               ^^^ non-constant value
 
 error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:54:46
+  --> $DIR/parse-error.rs:76:46
    |
 LL |     let mut bar = 0;
    |     ----------- help: consider using `const` instead of `let`: `const bar`
@@ -367,33 +407,6 @@ LL |     let mut bar = 0;
 LL |         asm!("{a}", a = const foo, a = const bar);
    |                                              ^^^ non-constant value
 
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:61:46
-   |
-LL |     let mut bar = 0;
-   |     ----------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{a}", in("eax") foo, a = const bar);
-   |                                              ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:63:46
-   |
-LL |     let mut bar = 0;
-   |     ----------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{a}", in("eax") foo, a = const bar);
-   |                                              ^^^ non-constant value
-
-error[E0435]: attempt to use a non-constant value in a constant
-  --> $DIR/parse-error.rs:65:42
-   |
-LL |     let mut bar = 0;
-   |     ----------- help: consider using `const` instead of `let`: `const bar`
-...
-LL |         asm!("{1}", in("eax") foo, const bar);
-   |                                          ^^^ non-constant value
-
-error: aborting due to 59 previous errors
+error: aborting due to 63 previous errors
 
 For more information about this error, try `rustc --explain E0435`.
diff --git a/tests/ui/asm/x86_64/x86_64_parse_error.rs b/tests/ui/asm/x86_64/x86_64_parse_error.rs
new file mode 100644
index 00000000000..715a67687d1
--- /dev/null
+++ b/tests/ui/asm/x86_64/x86_64_parse_error.rs
@@ -0,0 +1,21 @@
+// only-x86_64
+
+#![feature(asm_const)]
+
+use std::arch::asm;
+
+fn main() {
+    let mut foo = 0;
+    let mut bar = 0;
+    unsafe {
+        asm!("", a = in("eax") foo);
+        //~^ ERROR explicit register arguments cannot have names
+        asm!("{a}", in("eax") foo, a = const bar);
+        //~^ ERROR attempt to use a non-constant value in a constant
+        asm!("{a}", in("eax") foo, a = const bar);
+        //~^ ERROR attempt to use a non-constant value in a constant
+        asm!("{1}", in("eax") foo, const bar);
+        //~^ ERROR positional arguments cannot follow named arguments or explicit register arguments
+        //~^^ ERROR attempt to use a non-constant value in a constant
+    }
+}
diff --git a/tests/ui/asm/x86_64/x86_64_parse_error.stderr b/tests/ui/asm/x86_64/x86_64_parse_error.stderr
new file mode 100644
index 00000000000..f2854ae5128
--- /dev/null
+++ b/tests/ui/asm/x86_64/x86_64_parse_error.stderr
@@ -0,0 +1,44 @@
+error: explicit register arguments cannot have names
+  --> $DIR/x86_64_parse_error.rs:11:18
+   |
+LL |         asm!("", a = in("eax") foo);
+   |                  ^^^^^^^^^^^^^^^^^
+
+error: positional arguments cannot follow named arguments or explicit register arguments
+  --> $DIR/x86_64_parse_error.rs:17:36
+   |
+LL |         asm!("{1}", in("eax") foo, const bar);
+   |                     -------------  ^^^^^^^^^ positional argument
+   |                     |
+   |                     explicit register argument
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/x86_64_parse_error.rs:13:46
+   |
+LL |     let mut bar = 0;
+   |     ----------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", in("eax") foo, a = const bar);
+   |                                              ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/x86_64_parse_error.rs:15:46
+   |
+LL |     let mut bar = 0;
+   |     ----------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{a}", in("eax") foo, a = const bar);
+   |                                              ^^^ non-constant value
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/x86_64_parse_error.rs:17:42
+   |
+LL |     let mut bar = 0;
+   |     ----------- help: consider using `const` instead of `let`: `const bar`
+...
+LL |         asm!("{1}", in("eax") foo, const bar);
+   |                                          ^^^ non-constant value
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0435`.