Open BoxyUwU opened 1 month ago
This regressed in https://github.com/rust-lang/rust/pull/126128, cc @lcnr
Alright, it would be very useful to get a minimization of the underlying pattern here. I think we likely want to accept this breakage :thinking:
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-high
Alright, it would be very useful to get a minimization of the underlying pattern here. I think we likely want to accept this breakage 🤔
Depending on the result of the investigation, could #126128 end up in the release notes, correct? (just mentioning so we dont forget to label it as such)
Minimized from the triangulate crate (I'm unable to make it any smaller):
pub trait Mappable<T> {
type Output;
}
pub trait Mappable2<T> {
type Output;
}
// Deleting this impl makes it compile on beta
impl<T> Mappable2<T> for T {
type Output = i32;
}
pub trait Generic<M> {}
// Deleting the `: Mappable<T>` makes it error on stable.
pub struct IndexWithIter<I, M: Mappable<T>, T>(I, M, T);
// Changing the where clause to be an inline bound (`impl<I: Generic<M>, ....`) causes it to compile on beta
impl<I, M: Mappable<T, Output: Mappable2<T, Output = M>>, T> IndexWithIter<I, M, T>
where
I: Generic<M>,
{
fn new(_: I) {}
}
pub fn foo<M: Mappable<T, Output: Mappable2<T, Output = M>>, T>(x: impl Generic<M>) {
IndexWithIter::new(x);
}
Compiles on stable. Gives the following error on beta:
Compiling playground v0.0.1 (/playground)
error[E0275]: overflow evaluating the requirement `<M as Mappable<_>>::Output: Mappable2<_>`
--> src/lib.rs:28:5
|
28 | IndexWithIter::new(x);
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`playground`)
note: required by a bound in `IndexWithIter::<I, M, T>::new`
--> src/lib.rs:20:45
|
20 | impl<I, M: Mappable<T, Output: Mappable2<T, Output = M>>, T> IndexWithIter<I, M, T>
| ^^^^^^^^^^ required by this bound in `IndexWithIter::<I, M, T>::new`
...
24 | fn new(_: I) {}
| --- required by a bound in this associated function
For more information about this error, try `rustc --explain E0275`.
error: could not compile `playground` (lib) due to 1 previous error
I am unable to reproduce the issues with poke_search_cli or similari on my computer.
slightly more readable for me :thinking:
pub trait Mappable<T> {
type Output;
}
pub trait Mappable2<T> {
type Output;
}
// Deleting this impl makes it compile on beta
impl<T> Mappable2<T> for T {
type Output = i32;
}
pub trait Generic<M> {}
// Deleting the `: Mappable<T>` makes it error on stable.
pub struct IndexWithIter<I, M: Mappable<T>, T>(I, M, T);
// Changing the where clause to be an inline bound (`impl<I: Generic<M>, ....`) causes it to compile on beta
impl<I, M, T> IndexWithIter<I, M, T>
where
M: Mappable<T>,
M::Output: Mappable2<T, Output = M>,
I: Generic<M>,
{
fn new(x: I) {
IndexWithIter::<_, _, _>::new(x);
}
}
this is somehow caused by the order in which we evaluate nested goals and also subtyping, but I don't fully understand why this is happening yet.
yeah, I am also unable to reproduce the overflow in poke_search
and similari
, so they may be spurious due to order dependence in the old trait solver wrt to overflow depth
I have encountered an issue that may be related to this issue, report filed at: https://github.com/geoarrow/geoarrow-rs/issues/716
The compile error that only occurs with nightly + release build, the code compiles for nightly + debug builds, and stable + release.
the error message starts
Compiling geoarrow v0.2.0
error[E0275]: overflow evaluating the requirement `<impl GeometryTrait<T = f64> as geo_traits::geometry::GeometryTrait>::GeometryCollection<'_>: geo_traits::geometry_collection::GeometryCollectionTrait`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`geoarrow`)
note: required for `GeometryCollectionIterator<'_, f64, ..., ...>` to implement `Iterator`
--> /Users/andy/.cargo/registry/src/index.crates.io-6f17d22bba15001f/geoarrow-0.2.0/src/geo_traits/iterator.rs:38:15
|
Full message and attached file in the linked issue
Without actually verifying it, I suspect that this is due to MIR inlining causing instantiations that overflow. MIR inlining depends on the crate hash/defpath hash, so is affected by changes to the crate name.
To verify this, you can try using -Zinline-mir=no
.
Without actually verifying it, I suspect that this is due to MIR inlining causing instantiations that overflow. MIR inlining depends on the crate hash/defpath hash, so is affected by changes to the crate name. To verify this, you can try using
-Zinline-mir=no
.
Hi, thanks for looking into this.
I tried your suggestion on the original crate, (actually the commit 46554582089404faca5da8dfdde6f871cb1378e2 from the geoarrow repo) as well as geoarrow v0.2.0
RUSTFLAGS="-Zinline-mir" cargo build --release
However the same error occurs
Compiling geoarrow v0.2.0 .... OR .... Compiling geoarrow v0.3.0-beta.2 (/opt/git/geoarrow-rs)
error[E0275]: overflow evaluating the requirement `impl GeometryCollectionTrait<T = f64>: geo_traits::geometry_collection::GeometryCollectionTrait`
rustc +nightly --version --verbose rustc 1.82.0-nightly (4074d4902 2024-08-23) binary: rustc commit-hash: 4074d4902dc19ff1bbce1d74ef9ceae15b5f41ce commit-date: 2024-08-23 host: aarch64-apple-darwin release: 1.82.0-nightly LLVM version: 19.1.0
@apps4uco Your build command is incorrect.
I can confirm that, on commit 2089a0189a16a8959605791fbbc2cc48113f1ccf (tag rust-v0.2.0), and also on my minimized test case, compiling with the following command compiles fine without an error:
RUSTFLAGS='-Zinline-mir=no' cargo +nightly build --release
While the following command produces an error:
cargo +nightly build --release
@apps4uco Your build command is incorrect.
I should have stated that the global configuration I have is
$ rustup default nightly-aarch64-apple-darwin (default)
So it should be the same command as you had, or am I missing something?
It seems like a very weird edge case that we have hit.
What produced an error for me yesterday compiles fine today with the same command. Could that be related to the order cargo is compiling the crates?
Thanks once again for looking into this.
Current status: The issue from geoarrow-rs has been fixed in #129714. The issue from the triangulate crate is still unfixed, and might end up in stable rust version 1.81.0.
Maybe this should go on the release notes?
thinking through this:
The change in #126128 changes the equate of the self type IndexWithIter::<?0, ?1, ?2>
with the instantiated impl self type IndexWithIter<?I, ?M, ?T>
to subtyping.
Where this previously equated the inference variables, resulting in ?0 = ?I
, ?1 = ?M
and ?2 = ?T
, this now emits Subtype
obligations which get processed in the main fulfillment loop. This means that constraining ?0-2
doesn't immediately constrain ?I
, ?M
, or ?T
.
Trying to prove <M as Mappable<?T>>::Output: Mappable2<?T, Output = M>,
overflows, while proving <M as Mappable<T>>::Output: Mappable2<T, Output = M>
with T
inferred does not. For why it overflows, see https://github.com/rust-lang/rust/issues/128887#issuecomment-2326306019
We first constrain ?0
to I
, then prove subtype obligations, and then prove the where-bounds on the self-type IndexWithIter
. This means we prove M: Mappable<?2>
. This constrains ?2
to T
, but with #126128 does not constrain ?T
to T
as well.
We then first prove the projection predicate which overflows and then the M: Mappable<T>
predicate. We always move projection predicates before trait predicates, so adding a projection predicate to M: Mappable<T>
fixes the overflow (depending on the order of where-clauses) by first proving this one:
this regression therefore doesn't need an associated type bound on Mappable2
: https://play.rust-lang.org/?version=beta&mode=debug&edition=2021&gist=13e05a9fbba710cc556bd6366b292846
so what's going on here is the following change from the old behavior:
?Mimpl
and ?Mtype
via I: Generic<?Mimpl>
M: Mappable<?Ttype>
which constrains ?Timpl
and ?Ttype
<M as Mappable<T>>::Output: Bound<T>
to the new behavior
?Mimpl
via I: Generic<?Mimpl>
?Mimpl
?Mtype
which also constrains ?Mtype
M: Mappable<?Ttype>
which constrains ?Ttype
, but not ?Timpl
<M as Mappable<?Timpl>>::Output: Bound<?Timpl>
which overflowsso, assuming that the fact that <M as Mappable<?t>>::Output: Bound<?t>
should overflow, this change seems like an unfortunate, but acceptable inference breakage.
The reason that <M as Mappable<?t>>::Output: Bound<?t>
overflows is due to the generalizer emitting Projection
obligations in case there's an occurs check failure inside of an alias.
using https://github.com/rust-lang/rust/issues/128887#issuecomment-2326041914
trait Mappable<T> {
type Output;
}
pub trait Bound<T> {}
// Deleting this impl makes it compile on beta
impl<T> Bound<T> for T {}
trait Generic<M> {}
// Deleting the `: Mappable<T>` makes it error on stable.
pub struct IndexWithIter<I, M: Mappable<T>, T>(I, M, T);
impl<I, M, T> IndexWithIter<I, M, T>
where
<M as Mappable<T>>::Output: Bound<T>,
// flipping these where bounds causes this to succeed, even when removing
// the where-clause on the struct definition.
M: Mappable<T>,
I: Generic<M>,
{
fn new(x: I) {
IndexWithIter::<_, _, _>::new(x);
}
}
<M as Mappable<?t>>::Output: Bound<?t>
via the impl equates <M as Mappable<?t>>::Output
and ?t
?t
fails the occurs check and emits a Projection(<M as Mappable<?t>>::Output, ?t)
goal. As <M as Mappable<?t>>::Output
is a rigid projection, we equate it with ?t
yet again, causing overflow.We could in theory fix this by reverting occurs check failures back to a hard error in case the projection does not reference bound variables or placeholders (as we should have eagerly replaced all such projections with inference variables), however, this feels subtle and not worth it imo.
With this, I think we should not do anything here. I expect that #129073 will fix this again. THe underlying issue of fatal overflow introducing order dependence still persists however. cc @compiler-errors please test the minimization
OK, I assume them we want to keep this issue open until merge of #129073
(else, LMK if it can be closed)