-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Where clauses increase compilation time and memory use dramatically. #26325
Comments
It actually has nothing to do with the presence/absence of a method, this compiles in a similar amount of time: https://play.rust-lang.org/?gist=d9c18a3c48d6c0584579&version=nightly It's the where clause, which, yes, is required in this case, but only due to the method returning |
@Aatch I didn't think to specifically test whether it was the added information in the The big question to me is why does the function having output type In the Similarly, here is another example that I've just stumbled across: trait Marker {}
struct Bob;
impl Marker for Bob {}
trait DoNothing {
type Output;
}
impl DoNothing for Bob {
type Output = Bob;
}
struct Dude<M: Marker>(M);
// Conflicting implementation with this line uncommented,
// Marker not implemented for <Bob as DoNothing>::Output error with it commented
impl Marker for <Bob as DoNothing>::Output {}
const b: Dude<<Bob as DoNothing>::Output> = Dude(Bob);
fn main() {
} The compiler is able to check that |
The Your last example is another (separate) bug. |
The final example no longer compiles. When you write programs in the type system the type checker has to execute said programs via type checking so it is expected that it would impact compilation performance. Overall we have a lot of room for optimization in the where clause implementation but I'm not sure if this issue has a directly actionable solution. |
This is really hurting us freaks who try to implement any type-level shenanigans – I believe this also affects compile times for others in the wild.
Currently having those where clauses in the code means compilation time is growing exponentially with the number of types used. I'm not completely privvy to the details of the type checker implementation, but I'm quite certain the search space could use a good bit of pruning. |
If Rust is anything like ML, then typechecking is EXP-complete and provably intractable in the worst case. However, this involves cases where types turn out to be exponentially large and so probably does not apply here. |
Adding the same where-clause to the |
This hasn't been updated in a long time. Anybody have new numbers? |
It seems fixed; the example that used to timeout and gobble ram now has no problems compiling. |
When implementing a trait with a member function (vs. one without), the compiler requires more information and takes much longer to compile.
Consider the following two implementations of addition over Peano numbers as types:
First, using
std::ops::Add
: http://is.gd/7tO1cKSecond, using a custom trait for addition,
AddPeano
, that has only an associated type and no member functions: http://is.gd/byhqSnThe key difference is here:
Using
AddPeano
,Using
std::ops::Add
,Without the
where
clause, the compiler gives the errorIn
main()
for both of those examples, theAdd
traits are used for successive doubling until the number32
is reached. UsingAddPeano
, playpen finishes in moments, whereas usingAdd
it triggers playpen's timeout and fails to compile.I have had similar results locally ... even using up 8 GB of ram in the case of the
std::ops
version while the version without a function would compile virtually instantly.The text was updated successfully, but these errors were encountered: