From 3ef506fb4dc9415620d4f09be022834d02201257 Mon Sep 17 00:00:00 2001 From: Boxy Date: Wed, 22 Jan 2025 06:40:43 +0000 Subject: [PATCH] Don't pick `T: FnPtr` nested goals --- .../src/solve/fulfill.rs | 23 +++++- ...nt-pick-fnptr-bound-as-leaf.current.stderr | 17 +++++ .../dont-pick-fnptr-bound-as-leaf.next.stderr | 17 +++++ .../dont-pick-fnptr-bound-as-leaf.rs | 28 +++++++ ...=> bad-index-due-to-nested.current.stderr} | 12 +-- .../bad-index-due-to-nested.next.stderr | 76 +++++++++++++++++++ tests/ui/typeck/bad-index-due-to-nested.rs | 7 +- ....stderr => union-derive-eq.current.stderr} | 2 +- tests/ui/union/union-derive-eq.next.stderr | 19 +++++ tests/ui/union/union-derive-eq.rs | 16 +++- ....stderr => wf-trait-fn-arg.current.stderr} | 8 +- tests/ui/wf/wf-trait-fn-arg.next.stderr | 14 ++++ tests/ui/wf/wf-trait-fn-arg.rs | 16 ++-- ....stderr => wf-trait-fn-ret.current.stderr} | 8 +- tests/ui/wf/wf-trait-fn-ret.next.stderr | 14 ++++ tests/ui/wf/wf-trait-fn-ret.rs | 15 ++-- .../wf-trait-fn-where-clause.current.stderr | 19 +++++ .../wf/wf-trait-fn-where-clause.next.stderr | 14 ++++ tests/ui/wf/wf-trait-fn-where-clause.rs | 23 ++++-- tests/ui/wf/wf-trait-fn-where-clause.stderr | 19 ----- ...clauses-method-unsatisfied.current.stderr} | 11 ++- ...ere-clauses-method-unsatisfied.next.stderr | 23 ++++++ .../where-clauses-method-unsatisfied.rs | 10 ++- ... where-clauses-unsatisfied.current.stderr} | 11 ++- .../where-clauses-unsatisfied.next.stderr | 23 ++++++ .../where-clauses-unsatisfied.rs | 11 ++- 26 files changed, 388 insertions(+), 68 deletions(-) create mode 100644 tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.current.stderr create mode 100644 tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.next.stderr create mode 100644 tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.rs rename tests/ui/typeck/{bad-index-due-to-nested.stderr => bad-index-due-to-nested.current.stderr} (88%) create mode 100644 tests/ui/typeck/bad-index-due-to-nested.next.stderr rename tests/ui/union/{union-derive-eq.stderr => union-derive-eq.current.stderr} (95%) create mode 100644 tests/ui/union/union-derive-eq.next.stderr rename tests/ui/wf/{wf-trait-fn-arg.stderr => wf-trait-fn-arg.current.stderr} (74%) create mode 100644 tests/ui/wf/wf-trait-fn-arg.next.stderr rename tests/ui/wf/{wf-trait-fn-ret.stderr => wf-trait-fn-ret.current.stderr} (74%) create mode 100644 tests/ui/wf/wf-trait-fn-ret.next.stderr create mode 100644 tests/ui/wf/wf-trait-fn-where-clause.current.stderr create mode 100644 tests/ui/wf/wf-trait-fn-where-clause.next.stderr delete mode 100644 tests/ui/wf/wf-trait-fn-where-clause.stderr rename tests/ui/where-clauses/{where-clauses-method-unsatisfied.stderr => where-clauses-method-unsatisfied.current.stderr} (58%) create mode 100644 tests/ui/where-clauses/where-clauses-method-unsatisfied.next.stderr rename tests/ui/where-clauses/{where-clauses-unsatisfied.stderr => where-clauses-unsatisfied.current.stderr} (62%) create mode 100644 tests/ui/where-clauses/where-clauses-unsatisfied.next.stderr diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 4498beff4ea34..2b7da4bc5ff07 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -513,8 +513,27 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { _ => ChildMode::PassThrough, }; + let nested_goals = candidate.instantiate_nested_goals(self.span()); + + // If the candidate requires some `T: FnPtr` bound which does not hold should not be treated as + // an actual candidate, instead we should treat them as if the impl was never considered to + // have potentially applied. As if `impl Trait for for<..> fn(..A) -> R` was written + // instead of `impl Trait for T`. + // + // We do this as a separate loop so that we do not choose to tell the user about some nested + // goal before we encounter a `T: FnPtr` nested goal. + for nested_goal in &nested_goals { + if let Some(fn_ptr_trait) = tcx.lang_items().fn_ptr_trait() + && let Some(poly_trait_pred) = nested_goal.goal().predicate.as_trait_clause() + && poly_trait_pred.def_id() == fn_ptr_trait + && let Err(NoSolution) = nested_goal.result() + { + return ControlFlow::Break(self.obligation.clone()); + } + } + let mut impl_where_bound_count = 0; - for nested_goal in candidate.instantiate_nested_goals(self.span()) { + for nested_goal in nested_goals { trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result())); let make_obligation = |cause| Obligation { @@ -605,7 +624,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { } } -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] enum ChildMode<'tcx> { // Try to derive an `ObligationCause::{ImplDerived,BuiltinDerived}`, // and skip all `GoalSource::Misc`, which represent useless obligations diff --git a/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.current.stderr b/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.current.stderr new file mode 100644 index 0000000000000..a863886181cc5 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.current.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/dont-pick-fnptr-bound-as-leaf.rs:24:20 + | +LL | requires_trait(Foo); + | -------------- ^^^ the trait `Trait` is not implemented for `Foo` + | | + | required by a bound introduced by this call + | +note: required by a bound in `requires_trait` + --> $DIR/dont-pick-fnptr-bound-as-leaf.rs:19:22 + | +LL | fn requires_trait(_: T) {} + | ^^^^^ required by this bound in `requires_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.next.stderr b/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.next.stderr new file mode 100644 index 0000000000000..a863886181cc5 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.next.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/dont-pick-fnptr-bound-as-leaf.rs:24:20 + | +LL | requires_trait(Foo); + | -------------- ^^^ the trait `Trait` is not implemented for `Foo` + | | + | required by a bound introduced by this call + | +note: required by a bound in `requires_trait` + --> $DIR/dont-pick-fnptr-bound-as-leaf.rs:19:22 + | +LL | fn requires_trait(_: T) {} + | ^^^^^ required by this bound in `requires_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.rs b/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.rs new file mode 100644 index 0000000000000..995f2c9fbeed3 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.rs @@ -0,0 +1,28 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +// When emitting an error for `Foo: Trait` not holding we attempt to find a nested goal +// to give as the reason why the bound does not hold. This test checks that we do not +// try to tell the user that `Foo: FnPtr` is unimplemented as that would be confusing. + +#![feature(fn_ptr_trait)] + +use std::marker::FnPtr; + +trait Trait {} + +impl Trait for T {} + +struct Foo; + +fn requires_trait(_: T) {} +//~^ NOTE: required by a bound in `requires_trait` +//~| NOTE: required by this bound in `requires_trait` + +fn main() { + requires_trait(Foo); + //~^ ERROR: the trait bound `Foo: Trait` is not satisfied + //~| NOTE: the trait `Trait` is not implemented for `Foo` + //~| NOTE: required by a bound introduced by this call +} diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.current.stderr similarity index 88% rename from tests/ui/typeck/bad-index-due-to-nested.stderr rename to tests/ui/typeck/bad-index-due-to-nested.current.stderr index dd2ce092368a8..dc3d998c399a9 100644 --- a/tests/ui/typeck/bad-index-due-to-nested.stderr +++ b/tests/ui/typeck/bad-index-due-to-nested.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `K: Hash` is not satisfied - --> $DIR/bad-index-due-to-nested.rs:20:5 + --> $DIR/bad-index-due-to-nested.rs:24:5 | LL | map[k] | ^^^ the trait `Hash` is not implemented for `K` | note: required for `HashMap` to implement `Index<&K>` - --> $DIR/bad-index-due-to-nested.rs:7:12 + --> $DIR/bad-index-due-to-nested.rs:11:12 | LL | impl Index<&K> for HashMap | ^^^^^^^^^ ^^^^^^^^^^^^^ @@ -18,13 +18,13 @@ LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap, k: K) -> &'a V | +++++++++++++++++ error[E0277]: the trait bound `V: Copy` is not satisfied - --> $DIR/bad-index-due-to-nested.rs:20:5 + --> $DIR/bad-index-due-to-nested.rs:24:5 | LL | map[k] | ^^^ the trait `Copy` is not implemented for `V` | note: required for `HashMap` to implement `Index<&K>` - --> $DIR/bad-index-due-to-nested.rs:7:12 + --> $DIR/bad-index-due-to-nested.rs:11:12 | LL | impl Index<&K> for HashMap | ^^^^^^^^^ ^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | fn index<'a, K, V: std::marker::Copy>(map: &'a HashMap, k: K) -> &'a | +++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/bad-index-due-to-nested.rs:20:9 + --> $DIR/bad-index-due-to-nested.rs:24:9 | LL | fn index<'a, K, V>(map: &'a HashMap, k: K) -> &'a V { | - found this type parameter @@ -52,7 +52,7 @@ LL | map[&k] | + error[E0308]: mismatched types - --> $DIR/bad-index-due-to-nested.rs:20:5 + --> $DIR/bad-index-due-to-nested.rs:24:5 | LL | fn index<'a, K, V>(map: &'a HashMap, k: K) -> &'a V { | - found this type parameter ----- expected `&'a V` because of return type diff --git a/tests/ui/typeck/bad-index-due-to-nested.next.stderr b/tests/ui/typeck/bad-index-due-to-nested.next.stderr new file mode 100644 index 0000000000000..a0b275b7852ba --- /dev/null +++ b/tests/ui/typeck/bad-index-due-to-nested.next.stderr @@ -0,0 +1,76 @@ +error[E0277]: the trait bound `K: Hash` is not satisfied + --> $DIR/bad-index-due-to-nested.rs:24:5 + | +LL | map[k] + | ^^^ the trait `Hash` is not implemented for `K` + | +note: required for `HashMap` to implement `Index<&K>` + --> $DIR/bad-index-due-to-nested.rs:11:12 + | +LL | impl Index<&K> for HashMap + | ^^^^^^^^^ ^^^^^^^^^^^^^ +LL | where +LL | K: Hash, + | ---- unsatisfied trait bound introduced here +help: consider restricting type parameter `K` with trait `Hash` + | +LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap, k: K) -> &'a V { + | +++++++++++++++++ + +error[E0277]: the trait bound `V: Copy` is not satisfied + --> $DIR/bad-index-due-to-nested.rs:24:5 + | +LL | map[k] + | ^^^ the trait `Copy` is not implemented for `V` + | +note: required for `HashMap` to implement `Index<&K>` + --> $DIR/bad-index-due-to-nested.rs:11:12 + | +LL | impl Index<&K> for HashMap + | ^^^^^^^^^ ^^^^^^^^^^^^^ +... +LL | V: Copy, + | ---- unsatisfied trait bound introduced here +help: consider restricting type parameter `V` with trait `Copy` + | +LL | fn index<'a, K, V: std::marker::Copy>(map: &'a HashMap, k: K) -> &'a V { + | +++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/bad-index-due-to-nested.rs:24:9 + | +LL | fn index<'a, K, V>(map: &'a HashMap, k: K) -> &'a V { + | - found this type parameter +LL | map[k] + | ^ expected `&K`, found type parameter `K` + | + = note: expected reference `&_` + found type parameter `_` +help: consider borrowing here + | +LL | map[&k] + | + + +error[E0277]: the trait bound `K: Hash` is not satisfied + --> $DIR/bad-index-due-to-nested.rs:24:5 + | +LL | map[k] + | ^^^^^^ the trait `Hash` is not implemented for `K` + | +note: required for `HashMap` to implement `Index<&K>` + --> $DIR/bad-index-due-to-nested.rs:11:12 + | +LL | impl Index<&K> for HashMap + | ^^^^^^^^^ ^^^^^^^^^^^^^ +LL | where +LL | K: Hash, + | ---- unsatisfied trait bound introduced here +help: consider restricting type parameter `K` with trait `Hash` + | +LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap, k: K) -> &'a V { + | +++++++++++++++++ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/bad-index-due-to-nested.rs b/tests/ui/typeck/bad-index-due-to-nested.rs index 2564b530004e5..e7f385865af5f 100644 --- a/tests/ui/typeck/bad-index-due-to-nested.rs +++ b/tests/ui/typeck/bad-index-due-to-nested.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + use std::hash::Hash; use std::marker::PhantomData; use std::ops::Index; @@ -21,7 +25,8 @@ fn index<'a, K, V>(map: &'a HashMap, k: K) -> &'a V { //~^ ERROR the trait bound `K: Hash` is not satisfied //~| ERROR the trait bound `V: Copy` is not satisfied //~| ERROR mismatched types - //~| ERROR mismatched types + //[current]~| ERROR mismatched types + //[next]~^^^^^ ERROR the trait bound `K: Hash` is not satisfied } fn main() {} diff --git a/tests/ui/union/union-derive-eq.stderr b/tests/ui/union/union-derive-eq.current.stderr similarity index 95% rename from tests/ui/union/union-derive-eq.stderr rename to tests/ui/union/union-derive-eq.current.stderr index b068edd6d69cc..151ceebe1ba67 100644 --- a/tests/ui/union/union-derive-eq.stderr +++ b/tests/ui/union/union-derive-eq.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied - --> $DIR/union-derive-eq.rs:13:5 + --> $DIR/union-derive-eq.rs:21:5 | LL | #[derive(Eq)] | -- in this derive macro expansion diff --git a/tests/ui/union/union-derive-eq.next.stderr b/tests/ui/union/union-derive-eq.next.stderr new file mode 100644 index 0000000000000..3952b1f12840f --- /dev/null +++ b/tests/ui/union/union-derive-eq.next.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied + --> $DIR/union-derive-eq.rs:21:5 + | +LL | #[derive(Eq)] + | -- in this derive macro expansion +LL | union U2 { +LL | a: PartialEqNotEq, + | ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq` + | + = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` + | +LL + #[derive(Eq)] +LL | struct PartialEqNotEq; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/union/union-derive-eq.rs b/tests/ui/union/union-derive-eq.rs index e689f8c27d772..085262a72a18f 100644 --- a/tests/ui/union/union-derive-eq.rs +++ b/tests/ui/union/union-derive-eq.rs @@ -1,9 +1,17 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + #[derive(Eq)] // OK union U1 { a: u8, } -impl PartialEq for U1 { fn eq(&self, rhs: &Self) -> bool { true } } +impl PartialEq for U1 { + fn eq(&self, rhs: &Self) -> bool { + true + } +} #[derive(PartialEq, Copy, Clone)] struct PartialEqNotEq; @@ -13,6 +21,10 @@ union U2 { a: PartialEqNotEq, //~ ERROR the trait bound `PartialEqNotEq: Eq` is not satisfied } -impl PartialEq for U2 { fn eq(&self, rhs: &Self) -> bool { true } } +impl PartialEq for U2 { + fn eq(&self, rhs: &Self) -> bool { + true + } +} fn main() {} diff --git a/tests/ui/wf/wf-trait-fn-arg.stderr b/tests/ui/wf/wf-trait-fn-arg.current.stderr similarity index 74% rename from tests/ui/wf/wf-trait-fn-arg.stderr rename to tests/ui/wf/wf-trait-fn-arg.current.stderr index 8b35f36fa68a8..d5dd36fad6dd6 100644 --- a/tests/ui/wf/wf-trait-fn-arg.stderr +++ b/tests/ui/wf/wf-trait-fn-arg.current.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied - --> $DIR/wf-trait-fn-arg.rs:10:23 + --> $DIR/wf-trait-fn-arg.rs:16:23 | LL | fn bar(&self, x: &Bar); | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` | note: required by a bound in `Bar` - --> $DIR/wf-trait-fn-arg.rs:7:14 + --> $DIR/wf-trait-fn-arg.rs:11:15 | -LL | struct Bar { value: Box } - | ^^ required by this bound in `Bar` +LL | struct Bar { + | ^^ required by this bound in `Bar` help: consider further restricting `Self` | LL | fn bar(&self, x: &Bar) where Self: Eq; diff --git a/tests/ui/wf/wf-trait-fn-arg.next.stderr b/tests/ui/wf/wf-trait-fn-arg.next.stderr new file mode 100644 index 0000000000000..c55dc5c8a121a --- /dev/null +++ b/tests/ui/wf/wf-trait-fn-arg.next.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `Self: Eq` is not satisfied + --> $DIR/wf-trait-fn-arg.rs:16:23 + | +LL | fn bar(&self, x: &Bar); + | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self, x: &Bar) where Self: Eq; + | ++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-trait-fn-arg.rs b/tests/ui/wf/wf-trait-fn-arg.rs index 0445699427e2a..13a5b32828d82 100644 --- a/tests/ui/wf/wf-trait-fn-arg.rs +++ b/tests/ui/wf/wf-trait-fn-arg.rs @@ -1,16 +1,22 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + // Check that we test WF conditions for fn arguments in a trait definition. #![feature(rustc_attrs)] #![allow(dead_code)] #![allow(unused_variables)] -struct Bar { value: Box } +struct Bar { + value: Box, +} trait Foo { fn bar(&self, x: &Bar); - //~^ ERROR E0277 - // - // Here, Eq ought to be implemented. + //~^ ERROR E0277 + // + // Here, Eq ought to be implemented. } -fn main() { } +fn main() {} diff --git a/tests/ui/wf/wf-trait-fn-ret.stderr b/tests/ui/wf/wf-trait-fn-ret.current.stderr similarity index 74% rename from tests/ui/wf/wf-trait-fn-ret.stderr rename to tests/ui/wf/wf-trait-fn-ret.current.stderr index 3d70f04def2e0..0ad786c2fd566 100644 --- a/tests/ui/wf/wf-trait-fn-ret.stderr +++ b/tests/ui/wf/wf-trait-fn-ret.current.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied - --> $DIR/wf-trait-fn-ret.rs:10:23 + --> $DIR/wf-trait-fn-ret.rs:15:23 | LL | fn bar(&self) -> &Bar; | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` | note: required by a bound in `Bar` - --> $DIR/wf-trait-fn-ret.rs:7:14 + --> $DIR/wf-trait-fn-ret.rs:10:15 | -LL | struct Bar { value: Box } - | ^^ required by this bound in `Bar` +LL | struct Bar { + | ^^ required by this bound in `Bar` help: consider further restricting `Self` | LL | fn bar(&self) -> &Bar where Self: Eq; diff --git a/tests/ui/wf/wf-trait-fn-ret.next.stderr b/tests/ui/wf/wf-trait-fn-ret.next.stderr new file mode 100644 index 0000000000000..b3dca17672d31 --- /dev/null +++ b/tests/ui/wf/wf-trait-fn-ret.next.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `Self: Eq` is not satisfied + --> $DIR/wf-trait-fn-ret.rs:15:23 + | +LL | fn bar(&self) -> &Bar; + | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn bar(&self) -> &Bar where Self: Eq; + | ++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-trait-fn-ret.rs b/tests/ui/wf/wf-trait-fn-ret.rs index f49e43087701b..c00f6dd10af21 100644 --- a/tests/ui/wf/wf-trait-fn-ret.rs +++ b/tests/ui/wf/wf-trait-fn-ret.rs @@ -1,16 +1,21 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) // Check that we test WF conditions for fn return types in a trait definition. #![feature(rustc_attrs)] #![allow(dead_code)] #![allow(unused_variables)] -struct Bar { value: Box } +struct Bar { + value: Box, +} trait Foo { fn bar(&self) -> &Bar; - //~^ ERROR E0277 - // - // Here, Eq ought to be implemented. + //~^ ERROR E0277 + // + // Here, Eq ought to be implemented. } -fn main() { } +fn main() {} diff --git a/tests/ui/wf/wf-trait-fn-where-clause.current.stderr b/tests/ui/wf/wf-trait-fn-where-clause.current.stderr new file mode 100644 index 0000000000000..db5454d0f3c22 --- /dev/null +++ b/tests/ui/wf/wf-trait-fn-where-clause.current.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `Self: Eq` is not satisfied + --> $DIR/wf-trait-fn-where-clause.rs:18:20 + | +LL | Bar: Copy; + | ^^^^ the trait `Eq` is not implemented for `Self` + | +note: required by a bound in `Bar` + --> $DIR/wf-trait-fn-where-clause.rs:10:15 + | +LL | struct Bar { + | ^^ required by this bound in `Bar` +help: consider further restricting `Self` + | +LL | Bar: Copy, Self: Eq; + | ++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-trait-fn-where-clause.next.stderr b/tests/ui/wf/wf-trait-fn-where-clause.next.stderr new file mode 100644 index 0000000000000..8c8a5fa3e7041 --- /dev/null +++ b/tests/ui/wf/wf-trait-fn-where-clause.next.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `Self: Eq` is not satisfied + --> $DIR/wf-trait-fn-where-clause.rs:18:20 + | +LL | Bar: Copy; + | ^^^^ the trait `Eq` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | Bar: Copy, Self: Eq; + | ++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-trait-fn-where-clause.rs b/tests/ui/wf/wf-trait-fn-where-clause.rs index 1d2427ff981d7..9e36682e449d5 100644 --- a/tests/ui/wf/wf-trait-fn-where-clause.rs +++ b/tests/ui/wf/wf-trait-fn-where-clause.rs @@ -1,17 +1,24 @@ -// Check that we test WF conditions for fn where clauses in a trait definition. +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +// Check that we test WF conditions for fn where clauses in a trait definition. #![allow(dead_code)] #![allow(unused_variables)] -struct Bar { value: Box } +struct Bar { + value: Box, +} trait Foo { - fn bar(&self) where Self: Sized, Bar: Copy; - //~^ ERROR E0277 - // - // Here, Eq ought to be implemented. + fn bar(&self) + where + Self: Sized, + Bar: Copy; + //~^ ERROR E0277 + // + // Here, Eq ought to be implemented. } - -fn main() { } +fn main() {} diff --git a/tests/ui/wf/wf-trait-fn-where-clause.stderr b/tests/ui/wf/wf-trait-fn-where-clause.stderr deleted file mode 100644 index 0ad3b58e7c76a..0000000000000 --- a/tests/ui/wf/wf-trait-fn-where-clause.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: the trait bound `Self: Eq` is not satisfied - --> $DIR/wf-trait-fn-where-clause.rs:10:49 - | -LL | fn bar(&self) where Self: Sized, Bar: Copy; - | ^^^^ the trait `Eq` is not implemented for `Self` - | -note: required by a bound in `Bar` - --> $DIR/wf-trait-fn-where-clause.rs:7:14 - | -LL | struct Bar { value: Box } - | ^^ required by this bound in `Bar` -help: consider further restricting `Self` - | -LL | fn bar(&self) where Self: Sized, Bar: Copy, Self: Eq; - | ++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr b/tests/ui/where-clauses/where-clauses-method-unsatisfied.current.stderr similarity index 58% rename from tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr rename to tests/ui/where-clauses/where-clauses-method-unsatisfied.current.stderr index 840df342ef9a9..d1de813a2d9f8 100644 --- a/tests/ui/where-clauses/where-clauses-method-unsatisfied.stderr +++ b/tests/ui/where-clauses/where-clauses-method-unsatisfied.current.stderr @@ -1,14 +1,17 @@ error[E0277]: the trait bound `Bar: Eq` is not satisfied - --> $DIR/where-clauses-method-unsatisfied.rs:18:7 + --> $DIR/where-clauses-method-unsatisfied.rs:24:7 | LL | x.equals(&x); | ^^^^^^ the trait `Eq` is not implemented for `Bar` | note: required by a bound in `Foo::::equals` - --> $DIR/where-clauses-method-unsatisfied.rs:11:52 + --> $DIR/where-clauses-method-unsatisfied.rs:16:12 | -LL | fn equals(&self, u: &Foo) -> bool where T : Eq { - | ^^ required by this bound in `Foo::::equals` +LL | fn equals(&self, u: &Foo) -> bool + | ------ required by a bound in this associated function +LL | where +LL | T: Eq, + | ^^ required by this bound in `Foo::::equals` help: consider annotating `Bar` with `#[derive(Eq)]` | LL + #[derive(Eq)] diff --git a/tests/ui/where-clauses/where-clauses-method-unsatisfied.next.stderr b/tests/ui/where-clauses/where-clauses-method-unsatisfied.next.stderr new file mode 100644 index 0000000000000..d1de813a2d9f8 --- /dev/null +++ b/tests/ui/where-clauses/where-clauses-method-unsatisfied.next.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `Bar: Eq` is not satisfied + --> $DIR/where-clauses-method-unsatisfied.rs:24:7 + | +LL | x.equals(&x); + | ^^^^^^ the trait `Eq` is not implemented for `Bar` + | +note: required by a bound in `Foo::::equals` + --> $DIR/where-clauses-method-unsatisfied.rs:16:12 + | +LL | fn equals(&self, u: &Foo) -> bool + | ------ required by a bound in this associated function +LL | where +LL | T: Eq, + | ^^ required by this bound in `Foo::::equals` +help: consider annotating `Bar` with `#[derive(Eq)]` + | +LL + #[derive(Eq)] +LL | struct Bar; // does not implement Eq + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/where-clauses/where-clauses-method-unsatisfied.rs b/tests/ui/where-clauses/where-clauses-method-unsatisfied.rs index a8ae02964078b..34e9d9b57d1c6 100644 --- a/tests/ui/where-clauses/where-clauses-method-unsatisfied.rs +++ b/tests/ui/where-clauses/where-clauses-method-unsatisfied.rs @@ -1,14 +1,20 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) // Test that a where clause attached to a method allows us to add // additional constraints to a parameter out of scope. struct Foo { - value: T + value: T, } struct Bar; // does not implement Eq impl Foo { - fn equals(&self, u: &Foo) -> bool where T : Eq { + fn equals(&self, u: &Foo) -> bool + where + T: Eq, + { self.value == u.value } } diff --git a/tests/ui/where-clauses/where-clauses-unsatisfied.stderr b/tests/ui/where-clauses/where-clauses-unsatisfied.current.stderr similarity index 62% rename from tests/ui/where-clauses/where-clauses-unsatisfied.stderr rename to tests/ui/where-clauses/where-clauses-unsatisfied.current.stderr index 205b82d49bfeb..485b9459ddd0e 100644 --- a/tests/ui/where-clauses/where-clauses-unsatisfied.stderr +++ b/tests/ui/where-clauses/where-clauses-unsatisfied.current.stderr @@ -1,14 +1,17 @@ error[E0277]: the trait bound `Struct: Eq` is not satisfied - --> $DIR/where-clauses-unsatisfied.rs:6:10 + --> $DIR/where-clauses-unsatisfied.rs:15:10 | LL | drop(equal(&Struct, &Struct)) | ^^^^^ the trait `Eq` is not implemented for `Struct` | note: required by a bound in `equal` - --> $DIR/where-clauses-unsatisfied.rs:1:45 + --> $DIR/where-clauses-unsatisfied.rs:7:8 | -LL | fn equal(a: &T, b: &T) -> bool where T : Eq { a == b } - | ^^ required by this bound in `equal` +LL | fn equal(a: &T, b: &T) -> bool + | ----- required by a bound in this function +LL | where +LL | T: Eq, + | ^^ required by this bound in `equal` help: consider annotating `Struct` with `#[derive(Eq)]` | LL + #[derive(Eq)] diff --git a/tests/ui/where-clauses/where-clauses-unsatisfied.next.stderr b/tests/ui/where-clauses/where-clauses-unsatisfied.next.stderr new file mode 100644 index 0000000000000..485b9459ddd0e --- /dev/null +++ b/tests/ui/where-clauses/where-clauses-unsatisfied.next.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `Struct: Eq` is not satisfied + --> $DIR/where-clauses-unsatisfied.rs:15:10 + | +LL | drop(equal(&Struct, &Struct)) + | ^^^^^ the trait `Eq` is not implemented for `Struct` + | +note: required by a bound in `equal` + --> $DIR/where-clauses-unsatisfied.rs:7:8 + | +LL | fn equal(a: &T, b: &T) -> bool + | ----- required by a bound in this function +LL | where +LL | T: Eq, + | ^^ required by this bound in `equal` +help: consider annotating `Struct` with `#[derive(Eq)]` + | +LL + #[derive(Eq)] +LL | struct Struct; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/where-clauses/where-clauses-unsatisfied.rs b/tests/ui/where-clauses/where-clauses-unsatisfied.rs index 8b067d30a2a85..48798e2a15dbb 100644 --- a/tests/ui/where-clauses/where-clauses-unsatisfied.rs +++ b/tests/ui/where-clauses/where-clauses-unsatisfied.rs @@ -1,4 +1,13 @@ -fn equal(a: &T, b: &T) -> bool where T : Eq { a == b } +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +fn equal(a: &T, b: &T) -> bool +where + T: Eq, +{ + a == b +} struct Struct;