Closed konnorandrews closed 1 month ago
I just discovered that swapping the bounds on the Raise::Higher
causes it to work again on 1.79.0 and later.
(not working)
trait Raise{
type Higher<'lt, 'ctx, B>: for<'a, 'b> Lower<'a, 'b, Bound<'a, 'b>> + Lower<'lt, 'ctx, B, T = Self>;
}
(working)
trait Raise{
type Higher<'lt, 'ctx, B>: Lower<'lt, 'ctx, B, T = Self> + for<'a, 'b> Lower<'a, 'b, Bound<'a, 'b>>;
}
I have simplified the code to this
fn main() {}
trait Raise{
type Higher<'lt>: for<'a> Lower<'a> + Lower<'lt, T = Self>;
}
trait Lower<'lt> {
type T: Raise<Higher<'lt> = Self>;
}
fn use_lower<'a, T: Raise>(x: T) {
use_higher::<<T as Raise>::Higher::<'a>>(x);
}
fn use_higher<'a, H: for<'b> Lower<'b>>(x: <H as Lower<'a>>::T) {}
As before switching it with
type Higher<'lt>: Lower<'lt, T = Self> + for<'a> Lower<'a>;
works
cc @lcnr
has already been reverted on beta in https://github.com/rust-lang/rust/pull/125629.
the unstable result depending on whether the associated type bounds are swapped is caused by
before #119820 we already discarded the non-hr item bounds - ProjectionCandidate
- before using fn candidate_should_be_dropped_in_favor_of
, causing us to always use the hr one, regardless of order.
Here is a smaller example that doesn't use GATs.
pub trait ForLt<'a> {
type T;
}
pub trait Hrt: for<'a> ForLt<'a> {}
pub trait Other<'a> {
type Higher: Hrt + ForLt<'a>;
}
error: implementation of `ForLt` is not general enough
--> src/main.rs:10:18
|
7 | pub trait Hrt: for<'a> ForLt<'a> {}
| --------------------------------
| | |
| | doesn't satisfy where-clause
| due to a where-clause on `Hrt`...
...
10 | type Higher: Hrt + ForLt<'a>;
| ^^^
|
= note: ...`<Self as Other<'a>>::Higher` must implement `ForLt<'0>`, for any lifetime `'0`...
= note: ...but it actually implements `ForLt<'a>`
(A more meaningful example is to use type Higher: Hrt + ForLt<'a, T = i32>;
. As this actually adds a extra bound instead of it being a duplicate bound.)
Is the type Higher: ForLt<'a> + Hrt;
supposed to be allowed? I do use the stable behavior in some code and am wondering if I need to change to some other method to achieve this.
Same as #125194 . Changes in #119820 were reverted so in theory this regression should be neutralized in the current nightly. Can you check @konnorandrews ? thanks
I only reverted it on beta, it still affects nightly (and the new beta)
THis has since been fully reverted, closing as fixed. We already have added tests for this.
Code
I tried this code:
I expected to see this happen: For it to compile (based on rustc previously accepting this code) I am not 100% sure this code is supposed to be allowed.
Instead, this happened: A compiler error
Version it worked on
It most recently worked on: Rust 1.78.0
Version with regression
Rust 1.79.0 and later. Bisected to commit 43f4f2a3b1a3d3fb3dbbbe4fde33fb97c780ee98
@rustbot modify labels: +regression-from-stable-to-beta -regression-untriaged