From d3f1618a73d3f14bfdd28d62c1d933755ccbad3e Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 14 Jun 2024 12:02:45 +0200 Subject: [PATCH 01/11] fix python bootstrap tests requiring a downloaded stage0 --- src/bootstrap/bootstrap_test.py | 19 +++++++++++++++++++ src/bootstrap/src/core/build_steps/test.rs | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 6da410ed2f27..706f2c5bf070 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -138,6 +138,25 @@ def build_args(self, configure_args=None, args=None, env=None): if env is None: env = {} + # This test ends up invoking build_bootstrap_cmd, which searches for + # the Cargo binary and errors out if it cannot be found. This is not a + # problem in most cases, but there is a scenario where it would cause + # the test to fail. + # + # When a custom local Cargo is configured in config.toml (with the + # build.cargo setting), no Cargo is downloaded to any location known by + # bootstrap, and bootstrap relies on that setting to find it. + # + # In this test though we are not using the config.toml of the caller: + # we are generating a blank one instead. If we don't set build.cargo in + # it, the test will have no way to find Cargo, failing the test. + cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN") + if cargo_bin is not None: + configure_args += ["--set", "build.cargo=" + cargo_bin] + rustc_bin = os.environ.get("BOOTSTRAP_TEST_RUSTC_BIN") + if rustc_bin is not None: + configure_args += ["--set", "build.rustc=" + rustc_bin] + env = env.copy() env["PATH"] = os.environ["PATH"] diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 29cd90222b25..22a3f1efa299 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3040,6 +3040,8 @@ impl Step for Bootstrap { .args(["-m", "unittest", "bootstrap_test.py"]) .env("BUILD_DIR", &builder.out) .env("BUILD_PLATFORM", builder.build.build.triple) + .env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc) + .env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo) .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. From fcb6ff5171fd41c988a6c449f76ff34c2c2d5a43 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 14 Jun 2024 12:34:22 +0200 Subject: [PATCH 02/11] fix rust bootstrap tests requiring a downloaded stage0 --- src/bootstrap/src/core/config/config.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 36b44d0169c9..6664c5b451c8 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1189,7 +1189,19 @@ impl Config { pub fn parse(args: &[String]) -> Config { #[cfg(test)] fn get_toml(_: &Path) -> TomlConfig { - TomlConfig::default() + let mut default = TomlConfig::default(); + + // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the + // same ones used to call the tests. If we don't do that, bootstrap will use its own + // detection logic to find a suitable rustc and Cargo, which doesn't work when the + // caller is specìfying a custom local rustc or Cargo in their config.toml. + default.build = Some(Build { + rustc: std::env::var_os("RUSTC").map(|v| v.into()), + cargo: std::env::var_os("CARGO").map(|v| v.into()), + ..Build::default() + }); + + default } #[cfg(not(test))] From 198c809dd1b06d398c44f570c9635af640895ce9 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 8 Jul 2024 15:16:28 +0200 Subject: [PATCH 03/11] set the correct executable for initial_{rustc,cargo} Due to the way the paths initial_rustc and initial_cargo were constructed before this commit, they mixed \ and / for path separators and they omitted the .exe suffix. This worked fine up until now, as Windows is capable of handling the mixed path separators and the Command::new API adds the ".exe" suffix if missing from the executable. This resulted in paths that didn't actually exist on disk though, due to the missing .exe suffix. This commit fixes that by adding the .exe suffix to initial_rustc and initial_cargo when --build is Windows. --- src/bootstrap/src/core/config/config.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 6664c5b451c8..882bae8aeb6a 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1452,6 +1452,11 @@ impl Config { config.out = crate::utils::helpers::absolute(&config.out); } + // Hacky way to determine the executable suffix for the build target. We cannot use + // std::env::consts::EXE_SUFFIX as the build target might not be the target bootstrap was + // compiled with. + let initial_exe_suffix = if config.build.triple.contains("windows") { ".exe" } else { "" }; + config.initial_rustc = if let Some(rustc) = rustc { if !flags.skip_stage0_validation { config.check_stage0_version(&rustc, "rustc"); @@ -1459,7 +1464,12 @@ impl Config { rustc } else { config.download_beta_toolchain(); - config.out.join(config.build.triple).join("stage0/bin/rustc") + config + .out + .join(config.build.triple) + .join("stage0") + .join("bin") + .join(format!("rustc{initial_exe_suffix}")) }; config.initial_cargo = if let Some(cargo) = cargo { @@ -1469,7 +1479,12 @@ impl Config { cargo } else { config.download_beta_toolchain(); - config.out.join(config.build.triple).join("stage0/bin/cargo") + config + .out + .join(config.build.triple) + .join("stage0") + .join("bin") + .join(format!("cargo{initial_exe_suffix}")) }; // NOTE: it's important this comes *after* we set `initial_rustc` just above. From b4b2643c111714b541db1c18c178ad0ce654238b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 8 Jul 2024 17:24:28 +0200 Subject: [PATCH 04/11] set the correct rustc and cargo even for tests invoking parse_inner --- src/bootstrap/src/core/config/config.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 882bae8aeb6a..458120fd2027 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1189,19 +1189,7 @@ impl Config { pub fn parse(args: &[String]) -> Config { #[cfg(test)] fn get_toml(_: &Path) -> TomlConfig { - let mut default = TomlConfig::default(); - - // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the - // same ones used to call the tests. If we don't do that, bootstrap will use its own - // detection logic to find a suitable rustc and Cargo, which doesn't work when the - // caller is specìfying a custom local rustc or Cargo in their config.toml. - default.build = Some(Build { - rustc: std::env::var_os("RUSTC").map(|v| v.into()), - cargo: std::env::var_os("CARGO").map(|v| v.into()), - ..Build::default() - }); - - default + TomlConfig::default() } #[cfg(not(test))] @@ -1341,6 +1329,17 @@ impl Config { TomlConfig::default() }; + if cfg!(test) { + // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the + // same ones used to call the tests (if custom ones are not defined in the toml). If we + // don't do that, bootstrap will use its own detection logic to find a suitable rustc + // and Cargo, which doesn't work when the caller is specìfying a custom local rustc or + // Cargo in their config.toml. + let build = toml.build.get_or_insert_with(Default::default); + build.rustc = build.rustc.take().or(std::env::var_os("RUSTC").map(|p| p.into())); + build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); + } + if let Some(include) = &toml.profile { // Allows creating alias for profile names, allowing // profiles to be renamed while maintaining back compatibility From af3aa36d60746f8fac262cd5a3d32f23d60f36ea Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 10 Jul 2024 01:00:55 +0200 Subject: [PATCH 05/11] do not run test where it cannot run This was seen on Ferrocene, where we have a custom test target that does not have unwind support --- library/alloc/src/slice/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/slice/tests.rs b/library/alloc/src/slice/tests.rs index 0156b9928dab..0b972a13898e 100644 --- a/library/alloc/src/slice/tests.rs +++ b/library/alloc/src/slice/tests.rs @@ -240,6 +240,7 @@ fn panic_safe() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_sort() { let mut rng = test_rng(); From 7c88bda1cb9a454ebce2f84ce188e950272a12c0 Mon Sep 17 00:00:00 2001 From: Ashton Hunt Date: Tue, 9 Jul 2024 17:21:31 -0600 Subject: [PATCH 06/11] E0191 suggestion correction, inserts turbofish without dyn (#91997) --- .../src/hir_ty_lowering/errors.rs | 14 ++++++++++- .../dynless-turbofish-e0191-issue-91997.rs | 8 +++++++ ...dynless-turbofish-e0191-issue-91997.stderr | 23 +++++++++++++++++++ tests/ui/issues/issue-23024.stderr | 2 +- tests/ui/issues/issue-28344.stderr | 4 ++-- 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs create mode 100644 tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 2d240699105d..21613a98e219 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -12,9 +12,9 @@ use rustc_errors::MultiSpan; use rustc_errors::{ codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, }; -use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{self as hir, Node}; use rustc_middle::bug; use rustc_middle::query::Key; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; @@ -745,7 +745,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if object_safety_violations { return; } + + // related to issue #91997, turbofishes added only when in an expr or pat + let mut in_expr_or_pat = false; if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) { + let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id)); + in_expr_or_pat = match grandparent { + Node::Expr(_) | Node::Pat(_) => true, + _ => false, + }; match bound.trait_ref.path.segments { // FIXME: `trait_ref.path.span` can point to a full path with multiple // segments, even though `trait_ref.path.segments` is of length `1`. Work @@ -901,6 +909,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the // suggestion. format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", ")) + } else if in_expr_or_pat { + // The user wrote `Iterator`, so we don't have a type we can suggest, but at + // least we can clue them to the correct syntax `Iterator::`. + format!("{}::<{}>", snippet, types.join(", ")) } else { // The user wrote `Iterator`, so we don't have a type we can suggest, but at // least we can clue them to the correct syntax `Iterator`. diff --git a/tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs new file mode 100644 index 000000000000..69a4c13530bd --- /dev/null +++ b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs @@ -0,0 +1,8 @@ +trait MyIterator : Iterator {} + +fn main() { + let _ = MyIterator::next; +} +//~^^ ERROR the value of the associated type `Item` in `Iterator` must be specified [E0191] +//~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] +//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! diff --git a/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr new file mode 100644 index 000000000000..68d8adc5a401 --- /dev/null +++ b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr @@ -0,0 +1,23 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/dynless-turbofish-e0191-issue-91997.rs:4:13 + | +LL | let _ = MyIterator::next; + | ^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is an object-safe trait, use `dyn` + | +LL | let _ = ::next; + | ++++ + + +error[E0191]: the value of the associated type `Item` in `Iterator` must be specified + --> $DIR/dynless-turbofish-e0191-issue-91997.rs:4:13 + | +LL | let _ = MyIterator::next; + | ^^^^^^^^^^ help: specify the associated type: `MyIterator::` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/issues/issue-23024.stderr b/tests/ui/issues/issue-23024.stderr index 1672622d8b72..62278a51be63 100644 --- a/tests/ui/issues/issue-23024.stderr +++ b/tests/ui/issues/issue-23024.stderr @@ -23,7 +23,7 @@ error[E0191]: the value of the associated type `Output` in `FnOnce` must be spec --> $DIR/issue-23024.rs:8:39 | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); - | ^^ help: specify the associated type: `Fn` + | ^^ help: specify the associated type: `Fn::` error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr index d30fb3cfe58a..b7e0790f6796 100644 --- a/tests/ui/issues/issue-28344.stderr +++ b/tests/ui/issues/issue-28344.stderr @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` in `BitXor` must be spec --> $DIR/issue-28344.rs:4:17 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^ help: specify the associated type: `BitXor` + | ^^^^^^ help: specify the associated type: `BitXor::` error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope --> $DIR/issue-28344.rs:4:25 @@ -44,7 +44,7 @@ error[E0191]: the value of the associated type `Output` in `BitXor` must be spec --> $DIR/issue-28344.rs:10:13 | LL | let g = BitXor::bitor; - | ^^^^^^ help: specify the associated type: `BitXor` + | ^^^^^^ help: specify the associated type: `BitXor::` error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope --> $DIR/issue-28344.rs:10:21 From 9cd1d253a60aca27086da57b68c24b0924277d58 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 10 Jul 2024 09:27:30 +0200 Subject: [PATCH 07/11] use utils::helpers::exe --- src/bootstrap/src/core/config/config.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 458120fd2027..00acd3dabecb 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1451,11 +1451,6 @@ impl Config { config.out = crate::utils::helpers::absolute(&config.out); } - // Hacky way to determine the executable suffix for the build target. We cannot use - // std::env::consts::EXE_SUFFIX as the build target might not be the target bootstrap was - // compiled with. - let initial_exe_suffix = if config.build.triple.contains("windows") { ".exe" } else { "" }; - config.initial_rustc = if let Some(rustc) = rustc { if !flags.skip_stage0_validation { config.check_stage0_version(&rustc, "rustc"); @@ -1468,7 +1463,7 @@ impl Config { .join(config.build.triple) .join("stage0") .join("bin") - .join(format!("rustc{initial_exe_suffix}")) + .join(exe("rustc", config.build)) }; config.initial_cargo = if let Some(cargo) = cargo { @@ -1483,7 +1478,7 @@ impl Config { .join(config.build.triple) .join("stage0") .join("bin") - .join(format!("cargo{initial_exe_suffix}")) + .join(exe("cargo", config.build)) }; // NOTE: it's important this comes *after* we set `initial_rustc` just above. From c8e44471b823116fab9849667f80811104e26ef4 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 10 Jul 2024 11:56:56 +0200 Subject: [PATCH 08/11] Temporarily remove me from review rotation. --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 8767eb138a19..77b3db8a0109 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -941,7 +941,6 @@ compiler = [ libs = [ "@cuviper", "@Mark-Simulacrum", - "@m-ou-se", "@Amanieu", "@Nilstrieb", "@workingjubilee", From f77394fdf3f45188d3f110f72f31c4233d4d38eb Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 10 Jul 2024 14:13:16 +0200 Subject: [PATCH 09/11] instantiate higher ranked goals in candidate selection reverts #119820 --- .../src/traits/select/mod.rs | 66 ++++--------------- ...didate-from-env-universe-err-1.next.stderr | 23 +++++++ .../candidate-from-env-universe-err-1.rs | 7 +- .../candidate-from-env-universe-err-1.stderr | 26 -------- ...ate-from-env-universe-err-2.current.stderr | 25 ------- ...didate-from-env-universe-err-2.next.stderr | 4 +- ...ndidate-from-env-universe-err-2.old.stderr | 26 -------- .../candidate-from-env-universe-err-2.rs | 3 +- ...om-env-universe-err-project.current.stderr | 26 ++------ ...-from-env-universe-err-project.next.stderr | 8 +-- ...candidate-from-env-universe-err-project.rs | 8 +-- .../leak-check-in-selection-2.next.stderr | 6 +- .../leak-check-in-selection-2.old.stderr | 23 ------- .../leak-check/leak-check-in-selection-2.rs | 3 +- .../leak-check-in-selection-3.old.stderr | 21 +----- .../leak-check/leak-check-in-selection-3.rs | 6 +- ...igher-ranker-supertraits-transitive.stderr | 22 +++++-- .../hrtb-higher-ranker-supertraits.rs | 6 +- .../hrtb-higher-ranker-supertraits.stderr | 59 +++++++---------- tests/ui/implied-bounds/issue-100690.rs | 5 +- tests/ui/implied-bounds/issue-100690.stderr | 47 ++++--------- 21 files changed, 121 insertions(+), 299 deletions(-) create mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2c4ffdabf140..7a93f59f1639 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -64,20 +64,6 @@ mod _match; mod candidate_assembly; mod confirmation; -/// Whether to consider the binder of higher ranked goals for the `leak_check` when -/// evaluating higher-ranked goals. See #119820 for more info. -/// -/// While this is a bit hacky, it is necessary to match the behavior of the new solver: -/// We eagerly instantiate binders in the new solver, outside of candidate selection, so -/// the leak check inside of candidates does not consider any bound vars from the higher -/// ranked goal. However, we do exit the binder once we're completely finished with a goal, -/// so the leak-check can be used in evaluate by causing nested higher-ranked goals to fail. -#[derive(Debug, Copy, Clone)] -enum LeakCheckHigherRankedGoal { - No, - Yes, -} - #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub enum IntercrateAmbiguityCause<'tcx> { DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option> }, @@ -402,10 +388,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut no_candidates_apply = true; for c in candidate_set.vec.iter() { - if self - .evaluate_candidate(stack, c, LeakCheckHigherRankedGoal::No)? - .may_apply() - { + if self.evaluate_candidate(stack, c)?.may_apply() { no_candidates_apply = false; break; } @@ -476,7 +459,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // is needed for specialization. Propagate overflow if it occurs. let mut candidates = candidates .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::No) { + .map(|c| match self.evaluate_candidate(stack, &c) { Ok(eval) if eval.may_apply() => { Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) } @@ -566,7 +549,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result { debug_assert!(!self.infcx.next_trait_solver()); - self.evaluation_probe(|this, _outer_universe| { + self.evaluation_probe(|this| { let goal = this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env)); let mut result = this.evaluate_predicate_recursively( @@ -589,11 +572,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// `op`, but this can be overwritten if necessary. fn evaluation_probe( &mut self, - op: impl FnOnce(&mut Self, &mut ty::UniverseIndex) -> Result, + op: impl FnOnce(&mut Self) -> Result, ) -> Result { self.infcx.probe(|snapshot| -> Result { - let mut outer_universe = self.infcx.universe(); - let result = op(self, &mut outer_universe)?; + let outer_universe = self.infcx.universe(); + let result = op(self)?; match self.infcx.leak_check(outer_universe, Some(snapshot)) { Ok(()) => {} @@ -1254,7 +1237,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.candidate_from_obligation(stack) { - Ok(Some(c)) => self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::Yes), + Ok(Some(c)) => self.evaluate_candidate(stack, &c), Ok(None) => Ok(EvaluatedToAmbig), Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical), Err(..) => Ok(EvaluatedToErr), @@ -1279,10 +1262,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Further evaluates `candidate` to decide whether all type parameters match and whether nested /// obligations are met. Returns whether `candidate` remains viable after this further /// scrutiny. - /// - /// Depending on the value of [LeakCheckHigherRankedGoal], we may ignore the binder of the goal - /// when eagerly detecting higher ranked region errors via the `leak_check`. See that enum for - /// more info. #[instrument( level = "debug", skip(self, stack), @@ -1293,25 +1272,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidate: &SelectionCandidate<'tcx>, - leak_check_higher_ranked_goal: LeakCheckHigherRankedGoal, ) -> Result { - let mut result = self.evaluation_probe(|this, outer_universe| { - // We eagerly instantiate higher ranked goals to prevent universe errors - // from impacting candidate selection. This matches the behavior of the new - // solver. This slightly weakens type inference. - // - // In case there are no unresolved type or const variables this - // should still not be necessary to select a unique impl as any overlap - // relying on a universe error from higher ranked goals should have resulted - // in an overlap error in coherence. - let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate); - let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p)); - match leak_check_higher_ranked_goal { - LeakCheckHigherRankedGoal::No => *outer_universe = self.infcx.universe(), - LeakCheckHigherRankedGoal::Yes => {} - } - - match this.confirm_candidate(&obligation, candidate.clone()) { + let mut result = self.evaluation_probe(|this| { + match this.confirm_candidate(stack.obligation, candidate.clone()) { Ok(selection) => { debug!(?selection); this.evaluate_predicates_recursively( @@ -1731,19 +1694,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .map_err(|_| ()) } + fn where_clause_may_apply<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result { - self.evaluation_probe(|this, outer_universe| { - // Eagerly instantiate higher ranked goals. - // - // See the comment in `evaluate_candidate` to see why. - let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate); - let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p)); - *outer_universe = self.infcx.universe(); - match this.match_where_clause_trait_ref(&obligation, where_clause_trait_ref) { + self.evaluation_probe(|this| { + match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations), Err(()) => Ok(EvaluatedToErr), } diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr new file mode 100644 index 000000000000..90391b7b86b5 --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied + --> $DIR/candidate-from-env-universe-err-1.rs:27:16 + | +LL | hr_bound::<&T>(); + | ^^ the trait `for<'a> Trait` is not implemented for `&'a &T` + | +note: required by a bound in `hr_bound` + --> $DIR/candidate-from-env-universe-err-1.rs:14:20 + | +LL | fn hr_bound() + | -------- required by a bound in this function +LL | where +LL | for<'a> &'a T: Trait, + | ^^^^^ required by this bound in `hr_bound` +help: consider removing the leading `&`-reference + | +LL - hr_bound::<&T>(); +LL + hr_bound::(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs index b448f0bdc777..bd251216162d 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs @@ -1,3 +1,7 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@[old] check-pass + // cc #119820 trait Trait {} @@ -21,8 +25,7 @@ where // the leak check both candidates may apply and we prefer the // `param_env` candidate in winnowing. hr_bound::<&T>(); - //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR implementation of `Trait` is not general enough + //[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr deleted file mode 100644 index febe252d7d1d..000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/candidate-from-env-universe-err-1.rs:23:5 - | -LL | hr_bound::<&T>(); - | ^^^^^^^^^^^^^^ - | | - | the parameter type `T` must be valid for the static lifetime... - | ...so that the type `T` will meet its required lifetime bounds - | -help: consider adding an explicit lifetime bound - | -LL | T: Trait + 'static, - | +++++++++ - -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-1.rs:23:5 - | -LL | hr_bound::<&T>(); - | ^^^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `Trait` would have to be implemented for the type `&'0 &T`, for any lifetime `'0`... - = note: ...but `Trait` is actually implemented for the type `&'1 &'1 T`, for some specific lifetime `'1` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr deleted file mode 100644 index 22ce87c02486..000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { - | -- lifetime `'a` defined here -LL | impl_hr::(); - | ^^^^^^^^^^^^ requires that `'a` must outlive `'static` - | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/candidate-from-env-universe-err-2.rs:11:19 - | -LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} - | ^^^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | impl_hr::(); - | ^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `T` must implement `Trait<'0, '_>`, for any lifetime `'0`... - = note: ...but it actually implements `Trait<'1, '_>`, for some specific lifetime `'1` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr index a61bc748bea2..8771de85c192 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 + --> $DIR/candidate-from-env-universe-err-2.rs:15:5 | LL | impl_hr::(); | ^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T` | note: required by a bound in `impl_hr` - --> $DIR/candidate-from-env-universe-err-2.rs:11:19 + --> $DIR/candidate-from-env-universe-err-2.rs:12:19 | LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr` diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr deleted file mode 100644 index 29a72b1c1b64..000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { - | -- lifetime `'a` defined here -LL | impl_hr::(); - | ^^^^^^^^^^^^ requires that `'a` must outlive `'static` - | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/candidate-from-env-universe-err-2.rs:11:19 - | -LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} - | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | impl_hr::(); - | ^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> Trait<'a, '_>` - found trait `for<'b> Trait<'_, 'b>` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs index 56fa70469ccf..0132b7db6057 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs @@ -1,5 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass // cc #119820 @@ -13,8 +14,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { impl_hr::(); //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied - //[current]~^^ERROR lifetime may not live long enough - //[current]~| ERROR implementation of `Trait` is not general enough } fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr index bb0b2de788e8..7b9fd6bb4c57 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr @@ -1,23 +1,5 @@ -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-project.rs:28:5 - | -LL | trait_bound::(); - | ^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `T` must implement `Trait<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Trait<'static>` - -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-project.rs:39:5 - | -LL | projection_bound::(); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `T` must implement `Trait<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Trait<'static>` - error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:39:5 + --> $DIR/candidate-from-env-universe-err-project.rs:38:5 | LL | projection_bound::(); | ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -31,7 +13,7 @@ LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -40,7 +22,7 @@ LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); found associated type `>::Assoc` error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -49,6 +31,6 @@ LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); found associated type `>::Assoc` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr index 2804d5bbe940..90df487c07e7 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr @@ -15,7 +15,7 @@ LL | fn function1 + for<'a> Trait<'a>>() { | +++++++++++++++++++ error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied - --> $DIR/candidate-from-env-universe-err-project.rs:39:24 + --> $DIR/candidate-from-env-universe-err-project.rs:38:24 | LL | projection_bound::(); | ^ the trait `for<'a> Trait<'a>` is not implemented for `T` @@ -31,7 +31,7 @@ LL | fn function2 + for<'a> Trait<'a>>() { | +++++++++++++++++++ error[E0271]: type mismatch resolving `>::Assoc == usize` - --> $DIR/candidate-from-env-universe-err-project.rs:39:24 + --> $DIR/candidate-from-env-universe-err-project.rs:38:24 | LL | projection_bound::(); | ^ type mismatch resolving `>::Assoc == usize` @@ -48,13 +48,13 @@ LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^ required by this bound in `projection_bound` error: higher-ranked subtype error - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs index e0d2e44e6e7d..a77d87f6fa78 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs @@ -1,8 +1,8 @@ //@ revisions: next current //@[next] compile-flags: -Znext-solver -// cc #119820 the previous behavior here was inconsistent as we discarded -// the where-bound candidate for trait goals due to the leak check, but did +// cc #119820 the behavior is inconsistent as we discard the where-bound +// candidate for trait goals due to the leak check, but did // not do so for projection candidates and during normalization. // // This results in an inconsistency between `Trait` and `Projection` goals as @@ -27,7 +27,6 @@ fn function1>() { // We prefer env candidates over impl candidatescausing this to succeed. trait_bound::(); //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied - //[current]~^^ ERROR implementation of `Trait` is not general enough } fn function2>() { @@ -39,8 +38,7 @@ fn function2>() { projection_bound::(); //[next]~^ ERROR type mismatch resolving `>::Assoc == usize` //[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied - //[current]~^^^ ERROR implementation of `Trait` is not general enough - //[current]~| ERROR mismatched types + //[current]~^^^ ERROR mismatched types } fn function3>() { diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr index a840304e49c1..cb97bc4b8fc6 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-2.rs:16:5 + --> $DIR/leak-check-in-selection-2.rs:17:5 | LL | impls_trait::<(), _>(); | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` | note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found - --> $DIR/leak-check-in-selection-2.rs:9:1 + --> $DIR/leak-check-in-selection-2.rs:10:1 | LL | impl<'a> Trait<&'a str, &'a str> for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | LL | impl<'a> Trait<&'a str, String> for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-2.rs:13:19 + --> $DIR/leak-check-in-selection-2.rs:14:19 | LL | fn impls_trait Trait<&'a str, U>, U>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait` diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr deleted file mode 100644 index a840304e49c1..000000000000 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-2.rs:16:5 - | -LL | impls_trait::<(), _>(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` - | -note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found - --> $DIR/leak-check-in-selection-2.rs:9:1 - | -LL | impl<'a> Trait<&'a str, &'a str> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | impl<'a> Trait<&'a str, String> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-2.rs:13:19 - | -LL | fn impls_trait Trait<&'a str, U>, U>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs index 48dd569f201b..24e38ec45a2c 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs @@ -1,5 +1,6 @@ //@ revisions: old next //@[next] compile-flags: -Znext-solver +//@[old] check-pass // cc #119820 @@ -14,5 +15,5 @@ fn impls_trait Trait<&'a str, U>, U>() {} fn main() { impls_trait::<(), _>(); - //~^ ERROR type annotations needed + //[next]~^ ERROR type annotations needed } diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr index 662a06537401..194571dd4a85 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr @@ -1,22 +1,3 @@ -error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-3.rs:18:5 - | -LL | impls_leak::>(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak` - | -note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found - --> $DIR/leak-check-in-selection-3.rs:9:1 - | -LL | impl Leak<'_> for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | impl Leak<'static> for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `impls_leak` - --> $DIR/leak-check-in-selection-3.rs:12:18 - | -LL | fn impls_leak Leak<'a>>() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak` - error[E0283]: type annotations needed --> $DIR/leak-check-in-selection-3.rs:35:5 | @@ -43,6 +24,6 @@ note: required by a bound in `impls_indirect_leak` LL | fn impls_indirect_leak IndirectLeak<'a>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs index 9e99b6c527d9..9aa1be57a4fb 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs @@ -1,9 +1,9 @@ //@ revisions: old next //@[next] compile-flags: -Znext-solver -// cc #119820, the previous behavior here was inconsistent, +// cc #119820, the behavior here is inconsistent, // using the leak check to guide inference for `for<'a> Box<_>: Leak<'a>` -// but not for `for<'a> Box<_>: IndirectLeak<'a>` +// but not for `for<'a> Box<_>: IndirectLeak<'a>`. trait Leak<'a> {} impl Leak<'_> for Box {} @@ -16,7 +16,7 @@ fn direct() { // The `Box` impls fails the leak check, // meaning that we apply the `Box` impl. impls_leak::>(); - //~^ ERROR type annotations needed + //[next]~^ ERROR type annotations needed } trait IndirectLeak<'a> {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr index be19bf85bd2f..e10da26665eb 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr @@ -1,11 +1,23 @@ -error: implementation of `Bar` is not general enough - --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5 +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26 | LL | want_bar_for_any_ccx(b); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough + | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | | + | required by a bound introduced by this call | - = note: `B` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'static>` +note: required by a bound in `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15 + | +LL | fn want_bar_for_any_ccx(b: &B) + | -------------------- required by a bound in this function +LL | where B : for<'ccx> Bar<'ccx> + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` +help: consider further restricting this bound + | +LL | where B : Qux + for<'ccx> Bar<'ccx> + | +++++++++++++++++++++ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs index 70ce580258d4..7e2ecc937bd0 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs @@ -12,8 +12,7 @@ trait Bar<'ccx>: for<'tcx> Foo<'tcx> { fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) { want_foo_for_some_tcx(f); want_foo_for_any_tcx(f); - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `Foo` is not general enough + //~^ ERROR the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied } fn want_foo_for_any_tcx Foo<'tcx>>(f: &F) { @@ -27,8 +26,7 @@ fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) { want_bar_for_some_ccx(b); want_bar_for_any_ccx(b); - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `Bar` is not general enough + //~^ ERROR the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied } fn want_bar_for_any_ccx Bar<'ccx>>(b: &B) { diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr index dd760926ea11..af76377de850 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr @@ -1,50 +1,39 @@ -error: lifetime may not live long enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:14:5 +error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits.rs:14:26 | -LL | fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) { - | -- lifetime `'x` defined here -LL | want_foo_for_some_tcx(f); LL | want_foo_for_any_tcx(f); - | ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static` + | -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F` + | | + | required by a bound introduced by this call | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/hrtb-higher-ranker-supertraits.rs:19:28 +note: required by a bound in `want_foo_for_any_tcx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:18:28 | LL | fn want_foo_for_any_tcx Foo<'tcx>>(f: &F) { - | ^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Foo` is not general enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:14:5 - | -LL | want_foo_for_any_tcx(f); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` +help: consider further restricting this bound | - = note: `F` must implement `Foo<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1` +LL | fn want_foo_for_some_tcx<'x, F: Foo<'x> + for<'tcx> Foo<'tcx>>(f: &'x F) { + | +++++++++++++++++++++ -error: lifetime may not live long enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:29:5 +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits.rs:28:26 | -LL | fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) { - | -- lifetime `'x` defined here -... LL | want_bar_for_any_ccx(b); - | ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static` + | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | | + | required by a bound introduced by this call | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/hrtb-higher-ranker-supertraits.rs:34:28 +note: required by a bound in `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:32:28 | LL | fn want_bar_for_any_ccx Bar<'ccx>>(b: &B) { - | ^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Bar` is not general enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:29:5 - | -LL | want_bar_for_any_ccx(b); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` +help: consider further restricting this bound | - = note: `B` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` +LL | fn want_bar_for_some_ccx<'x, B: Bar<'x> + for<'ccx> Bar<'ccx>>(b: &B) { + | +++++++++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/implied-bounds/issue-100690.rs b/tests/ui/implied-bounds/issue-100690.rs index 041c687ec943..b0dbf749c467 100644 --- a/tests/ui/implied-bounds/issue-100690.rs +++ b/tests/ui/implied-bounds/issue-100690.rs @@ -32,10 +32,7 @@ impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandl F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static, { real_dispatch(f) - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types - // + //~^ ERROR expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F` } } diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr index 2cfd028f2559..4964dccd551d 100644 --- a/tests/ui/implied-bounds/issue-100690.stderr +++ b/tests/ui/implied-bounds/issue-100690.stderr @@ -1,41 +1,22 @@ -error: lifetime may not live long enough - --> $DIR/issue-100690.rs:34:9 +error[E0277]: expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F` + --> $DIR/issue-100690.rs:34:23 | -LL | impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle { - | -- lifetime `'a` defined here -... LL | real_dispatch(f) - | ^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + | ------------- ^ expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F` + | | + | required by a bound introduced by this call | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime + = note: expected a closure with arguments `(&mut UIView<'a, _>,)` + found a closure with arguments `(&mut UIView<'_, _>,)` +note: required by a bound in `real_dispatch` --> $DIR/issue-100690.rs:8:8 | +LL | fn real_dispatch(f: F) -> Result<(), io::Error> + | ------------- required by a bound in this function +LL | where LL | F: FnOnce(&mut UIView) -> Result<(), io::Error> + Send + 'static, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch` -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-100690.rs:34:9 - | -LL | real_dispatch(f) - | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: `F` must implement `FnOnce<(&mut UIView<'0, T>,)>`, for any lifetime `'0`... - = note: ...but it actually implements `FnOnce<(&mut UIView<'1, T>,)>`, for some specific lifetime `'1` - -error[E0308]: mismatched types - --> $DIR/issue-100690.rs:34:9 - | -LL | real_dispatch(f) - | ^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected associated type `,)>>::Output` - found associated type `,)>>::Output` -note: the lifetime requirement is introduced here - --> $DIR/issue-100690.rs:8:34 - | -LL | F: FnOnce(&mut UIView) -> Result<(), io::Error> + Send + 'static, - | ^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. From e7bd16e6c8f498af99a28e139dc4d74d8d43cbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 10 Jul 2024 14:45:14 +0200 Subject: [PATCH 10/11] Fix local download of Docker caches --- src/ci/docker/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 695b8b4c0d9e..40f421714118 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -93,7 +93,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then docker --version REGISTRY=ghcr.io - REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER} + REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER:-rust-lang-ci} # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum} # Tag used to cache the Docker build From e00fd781c91bc4b2703f25a75b0b28c775bd51b9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 10 Jul 2024 14:45:07 +0200 Subject: [PATCH 11/11] simplify and future-proof `needs_normalization` --- .../rustc_trait_selection/src/traits/normalize.rs | 13 +++++-------- compiler/rustc_type_ir/src/flags.rs | 8 ++++---- compiler/rustc_type_ir/src/visit.rs | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index dda3aaaf71e8..3a7481acbafd 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -109,16 +109,13 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( value: &T, reveal: Reveal, ) -> bool { - // This mirrors `ty::TypeFlags::HAS_ALIASES` except that we take `Reveal` into account. - - let mut flags = ty::TypeFlags::HAS_TY_PROJECTION - | ty::TypeFlags::HAS_TY_WEAK - | ty::TypeFlags::HAS_TY_INHERENT - | ty::TypeFlags::HAS_CT_PROJECTION; + let mut flags = ty::TypeFlags::HAS_ALIAS; + // Opaques are treated as rigid with `Reveal::UserFacing`, + // so we can ignore those. match reveal { - Reveal::UserFacing => {} - Reveal::All => flags |= ty::TypeFlags::HAS_TY_OPAQUE, + Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), + Reveal::All => {} } value.has_type_flags(flags) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6a1ac642b70f..81aa4a1f19ee 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -14,7 +14,7 @@ bitflags::bitflags! { /// Does this have `ConstKind::Param`? const HAS_CT_PARAM = 1 << 2; - const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits() + const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits() | TypeFlags::HAS_RE_PARAM.bits() | TypeFlags::HAS_CT_PARAM.bits(); @@ -27,7 +27,7 @@ bitflags::bitflags! { /// Does this have inference variables? Used to determine whether /// inference is required. - const HAS_INFER = TypeFlags::HAS_TY_INFER.bits() + const HAS_INFER = TypeFlags::HAS_TY_INFER.bits() | TypeFlags::HAS_RE_INFER.bits() | TypeFlags::HAS_CT_INFER.bits(); @@ -39,7 +39,7 @@ bitflags::bitflags! { const HAS_CT_PLACEHOLDER = 1 << 8; /// Does this have placeholders? - const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits() + const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits() | TypeFlags::HAS_RE_PLACEHOLDER.bits() | TypeFlags::HAS_CT_PLACEHOLDER.bits(); @@ -81,7 +81,7 @@ bitflags::bitflags! { /// Does this have `Alias` or `ConstKind::Unevaluated`? /// /// Rephrased, could this term be normalized further? - const HAS_ALIASES = TypeFlags::HAS_TY_PROJECTION.bits() + const HAS_ALIAS = TypeFlags::HAS_TY_PROJECTION.bits() | TypeFlags::HAS_TY_WEAK.bits() | TypeFlags::HAS_TY_OPAQUE.bits() | TypeFlags::HAS_TY_INHERENT.bits() diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 473a0aa250ff..25eb56fe3fb5 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -230,7 +230,7 @@ pub trait TypeVisitableExt: TypeVisitable { } fn has_aliases(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_ALIASES) + self.has_type_flags(TypeFlags::HAS_ALIAS) } fn has_inherent_projections(&self) -> bool {