BCT candidates=50

No-emit type-check timing for bct candidates=50.

tsz is 6.2x faster 128 lines 9 KB

Timing

tsz
62.75ms
tsgo
386.21ms

Files

// Best Common Type (BCT) O(N²) stress test
// Targets: infer.rs best_common_type() — N candidates × N subtype checks
//
// Each class in the hierarchy is a distinct type candidate. When the compiler
// infers the type of an array literal or multi-return function, it must find
// the "best common type" by checking every candidate against every other.

class Base { base: string = ''; }
class Derived0 extends Base { prop0: number = 0; }
class Derived1 extends Base { prop1: number = 1; }
class Derived2 extends Base { prop2: number = 2; }
class Derived3 extends Base { prop3: number = 3; }
class Derived4 extends Base { prop4: number = 4; }
class Derived5 extends Base { prop5: number = 5; }
class Derived6 extends Base { prop6: number = 6; }
class Derived7 extends Base { prop7: number = 7; }
class Derived8 extends Base { prop8: number = 8; }
class Derived9 extends Base { prop9: number = 9; }
class Derived10 extends Base { prop10: number = 10; }
class Derived11 extends Base { prop11: number = 11; }
class Derived12 extends Base { prop12: number = 12; }
class Derived13 extends Base { prop13: number = 13; }
class Derived14 extends Base { prop14: number = 14; }
class Derived15 extends Base { prop15: number = 15; }
class Derived16 extends Base { prop16: number = 16; }
class Derived17 extends Base { prop17: number = 17; }
class Derived18 extends Base { prop18: number = 18; }
class Derived19 extends Base { prop19: number = 19; }
class Derived20 extends Base { prop20: number = 20; }
class Derived21 extends Base { prop21: number = 21; }
class Derived22 extends Base { prop22: number = 22; }
class Derived23 extends Base { prop23: number = 23; }
class Derived24 extends Base { prop24: number = 24; }
class Derived25 extends Base { prop25: number = 25; }
class Derived26 extends Base { prop26: number = 26; }
class Derived27 extends Base { prop27: number = 27; }
class Derived28 extends Base { prop28: number = 28; }
class Derived29 extends Base { prop29: number = 29; }
class Derived30 extends Base { prop30: number = 30; }
class Derived31 extends Base { prop31: number = 31; }
class Derived32 extends Base { prop32: number = 32; }
class Derived33 extends Base { prop33: number = 33; }
class Derived34 extends Base { prop34: number = 34; }
class Derived35 extends Base { prop35: number = 35; }
class Derived36 extends Base { prop36: number = 36; }
class Derived37 extends Base { prop37: number = 37; }
class Derived38 extends Base { prop38: number = 38; }
class Derived39 extends Base { prop39: number = 39; }
class Derived40 extends Base { prop40: number = 40; }
class Derived41 extends Base { prop41: number = 41; }
class Derived42 extends Base { prop42: number = 42; }
class Derived43 extends Base { prop43: number = 43; }
class Derived44 extends Base { prop44: number = 44; }
class Derived45 extends Base { prop45: number = 45; }
class Derived46 extends Base { prop46: number = 46; }
class Derived47 extends Base { prop47: number = 47; }
class Derived48 extends Base { prop48: number = 48; }
class Derived49 extends Base { prop49: number = 49; }

// Array literal: BCT must find common type among 50 candidates
const items = [new Derived0(), new Derived1(), new Derived2(), new Derived3(), new Derived4(), new Derived5(), new Derived6(), new Derived7(), new Derived8(), new Derived9(), new Derived10(), new Derived11(), new Derived12(), new Derived13(), new Derived14(), new Derived15(), new Derived16(), new Derived17(), new Derived18(), new Derived19(), new Derived20(), new Derived21(), new Derived22(), new Derived23(), new Derived24(), new Derived25(), new Derived26(), new Derived27(), new Derived28(), new Derived29(), new Derived30(), new Derived31(), new Derived32(), new Derived33(), new Derived34(), new Derived35(), new Derived36(), new Derived37(), new Derived38(), new Derived39(), new Derived40(), new Derived41(), new Derived42(), new Derived43(), new Derived44(), new Derived45(), new Derived46(), new Derived47(), new Derived48(), new Derived49()];

