Open
Description
There are two factors here, which we've spotted combined in the wild:
- we hoist all
type X: ...;
bounds to the trait-level, i.e.:is sugar for:trait Trait { type X: A + B; type Y: C + D; }
trait Trait where Self::X: A, Self::X: B, Self::Y: C, Self::Y: D, { type X; type Y; }
- I doubt we can do much about this, perhaps group/index the bounds?
- lookup of
<_ as Foo>::X: Bar
inFoo
'swhere
clauses appears to be quadratic- this wouldn't have a noticeable impact without 1.
- probably easier to fix, I would've assumed it was already linear
And here's our stress test - apologies for the macro, but it takes a lot to push it into multiple seconds (the version in the wild had more sophisticated, and actually useful, macros):
macro_rules! stress {
(type $name:ident: $($i:expr,)*) => {
type $name: $(From<[(); $i]> + Into<[(); $i]> +)*;
};
(fn $($underscore:tt)*) => {
const _: () = {
$({fn _f<T: Trait>() {
#[derive(Copy, Clone)]
struct Foo<X>(X);
let $underscore = Foo(T::X::default()).clone();
}})*
};
};
}
trait Trait {
type X: Copy + Default;
// The bounds would normally be on many separate
// associated types, but that makes no difference.
stress!(type _Unused:
00, 01, 02, 03, 04, 05, 06, 07, 08, 09,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
// Uncomment to (almost) quadruple compile time:
//20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
//30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
// Add more to raise the total time to minutes.
);
}
stress!(fn
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
);
Using -Zself-profile
and summarize
, we get this (times are total "self" times):
Query | 20 (00 -19 ) |
40 (00 -39 ) |
Slowdown |
---|---|---|---|
type_op_prove_predicate |
2.52s | 9.17s | 3.64x |
typeck_tables_of |
1.78s | 5.83s | 3.28x |
check_item_well_formed |
1.43s | 4.47s | 3.13x |
cc @rust-lang/wg-traits