From 87ad80a6384824fb5e13cc54278eb5aaa36a89a4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 1 Jun 2024 13:03:07 -0700 Subject: [PATCH 01/17] Add `target_env = "p1"` to the `wasm32-wasip1` target This commit sets the `target_env` key for the `wasm32-wasi{,p1,p1-threads}` targets to the string `"p1"`. This mirrors how the `wasm32-wasip2` target has `target_env = "p2"`. The intention of this is to more easily detect each target in downstream crates to enable adding custom code per-target. cc #125803 --- .../rustc_target/src/spec/targets/wasm32_wasip1.rs | 1 + .../src/spec/targets/wasm32_wasip1_threads.rs | 1 + .../src/platform-support/wasm32-wasip1-threads.md | 12 ++++++++++++ src/doc/rustc/src/platform-support/wasm32-wasip1.md | 11 +++++++++++ src/doc/rustc/src/platform-support/wasm32-wasip2.md | 8 ++++++++ 5 files changed, 33 insertions(+) diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs index 7cbe9f09e6ca4..4c2d222b590e4 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs @@ -18,6 +18,7 @@ pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "wasi".into(); + options.env = "p1".into(); options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs index c592b944d44a8..38af48ab2665a 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs @@ -13,6 +13,7 @@ pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "wasi".into(); + options.env = "p1".into(); options.add_pre_link_args( LinkerFlavor::WasmLld(Cc::No), diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 519e9cc7cc49c..66cf964bd259d 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -150,3 +150,15 @@ or another engine that supports `wasi-threads` is installed and can be found in 5. Apply such [a change](https://github.com/g0djan/rust/compare/godjan/wasi-threads...g0djan:rust:godjan/wasi-run-ui-tests?expand=1) with an engine from the step 1. 6. Run `./x.py test --target wasm32-wasip1-threads tests/ui` and save the list of failed tests. 7. For both lists of failed tests run `cat list | sort > sorted_list` and compare it with `diff sorted_list1 sorted_list2`. + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +``` +#[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))] +``` + +Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the +`target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` +necessary to detect this target may change as the target becomes more stable. diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 4faa198873536..3f6ed130e12a2 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -121,3 +121,14 @@ can be tested locally, for example, with: ```text ./x.py test --target wasm32-wasip1 tests/ui ``` + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +``` +#[cfg(all(target_os = "wasi", target_env = "p1"))] +``` + +Note that the `target_env = "p1"` condition first appeared in Rust 1.80. Prior +to Rust 1.80 the `target_env` condition was not set. diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md index a385600cc224b..7b4eb31b21497 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md @@ -53,3 +53,11 @@ This target is not tested in CI at this time. Locally it can be tested with a ```text ./x.py test --target wasm32-wasip2 tests/ui ``` + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +``` +#[cfg(all(target_os = "wasi", target_env = "p2"))] +``` From 5ecb034cc307e40feda18f216f44564b13fa2a65 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 1 Jun 2024 13:40:41 -0700 Subject: [PATCH 02/17] Update test expectations --- tests/ui/check-cfg/well-known-values.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 0c50ec1abba99..95a92283db1e3 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -147,7 +147,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From d313e7e1836e3f92f42f6acdea449224288a1f23 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 2 Jun 2024 11:28:04 -0700 Subject: [PATCH 03/17] Fix testing examples in documentation --- src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md | 2 +- src/doc/rustc/src/platform-support/wasm32-wasip1.md | 2 +- src/doc/rustc/src/platform-support/wasm32-wasip2.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 66cf964bd259d..2b3d15e93c8cb 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -155,7 +155,7 @@ or another engine that supports `wasi-threads` is installed and can be found in It's recommended to conditionally compile code for this target with: -``` +```text #[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))] ``` diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 3f6ed130e12a2..fb70bbdc2b403 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -126,7 +126,7 @@ can be tested locally, for example, with: It's recommended to conditionally compile code for this target with: -``` +```text #[cfg(all(target_os = "wasi", target_env = "p1"))] ``` diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md index 7b4eb31b21497..1e53fbc178e2e 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md @@ -58,6 +58,6 @@ This target is not tested in CI at this time. Locally it can be tested with a It's recommended to conditionally compile code for this target with: -``` +```text #[cfg(all(target_os = "wasi", target_env = "p2"))] ``` From f88c647cdab91b7f82de2d68fb7ec0f4d00f86b8 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 5 Jun 2024 12:07:27 -0400 Subject: [PATCH 04/17] rewrite `short-ice` in `rmake` format --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/short-ice/Makefile | 10 ------ tests/run-make/short-ice/check.sh | 36 ------------------- tests/run-make/short-ice/rmake.rs | 31 ++++++++++++++++ 4 files changed, 31 insertions(+), 47 deletions(-) delete mode 100644 tests/run-make/short-ice/Makefile delete mode 100644 tests/run-make/short-ice/check.sh create mode 100644 tests/run-make/short-ice/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a015f96ae51d8..82f0a6531a755 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -218,7 +218,6 @@ run-make/sepcomp-cci-copies/Makefile run-make/sepcomp-inlining/Makefile run-make/sepcomp-separate/Makefile run-make/share-generics-dylib/Makefile -run-make/short-ice/Makefile run-make/silly-file-names/Makefile run-make/simd-ffi/Makefile run-make/split-debuginfo/Makefile diff --git a/tests/run-make/short-ice/Makefile b/tests/run-make/short-ice/Makefile deleted file mode 100644 index 23006fc09e2f3..0000000000000 --- a/tests/run-make/short-ice/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include ../tools.mk - -# ignore-windows - -export RUSTC := $(RUSTC_ORIGINAL) -export LD_LIBRARY_PATH := $(HOST_RPATH_DIR) -export TMPDIR := $(TMPDIR) - -all: - bash check.sh diff --git a/tests/run-make/short-ice/check.sh b/tests/run-make/short-ice/check.sh deleted file mode 100644 index 56babd2142f8c..0000000000000 --- a/tests/run-make/short-ice/check.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -export RUSTC_ICE=0 -RUST_BACKTRACE=1 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-1.log 2>&1 -RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-2.log 2>&1 - -short=$(cat $TMPDIR/rust-test-1.log | wc -l) -full=$(cat $TMPDIR/rust-test-2.log | wc -l) -rustc_query_count=$(cat $TMPDIR/rust-test-1.log | grep rustc_query_ | wc -l) -rustc_query_count_full=$(cat $TMPDIR/rust-test-2.log | grep rustc_query_ | wc -l) - -begin_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_begin_short_backtrace | wc -l) -end_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_end_short_backtrace | wc -l) - -cat $TMPDIR/rust-test-1.log -echo "=====================" -cat $TMPDIR/rust-test-2.log -echo "=====================" - -echo "short backtrace: $short" -echo "full backtrace: $full" -echo "begin_count: $begin_count" -echo "end_count : $end_count" -echo "rustc_query_count: $rustc_query_count" -echo "rustc_query_count_full: $rustc_query_count_full" - -## backtraces to vary a bit depending on platform and configuration options, -## here we make sure that the short backtrace of rustc_query is shorter than the full, -## and marks are in pairs. -if [ $short -lt $full ] && - [ $begin_count -eq $end_count ] && - [ $(($rustc_query_count + 5)) -lt $rustc_query_count_full ] && - [ $rustc_query_count_full -gt 5 ]; then - exit 0 -else - exit 1 -fi diff --git a/tests/run-make/short-ice/rmake.rs b/tests/run-make/short-ice/rmake.rs new file mode 100644 index 0000000000000..0aa1df61dbea0 --- /dev/null +++ b/tests/run-make/short-ice/rmake.rs @@ -0,0 +1,31 @@ +// Backtraces in internal compiler errors used to be unbearably long, spanning +// multiple hundreds of lines. A fix was pushed in #108938, and this test gathers +// varied metrics on level 1 and full-level backtraces to check that the output +// was shortened down to an appropriate length. +// See https://github.com/rust-lang/rust/issues/107910 + +use run_make_support::rustc; +use std::env; + +fn main() { + env::set_var("RUST_BACKTRACE", "1"); + let mut rust_test_1 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + env::set_var("RUST_BACKTRACE", "full"); + let mut rust_test_2 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let rust_test_log_1 = rust_test_1.stderr_utf8().push_str(&rust_test_1.stdout_utf8()).as_str(); + let rust_test_log_2 = rust_test_2.stderr_utf8().push_str(&rust_test_2.stdout_utf8()).as_str(); + + let rustc_query_count_full = count_lines_with(rust_test_log_2, "rustc_query_"); + + assert!( + rust_test_log_1.lines().count() < rust_test_log_2.lines().count() + && count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace") + == count_lines_with(rust_test_log_2, "__rust_end_short_backtrace") + && count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full + && rustc_query_count_full > 5 + ); +} + +fn count_lines_with(s: &str, search: &str) -> usize { + s.lines().filter(|l| l.contains(search)).count() +} From bbc50376b0f44c70e3a17a2db5cd16f3ad4f04f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 11 Jun 2024 16:30:47 +0000 Subject: [PATCH 05/17] ensure the self-contained linker is only enabled on nightly/dev --- src/bootstrap/src/core/build_steps/compile.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 66692a2a2cbbc..b16f3e5bd81c4 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1137,7 +1137,9 @@ pub fn rustc_cargo_env( } // Enable rustc's env var for `rust-lld` when requested. - if builder.config.lld_enabled { + if builder.config.lld_enabled + && (builder.config.channel == "dev" || builder.config.channel == "nightly") + { cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1"); } From 8a6bc13cfe2fe90237f76c58933d10d76fc8a29c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sun, 9 Jun 2024 14:24:36 -0400 Subject: [PATCH 06/17] Add set_backtrace_level helper function to run_make_support --- src/tools/run-make-support/src/rustc.rs | 6 ++++ tests/run-make/short-ice/rmake.rs | 37 ++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index d4c00d23b8b1c..2538c475caecf 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -100,6 +100,12 @@ impl Rustc { self } + //Adjust the backtrace level, displaying more detailed information at higher levels. + pub fn set_backtrace_level>(&mut self, level: R) -> &mut Self { + self.cmd.env("RUST_BACKTRACE", level); + self + } + /// Specify path to the output file. Equivalent to `-o`` in rustc. pub fn output>(&mut self, path: P) -> &mut Self { self.cmd.arg("-o"); diff --git a/tests/run-make/short-ice/rmake.rs b/tests/run-make/short-ice/rmake.rs index 0aa1df61dbea0..81403931c783e 100644 --- a/tests/run-make/short-ice/rmake.rs +++ b/tests/run-make/short-ice/rmake.rs @@ -4,26 +4,37 @@ // was shortened down to an appropriate length. // See https://github.com/rust-lang/rust/issues/107910 +//@ ignore-windows +// Reason: the assert_eq! on line 32 fails, as error output on Windows is different. + use run_make_support::rustc; -use std::env; fn main() { - env::set_var("RUST_BACKTRACE", "1"); - let mut rust_test_1 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); - env::set_var("RUST_BACKTRACE", "full"); - let mut rust_test_2 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); - let rust_test_log_1 = rust_test_1.stderr_utf8().push_str(&rust_test_1.stdout_utf8()).as_str(); - let rust_test_log_2 = rust_test_2.stderr_utf8().push_str(&rust_test_2.stdout_utf8()).as_str(); + let rust_test_1 = + rustc().set_backtrace_level("1").input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let rust_test_2 = rustc() + .set_backtrace_level("full") + .input("src/lib.rs") + .arg("-Ztreat-err-as-bug=1") + .run_fail(); + + let mut rust_test_log_1 = rust_test_1.stderr_utf8(); + rust_test_log_1.push_str(&rust_test_1.stdout_utf8()); + let rust_test_log_1 = rust_test_log_1.as_str(); + + let mut rust_test_log_2 = rust_test_2.stderr_utf8(); + rust_test_log_2.push_str(&rust_test_2.stdout_utf8()); + let rust_test_log_2 = rust_test_log_2.as_str(); let rustc_query_count_full = count_lines_with(rust_test_log_2, "rustc_query_"); - assert!( - rust_test_log_1.lines().count() < rust_test_log_2.lines().count() - && count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace") - == count_lines_with(rust_test_log_2, "__rust_end_short_backtrace") - && count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full - && rustc_query_count_full > 5 + assert!(rust_test_log_1.lines().count() < rust_test_log_2.lines().count()); + assert_eq!( + count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace"), + count_lines_with(rust_test_log_2, "__rust_end_short_backtrace") ); + assert!(count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full); + assert!(rustc_query_count_full > 5); } fn count_lines_with(s: &str, search: &str) -> usize { From 185a48d4b266722d550474a620c0e37e28b1c6d6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 08:55:48 +0000 Subject: [PATCH 07/17] Bump tracing-tree and allow rendering lines again --- compiler/rustc_log/Cargo.toml | 2 +- compiler/rustc_log/src/lib.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 3ff86f700a535..fe399bc77e32a 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" tracing = "0.1.28" tracing-core = "=0.1.30" # FIXME(Nilstrieb) tracing has a deadlock: https://github.com/tokio-rs/tracing/issues/2635 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } -tracing-tree = "0.3.0" +tracing-tree = "0.3.1" # tidy-alphabetical-end [dev-dependencies] diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 41b26ecce3c54..01b6e342df047 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -58,6 +58,7 @@ pub struct LoggerConfig { pub verbose_thread_ids: Result, pub backtrace: Result, pub wraptree: Result, + pub lines: Result, } impl LoggerConfig { @@ -69,6 +70,7 @@ impl LoggerConfig { verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")), backtrace: env::var(format!("{env}_BACKTRACE")), wraptree: env::var(format!("{env}_WRAPTREE")), + lines: env::var(format!("{env}_LINES")), } } } @@ -101,6 +103,11 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { Err(_) => false, }; + let lines = match cfg.lines { + Ok(v) => &v == "1", + Err(_) => false, + }; + let mut layer = tracing_tree::HierarchicalLayer::default() .with_writer(io::stderr) .with_ansi(color_logs) @@ -108,6 +115,7 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { .with_verbose_exit(verbose_entry_exit) .with_verbose_entry(verbose_entry_exit) .with_indent_amount(2) + .with_indent_lines(lines) .with_thread_ids(verbose_thread_ids) .with_thread_names(verbose_thread_ids); From 3da92891fd3f1eecb6b16d080da6ac3447f5bd9b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 09:49:32 +0000 Subject: [PATCH 08/17] Avoid a bunch of booleans in favor of `Result<(), ErrorGuaranteed>` as that more robustly proves that an error has been emitted --- compiler/rustc_hir_typeck/src/expr.rs | 16 +++---- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 7 ++- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 10 ++-- .../rustc_hir_typeck/src/method/suggest.rs | 46 ++++++++----------- 4 files changed, 35 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 5b27ebe3416ae..d77d898f3bda9 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1341,16 +1341,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); Ok(method) } - Err(error) => { - if segment.ident.name != kw::Empty { - if let Some(err) = - self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) - { - err.emit(); - } + Err(error) => Err(if segment.ident.name == kw::Empty { + self.dcx().span_delayed_bug(rcvr.span, "empty method name") + } else { + match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { + Ok(diag) => diag.emit(), + Err(guar) => guar, } - Err(()) - } + }), }; // Call the generic checker. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e354e1ec59c63..421ed9954e05b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -846,15 +846,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if item_name.name != kw::Empty { - if let Some(e) = self.report_method_error( + self.report_method_error( hir_id, ty.normalized, error, Expectation::NoExpectation, trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 - ) { - e.emit(); - } + )? + .emit(); } result diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b8333d4749378..b8ae21594fd40 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -113,16 +113,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, sp: Span, expr: &'tcx hir::Expr<'tcx>, - method: Result, ()>, + method: Result, ErrorGuaranteed>, args_no_rcvr: &'tcx [hir::Expr<'tcx>], tuple_arguments: TupleArgumentsFlag, expected: Expectation<'tcx>, ) -> Ty<'tcx> { let has_error = match method { - Ok(method) => method.args.references_error() || method.sig.references_error(), - Err(_) => true, + Ok(method) => method.args.error_reported().and(method.sig.error_reported()), + Err(guar) => Err(guar), }; - if has_error { + if let Err(guar) = has_error { let err_inputs = self.err_args(args_no_rcvr.len()); let err_inputs = match tuple_arguments { @@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, method.ok().map(|method| method.def_id), ); - return Ty::new_misc_error(self.tcx); + return Ty::new_error(self.tcx, guar); } let method = method.unwrap(); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 803d155432461..4e2b36f2d9e07 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -33,7 +33,7 @@ use rustc_middle::ty::IsSuggestable; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{edit_distance, ExpnKind, FileName, MacroKind, Span}; +use rustc_span::{edit_distance, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span}; use rustc_span::{Symbol, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote; @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Option> { + ) -> Result, ErrorGuaranteed> { let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), @@ -226,9 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Avoid suggestions when we don't know what's going on. - if rcvr_ty.references_error() { - return None; - } + rcvr_ty.error_reported()?; match error { MethodError::NoMatch(mut no_match_data) => { @@ -265,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut sources, Some(sugg_span), ); - err.emit(); + return Err(err.emit()); } MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { @@ -286,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); - err.emit(); + return Err(err.emit()); } MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => { @@ -343,12 +341,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); + return Err(err.emit()); } MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"), } - None } fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> { @@ -576,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Option> { + ) -> Result, ErrorGuaranteed> { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); @@ -608,14 +605,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - if self.suggest_wrapping_range_with_parens( + self.suggest_wrapping_range_with_parens( tcx, rcvr_ty, source, span, item_name, &short_ty_str, - ) || self.suggest_constraining_numerical_ty( + )?; + self.suggest_constraining_numerical_ty( tcx, rcvr_ty, source, @@ -623,9 +621,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, &short_ty_str, - ) { - return None; - } + )?; span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). @@ -881,7 +877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(span.shrink_to_lo(), format!("into_iter()."))], Applicability::MaybeIncorrect, ); - return Some(err); + return Ok(err); } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in // `::method` because otherwise the machinery will look for blanket @@ -1606,7 +1602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); - Some(err) + Ok(err) } /// If an appropriate error source is not found, check method chain for possible candidates @@ -2259,7 +2255,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, item_name: Ident, ty_str: &str, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { if let SelfSource::MethodCall(expr) = source { for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) { if let Node::Expr(parent_expr) = parent { @@ -2316,7 +2312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - tcx.dcx().emit_err(errors::MissingParenthesesInRange { + return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange { span, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), @@ -2325,13 +2321,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { left: range_span.shrink_to_lo(), right: range_span.shrink_to_hi(), }), - }); - return true; + })); } } } } - false + Ok(()) } fn suggest_constraining_numerical_ty( @@ -2343,7 +2338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind: &str, item_name: Ident, ty_str: &str, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { let found_candidate = all_traits(self.tcx) .into_iter() .any(|info| self.associated_value(info.def_id, item_name).is_some()); @@ -2447,10 +2442,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => {} } - err.emit(); - return true; + return Err(err.emit()); } - false + Ok(()) } /// For code `rect::area(...)`, From be464b800c5875d23549afb744dcd3cf428ed539 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 10:26:12 +0000 Subject: [PATCH 09/17] Upgrade a span_delayed_bug into a span_bug, as we have no tests hitting it. --- compiler/rustc_hir_typeck/src/expr.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d77d898f3bda9..cf2bf0d8f8b9c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1341,14 +1341,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); Ok(method) } - Err(error) => Err(if segment.ident.name == kw::Empty { - self.dcx().span_delayed_bug(rcvr.span, "empty method name") - } else { - match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { - Ok(diag) => diag.emit(), - Err(guar) => guar, + Err(error) => { + if segment.ident.name == kw::Empty { + span_bug!(rcvr.span, "empty method name") + } else { + match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { + Ok(diag) => Err(diag.emit()), + Err(guar) => Err(guar), + } } - }), + } }; // Call the generic checker. From 4a06a5bc7ad259023e4373e794687adfce252dac Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 12 Jun 2024 12:39:09 +0200 Subject: [PATCH 10/17] Adjust LoongArch64 data layouts for LLVM update The data layout was changed in LLVM 19: llvm/llvm-project#93814 --- compiler/rustc_codegen_llvm/src/context.rs | 8 ++++++++ .../src/spec/targets/loongarch64_unknown_linux_gnu.rs | 2 +- .../src/spec/targets/loongarch64_unknown_linux_musl.rs | 2 +- .../src/spec/targets/loongarch64_unknown_none.rs | 2 +- .../spec/targets/loongarch64_unknown_none_softfloat.rs | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 53a098d178e41..7d92888feeed4 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -142,6 +142,14 @@ pub unsafe fn create_module<'ll>( } } + if llvm_version < (19, 0, 0) { + if sess.target.arch == "loongarch64" { + // LLVM 19 updates the LoongArch64 data layout. + // See https://github.com/llvm/llvm-project/pull/93814 + target_data_layout = target_data_layout.replace("-n32:64", "-n64"); + } + } + // Ensure the data-layout values hardcoded remain the defaults. { let tm = crate::back::write::create_informational_target_machine(tcx.sess); 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..3e88180012e5b 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 @@ -10,7 +10,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs index 032a29708d147..c45bc43835002 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs @@ -10,7 +10,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs index b2bfc8e427231..69533e82c3ce6 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs index 02e44c187abe8..bc4c5bcde5ed5 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), From 4d72c42ddf05def4ade2bbe38712ebc8a1f2dcf4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 12:54:32 +0000 Subject: [PATCH 11/17] Eagerly emit the diagnostic instead of leaving it to all callers --- compiler/rustc_hir_typeck/src/expr.rs | 5 +-- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 3 +- .../rustc_hir_typeck/src/method/suggest.rs | 32 +++++++++++-------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index cf2bf0d8f8b9c..3321f029c8d8c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1345,10 +1345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if segment.ident.name == kw::Empty { span_bug!(rcvr.span, "empty method name") } else { - match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { - Ok(diag) => Err(diag.emit()), - Err(guar) => Err(guar), - } + Err(self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)) } } }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 421ed9954e05b..2b32a93bbbec6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -852,8 +852,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, Expectation::NoExpectation, trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 - )? - .emit(); + ); } result diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4e2b36f2d9e07..bffefe3625619 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Result, ErrorGuaranteed> { + ) -> ErrorGuaranteed { let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), @@ -226,7 +226,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Avoid suggestions when we don't know what's going on. - rcvr_ty.error_reported()?; + if let Err(guar) = rcvr_ty.error_reported() { + return guar; + } match error { MethodError::NoMatch(mut no_match_data) => { @@ -263,7 +265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut sources, Some(sugg_span), ); - return Err(err.emit()); + return err.emit(); } MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { @@ -284,7 +286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); - return Err(err.emit()); + return err.emit(); } MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => { @@ -341,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - return Err(err.emit()); + return err.emit(); } MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"), @@ -561,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn report_no_match_method_error( + fn report_no_match_method_error( &self, mut span: Span, rcvr_ty: Ty<'tcx>, @@ -573,7 +575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Result, ErrorGuaranteed> { + ) -> ErrorGuaranteed { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); @@ -605,15 +607,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - self.suggest_wrapping_range_with_parens( + if let Err(guar) = self.suggest_wrapping_range_with_parens( tcx, rcvr_ty, source, span, item_name, &short_ty_str, - )?; - self.suggest_constraining_numerical_ty( + ) { + return guar; + } + if let Err(guar) = self.suggest_constraining_numerical_ty( tcx, rcvr_ty, source, @@ -621,7 +625,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, &short_ty_str, - )?; + ) { + return guar; + } span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). @@ -877,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(span.shrink_to_lo(), format!("into_iter()."))], Applicability::MaybeIncorrect, ); - return Ok(err); + return err.emit(); } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in // `::method` because otherwise the machinery will look for blanket @@ -1602,7 +1608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); - Ok(err) + err.emit() } /// If an appropriate error source is not found, check method chain for possible candidates From 9065889ee639d8dd7c0dd098fee82a867e471be7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 12:56:56 +0000 Subject: [PATCH 12/17] Rename some functions --- compiler/rustc_hir_typeck/src/method/suggest.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index bffefe3625619..28d738c11c8fa 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -607,7 +607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - if let Err(guar) = self.suggest_wrapping_range_with_parens( + if let Err(guar) = self.report_failed_method_call_on_range_end( tcx, rcvr_ty, source, @@ -617,7 +617,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { return guar; } - if let Err(guar) = self.suggest_constraining_numerical_ty( + if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( tcx, rcvr_ty, source, @@ -2253,7 +2253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Suggest possible range with adding parentheses, for example: /// when encountering `0..1.map(|i| i + 1)` suggest `(0..1).map(|i| i + 1)`. - fn suggest_wrapping_range_with_parens( + fn report_failed_method_call_on_range_end( &self, tcx: TyCtxt<'tcx>, actual: Ty<'tcx>, @@ -2335,7 +2335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(()) } - fn suggest_constraining_numerical_ty( + fn report_failed_method_call_on_numerical_infer_var( &self, tcx: TyCtxt<'tcx>, actual: Ty<'tcx>, From 62990713cece662d36a192e2713a30cd7cfb115b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 14:25:34 +0000 Subject: [PATCH 13/17] Avoid a Ty::new_misc_error when an ErrorGuaranteed is available --- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 ++-- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2b32a93bbbec6..94e879ae9c3ed 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -660,8 +660,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - pub(crate) fn err_args(&self, len: usize) -> Vec> { - let ty_error = Ty::new_misc_error(self.tcx); + pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec> { + let ty_error = Ty::new_error(self.tcx, guar); vec![ty_error; len] } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b8ae21594fd40..e20a6ef7c1339 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -123,7 +123,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(guar) => Err(guar), }; if let Err(guar) = has_error { - let err_inputs = self.err_args(args_no_rcvr.len()); + let err_inputs = self.err_args(args_no_rcvr.len(), guar); let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, @@ -237,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // Otherwise, there's a mismatch, so clear out what we're expecting, and set // our input types to err_args so we don't blow up the error messages - struct_span_code_err!( + let guar = struct_span_code_err!( tcx.dcx(), call_span, E0059, @@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for the function trait is neither a tuple nor unit" ) .emit(); - (self.err_args(provided_args.len()), None) + (self.err_args(provided_args.len(), guar), None) } } } else { From af106617f17d7d4bdfe70158265f352b13511382 Mon Sep 17 00:00:00 2001 From: r0cky Date: Wed, 12 Jun 2024 23:31:27 +0800 Subject: [PATCH 14/17] Detect pub structs never constructed even though they impl pub trait with assoc constants --- compiler/rustc_passes/src/dead.rs | 4 +- ...sed-adt-impl-pub-trait-with-assoc-const.rs | 52 +++++++++++++++++++ ...adt-impl-pub-trait-with-assoc-const.stderr | 26 ++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs create mode 100644 tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 2cb3c5d8965c8..a72fbdb902159 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -472,7 +472,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { && let ItemKind::Impl(impl_ref) = self.tcx.hir().expect_item(local_impl_id).kind { - if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) + if !matches!(trait_item.kind, hir::TraitItemKind::Type(..)) && !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty) .ty_and_all_fields_are_public { @@ -802,7 +802,7 @@ fn check_item<'tcx>( // And we access the Map here to get HirId from LocalDefId for local_def_id in local_def_ids { // check the function may construct Self - let mut may_construct_self = true; + let mut may_construct_self = false; if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id)) { diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs new file mode 100644 index 0000000000000..bf2fc243e8194 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs @@ -0,0 +1,52 @@ +#![deny(dead_code)] + +struct T1; //~ ERROR struct `T1` is never constructed +pub struct T2(i32); //~ ERROR struct `T2` is never constructed +struct T3; + +trait Trait1 { //~ ERROR trait `Trait1` is never used + const UNUSED: i32; + fn unused(&self) {} + fn construct_self() -> Self; +} + +pub trait Trait2 { + const USED: i32; + fn used(&self) {} +} + +pub trait Trait3 { + const USED: i32; + fn construct_self() -> Self; +} + +impl Trait1 for T1 { + const UNUSED: i32 = 0; + fn construct_self() -> Self { + Self + } +} + +impl Trait1 for T2 { + const UNUSED: i32 = 0; + fn construct_self() -> Self { + T2(0) + } +} + +impl Trait2 for T1 { + const USED: i32 = 0; +} + +impl Trait2 for T2 { + const USED: i32 = 0; +} + +impl Trait3 for T3 { + const USED: i32 = 0; + fn construct_self() -> Self { + Self + } +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr new file mode 100644 index 0000000000000..174096d939883 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr @@ -0,0 +1,26 @@ +error: struct `T1` is never constructed + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:3:8 + | +LL | struct T1; + | ^^ + | +note: the lint level is defined here + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: struct `T2` is never constructed + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:12 + | +LL | pub struct T2(i32); + | ^^ + +error: trait `Trait1` is never used + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7 + | +LL | trait Trait1 { + | ^^^^^^ + +error: aborting due to 3 previous errors + From 39c3b86eaa756cf3b8a8957abae7fd029196f90d Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 11 Jun 2024 19:34:53 +0200 Subject: [PATCH 15/17] Add a `ignore-tidy-todo` to ignore the tidy TODO comment check --- src/tools/tidy/src/style.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 64cc227762055..2d3888ec75f25 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -444,7 +444,9 @@ pub fn check(path: &Path, bad: &mut bool) { suppressible_tidy_err!(err, skip_cr, "CR character"); } if filename != "style.rs" { - if trimmed.contains("TODO") { + // Allow using TODO in diagnostic suggestions by marking the + // relevant line with `// ignore-tidy-todo`. + if trimmed.contains("TODO") && !trimmed.contains("ignore-tidy-todo") { err( "TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME", ) From 4f5fb3126f24e2dbe401430c2b6961941be181f9 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 5 Jun 2024 11:06:41 +0200 Subject: [PATCH 16/17] Add TODO comment to unsafe env modification Addresses https://github.com/rust-lang/rust/pull/124636#issuecomment-2132119534. I think that the diff display regresses a little, because it's no longer showing the `+` to show where the `unsafe {}` is added. I think it's still fine. --- compiler/rustc_mir_build/src/check_unsafety.rs | 3 +++ compiler/rustc_mir_build/src/errors.rs | 5 +++++ tests/ui/rust-2024/unsafe-env-suggestion.fixed | 2 ++ tests/ui/rust-2024/unsafe-env-suggestion.stderr | 10 ++++++---- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index d781fb1c297d9..a65586ccdb7e7 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -97,6 +97,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { if !span.at_least_rust_2024() && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) => { + let sm = self.tcx.sess.source_map(); self.tcx.emit_node_span_lint( DEPRECATED_SAFE, self.hir_context, @@ -105,6 +106,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { span, function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), sub: CallToDeprecatedSafeFnRequiresUnsafeSub { + indent: sm.indentation_before(span).unwrap_or_default(), + start_of_line: sm.span_extend_to_line(span).shrink_to_lo(), left: span.shrink_to_lo(), right: span.shrink_to_hi(), }, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index cf324c03dc9f2..3bd2e47976b57 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -33,6 +33,11 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { #[derive(Subdiagnostic)] #[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")] pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { + pub(crate) indent: String, + #[suggestion_part( + code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo + )] + pub(crate) start_of_line: Span, #[suggestion_part(code = "unsafe {{ ")] pub(crate) left: Span, #[suggestion_part(code = " }}")] diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.fixed b/tests/ui/rust-2024/unsafe-env-suggestion.fixed index d9c738edfacbd..1f3d2dc0a31e8 100644 --- a/tests/ui/rust-2024/unsafe-env-suggestion.fixed +++ b/tests/ui/rust-2024/unsafe-env-suggestion.fixed @@ -6,9 +6,11 @@ use std::env; #[deny(unused_unsafe)] fn main() { + // TODO: Audit that the environment access only happens in single-threaded code. unsafe { env::set_var("FOO", "BAR") }; //~^ ERROR call to deprecated safe function //~| WARN this is accepted in the current edition + // TODO: Audit that the environment access only happens in single-threaded code. unsafe { env::remove_var("FOO") }; //~^ ERROR call to deprecated safe function //~| WARN this is accepted in the current edition diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.stderr b/tests/ui/rust-2024/unsafe-env-suggestion.stderr index 90c91c2a474a6..7c12f4aa5ede2 100644 --- a/tests/ui/rust-2024/unsafe-env-suggestion.stderr +++ b/tests/ui/rust-2024/unsafe-env-suggestion.stderr @@ -13,8 +13,9 @@ LL | #![deny(deprecated_safe)] | ^^^^^^^^^^^^^^^ help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code | -LL | unsafe { env::set_var("FOO", "BAR") }; - | ++++++++ + +LL + // TODO: Audit that the environment access only happens in single-threaded code. +LL ~ unsafe { env::set_var("FOO", "BAR") }; + | error: call to deprecated safe function `std::env::remove_var` is unsafe and requires unsafe block --> $DIR/unsafe-env-suggestion.rs:12:5 @@ -26,8 +27,9 @@ LL | env::remove_var("FOO"); = note: for more information, see issue #27970 help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code | -LL | unsafe { env::remove_var("FOO") }; - | ++++++++ + +LL + // TODO: Audit that the environment access only happens in single-threaded code. +LL ~ unsafe { env::remove_var("FOO") }; + | error: aborting due to 2 previous errors From 54429cf27928f8aa9039dc019a73a372dcc6306d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 12 Jun 2024 16:19:25 +0000 Subject: [PATCH 17/17] Fix outdated predacates_of.rs comments --- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 40204961e9c49..3421c8da4e9f3 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -169,12 +169,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen predicates.insert((trait_ref.upcast(tcx), tcx.def_span(def_id))); } - // Collect the predicates that were written inline by the user on each - // type parameter (e.g., ``). Also add `ConstArgHasType` predicates - // for each const parameter. + // Add implicit predicates that should be treated as if the user has written them, + // including the implicit `T: Sized` for all generic parameters, and `ConstArgHasType` + // for const params. for param in hir_generics.params { match param.kind { - // We already dealt with early bound lifetimes above. GenericParamKind::Lifetime { .. } => (), GenericParamKind::Type { .. } => { let param_ty = icx.lowerer().lower_ty_param(param.hir_id); @@ -204,7 +203,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } trace!(?predicates); - // Add in the bounds that appear in the where-clause. + // Add inline `` bounds and bounds in the where clause. for predicate in hir_generics.predicates { match predicate { hir::WherePredicate::BoundPredicate(bound_pred) => {