From 56e152d807cb1bacd697909cb960bdc3e4cbbaa1 Mon Sep 17 00:00:00 2001 From: Nathan Henrie Date: Thu, 1 Feb 2024 09:08:52 -0700 Subject: [PATCH 1/7] Add rust-lldb pretty printing for Path and PathBuf Fixes https://github.com/rust-lang/rust/issues/120553 Fixes https://github.com/rust-lang/rust/issues/48462 --- src/etc/lldb_commands | 3 +++ src/etc/lldb_lookup.py | 5 +++++ src/etc/lldb_providers.py | 29 +++++++++++++++++++++++++++++ src/etc/rust_types.py | 6 ++++++ tests/debuginfo/path.rs | 31 +++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+) create mode 100644 tests/debuginfo/path.rs diff --git a/src/etc/lldb_commands b/src/etc/lldb_commands index 615d13ccd0ffd..4be2dba34f6f8 100644 --- a/src/etc/lldb_commands +++ b/src/etc/lldb_commands @@ -16,4 +16,7 @@ type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)R type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^core::num::([a-z_]+::)*NonZero.+$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::([a-z_]+::)+)PathBuf$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust type category enable Rust diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index 36c7d82b34ac7..a93b42e1cc449 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -58,6 +58,11 @@ def summary_lookup(valobj, dict): if rust_type == RustType.STD_NONZERO_NUMBER: return StdNonZeroNumberSummaryProvider(valobj, dict) + if rust_type == RustType.STD_PATHBUF: + return StdPathBufSummaryProvider(valobj, dict) + if rust_type == RustType.STD_PATH: + return StdPathSummaryProvider(valobj, dict) + return "" diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 5d2b6fd525c14..1c43977a501a0 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -173,6 +173,35 @@ def StdStrSummaryProvider(valobj, dict): return '"%s"' % data +def StdPathBufSummaryProvider(valobj, dict): + # type: (SBValue, dict) -> str + # logger = Logger.Logger() + # logger >> "[StdPathBufSummaryProvider] for " + str(valobj.GetName()) + return StdOsStringSummaryProvider(valobj.GetChildMemberWithName("inner"), dict) + + +def StdPathSummaryProvider(valobj, dict): + # type: (SBValue, dict) -> str + # logger = Logger.Logger() + # logger >> "[StdPathSummaryProvider] for " + str(valobj.GetName()) + length = valobj.GetChildMemberWithName("length").GetValueAsUnsigned() + if length == 0: + return '""' + + data_ptr = valobj.GetChildMemberWithName("data_ptr") + + start = data_ptr.GetValueAsUnsigned() + error = SBError() + process = data_ptr.GetProcess() + data = process.ReadMemory(start, length, error) + if PY3: + try: + data = data.decode(encoding='UTF-8') + except UnicodeDecodeError: + return '%r' % data + return '"%s"' % data + + class StructSyntheticProvider: """Pretty-printer for structs and struct enum variants""" diff --git a/src/etc/rust_types.py b/src/etc/rust_types.py index 2b06683ef93cb..c0415a3cdcfe4 100644 --- a/src/etc/rust_types.py +++ b/src/etc/rust_types.py @@ -32,6 +32,8 @@ class RustType(object): STD_REF_MUT = "StdRefMut" STD_REF_CELL = "StdRefCell" STD_NONZERO_NUMBER = "StdNonZeroNumber" + STD_PATH = "StdPath" + STD_PATHBUF = "StdPathBuf" STD_STRING_REGEX = re.compile(r"^(alloc::([a-z_]+::)+)String$") @@ -51,6 +53,8 @@ class RustType(object): STD_REF_MUT_REGEX = re.compile(r"^(core::([a-z_]+::)+)RefMut<.+>$") STD_REF_CELL_REGEX = re.compile(r"^(core::([a-z_]+::)+)RefCell<.+>$") STD_NONZERO_NUMBER_REGEX = re.compile(r"^(core::([a-z_]+::)+)NonZero<.+>$") +STD_PATHBUF_REGEX = re.compile(r"^(std::([a-z_]+::)+)PathBuf$") +STD_PATH_REGEX = re.compile(r"^&(mut )?(std::([a-z_]+::)+)Path$") TUPLE_ITEM_REGEX = re.compile(r"__\d+$") @@ -75,6 +79,8 @@ class RustType(object): RustType.STD_REF_CELL: STD_REF_CELL_REGEX, RustType.STD_CELL: STD_CELL_REGEX, RustType.STD_NONZERO_NUMBER: STD_NONZERO_NUMBER_REGEX, + RustType.STD_PATHBUF: STD_PATHBUF_REGEX, + RustType.STD_PATH: STD_PATH_REGEX, } def is_tuple_fields(fields): diff --git a/tests/debuginfo/path.rs b/tests/debuginfo/path.rs new file mode 100644 index 0000000000000..afe923edcdd64 --- /dev/null +++ b/tests/debuginfo/path.rs @@ -0,0 +1,31 @@ +//@ ignore-gdb + +//@ compile-flags:-g + +// === LLDB TESTS ================================================================================= + +// lldb-command:run + +// lldb-command:print pathbuf +// lldb-check:[...]$0 = "/some/path" { inner = "/some/path" { inner = { inner = size=10 { [0] = '/' +// [1] = 's' [2] = 'o' [3] = 'm' [4] = 'e' [5] = '/' [6] = 'p' [7] = 'a' [8] = 't' [9] = 'h' } +// } } } +// lldb-command:po pathbuf +// lldb-check:"/some/path" +// lldb-command:print path +// lldb-check:[...]$1 = "/some/path" { data_ptr = [...] length = 10 } +// lldb-command:po path +// lldb-check:"/some/path" + +use std::path::Path; + +fn main() { + let path = Path::new("/some/path"); + let pathbuf = path.to_path_buf(); + + zzz(); // #break +} + +fn zzz() { + () +} From 25d06013db110db4ef4af46e9fded81b8adc03d6 Mon Sep 17 00:00:00 2001 From: Bernardo Meurer Costa Date: Fri, 22 Mar 2024 17:30:41 +0000 Subject: [PATCH 2/7] fix(bootstrap/dist): use versioned dirs when vendoring Currently, if you attempt to run ui tests in a vendored build, you will see this failure ``` ---- [ui] tests/ui/issues/issue-21763.rs stdout ---- diff of stderr: 8 = note: required because it appears within the type `(Rc<()>, Rc<()>)` 9 = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` 10 note: required because it appears within the type `hashbrown::map::HashMap, Rc<()>, RandomState>` - --> $HASHBROWN_SRC_LOCATION + --> /rust/deps/hashbrown/src/map.rs:190:12 12 note: required because it appears within the type `HashMap, Rc<()>>` 13 --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL 14 note: required by a bound in `foo` ``` This happend because the code that attempts to remap `HASHBROWN_SRC_LOCATION` expects it to be under `hashbrown-$version`, which is the case in a normal cargo registry, but not when vendor, where by default crates may not have the version in their directory name. This change passes `--versioned-dirs` to `cargo vendor` to enforce that every crate includes the version in the subdir name, which fixes the ui test and brings `--enable-vendor` builds closer to normal ones. --- src/bootstrap/src/core/build_steps/dist.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 012d64e534439..d9c7032d0db8e 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1003,6 +1003,7 @@ impl Step for PlainSourceTarball { // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("vendor") + .arg("--versioned-dirs") .arg("--sync") .arg(builder.src.join("./src/tools/cargo/Cargo.toml")) .arg("--sync") From 9685161b04f31c6663c166a0a241d3dea91b54d7 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 22 Mar 2024 11:02:29 -0700 Subject: [PATCH 3/7] Update stdarch submodule --- library/core/src/lib.rs | 1 + library/stdarch | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 2718dd114731b..464a85f5c99be 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -269,6 +269,7 @@ #![feature(arm_target_feature)] #![feature(avx512_target_feature)] #![feature(hexagon_target_feature)] +#![feature(loongarch_target_feature)] #![feature(mips_target_feature)] #![feature(powerpc_target_feature)] #![feature(riscv_target_feature)] diff --git a/library/stdarch b/library/stdarch index 56087ea170d87..967e7afd87cbe 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 56087ea170d878a7a57b3a5725e0c00f5f5cad70 +Subproject commit 967e7afd87cbea3232581a4a55031134ab88f595 From d3fc623f79d38002b3202551281488d7182049f7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:03:07 +0100 Subject: [PATCH 4/7] Introduce infrastructure for generating target docs --- Cargo.lock | 36 +++ Cargo.toml | 1 + .../src/spec/targets/aarch64_apple_tvos.rs | 6 +- .../src/spec/targets/i686_pc_windows_gnu.rs | 8 +- .../targets/loongarch64_unknown_linux_gnu.rs | 8 +- .../src/spec/targets/powerpc64_ibm_aix.rs | 8 +- src/bootstrap/src/core/build_steps/doc.rs | 31 ++- src/bootstrap/src/core/build_steps/tool.rs | 1 + src/bootstrap/src/lib.rs | 45 ++- .../host-x86_64/x86_64-gnu-llvm-17/Dockerfile | 4 + src/doc/rustc/src/SUMMARY.md | 3 + src/doc/rustc/src/platform-support.md | 13 +- src/doc/rustc/src/platform-support/aix.md | 10 + .../rustc/src/platform-support/apple-tvos.md | 10 + .../src/platform-support/loongarch-linux.md | 11 + src/doc/rustc/src/platform-support/targets.md | 7 + src/doc/rustc/target_infos/*-apple-tvos.md | 78 ++++++ .../rustc/target_infos/i686-pc-windows-gnu.md | 10 + .../loongarch*-unknown-linux-*.md | 93 +++++++ .../rustc/target_infos/powerpc64-ibm-aix.md | 18 ++ src/tools/target-docs/Cargo.toml | 14 + src/tools/target-docs/README.md | 37 +++ src/tools/target-docs/src/main.rs | 234 ++++++++++++++++ src/tools/target-docs/src/parse.rs | 135 +++++++++ src/tools/target-docs/src/parse/tests.rs | 99 +++++++ src/tools/target-docs/src/render.rs | 257 ++++++++++++++++++ 26 files changed, 1153 insertions(+), 24 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/targets.md create mode 100644 src/doc/rustc/target_infos/*-apple-tvos.md create mode 100644 src/doc/rustc/target_infos/i686-pc-windows-gnu.md create mode 100644 src/doc/rustc/target_infos/loongarch*-unknown-linux-*.md create mode 100644 src/doc/rustc/target_infos/powerpc64-ibm-aix.md create mode 100644 src/tools/target-docs/Cargo.toml create mode 100644 src/tools/target-docs/README.md create mode 100644 src/tools/target-docs/src/main.rs create mode 100644 src/tools/target-docs/src/parse.rs create mode 100644 src/tools/target-docs/src/parse/tests.rs create mode 100644 src/tools/target-docs/src/render.rs diff --git a/Cargo.lock b/Cargo.lock index b8fe1ebaf8019..e20a26cda3ae3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1585,6 +1585,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "glob-match" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" + [[package]] name = "globset" version = "0.4.13" @@ -5057,6 +5063,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.9.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "sha1" version = "0.10.6" @@ -5419,6 +5438,17 @@ dependencies = [ "xattr", ] +[[package]] +name = "target-docs" +version = "0.1.0" +dependencies = [ + "eyre", + "glob-match", + "serde", + "serde_json", + "serde_yaml", +] + [[package]] name = "tempfile" version = "3.10.1" @@ -6065,6 +6095,12 @@ dependencies = [ "diff", ] +[[package]] +name = "unsafe-libyaml" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" + [[package]] name = "unstable-book-gen" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index e12c968e205b7..90f17982f88e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ members = [ "src/tools/rustdoc-gui-test", "src/tools/opt-dist", "src/tools/coverage-dump", + "src/tools/target-docs", ] exclude = [ diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs index 0deadbdb02810..86e60ebe9fb8f 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs @@ -6,9 +6,9 @@ pub fn target() -> Target { Target { llvm_target: tvos_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, + description: Some("ARM64 tvOS".into()), + tier: Some(2), + host_tools: Some(false), std: None, }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs index 66e09416dde90..50465d6710987 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs @@ -18,10 +18,10 @@ pub fn target() -> Target { Target { llvm_target: "i686-pc-windows-gnu".into(), metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, - std: None, + description: Some("32-bit MinGW (Windows 7+)".into()), + tier: Some(1), + host_tools: Some(true), + std: Some(true), }, pointer_width: 32, data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs index f15a879894004..e4c3dc3492625 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs @@ -4,10 +4,10 @@ pub fn target() -> Target { Target { llvm_target: "loongarch64-unknown-linux-gnu".into(), metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, - std: None, + description: Some("LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)".into()), + tier: Some(2), + host_tools: Some(true), + std: Some(true), }, pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs index 481df71c1a65a..227799e1f6fac 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs @@ -11,10 +11,10 @@ pub fn target() -> Target { Target { llvm_target: "powerpc64-ibm-aix".into(), metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, - std: None, + description: Some("64-bit AIX (7.2 and newer)".into()), + tier: Some(3), + host_tools: Some(true), + std: Some(true), }, pointer_width: 64, data_layout: "E-m:a-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512".into(), diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 51b5cdc056577..92bd2d67c7199 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1147,14 +1147,17 @@ impl Step for RustcBook { /// Builds the rustc book. /// - /// The lints are auto-generated by a tool, and then merged into the book + /// The lints and target docs are auto-generated by a tool, and then merged into the book /// in the "md-doc" directory in the build output directory. Then /// "rustbook" is used to convert it to HTML. fn run(self, builder: &Builder<'_>) { let out_base = builder.md_doc_out(self.target).join("rustc"); t!(fs::create_dir_all(&out_base)); - let out_listing = out_base.join("src/lints"); - builder.cp_link_r(&builder.src.join("src/doc/rustc"), &out_base); + let out_lints_listing = out_base.join("src/lints"); + let out_src_listing = out_base.join("src"); + + // target-docs will be modifying the files in-place, so we need an actual copy. + builder.cp_r(&builder.src.join("src/doc/rustc"), &out_base); builder.info(&format!("Generating lint docs ({})", self.target)); let rustc = builder.rustc(self.compiler); @@ -1165,7 +1168,7 @@ impl Step for RustcBook { cmd.arg("--src"); cmd.arg(builder.src.join("compiler")); cmd.arg("--out"); - cmd.arg(&out_listing); + cmd.arg(&out_lints_listing); cmd.arg("--rustc"); cmd.arg(&rustc); cmd.arg("--rustc-target").arg(self.target.rustc_target_arg()); @@ -1194,6 +1197,26 @@ impl Step for RustcBook { builder.run(&mut cmd); drop(doc_generator_guard); + // Run target-docs generator + let mut cmd = builder.tool_cmd(Tool::TargetDocs); + cmd.arg(builder.src.join("src/doc/rustc/target_infos")); + cmd.arg(&out_src_listing); + cmd.env("RUSTC", &rustc); + // For now, we just check that the files are correct but do not generate output. + // Let the user override it to TARGET_CHECK_ONLY=0 for testing, but use 1 by default. + // See https://github.com/rust-lang/rust/issues/120745 for more info. + cmd.env("TARGET_CHECK_ONLY", std::env::var("TARGET_CHECK_ONLY").unwrap_or("1".to_owned())); + + let doc_generator_guard = builder.msg( + Kind::Run, + self.compiler.stage, + "target-docs", + self.compiler.host, + self.target, + ); + builder.run(&mut cmd); + drop(doc_generator_guard); + // Run rustbook/mdbook to generate the HTML pages. builder.ensure(RustbookSrc { target: self.target, diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index deab3fce54ca7..5ca0c66438206 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -301,6 +301,7 @@ bootstrap_tool!( RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes"; ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors"; LintDocs, "src/tools/lint-docs", "lint-docs"; + TargetDocs, "src/tools/target-docs", "target-docs"; JsonDocCk, "src/tools/jsondocck", "jsondocck"; JsonDocLint, "src/tools/jsondoclint", "jsondoclint"; HtmlChecker, "src/tools/html-checker", "html-checker"; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index d8397ab51de3c..412d309fb799a 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1668,10 +1668,23 @@ impl Build { /// You can neither rely on this being a copy nor it being a link, /// so do not write to dst. pub fn copy_link(&self, src: &Path, dst: &Path) { - self.copy_link_internal(src, dst, false); + self.copy_internal(src, dst, false, true); } - fn copy_link_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) { + /// Links a file from `src` to `dst`. + /// Unlike, [`Build::copy_link`], this makes an actual copy, which is usually not required, + /// so `copy_link` should be used instead if possible. + pub fn copy(&self, src: &Path, dst: &Path) { + self.copy_internal(src, dst, false, false); + } + + fn copy_internal( + &self, + src: &Path, + dst: &Path, + dereference_symlinks: bool, + link_if_possible: bool, + ) { if self.config.dry_run() { return; } @@ -1691,7 +1704,7 @@ impl Build { return; } } - if let Ok(()) = fs::hard_link(&src, dst) { + if link_if_possible && fs::hard_link(&src, dst).is_ok() { // Attempt to "easy copy" by creating a hard link // (symlinks don't work on windows), but if that fails // just fall back to a slow `copy` operation. @@ -1726,6 +1739,28 @@ impl Build { } } + /// Copies the `src` directory recursively to `dst`. Both are assumed to exist + /// when this function is called. + /// Unlike, [`Build::cp_link_r`], this makes an actual copy, which is usually not required, + /// so `cp_link_r` should be used instead if possible. + pub fn cp_r(&self, src: &Path, dst: &Path) { + if self.config.dry_run() { + return; + } + for f in self.read_dir(src) { + let path = f.path(); + let name = path.file_name().unwrap(); + let dst = dst.join(name); + if t!(f.file_type()).is_dir() { + t!(fs::create_dir_all(&dst)); + self.cp_r(&path, &dst); + } else { + let _ = fs::remove_file(&dst); + self.copy(&path, &dst); + } + } + } + /// Copies the `src` directory recursively to `dst`. Both are assumed to exist /// when this function is called. /// Will attempt to use hard links if possible and fall back to copying. @@ -1779,7 +1814,9 @@ impl Build { if !src.exists() { panic!("ERROR: File \"{}\" not found!", src.display()); } - self.copy_link_internal(src, &dst, true); + + self.copy_internal(src, &dst, true, true); + chmod(&dst, perms); } diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile index 538962802c96f..9fa1afcf811b8 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile @@ -49,6 +49,10 @@ ENV EXTERNAL_LLVM 1 # be missing. ENV IS_NOT_LATEST_LLVM 1 + +# Ubuntu LLVM 17 does not have support for experimental targets like csky. +ENV TARGET_DOCS_SKIP_TARGETS "csky-unknown-linux-gnuabiv2,csky-unknown-linux-gnuabiv2hf" + # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 83acce80f969d..a1ee671170669 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -69,6 +69,9 @@ - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) - [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md) + + + - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 75d38dd20bdeb..b1fb2b196bbf2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -40,6 +40,9 @@ target | notes `x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+) `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+) `x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 3.2+, glibc 2.17+) + + + [^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue]. @@ -102,7 +105,9 @@ target | notes `x86_64-unknown-illumos` | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 - + + + ## Tier 2 without Host Tools Tier 2 targets can be thought of as "guaranteed to build". The Rust project @@ -201,6 +206,9 @@ target | std | notes [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat `x86_64-unknown-redox` | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI + + + [^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue]. [wasi-rename]: https://github.com/rust-lang/compiler-team/issues/607 @@ -379,5 +387,8 @@ target | std | host | notes [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support `x86_64-wrs-vxworks` | ? | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) + + + [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/aix.md b/src/doc/rustc/src/platform-support/aix.md index c3ce71a183568..bbde0daa179fc 100644 --- a/src/doc/rustc/src/platform-support/aix.md +++ b/src/doc/rustc/src/platform-support/aix.md @@ -1,5 +1,15 @@ # `powerpc64-ibm-aix` + + **Tier: 3** Rust for AIX operating system, currently only 64-bit PowerPC is supported. diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index e7ea109df1ba1..4a42779bb3464 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -2,6 +2,16 @@ - aarch64-apple-tvos - x86_64-apple-tvos + + **Tier: 3** Apple tvOS targets: diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index e8f55b8bfce10..3cda4eaf4b07c 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -1,5 +1,16 @@ # loongarch\*-unknown-linux-\* + + + **Tier: 2** [LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited. diff --git a/src/doc/rustc/src/platform-support/targets.md b/src/doc/rustc/src/platform-support/targets.md new file mode 100644 index 0000000000000..2a34bac74b377 --- /dev/null +++ b/src/doc/rustc/src/platform-support/targets.md @@ -0,0 +1,7 @@ +# List of all targets + +An alphabetical list of all targets. + + + + diff --git a/src/doc/rustc/target_infos/*-apple-tvos.md b/src/doc/rustc/target_infos/*-apple-tvos.md new file mode 100644 index 0000000000000..1701dc42f9855 --- /dev/null +++ b/src/doc/rustc/target_infos/*-apple-tvos.md @@ -0,0 +1,78 @@ +--- +maintainers: ["@thomcc"] +--- + +## Overview + +Apple tvOS targets: +- Apple tvOS on aarch64 +- Apple tvOS Simulator on x86_64 + +## Requirements + +These targets are cross-compiled. You will need appropriate versions of Xcode +and the SDKs for tvOS (`AppleTVOS.sdk`) and/or the tvOS Simulator +(`AppleTVSimulator.sdk`) to build a toolchain and target these platforms. + +The targets support most (see below) of the standard library including the +allocator to the best of my knowledge, however they are very new, not yet +well-tested, and it is possible that there are various bugs. + +In theory we support back to tvOS version 7.0, although the actual minimum +version you can target may be newer than this, for example due to the versions +of Xcode and your SDKs. + +As with the other Apple targets, `rustc` respects the common environment +variables used by Xcode to configure this, in this case +`TVOS_DEPLOYMENT_TARGET`. + +As mentioned, "most" of the standard library is supported, which means that some portions +are known to be unsupported. The following APIs are currently known to have +missing or incomplete support: + +- `std::process::Command`'s API will return an error if it is configured in a + manner which cannot be performed using `posix_spawn` -- this is because the + more flexible `fork`/`exec`-based approach is prohibited on these platforms in + favor of `posix_spawn{,p}` (which still probably will get you rejected from + app stores, so is likely sideloading-only). A concrete set of cases where this + will occur is difficult to enumerate (and would quickly become stale), but in + some cases it may be worked around by tweaking the manner in which `Command` + is invoked. + +## Building the target + +The targets can be built by enabling them for a `rustc` build in `config.toml`, by adding, for example: + +```toml +[build] +build-stage = 1 +target = ["aarch64-apple-tvos", "x86_64-apple-tvos", "aarch64-apple-tvos-sim"] +``` + +It's possible that cargo under `-Zbuild-std` may also be used to target them. + +## Building Rust programs + +*Note: Building for this target requires the corresponding TVOS SDK, as provided by Xcode.* + +Rust programs can be built for these targets + +```text +$ rustc --target aarch64-apple-tvos your-code.rs +... +$ rustc --target x86_64-apple-tvos your-code.rs +... +$ rustc --target aarch64-apple-tvos-sim your-code.rs +``` + +## Testing + +There is no support for running the Rust or standard library testsuite on tvOS or the simulators at the moment. Testing has mostly been done manually with builds of static libraries called from Xcode or a simulator. + +It hopefully will be possible to improve this in the future. + +## Cross compilation + +This target can be cross-compiled from x86_64 or aarch64 macOS hosts. + +Other hosts are not supported for cross-compilation, but might work when also providing the required Xcode SDK. diff --git a/src/doc/rustc/target_infos/i686-pc-windows-gnu.md b/src/doc/rustc/target_infos/i686-pc-windows-gnu.md new file mode 100644 index 0000000000000..02fe6df687e12 --- /dev/null +++ b/src/doc/rustc/target_infos/i686-pc-windows-gnu.md @@ -0,0 +1,10 @@ +--- +footnotes: + i686-pc-windows-gnu: + - "x86_32-floats-return-ABI" + - "windows-support" +--- + +## Overview + +32-bit Windows using MinGW. diff --git a/src/doc/rustc/target_infos/loongarch*-unknown-linux-*.md b/src/doc/rustc/target_infos/loongarch*-unknown-linux-*.md new file mode 100644 index 0000000000000..b2156caa749bc --- /dev/null +++ b/src/doc/rustc/target_infos/loongarch*-unknown-linux-*.md @@ -0,0 +1,93 @@ +--- +maintainers: + - "[WANG Rui](https://github.com/heiher) `wangrui@loongson.cn`" + - "[ZHAI Xiang](https://github.com/xiangzhai) `zhaixiang@loongson.cn`" + - "[ZHAI Xiaojuan](https://github.com/zhaixiaojuan) `zhaixiaojuan@loongson.cn`" + - "[WANG Xuerui](https://github.com/xen0n) `git@xen0n.name`" +--- + +## Overview + +[LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited. + +[LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html + +The target name follow this format: `--`, where `` specifies the CPU family/model, `` specifies the vendor and `` the operating system name. +While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix ``. + +| `` | `Description` | +|------------------------|--------------------------------------------------------------------| +| f64 | The base ABI use 64-bits FPRs for parameter passing. (lp64d)| +| f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| +| sf | The base ABI uses no FPR for parameter passing. (lp64s) | + +
+ +|`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` | +|----------------------------------|-------------|----------|----------------------------------| +| lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu | +| lp64f/base | glibc | linux | loongarch64-unknown-linux-gnuf32 | +| lp64s/base | glibc | linux | loongarch64-unknown-linux-gnusf | +| lp64d/base | musl libc | linux | loongarch64-unknown-linux-musl| +| lp64f/base | musl libc | linux | loongarch64-unknown-linux-muslf32| +| lp64s/base | musl libc | linux | loongarch64-unknown-linux-muslsf | + +## Requirements + +This target is cross-compiled. +A GNU toolchain for LoongArch target is required. It can be downloaded from https://github.com/loongson/build-tools/releases, or built from the source code of GCC (12.1.0 or later) and Binutils (2.40 or later). + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["loongarch64-unknown-linux-gnu"] +``` + +Make sure `loongarch64-unknown-linux-gnu-gcc` can be searched from the directories specified in`$PATH`. Alternatively, you can use GNU LoongArch Toolchain by adding the following to `config.toml`: + +```toml +[target.loongarch64-unknown-linux-gnu] +# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN +cc = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" +cxx = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++" +ar = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ar" +ranlib = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ranlib" +linker = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" +``` + +## Cross compilation + +This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. Cross-compilation on other hosts may work but is not tested. + +## Testing +To test a cross-compiled binary on your build system, install the qemu binary that supports the LoongArch architecture and execute the following commands. +```text +CC_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ +CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++ \ +AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \ +CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ +# SET TARGET SYSTEM LIBRARY PATH +CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRARY_PATH" \ +cargo run --target loongarch64-unknown-linux-gnu --release +``` +Tested on x86 architecture, other architectures not tested. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you will either need to build Rust with the target enabled (see "Building the target" above), or build your own copy of `std` by using `build-std` or similar. + +If `rustc` has support for that target and the library artifacts are available, then Rust static libraries can be built for that target: + +```shell +$ rustc --target loongarch64-unknown-linux-gnu your-code.rs --crate-type staticlib +$ ls libyour_code.a +``` + +On Rust Nightly it's possible to build without the target artifacts available: + +```text +cargo build -Z build-std --target loongarch64-unknown-linux-gnu +``` diff --git a/src/doc/rustc/target_infos/powerpc64-ibm-aix.md b/src/doc/rustc/target_infos/powerpc64-ibm-aix.md new file mode 100644 index 0000000000000..ac070cb92f7f6 --- /dev/null +++ b/src/doc/rustc/target_infos/powerpc64-ibm-aix.md @@ -0,0 +1,18 @@ +--- +maintainers: [ + "QIU Chaofan `qiucofan@cn.ibm.com`, https://github.com/ecnelises", + "Kai LUO, `lkail@cn.ibm.com`, https://github.com/bzEq", +] +--- + +## Requirements + +This target supports host tools, std and alloc. This target cannot be cross-compiled as for now, mainly because of the unavailability of system linker on other platforms. + +Binary built for this target is expected to run on Power7 or newer CPU, and AIX 7.2 or newer version. + +Binary format of this platform is XCOFF. Archive file format is 'AIX big format'. + +## Testing + +This target supports running test suites natively, but it's not available to cross-compile and execute in emulator. diff --git a/src/tools/target-docs/Cargo.toml b/src/tools/target-docs/Cargo.toml new file mode 100644 index 0000000000000..78741710dcbb7 --- /dev/null +++ b/src/tools/target-docs/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "target-docs" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +eyre = "0.6.12" +glob-match = "0.2.1" +serde = { version = "1.0.185", features = ["derive"] } +serde_json = "1.0.114" +serde_yaml = "0.9.31" diff --git a/src/tools/target-docs/README.md b/src/tools/target-docs/README.md new file mode 100644 index 0000000000000..d7717a2ced8e8 --- /dev/null +++ b/src/tools/target-docs/README.md @@ -0,0 +1,37 @@ +# target-docs + +This tool generates target documentation for all targets in the rustc book. + +To achieve this, it uses a list of input markdown files provided in `src/doc/rustc/target_infos`. These files follow a strict format. +Every file covers a glob pattern of targets according to its file name. + +For every rustc target, we iterate through all the target infos and find matching globs. +When a glob matches, it extracts the h2 markdown sections and saves them for the target. + +In the end, a page is generated for every target using these sections. +Sections that are not provided are stubbed out. Currently, the sections are + +- Overview +- Requirements +- Testing +- Building the target +- Cross compilation +- Building Rust programs + +In addition to the markdown sections, we also have extra data about the targets. +This is achieved through YAML frontmatter. + +The frontmatter follows the following format: + +```yaml +maintainers: ["@someone"] +footnotes: + i686-pc-windows-gnu: + - "x86_32-floats-return-ABI" + - "windows-support" +``` + +The top level keys are: + +- `maintainers` (optional): list of strings +- `footnotes` (optional): for every *specific* target a list of footnotes. The footnotes have to be defined manually below the correct table in platform-support. diff --git a/src/tools/target-docs/src/main.rs b/src/tools/target-docs/src/main.rs new file mode 100644 index 0000000000000..73d8b3f4fbc47 --- /dev/null +++ b/src/tools/target-docs/src/main.rs @@ -0,0 +1,234 @@ +mod parse; +mod render; + +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + process::Command, +}; + +use eyre::{bail, Context, OptionExt, Result}; +use parse::ParsedTargetInfoFile; +use serde::Deserialize; + +/// Information about a target obtained from the markdown and rustc. +struct TargetInfo { + name: String, + maintainers: Vec, + sections: Vec<(String, String)>, + footnotes: Vec, + target_cfgs: Vec<(String, String)>, + metadata: RustcTargetMetadata, +} + +/// All the sections that we want every doc page to have. +/// It may make sense to relax this into two kinds of sections, "required" sections +/// and "optional" sections, where required sections will get stubbed out when not found +/// while optional sections will just not exist when not found. +// IMPORTANT: This is also documented in the README, keep it in sync. +const SECTIONS: &[&str] = &[ + "Overview", + "Requirements", + "Testing", + "Building the target", + "Cross compilation", + "Building Rust programs", +]; + +fn main() -> Result<()> { + let args = std::env::args().collect::>(); + let input_dir = args + .get(1) + .ok_or_eyre("first argument must be path to target_infos directory containing target source md files (src/doc/rustc/target_infos/)")?; + let output_src = args.get(2).ok_or_eyre( + "second argument must be path to `src` output directory (build/$target/md-doc/rustc/src)", + )?; + + println!("Loading target info docs from {input_dir}"); + println!("Writing output to {output_src}"); + + let targets_to_skip = std::env::var("TARGET_DOCS_SKIP_TARGETS"); + let targets_to_skip = + targets_to_skip.as_deref().map(|s| s.split(",").collect::>()).unwrap_or_default(); + + let rustc = + PathBuf::from(std::env::var("RUSTC").expect("must pass RUSTC env var pointing to rustc")); + let check_only = std::env::var("TARGET_CHECK_ONLY") == Ok("1".to_owned()); + + let targets = rustc_stdout(&rustc, &["--print", "target-list"]); + let targets = + targets.lines().filter(|target| !targets_to_skip.contains(target)).collect::>(); + + let mut info_patterns = parse::load_target_infos(Path::new(input_dir)) + .wrap_err("failed loading target_info")? + .into_iter() + .map(|info| { + let footnotes_used = + info.footnotes.keys().map(|target| (target.clone(), false)).collect(); + TargetPatternEntry { info, used: false, footnotes_used } + }) + .collect::>(); + + eprintln!("Collecting rustc information"); + let rustc_infos = + targets.iter().map(|target| rustc_target_info(&rustc, target)).collect::>(); + + let targets = targets + .into_iter() + .map(|target| target_doc_info(&mut info_patterns, target)) + .zip(rustc_infos) + .map(|(md, rustc)| TargetInfo { + name: md.name, + maintainers: md.maintainers, + sections: md.sections, + footnotes: md.footnotes, + target_cfgs: rustc.target_cfgs, + metadata: rustc.metadata, + }) + .collect::>(); + + eprintln!("Rendering targets check_only={check_only}"); + let targets_dir = Path::new(output_src).join("platform-support").join("targets"); + if !check_only { + std::fs::create_dir_all(&targets_dir).wrap_err("creating platform-support/targets dir")?; + } + for info in &targets { + let doc = render::render_target_md(info); + + if !check_only { + std::fs::write(targets_dir.join(format!("{}.md", info.name)), doc) + .wrap_err("writing target file")?; + } + } + + for target_pattern in info_patterns { + if !target_pattern.used { + bail!("target pattern `{}` was never used", target_pattern.info.pattern); + } + + for footnote_target in target_pattern.info.footnotes.keys() { + let used = target_pattern.footnotes_used[footnote_target]; + if !used { + bail!( + "in target pattern `{}`, the footnotes for target `{}` were never used", + target_pattern.info.pattern, + footnote_target, + ); + } + } + } + + render::render_static(check_only, Path::new(output_src), &targets)?; + + eprintln!("Finished generating target docs"); + Ok(()) +} + +struct TargetPatternEntry { + info: ParsedTargetInfoFile, + used: bool, + footnotes_used: HashMap, +} + +/// Information about a target obtained from the target_info markdown file. +struct TargetInfoMd { + name: String, + maintainers: Vec, + sections: Vec<(String, String)>, + footnotes: Vec, +} + +fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> TargetInfoMd { + let mut maintainers = Vec::new(); + let mut sections = Vec::new(); + + let mut footnotes = Vec::new(); + + for target_pattern_entry in info_patterns { + if glob_match::glob_match(&target_pattern_entry.info.pattern, target) { + target_pattern_entry.used = true; + let target_pattern = &target_pattern_entry.info; + + maintainers.extend_from_slice(&target_pattern.maintainers); + + for (section_name, content) in &target_pattern.sections { + if sections.iter().any(|(name, _)| name == section_name) { + panic!( + "target {target} inherits the section {section_name} from multiple patterns, create a more specific pattern and add it there" + ); + } + sections.push((section_name.clone(), content.clone())); + } + + if let Some(target_footnotes) = target_pattern.footnotes.get(target) { + target_pattern_entry.footnotes_used.insert(target.to_owned(), true); + + if !footnotes.is_empty() { + panic!("target {target} is assigned metadata from more than one pattern"); + } + footnotes = target_footnotes.clone(); + } + } + } + + TargetInfoMd { name: target.to_owned(), maintainers, sections, footnotes } +} + +/// Information about a target obtained from rustc. +struct RustcTargetInfo { + target_cfgs: Vec<(String, String)>, + metadata: RustcTargetMetadata, +} + +#[derive(Deserialize)] +struct RustcTargetMetadata { + description: Option, + tier: Option, + host_tools: Option, + std: Option, +} + +/// Get information about a target from rustc. +fn rustc_target_info(rustc: &Path, target: &str) -> RustcTargetInfo { + let cfgs = rustc_stdout(rustc, &["--print", "cfg", "--target", target]); + let target_cfgs = cfgs + .lines() + .filter_map(|line| { + if line.starts_with("target_") { + let Some((key, value)) = line.split_once('=') else { + // For example `unix` + return None; + }; + Some((key.to_owned(), value.to_owned())) + } else { + None + } + }) + .collect(); + + #[derive(Deserialize)] + struct TargetJson { + metadata: RustcTargetMetadata, + } + + let json_spec = rustc_stdout( + rustc, + &["-Zunstable-options", "--print", "target-spec-json", "--target", target], + ); + let spec = serde_json::from_str::(&json_spec) + .expect("parsing --print target-spec-json for metadata"); + + RustcTargetInfo { target_cfgs, metadata: spec.metadata } +} + +fn rustc_stdout(rustc: &Path, args: &[&str]) -> String { + let output = Command::new(rustc).args(args).output().unwrap(); + if !output.status.success() { + panic!( + "rustc failed: {}, {}", + output.status, + String::from_utf8(output.stderr).unwrap_or_default() + ) + } + String::from_utf8(output.stdout).unwrap() +} diff --git a/src/tools/target-docs/src/parse.rs b/src/tools/target-docs/src/parse.rs new file mode 100644 index 0000000000000..b771c8840209b --- /dev/null +++ b/src/tools/target-docs/src/parse.rs @@ -0,0 +1,135 @@ +//! Suboptimal half-markdown parser that's just good-enough for this. + +use eyre::{bail, OptionExt, Result, WrapErr}; +use serde::Deserialize; +use std::{collections::HashMap, fs::DirEntry, path::Path}; + +#[derive(Debug)] +pub struct ParsedTargetInfoFile { + pub pattern: String, + pub maintainers: Vec, + pub sections: Vec<(String, String)>, + pub footnotes: HashMap>, +} + +// IMPORTANT: This is also documented in the README, keep it in sync. +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct Frontmatter { + #[serde(default)] + maintainers: Vec, + #[serde(default)] + footnotes: HashMap>, +} + +// IMPORTANT: This is also documented in the README, keep it in sync. +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct TargetFootnotes { + pub target: String, + #[serde(default)] + pub footnotes: Vec, +} + +// IMPORTANT: This is also documented in the README, keep it in sync. +#[derive(Debug, PartialEq, Clone, Copy, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum TriStateBool { + True, + False, + Unknown, +} + +pub fn load_target_infos(directory: &Path) -> Result> { + let dir = std::fs::read_dir(directory).unwrap(); + let mut infos = Vec::new(); + + for entry in dir { + let entry = entry?; + infos.push( + load_single_target_info(&entry) + .wrap_err_with(|| format!("loading {}", entry.path().display()))?, + ) + } + + Ok(infos) +} + +fn load_single_target_info(entry: &DirEntry) -> Result { + let pattern = entry.file_name(); + let name = pattern + .to_str() + .ok_or_eyre("file name is invalid utf8")? + .strip_suffix(".md") + .ok_or_eyre("target_info files must end with .md")?; + let content: String = std::fs::read_to_string(entry.path()).wrap_err("reading content")?; + + parse_file(name, &content) +} + +fn parse_file(name: &str, content: &str) -> Result { + let mut frontmatter_splitter = content.split("---\n"); + + let frontmatter = frontmatter_splitter.nth(1).ok_or_eyre("missing frontmatter")?; + + let frontmatter_line_count = frontmatter.lines().count() + 2; // 2 from --- + + let frontmatter = + serde_yaml::from_str::(frontmatter).wrap_err("invalid frontmatter")?; + + let body = frontmatter_splitter.next().ok_or_eyre("no body")?; + + let mut sections = Vec::<(String, String)>::new(); + let mut in_codeblock = false; + + for (idx, line) in body.lines().enumerate() { + let number = frontmatter_line_count + idx + 1; // 1 because "line numbers" are off by 1 + + let push_line = |sections: &mut Vec<(String, String)>, line| { + match sections.last_mut() { + Some((_, content)) => { + content.push_str(line); + content.push('\n'); + } + None if line.trim().is_empty() => {} + None => { + bail!("line {number} with content not allowed before the first heading") + } + } + Ok(()) + }; + + if line.starts_with("```") { + in_codeblock ^= true; // toggle + push_line(&mut sections, line)?; + } else if line.starts_with('#') { + if in_codeblock { + push_line(&mut sections, line)?; + } else if let Some(header) = line.strip_prefix("## ") { + if !crate::SECTIONS.contains(&header) { + bail!( + "on line {number}, `{header}` is not an allowed section name, must be one of {:?}", + super::SECTIONS + ); + } + sections.push((header.to_owned(), String::new())); + } else { + bail!("on line {number}, the only allowed headings are `## `: `{line}`"); + } + } else { + push_line(&mut sections, line)?; + } + } + + sections.iter_mut().for_each(|section| section.1 = section.1.trim().to_owned()); + + Ok(ParsedTargetInfoFile { + pattern: name.to_owned(), + maintainers: frontmatter.maintainers, + sections, + footnotes: frontmatter.footnotes, + }) +} + +#[cfg(test)] +mod tests; diff --git a/src/tools/target-docs/src/parse/tests.rs b/src/tools/target-docs/src/parse/tests.rs new file mode 100644 index 0000000000000..5b0530ba52656 --- /dev/null +++ b/src/tools/target-docs/src/parse/tests.rs @@ -0,0 +1,99 @@ +#[test] +fn no_frontmatter() { + let name = "archlinux-unknown-linux-gnu.md"; // arch linux is an arch, right? + let content = ""; + assert!(super::parse_file(name, content).is_err()); +} + +#[test] +fn invalid_section() { + let name = "6502-nintendo-nes.md"; + let content = " +--- +--- + +## Not A Real Section +"; + + assert!(super::parse_file(name, content).is_err()); +} + +#[test] +fn wrong_header() { + let name = "x86_64-known-linux-gnu.md"; + let content = " +--- +--- + +# x86_64-known-linux-gnu +"; + + assert!(super::parse_file(name, content).is_err()); +} + +#[test] +fn parse_correctly() { + let name = "cat-unknown-linux-gnu.md"; + let content = r#" +--- +maintainers: ["who maintains the cat?"] +--- +## Requirements + +This target mostly just meows and doesn't do much. + +## Testing + +You can pet the cat and it might respond positively. + +## Cross compilation + +If you're on a dog system, there might be conflicts with the cat, be careful. +But it should be possible. + "#; + + let info = super::parse_file(name, content).unwrap(); + + assert_eq!(info.maintainers, vec!["who maintains the cat?"]); + assert_eq!(info.pattern, name); + assert_eq!( + info.sections, + vec![ + ( + "Requirements".to_owned(), + "This target mostly just meows and doesn't do much.".to_owned(), + ), + ( + "Testing".to_owned(), + "You can pet the cat and it might respond positively.".to_owned(), + ), + ( + "Cross compilation".to_owned(), + "If you're on a dog system, there might be conflicts with the cat, be careful.\nBut it should be possible.".to_owned(), + ), + ] + ); +} + +#[test] +fn backticks() { + let name = "microservices-unknown-linux-gnu"; // microservices are my favourite architecture + let content = r#" +--- +--- + +## Testing + +```text +# hello world +``` + "#; + + let info = super::parse_file(name, content).unwrap(); + + assert_eq!(info.pattern, name); + assert_eq!( + info.sections, + vec![("Testing".to_owned(), "```text\n# hello world\n```".to_owned(),),] + ); +} diff --git a/src/tools/target-docs/src/render.rs b/src/tools/target-docs/src/render.rs new file mode 100644 index 0000000000000..ecb18049a2b33 --- /dev/null +++ b/src/tools/target-docs/src/render.rs @@ -0,0 +1,257 @@ +use eyre::{Context, OptionExt, Result}; +use std::{fs, path::Path}; + +use crate::TargetInfo; + +/// Renders a single target markdown file from the information obtained. +pub fn render_target_md(target: &TargetInfo) -> String { + let render_header_option_bool = |bool| match bool { + Some(true) => "Yes", + Some(false) => "No", + None => "?", + }; + + let mut doc = format!( + "# {}\n\n**Tier: {}**\n\n**std: {}**\n\n**host tools: {}**\n\n", + target.name, + match target.metadata.tier { + Some(1) => "1", + Some(2) => "2", + Some(3) => "3", + _ => "UNKNOWN", + }, + render_header_option_bool(target.metadata.std), + render_header_option_bool(target.metadata.host_tools), + ); + + let mut section = |name: &str, content: &str| { + doc.push_str("## "); + doc.push_str(name.trim()); + doc.push('\n'); + doc.push_str(content.trim()); + doc.push_str("\n\n"); + }; + + let maintainers_content = if target.maintainers.is_empty() { + "This target does not have any maintainers!".to_owned() + } else { + format!( + "This target is maintained by:\n{}", + target + .maintainers + .iter() + .map(|maintainer| { + let maintainer = if maintainer.starts_with('@') && !maintainer.contains(' ') { + format!( + "[@{0}](https://github.com/{0})", + maintainer.strip_prefix("@").unwrap() + ) + } else { + maintainer.to_owned() + }; + + format!("- {maintainer}") + }) + .collect::>() + .join("\n") + ) + }; + + section("Maintainers", &maintainers_content); + + for section_name in crate::SECTIONS { + let value = target.sections.iter().find(|(name, _)| name == section_name); + + let section_content = match value { + Some((_, value)) => value.clone(), + None => "Unknown.".to_owned(), + }; + section(section_name, §ion_content); + } + + let cfg_text = target + .target_cfgs + .iter() + .map(|(key, value)| format!("- `{key}` = `{value}`")) + .collect::>() + .join("\n"); + let cfg_content = + format!("This target defines the following target-specific cfg values:\n{cfg_text}\n"); + + section("cfg", &cfg_content); + + doc +} + +/// Replaces inner part of the form +/// `` +/// with replacement`. +fn replace_section(prev_content: &str, section_name: &str, replacement: &str) -> Result { + let magic_summary_start = format!(""); + let magic_summary_end = format!(""); + + let (pre_target, target_and_after) = prev_content + .split_once(&magic_summary_start) + .ok_or_eyre(" not found")?; + + let (_, post_target) = target_and_after + .split_once(&magic_summary_end) + .ok_or_eyre(" not found")?; + + let new = format!("{pre_target}{replacement}{post_target}"); + Ok(new) +} + +/// Renders the non-target files like `SUMMARY.md` that depend on the target. +pub fn render_static(check_only: bool, src_output: &Path, targets: &[TargetInfo]) -> Result<()> { + let targets_file = src_output.join("platform-support").join("targets.md"); + let old_targets = fs::read_to_string(&targets_file).wrap_err("reading summary file")?; + + let target_list = targets + .iter() + .map(|target| format!("- [{0}](platform-support/targets/{0}.md)", target.name)) + .collect::>() + .join("\n"); + + let new_targets = + replace_section(&old_targets, "TARGET", &target_list).wrap_err("replacing targets.md")?; + + if !check_only { + fs::write(targets_file, new_targets).wrap_err("writing targets.md")?; + } + + let platform_support_main = src_output.join("platform-support.md"); + let platform_support_main_old = + fs::read_to_string(&platform_support_main).wrap_err("reading platform-support.md")?; + let platform_support_main_new = + render_platform_support_tables(&platform_support_main_old, targets)?; + + if !check_only { + fs::write(platform_support_main, platform_support_main_new) + .wrap_err("writing platform-support.md")?; + } + + let summary = src_output.join("SUMMARY.md"); + let summary_old = fs::read_to_string(&summary).wrap_err("reading SUMMARY.md")?; + // indent the list + let summary_new = + replace_section(&summary_old, "TARGET_LIST", &target_list.replace("- ", " - ")) + .wrap_err("replacig SUMMARY.md")?; + if !check_only { + fs::write(summary, summary_new).wrap_err("writing SUMAMRY.md")?; + } + + Ok(()) +} + +impl TargetInfo { + fn has_host_tools(&self) -> bool { + self.metadata.host_tools.unwrap_or(false) + } +} + +fn render_platform_support_tables(content: &str, targets: &[TargetInfo]) -> Result { + let replace_table = |content, name, tier_table| -> Result { + let section_string = render_table(targets, tier_table)?; + replace_section(content, name, §ion_string).wrap_err("replacing platform support.md") + }; + + let content = replace_table( + content, + "TIER1HOST", + TierTable { + filter: |target| target.metadata.tier == Some(1), + include_host: false, + include_std: false, + }, + )?; + let content = replace_table( + &content, + "TIER2HOST", + TierTable { + filter: |target| target.metadata.tier == Some(2) && target.has_host_tools(), + include_host: false, + include_std: false, + }, + )?; + let content = replace_table( + &content, + "TIER2", + TierTable { + filter: |target| target.metadata.tier == Some(2) && !target.has_host_tools(), + include_host: false, + include_std: true, + }, + )?; + let content = replace_table( + &content, + "TIER3", + TierTable { + filter: |target| target.metadata.tier == Some(3), + include_host: true, + include_std: true, + }, + )?; + + Ok(content) +} + +fn render_table_option_bool(bool: Option) -> &'static str { + match bool { + Some(true) => "✓", + Some(false) => " ", + None => "?", + } +} + +struct TierTable { + filter: fn(&TargetInfo) -> bool, + include_std: bool, + include_host: bool, +} + +fn render_table(targets: &[TargetInfo], table: TierTable) -> Result { + let mut rows = Vec::new(); + + let targets = targets.iter().filter(|target| (table.filter)(target)); + + for target in targets { + let meta = &target.metadata; + + let mut notes = meta.description.as_deref().unwrap_or("unknown").to_owned(); + + if !target.footnotes.is_empty() { + let footnotes_str = target + .footnotes + .iter() + .map(|footnote| format!("[^{}]", footnote)) + .collect::>() + .join(" "); + + notes = format!("{notes} {footnotes_str}"); + } + + let std = if table.include_std { + let std = render_table_option_bool(meta.std); + format!(" | {std}") + } else { + String::new() + }; + + let host = if table.include_host { + let host = render_table_option_bool(meta.host_tools); + format!(" | {host}") + } else { + String::new() + }; + + rows.push(format!( + "[`{0}`](platform-support/targets/{0}.md){std}{host} | {notes}", + target.name + )); + } + + let result = rows.join("\n"); + + Ok(result) +} From 87808e71be434dd5ba4fc23115ee84d9a3aaa094 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 23 Mar 2024 17:30:12 -0700 Subject: [PATCH 5/7] Use `chunk_by` when building `ReverseSccGraph` --- .../rustc_borrowck/src/region_infer/reverse_sccs.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index eeb944702a7f9..f94001de357a9 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -1,6 +1,5 @@ use crate::constraints::ConstraintSccIndex; use crate::RegionInferenceContext; -use itertools::Itertools; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::graph::WithSuccessors; @@ -48,16 +47,16 @@ impl RegionInferenceContext<'_> { .universal_regions .universal_regions() .map(|region| (self.constraint_sccs.scc(region), region)) - .collect_vec(); + .collect::>(); paired_scc_regions.sort(); let universal_regions = paired_scc_regions.iter().map(|&(_, region)| region).collect(); let mut scc_regions = FxIndexMap::default(); let mut start = 0; - for (scc, group) in &paired_scc_regions.into_iter().group_by(|(scc, _)| *scc) { - let group_size = group.count(); - scc_regions.insert(scc, start..start + group_size); - start += group_size; + for chunk in paired_scc_regions.chunk_by(|&(scc1, _), &(scc2, _)| scc1 == scc2) { + let (scc, _) = chunk[0]; + scc_regions.insert(scc, start..start + chunk.len()); + start += chunk.len(); } self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions }); From ea4518522f65480eb507a255dc215d39231e659f Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Mon, 19 Feb 2024 18:39:35 +0000 Subject: [PATCH 6/7] CFI: Handle dyn with no principal In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set. Fixes #122998 --- .../src/typeid/typeid_itanium_cxx_abi.rs | 27 ++++++++++--------- tests/ui/sanitizer/cfi-drop-no-principal.rs | 21 +++++++++++++++ 2 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 tests/ui/sanitizer/cfi-drop-no-principal.rs diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 367fec0e8fcb7..eda7d396d7240 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -747,9 +747,8 @@ fn transform_predicates<'tcx>( tcx: TyCtxt<'tcx>, predicates: &List>, ) -> &'tcx List> { - let predicates: Vec> = predicates - .iter() - .filter_map(|predicate| match predicate.skip_binder() { + tcx.mk_poly_existential_predicates_from_iter(predicates.iter().filter_map(|predicate| { + match predicate.skip_binder() { ty::ExistentialPredicate::Trait(trait_ref) => { let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id); Some(ty::Binder::dummy(ty::ExistentialPredicate::Trait( @@ -758,9 +757,8 @@ fn transform_predicates<'tcx>( } ty::ExistentialPredicate::Projection(..) => None, ty::ExistentialPredicate::AutoTrait(..) => Some(predicate), - }) - .collect(); - tcx.mk_poly_existential_predicates(&predicates) + } + })) } /// Transforms args for being encoded and used in the substitution dictionary. @@ -1171,14 +1169,17 @@ fn strip_receiver_auto<'tcx>( let ty::Dynamic(preds, lifetime, kind) = ty.kind() else { bug!("Tried to strip auto traits from non-dynamic type {ty}"); }; - let filtered_preds = - if preds.principal().is_some() { + let new_rcvr = if preds.principal().is_some() { + let filtered_preds = tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| { !matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..)) - })) - } else { - ty::List::empty() - }; - let new_rcvr = Ty::new_dynamic(tcx, filtered_preds, *lifetime, *kind); + })); + Ty::new_dynamic(tcx, filtered_preds, *lifetime, *kind) + } else { + // If there's no principal type, re-encode it as a unit, since we don't know anything + // about it. This technically discards the knowledge that it was a type that was made + // into a trait object at some point, but that's not a lot. + tcx.types.unit + }; tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1)) } diff --git a/tests/ui/sanitizer/cfi-drop-no-principal.rs b/tests/ui/sanitizer/cfi-drop-no-principal.rs new file mode 100644 index 0000000000000..c1c88c8c71c73 --- /dev/null +++ b/tests/ui/sanitizer/cfi-drop-no-principal.rs @@ -0,0 +1,21 @@ +// Check that dropping a trait object without a principal trait succeeds + +//@ needs-sanitizer-cfi +// FIXME(#122848) Remove only-linux once OSX CFI binaries works +//@ only-linux +//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi +//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0 +// FIXME(#118761) Should be run-pass once the labels on drop are compatible. +// This test is being landed ahead of that to test that the compiler doesn't ICE while labeling the +// callsite for a drop, but the vtable doesn't have the correct label yet. +//@ build-pass + +struct CustomDrop; + +impl Drop for CustomDrop { + fn drop(&mut self) {} +} + +fn main() { + let _ = Box::new(CustomDrop) as Box; +} From aaf49b4a82e8132fcce696ea221e95dcf9989635 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Fri, 22 Mar 2024 17:43:53 -0700 Subject: [PATCH 7/7] In `pretty_print_type()`, print `async fn` futures' paths instead of spans. This makes `-Zprint-type-sizes`'s output easier to read, because the name of an `async fn` is more immediately recognizable than its span. I also deleted the comment "FIXME(eddyb) should use `def_span`." because it appears to have already been fixed by commit 67727aa7c31a24ea73a91a9134c3653fae8209ab. --- compiler/rustc_middle/src/ty/print/pretty.rs | 18 ++++-- ...await.a-{closure#0}.coroutine_resume.0.mir | 6 +- ...await.b-{closure#0}.coroutine_resume.0.mir | 62 +++++++++---------- ....run2-{closure#0}.Inline.panic-unwind.diff | 62 +++++++++---------- .../future-sizes/async-awaiting-fut.stdout | 28 ++++----- .../async-await/future-sizes/large-arg.stdout | 26 ++++---- .../trait-bounds/future.current.stderr | 2 +- tests/ui/print_type_sizes/async.stdout | 10 +-- .../hkl_forbidden4.stderr | 2 +- 9 files changed, 112 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3f0a3a1a7bfb1..914b19efc7e85 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -804,7 +804,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } ty::Str => p!("str"), ty::Coroutine(did, args) => { - p!(write("{{")); + p!("{{"); let coroutine_kind = self.tcx().coroutine_kind(did).unwrap(); let should_print_movability = self.should_print_verbose() || matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_)); @@ -818,9 +818,17 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { if !self.should_print_verbose() { p!(write("{}", coroutine_kind)); - // FIXME(eddyb) should use `def_span`. - if let Some(did) = did.as_local() { - let span = self.tcx().def_span(did); + if coroutine_kind.is_fn_like() { + // If we are printing an `async fn` coroutine type, then give the path + // of the fn, instead of its span, because that will in most cases be + // more helpful for the reader than just a source location. + // + // This will look like: + // {async fn body of some_fn()} + let did_of_the_fn_item = self.tcx().parent(did); + p!(" of ", print_def_path(did_of_the_fn_item, args), "()"); + } else if let Some(local_did) = did.as_local() { + let span = self.tcx().def_span(local_did); p!(write( "@{}", // This may end up in stderr diagnostics but it may also be emitted @@ -828,7 +836,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { self.tcx().sess.source_map().span_to_embeddable_string(span) )); } else { - p!(write("@"), print_def_path(did, args)); + p!("@", print_def_path(did, args)); } } else { p!(print_def_path(did, args)); diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir index 8b22743d2b066..7480324b17791 100644 --- a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir @@ -9,7 +9,7 @@ storage_conflicts: BitMatrix(0x0) {}, } */ -fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>, _2: &mut Context<'_>) -> Poll<()> { +fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _4; let mut _0: std::task::Poll<()>; let mut _3: (); @@ -17,7 +17,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}> let mut _5: u32; bb0: { - _5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}))); + _5 = discriminant((*(_1.0: &mut {async fn body of a()}))); switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5]; } @@ -29,7 +29,7 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}> bb2: { _0 = Poll::<()>::Ready(move _3); - discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}))) = 1; + discriminant((*(_1.0: &mut {async fn body of a()}))) = 1; return; } diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index 2f7c4f7d40221..d697ea4923167 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -51,19 +51,19 @@ }, } */ -fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, _2: &mut Context<'_>) -> Poll<()> { +fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> { debug _task_context => _38; let mut _0: std::task::Poll<()>; let _3: (); - let mut _4: {async fn body@$DIR/async_await.rs:12:14: 12:16}; - let mut _5: {async fn body@$DIR/async_await.rs:12:14: 12:16}; - let mut _6: {async fn body@$DIR/async_await.rs:12:14: 12:16}; + let mut _4: {async fn body of a()}; + let mut _5: {async fn body of a()}; + let mut _6: {async fn body of a()}; let mut _7: (); let _8: (); let mut _9: std::task::Poll<()>; - let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>; - let mut _11: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}; - let mut _12: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}; + let mut _10: std::pin::Pin<&mut {async fn body of a()}>; + let mut _11: &mut {async fn body of a()}; + let mut _12: &mut {async fn body of a()}; let mut _13: &mut std::task::Context<'_>; let mut _14: &mut std::task::Context<'_>; let mut _15: &mut std::task::Context<'_>; @@ -71,14 +71,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, let mut _18: !; let mut _19: &mut std::task::Context<'_>; let mut _20: (); - let mut _21: {async fn body@$DIR/async_await.rs:12:14: 12:16}; - let mut _22: {async fn body@$DIR/async_await.rs:12:14: 12:16}; - let mut _23: {async fn body@$DIR/async_await.rs:12:14: 12:16}; + let mut _21: {async fn body of a()}; + let mut _22: {async fn body of a()}; + let mut _23: {async fn body of a()}; let _24: (); let mut _25: std::task::Poll<()>; - let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>; - let mut _27: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}; - let mut _28: &mut {async fn body@$DIR/async_await.rs:12:14: 12:16}; + let mut _26: std::pin::Pin<&mut {async fn body of a()}>; + let mut _27: &mut {async fn body of a()}; + let mut _28: &mut {async fn body of a()}; let mut _29: &mut std::task::Context<'_>; let mut _30: &mut std::task::Context<'_>; let mut _31: &mut std::task::Context<'_>; @@ -90,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, let mut _38: &mut std::task::Context<'_>; let mut _39: u32; scope 1 { - debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}); + debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}); let _17: (); scope 2 { } @@ -99,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, } } scope 4 { - debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}); + debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}); let _33: (); scope 5 { } @@ -109,7 +109,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, } bb0: { - _39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))); + _39 = discriminant((*(_1.0: &mut {async fn body of b()}))); switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; } @@ -122,14 +122,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, } bb2: { - _4 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; + _4 = <{async fn body of a()} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; } bb3: { StorageDead(_5); PlaceMention(_4); nop; - (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _4; + (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}) = move _4; goto -> bb4; } @@ -139,9 +139,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageLive(_10); StorageLive(_11); StorageLive(_12); - _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}); + _12 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}); _11 = &mut (*_12); - _10 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; + _10 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; } bb5: { @@ -157,7 +157,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, bb6: { _13 = &mut (*_14); StorageDead(_15); - _9 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; + _9 = <{async fn body of a()} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; } bb7: { @@ -186,7 +186,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageDead(_4); StorageDead(_19); StorageDead(_20); - discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3; + discriminant((*(_1.0: &mut {async fn body of b()}))) = 3; return; } @@ -199,7 +199,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageDead(_12); StorageDead(_9); StorageDead(_8); - drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb12, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()})) -> [return: bb12, unwind unreachable]; } bb11: { @@ -224,14 +224,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, } bb14: { - _21 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; + _21 = <{async fn body of a()} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; } bb15: { StorageDead(_22); PlaceMention(_21); nop; - (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _21; + (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}) = move _21; goto -> bb16; } @@ -241,9 +241,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageLive(_26); StorageLive(_27); StorageLive(_28); - _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}); + _28 = &mut (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()}); _27 = &mut (*_28); - _26 = Pin::<&mut {async fn body@$DIR/async_await.rs:12:14: 12:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; + _26 = Pin::<&mut {async fn body of a()}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; } bb17: { @@ -259,7 +259,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, bb18: { _29 = &mut (*_30); StorageDead(_31); - _25 = <{async fn body@$DIR/async_await.rs:12:14: 12:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; + _25 = <{async fn body of a()} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; } bb19: { @@ -283,7 +283,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageDead(_21); StorageDead(_35); StorageDead(_36); - discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4; + discriminant((*(_1.0: &mut {async fn body of b()}))) = 4; return; } @@ -296,7 +296,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, StorageDead(_28); StorageDead(_25); StorageDead(_24); - drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16})) -> [return: bb23, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()})) -> [return: bb23, unwind unreachable]; } bb22: { @@ -319,7 +319,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>, bb25: { _0 = Poll::<()>::Ready(move _37); - discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 1; + discriminant((*(_1.0: &mut {async fn body of b()}))) = 1; return; } diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index ed18c0a3adb8c..96a93cdda3dfc 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -5,24 +5,24 @@ debug permit => (_1.0: ActionPermit<'_, T>); debug ctx => (*(_1.1: &mut std::task::Context<'_>)); let mut _0: (); - let mut _2: {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; + let mut _2: {async fn body of ActionPermit<'_, T>::perform()}; let mut _3: ActionPermit<'_, T>; - let mut _5: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; + let mut _5: &mut {async fn body of ActionPermit<'_, T>::perform()}; let _6: (); let mut _7: std::task::Poll<()>; - let mut _8: std::pin::Pin<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>; + let mut _8: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>; let mut _9: &mut std::task::Context<'_>; let mut _10: &mut std::task::Context<'_>; scope 1 { debug fut => _2; - let _4: std::pin::Pin<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>; + let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>; scope 2 { debug fut => _4; scope 4 { } + scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) { + debug _task_context => _31; -+ debug self => ((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})).0: ActionPermit<'_, T>); ++ debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>); + let _11: ActionPermit<'_, T>; + let mut _12: std::future::Ready<()>; + let mut _13: std::future::Ready<()>; @@ -43,21 +43,21 @@ + let mut _30: (); + let mut _31: &mut std::task::Context<'_>; + let mut _32: u32; -+ let mut _33: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _34: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _35: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _36: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _37: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _38: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _39: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _40: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _41: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; -+ let mut _42: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}; ++ let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _36: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _37: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _41: &mut {async fn body of ActionPermit<'_, T>::perform()}; ++ let mut _42: &mut {async fn body of ActionPermit<'_, T>::perform()}; + scope 8 { -+ debug self => (((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})) as variant#3).0: ActionPermit<'_, T>); ++ debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>); + let mut _15: std::future::Ready<()>; + scope 9 { -+ debug __awaitee => (((*(_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6})) as variant#3).1: std::future::Ready<()>); ++ debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>); + let _26: (); + scope 10 { + } @@ -73,7 +73,7 @@ + } } scope 3 { -+ scope 6 (inlined Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>::new_unchecked) { ++ scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) { + debug pointer => _5; + } } @@ -95,11 +95,11 @@ StorageLive(_4); StorageLive(_5); _5 = &mut _2; -- _4 = Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}>::new_unchecked(move _5) -> [return: bb2, unwind: bb5]; +- _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked(move _5) -> [return: bb2, unwind: bb5]; - } - - bb2: { -+ _4 = Pin::<&mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}> { __pointer: _5 }; ++ _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}> { __pointer: _5 }; StorageDead(_5); StorageLive(_6); StorageLive(_7); @@ -108,7 +108,7 @@ StorageLive(_9); _10 = deref_copy (_1.1: &mut std::task::Context<'_>); _9 = &mut (*_10); -- _7 = <{async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5]; +- _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5]; + StorageLive(_11); + StorageLive(_15); + StorageLive(_16); @@ -127,7 +127,7 @@ + StorageLive(_40); + StorageLive(_41); + StorageLive(_42); -+ _33 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _32 = discriminant((*_33)); + switchInt(move _32) -> [0: bb5, 1: bb22, 2: bb21, 3: bb20, otherwise: bb10]; } @@ -181,8 +181,8 @@ - return; + bb5: { + _31 = move _9; -+ _34 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); -+ _35 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>); + StorageLive(_12); + StorageLive(_13); @@ -200,7 +200,7 @@ - drop(_2) -> [return: bb6, unwind terminate(cleanup)]; + bb6: { + StorageDead(_13); -+ _36 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + (((*_36) as variant#3).1: std::future::Ready<()>) = move _12; + goto -> bb7; } @@ -213,7 +213,7 @@ + StorageLive(_19); + StorageLive(_20); + StorageLive(_21); -+ _37 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>); + _20 = &mut (*_21); + _19 = Pin::<&mut std::future::Ready<()>>::new_unchecked(move _20) -> [return: bb8, unwind: bb15]; @@ -255,7 +255,7 @@ + StorageDead(_12); + StorageDead(_28); + StorageDead(_29); -+ _38 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_38)) = 3; + goto -> bb4; + } @@ -270,13 +270,13 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ _39 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb13, unwind: bb19]; + } + + bb13: { + _7 = Poll::<()>::Ready(move _30); -+ _40 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_40)) = 1; + goto -> bb4; + } @@ -308,12 +308,12 @@ + + bb18 (cleanup): { + StorageDead(_12); -+ _41 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb19, unwind terminate(cleanup)]; + } + + bb19 (cleanup): { -+ _42 = deref_copy (_8.0: &mut {async fn body@$DIR/inline_coroutine_body.rs:25:28: 27:6}); ++ _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); + discriminant((*_42)) = 2; + goto -> bb2; + } diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index d6fb643702c56..def967ba195ef 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -1,17 +1,17 @@ -print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:21:21: 24:2}`: 3078 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of test()}`: 3078 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Suspend0`: 3077 bytes -print-type-size local `.__awaitee`: 3077 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2} +print-type-size local `.__awaitee`: 3077 bytes, type: {async fn body of calls_fut<{async fn body of big_fut()}>()} print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}>`: 3077 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size field `.value`: 3077 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}>`: 3077 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3077 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 3077 bytes -print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2}`: 3077 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of calls_fut<{async fn body of big_fut()}>()}`: 3077 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes @@ -20,29 +20,29 @@ print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 print-type-size padding: 1 bytes print-type-size local `.fut`: 1025 bytes, alignment: 1 bytes print-type-size local `..coroutine_field4`: 1 bytes, type: bool -print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19} +print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()} print-type-size variant `Suspend1`: 3076 bytes print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size padding: 1026 bytes print-type-size local `..coroutine_field4`: 1 bytes, alignment: 1 bytes, type: bool -print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37} +print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body of big_fut()} print-type-size variant `Suspend2`: 2052 bytes print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size padding: 1 bytes print-type-size local `.fut`: 1025 bytes, alignment: 1 bytes print-type-size local `..coroutine_field4`: 1 bytes, type: bool -print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19} +print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()} print-type-size variant `Returned`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes print-type-size variant `Panicked`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}>`: 1025 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}>`: 1025 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1025 bytes -print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37}`: 1025 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of big_fut()}`: 1025 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 1024 bytes print-type-size upvar `.arg`: 1024 bytes @@ -52,13 +52,13 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.arg`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes print-type-size type: `std::mem::MaybeUninit`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1 bytes @@ -67,7 +67,7 @@ print-type-size discriminant: 1 bytes print-type-size variant `Ready`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Pending`: 0 bytes -print-type-size type: `{async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19}`: 1 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of wait()}`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Returned`: 0 bytes diff --git a/tests/ui/async-await/future-sizes/large-arg.stdout b/tests/ui/async-await/future-sizes/large-arg.stdout index 589df102af4bd..67168a3d6ef74 100644 --- a/tests/ui/async-await/future-sizes/large-arg.stdout +++ b/tests/ui/async-await/future-sizes/large-arg.stdout @@ -1,47 +1,47 @@ -print-type-size type: `{async fn body@$DIR/large-arg.rs:6:21: 8:2}`: 3076 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of test()}`: 3076 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Suspend0`: 3075 bytes -print-type-size local `.__awaitee`: 3075 bytes, type: {async fn body@$DIR/large-arg.rs:10:30: 12:2} +print-type-size local `.__awaitee`: 3075 bytes, type: {async fn body of a<[u8; 1024]>()} print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:10:30: 12:2}>`: 3075 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size field `.value`: 3075 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/large-arg.rs:10:30: 12:2}>`: 3075 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3075 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 3075 bytes -print-type-size type: `{async fn body@$DIR/large-arg.rs:10:30: 12:2}`: 3075 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of a<[u8; 1024]>()}`: 3075 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size variant `Suspend0`: 3074 bytes print-type-size upvar `.t`: 1024 bytes -print-type-size local `.__awaitee`: 2050 bytes, type: {async fn body@$DIR/large-arg.rs:13:26: 15:2} +print-type-size local `.__awaitee`: 2050 bytes, type: {async fn body of b<[u8; 1024]>()} print-type-size variant `Returned`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:13:26: 15:2}>`: 2050 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size field `.value`: 2050 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/large-arg.rs:13:26: 15:2}>`: 2050 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 2050 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 2050 bytes -print-type-size type: `{async fn body@$DIR/large-arg.rs:13:26: 15:2}`: 2050 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of b<[u8; 1024]>()}`: 2050 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size variant `Suspend0`: 2049 bytes print-type-size upvar `.t`: 1024 bytes -print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body@$DIR/large-arg.rs:16:26: 18:2} +print-type-size local `.__awaitee`: 1025 bytes, type: {async fn body of c<[u8; 1024]>()} print-type-size variant `Returned`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/large-arg.rs:16:26: 18:2}>`: 1025 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/large-arg.rs:16:26: 18:2}>`: 1025 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1025 bytes @@ -50,7 +50,7 @@ print-type-size discriminant: 1 bytes print-type-size variant `Ready`: 1024 bytes print-type-size field `.0`: 1024 bytes print-type-size variant `Pending`: 0 bytes -print-type-size type: `{async fn body@$DIR/large-arg.rs:16:26: 18:2}`: 1025 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of c<[u8; 1024]>()}`: 1025 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 1024 bytes print-type-size upvar `.t`: 1024 bytes diff --git a/tests/ui/higher-ranked/trait-bounds/future.current.stderr b/tests/ui/higher-ranked/trait-bounds/future.current.stderr index 5a6381ad28eb3..673bc48a424e7 100644 --- a/tests/ui/higher-ranked/trait-bounds/future.current.stderr +++ b/tests/ui/higher-ranked/trait-bounds/future.current.stderr @@ -1,6 +1,6 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> {async fn body@$DIR/future.rs:33:35: 35:2}: core::future::future::Future` +#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> {async fn body of strlen()}: core::future::future::Future` #1 [codegen_select_candidate] computing candidate for `` end of query stack diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index 1df4d85d09e33..83a6962e4cd13 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -1,11 +1,11 @@ -print-type-size type: `{async fn body@$DIR/async.rs:10:36: 13:2}`: 16386 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of test()}`: 16386 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes print-type-size variant `Suspend0`: 16385 bytes print-type-size upvar `.arg`: 8192 bytes print-type-size local `.arg`: 8192 bytes -print-type-size local `.__awaitee`: 1 bytes, type: {async fn body@$DIR/async.rs:8:17: 8:19} +print-type-size local `.__awaitee`: 1 bytes, type: {async fn body of wait()} print-type-size variant `Returned`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes print-type-size variant `Panicked`: 8192 bytes @@ -16,9 +16,9 @@ print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment print-type-size variant `MaybeUninit`: 8192 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 8192 bytes -print-type-size type: `std::mem::ManuallyDrop<{async fn body@$DIR/async.rs:8:17: 8:19}>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes -print-type-size type: `std::mem::MaybeUninit<{async fn body@$DIR/async.rs:8:17: 8:19}>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1 bytes @@ -27,7 +27,7 @@ print-type-size discriminant: 1 bytes print-type-size variant `Ready`: 0 bytes print-type-size field `.0`: 0 bytes print-type-size variant `Pending`: 0 bytes -print-type-size type: `{async fn body@$DIR/async.rs:8:17: 8:19}`: 1 bytes, alignment: 1 bytes +print-type-size type: `{async fn body of wait()}`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Returned`: 0 bytes diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index d7a0452727e83..cd4982b24809a 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -10,7 +10,7 @@ error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:13:1 | LL | async fn operation(_: &mut ()) -> () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body@$DIR/hkl_forbidden4.rs:13:38: 16:2}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `FutNothing<'_>`, got `{async fn body of operation()}` | note: previous use here --> $DIR/hkl_forbidden4.rs:15:5