From d558353f2860298fabb898923dc41c99190a5ab4 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 10 Aug 2023 12:35:34 +0200 Subject: make the provisional cache slightly less broken --- .../src/solve/search_graph/cache.rs | 32 ++++++----- .../src/solve/search_graph/mod.rs | 65 +++++++++++++--------- .../new-solver/cycles/inductive-not-on-stack.rs | 2 +- .../cycles/inductive-not-on-stack.stderr | 15 +---- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs b/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs index 56f126e9157..be48447e27c 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs @@ -19,21 +19,25 @@ rustc_index::newtype_index! { #[derive(Debug, Clone)] pub(super) struct ProvisionalEntry<'tcx> { - // In case we have a coinductive cycle, this is the - // the currently least restrictive result of this goal. - pub(super) response: QueryResult<'tcx>, - // In case of a cycle, the position of deepest stack entry involved - // in that cycle. This is monotonically decreasing in the stack as all - // elements between the current stack element in the deepest stack entry - // involved have to also be involved in that cycle. - // - // We can only move entries to the global cache once we're complete done - // with the cycle. If this entry has not been involved in a cycle, - // this is just its own depth. + /// In case we have a coinductive cycle, this is the + /// the current provisional result of this goal. + /// + /// This starts out as `None` for all goals and gets to some + /// when the goal gets popped from the stack or we rerun evaluation + /// for this goal to reach a fixpoint. + pub(super) response: Option>, + /// In case of a cycle, the position of deepest stack entry involved + /// in that cycle. This is monotonically decreasing in the stack as all + /// elements between the current stack element in the deepest stack entry + /// involved have to also be involved in that cycle. + /// + /// We can only move entries to the global cache once we're complete done + /// with the cycle. If this entry has not been involved in a cycle, + /// this is just its own depth. pub(super) depth: StackDepth, - // The goal for this entry. Should always be equal to the corresponding goal - // in the lookup table. + /// The goal for this entry. Should always be equal to the corresponding goal + /// in the lookup table. pub(super) input: CanonicalInput<'tcx>, } @@ -92,7 +96,7 @@ impl<'tcx> ProvisionalCache<'tcx> { self.entries[entry_index].depth } - pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> QueryResult<'tcx> { + pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> Option> { self.entries[entry_index].response } } diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 21c8d476902..b860f374c0a 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -13,7 +13,7 @@ use rustc_middle::traits::solve::CacheData; use rustc_middle::traits::solve::{CanonicalInput, Certainty, EvaluationCache, QueryResult}; use rustc_middle::ty::TyCtxt; use rustc_session::Limit; -use std::{collections::hash_map::Entry, mem}; +use std::collections::hash_map::Entry; rustc_index::newtype_index! { pub struct StackDepth {} @@ -216,8 +216,8 @@ impl<'tcx> SearchGraph<'tcx> { cycle_participants: Default::default(), }; assert_eq!(self.stack.push(entry), depth); - let response = Self::response_no_constraints(tcx, input, Certainty::Yes); - let entry_index = cache.entries.push(ProvisionalEntry { response, depth, input }); + let entry_index = + cache.entries.push(ProvisionalEntry { response: None, depth, input }); v.insert(entry_index); } // We have a nested goal which relies on a goal `root` deeper in the stack. @@ -243,23 +243,31 @@ impl<'tcx> SearchGraph<'tcx> { root.cycle_participants.insert(e.input); } - // NOTE: The goals on the stack aren't the only goals involved in this cycle. - // We can also depend on goals which aren't part of the stack but coinductively - // depend on the stack themselves. We already checked whether all the goals - // between these goals and their root on the stack. This means that as long as - // each goal in a cycle is checked for coinductivity by itself, simply checking - // the stack is enough. - if self.stack.raw[stack_depth.index()..] - .iter() - .all(|g| g.input.value.goal.predicate.is_coinductive(tcx)) - { - // If we're in a coinductive cycle, we have to retry proving the current goal - // until we reach a fixpoint. - self.stack[stack_depth].has_been_used = true; - return cache.provisional_result(entry_index); + // If we're in a cycle, we have to retry proving the current goal + // until we reach a fixpoint. + self.stack[stack_depth].has_been_used = true; + return if let Some(result) = cache.provisional_result(entry_index) { + result } else { - return Self::response_no_constraints(tcx, input, Certainty::OVERFLOW); - } + // If we don't have a provisional result yet, the goal has to + // still be on the stack. + let mut goal_on_stack = false; + let mut is_coinductive = true; + for entry in self.stack.raw[stack_depth.index()..] + .iter() + .skip_while(|entry| entry.input != input) + { + goal_on_stack = true; + is_coinductive &= entry.input.value.goal.predicate.is_coinductive(tcx); + } + debug_assert!(goal_on_stack); + + if is_coinductive { + Self::response_no_constraints(tcx, input, Certainty::Yes) + } else { + Self::response_no_constraints(tcx, input, Certainty::OVERFLOW) + } + }; } } @@ -288,15 +296,18 @@ impl<'tcx> SearchGraph<'tcx> { let provisional_entry_index = *cache.lookup_table.get(&stack_entry.input).unwrap(); let provisional_entry = &mut cache.entries[provisional_entry_index]; - let prev_response = mem::replace(&mut provisional_entry.response, response); - if stack_entry.has_been_used && prev_response != response { - // If so, remove all entries whose result depends on this goal - // from the provisional cache... + if stack_entry.has_been_used + && provisional_entry.response.map_or(true, |r| r != response) + { + // If so, update the provisional result for this goal and remove + // all entries whose result depends on this goal from the provisional + // cache... // - // That's not completely correct, as a nested goal can also + // That's not completely correct, as a nested goal can also only // depend on a goal which is lower in the stack so it doesn't // actually depend on the current goal. This should be fairly // rare and is hopefully not relevant for performance. + provisional_entry.response = Some(response); #[allow(rustc::potential_query_instability)] cache.lookup_table.retain(|_key, index| *index <= provisional_entry_index); cache.entries.truncate(provisional_entry_index.index() + 1); @@ -315,8 +326,8 @@ impl<'tcx> SearchGraph<'tcx> { }); // We're now done with this goal. In case this goal is involved in a larger cycle - // do not remove it from the provisional cache and do not add it to the global - // cache. + // do not remove it from the provisional cache and update its provisional result. + // We only add the root of cycles to the global cache. // // It is not possible for any nested goal to depend on something deeper on the // stack, as this would have also updated the depth of the current goal. @@ -348,6 +359,8 @@ impl<'tcx> SearchGraph<'tcx> { dep_node, result, ) + } else { + provisional_entry.response = Some(result); } result diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs index f06b98a79cf..3cfe7ab87f6 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs @@ -39,7 +39,7 @@ fn impls_ar() {} fn main() { impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` + // FIXME(-Ztrait-solver=next): This is broken and should error. impls_ar::<()>(); //~^ ERROR overflow evaluating the requirement `(): AR` diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr index 33fac603cbd..0e1c86c1bb3 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr @@ -1,16 +1,3 @@ -error[E0275]: overflow evaluating the requirement `(): A` - --> $DIR/inductive-not-on-stack.rs:41:5 - | -LL | impls_a::<()>(); - | ^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) -note: required by a bound in `impls_a` - --> $DIR/inductive-not-on-stack.rs:25:15 - | -LL | fn impls_a() {} - | ^ required by this bound in `impls_a` - error[E0275]: overflow evaluating the requirement `(): AR` --> $DIR/inductive-not-on-stack.rs:44:5 | @@ -24,6 +11,6 @@ note: required by a bound in `impls_ar` LL | fn impls_ar() {} | ^^ required by this bound in `impls_ar` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0275`. -- cgit 1.4.1-3-g733a5 From 02529d2cbecfd4edb6f481c8f0aaad9ad1fadfbb Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 10 Aug 2023 12:56:53 +0200 Subject: add and move trait solver cycle tests --- .../assembly/runaway-impl-candidate-selection.rs | 15 +++++ .../runaway-impl-candidate-selection.stderr | 9 +++ .../coinduction/fixpoint-exponential-growth.rs | 32 ---------- .../coinduction/fixpoint-exponential-growth.stderr | 23 -------- .../coinduction/incompleteness-unstable-result.rs | 69 ---------------------- .../incompleteness-unstable-result.stderr | 16 ----- .../coinduction/fixpoint-exponential-growth.rs | 32 ++++++++++ .../coinduction/fixpoint-exponential-growth.stderr | 23 ++++++++ .../coinduction/incompleteness-unstable-result.rs | 69 ++++++++++++++++++++++ .../incompleteness-unstable-result.stderr | 16 +++++ .../cycles/double-cycle-inductive-coinductive.rs | 37 ++++++++++++ .../double-cycle-inductive-coinductive.stderr | 29 +++++++++ .../new-solver/cycles/inductive-cycle-but-err.rs | 48 +++++++++++++++ .../cycles/inductive-cycle-but-err.stderr | 16 +++++ .../new-solver/cycles/inductive-cycle-but-ok.rs | 44 ++++++++++++++ ...tive-cycle-discarded-coinductive-constraints.rs | 36 +++++++++++ .../cycles/leak-check-coinductive-cycle.rs | 33 +++++++++++ .../new-solver/cycles/provisional-result-done.rs | 33 +++++++++++ .../traits/new-solver/dyn-any-dont-prefer-impl.rs | 4 ++ .../traits/new-solver/exponential-trait-goals.rs | 20 ------- .../new-solver/exponential-trait-goals.stderr | 23 -------- .../new-solver/leak-check-coinductive-cycle.rs | 33 ----------- .../new-solver/overflow/exponential-trait-goals.rs | 20 +++++++ .../overflow/exponential-trait-goals.stderr | 23 ++++++++ .../overflow/recursive-self-normalization-2.rs | 20 +++++++ .../overflow/recursive-self-normalization-2.stderr | 20 +++++++ .../overflow/recursive-self-normalization.rs | 16 +++++ .../overflow/recursive-self-normalization.stderr | 20 +++++++ .../traits/new-solver/provisional-result-done.rs | 33 ----------- .../new-solver/recursive-self-normalization-2.rs | 20 ------- .../recursive-self-normalization-2.stderr | 20 ------- .../new-solver/recursive-self-normalization.rs | 16 ----- .../new-solver/recursive-self-normalization.stderr | 20 ------- .../new-solver/runaway-impl-candidate-selection.rs | 15 ----- .../runaway-impl-candidate-selection.stderr | 9 --- 35 files changed, 563 insertions(+), 349 deletions(-) create mode 100644 tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs create mode 100644 tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr delete mode 100644 tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.rs delete mode 100644 tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.stderr delete mode 100644 tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs delete mode 100644 tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.stderr create mode 100644 tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs create mode 100644 tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr create mode 100644 tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs create mode 100644 tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr create mode 100644 tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs create mode 100644 tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr create mode 100644 tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs create mode 100644 tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr create mode 100644 tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs create mode 100644 tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs create mode 100644 tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs create mode 100644 tests/ui/traits/new-solver/cycles/provisional-result-done.rs delete mode 100644 tests/ui/traits/new-solver/exponential-trait-goals.rs delete mode 100644 tests/ui/traits/new-solver/exponential-trait-goals.stderr delete mode 100644 tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs create mode 100644 tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs create mode 100644 tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr create mode 100644 tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs create mode 100644 tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr create mode 100644 tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs create mode 100644 tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr delete mode 100644 tests/ui/traits/new-solver/provisional-result-done.rs delete mode 100644 tests/ui/traits/new-solver/recursive-self-normalization-2.rs delete mode 100644 tests/ui/traits/new-solver/recursive-self-normalization-2.stderr delete mode 100644 tests/ui/traits/new-solver/recursive-self-normalization.rs delete mode 100644 tests/ui/traits/new-solver/recursive-self-normalization.stderr delete mode 100644 tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs delete mode 100644 tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr diff --git a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs new file mode 100644 index 00000000000..1dca86d3630 --- /dev/null +++ b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.rs @@ -0,0 +1,15 @@ +// compile-flags: -Ztrait-solver=next + +// In the new solver, we are trying to select `::Item: Debug`, +// which, naively can be unified with every impl of `Debug` if we're not careful. +// This test makes sure that we treat projections with inference var substs as +// placeholders during fast reject. + +fn iter() -> ::Item { + todo!() +} + +fn main() { + println!("{:?}", iter::<_>()); + //~^ ERROR type annotations needed +} diff --git a/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr new file mode 100644 index 00000000000..47004821ad7 --- /dev/null +++ b/tests/ui/traits/new-solver/assembly/runaway-impl-candidate-selection.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/runaway-impl-candidate-selection.rs:13:22 + | +LL | println!("{:?}", iter::<_>()); + | ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `iter` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.rs b/tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.rs deleted file mode 100644 index fcafdcf637a..00000000000 --- a/tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.rs +++ /dev/null @@ -1,32 +0,0 @@ -// compile-flags: -Ztrait-solver=next - -// Proving `W: Trait` instantiates `?0` with `(W, W)` and then -// proves `W: Trait` and `W: Trait`, resulting in a coinductive cycle. -// -// Proving coinductive cycles runs until we reach a fixpoint. This fixpoint is -// never reached here and each step doubles the amount of nested obligations. -// -// This previously caused a hang in the trait solver, see -// https://github.com/rust-lang/trait-system-refactor-initiative/issues/13. - -#![feature(rustc_attrs)] - -#[rustc_coinductive] -trait Trait {} - -struct W(T); - -impl Trait for W<(W, W)> -where - W: Trait, - W: Trait, -{ -} - -fn impls() {} - -fn main() { - impls::>(); - //~^ ERROR type annotations needed - //~| ERROR overflow evaluating the requirement -} diff --git a/tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.stderr deleted file mode 100644 index 7d3535e1f01..00000000000 --- a/tests/ui/traits/new-solver/coinduction/fixpoint-exponential-growth.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/fixpoint-exponential-growth.rs:29:5 - | -LL | impls::>(); - | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls` - -error[E0275]: overflow evaluating the requirement `W<_>: Trait` - --> $DIR/fixpoint-exponential-growth.rs:29:5 - | -LL | impls::>(); - | ^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`) -note: required by a bound in `impls` - --> $DIR/fixpoint-exponential-growth.rs:26:13 - | -LL | fn impls() {} - | ^^^^^ required by this bound in `impls` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0275, E0282. -For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs deleted file mode 100644 index 0cd14f05c8d..00000000000 --- a/tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs +++ /dev/null @@ -1,69 +0,0 @@ -// compile-flags: -Ztrait-solver=next -#![feature(rustc_attrs)] - -// This test is incredibly subtle. At its core the goal is to get a coinductive cycle, -// which, depending on its root goal, either holds or errors. We achieve this by getting -// incomplete inference via a `ParamEnv` candidate in the `A` impl and required -// inference from an `Impl` candidate in the `B` impl. -// -// To make global cache accesses stronger than the guidance from the where-bounds, we add -// another coinductive cycle from `A: Trait` to `A: Trait` and only -// constrain `D` directly. This means that any candidates which rely on `V` only make -// progress in the second iteration, allowing a cache access in the first iteration to take -// precedence. -// -// tl;dr: our caching of coinductive cycles was broken and this is a regression -// test for that. - -#[rustc_coinductive] -trait Trait {} -struct A(*const T); -struct B(*const T); - -trait IncompleteGuidance {} -impl IncompleteGuidance for T {} -impl IncompleteGuidance for T {} -impl IncompleteGuidance for T {} - -trait ImplGuidance {} -impl ImplGuidance for T {} -impl ImplGuidance for T {} - -impl Trait for A -where - T: IncompleteGuidance, - A: Trait, - B: Trait, - (): ToU8, -{ -} - -trait ToU8 {} -impl ToU8 for () {} - -impl Trait for B -where - T: ImplGuidance, - A: Trait, -{ -} - -fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} - -fn with_bound() -where - X: IncompleteGuidance, - X: IncompleteGuidance, - X: IncompleteGuidance, -{ - impls_trait::, _, _, _>(); // entering the cycle from `B` works - - // entering the cycle from `A` fails, but would work if we were to use the cache - // result of `B`. - impls_trait::, _, _, _>(); - //~^ ERROR the trait bound `A: Trait<_, _, _>` is not satisfied -} - -fn main() { - with_bound::(); -} diff --git a/tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.stderr deleted file mode 100644 index f1871ff0564..00000000000 --- a/tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:63:19 - | -LL | impls_trait::, _, _, _>(); - | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` - | - = help: the trait `Trait` is implemented for `A` -note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:51:28 - | -LL | fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs new file mode 100644 index 00000000000..fcafdcf637a --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs @@ -0,0 +1,32 @@ +// compile-flags: -Ztrait-solver=next + +// Proving `W: Trait` instantiates `?0` with `(W, W)` and then +// proves `W: Trait` and `W: Trait`, resulting in a coinductive cycle. +// +// Proving coinductive cycles runs until we reach a fixpoint. This fixpoint is +// never reached here and each step doubles the amount of nested obligations. +// +// This previously caused a hang in the trait solver, see +// https://github.com/rust-lang/trait-system-refactor-initiative/issues/13. + +#![feature(rustc_attrs)] + +#[rustc_coinductive] +trait Trait {} + +struct W(T); + +impl Trait for W<(W, W)> +where + W: Trait, + W: Trait, +{ +} + +fn impls() {} + +fn main() { + impls::>(); + //~^ ERROR type annotations needed + //~| ERROR overflow evaluating the requirement +} diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr new file mode 100644 index 00000000000..7d3535e1f01 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr @@ -0,0 +1,23 @@ +error[E0282]: type annotations needed + --> $DIR/fixpoint-exponential-growth.rs:29:5 + | +LL | impls::>(); + | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls` + +error[E0275]: overflow evaluating the requirement `W<_>: Trait` + --> $DIR/fixpoint-exponential-growth.rs:29:5 + | +LL | impls::>(); + | ^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`) +note: required by a bound in `impls` + --> $DIR/fixpoint-exponential-growth.rs:26:13 + | +LL | fn impls() {} + | ^^^^^ required by this bound in `impls` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0275, E0282. +For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs new file mode 100644 index 00000000000..0cd14f05c8d --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -0,0 +1,69 @@ +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs)] + +// This test is incredibly subtle. At its core the goal is to get a coinductive cycle, +// which, depending on its root goal, either holds or errors. We achieve this by getting +// incomplete inference via a `ParamEnv` candidate in the `A` impl and required +// inference from an `Impl` candidate in the `B` impl. +// +// To make global cache accesses stronger than the guidance from the where-bounds, we add +// another coinductive cycle from `A: Trait` to `A: Trait` and only +// constrain `D` directly. This means that any candidates which rely on `V` only make +// progress in the second iteration, allowing a cache access in the first iteration to take +// precedence. +// +// tl;dr: our caching of coinductive cycles was broken and this is a regression +// test for that. + +#[rustc_coinductive] +trait Trait {} +struct A(*const T); +struct B(*const T); + +trait IncompleteGuidance {} +impl IncompleteGuidance for T {} +impl IncompleteGuidance for T {} +impl IncompleteGuidance for T {} + +trait ImplGuidance {} +impl ImplGuidance for T {} +impl ImplGuidance for T {} + +impl Trait for A +where + T: IncompleteGuidance, + A: Trait, + B: Trait, + (): ToU8, +{ +} + +trait ToU8 {} +impl ToU8 for () {} + +impl Trait for B +where + T: ImplGuidance, + A: Trait, +{ +} + +fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} + +fn with_bound() +where + X: IncompleteGuidance, + X: IncompleteGuidance, + X: IncompleteGuidance, +{ + impls_trait::, _, _, _>(); // entering the cycle from `B` works + + // entering the cycle from `A` fails, but would work if we were to use the cache + // result of `B`. + impls_trait::, _, _, _>(); + //~^ ERROR the trait bound `A: Trait<_, _, _>` is not satisfied +} + +fn main() { + with_bound::(); +} diff --git a/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr new file mode 100644 index 00000000000..f1871ff0564 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/coinduction/incompleteness-unstable-result.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied + --> $DIR/incompleteness-unstable-result.rs:63:19 + | +LL | impls_trait::, _, _, _>(); + | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` + | + = help: the trait `Trait` is implemented for `A` +note: required by a bound in `impls_trait` + --> $DIR/incompleteness-unstable-result.rs:51:28 + | +LL | fn impls_trait, U: ?Sized, V: ?Sized, D: ?Sized>() {} + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs new file mode 100644 index 00000000000..5617e45adf6 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.rs @@ -0,0 +1,37 @@ +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs)] + +// Test that having both an inductive and a coinductive cycle +// is handled correctly. + +#[rustc_coinductive] +trait Trait {} +impl Trait for T {} + +trait Inductive {} +impl Inductive for T {} +#[rustc_coinductive] +trait Coinductive {} +impl Coinductive for T {} + +fn impls_trait() {} + +#[rustc_coinductive] +trait TraitRev {} +impl TraitRev for T {} + +trait InductiveRev {} +impl InductiveRev for T {} +#[rustc_coinductive] +trait CoinductiveRev {} +impl CoinductiveRev for T {} + +fn impls_trait_rev() {} + +fn main() { + impls_trait::<()>(); + //~^ ERROR overflow evaluating the requirement + + impls_trait_rev::<()>(); + //~^ ERROR overflow evaluating the requirement +} diff --git a/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr new file mode 100644 index 00000000000..4b8846da535 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr @@ -0,0 +1,29 @@ +error[E0275]: overflow evaluating the requirement `(): Trait` + --> $DIR/double-cycle-inductive-coinductive.rs:32:5 + | +LL | impls_trait::<()>(); + | ^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`) +note: required by a bound in `impls_trait` + --> $DIR/double-cycle-inductive-coinductive.rs:17:19 + | +LL | fn impls_trait() {} + | ^^^^^ required by this bound in `impls_trait` + +error[E0275]: overflow evaluating the requirement `(): TraitRev` + --> $DIR/double-cycle-inductive-coinductive.rs:35:5 + | +LL | impls_trait_rev::<()>(); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`) +note: required by a bound in `impls_trait_rev` + --> $DIR/double-cycle-inductive-coinductive.rs:29:23 + | +LL | fn impls_trait_rev() {} + | ^^^^^^^^ required by this bound in `impls_trait_rev` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs new file mode 100644 index 00000000000..cda98789886 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs @@ -0,0 +1,48 @@ +// compile-flags: -Ztrait-solver=next +#![feature(trivial_bounds, marker_trait_attr)] +#![allow(trivial_bounds)] +// This previously triggered a bug in the provisional cache. +// +// This has the proof tree +// - `MultipleCandidates: Trait` proven via impl-one +// - `MultipleNested: Trait` via impl +// - `MultipleCandidates: Trait` (inductive cycle ~> OVERFLOW) +// - `DoesNotImpl: Trait` (ERR) +// - `MultipleCandidates: Trait` proven via impl-two +// - `MultipleNested: Trait` (in provisional cache ~> OVERFLOW) +// +// We previously incorrectly treated the `MultipleCandidates: Trait` as +// overflow because it was in the cache and reached via an inductive cycle. +// It should be `NoSolution`. + +struct MultipleCandidates; +struct MultipleNested; +struct DoesNotImpl; + +#[marker] +trait Trait {} + +// impl-one +impl Trait for MultipleCandidates +where + MultipleNested: Trait +{} + +// impl-two +impl Trait for MultipleCandidates +where + MultipleNested: Trait, +{} + +impl Trait for MultipleNested +where + MultipleCandidates: Trait, + DoesNotImpl: Trait, +{} + +fn impls_trait() {} + +fn main() { + impls_trait::(); + //~^ ERROR the trait bound `MultipleCandidates: Trait` is not satisfied +} diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr new file mode 100644 index 00000000000..57227321a6d --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `MultipleCandidates: Trait` is not satisfied + --> $DIR/inductive-cycle-but-err.rs:46:19 + | +LL | impls_trait::(); + | ^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `MultipleCandidates` + | + = help: the trait `Trait` is implemented for `MultipleCandidates` +note: required by a bound in `impls_trait` + --> $DIR/inductive-cycle-but-err.rs:43:19 + | +LL | fn impls_trait() {} + | ^^^^^ required by this bound in `impls_trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs new file mode 100644 index 00000000000..d4851eb694b --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs @@ -0,0 +1,44 @@ +// compile-flags: -Ztrait-solver=next +// check-pass +#![feature(trivial_bounds, marker_trait_attr)] +#![allow(trivial_bounds)] + +// This previously triggered a bug in the provisional cache. +// +// This has the proof tree +// - `Root: Trait` proven via impl +// - `MultipleCandidates: Trait` +// - candidate: overflow-impl +// - `Root: Trait` (inductive cycle ~> OVERFLOW) +// - candidate: trivial-impl ~> YES +// - merge respones ~> YES +// - `MultipleCandidates: Trait` (in provisional cache ~> OVERFLOW) +// +// We previously incorrectly treated the `MultipleCandidates: Trait` as +// overflow because it was in the cache and reached via an inductive cycle. +// It should be `YES`. + +struct Root; +struct MultipleCandidates; + +#[marker] +trait Trait {} +impl Trait for Root +where + MultipleCandidates: Trait, + MultipleCandidates: Trait, +{} + +// overflow-impl +impl Trait for MultipleCandidates +where + Root: Trait, +{} +// trivial-impl +impl Trait for MultipleCandidates {} + +fn impls_trait() {} + +fn main() { + impls_trait::(); +} diff --git a/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs b/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs new file mode 100644 index 00000000000..530e6d0ecf3 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-cycle-discarded-coinductive-constraints.rs @@ -0,0 +1,36 @@ +// check-pass +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs, marker_trait_attr)] +#[rustc_coinductive] +trait Trait {} + +impl Trait for (T, U) +where + (U, T): Trait, + (T, U): Inductive, + (): ConstrainToU32, +{} + +trait ConstrainToU32 {} +impl ConstrainToU32 for () {} + +// We only prefer the candidate without an inductive cycle +// once the inductive cycle has the same constraints as the +// other goal. +#[marker] +trait Inductive {} +impl Inductive for (T, U) +where + (T, U): Trait, +{} + +impl Inductive for (u32, u32) {} + +fn impls_trait() +where + (T, U): Trait, +{} + +fn main() { + impls_trait::<_, _>(); +} diff --git a/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs b/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs new file mode 100644 index 00000000000..a6d31872673 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs @@ -0,0 +1,33 @@ +// compile-flags: -Ztrait-solver=next +// check-pass +#![feature(rustc_attrs)] + +#[rustc_coinductive] +trait Trait {} +impl<'a, 'b, T> Trait for (&'a (), &'b ()) +where + 'b: 'a, + &'a (): Trait, +{} + +impl Trait for &'static () {} +impl<'a> Trait for &'a () +where + for<'b> (&'a (), &'b ()): Trait, +{} + + +fn impls_trait, U>() {} + +fn main() { + // This infers to `impls_trait::<(&'static (), &'static ()), i32>();` + // + // In the first attempt we have 2 candidates for `&'a (): Trait<_>` + // and we get ambiguity. The result is therefore ambiguity with a `'b: 'a` + // constraint. The next attempt then uses that provisional result when + // trying to apply `impl<'a> Trait for &'a ()`. This means we get a + // `for<'b> 'b: 'a` bound which fails the leak check. Because of this we + // end up with a single impl for `&'a (): Trait<_>` which infers `_` to `i32` + // and succeeds. + impls_trait::<(&(), &()), _>(); +} diff --git a/tests/ui/traits/new-solver/cycles/provisional-result-done.rs b/tests/ui/traits/new-solver/cycles/provisional-result-done.rs new file mode 100644 index 00000000000..589d34dd7ab --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/provisional-result-done.rs @@ -0,0 +1,33 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +// This tests checks that we update results in the provisional cache when +// we pop a goal from the stack. +#![feature(auto_traits)] +auto trait Coinductive {} +struct Foo(T); +struct Bar(T); + +impl Coinductive for Foo +where + Bar: Coinductive +{} + +impl Coinductive for Bar +where + Foo: Coinductive, + Bar: ConstrainInfer, +{} + +trait ConstrainInfer {} +impl ConstrainInfer for Bar {} +impl ConstrainInfer for Foo {} + +fn impls() -> T { todo!() } + +fn constrain(_: T) {} + +fn main() { + // This should constrain `_` to `u8`. + impls::>(); +} diff --git a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs index 7d15b8c6392..af35a6195e0 100644 --- a/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs +++ b/tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs @@ -1,6 +1,10 @@ // compile-flags: -Ztrait-solver=next // check-pass +// Test that selection prefers the builtin trait object impl for `Any` +// instead of the user defined impl. Both impls apply to the trait +// object. + use std::any::Any; fn needs_usize(_: &usize) {} diff --git a/tests/ui/traits/new-solver/exponential-trait-goals.rs b/tests/ui/traits/new-solver/exponential-trait-goals.rs deleted file mode 100644 index b37f09ee185..00000000000 --- a/tests/ui/traits/new-solver/exponential-trait-goals.rs +++ /dev/null @@ -1,20 +0,0 @@ -// compile-flags: -Ztrait-solver=next - -trait Trait {} - -struct W(T); - -impl Trait for W<(W, W)> -where - W: Trait, - W: Trait, -{ -} - -fn impls() {} - -fn main() { - impls::>(); - //~^ ERROR type annotations needed - //~| ERROR overflow evaluating the requirement `W<_>: Trait` -} diff --git a/tests/ui/traits/new-solver/exponential-trait-goals.stderr b/tests/ui/traits/new-solver/exponential-trait-goals.stderr deleted file mode 100644 index 28a99cbbca6..00000000000 --- a/tests/ui/traits/new-solver/exponential-trait-goals.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/exponential-trait-goals.rs:17:5 - | -LL | impls::>(); - | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls` - -error[E0275]: overflow evaluating the requirement `W<_>: Trait` - --> $DIR/exponential-trait-goals.rs:17:5 - | -LL | impls::>(); - | ^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`exponential_trait_goals`) -note: required by a bound in `impls` - --> $DIR/exponential-trait-goals.rs:14:13 - | -LL | fn impls() {} - | ^^^^^ required by this bound in `impls` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0275, E0282. -For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs b/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs deleted file mode 100644 index 1f7d4a49c90..00000000000 --- a/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs +++ /dev/null @@ -1,33 +0,0 @@ -// check-pass -// compile-flags: -Ztrait-solver=next -#![feature(rustc_attrs)] - -#[rustc_coinductive] -trait Trait {} -impl<'a, 'b, T> Trait for (&'a (), &'b ()) -where - 'b: 'a, - &'a (): Trait, -{} - -impl Trait for &'static () {} -impl<'a> Trait for &'a () -where - for<'b> (&'a (), &'b ()): Trait, -{} - - -fn impls_trait, U>() {} - -fn main() { - // This infers to `impls_trait::<(&'static (), &'static ()), i32>();` - // - // In the first attempt we have 2 candidates for `&'a (): Trait<_>` - // and we get ambiguity. The result is therefore ambiguity with a `'b: 'a` - // constraint. The next attempt then uses that provisional result when - // trying to apply `impl<'a> Trait for &'a ()`. This means we get a - // `for<'b> 'b: 'a` bound which fails the leak check. Because of this we - // end up with a single impl for `&'a (): Trait<_>` which infers `_` to `i32` - // and succeeds. - impls_trait::<(&(), &()), _>(); -} diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs new file mode 100644 index 00000000000..b37f09ee185 --- /dev/null +++ b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.rs @@ -0,0 +1,20 @@ +// compile-flags: -Ztrait-solver=next + +trait Trait {} + +struct W(T); + +impl Trait for W<(W, W)> +where + W: Trait, + W: Trait, +{ +} + +fn impls() {} + +fn main() { + impls::>(); + //~^ ERROR type annotations needed + //~| ERROR overflow evaluating the requirement `W<_>: Trait` +} diff --git a/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr new file mode 100644 index 00000000000..28a99cbbca6 --- /dev/null +++ b/tests/ui/traits/new-solver/overflow/exponential-trait-goals.stderr @@ -0,0 +1,23 @@ +error[E0282]: type annotations needed + --> $DIR/exponential-trait-goals.rs:17:5 + | +LL | impls::>(); + | ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls` + +error[E0275]: overflow evaluating the requirement `W<_>: Trait` + --> $DIR/exponential-trait-goals.rs:17:5 + | +LL | impls::>(); + | ^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`exponential_trait_goals`) +note: required by a bound in `impls` + --> $DIR/exponential-trait-goals.rs:14:13 + | +LL | fn impls() {} + | ^^^^^ required by this bound in `impls` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0275, E0282. +For more information about an error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs new file mode 100644 index 00000000000..d086db475ac --- /dev/null +++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.rs @@ -0,0 +1,20 @@ +//~ ERROR overflow +// compile-flags: -Ztrait-solver=next + +trait Foo1 { + type Assoc1; +} + +trait Foo2 { + type Assoc2; +} + +trait Bar {} +fn needs_bar() {} + +fn test::Assoc2> + Foo2::Assoc1>>() { + needs_bar::(); + //~^ ERROR overflow evaluating the requirement `::Assoc1: Bar` +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr new file mode 100644 index 00000000000..eebaf21d7df --- /dev/null +++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization-2.stderr @@ -0,0 +1,20 @@ +error[E0275]: overflow evaluating the requirement `::Assoc1: Bar` + --> $DIR/recursive-self-normalization-2.rs:16:5 + | +LL | needs_bar::(); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) +note: required by a bound in `needs_bar` + --> $DIR/recursive-self-normalization-2.rs:13:17 + | +LL | fn needs_bar() {} + | ^^^ required by this bound in `needs_bar` + +error[E0275]: overflow evaluating the requirement `::Assoc2` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs new file mode 100644 index 00000000000..d15df7dea73 --- /dev/null +++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs @@ -0,0 +1,16 @@ +//~ ERROR overflow evaluating the requirement `::Assoc` [E0275] +// compile-flags: -Ztrait-solver=next + +trait Foo { + type Assoc; +} + +trait Bar {} +fn needs_bar() {} + +fn test::Assoc>>() { + needs_bar::(); + //~^ ERROR overflow evaluating the requirement `::Assoc: Bar` +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr new file mode 100644 index 00000000000..6a87fe2f121 --- /dev/null +++ b/tests/ui/traits/new-solver/overflow/recursive-self-normalization.stderr @@ -0,0 +1,20 @@ +error[E0275]: overflow evaluating the requirement `::Assoc: Bar` + --> $DIR/recursive-self-normalization.rs:12:5 + | +LL | needs_bar::(); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) +note: required by a bound in `needs_bar` + --> $DIR/recursive-self-normalization.rs:9:17 + | +LL | fn needs_bar() {} + | ^^^ required by this bound in `needs_bar` + +error[E0275]: overflow evaluating the requirement `::Assoc` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/provisional-result-done.rs b/tests/ui/traits/new-solver/provisional-result-done.rs deleted file mode 100644 index 589d34dd7ab..00000000000 --- a/tests/ui/traits/new-solver/provisional-result-done.rs +++ /dev/null @@ -1,33 +0,0 @@ -// compile-flags: -Ztrait-solver=next -// check-pass - -// This tests checks that we update results in the provisional cache when -// we pop a goal from the stack. -#![feature(auto_traits)] -auto trait Coinductive {} -struct Foo(T); -struct Bar(T); - -impl Coinductive for Foo -where - Bar: Coinductive -{} - -impl Coinductive for Bar -where - Foo: Coinductive, - Bar: ConstrainInfer, -{} - -trait ConstrainInfer {} -impl ConstrainInfer for Bar {} -impl ConstrainInfer for Foo {} - -fn impls() -> T { todo!() } - -fn constrain(_: T) {} - -fn main() { - // This should constrain `_` to `u8`. - impls::>(); -} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs b/tests/ui/traits/new-solver/recursive-self-normalization-2.rs deleted file mode 100644 index d086db475ac..00000000000 --- a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -//~ ERROR overflow -// compile-flags: -Ztrait-solver=next - -trait Foo1 { - type Assoc1; -} - -trait Foo2 { - type Assoc2; -} - -trait Bar {} -fn needs_bar() {} - -fn test::Assoc2> + Foo2::Assoc1>>() { - needs_bar::(); - //~^ ERROR overflow evaluating the requirement `::Assoc1: Bar` -} - -fn main() {} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr b/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr deleted file mode 100644 index eebaf21d7df..00000000000 --- a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0275]: overflow evaluating the requirement `::Assoc1: Bar` - --> $DIR/recursive-self-normalization-2.rs:16:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) -note: required by a bound in `needs_bar` - --> $DIR/recursive-self-normalization-2.rs:13:17 - | -LL | fn needs_bar() {} - | ^^^ required by this bound in `needs_bar` - -error[E0275]: overflow evaluating the requirement `::Assoc2` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization_2`) - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.rs b/tests/ui/traits/new-solver/recursive-self-normalization.rs deleted file mode 100644 index d15df7dea73..00000000000 --- a/tests/ui/traits/new-solver/recursive-self-normalization.rs +++ /dev/null @@ -1,16 +0,0 @@ -//~ ERROR overflow evaluating the requirement `::Assoc` [E0275] -// compile-flags: -Ztrait-solver=next - -trait Foo { - type Assoc; -} - -trait Bar {} -fn needs_bar() {} - -fn test::Assoc>>() { - needs_bar::(); - //~^ ERROR overflow evaluating the requirement `::Assoc: Bar` -} - -fn main() {} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.stderr b/tests/ui/traits/new-solver/recursive-self-normalization.stderr deleted file mode 100644 index 6a87fe2f121..00000000000 --- a/tests/ui/traits/new-solver/recursive-self-normalization.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0275]: overflow evaluating the requirement `::Assoc: Bar` - --> $DIR/recursive-self-normalization.rs:12:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) -note: required by a bound in `needs_bar` - --> $DIR/recursive-self-normalization.rs:9:17 - | -LL | fn needs_bar() {} - | ^^^ required by this bound in `needs_bar` - -error[E0275]: overflow evaluating the requirement `::Assoc` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_self_normalization`) - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs b/tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs deleted file mode 100644 index 1dca86d3630..00000000000 --- a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.rs +++ /dev/null @@ -1,15 +0,0 @@ -// compile-flags: -Ztrait-solver=next - -// In the new solver, we are trying to select `::Item: Debug`, -// which, naively can be unified with every impl of `Debug` if we're not careful. -// This test makes sure that we treat projections with inference var substs as -// placeholders during fast reject. - -fn iter() -> ::Item { - todo!() -} - -fn main() { - println!("{:?}", iter::<_>()); - //~^ ERROR type annotations needed -} diff --git a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr b/tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr deleted file mode 100644 index 47004821ad7..00000000000 --- a/tests/ui/traits/new-solver/runaway-impl-candidate-selection.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/runaway-impl-candidate-selection.rs:13:22 - | -LL | println!("{:?}", iter::<_>()); - | ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `iter` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. -- cgit 1.4.1-3-g733a5