// Function with 50 return branches — BCT on return type inference
function pickOne(index: number) {
    if (index === 0) return new Derived0();
    if (index === 1) return new Derived1();
    if (index === 2) return new Derived2();
    if (index === 3) return new Derived3();
    if (index === 4) return new Derived4();
    if (index === 5) return new Derived5();
    if (index === 6) return new Derived6();
    if (index === 7) return new Derived7();
    if (index === 8) return new Derived8();
    if (index === 9) return new Derived9();
    if (index === 10) return new Derived10();
    if (index === 11) return new Derived11();
    if (index === 12) return new Derived12();
    if (index === 13) return new Derived13();
    if (index === 14) return new Derived14();
    if (index === 15) return new Derived15();
    if (index === 16) return new Derived16();
    if (index === 17) return new Derived17();
    if (index === 18) return new Derived18();
    if (index === 19) return new Derived19();
    if (index === 20) return new Derived20();
    if (index === 21) return new Derived21();
    if (index === 22) return new Derived22();
    if (index === 23) return new Derived23();
    if (index === 24) return new Derived24();
    if (index === 25) return new Derived25();
    if (index === 26) return new Derived26();
    if (index === 27) return new Derived27();
    if (index === 28) return new Derived28();
    if (index === 29) return new Derived29();
    if (index === 30) return new Derived30();
    if (index === 31) return new Derived31();
    if (index === 32) return new Derived32();
    if (index === 33) return new Derived33();
    if (index === 34) return new Derived34();
    if (index === 35) return new Derived35();
    if (index === 36) return new Derived36();
    if (index === 37) return new Derived37();
    if (index === 38) return new Derived38();
    if (index === 39) return new Derived39();
    if (index === 40) return new Derived40();
    if (index === 41) return new Derived41();
    if (index === 42) return new Derived42();
    if (index === 43) return new Derived43();
    if (index === 44) return new Derived44();
    if (index === 45) return new Derived45();
    if (index === 46) return new Derived46();
    if (index === 47) return new Derived47();
    if (index === 48) return new Derived48();
    if (index === 49) return new Derived49();
    return new Base();
}

// Generic calls accumulating 50 candidates
function identity<T>(x: T): T { return x; }
const mixed = [identity(new Derived0()), identity(new Derived1()), identity(new Derived2()), identity(new Derived3()), identity(new Derived4()), identity(new Derived5()), identity(new Derived6()), identity(new Derived7()), identity(new Derived8()), identity(new Derived9()), identity(new Derived10()), identity(new Derived11()), identity(new Derived12()), identity(new Derived13()), identity(new Derived14()), identity(new Derived15()), identity(new Derived16()), identity(new Derived17()), identity(new Derived18()), identity(new Derived19()), identity(new Derived20()), identity(new Derived21()), identity(new Derived22()), identity(new Derived23()), identity(new Derived24()), identity(new Derived25()), identity(new Derived26()), identity(new Derived27()), identity(new Derived28()), identity(new Derived29()), identity(new Derived30()), identity(new Derived31()), identity(new Derived32()), identity(new Derived33()), identity(new Derived34()), identity(new Derived35()), identity(new Derived36()), identity(new Derived37()), identity(new Derived38()), identity(new Derived39()), identity(new Derived40()), identity(new Derived41()), identity(new Derived42()), identity(new Derived43()), identity(new Derived44()), identity(new Derived45()), identity(new Derived46()), identity(new Derived47()), identity(new Derived48()), identity(new Derived49())];

// Ternary chain: 50 candidates for common type
declare const flag: number;
const chosen = flag === 0 ? new Derived0() : flag === 1 ? new Derived1() : flag === 2 ? new Derived2() : flag === 3 ? new Derived3() : flag === 4 ? new Derived4() : flag === 5 ? new Derived5() : flag === 6 ? new Derived6() : flag === 7 ? new Derived7() : flag === 8 ? new Derived8() : flag === 9 ? new Derived9() : flag === 10 ? new Derived10() : flag === 11 ? new Derived11() : flag === 12 ? new Derived12() : flag === 13 ? new Derived13() : flag === 14 ? new Derived14() : flag === 15 ? new Derived15() : flag === 16 ? new Derived16() : flag === 17 ? new Derived17() : flag === 18 ? new Derived18() : flag === 19 ? new Derived19() : flag === 20 ? new Derived20() : flag === 21 ? new Derived21() : flag === 22 ? new Derived22() : flag === 23 ? new Derived23() : flag === 24 ? new Derived24() : flag === 25 ? new Derived25() : flag === 26 ? new Derived26() : flag === 27 ? new Derived27() : flag === 28 ? new Derived28() : flag === 29 ? new Derived29() : flag === 30 ? new Derived30() : flag === 31 ? new Derived31() : flag === 32 ? new Derived32() : flag === 33 ? new Derived33() : flag === 34 ? new Derived34() : flag === 35 ? new Derived35() : flag === 36 ? new Derived36() : flag === 37 ? new Derived37() : flag === 38 ? new Derived38() : flag === 39 ? new Derived39() : flag === 40 ? new Derived40() : flag === 41 ? new Derived41() : flag === 42 ? new Derived42() : flag === 43 ? new Derived43() : flag === 44 ? new Derived44() : flag === 45 ? new Derived45() : flag === 46 ? new Derived46() : flag === 47 ? new Derived47() : flag === 48 ? new Derived48() : flag === 49 ? new Derived49() : new Base();

const _base: Base = items[0];
const _picked: Base = pickOne(0);
const _chosen: Base = chosen;