From 9e0d1a328443b07bc50e9d66fd1c0e2a5568a13b Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 19 May 2023 16:03:35 -0400 Subject: [PATCH 01/50] Print a backtrace in const eval if interrupted --- Cargo.lock | 1 + compiler/rustc_const_eval/messages.ftl | 2 ++ .../src/const_eval/eval_queries.rs | 9 ++++++++- compiler/rustc_const_eval/src/errors.rs | 1 + compiler/rustc_const_eval/src/lib.rs | 7 +++++++ compiler/rustc_driver_impl/Cargo.toml | 1 + compiler/rustc_driver_impl/src/lib.rs | 19 +++++++++++++++++++ .../rustc_middle/src/mir/interpret/error.rs | 2 ++ src/tools/miri/src/bin/miri.rs | 4 ++++ src/tools/miri/src/concurrency/thread.rs | 19 ++++--------------- src/tools/tidy/src/deps.rs | 3 +++ tests/run-make/jobserver-error/Makefile | 4 +++- .../jobserver-error/cannot_open_fd.stderr | 2 +- 13 files changed, 56 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3110f32ade968..3c1e9634c57c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3771,6 +3771,7 @@ dependencies = [ name = "rustc_driver_impl" version = "0.0.0" dependencies = [ + "ctrlc", "libc", "rustc_ast", "rustc_ast_lowering", diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 0046190d20cc7..d6aae60c3382a 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -146,6 +146,8 @@ const_eval_intern_kind = {$kind -> *[other] {""} } +const_eval_interrupted = compilation was interrupted + const_eval_invalid_align_details = invalid align passed to `{$name}`: {$align} is {$err_kind -> [not_power_of_two] not a power of 2 diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 5a1c7cc4209ad..098a6201c4ea3 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -1,3 +1,5 @@ +use std::sync::atomic::Ordering::Relaxed; + use either::{Left, Right}; use rustc_hir::def::DefKind; @@ -22,6 +24,7 @@ use crate::interpret::{ InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, }; +use crate::CTRL_C_RECEIVED; // Returns a pointer to where the result lives #[instrument(level = "trace", skip(ecx, body))] @@ -79,7 +82,11 @@ fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( ecx.storage_live_for_always_live_locals()?; // The main interpreter loop. - while ecx.step()? {} + while ecx.step()? { + if CTRL_C_RECEIVED.load(Relaxed) { + throw_exhaust!(Interrupted); + } + } // Intern the result intern_const_alloc_recursive(ecx, intern_kind, &ret)?; diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index cc32640408b7e..5c46ec799f1ec 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -884,6 +884,7 @@ impl ReportErrorExt for ResourceExhaustionInfo { ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached, ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted, ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full, + ResourceExhaustionInfo::Interrupted => const_eval_interrupted, } } fn add_args(self, _: &mut Diag<'_, G>) {} diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 1e7ee208af1ab..7928f139aa06b 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -32,6 +32,8 @@ pub mod interpret; pub mod transform; pub mod util; +use std::sync::atomic::AtomicBool; + pub use errors::ReportErrorExt; use rustc_middle::{ty, util::Providers}; @@ -57,3 +59,8 @@ pub fn provide(providers: &mut Providers) { util::check_validity_requirement(tcx, init_kind, param_env_and_ty) }; } + +/// `rustc_driver::main` installs a handler that will set this to `true` if +/// the compiler has been sent a request to shut down, such as by a Ctrl-C. +/// This static lives here because it is only read by the interpreter. +pub static CTRL_C_RECEIVED: AtomicBool = AtomicBool::new(false); diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index fcc0afd3488b0..e4fb13822f81e 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +ctrlc = "3.4.4" rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 938f9f0beaacd..1a0ae9eb21129 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -19,6 +19,7 @@ extern crate tracing; use rustc_ast as ast; use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; +use rustc_const_eval::CTRL_C_RECEIVED; use rustc_data_structures::profiling::{ get_resident_set_size, print_time_passes_entry, TimePassesFormat, }; @@ -1518,6 +1519,22 @@ pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) { } } +/// Install our usual `ctrlc` handler, which sets [`rustc_const_eval::CTRL_C_RECEIVED`]. +/// Making this handler optional lets tools can install a different handler, if they wish. +pub fn install_ctrlc_handler() { + ctrlc::set_handler(move || { + // Indicate that we have been signaled to stop. If we were already signaled, exit + // immediately. In our interpreter loop we try to consult this value often, but if for + // whatever reason we don't get to that check or the cleanup we do upon finding that + // this bool has become true takes a long time, the exit here will promptly exit the + // process on the second Ctrl-C. + if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) { + std::process::exit(1); + } + }) + .expect("Unable to install ctrlc handler"); +} + pub fn main() -> ! { let start_time = Instant::now(); let start_rss = get_resident_set_size(); @@ -1528,6 +1545,8 @@ pub fn main() -> ! { signal_handler::install(); let mut callbacks = TimePassesCallbacks::default(); let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ()); + install_ctrlc_handler(); + let exit_code = catch_with_exit_code(|| { RunCompiler::new(&args::raw_args(&early_dcx)?, &mut callbacks) .set_using_internal_features(using_internal_features) diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 751d6de83f92c..c86970635a55f 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -482,6 +482,8 @@ pub enum ResourceExhaustionInfo { MemoryExhausted, /// The address space (of the target) is full. AddressSpaceFull, + /// The compiler got an interrupt signal (a user ran out of patience). + Interrupted, } /// A trait for machine-specific errors (or other "machine stop" conditions). diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 6955e649b4d17..5ad4c7d2d1c4b 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -344,6 +344,10 @@ fn main() { let args = rustc_driver::args::raw_args(&early_dcx) .unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE)); + // Install the ctrlc handler that sets `rustc_const_eval::CTRL_C_RECEIVED`, even if + // MIRI_BE_RUSTC is set. + rustc_driver::install_ctrlc_handler(); + // If the environment asks us to actually be rustc, then do that. if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") { // Earliest rustc setup. diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 805c0580b2f15..e2e18d3a7344f 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -3,12 +3,13 @@ use std::cell::RefCell; use std::collections::hash_map::Entry; use std::num::TryFromIntError; -use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; +use std::sync::atomic::Ordering::Relaxed; use std::task::Poll; use std::time::{Duration, SystemTime}; use either::Either; +use rustc_const_eval::CTRL_C_RECEIVED; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_index::{Idx, IndexVec}; @@ -1045,21 +1046,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program /// termination). fn run_threads(&mut self) -> InterpResult<'tcx, !> { - static SIGNALED: AtomicBool = AtomicBool::new(false); - ctrlc::set_handler(move || { - // Indicate that we have ben signaled to stop. If we were already signaled, exit - // immediately. In our interpreter loop we try to consult this value often, but if for - // whatever reason we don't get to that check or the cleanup we do upon finding that - // this bool has become true takes a long time, the exit here will promptly exit the - // process on the second Ctrl-C. - if SIGNALED.swap(true, Relaxed) { - std::process::exit(1); - } - }) - .unwrap(); - let this = self.eval_context_mut(); + let this = self.eval_context_mut(); loop { - if SIGNALED.load(Relaxed) { + if CTRL_C_RECEIVED.load(Relaxed) { this.machine.handle_abnormal_termination(); std::process::exit(1); } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 10fdfc0a65f75..b74afa0d3e86e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -208,6 +208,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "byteorder", // via ruzstd in object in thorin-dwp "cc", "cfg-if", + "cfg_aliases", "compiler_builtins", "cpufeatures", "crc32fast", @@ -216,6 +217,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "crossbeam-epoch", "crossbeam-utils", "crypto-common", + "ctrlc", "darling", "darling_core", "darling_macro", @@ -281,6 +283,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "memmap2", "memoffset", "miniz_oxide", + "nix", "nu-ansi-term", "num-conv", "num_cpus", diff --git a/tests/run-make/jobserver-error/Makefile b/tests/run-make/jobserver-error/Makefile index a7601b8671563..9f34970f96f10 100644 --- a/tests/run-make/jobserver-error/Makefile +++ b/tests/run-make/jobserver-error/Makefile @@ -4,9 +4,11 @@ include ../tools.mk # ignore-cross-compile # Test compiler behavior in case environment specifies wrong jobserver. +# Note that by default, the compiler uses file descriptors 0 (stdin), 1 (stdout), 2 (stderr), +# but also 3 and 4 for either end of the ctrl-c signal handler self-pipe. all: - bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=3,3" $(RUSTC)' 2>&1 | diff cannot_open_fd.stderr - + bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=5,5" $(RUSTC)' 2>&1 | diff cannot_open_fd.stderr - bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=3,3" $(RUSTC) - 3&1 | diff not_a_pipe.stderr - # This test randomly fails, see https://github.com/rust-lang/rust/issues/110321 diff --git a/tests/run-make/jobserver-error/cannot_open_fd.stderr b/tests/run-make/jobserver-error/cannot_open_fd.stderr index 343de5cd52c3b..7c42184653594 100644 --- a/tests/run-make/jobserver-error/cannot_open_fd.stderr +++ b/tests/run-make/jobserver-error/cannot_open_fd.stderr @@ -1,4 +1,4 @@ -warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=3,3"`: cannot open file descriptor 3 from the jobserver environment variable value: Bad file descriptor (os error 9) +warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=5,5"`: cannot open file descriptor 5 from the jobserver environment variable value: Bad file descriptor (os error 9) | = note: the build environment is likely misconfigured From 7b3ef1314661b37e14b1b042ad152892e9e6ff18 Mon Sep 17 00:00:00 2001 From: Reed Date: Mon, 18 Mar 2024 11:39:00 -0700 Subject: [PATCH 02/50] Fix a typo in the alloc::string::String docs --- library/alloc/src/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index c4dcff1b1c49c..f5c1245a7624a 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -261,7 +261,7 @@ use crate::vec::Vec; /// /// A `String` is made up of three components: a pointer to some bytes, a /// length, and a capacity. The pointer points to an internal buffer `String` -/// uses to store its data. The length is the number of bytes currently stored +/// used to store its data. The length is the number of bytes currently stored /// in the buffer, and the capacity is the size of the buffer in bytes. As such, /// the length will always be less than or equal to the capacity. /// From d1ba632f4f65051a6230db59e2ed2e1b1e8f12fc Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Fri, 22 Mar 2024 16:27:26 +0300 Subject: [PATCH 03/50] Delegation: fix ICE on `bound_vars` divergence --- .../src/collect/resolve_bound_vars.rs | 10 +++++- .../src/hir_ty_lowering/mod.rs | 8 +---- tests/ui/delegation/ice-issue-122550.rs | 18 +++++++++++ tests/ui/delegation/ice-issue-122550.stderr | 31 +++++++++++++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 tests/ui/delegation/ice-issue-122550.rs create mode 100644 tests/ui/delegation/ice-issue-122550.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 27a26cfe4747f..ee3436805ca7f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -793,12 +793,20 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { fd: &'tcx hir::FnDecl<'tcx>, body_id: hir::BodyId, _: Span, - _: LocalDefId, + def_id: LocalDefId, ) { let output = match fd.output { hir::FnRetTy::DefaultReturn(_) => None, hir::FnRetTy::Return(ty) => Some(ty), }; + if let Some(ty) = output + && let hir::TyKind::InferDelegation(sig_id, _) = ty.kind + { + let bound_vars: Vec<_> = + self.tcx.fn_sig(sig_id).skip_binder().bound_vars().iter().collect(); + let hir_id = self.tcx.local_def_id_to_hir_id(def_id); + self.map.late_bound_vars.insert(hir_id, bound_vars); + } self.visit_fn_like_elision(fd.inputs, output, matches!(fk, intravisit::FnKind::Closure)); intravisit::walk_fn_kind(self, fk); self.visit_nested_body(body_id) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 109e00d4f24e5..b115b4bc9a68b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2494,13 +2494,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_ty: Option<&hir::Ty<'_>>, ) -> ty::PolyFnSig<'tcx> { let tcx = self.tcx(); - let bound_vars = if let hir::FnRetTy::Return(ret_ty) = decl.output - && let hir::TyKind::InferDelegation(sig_id, _) = ret_ty.kind - { - tcx.fn_sig(sig_id).skip_binder().bound_vars() - } else { - tcx.late_bound_vars(hir_id) - }; + let bound_vars = tcx.late_bound_vars(hir_id); debug!(?bound_vars); // We proactively collect all the inferred type params to emit a single error per fn def. diff --git a/tests/ui/delegation/ice-issue-122550.rs b/tests/ui/delegation/ice-issue-122550.rs new file mode 100644 index 0000000000000..92c0dda960543 --- /dev/null +++ b/tests/ui/delegation/ice-issue-122550.rs @@ -0,0 +1,18 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn description(&self) -> &str {} + //~^ ERROR mismatched types +} + +struct F; +struct S(F); + +impl S { + reuse ::description { &self.0 } + //~^ ERROR mismatched types + //~| ERROR the trait bound `S: Trait` is not satisfied +} + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-122550.stderr b/tests/ui/delegation/ice-issue-122550.stderr new file mode 100644 index 0000000000000..c92170644e78f --- /dev/null +++ b/tests/ui/delegation/ice-issue-122550.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/ice-issue-122550.rs:5:35 + | +LL | fn description(&self) -> &str {} + | ^^ expected `&str`, found `()` + +error[E0308]: mismatched types + --> $DIR/ice-issue-122550.rs:13:39 + | +LL | reuse ::description { &self.0 } + | ^^^^^^^ expected `&S`, found `&F` + | + = note: expected reference `&S` + found reference `&F` + +error[E0277]: the trait bound `S: Trait` is not satisfied + --> $DIR/ice-issue-122550.rs:13:12 + | +LL | reuse ::description { &self.0 } + | ^ the trait `Trait` is not implemented for `S` + | +help: this trait has no implementations, consider adding one + --> $DIR/ice-issue-122550.rs:4:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From bf12aa49e71d6e444c34d7adb87647f36b7dde1a Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Thu, 21 Mar 2024 16:13:46 -0400 Subject: [PATCH 04/50] Don't emit an error about failing to produce a file with a specific name If user never gave an explicit name --- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_session/src/config.rs | 5 ++++ .../issues/no-explicit-path-issue-122509.rs | 23 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/ui/issues/no-explicit-path-issue-122509.rs diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 4eda4c2f08c69..b7bcaac3b18f6 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -592,7 +592,7 @@ fn produce_final_output_artifacts( .unwrap() .to_owned(); - if crate_output.outputs.contains_key(&output_type) { + if crate_output.outputs.contains_explicit_name(&output_type) { // 2) Multiple codegen units, with `--emit foo=some_name`. We have // no good solution for this case, so warn the user. sess.dcx().emit_warn(errors::IgnoringEmitPath { extension }); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index e6eb1a3e83c6c..e4d2af95c572a 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -557,6 +557,11 @@ impl OutputTypes { self.0.contains_key(key) } + /// Returns `true` if user specified a name and not just produced type + pub fn contains_explicit_name(&self, key: &OutputType) -> bool { + self.0.get(key).map_or(false, |f| f.is_some()) + } + pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option> { self.0.iter() } diff --git a/tests/ui/issues/no-explicit-path-issue-122509.rs b/tests/ui/issues/no-explicit-path-issue-122509.rs new file mode 100644 index 0000000000000..4e8eefde5dad1 --- /dev/null +++ b/tests/ui/issues/no-explicit-path-issue-122509.rs @@ -0,0 +1,23 @@ +//@ build-pass +//@ compile-flags: -C codegen-units=2 --emit asm + +fn one() -> usize { + 1 +} + +pub mod a { + pub fn two() -> usize { + ::one() + ::one() + } +} + +pub mod b { + pub fn three() -> usize { + ::one() + ::a::two() + } +} + +fn main() { + a::two(); + b::three(); +} From b84326ec9caca0c8877bc58a85a8c7814ca6c052 Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Fri, 22 Mar 2024 11:20:55 -0400 Subject: [PATCH 05/50] tests/ui: Add a directory for warnings, add a test --- src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/{issues => warnings}/no-explicit-path-issue-122509.rs | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/{issues => warnings}/no-explicit-path-issue-122509.rs (100%) diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 22927cffd1b9b..015d0518a405a 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -18,7 +18,7 @@ const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1750; -const ROOT_ENTRY_LIMIT: usize = 859; +const ROOT_ENTRY_LIMIT: usize = 860; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/issues/no-explicit-path-issue-122509.rs b/tests/ui/warnings/no-explicit-path-issue-122509.rs similarity index 100% rename from tests/ui/issues/no-explicit-path-issue-122509.rs rename to tests/ui/warnings/no-explicit-path-issue-122509.rs From 25d06013db110db4ef4af46e9fded81b8adc03d6 Mon Sep 17 00:00:00 2001 From: Bernardo Meurer Costa Date: Fri, 22 Mar 2024 17:30:41 +0000 Subject: [PATCH 06/50] 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 07/50] 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 08235b1603f77f39468e7b2e552945501c0cc048 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 22 Mar 2024 16:56:13 -0400 Subject: [PATCH 08/50] Validate that we're only matching on unit struct for path pattern --- compiler/rustc_hir_typeck/src/pat.rs | 21 ++++++++++- ...70549-resolve-after-recovered-self-ctor.rs | 4 +- ...9-resolve-after-recovered-self-ctor.stderr | 9 +++-- .../no-match-tuple-variant-self-ctor.rs | 37 +++++++++++++++++++ ...tch-tuple-variant-self-ctor.struct_.stderr | 19 ++++++++++ ...match-tuple-variant-self-ctor.tuple.stderr | 9 +++++ 6 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 tests/ui/pattern/no-match-tuple-variant-self-ctor.rs create mode 100644 tests/ui/pattern/no-match-tuple-variant-self-ctor.struct_.stderr create mode 100644 tests/ui/pattern/no-match-tuple-variant-self-ctor.tuple.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index dad43cb8abe97..8cb3b4b8e47d1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -919,8 +919,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, E0533, expected); return Ty::new_error(tcx, e); } - Res::SelfCtor(..) - | Res::Def( + Res::SelfCtor(def_id) => { + if let ty::Adt(adt_def, _) = *tcx.type_of(def_id).skip_binder().kind() + && adt_def.is_struct() + && let Some((CtorKind::Const, _)) = adt_def.non_enum_variant().ctor + { + // Ok, we allow unit struct ctors in patterns only. + } else { + let e = report_unexpected_variant_res( + tcx, + res, + qpath, + pat.span, + E0533, + "unit struct", + ); + return Ty::new_error(tcx, e); + } + } + Res::Def( DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst diff --git a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs index aeccd0d9f76ca..ada10fcda27d9 100644 --- a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs +++ b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.rs @@ -4,12 +4,12 @@ impl S { fn foo(&mur Self) {} //~^ ERROR expected identifier, found keyword `Self` //~| ERROR expected one of `:`, `@` - //~| ERROR the `Self` constructor can only be used with + //~| ERROR expected unit struct, found self constructor `Self` fn bar(&'static mur Self) {} //~^ ERROR unexpected lifetime //~| ERROR expected identifier, found keyword `Self` //~| ERROR expected one of `:`, `@` - //~| ERROR the `Self` constructor can only be used with + //~| ERROR expected unit struct, found self constructor `Self` fn baz(&mur Self @ _) {} //~^ ERROR expected one of `:`, `@` diff --git a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr index 421f145403623..ec0af9a6caf1e 100644 --- a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr +++ b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr @@ -40,17 +40,18 @@ error: expected one of `:`, `@`, or `|`, found keyword `Self` LL | fn baz(&mur Self @ _) {} | ^^^^ expected one of `:`, `@`, or `|` -error: the `Self` constructor can only be used with tuple or unit structs +error[E0533]: expected unit struct, found self constructor `Self` --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17 | LL | fn foo(&mur Self) {} - | ^^^^ help: use curly brackets: `Self { /* fields */ }` + | ^^^^ not a unit struct -error: the `Self` constructor can only be used with tuple or unit structs +error[E0533]: expected unit struct, found self constructor `Self` --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25 | LL | fn bar(&'static mur Self) {} - | ^^^^ help: use curly brackets: `Self { /* fields */ }` + | ^^^^ not a unit struct error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0533`. diff --git a/tests/ui/pattern/no-match-tuple-variant-self-ctor.rs b/tests/ui/pattern/no-match-tuple-variant-self-ctor.rs new file mode 100644 index 0000000000000..7c2821e77ab94 --- /dev/null +++ b/tests/ui/pattern/no-match-tuple-variant-self-ctor.rs @@ -0,0 +1,37 @@ +//@ revisions: tuple unit struct_ +//@[unit] check-pass + +#[cfg(unit)] +mod unit { + struct S; + impl S { + fn foo() { + let Self = S; + } + } +} + +#[cfg(tuple)] +mod tuple { + struct S(()); + impl S { + fn foo() { + let Self = S; + //[tuple]~^ ERROR expected unit struct + } + } +} + +#[cfg(struct_)] +mod struct_ { + struct S {} + impl S { + fn foo() { + let Self = S; + //[struct_]~^ ERROR expected value, found struct `S` + //[struct_]~| ERROR expected unit struct, found self constructor `Self` + } + } +} + +fn main() {} diff --git a/tests/ui/pattern/no-match-tuple-variant-self-ctor.struct_.stderr b/tests/ui/pattern/no-match-tuple-variant-self-ctor.struct_.stderr new file mode 100644 index 0000000000000..5ed3979feb807 --- /dev/null +++ b/tests/ui/pattern/no-match-tuple-variant-self-ctor.struct_.stderr @@ -0,0 +1,19 @@ +error[E0423]: expected value, found struct `S` + --> $DIR/no-match-tuple-variant-self-ctor.rs:30:24 + | +LL | struct S {} + | ----------- `S` defined here +... +LL | let Self = S; + | ^ help: use struct literal syntax instead: `S {}` + +error[E0533]: expected unit struct, found self constructor `Self` + --> $DIR/no-match-tuple-variant-self-ctor.rs:30:17 + | +LL | let Self = S; + | ^^^^ not a unit struct + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0533. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/pattern/no-match-tuple-variant-self-ctor.tuple.stderr b/tests/ui/pattern/no-match-tuple-variant-self-ctor.tuple.stderr new file mode 100644 index 0000000000000..d31a4a7918990 --- /dev/null +++ b/tests/ui/pattern/no-match-tuple-variant-self-ctor.tuple.stderr @@ -0,0 +1,9 @@ +error[E0533]: expected unit struct, found self constructor `Self` + --> $DIR/no-match-tuple-variant-self-ctor.rs:19:17 + | +LL | let Self = S; + | ^^^^ not a unit struct + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0533`. From c31b2178e0c4266550375dc1641ba60dfbcf58e1 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sun, 24 Mar 2024 00:32:04 +0900 Subject: [PATCH 09/50] Add regression tests for #101903 --- ...function-return-type-issue-101903-fixed.rs | 26 +++++++++++++++++ ...it-in-function-return-type-issue-101903.rs | 29 +++++++++++++++++++ ...n-function-return-type-issue-101903.stderr | 13 +++++++++ 3 files changed, 68 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs create mode 100644 tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs create mode 100644 tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs new file mode 100644 index 0000000000000..109a70c766d42 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903-fixed.rs @@ -0,0 +1,26 @@ +//@ check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +trait Duh {} + +impl Duh for i32 {} + +trait Trait { + type Assoc: Duh; +} + +impl R> Trait for F { + type Assoc = R; +} + +type Sendable = impl Send + Duh; + +type Foo = impl Trait; + +fn foo() -> Foo { + || 42 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs new file mode 100644 index 0000000000000..4f9d54737dc4c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs @@ -0,0 +1,29 @@ +//@ check-pass + +// See https://doc.rust-lang.org/1.77.0/nightly-rustc/rustc_lint/opaque_hidden_inferred_bound/static.OPAQUE_HIDDEN_INFERRED_BOUND.html#example + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +trait Duh {} + +impl Duh for i32 {} + +trait Trait { + type Assoc: Duh; +} + +impl R> Trait for F { + type Assoc = R; +} + +type Sendable = impl Send; + +type Foo = impl Trait; + //~^ WARNING opaque type `Foo` does not satisfy its associated type bounds + +fn foo() -> Foo { + || 42 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr new file mode 100644 index 0000000000000..68def454c7fbd --- /dev/null +++ b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr @@ -0,0 +1,13 @@ +warning: opaque type `Foo` does not satisfy its associated type bounds + --> $DIR/tait-in-function-return-type-issue-101903.rs:22:23 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `Sendable` +... +LL | type Foo = impl Trait; + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default + +warning: 1 warning emitted + From 87808e71be434dd5ba4fc23115ee84d9a3aaa094 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 23 Mar 2024 17:30:12 -0700 Subject: [PATCH 10/50] 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 127c36c79490326ceeb14675425af672c589256d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:01:50 +0100 Subject: [PATCH 11/50] add test for https://github.com/rust-lang/rust/issues/119731 Fixes #119731 --- .../unevaluated-const-ice-119731.rs | 39 ++++++++ .../unevaluated-const-ice-119731.stderr | 92 +++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs new file mode 100644 index 0000000000000..51cae20df84d4 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs @@ -0,0 +1,39 @@ +// rust-lang/rust#119731 +// ICE ... unevaluated constant UnevaluatedConst + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +mod v20 { + const v4: usize = 512; + pub type v11 = [[usize; v4]; v4]; + //~^ WARN type `v11` should have an upper camel case name + const v2: v11 = [[256; v4]; v4]; + + const v0: [[usize; v4]; v4] = v6(v8); + //~^ ERROR cannot find value `v8` in this scope + //~| ERROR cannot find function `v6` in this scope + pub struct v17 { + //~^ WARN type `v17` should have an upper camel case name + //~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter + _p: (), + } + + impl v17<512, v0> { + pub const fn v21() -> v18 {} + //~^ ERROR cannot find type `v18` in this scope + } + + impl v17 { + //~^ ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} + //~| ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} + pub const fn v21() -> v18 { + //~^ ERROR cannot find type `v18` in this scope + v18 { _p: () } + //~^ ERROR cannot find struct, variant or union type `v18` in this scope + } + } +} +pub use v20::{v13, v17}; +//~^ ERROR unresolved import `v20::v13` +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr new file mode 100644 index 0000000000000..39f022fbee9db --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -0,0 +1,92 @@ +error[E0432]: unresolved import `v20::v13` + --> $DIR/unevaluated-const-ice-119731.rs:37:15 + | +LL | pub use v20::{v13, v17}; + | ^^^ + | | + | no `v13` in `v20` + | help: a similar name exists in the module: `v11` + +error[E0425]: cannot find value `v8` in this scope + --> $DIR/unevaluated-const-ice-119731.rs:13:38 + | +LL | const v0: [[usize; v4]; v4] = v6(v8); + | ^^ not found in this scope + +error[E0412]: cannot find type `v18` in this scope + --> $DIR/unevaluated-const-ice-119731.rs:23:31 + | +LL | pub type v11 = [[usize; v4]; v4]; + | --------------------------------- similarly named type alias `v11` defined here +... +LL | pub const fn v21() -> v18 {} + | ^^^ help: a type alias with a similar name exists: `v11` + +error[E0412]: cannot find type `v18` in this scope + --> $DIR/unevaluated-const-ice-119731.rs:30:31 + | +LL | pub type v11 = [[usize; v4]; v4]; + | --------------------------------- similarly named type alias `v11` defined here +... +LL | pub const fn v21() -> v18 { + | ^^^ help: a type alias with a similar name exists: `v11` + +error[E0422]: cannot find struct, variant or union type `v18` in this scope + --> $DIR/unevaluated-const-ice-119731.rs:32:13 + | +LL | pub type v11 = [[usize; v4]; v4]; + | --------------------------------- similarly named type alias `v11` defined here +... +LL | v18 { _p: () } + | ^^^ help: a type alias with a similar name exists: `v11` + +warning: type `v11` should have an upper camel case name + --> $DIR/unevaluated-const-ice-119731.rs:9:14 + | +LL | pub type v11 = [[usize; v4]; v4]; + | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V11` + | + = note: `#[warn(non_camel_case_types)]` on by default + +warning: type `v17` should have an upper camel case name + --> $DIR/unevaluated-const-ice-119731.rs:16:16 + | +LL | pub struct v17 { + | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V17` + +error[E0425]: cannot find function `v6` in this scope + --> $DIR/unevaluated-const-ice-119731.rs:13:35 + | +LL | const v0: [[usize; v4]; v4] = v6(v8); + | ^^ not found in this scope + +error: `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter + --> $DIR/unevaluated-const-ice-119731.rs:16:48 + | +LL | pub struct v17 { + | ^^^ + | + = note: the only supported types are integers, `bool` and `char` +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + | +LL + #![feature(adt_const_params)] + | + +error: maximum number of nodes exceeded in constant v20::v17::::{constant#1} + --> $DIR/unevaluated-const-ice-119731.rs:27:37 + | +LL | impl v17 { + | ^^ + +error: maximum number of nodes exceeded in constant v20::v17::::{constant#1} + --> $DIR/unevaluated-const-ice-119731.rs:27:37 + | +LL | impl v17 { + | ^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 9 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0412, E0422, E0425, E0432. +For more information about an error, try `rustc --explain E0412`. From db68dc27f4c7a18be8e01864eb5f95f8879858e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:05:27 +0100 Subject: [PATCH 12/50] add test for #116599 Fixes #116599 --- .../unexpected-inference-var-ice-116599.rs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/ui/nll/unexpected-inference-var-ice-116599.rs diff --git a/tests/ui/nll/unexpected-inference-var-ice-116599.rs b/tests/ui/nll/unexpected-inference-var-ice-116599.rs new file mode 100644 index 0000000000000..53eeba23224de --- /dev/null +++ b/tests/ui/nll/unexpected-inference-var-ice-116599.rs @@ -0,0 +1,44 @@ +// ICE unexpected inference var +// issue: rust-lang/rust#116599 +//@ check-pass + +pub trait EvaluateConstMethods { + type Trait: TraitWithConstMethods; + + /// **This block breaks** + const DATA_3: Data3 = { + <<::Method2 as ConstFn<_, _>>::Body< + <::Method1 as ConstFn<_, _>>::Body, + > as Contains<_>>::ITEM + }; +} + +pub trait TraitWithConstMethods { + /// "const trait method" of signature `fn(Data1) -> Data2` + type Method1: ConstFn; + + /// "const trait method" of signature `fn(Data2) -> Data3` + type Method2: ConstFn; +} + +/// A trait which tries to implement const methods in traits +pub trait ConstFn { + type Body>: Contains; +} + +/// A ZST which represents / "contains" a const value which can be pass to a [`ConstFn`] +pub trait Contains { + const ITEM: T; +} + +pub struct ContainsData1; +impl Contains for ContainsData1 { + const ITEM: Data1 = Data1 {}; +} + +// Arbitrary data +pub struct Data1 {} +pub struct Data2 {} +pub struct Data3 {} + +pub fn main() {} From 8ed5e6744fcd7dbda2a3fe0f061b39b4c440bb73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:09:56 +0100 Subject: [PATCH 13/50] add test for #114464 Fixes #114464 --- .../convert-refree-region-vid-ice-114464.rs | 17 +++++++++++++++++ .../convert-refree-region-vid-ice-114464.stderr | 11 +++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.rs b/tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.rs new file mode 100644 index 0000000000000..f58fd12e4d356 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.rs @@ -0,0 +1,17 @@ +// ICE cannot convert Refree.. to a region vid +// issue: rust-lang/rust#114464 + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn test() {} + +fn wow<'a>() { + test::<{ + let _: &'a (); + //~^ ERROR cannot capture late-bound lifetime in constant + 3 + }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.stderr b/tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.stderr new file mode 100644 index 0000000000000..a234c5e129d2e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/convert-refree-region-vid-ice-114464.stderr @@ -0,0 +1,11 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/convert-refree-region-vid-ice-114464.rs:11:17 + | +LL | fn wow<'a>() { + | -- lifetime defined here +LL | test::<{ +LL | let _: &'a (); + | ^^ + +error: aborting due to 1 previous error + From cdea6d83824c9d8d03dc3d0e9869d1b06617e2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:16:29 +0100 Subject: [PATCH 14/50] add test for ICE: no entry found for key for const function in generic_const_exprs #113133 Fixes #113133 --- .../no-entry-found-for-key-ice-gce-nlb-113133.rs | 13 +++++++++++++ ...no-entry-found-for-key-ice-gce-nlb-113133.stderr | 8 ++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs new file mode 100644 index 0000000000000..5673f1dd0738f --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.rs @@ -0,0 +1,13 @@ +// ICE no entry found for key generics_of +// issue: rust-lang/rust#113133 + +#![allow(incomplete_features)] +#![feature(generic_const_exprs, non_lifetime_binders)] + +pub fn foo() +where + for ():, + //~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders +{} + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr new file mode 100644 index 0000000000000..5924a673da944 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/no-entry-found-for-key-ice-gce-nlb-113133.stderr @@ -0,0 +1,8 @@ +error: defaults for generic parameters are not allowed in `for<...>` binders + --> $DIR/no-entry-found-for-key-ice-gce-nlb-113133.rs:9:9 + | +LL | for ():, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From b151e066591728798cb9718628d1e694eda99b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:19:25 +0100 Subject: [PATCH 15/50] add test for ICE: min_specialization: Ok(['?0, Const { ty: usize, kind: Leaf(0x0000000000000000) }]) is not fully resolved #113045 Fixes https://github.com/rust-lang/rust/issues/113045 --- .../ice-const-not-fully-resolved-113045.rs | 15 +++++++++++++ ...ice-const-not-fully-resolved-113045.stderr | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.rs create mode 100644 tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr diff --git a/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.rs b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.rs new file mode 100644 index 0000000000000..6f0f233b87021 --- /dev/null +++ b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.rs @@ -0,0 +1,15 @@ +// ICE min_specialization: +// Ok(['?0, Const { ty: usize, kind: Leaf(0x0000000000000000) }]) is not fully resolved +// issue: rust-lang/rust#113045 + +#![feature(min_specialization)] + +trait X {} + +impl<'a, const N: usize> X for [(); N] {} + +impl<'a, Unconstrained> X for [(); 0] {} +//~^ ERROR the type parameter `Unconstrained` is not constrained by the impl trait, self type, or predicates +//~| ERROR specialization impl does not specialize any associated items + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr new file mode 100644 index 0000000000000..acbdb9b0a308e --- /dev/null +++ b/tests/ui/specialization/min_specialization/ice-const-not-fully-resolved-113045.stderr @@ -0,0 +1,21 @@ +error[E0207]: the type parameter `Unconstrained` is not constrained by the impl trait, self type, or predicates + --> $DIR/ice-const-not-fully-resolved-113045.rs:11:10 + | +LL | impl<'a, Unconstrained> X for [(); 0] {} + | ^^^^^^^^^^^^^ unconstrained type parameter + +error: specialization impl does not specialize any associated items + --> $DIR/ice-const-not-fully-resolved-113045.rs:11:1 + | +LL | impl<'a, Unconstrained> X for [(); 0] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl is a specialization of this impl + --> $DIR/ice-const-not-fully-resolved-113045.rs:9:1 + | +LL | impl<'a, const N: usize> X for [(); N] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. From 6203ebe2747acb76a0bcf36b6e2429009a381cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:28:25 +0100 Subject: [PATCH 16/50] add test for ICE with associated_const_equality #108220 Fixes #108220 --- .../assoc-const-AnonConst-ice-108220.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/ui/generic-const-items/assoc-const-AnonConst-ice-108220.rs diff --git a/tests/ui/generic-const-items/assoc-const-AnonConst-ice-108220.rs b/tests/ui/generic-const-items/assoc-const-AnonConst-ice-108220.rs new file mode 100644 index 0000000000000..f5babb67b5639 --- /dev/null +++ b/tests/ui/generic-const-items/assoc-const-AnonConst-ice-108220.rs @@ -0,0 +1,35 @@ +// ICE assertion failed: matches!(self.def_kind(ct.def.did), DefKind :: AnonConst) +// issue: rust-lang/rust#108220 +//@ check-pass + +#![feature(associated_const_equality)] +#![allow(unused)] + +use std::marker::PhantomData; + +pub struct NoPin; + +pub trait SetAlternate {} + +impl SetAlternate<0> for NoPin {} + +pub trait PinA { + const A: u8; +} + +impl PinA for NoPin { + const A: u8 = 0; +} + +pub trait Pins {} + +impl Pins for T where + T: PinA + SetAlternate +{ +} + +struct Serial(PhantomData); + +impl Serial where NoPin: Pins {} + +fn main() {} From 5e0d8c3b6261db13d64d5f6aa43c7088876fbb20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:35:24 +0100 Subject: [PATCH 17/50] add test for ICE: no errors encountered even though delay_span_bug issued, expected ReFree to map to ReEarlyBound #108580 Fixes https://github.com/rust-lang/rust/issues/108580 --- ...efree-to-map-to-reearlybound-ice-108580.rs | 16 ++++++++++++++++ ...e-to-map-to-reearlybound-ice-108580.stderr | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.rs create mode 100644 tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr diff --git a/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.rs b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.rs new file mode 100644 index 0000000000000..bb10701cf6fb7 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.rs @@ -0,0 +1,16 @@ +// ICE expected ReFree to map to ReEarlyBound +// issue: rust-lang/rust#108580 +//@ check-pass + +trait Foo { + fn bar(&self) -> impl Iterator + '_; +} + +impl Foo for () { + fn bar(&self) -> impl Iterator + '_ { + //~^ WARN impl trait in impl method signature does not match trait method signature + vec![()].into_iter() + } +} + +pub fn main() {} diff --git a/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr new file mode 100644 index 0000000000000..94f068cabaa82 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr @@ -0,0 +1,19 @@ +warning: impl trait in impl method signature does not match trait method signature + --> $DIR/expeced-refree-to-map-to-reearlybound-ice-108580.rs:10:22 + | +LL | fn bar(&self) -> impl Iterator + '_; + | ------------------------------------- return type from trait method defined here +... +LL | fn bar(&self) -> impl Iterator + '_ { + | ^^^^^^^^^^^^^^^^^^ + | + = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate + = note: we are soliciting feedback, see issue #121718 for more information + = note: `#[warn(refining_impl_trait_internal)]` on by default +help: replace the return type so that it matches the trait + | +LL | fn bar(&self) -> impl Iterator + '_ { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +warning: 1 warning emitted + From 56ea366763b5fbac9ded4e0bdab7bd0fe1cb75b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:41:34 +0100 Subject: [PATCH 18/50] add test for Failed to normalize closure with TAIT #109020 Fixes #109020 --- .../closure-normalization-ice-109020.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs diff --git a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs new file mode 100644 index 0000000000000..c5ee46024f987 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs @@ -0,0 +1,41 @@ +// ICE Failed to normalize closure with TAIT +// issue: rust-lang/rust#109020 +//@ check-pass + +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +type WithEmplacableForFn<'a> = impl EmplacableFn + 'a; + +fn with_emplacable_for<'a, F, R>(mut f: F) -> R +where + F: for<'b> FnMut(Emplacable>) -> R, +{ + fn with_emplacable_for_inner<'a, R>( + _: &'a (), + _: &mut dyn FnMut(Emplacable>) -> R, + ) -> R { + fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> { + () + } + loop {} + } + + with_emplacable_for_inner(&(), &mut f) +} + +trait EmplacableFn {} + +impl EmplacableFn for () {} + +struct Emplacable +where + F: EmplacableFn, +{ + phantom: PhantomData, +} + +fn main() { + with_emplacable_for(|_| {}); +} From e800b99347b88dc90bb105a0551011ac01ead624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:49:16 +0100 Subject: [PATCH 19/50] add tests for ICE in mir building with captured value of unresolved type, None in compiler/rustc_mir_build/src/build/expr/as_place.rs #110453 Fixes #110453 --- ...-build-2021-closure-capture-ice-110453-1.rs | 18 ++++++++++++++++++ ...ld-2021-closure-capture-ice-110453-1.stderr | 14 ++++++++++++++ ...-build-2021-closure-capture-ice-110453-2.rs | 11 +++++++++++ ...ld-2021-closure-capture-ice-110453-2.stderr | 9 +++++++++ 4 files changed, 52 insertions(+) create mode 100644 tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs create mode 100644 tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr create mode 100644 tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs create mode 100644 tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs new file mode 100644 index 0000000000000..0b2e63bfcf772 --- /dev/null +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs @@ -0,0 +1,18 @@ +// ICE in mir building with captured value of unresolved type +// None in compiler/rustc_mir_build/src/build/expr/as_place.rs +// issue: rust-lang/rust#110453 +//@ edition:2021 + +#![crate_type="lib"] + +pub struct B; +pub fn a() -> B { B } + +mod handlers { + pub struct C(B); + //~^ ERROR cannot find type `B` in this scope + pub fn c() -> impl Fn() -> C { + let a1 = (); + || C((crate::a(), a1).into()) + } +} diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr new file mode 100644 index 0000000000000..468da0227d3d0 --- /dev/null +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr @@ -0,0 +1,14 @@ +error[E0412]: cannot find type `B` in this scope + --> $DIR/mir-build-2021-closure-capture-ice-110453-1.rs:12:18 + | +LL | pub struct C(B); + | ^ not found in this scope + | +help: consider importing this struct + | +LL + use crate::B; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs new file mode 100644 index 0000000000000..d63ccc6651c7b --- /dev/null +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs @@ -0,0 +1,11 @@ +// ICE in mir building with captured value of unresolved type +// None in compiler/rustc_mir_build/src/build/expr/as_place.rs +// issue: rust-lang/rust#110453 +//@ edition:2021 + +#![crate_type="lib"] + +pub fn dup(f: impl Fn(i32) -> i32) -> impl Fn(as_str) -> i32 { +//~^ ERROR cannot find type `as_str` in this scope + move |a| f(a * 2) +} diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr new file mode 100644 index 0000000000000..8fe4981eb3f24 --- /dev/null +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `as_str` in this scope + --> $DIR/mir-build-2021-closure-capture-ice-110453-2.rs:8:47 + | +LL | pub fn dup(f: impl Fn(i32) -> i32) -> impl Fn(as_str) -> i32 { + | ^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. From e4d816e66c9de3e78a330cd27287c10b831b1c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 24 Mar 2024 10:57:20 +0100 Subject: [PATCH 20/50] add tests for ICE: 'broken MIR: bad assignment: NoSolution' on trait with default method and no impls Fixes #109869 --- ...-method-but-no-impl-broken-mir-109869-1.rs | 21 +++++++++++++++++++ ...hod-but-no-impl-broken-mir-109869-1.stderr | 19 +++++++++++++++++ ...-method-but-no-impl-broken-mir-109869-2.rs | 17 +++++++++++++++ ...hod-but-no-impl-broken-mir-109869-2.stderr | 14 +++++++++++++ ...o-impl-broken-mir-109869-trivial-bounds.rs | 18 ++++++++++++++++ ...pl-broken-mir-109869-trivial-bounds.stderr | 14 +++++++++++++ 6 files changed, 103 insertions(+) create mode 100644 tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.rs create mode 100644 tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.stderr create mode 100644 tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.rs create mode 100644 tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.stderr create mode 100644 tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.rs create mode 100644 tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.stderr diff --git a/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.rs b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.rs new file mode 100644 index 0000000000000..5cccda626084e --- /dev/null +++ b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.rs @@ -0,0 +1,21 @@ +// ICE 'broken MIR: bad assignment: NoSolution' +// on trait with default method and no impls +// issue: rust-lang/rust#109869 + +type Spanned = (T, ()); + +trait Span {} + +impl Span for (T, ()) {} + +impl> From> for dyn Span +where + Self: Sized +{ + fn from((from, ()): Spanned) -> Self { + (T::from(from), ()) + //~^ ERROR mismatched types + } +} + +pub fn main() {} diff --git a/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.stderr b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.stderr new file mode 100644 index 0000000000000..d43c9c018211c --- /dev/null +++ b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/ice-trait-with-default-method-but-no-impl-broken-mir-109869-1.rs:16:9 + | +LL | fn from((from, ()): Spanned) -> Self { + | ---- expected `(dyn Span + 'static)` because of return type +LL | (T::from(from), ()) + | ^^^^^^^^^^^^^^^^^^^ expected `dyn Span`, found `(T, ())` + | + = note: expected trait object `(dyn Span + 'static)` + found tuple `(T, ())` + = help: `(T, ())` implements `Span` so you could box the found value and coerce it to the trait object `Box`, you will have to change the expected type as well +help: call `Into::into` on this expression to convert `(T, ())` into `(dyn Span + 'static)` + | +LL | (T::from(from), ()).into() + | +++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.rs b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.rs new file mode 100644 index 0000000000000..2e0179fb164ef --- /dev/null +++ b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.rs @@ -0,0 +1,17 @@ +// ICE 'broken MIR: bad assignment: NoSolution' +// on trait with default method and no impls +// issue: rust-lang/rust#109869 + +trait Empty {} + +impl Default for dyn Empty +where + Self: Sized, +{ + fn default() -> Self { + () + //~^ ERROR mismatched types + } +} + +pub fn main() {} diff --git a/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.stderr b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.stderr new file mode 100644 index 0000000000000..5f00ced09b845 --- /dev/null +++ b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/ice-trait-with-default-method-but-no-impl-broken-mir-109869-2.rs:12:9 + | +LL | fn default() -> Self { + | ---- expected `(dyn Empty + 'static)` because of return type +LL | () + | ^^ expected `dyn Empty`, found `()` + | + = note: expected trait object `(dyn Empty + 'static)` + found unit type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.rs b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.rs new file mode 100644 index 0000000000000..d8bc2a4321e11 --- /dev/null +++ b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.rs @@ -0,0 +1,18 @@ +// ICE 'broken MIR: bad assignment: NoSolution' +// on trait with default method and no impls +// issue: rust-lang/rust#109869 + +#![feature(trivial_bounds)] +trait Empty {} + +impl Default for dyn Empty +where + Self: Sized, +{ + fn default() -> Self { + () + //~^ ERROR mismatched types + } +} + +pub fn main() {} diff --git a/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.stderr b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.stderr new file mode 100644 index 0000000000000..872b7f5cee1d6 --- /dev/null +++ b/tests/ui/traits/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/ice-trait-with-default-method-but-no-impl-broken-mir-109869-trivial-bounds.rs:13:9 + | +LL | fn default() -> Self { + | ---- expected `(dyn Empty + 'static)` because of return type +LL | () + | ^^ expected `dyn Empty`, found `()` + | + = note: expected trait object `(dyn Empty + 'static)` + found unit type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 47192937d42e47cae6b110dcbf755dbfea7956e8 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sun, 24 Mar 2024 13:57:59 +0000 Subject: [PATCH 21/50] Fix unpretty UI test when /tmp does not exist --- tests/ui/unpretty/avoid-crash.rs | 2 +- tests/ui/unpretty/avoid-crash.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/unpretty/avoid-crash.rs b/tests/ui/unpretty/avoid-crash.rs index 94aa7e77dcb30..2105068617b1c 100644 --- a/tests/ui/unpretty/avoid-crash.rs +++ b/tests/ui/unpretty/avoid-crash.rs @@ -1,4 +1,4 @@ //@ normalize-stderr-test "error `.*`" -> "$$ERROR_MESSAGE" -//@ compile-flags: -o/tmp/ -Zunpretty=ast-tree +//@ compile-flags: -o. -Zunpretty=ast-tree fn main() {} diff --git a/tests/ui/unpretty/avoid-crash.stderr b/tests/ui/unpretty/avoid-crash.stderr index 6fa3e8ca630a4..1c966754e94e4 100644 --- a/tests/ui/unpretty/avoid-crash.stderr +++ b/tests/ui/unpretty/avoid-crash.stderr @@ -1,4 +1,4 @@ -error: failed to write `/tmp/` due to $ERROR_MESSAGE +error: failed to write `.` due to $ERROR_MESSAGE error: aborting due to 1 previous error From 2cb53473d92251a6ba2538fe034ab1ad62224ed1 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sun, 24 Mar 2024 14:57:57 +0000 Subject: [PATCH 22/50] Rename `{enter,exit}_lint_attrs` to `check_attributes{,_post}` --- compiler/rustc_lint/src/early.rs | 4 ++-- compiler/rustc_lint/src/late.rs | 9 ++------- compiler/rustc_lint/src/passes.rs | 18 ++++-------------- src/tools/clippy/clippy_config/src/msrvs.rs | 4 ++-- .../clippy_lints/src/cognitive_complexity.rs | 4 ++-- .../clippy/clippy_lints/src/missing_doc.rs | 4 ++-- .../src/utils/internal_lints/msrv_attr_impl.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 8 ++++---- 8 files changed, 19 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index d78ec8c0dd348..9fae32a49c782 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -73,10 +73,10 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { self.inlined_check_id(id); debug!("early context: enter_attrs({:?})", attrs); - lint_callback!(self, enter_lint_attrs, attrs); + lint_callback!(self, check_attributes, attrs); ensure_sufficient_stack(|| f(self)); debug!("early context: exit_attrs({:?})", attrs); - lint_callback!(self, exit_lint_attrs, attrs); + lint_callback!(self, check_attributes_post, attrs); self.context.builder.pop(push); } } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 384bd353d755d..99207e3f315cf 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -15,7 +15,6 @@ //! for all lint attributes. use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; -use rustc_ast as ast; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::{join, Lrc}; use rustc_hir as hir; @@ -62,13 +61,13 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { let prev = self.context.last_node_with_lint_attrs; self.context.last_node_with_lint_attrs = id; debug!("late context: enter_attrs({:?})", attrs); - lint_callback!(self, enter_lint_attrs, attrs); + lint_callback!(self, check_attributes, attrs); for attr in attrs { lint_callback!(self, check_attribute, attr); } f(self); debug!("late context: exit_attrs({:?})", attrs); - lint_callback!(self, exit_lint_attrs, attrs); + lint_callback!(self, check_attributes_post, attrs); self.context.last_node_with_lint_attrs = prev; } @@ -310,10 +309,6 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas lint_callback!(self, check_path, p, id); hir_visit::walk_path(self, p); } - - fn visit_attribute(&mut self, attr: &'tcx ast::Attribute) { - lint_callback!(self, check_attribute, attr); - } } // Combines multiple lint passes into a single pass, at runtime. Each diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 3e93cc0be6aa6..d8ba84eb7a1a8 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -41,13 +41,8 @@ macro_rules! late_lint_methods { fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>); fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId); fn check_attribute(a: &'tcx rustc_ast::Attribute); - - /// Called when entering a syntax node that can have lint attributes such - /// as `#[allow(...)]`. Called with *all* the attributes of that node. - fn enter_lint_attrs(a: &'tcx [rustc_ast::Attribute]); - - /// Counterpart to `enter_lint_attrs`. - fn exit_lint_attrs(a: &'tcx [rustc_ast::Attribute]); + fn check_attributes(a: &'tcx [rustc_ast::Attribute]); + fn check_attributes_post(a: &'tcx [rustc_ast::Attribute]); ]); ) } @@ -162,16 +157,11 @@ macro_rules! early_lint_methods { fn check_impl_item(a: &rustc_ast::AssocItem); fn check_variant(a: &rustc_ast::Variant); fn check_attribute(a: &rustc_ast::Attribute); + fn check_attributes(a: &[rustc_ast::Attribute]); + fn check_attributes_post(a: &[rustc_ast::Attribute]); fn check_mac_def(a: &rustc_ast::MacroDef); fn check_mac(a: &rustc_ast::MacCall); - /// Called when entering a syntax node that can have lint attributes such - /// as `#[allow(...)]`. Called with *all* the attributes of that node. - fn enter_lint_attrs(a: &[rustc_ast::Attribute]); - - /// Counterpart to `enter_lint_attrs`. - fn exit_lint_attrs(a: &[rustc_ast::Attribute]); - fn enter_where_predicate(a: &rustc_ast::WherePredicate); fn exit_where_predicate(a: &rustc_ast::WherePredicate); ]); diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs index bf4da5f14fe0a..149c4776dc9c9 100644 --- a/src/tools/clippy/clippy_config/src/msrvs.rs +++ b/src/tools/clippy/clippy_config/src/msrvs.rs @@ -143,13 +143,13 @@ impl Msrv { None } - pub fn enter_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) { + pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) { if let Some(version) = Self::parse_attr(sess, attrs) { self.stack.push(version); } } - pub fn exit_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) { + pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) { if Self::parse_attr(sess, attrs).is_some() { self.stack.pop(); } diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index 60f436dc5d2be..7dac3c5d9dabc 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -158,10 +158,10 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity { } } - fn enter_lint_attrs(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { + fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { self.limit.push_attrs(cx.sess(), attrs, "cognitive_complexity"); } - fn exit_lint_attrs(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { + fn check_attributes_post(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { self.limit.pop_attrs(cx.sess(), attrs, "cognitive_complexity"); } } diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 6878fb3349d4a..2773427e72d5a 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -162,12 +162,12 @@ impl MissingDoc { impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]); impl<'tcx> LateLintPass<'tcx> for MissingDoc { - fn enter_lint_attrs(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) { + fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) { let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs); self.doc_hidden_stack.push(doc_hidden); } - fn exit_lint_attrs(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) { + fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) { self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs index 6d5240db83249..8d208fbb7e954 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs @@ -42,7 +42,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV)) }) - && !items.iter().any(|item| item.ident.name == sym!(enter_lint_attrs)) + && !items.iter().any(|item| item.ident.name == sym!(check_attributes)) { let context = if is_late_pass { "LateContext" } else { "EarlyContext" }; let lint_pass = if is_late_pass { "LateLintPass" } else { "EarlyLintPass" }; diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 3b1b99caebe23..8251bdf78fc7d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -131,14 +131,14 @@ use rustc_middle::hir::nested_filter; #[macro_export] macro_rules! extract_msrv_attr { ($context:ident) => { - fn enter_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { + fn check_attributes(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); - self.msrv.enter_lint_attrs(sess, attrs); + self.msrv.check_attributes(sess, attrs); } - fn exit_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { + fn check_attributes_post(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) { let sess = rustc_lint::LintContext::sess(cx); - self.msrv.exit_lint_attrs(sess, attrs); + self.msrv.check_attributes_post(sess, attrs); } }; } From 58e2ad3d582998453d34c182129f02653f565b5f Mon Sep 17 00:00:00 2001 From: Reed Date: Sun, 24 Mar 2024 12:20:39 -0700 Subject: [PATCH 23/50] Amended wording --- library/alloc/src/string.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index f5c1245a7624a..7dba5b4e1f9fa 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -260,8 +260,8 @@ use crate::vec::Vec; /// # Representation /// /// A `String` is made up of three components: a pointer to some bytes, a -/// length, and a capacity. The pointer points to an internal buffer `String` -/// used to store its data. The length is the number of bytes currently stored +/// length, and a capacity. The pointer points to the internal buffer which `String` +/// uses to store its data. The length is the number of bytes currently stored /// in the buffer, and the capacity is the size of the buffer in bytes. As such, /// the length will always be less than or equal to the capacity. /// From e6918b1e5dcf4a2e88c2c39cddfb761dc4a71aca Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 21:42:32 -0400 Subject: [PATCH 24/50] Add async-closures/once.rs back to cranelift tests --- compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 9b360fb303624..fcf3ba0357487 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -154,7 +154,6 @@ rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug # ====================== rm tests/ui/backtrace.rs # TODO warning rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue -rm tests/ui/async-await/async-closures/once.rs # FIXME bug in the rustc FnAbi calculation code rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From 3733dcc72d3b8504ab812990b30e17bd5f0afd5b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:19:07 +0000 Subject: [PATCH 25/50] Add needs-unwind annotations to a couple of tests --- .../rustc_codegen_cranelift/scripts/test_rustc_tests.sh | 6 ------ tests/run-make/libtest-junit/Makefile | 1 + tests/ui/asm/may_unwind.rs | 1 + tests/ui/stable-mir-print/basic_function.rs | 1 + 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 9b360fb303624..7f47fd972c44d 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -41,12 +41,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ -# requires stack unwinding -# FIXME add needs-unwind to these tests -rm -r tests/run-make/libtest-junit -rm tests/ui/asm/may_unwind.rs -rm tests/ui/stable-mir-print/basic_function.rs - # extra warning about -Cpanic=abort for proc macros rm tests/ui/proc-macro/crt-static.rs rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs diff --git a/tests/run-make/libtest-junit/Makefile b/tests/run-make/libtest-junit/Makefile index d97cafccf1fd4..26e56242dd239 100644 --- a/tests/run-make/libtest-junit/Makefile +++ b/tests/run-make/libtest-junit/Makefile @@ -1,4 +1,5 @@ # ignore-cross-compile +# needs-unwind contains should_panic test include ../tools.mk # Test expected libtest's junit output diff --git a/tests/ui/asm/may_unwind.rs b/tests/ui/asm/may_unwind.rs index 216408b38733a..1d4f50d5fe89d 100644 --- a/tests/ui/asm/may_unwind.rs +++ b/tests/ui/asm/may_unwind.rs @@ -1,5 +1,6 @@ //@ run-pass //@ needs-asm-support +//@ needs-unwind #![feature(asm_unwind)] diff --git a/tests/ui/stable-mir-print/basic_function.rs b/tests/ui/stable-mir-print/basic_function.rs index deefef63bdb6e..5f582ece6fb41 100644 --- a/tests/ui/stable-mir-print/basic_function.rs +++ b/tests/ui/stable-mir-print/basic_function.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Z unpretty=stable-mir -Z mir-opt-level=3 //@ check-pass //@ only-x86_64 +//@ needs-unwind unwind edges are different with panic=abort fn foo(i: i32) -> i32 { i + 1 From 3010fa9afb2a103781c7e9c780401c4ccc76818b Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Fri, 22 Mar 2024 17:43:53 -0700 Subject: [PATCH 26/50] 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 +++++++++---------- ...y.run2-{closure#0}.Inline.panic-abort.diff | 54 ++++++++-------- ....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 +- 10 files changed, 139 insertions(+), 131 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-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index b189b4e73f405..0243e31cb1ac7 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.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,19 +43,19 @@ + 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 _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()}; + 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 { + } @@ -71,7 +71,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; + } } @@ -93,11 +93,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 unreachable]; +- _4 = Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked(move _5) -> [return: bb2, unwind unreachable]; - } - - 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); @@ -106,7 +106,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 unreachable]; +- _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind unreachable]; + StorageLive(_11); + StorageLive(_15); + StorageLive(_16); @@ -123,7 +123,7 @@ + StorageLive(_38); + StorageLive(_39); + StorageLive(_40); -+ _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: bb3, 1: bb13, 3: bb12, otherwise: bb8]; } @@ -164,8 +164,8 @@ + bb3: { + _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); @@ -183,7 +183,7 @@ - StorageDead(_2); - return; + 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 -> bb5; + } @@ -194,7 +194,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: bb6, unwind unreachable]; @@ -236,7 +236,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 -> bb2; + } @@ -251,13 +251,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: bb11, unwind unreachable]; + } + + bb11: { + _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 -> bb2; + } 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 From 5f5dcaefe648390e2d5763c8f6480bba0ffb55bb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:24:08 +0000 Subject: [PATCH 27/50] Add needs-unwind for proc macro tests Rustc gives a warning when compiling proc macros with panic=abort. --- .../rustc_codegen_cranelift/scripts/test_rustc_tests.sh | 9 --------- tests/ui/proc-macro/allowed-signatures.rs | 3 ++- tests/ui/proc-macro/crt-static.rs | 1 + .../proc-macro/no-mangle-in-proc-macro-issue-111888.rs | 1 + tests/ui/proc-macro/no-missing-docs.rs | 1 + tests/ui/proc-macro/proc-macro-deprecated-attr.rs | 1 + tests/ui/proc-macro/quote-debug.rs | 1 + tests/ui/proc-macro/quote-debug.stdout | 1 + tests/ui/rust-2018/proc-macro-crate-in-paths.rs | 1 + 9 files changed, 9 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 7f47fd972c44d..b6651fa28919b 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -41,15 +41,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ -# extra warning about -Cpanic=abort for proc macros -rm tests/ui/proc-macro/crt-static.rs -rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs -rm tests/ui/proc-macro/quote-debug.rs -rm tests/ui/proc-macro/no-missing-docs.rs -rm tests/ui/rust-2018/proc-macro-crate-in-paths.rs -rm tests/ui/proc-macro/allowed-signatures.rs -rm tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs - # vendor intrinsics rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic diff --git a/tests/ui/proc-macro/allowed-signatures.rs b/tests/ui/proc-macro/allowed-signatures.rs index 8dede3f50b59b..c70d62ab57b0d 100644 --- a/tests/ui/proc-macro/allowed-signatures.rs +++ b/tests/ui/proc-macro/allowed-signatures.rs @@ -1,6 +1,7 @@ //@ check-pass //@ force-host //@ no-prefer-dynamic +//@ needs-unwind compiling proc macros with panic=abort causes a warning #![crate_type = "proc-macro"] #![allow(private_interfaces)] @@ -9,7 +10,7 @@ use proc_macro::TokenStream; #[proc_macro] pub fn foo(t: T) -> TokenStream { - TokenStream::new() + TokenStream::new() } trait Project { diff --git a/tests/ui/proc-macro/crt-static.rs b/tests/ui/proc-macro/crt-static.rs index 0874c4e8a38bd..0255d26254e28 100644 --- a/tests/ui/proc-macro/crt-static.rs +++ b/tests/ui/proc-macro/crt-static.rs @@ -7,6 +7,7 @@ //@ force-host //@ no-prefer-dynamic //@ needs-dynamic-linking +//@ needs-unwind compiling proc macros with panic=abort causes a warning #![crate_type = "proc-macro"] diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs index e04d45bbd0dfe..1424754f0cabf 100644 --- a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs +++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs @@ -1,6 +1,7 @@ //@ build-pass //@ force-host //@ no-prefer-dynamic +//@ needs-unwind compiling proc macros with panic=abort causes a warning //@ aux-build:exports_no_mangle.rs #![crate_type = "proc-macro"] diff --git a/tests/ui/proc-macro/no-missing-docs.rs b/tests/ui/proc-macro/no-missing-docs.rs index 124af9bea756d..49d9ead340b2e 100644 --- a/tests/ui/proc-macro/no-missing-docs.rs +++ b/tests/ui/proc-macro/no-missing-docs.rs @@ -4,6 +4,7 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ force-host //@ no-prefer-dynamic +//@ needs-unwind compiling proc macros with panic=abort causes a warning #![crate_type = "proc-macro"] #![deny(missing_docs)] diff --git a/tests/ui/proc-macro/proc-macro-deprecated-attr.rs b/tests/ui/proc-macro/proc-macro-deprecated-attr.rs index 5e06a1c6cf8ba..85e930bf7f590 100644 --- a/tests/ui/proc-macro/proc-macro-deprecated-attr.rs +++ b/tests/ui/proc-macro/proc-macro-deprecated-attr.rs @@ -1,6 +1,7 @@ //@ check-pass //@ force-host //@ no-prefer-dynamic +//@ needs-unwind compiling proc macros with panic=abort causes a warning #![deny(deprecated)] diff --git a/tests/ui/proc-macro/quote-debug.rs b/tests/ui/proc-macro/quote-debug.rs index f1593b505f9a3..11d144d609f5a 100644 --- a/tests/ui/proc-macro/quote-debug.rs +++ b/tests/ui/proc-macro/quote-debug.rs @@ -2,6 +2,7 @@ //@ force-host //@ no-prefer-dynamic //@ compile-flags: -Z unpretty=expanded +//@ needs-unwind compiling proc macros with panic=abort causes a warning // // This file is not actually used as a proc-macro - instead, // it's just used to show the output of the `quote!` macro diff --git a/tests/ui/proc-macro/quote-debug.stdout b/tests/ui/proc-macro/quote-debug.stdout index 51f34423366ff..d84b4e051e872 100644 --- a/tests/ui/proc-macro/quote-debug.stdout +++ b/tests/ui/proc-macro/quote-debug.stdout @@ -4,6 +4,7 @@ //@ force-host //@ no-prefer-dynamic //@ compile-flags: -Z unpretty=expanded +//@ needs-unwind compiling proc macros with panic=abort causes a warning // // This file is not actually used as a proc-macro - instead, // it's just used to show the output of the `quote!` macro diff --git a/tests/ui/rust-2018/proc-macro-crate-in-paths.rs b/tests/ui/rust-2018/proc-macro-crate-in-paths.rs index ce29fc51a4fda..e5a4b7a9d5cb7 100644 --- a/tests/ui/rust-2018/proc-macro-crate-in-paths.rs +++ b/tests/ui/rust-2018/proc-macro-crate-in-paths.rs @@ -1,6 +1,7 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ force-host //@ no-prefer-dynamic +//@ needs-unwind compiling proc macros with panic=abort causes a warning #![crate_type = "proc-macro"] #![deny(rust_2018_compatibility)] From 95f268efa6bb600ae3117d893955f4420a9452ec Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:00:21 -0400 Subject: [PATCH 28/50] Update books --- src/doc/edition-guide | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/edition-guide b/src/doc/edition-guide index e1eead1181a69..98b33e9a44145 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit e1eead1181a691e56299294d5f1d62fe7a26d317 +Subproject commit 98b33e9a441457b0a491fe1be90e7de64eafc3e5 diff --git a/src/doc/reference b/src/doc/reference index 5afb503a4c1ea..984b36eca4b92 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 5afb503a4c1ea3c84370f8f4c08a1cddd1cdf6ad +Subproject commit 984b36eca4b9293df04d5ba4eb5c4f77db0f51dc diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index e093099709456..7601e0c5ad29d 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit e093099709456e6fd74fecd2505fdf49a2471c10 +Subproject commit 7601e0c5ad29d5bd3b518700ea63fddfff5915a7 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 8a5d647f19b08..ffa246b7fd95a 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 8a5d647f19b08998612146b1cb2ca47083db63e0 +Subproject commit ffa246b7fd95a96e1cd54883e613aed42c32547d From 69c2a61e5b52d4c054d214b311fbcf53a42244ec Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Mon, 25 Mar 2024 13:11:42 -0400 Subject: [PATCH 29/50] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index d438c80c45c24..a510712d05c6c 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d438c80c45c24be676ef5867edc79d0a14910efe +Subproject commit a510712d05c6c98f987af24dd73cdfafee8922e6 From 99fbc6f8efd4f30b571485c9e3aae391aefedeba Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 25 Mar 2024 13:58:33 -0400 Subject: [PATCH 30/50] Instance is Copy --- compiler/rustc_codegen_llvm/src/builder.rs | 4 +-- compiler/rustc_codegen_llvm/src/declare.rs | 10 +++--- compiler/rustc_middle/src/ty/instance.rs | 8 ++--- compiler/rustc_mir_transform/src/inline.rs | 6 ++-- compiler/rustc_monomorphize/src/collector.rs | 38 ++++++++++---------- compiler/rustc_monomorphize/src/lib.rs | 2 +- compiler/rustc_symbol_mangling/src/typeid.rs | 8 ++--- 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index a5a5ae73d77a1..8724752ce2444 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1630,7 +1630,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } let typeid = if let Some(instance) = instance { - typeid_for_instance(self.tcx, &instance, options) + typeid_for_instance(self.tcx, instance, options) } else { typeid_for_fnabi(self.tcx, fn_abi, options) }; @@ -1678,7 +1678,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } let kcfi_typeid = if let Some(instance) = instance { - kcfi_typeid_for_instance(self.tcx, &instance, options) + kcfi_typeid_for_instance(self.tcx, instance, options) } else { kcfi_typeid_for_fnabi(self.tcx, fn_abi, options) }; diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 78c0725a63784..1a2498c75a7ff 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -141,17 +141,17 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { if self.tcx.sess.is_sanitizer_cfi_enabled() { if let Some(instance) = instance { - let typeid = typeid_for_instance(self.tcx, &instance, TypeIdOptions::empty()); + let typeid = typeid_for_instance(self.tcx, instance, TypeIdOptions::empty()); self.set_type_metadata(llfn, typeid); let typeid = - typeid_for_instance(self.tcx, &instance, TypeIdOptions::GENERALIZE_POINTERS); + typeid_for_instance(self.tcx, instance, TypeIdOptions::GENERALIZE_POINTERS); self.add_type_metadata(llfn, typeid); let typeid = - typeid_for_instance(self.tcx, &instance, TypeIdOptions::NORMALIZE_INTEGERS); + typeid_for_instance(self.tcx, instance, TypeIdOptions::NORMALIZE_INTEGERS); self.add_type_metadata(llfn, typeid); let typeid = typeid_for_instance( self.tcx, - &instance, + instance, TypeIdOptions::GENERALIZE_POINTERS | TypeIdOptions::NORMALIZE_INTEGERS, ); self.add_type_metadata(llfn, typeid); @@ -182,7 +182,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } if let Some(instance) = instance { - let kcfi_typeid = kcfi_typeid_for_instance(self.tcx, &instance, options); + let kcfi_typeid = kcfi_typeid_for_instance(self.tcx, instance, options); self.set_kcfi_type_metadata(llfn, kcfi_typeid); } else { let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 65574f5702b5f..4fec5653a798c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -335,7 +335,7 @@ impl<'tcx> InstanceDef<'tcx> { fn fmt_instance( f: &mut fmt::Formatter<'_>, - instance: &Instance<'_>, + instance: Instance<'_>, type_length: Option, ) -> fmt::Result { ty::tls::with(|tcx| { @@ -369,9 +369,9 @@ fn fmt_instance( } } -pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize); +pub struct ShortInstance<'tcx>(pub Instance<'tcx>, pub usize); -impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> { +impl<'tcx> fmt::Display for ShortInstance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt_instance(f, self.0, Some(rustc_session::Limit(self.1))) } @@ -379,7 +379,7 @@ impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt_instance(f, self, None) + fmt_instance(f, *self, None) } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 78c0615b1650e..5f74841151cda 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -165,7 +165,7 @@ impl<'tcx> Inliner<'tcx> { caller_body: &mut Body<'tcx>, callsite: &CallSite<'tcx>, ) -> Result, &'static str> { - self.check_mir_is_available(caller_body, &callsite.callee)?; + self.check_mir_is_available(caller_body, callsite.callee)?; let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id()); let cross_crate_inlinable = self.tcx.cross_crate_inlinable(callsite.callee.def_id()); @@ -298,7 +298,7 @@ impl<'tcx> Inliner<'tcx> { fn check_mir_is_available( &self, caller_body: &Body<'tcx>, - callee: &Instance<'tcx>, + callee: Instance<'tcx>, ) -> Result<(), &'static str> { let caller_def_id = caller_body.source.def_id(); let callee_def_id = callee.def_id(); @@ -354,7 +354,7 @@ impl<'tcx> Inliner<'tcx> { // If we know for sure that the function we're calling will itself try to // call us, then we avoid inlining that function. - if self.tcx.mir_callgraph_reachable((*callee, caller_def_id.expect_local())) { + if self.tcx.mir_callgraph_reachable((callee, caller_def_id.expect_local())) { return Err("caller might be reachable from callee (query cycle avoidance)"); } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index a51b1c34a1aba..3285cbd04327f 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -397,7 +397,7 @@ fn collect_items_rec<'tcx>( let instance = Instance::mono(tcx, def_id); // Sanity check whether this ended up being collected accidentally - debug_assert!(should_codegen_locally(tcx, &instance)); + debug_assert!(should_codegen_locally(tcx, instance)); let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; // Nested statics have no type. @@ -429,7 +429,7 @@ fn collect_items_rec<'tcx>( } MonoItem::Fn(instance) => { // Sanity check whether this ended up being collected accidentally - debug_assert!(should_codegen_locally(tcx, &instance)); + debug_assert!(should_codegen_locally(tcx, instance)); // Keep track of the monomorphization recursion depth recursion_depth_reset = Some(check_recursion_limit( @@ -474,7 +474,7 @@ fn collect_items_rec<'tcx>( } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { let instance = Instance::mono(tcx, *def_id); - if should_codegen_locally(tcx, &instance) { + if should_codegen_locally(tcx, instance) { trace!("collecting static {:?}", def_id); used_items.push(dummy_spanned(MonoItem::Static(*def_id))); } @@ -557,7 +557,7 @@ fn collect_items_rec<'tcx>( /// If the type name is longer than before+after, it will be written to a file. fn shrunk_instance_name<'tcx>( tcx: TyCtxt<'tcx>, - instance: &Instance<'tcx>, + instance: Instance<'tcx>, ) -> (String, Option) { let s = instance.to_string(); @@ -603,7 +603,7 @@ fn check_recursion_limit<'tcx>( if !recursion_limit.value_within_limit(adjusted_recursion_depth) { let def_span = tcx.def_span(def_id); let def_path_str = tcx.def_path_str(def_id); - let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); + let (shrunk, written_to_path) = shrunk_instance_name(tcx, instance); let mut path = PathBuf::new(); let was_written = if let Some(written_to_path) = written_to_path { path = written_to_path; @@ -645,7 +645,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { // // Bail out in these cases to avoid that bad user experience. if !tcx.type_length_limit().value_within_limit(type_length) { - let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); + let (shrunk, written_to_path) = shrunk_instance_name(tcx, instance); let span = tcx.def_span(instance.def_id()); let mut path = PathBuf::new(); let was_written = if let Some(path2) = written_to_path { @@ -892,7 +892,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { if let ty::Closure(def_id, args) = *source_ty.kind() { let instance = Instance::resolve_closure(self.tcx, def_id, args, ty::ClosureKind::FnOnce); - if should_codegen_locally(self.tcx, &instance) { + if should_codegen_locally(self.tcx, instance) { self.used_items.push(create_fn_mono_item(self.tcx, instance, span)); } } else { @@ -902,7 +902,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { mir::Rvalue::ThreadLocalRef(def_id) => { assert!(self.tcx.is_thread_local_static(def_id)); let instance = Instance::mono(self.tcx, def_id); - if should_codegen_locally(self.tcx, &instance) { + if should_codegen_locally(self.tcx, instance) { trace!("collecting thread-local static {:?}", def_id); self.used_items.push(respan(span, MonoItem::Static(def_id))); } @@ -929,7 +929,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { let tcx = self.tcx; let push_mono_lang_item = |this: &mut Self, lang_item: LangItem| { let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source))); - if should_codegen_locally(tcx, &instance) { + if should_codegen_locally(tcx, instance) { this.used_items.push(create_fn_mono_item(tcx, instance, source)); } }; @@ -962,7 +962,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { } mir::InlineAsmOperand::SymStatic { def_id } => { let instance = Instance::mono(self.tcx, def_id); - if should_codegen_locally(self.tcx, &instance) { + if should_codegen_locally(self.tcx, instance) { trace!("collecting asm sym static {:?}", def_id); self.used_items.push(respan(source, MonoItem::Static(def_id))); } @@ -1051,7 +1051,7 @@ fn visit_instance_use<'tcx>( output: &mut MonoItems<'tcx>, ) { debug!("visit_item_use({:?}, is_direct_call={:?})", instance, is_direct_call); - if !should_codegen_locally(tcx, &instance) { + if !should_codegen_locally(tcx, instance) { return; } if let ty::InstanceDef::Intrinsic(def_id) = instance.def { @@ -1063,13 +1063,13 @@ fn visit_instance_use<'tcx>( // codegen a call to that function without generating code for the function itself. let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap(); let panic_instance = Instance::mono(tcx, def_id); - if should_codegen_locally(tcx, &panic_instance) { + if should_codegen_locally(tcx, panic_instance) { output.push(create_fn_mono_item(tcx, panic_instance, source)); } } else if tcx.has_attr(def_id, sym::rustc_intrinsic) { // Codegen the fallback body of intrinsics with fallback bodies let instance = ty::Instance::new(def_id, instance.args); - if should_codegen_locally(tcx, &instance) { + if should_codegen_locally(tcx, instance) { output.push(create_fn_mono_item(tcx, instance, source)); } } @@ -1107,7 +1107,7 @@ fn visit_instance_use<'tcx>( /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. -pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> bool { +pub(crate) fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool { let Some(def_id) = instance.def.def_id_if_not_guaranteed_local_codegen() else { return true; }; @@ -1304,7 +1304,7 @@ fn create_mono_items_for_vtable_methods<'tcx>( None } VtblEntry::Method(instance) => { - Some(*instance).filter(|instance| should_codegen_locally(tcx, instance)) + Some(*instance).filter(|instance| should_codegen_locally(tcx, *instance)) } }) .map(|item| create_fn_mono_item(tcx, item, source)); @@ -1321,7 +1321,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt GlobalAlloc::Static(def_id) => { assert!(!tcx.is_thread_local_static(def_id)); let instance = Instance::mono(tcx, def_id); - if should_codegen_locally(tcx, &instance) { + if should_codegen_locally(tcx, instance) { trace!("collecting static {:?}", def_id); output.push(dummy_spanned(MonoItem::Static(def_id))); } @@ -1339,7 +1339,7 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt } } GlobalAlloc::Function(fn_instance) => { - if should_codegen_locally(tcx, &fn_instance) { + if should_codegen_locally(tcx, fn_instance) { trace!("collecting {:?} with {:#?}", alloc_id, fn_instance); output.push(create_fn_mono_item(tcx, fn_instance, DUMMY_SP)); } @@ -1474,7 +1474,7 @@ fn visit_mentioned_item<'tcx>( if let ty::Closure(def_id, args) = *source_ty.kind() { let instance = Instance::resolve_closure(tcx, def_id, args, ty::ClosureKind::FnOnce); - if should_codegen_locally(tcx, &instance) { + if should_codegen_locally(tcx, instance) { output.push(create_fn_mono_item(tcx, instance, span)); } } else { @@ -1736,7 +1736,7 @@ fn create_mono_items_for_default_impls<'tcx>( let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); - if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, &instance) { + if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, instance) { output.push(mono_item); } } diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 4ec842e8f85a2..9c4a6e69a3cb9 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -64,7 +64,7 @@ pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>( !instance.def_id().is_local() && tcx.is_compiler_builtins(LOCAL_CRATE) && tcx.codegen_fn_attrs(instance.def_id()).link_name.is_none() - && !should_codegen_locally(tcx, &instance) + && !should_codegen_locally(tcx, instance) } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs index 3bf564a4a16dd..1d28d2b732fdf 100644 --- a/compiler/rustc_symbol_mangling/src/typeid.rs +++ b/compiler/rustc_symbol_mangling/src/typeid.rs @@ -33,10 +33,10 @@ pub fn typeid_for_fnabi<'tcx>( /// Returns a type metadata identifier for the specified Instance. pub fn typeid_for_instance<'tcx>( tcx: TyCtxt<'tcx>, - instance: &Instance<'tcx>, + instance: Instance<'tcx>, options: TypeIdOptions, ) -> String { - typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options) + typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options) } /// Returns a KCFI type metadata identifier for the specified FnAbi. @@ -55,12 +55,12 @@ pub fn kcfi_typeid_for_fnabi<'tcx>( /// Returns a KCFI type metadata identifier for the specified Instance. pub fn kcfi_typeid_for_instance<'tcx>( tcx: TyCtxt<'tcx>, - instance: &Instance<'tcx>, + instance: Instance<'tcx>, options: TypeIdOptions, ) -> u32 { // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) let mut hash: XxHash64 = Default::default(); - hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options).as_bytes()); + hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes()); hash.finish() as u32 } From b500693ad7dcc6e8651217f2f5c1d2f5899c3cff Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 21 Mar 2024 22:38:22 +0000 Subject: [PATCH 31/50] Don't emit load metadata in debug mode --- compiler/rustc_codegen_llvm/src/builder.rs | 11 +++++++++++ tests/codegen/intrinsics/typed_swap.rs | 13 ++++++------- tests/codegen/loads.rs | 3 ++- tests/codegen/overaligned-constant.rs | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index a5a5ae73d77a1..79e35e927bc73 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout, }; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_session::config::OptLevel; use rustc_span::Span; use rustc_symbol_mangling::typeid::{ kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance, @@ -551,6 +552,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { layout: TyAndLayout<'tcx>, offset: Size, ) { + if bx.cx.sess().opts.optimize == OptLevel::No { + // Don't emit metadata we're not going to use + return; + } + if !scalar.is_uninit_valid() { bx.noundef_metadata(load); } @@ -667,6 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { return; } + if self.cx.sess().opts.optimize == OptLevel::No { + // Don't emit metadata we're not going to use + return; + } + unsafe { let llty = self.cx.val_ty(load); let v = [ diff --git a/tests/codegen/intrinsics/typed_swap.rs b/tests/codegen/intrinsics/typed_swap.rs index b55fb8ee36fd6..e73931d1d547e 100644 --- a/tests/codegen/intrinsics/typed_swap.rs +++ b/tests/codegen/intrinsics/typed_swap.rs @@ -24,9 +24,8 @@ pub unsafe fn swap_i32(x: &mut i32, y: &mut i32) { // CHECK-NOT: alloca // CHECK: %[[TEMP:.+]] = load i32, ptr %x, align 4 - // CHECK-SAME: !noundef + // OPT3-SAME: !noundef // OPT0: %[[TEMP2:.+]] = load i32, ptr %y, align 4 - // OPT0-SAME: !noundef // OPT0: store i32 %[[TEMP2]], ptr %x, align 4 // OPT0-NOT: memcpy // OPT3-NOT: load @@ -42,9 +41,9 @@ pub unsafe fn swap_pair(x: &mut (i32, u32), y: &mut (i32, u32)) { // CHECK-NOT: alloca // CHECK: load i32 - // CHECK-SAME: !noundef + // OPT3-SAME: !noundef // CHECK: load i32 - // CHECK-SAME: !noundef + // OPT3-SAME: !noundef // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 8, i1 false) // CHECK: store i32 // CHECK: store i32 @@ -57,10 +56,10 @@ pub unsafe fn swap_str<'a>(x: &mut &'a str, y: &mut &'a str) { // CHECK-NOT: alloca // CHECK: load ptr - // CHECK-SAME: !nonnull - // CHECK-SAME: !noundef + // OPT3-SAME: !nonnull + // OPT3-SAME: !noundef // CHECK: load i64 - // CHECK-SAME: !noundef + // OPT3-SAME: !noundef // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 16, i1 false) // CHECK: store ptr // CHECK: store i64 diff --git a/tests/codegen/loads.rs b/tests/codegen/loads.rs index b86b3dd3a1967..ba4de77ce6fd4 100644 --- a/tests/codegen/loads.rs +++ b/tests/codegen/loads.rs @@ -1,4 +1,5 @@ -//@ compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 +//@ compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 -O + #![crate_type = "lib"] #![feature(generic_nonzero)] diff --git a/tests/codegen/overaligned-constant.rs b/tests/codegen/overaligned-constant.rs index 351c8ea8f4b2b..9e5b69ff2670e 100644 --- a/tests/codegen/overaligned-constant.rs +++ b/tests/codegen/overaligned-constant.rs @@ -16,7 +16,7 @@ fn main() { // CHECK-LABEL: @_ZN20overaligned_constant4main // CHECK: [[full:%_.*]] = alloca %SmallStruct, align 8 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false) - // CHECK: %b.0 = load i32, ptr @0, align 4, + // CHECK: %b.0 = load i32, ptr @0, align 4 // CHECK: %b.1 = load i32, ptr getelementptr inbounds ({{.*}}), align 4 let mut s = S(1); From d94f6576dd88d960ddeaae9208298473b9a27f71 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 22 Mar 2024 14:55:26 +0100 Subject: [PATCH 32/50] extend doc comment for reachability set computation also extend the const fn reachability test --- compiler/rustc_passes/src/reachable.rs | 72 ++++++++++++++++-------- tests/ui/consts/auxiliary/issue-63226.rs | 13 ++++- tests/ui/consts/issue-63226.rs | 2 + 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index b7135de08ba84..7db911465901e 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -1,9 +1,14 @@ -// Finds items that are externally reachable, to determine which items -// need to have their metadata (and possibly their AST) serialized. -// All items that can be referred to through an exported name are -// reachable, and when a reachable thing is inline or generic, it -// makes all other generics or inline functions that it references -// reachable as well. +//! Finds local items that are externally reachable, which means that other crates need access to +//! their compiled machine code or their MIR. +//! +//! An item is "externally reachable" if it is relevant for other crates. This obviously includes +//! all public items. However, some of these items cannot be compiled to machine code (because they +//! are generic), and for some the machine code is not sufficient (because we want to cross-crate +//! inline them). These items "need cross-crate MIR". When a reachable function `f` needs +//! cross-crate MIR, then all the functions it calls also become reachable, as they will be +//! necessary to use the MIR of `f` from another crate. Furthermore, an item can become "externally +//! reachable" by having a `const`/`const fn` return a pointer to that item, so we also need to +//! recurse into reachable `const`/`const fn`. use hir::def_id::LocalDefIdSet; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -21,7 +26,9 @@ use rustc_privacy::DefIdVisitor; use rustc_session::config::CrateType; use rustc_target::spec::abi::Abi; -fn item_might_be_inlined(tcx: TyCtxt<'_>, def_id: DefId) -> bool { +/// Determines whether this item is recursive for reachability. See `is_recursively_reachable_local` +/// below for details. +fn recursively_reachable(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.generics_of(def_id).requires_monomorphization(tcx) || tcx.cross_crate_inlinable(def_id) || tcx.is_const_fn(def_id) @@ -54,12 +61,20 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { let res = match expr.kind { hir::ExprKind::Path(ref qpath) => { + // This covers fn ptr casts but also "non-method" calls. Some(self.typeck_results().qpath_res(qpath, expr.hir_id)) } - hir::ExprKind::MethodCall(..) => self - .typeck_results() - .type_dependent_def(expr.hir_id) - .map(|(kind, def_id)| Res::Def(kind, def_id)), + hir::ExprKind::MethodCall(..) => { + // Method calls don't involve a full "path", so we need to determine the callee + // based on the receiver type. + // If this is a method call on a generic type, we might not be able to find the + // callee. That's why `reachable_set` also adds all potential callees for such + // calls, i.e. all trait impl items, to the reachable set. So here we only worry + // about the calls we can identify. + self.typeck_results() + .type_dependent_def(expr.hir_id) + .map(|(kind, def_id)| Res::Def(kind, def_id)) + } hir::ExprKind::Closure(&hir::Closure { def_id, .. }) => { self.reachable_symbols.insert(def_id); None @@ -96,16 +111,24 @@ impl<'tcx> ReachableContext<'tcx> { .expect("`ReachableContext::typeck_results` called outside of body") } - // Returns true if the given def ID represents a local item that is - // eligible for inlining and false otherwise. - fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool { + /// Returns true if the given def ID represents a local item that is recursive for reachability, + /// i.e. whether everything mentioned in here also needs to be considered reachable. + /// + /// There are two reasons why an item may be recursively reachable: + /// - It needs cross-crate MIR (see the module-level doc comment above). + /// - It is a `const` or `const fn`. This is *not* because we need the MIR to interpret them + /// (MIR for const-eval and MIR for codegen is separate, and MIR for const-eval is always + /// encoded). Instead, it is because `const fn` can create `fn()` pointers to other items + /// which end up in the evaluated result of the constant and can then be called from other + /// crates. Those items must be considered reachable. + fn is_recursively_reachable_local(&self, def_id: DefId) -> bool { let Some(def_id) = def_id.as_local() else { return false; }; match self.tcx.hir_node_by_def_id(def_id) { Node::Item(item) => match item.kind { - hir::ItemKind::Fn(..) => item_might_be_inlined(self.tcx, def_id.into()), + hir::ItemKind::Fn(..) => recursively_reachable(self.tcx, def_id.into()), _ => false, }, Node::TraitItem(trait_method) => match trait_method.kind { @@ -117,7 +140,7 @@ impl<'tcx> ReachableContext<'tcx> { Node::ImplItem(impl_item) => match impl_item.kind { hir::ImplItemKind::Const(..) => true, hir::ImplItemKind::Fn(..) => { - item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id()) + recursively_reachable(self.tcx, impl_item.hir_id().owner.to_def_id()) } hir::ImplItemKind::Type(_) => false, }, @@ -174,7 +197,7 @@ impl<'tcx> ReachableContext<'tcx> { Node::Item(item) => { match item.kind { hir::ItemKind::Fn(.., body) => { - if item_might_be_inlined(self.tcx, item.owner_id.into()) { + if recursively_reachable(self.tcx, item.owner_id.into()) { self.visit_nested_body(body); } } @@ -228,7 +251,7 @@ impl<'tcx> ReachableContext<'tcx> { self.visit_nested_body(body); } hir::ImplItemKind::Fn(_, body) => { - if item_might_be_inlined(self.tcx, impl_item.hir_id().owner.to_def_id()) { + if recursively_reachable(self.tcx, impl_item.hir_id().owner.to_def_id()) { self.visit_nested_body(body) } } @@ -316,7 +339,7 @@ impl<'tcx> ReachableContext<'tcx> { self.worklist.push(def_id); } _ => { - if self.def_id_represents_local_inlined_item(def_id.to_def_id()) { + if self.is_recursively_reachable_local(def_id.to_def_id()) { self.worklist.push(def_id); } else { self.reachable_symbols.insert(def_id); @@ -394,6 +417,7 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) } +/// See module-level doc comment above. fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet { let effective_visibilities = &tcx.effective_visibilities(()); @@ -427,14 +451,16 @@ fn reachable_set(tcx: TyCtxt<'_>, (): ()) -> LocalDefIdSet { } } { - // Some methods from non-exported (completely private) trait impls still have to be - // reachable if they are called from inlinable code. Generally, it's not known until - // monomorphization if a specific trait impl item can be reachable or not. So, we - // conservatively mark all of them as reachable. + // As explained above, we have to mark all functions called from reachable + // `item_might_be_inlined` items as reachable. The issue is, when those functions are + // generic and call a trait method, we have no idea where that call goes! So, we + // conservatively mark all trait impl items as reachable. // FIXME: One possible strategy for pruning the reachable set is to avoid marking impl // items of non-exported traits (or maybe all local traits?) unless their respective // trait items are used from inlinable code through method call syntax or UFCS, or their // trait is a lang item. + // (But if you implement this, don't forget to take into account that vtables can also + // make trait methods reachable!) let crate_items = tcx.hir_crate_items(()); for id in crate_items.items() { diff --git a/tests/ui/consts/auxiliary/issue-63226.rs b/tests/ui/consts/auxiliary/issue-63226.rs index 2dc9539ba527b..5bb0e694af753 100644 --- a/tests/ui/consts/auxiliary/issue-63226.rs +++ b/tests/ui/consts/auxiliary/issue-63226.rs @@ -2,13 +2,24 @@ pub struct VTable{ state:extern "C" fn(), } -impl VTable{ +impl VTable { pub const fn vtable()->&'static VTable{ Self::VTABLE } const VTABLE: &'static VTable = &VTable{state}; + + pub const VTABLE2: &'static VTable = + &VTable{state: state2}; } +pub const VTABLE3: &'static VTable = + &VTable{state: state3}; + +// Only referenced via a `pub const fn`, and yet reachable. extern "C" fn state() {} +// Only referenced via a associated `pub const`, and yet reachable. +extern "C" fn state2() {} +// Only referenced via a free `pub const`, and yet reachable. +extern "C" fn state3() {} diff --git a/tests/ui/consts/issue-63226.rs b/tests/ui/consts/issue-63226.rs index f8ceab339255a..41e63c294ac90 100644 --- a/tests/ui/consts/issue-63226.rs +++ b/tests/ui/consts/issue-63226.rs @@ -8,5 +8,7 @@ use issue_63226::VTable; static ICE_ICE:&'static VTable=VTable::vtable(); +static MORE_ICE:&'static VTable=VTable::VTABLE2; +static MORE_ICE3:&'static VTable=issue_63226::VTABLE3; fn main() {} From 5f95fc1dff13b515f745be26062e9344403ee3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 25 Mar 2024 20:15:28 +0100 Subject: [PATCH 33/50] add test for Compiler panic using fn_traits #81974 Fixes https://github.com/rust-lang/rust/issues/81974 --- .../rust-call-abi-not-a-tuple-ice-81974.rs | 59 ++++++++++++++ ...rust-call-abi-not-a-tuple-ice-81974.stderr | 78 +++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs create mode 100644 tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs new file mode 100644 index 0000000000000..6380449124ffb --- /dev/null +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.rs @@ -0,0 +1,59 @@ +// ICE argument to function with "rust-call" ABI is not a tuple +// issue: rust-lang/rust#81974 + +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +use std::collections::HashMap; +use std::hash::Hash; + +struct CachedFun { + cache: HashMap, + fun: fn(&mut CachedFun, A) -> B, +} + +impl CachedFun { + fn new(fun: fn(&mut Self, A) -> B) -> Self { + CachedFun { + cache: HashMap::new(), + fun, + } + } +} + +impl FnOnce for CachedFun +//~^ ERROR type parameter to bare `FnOnce` trait must be a tuple +where + A: Eq + Hash + Clone, + B: Clone, +{ + type Output = B; + extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument + self.call_mut(a) + //~^ ERROR `A` is not a tuple + } +} + +impl FnMut for CachedFun +//~^ ERROR type parameter to bare `FnMut` trait must be a tuple +where + A: Eq + Hash + Clone, + B: Clone, +{ + extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { + //~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument + self.cache.get(&a).map(|a| a.clone()).unwrap_or_else(|| { + let b = (self.fun)(self, a.clone()); + self.cache.insert(a, b.clone()); + b + }) + } +} + +fn main() -> () { + let pesce = |y: &mut CachedFun, x| x + 1; + let cachedcoso = CachedFun::new(pesce); + cachedcoso.call_once(1); + //~^ ERROR `i32` is not a tuple +} diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr new file mode 100644 index 0000000000000..cceaddf780331 --- /dev/null +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -0,0 +1,78 @@ +error[E0059]: type parameter to bare `FnOnce` trait must be a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:24:12 + | +LL | impl FnOnce for CachedFun + | ^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | +note: required by a bound in `FnOnce` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0059]: type parameter to bare `FnMut` trait must be a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:38:12 + | +LL | impl FnMut for CachedFun + | ^^^^^^^^ the trait `Tuple` is not implemented for `A` + | +note: required by a bound in `FnMut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5 + | +LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:44:5 + | +LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: `A` is not a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:33:23 + | +LL | self.call_mut(a) + | -------- ^ the trait `Tuple` is not implemented for `A` + | | + | required by a bound introduced by this call + | +note: required by a bound in `call_mut` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL +help: consider further restricting this bound + | +LL | A: Eq + Hash + Clone + std::marker::Tuple, + | ++++++++++++++++++++ + +error[E0277]: `i32` is not a tuple + --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:57:26 + | +LL | cachedcoso.call_once(1); + | --------- ^ the trait `Tuple` is not implemented for `i32` + | | + | required by a bound introduced by this call + | +note: required by a bound in `call_once` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0059, E0277. +For more information about an error, try `rustc --explain E0059`. From 6fe555549bed31133f6035e55b44cf918567046c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 25 Mar 2024 20:20:01 +0100 Subject: [PATCH 34/50] add test for ICE Where clause `Binder(..)` was applicable to `Obligation(..)` but now is not Fixes https://github.com/rust-lang/rust/issues/84727 --- tests/ui/traits/trait-selection-ice-84727.rs | 38 +++++++++++++++ .../traits/trait-selection-ice-84727.stderr | 47 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 tests/ui/traits/trait-selection-ice-84727.rs create mode 100644 tests/ui/traits/trait-selection-ice-84727.stderr diff --git a/tests/ui/traits/trait-selection-ice-84727.rs b/tests/ui/traits/trait-selection-ice-84727.rs new file mode 100644 index 0000000000000..08a282892a59c --- /dev/null +++ b/tests/ui/traits/trait-selection-ice-84727.rs @@ -0,0 +1,38 @@ +// ICE Where clause `Binder(..)` was applicable to `Obligation(..)` but now is not +// issue: rust-lang/rust#84727 + +struct Cell { + foreground: Color, + //~^ ERROR cannot find type `Color` in this scope + background: Color, + //~^ ERROR cannot find type `Color` in this scope +} + +trait Over { + fn over(self) -> Output; +} + +impl + Over, Cell> for Cell +where + Self: Over, Cell>, + //~^ ERROR cannot find type `Color` in this scope +{ + fn over(self) -> Cell { + //~^ ERROR mismatched types + self.over(); + } +} + +impl<'b, TopFg, TopBg, BottomFg, BottomBg> Over<&Cell, ()> + for Cell +where + Cell: Over, Cell>, +{ + fn over(self) -> Cell { + //~^ ERROR cannot find type `NewBg` in this scope + self.over(); + } +} + +pub fn main() {} diff --git a/tests/ui/traits/trait-selection-ice-84727.stderr b/tests/ui/traits/trait-selection-ice-84727.stderr new file mode 100644 index 0000000000000..d4bc4163897c4 --- /dev/null +++ b/tests/ui/traits/trait-selection-ice-84727.stderr @@ -0,0 +1,47 @@ +error[E0412]: cannot find type `Color` in this scope + --> $DIR/trait-selection-ice-84727.rs:5:17 + | +LL | foreground: Color, + | ^^^^^ not found in this scope + +error[E0412]: cannot find type `Color` in this scope + --> $DIR/trait-selection-ice-84727.rs:7:17 + | +LL | background: Color, + | ^^^^^ not found in this scope + +error[E0412]: cannot find type `Color` in this scope + --> $DIR/trait-selection-ice-84727.rs:18:16 + | +LL | Self: Over, Cell>, + | ^^^^^ not found in this scope + +error[E0412]: cannot find type `NewBg` in this scope + --> $DIR/trait-selection-ice-84727.rs:32:27 + | +LL | fn over(self) -> Cell { + | ^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<'b, TopFg, TopBg, BottomFg, BottomBg, NewBg> Over<&Cell, ()> + | +++++++ + +error[E0308]: mismatched types + --> $DIR/trait-selection-ice-84727.rs:21:22 + | +LL | fn over(self) -> Cell { + | ---- ^^^^^^^^^^^ expected `Cell`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression +LL | +LL | self.over(); + | - help: remove this semicolon to return this value + | + = note: expected struct `Cell` + found unit type `()` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. From a3c2d752bdaea980e4792cc6f3c76f7e4380e345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 25 Mar 2024 20:35:51 +0100 Subject: [PATCH 35/50] add test for ICE: failed to get layout for [type error] #92979 Fixes https://github.com/rust-lang/rust/issues/92979 --- ...-to-get-layout-for-type-error-ice-92979.rs | 78 +++++++++++++++++++ ...get-layout-for-type-error-ice-92979.stderr | 16 ++++ 2 files changed, 94 insertions(+) create mode 100644 tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.rs create mode 100644 tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.stderr diff --git a/tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.rs b/tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.rs new file mode 100644 index 0000000000000..7445d8dc51e66 --- /dev/null +++ b/tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.rs @@ -0,0 +1,78 @@ +// ICE: failed to get layout for [type error] +// issue: rust-lang/rust#92979 + +use std::fs; +use std::fs::File; +use std::io::Read; +use std::convert::TryInto; + +fn get_file_as_byte_vec(filename: &String) -> Vec { + let mut f = File::open(&filename).expect("no file found"); + let metadata = fs::metadata(&filename).expect("unable to read metadata"); + let mut buffer = vec![0; metadata.len() as usize]; + f.read(&mut buffer).expect("buffer overflow"); + + buffer +} + + + +fn demo(v: Vec) -> [T; N] { + v.try_into() + .unwrap_or_else(|v: Vec| panic!("Expected a Vec of length {} but it was {}", N, v.len())) +} + + +fn main() { + + // Specify filepath + let file: &String = &String::from("SomeBinaryDataFileWith4ByteHeaders_f32s_and_u32s"); + + // Read file into a vector of bytes + let file_data = get_file_as_byte_vec(file); + + // Print length of vector and first few values + let length = file_data.len(); + println!("The read function read {} bytes", length); + println!("The first few bytes:"); + for i in 0..20{ + println!("{}", file_data[i]); + } + + // Manually count just to make sure + let mut n: u64 = 0; + for data in file_data{ + n += 1; + } + println!("We counted {} bytes", n); + assert!(n as usize == length, "Manual counting does not equal len method"); + + // Simulation parameters + const N: usize = 49627502; // Number of Particles + const bs: f64 = 125.0; // Box Size + const HEADER_INCREMENT: u64 = 4*1; + + // Initialize index and counter variables + let (mut j, mut pos, mut vel, mut id, mut mass): (u64, u64, u64, u64, u64) = (0, 0, 0, 0, 0); + + // Unpack Position Data + j += HEADER_INCREMENT; + let mut position: Vec = Vec::new(); + while position.len() < N*3 { + + let p: Vec = Vec::new(); + for item in 0i8..4 { + let item = item; + p.push(file_data[j as usize]); + j += 1; + } + &mut position[position.len()] = f32::from_be_bytes(demo(p)); + //~^ ERROR invalid left-hand side of assignment + } + + // Ensure position data is indeed position by checking values + for p in position { + assert!((p > 0.) & (p < 125.), "Not in box") + } + +} diff --git a/tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.stderr b/tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.stderr new file mode 100644 index 0000000000000..a6b9e37689685 --- /dev/null +++ b/tests/ui/layout/failed-to-get-layout-for-type-error-ice-92979.stderr @@ -0,0 +1,16 @@ +error[E0070]: invalid left-hand side of assignment + --> $DIR/failed-to-get-layout-for-type-error-ice-92979.rs:69:39 + | +LL | &mut position[position.len()] = f32::from_be_bytes(demo(p)); + | ----------------------------- ^ + | | + | cannot assign to this expression + | +help: consider dereferencing here to assign to the mutably borrowed value + | +LL | *&mut position[position.len()] = f32::from_be_bytes(demo(p)); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0070`. From d261647c93380d5ed535c5ed2f176792f4d74d6c Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Mon, 25 Mar 2024 11:02:02 -0700 Subject: [PATCH 36/50] Import the 2021 prelude in the core crate --- library/core/Cargo.toml | 3 ++- library/core/src/array/equality.rs | 1 - library/core/src/array/mod.rs | 2 +- library/core/src/char/convert.rs | 1 - library/core/src/convert/num.rs | 4 ---- library/core/src/iter/adapters/step_by.rs | 1 - library/core/src/iter/range.rs | 1 - library/core/src/iter/traits/iterator.rs | 2 +- library/core/src/lib.rs | 2 +- library/core/src/net/parser.rs | 1 - library/core/src/option.rs | 2 +- library/core/src/ptr/alignment.rs | 1 - library/core/src/result.rs | 2 +- library/core/src/unit.rs | 2 -- library/portable-simd/crates/core_simd/src/lib.rs | 4 ---- library/portable-simd/crates/core_simd/src/vector.rs | 1 - 16 files changed, 7 insertions(+), 23 deletions(-) diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 3dc8c84e0bfde..a02fcf504168a 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -7,7 +7,8 @@ description = "The Rust Core Library" autotests = false autobenches = false # If you update this, be sure to update it in a bunch of other places too! -# As of 2022, it was the ci/pgo.sh script and the core-no-fp-fmt-parse test. +# As of 2024, it was src/tools/opt-dist, the core-no-fp-fmt-parse test and +# the version of the prelude imported in core/lib.rs. edition = "2021" [lib] diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs index bdb6599abf549..bb668d2a67309 100644 --- a/library/core/src/array/equality.rs +++ b/library/core/src/array/equality.rs @@ -1,5 +1,4 @@ use crate::cmp::BytewiseEq; -use crate::convert::TryInto; #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq<[U; N]> for [T; N] diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 8b5b48c59c29b..2a447aafe72d3 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -6,7 +6,7 @@ use crate::borrow::{Borrow, BorrowMut}; use crate::cmp::Ordering; -use crate::convert::{Infallible, TryFrom}; +use crate::convert::Infallible; use crate::error::Error; use crate::fmt; use crate::hash::{self, Hash}; diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 8f61292911030..f0c2636307fcf 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -1,7 +1,6 @@ //! Character conversions. use crate::char::TryFromCharError; -use crate::convert::TryFrom; use crate::error::Error; use crate::fmt; use crate::mem::transmute; diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 46a9006c14665..0167d04c413fe 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -1,4 +1,3 @@ -use super::TryFrom; use crate::num::TryFromIntError; mod private { @@ -323,7 +322,6 @@ impl_try_from_lower_bounded!(isize => usize); #[cfg(target_pointer_width = "16")] mod ptr_try_from_impls { use super::TryFromIntError; - use crate::convert::TryFrom; impl_try_from_upper_bounded!(usize => u8); impl_try_from_unbounded!(usize => u16, u32, u64, u128); @@ -346,7 +344,6 @@ mod ptr_try_from_impls { #[cfg(target_pointer_width = "32")] mod ptr_try_from_impls { use super::TryFromIntError; - use crate::convert::TryFrom; impl_try_from_upper_bounded!(usize => u8, u16); impl_try_from_unbounded!(usize => u32, u64, u128); @@ -372,7 +369,6 @@ mod ptr_try_from_impls { #[cfg(target_pointer_width = "64")] mod ptr_try_from_impls { use super::TryFromIntError; - use crate::convert::TryFrom; impl_try_from_upper_bounded!(usize => u8, u16, u32); impl_try_from_unbounded!(usize => u64, u128); diff --git a/library/core/src/iter/adapters/step_by.rs b/library/core/src/iter/adapters/step_by.rs index 54ed4c952fb8b..b8b96417d134e 100644 --- a/library/core/src/iter/adapters/step_by.rs +++ b/library/core/src/iter/adapters/step_by.rs @@ -1,4 +1,3 @@ -use crate::convert::TryFrom; use crate::{ intrinsics, iter::{from_fn, TrustedLen, TrustedRandomAccess}, diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 055ead117ea24..5eea764b28adc 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -1,5 +1,4 @@ use crate::ascii::Char as AsciiChar; -use crate::convert::TryFrom; use crate::mem; use crate::net::{Ipv4Addr, Ipv6Addr}; use crate::num::NonZero; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index e1904ed220cb4..d2c9e1554b4f8 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -8,11 +8,11 @@ use super::super::ByRefSized; use super::super::TrustedRandomAccessNoCoerce; use super::super::{ArrayChunks, Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse}; use super::super::{FlatMap, Flatten}; -use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip}; use super::super::{ Inspect, Map, MapWhile, MapWindows, Peekable, Rev, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, }; +use super::super::{Intersperse, IntersperseWith, Product, Sum, Zip}; fn _assert_is_object_safe(_: &dyn Iterator) {} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index f0448a98981fb..d6f4b33c24025 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -285,7 +285,7 @@ extern crate self as core; #[prelude_import] #[allow(unused)] -use prelude::v1::*; +use prelude::rust_2021::*; #[cfg(not(test))] // See #65860 #[macro_use] diff --git a/library/core/src/net/parser.rs b/library/core/src/net/parser.rs index 835ab9d73af57..deea821244859 100644 --- a/library/core/src/net/parser.rs +++ b/library/core/src/net/parser.rs @@ -3,7 +3,6 @@ //! This module is "publicly exported" through the `FromStr` implementations //! below. -use crate::convert::{TryFrom, TryInto}; use crate::error::Error; use crate::fmt; use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 0083d15efaefb..631e1654ce075 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -553,7 +553,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; +use crate::iter::{self, FusedIterator, TrustedLen}; use crate::panicking::{panic, panic_str}; use crate::pin::Pin; use crate::{ diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index bc84fb5ccb0d7..68fce3960c78c 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -1,4 +1,3 @@ -use crate::convert::{TryFrom, TryInto}; use crate::num::NonZero; #[cfg(debug_assertions)] use crate::ub_checks::assert_unsafe_precondition; diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 6879ac03f70bc..b2b627fe6a9cc 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -488,7 +488,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; +use crate::iter::{self, FusedIterator, TrustedLen}; use crate::ops::{self, ControlFlow, Deref, DerefMut}; use crate::{convert, fmt, hint}; diff --git a/library/core/src/unit.rs b/library/core/src/unit.rs index 6656dd5c40beb..d656005f3d42d 100644 --- a/library/core/src/unit.rs +++ b/library/core/src/unit.rs @@ -1,5 +1,3 @@ -use crate::iter::FromIterator; - /// Collapses all unit items from an iterator into one. /// /// This is more useful when combined with higher-level abstractions, like diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs index 7a161b7e01d25..48514e52587f0 100644 --- a/library/portable-simd/crates/core_simd/src/lib.rs +++ b/library/portable-simd/crates/core_simd/src/lib.rs @@ -45,10 +45,6 @@ #![unstable(feature = "portable_simd", issue = "86656")] //! Portable SIMD module. -#[prelude_import] -#[allow(unused_imports)] -use core::prelude::v1::*; - #[path = "mod.rs"] mod core_simd; pub use self::core_simd::simd; diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs index 6c8205b112c31..8dbdfc0e1fe03 100644 --- a/library/portable-simd/crates/core_simd/src/vector.rs +++ b/library/portable-simd/crates/core_simd/src/vector.rs @@ -4,7 +4,6 @@ use crate::simd::{ ptr::{SimdConstPtr, SimdMutPtr}, LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle, }; -use core::convert::{TryFrom, TryInto}; /// A SIMD vector with the shape of `[T; N]` but the operations of `T`. /// From 92f40b8059096c8cc868c1116a31a6d2eea8bc71 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 21 Mar 2024 03:04:49 +0000 Subject: [PATCH 37/50] fix ICE in check_unique --- .../src/region_infer/opaque_types.rs | 13 +++++++++++-- .../ui/type-alias-impl-trait/param_mismatch4.rs | 16 ++++++++++++++++ .../type-alias-impl-trait/param_mismatch4.stderr | 12 ++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/param_mismatch4.rs create mode 100644 tests/ui/type-alias-impl-trait/param_mismatch4.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index d5875a226fe02..49f7242cd8349 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -69,9 +69,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { continue; } + // Ignore non-universal regions because they result in an error eventually. + // FIXME(aliemjay): This logic will be rewritten in a later commit. + let Some(r1) = self.universal_name(r1) else { + continue; + }; + let Some(r2) = self.universal_name(r2) else { + continue; + }; + infcx.dcx().emit_err(LifetimeMismatchOpaqueParam { - arg: self.universal_name(r1).unwrap().into(), - prev: self.universal_name(r2).unwrap().into(), + arg: r1.into(), + prev: r2.into(), span: a_ty.span, prev_span: b_ty.span, }); diff --git a/tests/ui/type-alias-impl-trait/param_mismatch4.rs b/tests/ui/type-alias-impl-trait/param_mismatch4.rs new file mode 100644 index 0000000000000..e072f3ab8e05b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/param_mismatch4.rs @@ -0,0 +1,16 @@ +//! This test checks that when checking for opaque types that +//! only differ in lifetimes, we handle the case of non-generic +//! regions correctly. +#![feature(type_alias_impl_trait)] + +type Opq<'a> = impl Sized; + +// Two defining uses: Opq<'{empty}> and Opq<'a>. +// This used to ICE. +// issue: #122782 +fn build<'a>() -> Opq<'a> { + let _: Opq<'_> = (); + //~^ ERROR expected generic lifetime parameter, found `'_` +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/param_mismatch4.stderr b/tests/ui/type-alias-impl-trait/param_mismatch4.stderr new file mode 100644 index 0000000000000..d3fdea25a3dc4 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/param_mismatch4.stderr @@ -0,0 +1,12 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/param_mismatch4.rs:12:12 + | +LL | type Opq<'a> = impl Sized; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | let _: Opq<'_> = (); + | ^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0792`. From 4e1999d3870c7be9a4addcfcf4fd5db9d29b7d1c Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Mon, 18 Mar 2024 08:33:24 +0000 Subject: [PATCH 38/50] ignore uncaptured lifetimes when checking opaques --- .../src/region_infer/opaque_types.rs | 23 +++--- compiler/rustc_middle/src/ty/mod.rs | 32 ++++++++ ...g-use-uncaptured-non-universal-region-2.rs | 74 +++++++++++++++++++ ...g-use-uncaptured-non-universal-region-3.rs | 13 ++++ ...ing-use-uncaptured-non-universal-region.rs | 16 ++++ ...erased-regions-in-hidden-ty.current.stderr | 2 +- .../erased-regions-in-hidden-ty.next.stderr | 2 +- .../impl-trait/erased-regions-in-hidden-ty.rs | 2 +- ...ariant-duplicate-lifetime-unconstrained.rs | 18 +++++ .../escaping-bound-var.rs | 4 + .../escaping-bound-var.stderr | 14 +++- 11 files changed, 183 insertions(+), 17 deletions(-) create mode 100644 tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-2.rs create mode 100644 tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-3.rs create mode 100644 tests/ui/impl-trait/defining-use-uncaptured-non-universal-region.rs create mode 100644 tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 49f7242cd8349..4958e2c1ade43 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -179,7 +179,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Next, insert universal regions from args, so we can translate regions that appear // in them but are not subject to member constraints, for instance closure args. - let universal_args = infcx.tcx.fold_regions(args, |region, _| { + let universal_key = opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |region| { if let ty::RePlaceholder(..) = region.kind() { // Higher kinded regions don't need remapping, they don't refer to anything outside of this the args. return region; @@ -187,6 +187,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let vid = self.to_region_vid(region); to_universal_region(vid, &mut arg_regions) }); + let universal_args = universal_key.args; debug!(?universal_args); debug!(?arg_regions); @@ -431,23 +432,21 @@ fn check_opaque_type_well_formed<'tcx>( } } -fn check_opaque_type_parameter_valid( - tcx: TyCtxt<'_>, - opaque_type_key: OpaqueTypeKey<'_>, +fn check_opaque_type_parameter_valid<'tcx>( + tcx: TyCtxt<'tcx>, + opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, ) -> Result<(), ErrorGuaranteed> { let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id); - let (parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin { + let (_parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin { OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true), OpaqueTyOrigin::AsyncFn(parent) | OpaqueTyOrigin::FnReturn(parent) => (parent, false), }; - let parent_generics = tcx.generics_of(parent); + let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); - // Only check the parent generics, which will ignore any of the - // duplicated lifetime args that come from reifying late-bounds. - for (i, arg) in opaque_type_key.args.iter().take(parent_generics.count()).enumerate() { + for (i, arg) in opaque_type_key.iter_captured_args(tcx) { let arg_is_param = match arg.unpack() { GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Lifetime(lt) if is_ty_alias => { @@ -464,7 +463,7 @@ fn check_opaque_type_parameter_valid( seen_params.entry(arg).or_default().push(i); } else { // Prevent `fn foo() -> Foo` from being defining. - let opaque_param = parent_generics.param_at(i, tcx); + let opaque_param = opaque_generics.param_at(i, tcx); let kind = opaque_param.kind.descr(); return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam { @@ -478,10 +477,10 @@ fn check_opaque_type_parameter_valid( for (_, indices) in seen_params { if indices.len() > 1 { - let descr = parent_generics.param_at(indices[0], tcx).kind.descr(); + let descr = opaque_generics.param_at(indices[0], tcx).kind.descr(); let spans: Vec<_> = indices .into_iter() - .map(|i| tcx.def_span(parent_generics.param_at(i, tcx).def_id)) + .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) .collect(); #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ce53ccc8cd7a..0be1a1ab39d69 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -832,6 +832,38 @@ pub struct OpaqueTypeKey<'tcx> { pub args: GenericArgsRef<'tcx>, } +impl<'tcx> OpaqueTypeKey<'tcx> { + pub fn iter_captured_args( + self, + tcx: TyCtxt<'tcx>, + ) -> impl Iterator)> { + std::iter::zip(self.args, tcx.variances_of(self.def_id)).enumerate().filter_map( + |(i, (arg, v))| match (arg.unpack(), v) { + (_, ty::Invariant) => Some((i, arg)), + (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None, + _ => bug!("unexpected opaque type arg variance"), + }, + ) + } + + pub fn fold_captured_lifetime_args( + self, + tcx: TyCtxt<'tcx>, + mut f: impl FnMut(Region<'tcx>) -> Region<'tcx>, + ) -> Self { + let Self { def_id, args } = self; + let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| { + match (arg.unpack(), v) { + (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg, + (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(), + _ => arg, + } + }); + let args = tcx.mk_args_from_iter(args); + Self { def_id, args } + } +} + #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] pub struct OpaqueHiddenType<'tcx> { /// The span of this particular definition of the opaque type. So diff --git a/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-2.rs b/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-2.rs new file mode 100644 index 0000000000000..56e099c28d219 --- /dev/null +++ b/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-2.rs @@ -0,0 +1,74 @@ +// issue: #110623 +//@ check-pass + +use std::{collections::BTreeMap, num::ParseIntError, str::FromStr}; + +enum FileSystem { + File(usize), + Directory(BTreeMap), +} + +impl FromStr for FileSystem { + type Err = ParseIntError; + + fn from_str(s: &str) -> Result { + if s.starts_with("dir") { + Ok(Self::new_dir()) + } else { + Ok(Self::File(s.split_whitespace().next().unwrap().parse()?)) + } + } +} + +impl FileSystem { + fn new_dir() -> FileSystem { + FileSystem::Directory(BTreeMap::new()) + } + + fn insert(&mut self, name: String, other: FileSystem) -> Option { + match self { + FileSystem::File(_) => panic!("can only insert into directory!"), + FileSystem::Directory(tree) => tree.insert(name, other), + } + } + + // Recursively build a tree from commands. This uses (abuses?) + // the fact that `cd /` only appears at the start and that + // subsequent `cd`s can only move ONE level to use the recursion + // stack as the filesystem stack + fn build<'a>( + &mut self, + mut commands: impl Iterator + 'a, + ) -> Option + 'a> { + let cmd = commands.next()?; + let mut elements = cmd.lines(); + match elements.next().map(str::trim) { + Some("cd /") | None => self.build(commands), + Some("cd ..") => { + // return to higher scope + Some(commands) + } + Some("ls") => { + for item in elements { + let name = item.split_whitespace().last().unwrap(); + let prior = self.insert(name.to_string(), item.parse().unwrap()); + debug_assert!(prior.is_none()); + } + // continue on + self.build(commands) + } + Some(other_cd) => { + let name = other_cd + .trim() + .strip_prefix("cd ") + .expect("expected a cd command"); + let mut directory = FileSystem::new_dir(); + let further_commands = directory.build(commands); + self.insert(name.to_string(), directory); + self.build(further_commands?) // THIS LINE FAILS TO COMPILE + } + } + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-3.rs b/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-3.rs new file mode 100644 index 0000000000000..a6dcad3face0a --- /dev/null +++ b/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region-3.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +trait Bar {} +impl Bar<"asdf"> for () {} + +fn foo() -> impl Bar<"asdf"> { + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region.rs b/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region.rs new file mode 100644 index 0000000000000..f90ff51c651aa --- /dev/null +++ b/tests/ui/impl-trait/defining-use-uncaptured-non-universal-region.rs @@ -0,0 +1,16 @@ +// issue: #111906 +//@ check-pass + +#![allow(unconditional_recursion)] + +fn foo<'a: 'a>() -> impl Sized { + let _: () = foo::<'a>(); + loop {} +} + +fn bar<'a: 'a>() -> impl Sized + 'a { + let _: *mut &'a () = bar::<'a>(); + loop {} +} + +fn main() {} diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr b/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr index 1d648162113f3..78ef8ec404c9b 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.current.stderr @@ -1,4 +1,4 @@ -error: {foo::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} +error: {foo<'{erased}>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} --> $DIR/erased-regions-in-hidden-ty.rs:12:36 | LL | fn foo<'a: 'a>(x: &'a Vec) -> impl Fn() + 'static { diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr b/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr index 1d648162113f3..78ef8ec404c9b 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.next.stderr @@ -1,4 +1,4 @@ -error: {foo::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} +error: {foo<'{erased}>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} --> $DIR/erased-regions-in-hidden-ty.rs:12:36 | LL | fn foo<'a: 'a>(x: &'a Vec) -> impl Fn() + 'static { diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs index 9d71685f179e4..e60f1badcae0f 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs @@ -10,7 +10,7 @@ // Make sure that the compiler can handle `ReErased` in the hidden type of an opaque. fn foo<'a: 'a>(x: &'a Vec) -> impl Fn() + 'static { - //~^ ERROR 'a/#0>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} + //~^ ERROR '{erased}>::{closure#0} closure_kind_ty=i8 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=()} // Can't write whole type because of lack of path sanitization || () } diff --git a/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs new file mode 100644 index 0000000000000..3b83b2e544b01 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bivariant-duplicate-lifetime-unconstrained.rs @@ -0,0 +1,18 @@ +// The defining use below has an unconstrained lifetime argument. +// Opaque<'{empty}, 'a> := (); +// Make sure we accept it because the lifetime parameter in such position is +// irrelevant - it is an artifact of how we internally represent opaque +// generics. +// See issue #122307 for details. + +//@ check-pass +#![feature(type_alias_impl_trait)] +#![allow(unconditional_recursion)] + +type Opaque<'a> = impl Sized + 'a; + +fn test<'a>() -> Opaque<'a> { + let _: () = test::<'a>(); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 1ff200680be5e..4abd6b75ae6bd 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -17,6 +17,10 @@ impl Test<'_> for () {} fn constrain() -> Foo { () + //~^ ERROR expected generic lifetime parameter, found `'static` + // FIXME(aliemjay): Undesirable error message appears because error regions + // are converterted internally into `'?0` which corresponds to `'static` + // This should be fixed in a later commit. } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index 09f6fba79cfdf..b903b9f915146 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -10,6 +10,16 @@ note: lifetime declared here LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; | ^^ -error: aborting due to 1 previous error +error[E0792]: expected generic lifetime parameter, found `'static` + --> $DIR/escaping-bound-var.rs:19:5 + | +LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | () + | ^^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0657`. +Some errors have detailed explanations: E0657, E0792. +For more information about an error, try `rustc --explain E0657`. From eee5a77ed0352817e32a37832f144c3364394ff8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 26 Mar 2024 11:51:57 +0100 Subject: [PATCH 39/50] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index fa06a069d541e..acf96cfab7a08 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -cb7c63606e53715f94f3ba04d38e50772e4cd23d +b13a71a2e77f4625d1a2b8a5b9488414686ebca9 From 4ecdf5ff00a9af18160bc7214cbcb8a6a1e01d10 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Sat, 21 Oct 2023 16:28:51 +0000 Subject: [PATCH 40/50] except equal parameters from the uniqueness check --- .../src/region_infer/opaque_types.rs | 98 ++++++++++++++++++- tests/ui/error-codes/E0657.rs | 2 + tests/ui/error-codes/E0657.stderr | 27 ++++- .../rpit/non-defining-use-lifetimes.rs | 38 +++++++ .../rpit/non-defining-use-lifetimes.stderr | 36 +++++++ .../equal-lifetime-params-ok.rs | 50 ++++++++++ 6 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs create mode 100644 tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr create mode 100644 tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 4958e2c1ade43..0474dd18d4555 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -432,6 +432,10 @@ fn check_opaque_type_well_formed<'tcx>( } } +/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter]. +/// +/// [rustc-dev-guide chapter]: +/// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html fn check_opaque_type_parameter_valid<'tcx>( tcx: TyCtxt<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, @@ -444,6 +448,7 @@ fn check_opaque_type_parameter_valid<'tcx>( }; let opaque_generics = tcx.generics_of(opaque_type_key.def_id); + let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); for (i, arg) in opaque_type_key.iter_captured_args(tcx) { @@ -451,6 +456,7 @@ fn check_opaque_type_parameter_valid<'tcx>( GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Lifetime(lt) if is_ty_alias => { matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) + || (lt.is_static() && opaque_env.param_equal_static(i)) } // FIXME(#113916): we can't currently check for unique lifetime params, // see that issue for more. We will also have to ignore unused lifetime @@ -460,7 +466,13 @@ fn check_opaque_type_parameter_valid<'tcx>( }; if arg_is_param { - seen_params.entry(arg).or_default().push(i); + // Register if the same lifetime appears multiple times in the generic args. + // There is an exception when the opaque type *requires* the lifetimes to be equal. + // See [rustc-dev-guide chapter] § "An exception to uniqueness rule". + let seen_where = seen_params.entry(arg).or_default(); + if !seen_where.first().is_some_and(|&prev_i| opaque_env.params_equal(i, prev_i)) { + seen_where.push(i); + } } else { // Prevent `fn foo() -> Foo` from being defining. let opaque_param = opaque_generics.param_at(i, tcx); @@ -494,3 +506,87 @@ fn check_opaque_type_parameter_valid<'tcx>( Ok(()) } + +/// Computes if an opaque type requires a lifetime parameter to be equal to +/// another one or to the `'static` lifetime. +/// These requirements are derived from the explicit and implied bounds. +struct LazyOpaqueTyEnv<'tcx> { + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + + /// Equal parameters will have the same name. Computed Lazily. + /// Example: + /// `type Opaque<'a: 'static, 'b: 'c, 'c: 'b> = impl Sized;` + /// Identity args: `['a, 'b, 'c]` + /// Canonical args: `['static, 'b, 'b]` + canonical_args: std::cell::OnceCell>, +} + +impl<'tcx> LazyOpaqueTyEnv<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + Self { tcx, def_id, canonical_args: std::cell::OnceCell::new() } + } + + pub fn param_equal_static(&self, param_index: usize) -> bool { + self.get_canonical_args()[param_index].expect_region().is_static() + } + + pub fn params_equal(&self, param1: usize, param2: usize) -> bool { + let canonical_args = self.get_canonical_args(); + canonical_args[param1] == canonical_args[param2] + } + + fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> { + use rustc_hir as hir; + use rustc_infer::infer::outlives::env::OutlivesEnvironment; + use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; + + if let Some(&canonical_args) = self.canonical_args.get() { + return canonical_args; + } + + let &Self { tcx, def_id, .. } = self; + let origin = tcx.opaque_type_origin(def_id); + let parent = match origin { + hir::OpaqueTyOrigin::FnReturn(parent) + | hir::OpaqueTyOrigin::AsyncFn(parent) + | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent, + }; + let param_env = tcx.param_env(parent); + let args = GenericArgs::identity_for_item(tcx, parent).extend_to( + tcx, + def_id.to_def_id(), + |param, _| { + tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into() + }, + ); + + let infcx = tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); + + let wf_tys = ocx.assumed_wf_types(param_env, parent).unwrap_or_else(|_| { + tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "error getting implied bounds"); + Default::default() + }); + let implied_bounds = infcx.implied_bounds_tys(param_env, parent, &wf_tys); + let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); + + let mut seen = vec![tcx.lifetimes.re_static]; + let canonical_args = tcx.fold_regions(args, |r1, _| { + if r1.is_error() { + r1 + } else if let Some(&r2) = seen.iter().find(|&&r2| { + let free_regions = outlives_env.free_region_map(); + free_regions.sub_free_regions(tcx, r1, r2) + && free_regions.sub_free_regions(tcx, r2, r1) + }) { + r2 + } else { + seen.push(r1); + r1 + } + }); + self.canonical_args.set(canonical_args).unwrap(); + canonical_args + } +} diff --git a/tests/ui/error-codes/E0657.rs b/tests/ui/error-codes/E0657.rs index 212c1d9e581a2..d70c0b334fa84 100644 --- a/tests/ui/error-codes/E0657.rs +++ b/tests/ui/error-codes/E0657.rs @@ -11,6 +11,7 @@ fn free_fn_capture_hrtb_in_impl_trait() //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type { Box::new(()) + //~^ ERROR expected generic lifetime parameter, found `'static` } struct Foo; @@ -20,6 +21,7 @@ impl Foo { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type { Box::new(()) + //~^ ERROR expected generic lifetime parameter, found `'static` } } diff --git a/tests/ui/error-codes/E0657.stderr b/tests/ui/error-codes/E0657.stderr index c539007cdcf19..28b989aa429da 100644 --- a/tests/ui/error-codes/E0657.stderr +++ b/tests/ui/error-codes/E0657.stderr @@ -10,18 +10,37 @@ note: lifetime declared here LL | -> Box Id>> | ^^ +error[E0792]: expected generic lifetime parameter, found `'static` + --> $DIR/E0657.rs:13:5 + | +LL | -> Box Id>> + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | Box::new(()) + | ^^^^^^^^^^^^ + error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/E0657.rs:19:35 + --> $DIR/E0657.rs:20:35 | LL | -> Box Id>> | ^^ | note: lifetime declared here - --> $DIR/E0657.rs:19:20 + --> $DIR/E0657.rs:20:20 | LL | -> Box Id>> | ^^ -error: aborting due to 2 previous errors +error[E0792]: expected generic lifetime parameter, found `'static` + --> $DIR/E0657.rs:23:9 + | +LL | -> Box Id>> + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | Box::new(()) + | ^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0657`. +Some errors have detailed explanations: E0657, E0792. +For more information about an error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs new file mode 100644 index 0000000000000..aa60ec27e00a3 --- /dev/null +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs @@ -0,0 +1,38 @@ +// issue: #111935 +// FIXME(aliemjay): outdated due to "once modulo regions" restriction. +// FIXME(aliemjay): mod `infer` should fail. + +#![allow(unconditional_recursion)] + +// Lt indirection is necessary to make the lifetime of the function late-bound, +// in order to bypass some other bugs. +type Lt<'lt> = Option<*mut &'lt ()>; + +mod statik { + use super::*; + // invalid defining use: Opaque<'static> := () + fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { + let _: () = foo(Lt::<'static>::None); + //~^ ERROR opaque type used twice with different lifetimes + } +} + +mod infer { + use super::*; + // invalid defining use: Opaque<'_> := () + fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { + let _: () = foo(Lt::<'_>::None); + } +} + +mod equal { + use super::*; + // invalid defining use: Opaque<'a, 'a> := () + // because of the use of equal lifetimes in args + fn foo<'a, 'b>(_: Lt<'a>, _: Lt<'b>) -> impl Sized + 'a + 'b { + let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); + //~^ ERROR opaque type used twice with different lifetimes + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr new file mode 100644 index 0000000000000..fe6bf71abdbd3 --- /dev/null +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr @@ -0,0 +1,36 @@ +error: opaque type used twice with different lifetimes + --> $DIR/non-defining-use-lifetimes.rs:15:16 + | +LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { + | ______________________________________________- +LL | | let _: () = foo(Lt::<'static>::None); + | | ^^ lifetime `'static` used here +LL | | +LL | | } + | |_____- lifetime `'a` previously used here + | +note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types + --> $DIR/non-defining-use-lifetimes.rs:15:16 + | +LL | let _: () = foo(Lt::<'static>::None); + | ^^ + +error: opaque type used twice with different lifetimes + --> $DIR/non-defining-use-lifetimes.rs:33:16 + | +LL | fn foo<'a, 'b>(_: Lt<'a>, _: Lt<'b>) -> impl Sized + 'a + 'b { + | __________________________________________________________________- +LL | | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); + | | ^^ lifetime `'a` used here +LL | | +LL | | } + | |_____- lifetime `'b` previously used here + | +note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types + --> $DIR/non-defining-use-lifetimes.rs:33:16 + | +LL | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); + | ^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs new file mode 100644 index 0000000000000..6e3f72a1ebe44 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs @@ -0,0 +1,50 @@ +// FIXME: description +// issue: #113916 +//@ check-pass + +#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_assoc_type)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +mod equal_params { + type Opaque<'a: 'b, 'b: 'a> = impl super::Trait<'a, 'b>; + fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> { + let _ = None::<&'a &'b &'a ()>; + 0u8 + } +} + +mod equal_static { + type Opaque<'a: 'static> = impl Sized + 'a; + fn test<'a: 'static>() -> Opaque<'a> { + let _ = None::<&'static &'a ()>; + 0u8 + } +} + +mod implied_bounds { + trait Traitor { + type Assoc; + fn define(self) -> Self::Assoc; + } + + impl<'a> Traitor for &'static &'a () { + type Assoc = impl Sized + 'a; + fn define(self) -> Self::Assoc { + let _ = None::<&'static &'a ()>; + 0u8 + } + } + + impl<'a, 'b> Traitor for (&'a &'b (), &'b &'a ()) { + type Assoc = impl Sized + 'a + 'b; + fn define(self) -> Self::Assoc { + let _ = None::<(&'a &'b (), &'b &'a ())>; + 0u8 + } + } +} + +fn main() {} From c337825d6dae4b2ada4b358b95aa6ee730a49677 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Tue, 19 Mar 2024 19:23:47 +0000 Subject: [PATCH 41/50] ignore error params --- .../src/region_infer/opaque_types.rs | 8 ++++++ tests/ui/error-codes/E0657.rs | 2 -- tests/ui/error-codes/E0657.stderr | 27 +++---------------- .../escaping-bound-var.rs | 4 --- .../escaping-bound-var.stderr | 14 ++-------- 5 files changed, 14 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 0474dd18d4555..84bacabc14eea 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -478,6 +478,10 @@ fn check_opaque_type_parameter_valid<'tcx>( let opaque_param = opaque_generics.param_at(i, tcx); let kind = opaque_param.kind.descr(); + if let Err(guar) = opaque_env.param_is_error(i) { + return Err(guar); + } + return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam { ty: arg, kind, @@ -536,6 +540,10 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> { canonical_args[param1] == canonical_args[param2] } + pub fn param_is_error(&self, param_index: usize) -> Result<(), ErrorGuaranteed> { + self.get_canonical_args()[param_index].error_reported() + } + fn get_canonical_args(&self) -> ty::GenericArgsRef<'tcx> { use rustc_hir as hir; use rustc_infer::infer::outlives::env::OutlivesEnvironment; diff --git a/tests/ui/error-codes/E0657.rs b/tests/ui/error-codes/E0657.rs index d70c0b334fa84..212c1d9e581a2 100644 --- a/tests/ui/error-codes/E0657.rs +++ b/tests/ui/error-codes/E0657.rs @@ -11,7 +11,6 @@ fn free_fn_capture_hrtb_in_impl_trait() //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type { Box::new(()) - //~^ ERROR expected generic lifetime parameter, found `'static` } struct Foo; @@ -21,7 +20,6 @@ impl Foo { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type { Box::new(()) - //~^ ERROR expected generic lifetime parameter, found `'static` } } diff --git a/tests/ui/error-codes/E0657.stderr b/tests/ui/error-codes/E0657.stderr index 28b989aa429da..c539007cdcf19 100644 --- a/tests/ui/error-codes/E0657.stderr +++ b/tests/ui/error-codes/E0657.stderr @@ -10,37 +10,18 @@ note: lifetime declared here LL | -> Box Id>> | ^^ -error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/E0657.rs:13:5 - | -LL | -> Box Id>> - | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type -... -LL | Box::new(()) - | ^^^^^^^^^^^^ - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/E0657.rs:20:35 + --> $DIR/E0657.rs:19:35 | LL | -> Box Id>> | ^^ | note: lifetime declared here - --> $DIR/E0657.rs:20:20 + --> $DIR/E0657.rs:19:20 | LL | -> Box Id>> | ^^ -error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/E0657.rs:23:9 - | -LL | -> Box Id>> - | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type -... -LL | Box::new(()) - | ^^^^^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0657, E0792. -For more information about an error, try `rustc --explain E0657`. +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 4abd6b75ae6bd..1ff200680be5e 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -17,10 +17,6 @@ impl Test<'_> for () {} fn constrain() -> Foo { () - //~^ ERROR expected generic lifetime parameter, found `'static` - // FIXME(aliemjay): Undesirable error message appears because error regions - // are converterted internally into `'?0` which corresponds to `'static` - // This should be fixed in a later commit. } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index b903b9f915146..09f6fba79cfdf 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -10,16 +10,6 @@ note: lifetime declared here LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; | ^^ -error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/escaping-bound-var.rs:19:5 - | -LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type -... -LL | () - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0657, E0792. -For more information about an error, try `rustc --explain E0657`. +For more information about this error, try `rustc --explain E0657`. From ce91e46a1e9ad5126df1128068113d6f2d618827 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Mon, 18 Mar 2024 16:03:18 +0000 Subject: [PATCH 42/50] check RPITs for invalid args --- .../src/region_infer/opaque_types.rs | 12 +------ ...captured-non-universal-region.infer.stderr | 12 +++++++ ...ining-use-captured-non-universal-region.rs | 24 ++++++++++++++ ...aptured-non-universal-region.statik.stderr | 33 +++++++++++++++++++ .../impl-fn-predefined-lifetimes.rs | 4 +-- .../impl-fn-predefined-lifetimes.stderr | 24 ++++---------- .../bad-item-bound-within-rpitit-2.rs | 1 + .../bad-item-bound-within-rpitit-2.stderr | 13 ++++++-- tests/ui/impl-trait/rpit/early_bound.rs | 1 + tests/ui/impl-trait/rpit/early_bound.stderr | 12 ++++++- .../rpit/non-defining-use-lifetimes.rs | 2 +- .../rpit/non-defining-use-lifetimes.stderr | 15 +++++++-- .../type-alias-impl-trait/hkl_forbidden4.rs | 1 + .../hkl_forbidden4.stderr | 27 ++++++++++----- 14 files changed, 134 insertions(+), 47 deletions(-) create mode 100644 tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr create mode 100644 tests/ui/impl-trait/defining-use-captured-non-universal-region.rs create mode 100644 tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 84bacabc14eea..dbf55db6e6b40 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -441,12 +441,6 @@ fn check_opaque_type_parameter_valid<'tcx>( opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, ) -> Result<(), ErrorGuaranteed> { - let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id); - let (_parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin { - OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true), - OpaqueTyOrigin::AsyncFn(parent) | OpaqueTyOrigin::FnReturn(parent) => (parent, false), - }; - let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); @@ -454,14 +448,10 @@ fn check_opaque_type_parameter_valid<'tcx>( for (i, arg) in opaque_type_key.iter_captured_args(tcx) { let arg_is_param = match arg.unpack() { GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), - GenericArgKind::Lifetime(lt) if is_ty_alias => { + GenericArgKind::Lifetime(lt) => { matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) || (lt.is_static() && opaque_env.param_equal_static(i)) } - // FIXME(#113916): we can't currently check for unique lifetime params, - // see that issue for more. We will also have to ignore unused lifetime - // params for RPIT, but that's comparatively trivial ✨ - GenericArgKind::Lifetime(_) => continue, GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)), }; diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr new file mode 100644 index 0000000000000..ec062abb2fc6f --- /dev/null +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr @@ -0,0 +1,12 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/defining-use-captured-non-universal-region.rs:15:18 + | +LL | fn foo<'a>() -> impl Sized + 'a { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | let i: i32 = foo::<'_>(); + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs new file mode 100644 index 0000000000000..4f72333e65e89 --- /dev/null +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs @@ -0,0 +1,24 @@ +// This was an ICE. See #110726. +// FIXME(aliemjay): outdated due to "once modulo regions" restriction. + +//@ revisions: statik infer fixed +//@ [fixed] check-pass +#![allow(unconditional_recursion)] + +fn foo<'a>() -> impl Sized + 'a { + #[cfg(statik)] + let i: i32 = foo::<'static>(); + //[statik]~^ ERROR opaque type used twice with different lifetimes + //[statik]~| ERROR opaque type used twice with different lifetimes + + #[cfg(infer)] + let i: i32 = foo::<'_>(); + //[infer]~^ ERROR expected generic lifetime parameter, found `'_` + + #[cfg(fixed)] + let i: i32 = foo::<'a>(); + + i +} + +fn main() {} diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr new file mode 100644 index 0000000000000..b44f9ca69442a --- /dev/null +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr @@ -0,0 +1,33 @@ +error: opaque type used twice with different lifetimes + --> $DIR/defining-use-captured-non-universal-region.rs:10:18 + | +LL | let i: i32 = foo::<'static>(); + | ^^^^^^^^^^^^^^^^ lifetime `'static` used here +... +LL | i + | - lifetime `'a` previously used here + | +note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types + --> $DIR/defining-use-captured-non-universal-region.rs:10:18 + | +LL | let i: i32 = foo::<'static>(); + | ^^^^^^^^^^^^^^^^ + +error: opaque type used twice with different lifetimes + --> $DIR/defining-use-captured-non-universal-region.rs:10:18 + | +LL | let i: i32 = foo::<'static>(); + | ^^^^^^^^^^^^^^^^ lifetime `'static` used here +... +LL | i + | - lifetime `'a` previously used here + | +note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types + --> $DIR/defining-use-captured-non-universal-region.rs:10:18 + | +LL | let i: i32 = foo::<'static>(); + | ^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 1577866237544..199cbbf4fcc9b 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,10 +2,8 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - //~^ ERROR cannot resolve opaque type - |x| x - //~^ ERROR concrete type differs from previous defining opaque type use + //~^ ERROR expected generic lifetime parameter, found `'_` } fn _b<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) { diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index c19420bbb0ceb..6064b09ef0927 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -1,21 +1,11 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/impl-fn-predefined-lifetimes.rs:7:9 - | -LL | |x| x - | ^ expected `impl Debug + '_`, got `&u8` - | -note: previous use here - --> $DIR/impl-fn-predefined-lifetimes.rs:7:5 - | -LL | |x| x - | ^^^^^ - -error[E0720]: cannot resolve opaque type - --> $DIR/impl-fn-predefined-lifetimes.rs:4:35 +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/impl-fn-predefined-lifetimes.rs:5:9 | LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - | ^^^^^^^^^^^^^^^ cannot resolve opaque type + | -- this generic parameter must be used with a generic lifetime parameter +LL | |x| x + | ^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs index 41d5f0f64498d..5b3a4eb53ff15 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs @@ -5,6 +5,7 @@ trait Foo { fn bar<'other: 'a>() -> impl Sized + 'a {} //~^ ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` + //~| ERROR expected generic lifetime parameter, found `'static` } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr index b0832eb33ca74..8975578dabd84 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr @@ -28,6 +28,15 @@ help: consider introducing lifetime `'a` here LL | trait Foo<'a> { | ++++ -error: aborting due to 2 previous errors +error[E0792]: expected generic lifetime parameter, found `'static` + --> $DIR/bad-item-bound-within-rpitit-2.rs:5:45 + | +LL | fn bar<'other: 'a>() -> impl Sized + 'a {} + | ------ ^^ + | | + | cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0261`. +Some errors have detailed explanations: E0261, E0792. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/rpit/early_bound.rs b/tests/ui/impl-trait/rpit/early_bound.rs index 6dda687929c4d..005bcea59f243 100644 --- a/tests/ui/impl-trait/rpit/early_bound.rs +++ b/tests/ui/impl-trait/rpit/early_bound.rs @@ -5,6 +5,7 @@ fn test<'a: 'a>(n: bool) -> impl Sized + 'a { let true = n else { loop {} }; let _ = || { let _ = identity::<&'a ()>(test(false)); + //~^ ERROR expected generic lifetime parameter, found `'_` }; loop {} } diff --git a/tests/ui/impl-trait/rpit/early_bound.stderr b/tests/ui/impl-trait/rpit/early_bound.stderr index 780dea4e284ee..b0c7bd4199cc2 100644 --- a/tests/ui/impl-trait/rpit/early_bound.stderr +++ b/tests/ui/impl-trait/rpit/early_bound.stderr @@ -1,3 +1,12 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/early_bound.rs:7:17 + | +LL | fn test<'a: 'a>(n: bool) -> impl Sized + 'a { + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | let _ = identity::<&'a ()>(test(false)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: concrete type differs from previous defining opaque type use --> $DIR/early_bound.rs:3:29 | @@ -10,5 +19,6 @@ note: previous use here LL | let _ = identity::<&'a ()>(test(false)); | ^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs index aa60ec27e00a3..923b194d48384 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs @@ -1,6 +1,5 @@ // issue: #111935 // FIXME(aliemjay): outdated due to "once modulo regions" restriction. -// FIXME(aliemjay): mod `infer` should fail. #![allow(unconditional_recursion)] @@ -22,6 +21,7 @@ mod infer { // invalid defining use: Opaque<'_> := () fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { let _: () = foo(Lt::<'_>::None); + //~^ ERROR expected generic lifetime parameter, found `'_` } } diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr index fe6bf71abdbd3..e0122d32abe55 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr @@ -1,5 +1,5 @@ error: opaque type used twice with different lifetimes - --> $DIR/non-defining-use-lifetimes.rs:15:16 + --> $DIR/non-defining-use-lifetimes.rs:14:16 | LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { | ______________________________________________- @@ -10,11 +10,19 @@ LL | | } | |_____- lifetime `'a` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/non-defining-use-lifetimes.rs:15:16 + --> $DIR/non-defining-use-lifetimes.rs:14:16 | LL | let _: () = foo(Lt::<'static>::None); | ^^ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/non-defining-use-lifetimes.rs:23:16 + | +LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { + | -- this generic parameter must be used with a generic lifetime parameter +LL | let _: () = foo(Lt::<'_>::None); + | ^^ + error: opaque type used twice with different lifetimes --> $DIR/non-defining-use-lifetimes.rs:33:16 | @@ -32,5 +40,6 @@ note: if all non-lifetime generic parameters are the same, but the lifetime para LL | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); | ^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index ef9fe604ea783..3b54fb7ea999f 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -13,6 +13,7 @@ type FutNothing<'a> = impl 'a + Future; async fn operation(_: &mut ()) -> () { //~^ ERROR: concrete type differs from previous call(operation).await + //~^ ERROR: expected generic lifetime parameter, found `'any` } async fn call(_f: F) diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index cd4982b24809a..c41ed0642a46c 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -6,20 +6,17 @@ LL | type FutNothing<'a> = impl 'a + Future; | = note: `FutNothing` must be used in combination with a concrete type within the same module -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 of operation()}` - | -note: previous use here +error[E0792]: expected generic lifetime parameter, found `'any` --> $DIR/hkl_forbidden4.rs:15:5 | +LL | async fn operation(_: &mut ()) -> () { + | - this generic parameter must be used with a generic lifetime parameter +LL | LL | call(operation).await | ^^^^^^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:21:1 + --> $DIR/hkl_forbidden4.rs:22:1 | LL | type FutNothing<'a> = impl 'a + Future; | -- this generic parameter must be used with a generic lifetime parameter @@ -29,6 +26,18 @@ LL | | LL | | } | |_^ -error: aborting due to 3 previous errors +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 of operation()}` + | +note: previous use here + --> $DIR/hkl_forbidden4.rs:15:5 + | +LL | call(operation).await + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`. From 15c7e59c05d14be214ded1f8fe703bfb0c14ffa0 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 18 Oct 2023 09:04:13 +0000 Subject: [PATCH 43/50] favor placeholders over existentials when choosing SCC representatives ... even when the existential has the least RegionVid. universal regions (of root universe) > placeholders > existentials The previous behavior, that chooses the minimal RegionVid index, naturally prefers universal regions over others because they always have the least RegionVids, but there was no guranteed ordering between placeholders and existentials. --- .../rustc_borrowck/src/region_infer/mod.rs | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 54c516c960c1f..599f7dd18c3ea 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -95,9 +95,11 @@ pub struct RegionInferenceContext<'tcx> { /// visible from this index. scc_universes: IndexVec, - /// Contains a "representative" from each SCC. This will be the - /// minimal RegionVid belonging to that universe. It is used as a - /// kind of hacky way to manage checking outlives relationships, + /// Contains the "representative" region of each SCC. + /// It is defined as the one with the minimal RegionVid, favoring + /// free regions, then placeholders, then existential regions. + /// + /// It is a hacky way to manage checking regions for equality, /// since we can 'canonicalize' each region to the representative /// of its SCC and be sure that -- if they have the same repr -- /// they *must* be equal (though not having the same repr does not @@ -481,8 +483,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { scc_universes } - /// For each SCC, we compute a unique `RegionVid` (in fact, the - /// minimal one that belongs to the SCC). See + /// For each SCC, we compute a unique `RegionVid`. See the /// `scc_representatives` field of `RegionInferenceContext` for /// more details. fn compute_scc_representatives( @@ -490,13 +491,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { definitions: &IndexSlice>, ) -> IndexVec { let num_sccs = constraints_scc.num_sccs(); - let next_region_vid = definitions.next_index(); - let mut scc_representatives = IndexVec::from_elem_n(next_region_vid, num_sccs); - - for region_vid in definitions.indices() { - let scc = constraints_scc.scc(region_vid); - let prev_min = scc_representatives[scc]; - scc_representatives[scc] = region_vid.min(prev_min); + let mut scc_representatives = IndexVec::from_elem_n(RegionVid::MAX, num_sccs); + + // Iterate over all RegionVids *in-order* and pick the least RegionVid as the + // representative of its SCC. This naturally prefers free regions over others. + for (vid, def) in definitions.iter_enumerated() { + let repr = &mut scc_representatives[constraints_scc.scc(vid)]; + if *repr == ty::RegionVid::MAX { + *repr = vid; + } else if matches!(def.origin, NllRegionVariableOrigin::Placeholder(_)) + && matches!(definitions[*repr].origin, NllRegionVariableOrigin::Existential { .. }) + { + // Pick placeholders over existentials even if they have a greater RegionVid. + *repr = vid; + } } scc_representatives From 08c8caa5244b91ab7bda3bbc383f66ae07f3cc93 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 18 Oct 2023 09:33:57 +0000 Subject: [PATCH 44/50] convert all named regions in opaque types to nll vars Do it in typeck before entering region inference routines particularly because we will no longer be able to convert placeholders. --- compiler/rustc_borrowck/src/type_check/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a206aac0467f4..b72dccb2ebd0d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -229,6 +229,22 @@ pub(crate) fn type_check<'mir, 'tcx>( ); } + // Convert all regions to nll vars. + let (opaque_type_key, hidden_type) = + infcx.tcx.fold_regions((opaque_type_key, hidden_type), |region, _| { + match region.kind() { + ty::ReVar(_) => region, + ty::RePlaceholder(placeholder) => checker + .borrowck_context + .constraints + .placeholder_region(infcx, placeholder), + _ => ty::Region::new_var( + infcx.tcx, + checker.borrowck_context.universal_regions.to_region_vid(region), + ), + } + }); + (opaque_type_key, hidden_type) }) .collect(); From f4940e4d22006e902989bbe41ad0484d549495f5 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 18 Oct 2023 13:56:15 +0000 Subject: [PATCH 45/50] rework opaque types region inference --- .../src/region_infer/opaque_types.rs | 152 ++++++++---------- .../src/type_check/free_region_relations.rs | 7 + .../defined-by-user-annotation.rs | 22 ++- .../equal-lifetime-params-not-ok.rs | 37 +++++ .../equal-lifetime-params-not-ok.stderr | 59 +++++++ .../generic-not-strictly-equal.basic.stderr | 12 ++ ...t-strictly-equal.member_constraints.stderr | 15 ++ .../generic-not-strictly-equal.rs | 38 +++++ 8 files changed, 250 insertions(+), 92 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs create mode 100644 tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr create mode 100644 tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr create mode 100644 tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr create mode 100644 tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index dbf55db6e6b40..7fbf4fbf08589 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,10 +1,10 @@ -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; -use rustc_infer::infer::InferCtxt; use rustc_infer::infer::TyCtxtInferExt as _; +use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_macros::extension; use rustc_middle::traits::DefiningAnchor; @@ -95,8 +95,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// For example consider `fn f<'a>(x: &'a i32) -> impl Sized + 'a { x }`. /// This is lowered to give HIR something like /// - /// type f<'a>::_Return<'_a> = impl Sized + '_a; - /// fn f<'a>(x: &'a i32) -> f<'static>::_Return<'a> { x } + /// type f<'a>::_Return<'_x> = impl Sized + '_x; + /// fn f<'a>(x: &'a i32) -> f<'a>::_Return<'a> { x } /// /// When checking the return type record the type from the return and the /// type used in the return value. In this case they might be `_Return<'1>` @@ -104,30 +104,34 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// Once we to this method, we have completed region inference and want to /// call `infer_opaque_definition_from_instantiation` to get the inferred - /// type of `_Return<'_a>`. `infer_opaque_definition_from_instantiation` + /// type of `_Return<'_x>`. `infer_opaque_definition_from_instantiation` /// compares lifetimes directly, so we need to map the inference variables /// back to concrete lifetimes: `'static`, `ReEarlyParam` or `ReLateParam`. /// - /// First we map all the lifetimes in the concrete type to an equal - /// universal region that occurs in the concrete type's args, in this case - /// this would result in `&'1 i32`. We only consider regions in the args + /// First we map the regions in the the generic parameters `_Return<'1>` to + /// their `external_name` giving `_Return<'a>`. This step is a bit involved. + /// See the [rustc-dev-guide chapter] for more info. + /// + /// Then we map all the lifetimes in the concrete type to an equal + /// universal region that occurs in the opaque type's args, in this case + /// this would result in `&'a i32`. We only consider regions in the args /// in case there is an equal region that does not. For example, this should /// be allowed: /// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }` /// - /// Then we map the regions in both the type and the generic parameters to their - /// `external_name` giving `concrete_type = &'a i32`, - /// `args = ['static, 'a]`. This will then allow - /// `infer_opaque_definition_from_instantiation` to determine that - /// `_Return<'_a> = &'_a i32`. + /// This will then allow `infer_opaque_definition_from_instantiation` to + /// determine that `_Return<'_x> = &'_x i32`. /// /// There's a slight complication around closures. Given /// `fn f<'a: 'a>() { || {} }` the closure's type is something like /// `f::<'a>::{{closure}}`. The region parameter from f is essentially /// ignored by type checking so ends up being inferred to an empty region. /// Calling `universal_upper_bound` for such a region gives `fr_fn_body`, - /// which has no `external_name` in which case we use `'empty` as the + /// which has no `external_name` in which case we use `'{erased}` as the /// region to pass to `infer_opaque_definition_from_instantiation`. + /// + /// [rustc-dev-guide chapter]: + /// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html #[instrument(level = "debug", skip(self, infcx), ret)] pub(crate) fn infer_opaque_types( &self, @@ -138,85 +142,59 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut result: FxIndexMap> = FxIndexMap::default(); - let member_constraints: FxIndexMap<_, _> = self - .member_constraints - .all_indices() - .map(|ci| (self.member_constraints[ci].key, ci)) - .collect(); - debug!(?member_constraints); - for (opaque_type_key, concrete_type) in opaque_ty_decls { - let args = opaque_type_key.args; - debug!(?concrete_type, ?args); + debug!(?opaque_type_key, ?concrete_type); - let mut arg_regions = vec![self.universal_regions.fr_static]; + let mut arg_regions: Vec<(ty::RegionVid, ty::Region<'_>)> = + vec![(self.universal_regions.fr_static, infcx.tcx.lifetimes.re_static)]; - let to_universal_region = |vid, arg_regions: &mut Vec<_>| match self.universal_name(vid) - { - Some(region) => { - let vid = self.universal_regions.to_region_vid(region); - arg_regions.push(vid); - region - } - None => { - arg_regions.push(vid); - ty::Region::new_error_with_message( - infcx.tcx, - concrete_type.span, - "opaque type with non-universal region args", - ) - } - }; + let opaque_type_key = + opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |region| { + // Use the SCC representative instead of directly using `region`. + // See [rustc-dev-guide chapter] § "Strict lifetime equality". + let scc = self.constraint_sccs.scc(region.as_var()); + let vid = self.scc_representatives[scc]; + let named = match self.definitions[vid].origin { + // Iterate over all universal regions in a consistent order and find the + // *first* equal region. This makes sure that equal lifetimes will have + // the same name and simplifies subsequent handling. + // See [rustc-dev-guide chapter] § "Semantic lifetime equality". + NllRegionVariableOrigin::FreeRegion => self + .universal_regions + .universal_regions() + .filter(|&ur| self.universal_region_relations.equal(vid, ur)) + // FIXME(aliemjay): universal regions with no `external_name` + // are extenal closure regions, which should be rejected eventually. + .find_map(|ur| self.definitions[ur].external_name), + NllRegionVariableOrigin::Placeholder(placeholder) => { + Some(ty::Region::new_placeholder(infcx.tcx, placeholder)) + } + NllRegionVariableOrigin::Existential { .. } => None, + } + .unwrap_or_else(|| { + ty::Region::new_error_with_message( + infcx.tcx, + concrete_type.span, + "opaque type with non-universal region args", + ) + }); - // Start by inserting universal regions from the member_constraint choice regions. - // This will ensure they get precedence when folding the regions in the concrete type. - if let Some(&ci) = member_constraints.get(&opaque_type_key) { - for &vid in self.member_constraints.choice_regions(ci) { - to_universal_region(vid, &mut arg_regions); - } - } - debug!(?arg_regions); - - // Next, insert universal regions from args, so we can translate regions that appear - // in them but are not subject to member constraints, for instance closure args. - let universal_key = opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |region| { - if let ty::RePlaceholder(..) = region.kind() { - // Higher kinded regions don't need remapping, they don't refer to anything outside of this the args. - return region; - } - let vid = self.to_region_vid(region); - to_universal_region(vid, &mut arg_regions) - }); - let universal_args = universal_key.args; - debug!(?universal_args); - debug!(?arg_regions); - - // Deduplicate the set of regions while keeping the chosen order. - let arg_regions = arg_regions.into_iter().collect::>(); - debug!(?arg_regions); - - let universal_concrete_type = - infcx.tcx.fold_regions(concrete_type, |region, _| match *region { - ty::ReVar(vid) => arg_regions - .iter() - .find(|ur_vid| self.eval_equal(vid, **ur_vid)) - .and_then(|ur_vid| self.definitions[*ur_vid].external_name) - .unwrap_or(infcx.tcx.lifetimes.re_erased), - ty::RePlaceholder(_) => ty::Region::new_error_with_message( - infcx.tcx, - concrete_type.span, - "hidden type contains placeholders, we don't support higher kinded opaques yet", - ), - _ => region, + arg_regions.push((vid, named)); + named }); - debug!(?universal_concrete_type); + debug!(?opaque_type_key, ?arg_regions); + + let concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| { + arg_regions + .iter() + .find(|&&(arg_vid, _)| self.eval_equal(region.as_var(), arg_vid)) + .map(|&(_, arg_named)| arg_named) + .unwrap_or(infcx.tcx.lifetimes.re_erased) + }); + debug!(?concrete_type); - let opaque_type_key = - OpaqueTypeKey { def_id: opaque_type_key.def_id, args: universal_args }; - let ty = infcx.infer_opaque_definition_from_instantiation( - opaque_type_key, - universal_concrete_type, - ); + let ty = + infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type); // Sometimes two opaque types are the same only after we remap the generic parameters // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to `(X, Y)` // and `OpaqueType` mapped to `(Y, X)`, and those are the same, but we only know that diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 86d20599a2a88..7553e3ee04fb4 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -164,6 +164,13 @@ impl UniversalRegionRelations<'_> { self.outlives.contains(fr1, fr2) } + /// Returns `true` if fr1 is known to equal fr2. + /// + /// This will only ever be true for universally quantified regions. + pub(crate) fn equal(&self, fr1: RegionVid, fr2: RegionVid) -> bool { + self.outlives.contains(fr1, fr2) && self.outlives.contains(fr2, fr1) + } + /// Returns a vector of free regions `x` such that `fr1: x` is /// known to hold. pub(crate) fn regions_outlived_by(&self, fr1: RegionVid) -> Vec { diff --git a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs index d97a3010a17a0..0e1d44e7bb3a3 100644 --- a/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs +++ b/tests/ui/type-alias-impl-trait/defined-by-user-annotation.rs @@ -8,12 +8,24 @@ impl Equate for T { type Proj = T; } trait Indirect { type Ty; } impl> Indirect for (A, B) { type Ty = (); } -type Opq = impl Sized; -fn define_1(_: Opq) { - let _ = None::<<(Opq, u8) as Indirect>::Ty>; +mod basic { + use super::*; + type Opq = impl Sized; + fn define_1(_: Opq) { + let _ = None::<<(Opq, u8) as Indirect>::Ty>; + } + fn define_2() -> Opq { + 0u8 + } } -fn define_2() -> Opq { - 0u8 + +// `Opq<'a> == &'b u8` shouldn't be an error because `'a == 'b`. +mod lifetime { + use super::*; + type Opq<'a> = impl Sized + 'a; + fn define<'a: 'b, 'b: 'a>(_: Opq<'a>) { + let _ = None::<<(Opq<'a>, &'b u8) as Indirect>::Ty>; + } } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs new file mode 100644 index 0000000000000..59ba2694a7643 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.rs @@ -0,0 +1,37 @@ +// issue: #112841 + +#![feature(type_alias_impl_trait)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +mod mod1 { + type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + fn test<'a>() -> Opaque<'a, 'a> {} + //~^ ERROR non-defining opaque type use in defining scope + //~| ERROR non-defining opaque type use in defining scope +} + +mod mod2 { + type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {} + //~^ ERROR non-defining opaque type use in defining scope +} + +mod mod3 { + type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a } + //~^ ERROR non-defining opaque type use in defining scope +} + +// This is similar to the previous cases in that 'a is equal to 'static, +// which is is some sense an implicit parameter to `Opaque`. +// For example, given a defining use `Opaque<'a> := &'a ()`, +// it is ambiguous whether `Opaque<'a> := &'a ()` or `Opaque<'a> := &'static ()` +mod mod4 { + type Opaque<'a> = impl super::Trait<'a, 'a>; + fn test<'a: 'static>() -> Opaque<'a> {} + //~^ ERROR expected generic lifetime parameter, found `'static` +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr new file mode 100644 index 0000000000000..b08bc8b826873 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-not-ok.stderr @@ -0,0 +1,59 @@ +error: non-defining opaque type use in defining scope + --> $DIR/equal-lifetime-params-not-ok.rs:10:22 + | +LL | fn test<'a>() -> Opaque<'a, 'a> {} + | ^^^^^^^^^^^^^^ generic argument `'a` used twice + | +note: for this opaque type + --> $DIR/equal-lifetime-params-not-ok.rs:9:27 + | +LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: non-defining opaque type use in defining scope + --> $DIR/equal-lifetime-params-not-ok.rs:10:37 + | +LL | fn test<'a>() -> Opaque<'a, 'a> {} + | ^^ + | +note: lifetime used multiple times + --> $DIR/equal-lifetime-params-not-ok.rs:9:17 + | +LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + | ^^ ^^ + +error: non-defining opaque type use in defining scope + --> $DIR/equal-lifetime-params-not-ok.rs:17:49 + | +LL | fn test<'a: 'b, 'b: 'a>() -> Opaque<'a, 'b> {} + | ^^ + | +note: lifetime used multiple times + --> $DIR/equal-lifetime-params-not-ok.rs:16:17 + | +LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + | ^^ ^^ + +error: non-defining opaque type use in defining scope + --> $DIR/equal-lifetime-params-not-ok.rs:23:61 + | +LL | fn test<'a: 'b, 'b: 'a>(a: &'a str) -> Opaque<'a, 'b> { a } + | ^ + | +note: lifetime used multiple times + --> $DIR/equal-lifetime-params-not-ok.rs:22:17 + | +LL | type Opaque<'a, 'b> = impl super::Trait<'a, 'b>; + | ^^ ^^ + +error[E0792]: expected generic lifetime parameter, found `'static` + --> $DIR/equal-lifetime-params-not-ok.rs:33:42 + | +LL | type Opaque<'a> = impl super::Trait<'a, 'a>; + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +LL | fn test<'a: 'static>() -> Opaque<'a> {} + | ^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr new file mode 100644 index 0000000000000..e5f86c8c19355 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.basic.stderr @@ -0,0 +1,12 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/generic-not-strictly-equal.rs:33:5 + | +LL | type Opaque<'a> = impl Copy + Captures<'a>; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | relate(opaque, hidden); // defining use: Opaque<'?1> := u8 + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr new file mode 100644 index 0000000000000..693af69d6fab9 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.member_constraints.stderr @@ -0,0 +1,15 @@ +error[E0700]: hidden type for `Opaque<'x>` captures lifetime that does not appear in bounds + --> $DIR/generic-not-strictly-equal.rs:33:5 + | +LL | type Opaque<'a> = impl Copy + Captures<'a>; + | ------------------------ opaque type defined here +LL | +LL | fn test<'x>(_: Opaque<'x>) { + | -- hidden type `&'x u8` captures the lifetime `'x` as defined here +... +LL | relate(opaque, hidden); // defining use: Opaque<'?1> := u8 + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs new file mode 100644 index 0000000000000..a059fd3b8227e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/generic-not-strictly-equal.rs @@ -0,0 +1,38 @@ +// `Opaque<'?1> := u8` is not a valid defining use here. +// +// Due to fundamental limitations of the member constraints algorithm, +// we require '?1 to be *equal* to some universal region. +// +// While '?1 is eventually inferred to be equal to 'x because of the constraint '?1: 'x, +// we don't consider them equal in the strict sense because they lack the bidirectional outlives +// constraints ['?1: 'x, 'x: '?1]. In NLL terms, they are not part of the same SCC. +// +// See #113971 for details. + +//@ revisions: basic member_constraints +#![feature(type_alias_impl_trait)] + +trait Captures<'a> {} +impl Captures<'_> for T {} + +fn ensure_outlives<'a, X: 'a>(_: X) {} +fn relate(_: X, _: X) {} + +type Opaque<'a> = impl Copy + Captures<'a>; + +fn test<'x>(_: Opaque<'x>) { + let opaque = None::>; // let's call this lifetime '?1 + + #[cfg(basic)] + let hidden = None::; + + #[cfg(member_constraints)] + let hidden = None::<&'x u8>; + + ensure_outlives::<'x>(opaque); // outlives constraint: '?1: 'x + relate(opaque, hidden); // defining use: Opaque<'?1> := u8 + //[basic]~^ ERROR expected generic lifetime parameter, found `'_` + //[member_constraints]~^^ ERROR captures lifetime that does not appear in bounds +} + +fn main() {} From 6b6ed2ea28e591ccae99048f226f98abfcd2e087 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 19 Oct 2023 10:42:25 +0000 Subject: [PATCH 46/50] reject external lifetimes as invalid arguments --- .../src/region_infer/opaque_types.rs | 14 +++++++++---- .../defined-in-closure-external-lifetime.rs | 19 +++++++++++++++++ ...efined-in-closure-external-lifetime.stderr | 21 +++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs create mode 100644 tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7fbf4fbf08589..8a03d59b71019 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -18,6 +18,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use crate::session_diagnostics::LifetimeMismatchOpaqueParam; use crate::session_diagnostics::NonGenericOpaqueTypeParam; +use crate::universal_regions::RegionClassification; use super::RegionInferenceContext; @@ -162,10 +163,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { NllRegionVariableOrigin::FreeRegion => self .universal_regions .universal_regions() - .filter(|&ur| self.universal_region_relations.equal(vid, ur)) - // FIXME(aliemjay): universal regions with no `external_name` - // are extenal closure regions, which should be rejected eventually. - .find_map(|ur| self.definitions[ur].external_name), + .filter(|&ur| { + // See [rustc-dev-guide chapter] § "Closure restrictions". + !matches!( + self.universal_regions.region_classification(ur), + Some(RegionClassification::External) + ) + }) + .find(|&ur| self.universal_region_relations.equal(vid, ur)) + .map(|ur| self.definitions[ur].external_name.unwrap()), NllRegionVariableOrigin::Placeholder(placeholder) => { Some(ty::Region::new_placeholder(infcx.tcx, placeholder)) } diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs new file mode 100644 index 0000000000000..9101e4385b3d3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +mod case1 { + type Opaque<'x> = impl Sized + 'x; + fn foo<'s>() -> Opaque<'s> { + let _ = || { let _: Opaque<'s> = (); }; + //~^ ERROR expected generic lifetime parameter, found `'_` + } +} + +mod case2 { + type Opaque<'x> = impl Sized + 'x; + fn foo<'s>() -> Opaque<'s> { + let _ = || -> Opaque<'s> {}; + //~^ ERROR expected generic lifetime parameter, found `'_` + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr new file mode 100644 index 0000000000000..a8fd1f691dd40 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defined-in-closure-external-lifetime.stderr @@ -0,0 +1,21 @@ +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/defined-in-closure-external-lifetime.rs:6:29 + | +LL | type Opaque<'x> = impl Sized + 'x; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn foo<'s>() -> Opaque<'s> { +LL | let _ = || { let _: Opaque<'s> = (); }; + | ^^^^^^^^^^ + +error[E0792]: expected generic lifetime parameter, found `'_` + --> $DIR/defined-in-closure-external-lifetime.rs:14:34 + | +LL | type Opaque<'x> = impl Sized + 'x; + | -- this generic parameter must be used with a generic lifetime parameter +LL | fn foo<'s>() -> Opaque<'s> { +LL | let _ = || -> Opaque<'s> {}; + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0792`. From 7c6876f9a9fe400e29430cb47cc11e71c13bb875 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Fri, 22 Mar 2024 08:02:12 +0000 Subject: [PATCH 47/50] simplify check_unique --- .../src/region_infer/opaque_types.rs | 95 +++++-------------- ...captured-non-universal-region.infer.stderr | 2 +- ...ining-use-captured-non-universal-region.rs | 3 +- ...aptured-non-universal-region.statik.stderr | 33 ++----- .../rpit/non-defining-use-lifetimes.rs | 4 +- .../rpit/non-defining-use-lifetimes.stderr | 34 ++----- .../lifetime_mismatch.rs | 4 - .../lifetime_mismatch.stderr | 69 +------------- .../multiple-def-uses-in-one-fn-lifetimes.rs | 5 +- ...ltiple-def-uses-in-one-fn-lifetimes.stderr | 53 +---------- 10 files changed, 52 insertions(+), 250 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 8a03d59b71019..63b8044581747 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -9,7 +9,6 @@ use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_macros::extension; use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::visit::TypeVisitableExt; -use rustc_middle::ty::RegionVid; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_span::Span; @@ -23,73 +22,6 @@ use crate::universal_regions::RegionClassification; use super::RegionInferenceContext; impl<'tcx> RegionInferenceContext<'tcx> { - fn universal_name(&self, vid: ty::RegionVid) -> Option> { - let scc = self.constraint_sccs.scc(vid); - self.scc_values - .universal_regions_outlived_by(scc) - .find_map(|lb| self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)) - } - - fn generic_arg_to_region(&self, arg: ty::GenericArg<'tcx>) -> Option { - let region = arg.as_region()?; - - if let ty::RePlaceholder(..) = region.kind() { - None - } else { - Some(self.to_region_vid(region)) - } - } - - /// Check that all opaque types have the same region parameters if they have the same - /// non-region parameters. This is necessary because within the new solver we perform various query operations - /// modulo regions, and thus could unsoundly select some impls that don't hold. - fn check_unique( - &self, - infcx: &InferCtxt<'tcx>, - opaque_ty_decls: &FxIndexMap, OpaqueHiddenType<'tcx>>, - ) { - for (i, (a, a_ty)) in opaque_ty_decls.iter().enumerate() { - for (b, b_ty) in opaque_ty_decls.iter().skip(i + 1) { - if a.def_id != b.def_id { - continue; - } - // Non-lifetime params differ -> ok - if infcx.tcx.erase_regions(a.args) != infcx.tcx.erase_regions(b.args) { - continue; - } - trace!(?a, ?b); - for (a, b) in a.args.iter().zip(b.args) { - trace!(?a, ?b); - let Some(r1) = self.generic_arg_to_region(a) else { - continue; - }; - let Some(r2) = self.generic_arg_to_region(b) else { - continue; - }; - if self.eval_equal(r1, r2) { - continue; - } - - // Ignore non-universal regions because they result in an error eventually. - // FIXME(aliemjay): This logic will be rewritten in a later commit. - let Some(r1) = self.universal_name(r1) else { - continue; - }; - let Some(r2) = self.universal_name(r2) else { - continue; - }; - - infcx.dcx().emit_err(LifetimeMismatchOpaqueParam { - arg: r1.into(), - prev: r2.into(), - span: a_ty.span, - prev_span: b_ty.span, - }); - } - } - } - } - /// Resolve any opaque types that were encountered while borrow checking /// this item. This is then used to get the type in the `type_of` query. /// @@ -139,9 +71,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx: &InferCtxt<'tcx>, opaque_ty_decls: FxIndexMap, OpaqueHiddenType<'tcx>>, ) -> FxIndexMap> { - self.check_unique(infcx, &opaque_ty_decls); - let mut result: FxIndexMap> = FxIndexMap::default(); + let mut decls_modulo_regions: FxIndexMap, (OpaqueTypeKey<'tcx>, Span)> = + FxIndexMap::default(); for (opaque_type_key, concrete_type) in opaque_ty_decls { debug!(?opaque_type_key, ?concrete_type); @@ -228,6 +160,29 @@ impl<'tcx> RegionInferenceContext<'tcx> { OpaqueHiddenType { ty, span: concrete_type.span }, ); } + + // Check that all opaque types have the same region parameters if they have the same + // non-region parameters. This is necessary because within the new solver we perform + // various query operations modulo regions, and thus could unsoundly select some impls + // that don't hold. + if !ty.references_error() + && let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert( + infcx.tcx.erase_regions(opaque_type_key), + (opaque_type_key, concrete_type.span), + ) + && let Some((arg1, arg2)) = std::iter::zip( + prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), + opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), + ) + .find(|(arg1, arg2)| arg1 != arg2) + { + infcx.dcx().emit_err(LifetimeMismatchOpaqueParam { + arg: arg1, + prev: arg2, + span: prev_span, + prev_span: concrete_type.span, + }); + } } result } diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr index ec062abb2fc6f..2cb82bf771c44 100644 --- a/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/defining-use-captured-non-universal-region.rs:15:18 + --> $DIR/defining-use-captured-non-universal-region.rs:14:18 | LL | fn foo<'a>() -> impl Sized + 'a { | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs index 4f72333e65e89..2d54804f1fa62 100644 --- a/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs @@ -8,8 +8,7 @@ fn foo<'a>() -> impl Sized + 'a { #[cfg(statik)] let i: i32 = foo::<'static>(); - //[statik]~^ ERROR opaque type used twice with different lifetimes - //[statik]~| ERROR opaque type used twice with different lifetimes + //[statik]~^ ERROR expected generic lifetime parameter, found `'static` #[cfg(infer)] let i: i32 = foo::<'_>(); diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr index b44f9ca69442a..0d9b7df225771 100644 --- a/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr @@ -1,33 +1,12 @@ -error: opaque type used twice with different lifetimes - --> $DIR/defining-use-captured-non-universal-region.rs:10:18 - | -LL | let i: i32 = foo::<'static>(); - | ^^^^^^^^^^^^^^^^ lifetime `'static` used here -... -LL | i - | - lifetime `'a` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/defining-use-captured-non-universal-region.rs:10:18 - | -LL | let i: i32 = foo::<'static>(); - | ^^^^^^^^^^^^^^^^ - -error: opaque type used twice with different lifetimes - --> $DIR/defining-use-captured-non-universal-region.rs:10:18 - | -LL | let i: i32 = foo::<'static>(); - | ^^^^^^^^^^^^^^^^ lifetime `'static` used here -... -LL | i - | - lifetime `'a` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types +error[E0792]: expected generic lifetime parameter, found `'static` --> $DIR/defining-use-captured-non-universal-region.rs:10:18 | +LL | fn foo<'a>() -> impl Sized + 'a { + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +LL | #[cfg(statik)] LL | let i: i32 = foo::<'static>(); | ^^^^^^^^^^^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs index 923b194d48384..cad41d2f2edff 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs @@ -12,7 +12,7 @@ mod statik { // invalid defining use: Opaque<'static> := () fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { let _: () = foo(Lt::<'static>::None); - //~^ ERROR opaque type used twice with different lifetimes + //~^ ERROR expected generic lifetime parameter, found `'static` } } @@ -31,7 +31,7 @@ mod equal { // because of the use of equal lifetimes in args fn foo<'a, 'b>(_: Lt<'a>, _: Lt<'b>) -> impl Sized + 'a + 'b { let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); - //~^ ERROR opaque type used twice with different lifetimes + //~^ ERROR non-defining opaque type use in defining scope } } diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr index e0122d32abe55..7ef96a2e59575 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr @@ -1,17 +1,8 @@ -error: opaque type used twice with different lifetimes - --> $DIR/non-defining-use-lifetimes.rs:14:16 - | -LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { - | ______________________________________________- -LL | | let _: () = foo(Lt::<'static>::None); - | | ^^ lifetime `'static` used here -LL | | -LL | | } - | |_____- lifetime `'a` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types +error[E0792]: expected generic lifetime parameter, found `'static` --> $DIR/non-defining-use-lifetimes.rs:14:16 | +LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { + | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type LL | let _: () = foo(Lt::<'static>::None); | ^^ @@ -23,22 +14,17 @@ LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { LL | let _: () = foo(Lt::<'_>::None); | ^^ -error: opaque type used twice with different lifetimes - --> $DIR/non-defining-use-lifetimes.rs:33:16 - | -LL | fn foo<'a, 'b>(_: Lt<'a>, _: Lt<'b>) -> impl Sized + 'a + 'b { - | __________________________________________________________________- -LL | | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); - | | ^^ lifetime `'a` used here -LL | | -LL | | } - | |_____- lifetime `'b` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types +error: non-defining opaque type use in defining scope --> $DIR/non-defining-use-lifetimes.rs:33:16 | LL | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); | ^^ + | +note: lifetime used multiple times + --> $DIR/non-defining-use-lifetimes.rs:32:58 + | +LL | fn foo<'a, 'b>(_: Lt<'a>, _: Lt<'b>) -> impl Sized + 'a + 'b { + | ^^ ^^ error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs index 9ec585d93f58d..45a55050c4435 100644 --- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs +++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.rs @@ -5,7 +5,6 @@ type Foo<'a> = impl Sized; fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (Foo<'a>, Foo<'b>) { (x, y) //~^ ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes } type Bar<'a, 'b> = impl std::fmt::Debug; @@ -13,9 +12,6 @@ type Bar<'a, 'b> = impl std::fmt::Debug; fn bar<'x, 'y>(i: &'x i32, j: &'y i32) -> (Bar<'x, 'y>, Bar<'y, 'x>) { (i, j) //~^ ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes } fn main() { diff --git a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr b/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr index 7f54f47d27d0c..4f7b0f1740765 100644 --- a/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr +++ b/tests/ui/type-alias-impl-trait/lifetime_mismatch.stderr @@ -14,53 +14,7 @@ LL | (x, y) | ^^^^^^ error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:6:5 - | -LL | (x, y) - | ^^^^^^ - | | - | lifetime `'a` used here - | lifetime `'b` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:6:5 - | -LL | (x, y) - | ^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:14:5 - | -LL | (i, j) - | ^^^^^^ - | | - | lifetime `'x` used here - | lifetime `'y` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:14:5 - | -LL | (i, j) - | ^^^^^^ - -error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:14:5 - | -LL | (i, j) - | ^^^^^^ - | | - | lifetime `'y` used here - | lifetime `'x` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:14:5 - | -LL | (i, j) - | ^^^^^^ - -error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:14:5 + --> $DIR/lifetime_mismatch.rs:13:5 | LL | (i, j) | ^^^^^^ @@ -69,27 +23,10 @@ LL | (i, j) | lifetime `'y` previously used here | note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:14:5 - | -LL | (i, j) - | ^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: opaque type used twice with different lifetimes - --> $DIR/lifetime_mismatch.rs:14:5 - | -LL | (i, j) - | ^^^^^^ - | | - | lifetime `'y` used here - | lifetime `'x` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/lifetime_mismatch.rs:14:5 + --> $DIR/lifetime_mismatch.rs:13:5 | LL | (i, j) | ^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs index 5bec38c5e5b2f..580fb58ef8388 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs @@ -3,11 +3,8 @@ type Foo<'a, 'b> = impl std::fmt::Debug; fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) { - (i, i) + (i, j) //~^ ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes - //~| ERROR opaque type used twice with different lifetimes } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr index 0ccb3e2221d83..b2b9e604a6b69 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr @@ -1,7 +1,7 @@ error: opaque type used twice with different lifetimes --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 | -LL | (i, i) +LL | (i, j) | ^^^^^^ | | | lifetime `'x` used here @@ -10,55 +10,8 @@ LL | (i, i) note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 | -LL | (i, i) +LL | (i, j) | ^^^^^^ -error: opaque type used twice with different lifetimes - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 - | -LL | (i, i) - | ^^^^^^ - | | - | lifetime `'y` used here - | lifetime `'x` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 - | -LL | (i, i) - | ^^^^^^ - -error: opaque type used twice with different lifetimes - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 - | -LL | (i, i) - | ^^^^^^ - | | - | lifetime `'x` used here - | lifetime `'y` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 - | -LL | (i, i) - | ^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: opaque type used twice with different lifetimes - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 - | -LL | (i, i) - | ^^^^^^ - | | - | lifetime `'y` used here - | lifetime `'x` previously used here - | -note: if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types - --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5 - | -LL | (i, i) - | ^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error From fb35156bb567417121e8e93ebd93a0fd13bce732 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 28 Mar 2024 06:07:50 +0000 Subject: [PATCH 48/50] fixup except equal params from --- tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs index 6e3f72a1ebe44..0ce85a4d6cbe1 100644 --- a/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs +++ b/tests/ui/type-alias-impl-trait/equal-lifetime-params-ok.rs @@ -1,4 +1,6 @@ -// FIXME: description +// Normally we do not allow equal lifetimes in opaque type generic args at +// their defining sites. An exception to this rule, however, is when the bounds +// of the opaque type *require* the lifetimes to be equal. // issue: #113916 //@ check-pass From 59c217fed2bc74f3685bf3461674f6b3c7e113c3 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 28 Mar 2024 06:11:09 +0000 Subject: [PATCH 49/50] remove test FIXME re once-module-region --- ...efining-use-captured-non-universal-region.infer.stderr | 2 +- .../defining-use-captured-non-universal-region.rs | 1 - ...fining-use-captured-non-universal-region.statik.stderr | 2 +- tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs | 1 - .../ui/impl-trait/rpit/non-defining-use-lifetimes.stderr | 8 ++++---- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr index 2cb82bf771c44..ded9a92d8e8c4 100644 --- a/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.infer.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/defining-use-captured-non-universal-region.rs:14:18 + --> $DIR/defining-use-captured-non-universal-region.rs:13:18 | LL | fn foo<'a>() -> impl Sized + 'a { | -- this generic parameter must be used with a generic lifetime parameter diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs index 2d54804f1fa62..e18302dc061a3 100644 --- a/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.rs @@ -1,5 +1,4 @@ // This was an ICE. See #110726. -// FIXME(aliemjay): outdated due to "once modulo regions" restriction. //@ revisions: statik infer fixed //@ [fixed] check-pass diff --git a/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr index 0d9b7df225771..43beb29f9ec46 100644 --- a/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr +++ b/tests/ui/impl-trait/defining-use-captured-non-universal-region.statik.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/defining-use-captured-non-universal-region.rs:10:18 + --> $DIR/defining-use-captured-non-universal-region.rs:9:18 | LL | fn foo<'a>() -> impl Sized + 'a { | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs index cad41d2f2edff..5e04e6b091adc 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.rs @@ -1,5 +1,4 @@ // issue: #111935 -// FIXME(aliemjay): outdated due to "once modulo regions" restriction. #![allow(unconditional_recursion)] diff --git a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr index 7ef96a2e59575..d2a224601fbe6 100644 --- a/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr +++ b/tests/ui/impl-trait/rpit/non-defining-use-lifetimes.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/non-defining-use-lifetimes.rs:14:16 + --> $DIR/non-defining-use-lifetimes.rs:13:16 | LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type @@ -7,7 +7,7 @@ LL | let _: () = foo(Lt::<'static>::None); | ^^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/non-defining-use-lifetimes.rs:23:16 + --> $DIR/non-defining-use-lifetimes.rs:22:16 | LL | fn foo<'a>(_: Lt<'a>) -> impl Sized + 'a { | -- this generic parameter must be used with a generic lifetime parameter @@ -15,13 +15,13 @@ LL | let _: () = foo(Lt::<'_>::None); | ^^ error: non-defining opaque type use in defining scope - --> $DIR/non-defining-use-lifetimes.rs:33:16 + --> $DIR/non-defining-use-lifetimes.rs:32:16 | LL | let _: () = foo(Lt::<'a>::None, Lt::<'a>::None); | ^^ | note: lifetime used multiple times - --> $DIR/non-defining-use-lifetimes.rs:32:58 + --> $DIR/non-defining-use-lifetimes.rs:31:58 | LL | fn foo<'a, 'b>(_: Lt<'a>, _: Lt<'b>) -> impl Sized + 'a + 'b { | ^^ ^^ From 89a36c03850a404d8d3a4b869cb85293e1f9a978 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 26 Mar 2024 11:53:50 +0100 Subject: [PATCH 50/50] fmt --- src/tools/miri/src/concurrency/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index e2e18d3a7344f..d0d73bb1b34c0 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -1046,7 +1046,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program /// termination). fn run_threads(&mut self) -> InterpResult<'tcx, !> { - let this = self.eval_context_mut(); + let this = self.eval_context_mut(); loop { if CTRL_C_RECEIVED.load(Relaxed) { this.machine.handle_abnormal_termination();