Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 223

Show
Ignore:
Timestamp:
10/29/09 04:58:14 (15 years ago)
Author:
walter
Message:

bugzilla 3102

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/expression.c

    r222 r223  
    13921392        case Tenum: 
    13931393        { 
    13941394        TypeEnum *te = (TypeEnum *)t; 
    13951395        t = te->sym->memtype; 
    13961396        continue; 
    13971397        } 
    13981398 
    13991399        case Ttypedef: 
    14001400        { 
    14011401        TypeTypedef *tt = (TypeTypedef *)t; 
    14021402        t = tt->sym->basetype; 
    14031403        continue; 
    14041404        } 
    14051405 
    14061406        default: 
    14071407        /* This can happen if errors, such as 
    14081408         * the type is painted on like in fromConstInitializer(). 
    14091409         */ 
    14101410        if (!global.errors) 
    14111411        { 
    1412 printf("ty = %d, %d\n", type->ty, t->ty); 
    1413 if (type->ty == Tenum) printf("test1\n"); 
    14141412            type->print(); 
    14151413            assert(0); 
    14161414        } 
    14171415        break; 
    14181416    } 
    14191417    break; 
    14201418    } 
    14211419    return value; 
    14221420} 
    14231421 
    14241422real_t IntegerExp::toReal() 
    14251423{ 
    14261424    Type *t; 
    14271425 
    14281426    toInteger(); 
    14291427    t = type->toBasetype(); 
    14301428    if (t->ty == Tuns64) 
    14311429    return (real_t)(d_uns64)value; 
    14321430    else 
    14331431    return (real_t)(d_int64)value; 
     
    47344732    p->setDim(parameters->dim); 
    47354733    for (int i = 0; i < p->dim; i++) 
    47364734    {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    47374735        p->data[i] = (void *)tp->syntaxCopy(); 
    47384736    } 
    47394737    } 
    47404738 
    47414739    return new IsExp(loc, 
    47424740    targ->syntaxCopy(), 
    47434741    id, 
    47444742    tok, 
    47454743    tspec ? tspec->syntaxCopy() : NULL, 
    47464744    tok2, 
    47474745    p); 
    47484746} 
    47494747 
    47504748Expression *IsExp::semantic(Scope *sc) 
    47514749{   Type *tded; 
    47524750 
    47534751    /* is(targ id tok tspec) 
     4752     * is(targ id :  tok2) 
    47544753     * is(targ id == tok2) 
    47554754     */ 
    47564755 
    47574756    //printf("IsExp::semantic(%s)\n", toChars()); 
    47584757    if (id && !(sc->flags & SCOPEstaticif)) 
    47594758    error("can only declare type aliases within static if conditionals"); 
    47604759 
    47614760    Type *t = targ->trySemantic(loc, sc); 
    47624761    if (!t) 
    47634762    goto Lno;           // errors, so condition is false 
    47644763    targ = t; 
    47654764    if (tok2 != TOKreserved) 
    47664765    { 
    47674766    switch (tok2) 
    47684767    { 
    47694768        case TOKtypedef: 
    47704769        if (targ->ty != Ttypedef) 
    47714770            goto Lno; 
    47724771        tded = ((TypeTypedef *)targ)->sym->basetype; 
    47734772        break; 
     
    48864885        else if (targ->ty == Tpointer && 
    48874886             ((TypePointer *)targ)->next->ty == Tfunction) 
    48884887        {   tded = ((TypePointer *)targ)->next; 
    48894888            tded = ((TypeFunction *)tded)->next; 
    48904889        } 
    48914890        else 
    48924891            goto Lno; 
    48934892        break; 
    48944893 
    48954894        default: 
    48964895        assert(0); 
    48974896    } 
    48984897    goto Lyes; 
    48994898    } 
    49004899    else if (id && tspec) 
    49014900    { 
    49024901    /* Evaluate to TRUE if targ matches tspec. 
    49034902     * If TRUE, declare id as an alias for the specialized type. 
    49044903     */ 
    49054904 
    4906     MATCH m; 
    49074905    assert(parameters && parameters->dim); 
    49084906 
    49094907    Objects dedtypes; 
    49104908    dedtypes.setDim(parameters->dim); 
    49114909    dedtypes.zero(); 
    49124910 
    4913     m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 
     4911    MATCH m = targ->deduceType(NULL, tspec, parameters, &dedtypes); 
     4912//printf("targ: %s\n", targ->toChars()); 
     4913//printf("tspec: %s\n", tspec->toChars()); 
     4914//printf("test1 %d\n", m); 
    49144915    if (m == MATCHnomatch || 
    49154916        (m != MATCHexact && tok == TOKequal)) 
    49164917    { 
    49174918        goto Lno; 
    49184919    } 
    49194920    else 
    49204921    { 
    49214922        tded = (Type *)dedtypes.data[0]; 
    49224923        if (!tded) 
    49234924        tded = targ; 
    49244925 
    49254926        Objects tiargs; 
    49264927        tiargs.setDim(1); 
    49274928        tiargs.data[0] = (void *)targ; 
    49284929 
    49294930        /* Declare trailing parameters 
    49304931         */ 
    49314932        for (int i = 1; i < parameters->dim; i++) 
    49324933        {   TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    49334934        Declaration *s = NULL; 
  • trunk/src/mtype.c

    r222 r223  
    328328 *  MATCHequal  'this' == 'to' 
    329329 *  MATCHconst  'to' is const 
    330330 *  MATCHnomatch    conversion to mutable or invariant 
    331331 */ 
    332332 
    333333MATCH Type::constConv(Type *to) 
    334334{ 
    335335    if (equals(to)) 
    336336    return MATCHexact; 
    337337    if (ty == to->ty && to->mod == MODconst) 
    338338    return MATCHconst; 
    339339    return MATCHnomatch; 
    340340} 
    341341 
    342342/******************************** 
    343343 * Convert to 'const'. 
    344344 */ 
    345345 
    346346Type *Type::constOf() 
    347347{ 
    348 #if 0 
    349     //printf("Type::constOf() %p %s\n", this, toChars()); 
    350     if (isConst()) 
    351     return this; 
    352     if (cto) 
    353     return cto; 
    354     Type *t = makeConst(); 
    355     t = t->merge(); 
    356     cto = t; 
    357     if (ito) 
    358     ito->cto = t; 
    359     //if (t->nextOf()) assert(t->nextOf()->isConst()); 
    360     //printf("-Type::constOf() %p %s\n", t, toChars()); 
    361     return t; 
    362 #else 
    363348    //printf("Type::constOf() %p %s\n", this, toChars()); 
    364349    if (mod == MODconst) 
    365350    return this; 
    366351    if (cto) 
    367352    {   assert(cto->mod == MODconst); 
    368353    return cto; 
    369354    } 
    370355    Type *t = makeConst(); 
    371356    t = t->merge(); 
    372357    t->fixTo(this); 
    373358    //printf("-Type::constOf() %p %s\n", t, toChars()); 
    374359    return t; 
    375 #endif 
    376360} 
    377361 
    378362/******************************** 
    379363 * Convert to 'immutable'. 
    380364 */ 
    381365 
    382366Type *Type::invariantOf() 
    383367{ 
    384 #if 0 
    385     //printf("Type::invariantOf() %p %s\n", this, toChars()); 
    386     if (isInvariant()) 
    387     { 
    388     return this; 
    389     } 
    390     if (ito) 
    391     { 
    392     //if (!ito->isInvariant()) printf("\tito is %p %s\n", ito, ito->toChars()); 
    393     assert(ito->isInvariant()); 
    394     return ito; 
    395     } 
    396     Type *t = makeInvariant(); 
    397     t = t->merge(); 
    398     ito = t; 
    399     if (cto) 
    400     cto->ito = t; 
    401 #if 0 // fails for function types 
    402     if (t->nextOf() && !t->nextOf()->isInvariant()) 
    403     { 
    404     assert(0); 
    405     } 
    406 #endif 
    407     //printf("\t%p\n", t); 
    408     return t; 
    409 #else 
    410368    //printf("Type::invariantOf() %p %s\n", this, toChars()); 
    411369    if (isInvariant()) 
    412370    { 
    413371    return this; 
    414372    } 
    415373    if (ito) 
    416374    { 
    417375    assert(ito->isInvariant()); 
    418376    return ito; 
    419377    } 
    420378    Type *t = makeInvariant(); 
    421379    t = t->merge(); 
    422380    t->fixTo(this); 
    423381    //printf("\t%p\n", t); 
    424382    return t; 
    425 #endif 
    426383} 
    427384 
    428385/******************************** 
    429386 * Make type mutable. 
    430387 */ 
    431388 
    432389Type *Type::mutableOf() 
    433390{ 
    434 #if 0 
    435     //printf("Type::mutableOf() %p, %s\n", this, toChars()); 
    436     Type *t = this; 
    437     if (isConst()) 
    438     {   t = cto; 
    439     assert(!t || t->isMutable()); 
    440     } 
    441     else if (isInvariant()) 
    442     {   t = ito; 
    443     assert(!t || t->isMutable()); 
    444     } 
    445     if (!t) 
    446     { 
    447     unsigned sz = sizeTy[ty]; 
    448     t = (Type *)mem.malloc(sz); 
    449     memcpy(t, this, sz); 
    450     t->mod = 0; 
    451     t->deco = NULL; 
    452     t->arrayof = NULL; 
    453     t->pto = NULL; 
    454     t->rto = NULL; 
    455     t->cto = NULL; 
    456     t->ito = NULL; 
    457     t->sto = NULL; 
    458     t->scto = NULL; 
    459     t->vtinfo = NULL; 
    460     if (ty == Tsarray) 
    461     {   TypeSArray *ta = (TypeSArray *)t; 
    462         //ta->next = ta->next->mutableOf(); 
    463     } 
    464     t = t->merge(); 
    465     if (isConst()) 
    466     {   cto = t; 
    467         t->cto = this; 
    468         if (ito) 
    469         ito->cto = this; 
    470     } 
    471     else if (isInvariant()) 
    472     {   ito = t; 
    473         t->ito = this; 
    474         if (cto) 
    475         cto->ito = this; 
    476     } 
    477     } 
    478     return t; 
    479 #else 
    480391    //printf("Type::mutableOf() %p, %s\n", this, toChars()); 
    481392    Type *t = this; 
    482393    if (isConst()) 
    483394    {   if (isShared()) 
    484395        t = sto;        // shared const => shared 
    485396    else 
    486397        t = cto; 
    487398    assert(!t || t->isMutable()); 
    488399    } 
    489400    else if (isInvariant()) 
    490401    {   t = ito; 
    491402    assert(!t || (t->isMutable() && !t->isShared())); 
    492403    } 
    493404    if (!t) 
    494405    { 
    495406    unsigned sz = sizeTy[ty]; 
    496407    t = (Type *)mem.malloc(sz); 
    497408    memcpy(t, this, sz); 
    498     t->mod = 0
     409    t->mod = mod & MODshared
    499410    t->deco = NULL; 
    500411    t->arrayof = NULL; 
    501412    t->pto = NULL; 
    502413    t->rto = NULL; 
    503414    t->cto = NULL; 
    504415    t->ito = NULL; 
    505416    t->sto = NULL; 
    506417    t->scto = NULL; 
    507418    t->vtinfo = NULL; 
    508419    t = t->merge(); 
    509420 
    510421    t->fixTo(this); 
    511422 
    512423    switch (mod) 
    513424    { 
    514425        case MODconst: 
    515426        t->cto = this; 
    516427        break; 
    517428 
    518429        case MODinvariant: 
    519430        t->ito = this; 
    520431        break; 
    521432 
    522         case MODshared: 
    523         t->sto = this; 
    524         break; 
    525  
    526433        case MODshared | MODconst: 
    527434        t->scto = this; 
    528435        break; 
    529436 
    530437        default: 
    531438        assert(0); 
    532439    } 
    533440    } 
    534441    return t; 
    535 #endif 
    536442} 
    537443 
    538444Type *Type::sharedOf() 
    539445{ 
    540446    //printf("Type::sharedOf() %p, %s\n", this, toChars()); 
    541447    if (mod == MODshared) 
    542448    { 
    543449    return this; 
    544450    } 
    545451    if (sto) 
    546452    { 
    547453    assert(sto->isShared()); 
    548454    return sto; 
    549455    } 
    550456    Type *t = makeShared(); 
    551457    t = t->merge(); 
    552458    t->fixTo(this); 
    553459    //printf("\t%p\n", t); 
    554460    return t; 
    555461} 
    556462 
    557463Type *Type::sharedConstOf() 
    558464{ 
    559465    //printf("Type::sharedConstOf() %p, %s\n", this, toChars()); 
    560466    if (mod == (MODshared | MODconst)) 
    561467    { 
    562468    return this; 
    563469    } 
    564470    if (scto) 
    565471    { 
    566472    assert(scto->mod == (MODshared | MODconst)); 
    567473    return scto; 
    568474    } 
    569475    Type *t = makeSharedConst(); 
    570476    t = t->merge(); 
    571477    t->fixTo(this); 
    572478    //printf("\t%p\n", t); 
    573479    return t; 
    574480} 
    575481 
     482 
     483/******************************** 
     484 * Make type unshared. 
     485 */ 
     486 
     487Type *Type::unSharedOf() 
     488{ 
     489    //printf("Type::unSharedOf() %p, %s\n", this, toChars()); 
     490    Type *t = this; 
     491 
     492    if (isShared()) 
     493    { 
     494    if (isConst()) 
     495        t = cto;    // shared const => const 
     496    else 
     497        t = sto; 
     498    assert(!t || !t->isShared()); 
     499    } 
     500 
     501    if (!t) 
     502    { 
     503    unsigned sz = sizeTy[ty]; 
     504    t = (Type *)mem.malloc(sz); 
     505    memcpy(t, this, sz); 
     506    t->mod = mod & ~MODshared; 
     507    t->deco = NULL; 
     508    t->arrayof = NULL; 
     509    t->pto = NULL; 
     510    t->rto = NULL; 
     511    t->cto = NULL; 
     512    t->ito = NULL; 
     513    t->sto = NULL; 
     514    t->scto = NULL; 
     515    t->vtinfo = NULL; 
     516    t = t->merge(); 
     517 
     518    t->fixTo(this); 
     519 
     520    switch (mod) 
     521    { 
     522        case MODshared: 
     523        t->sto = this; 
     524        break; 
     525 
     526        case MODshared | MODconst: 
     527        t->scto = this; 
     528        break; 
     529 
     530        default: 
     531        assert(0); 
     532    } 
     533    } 
     534    assert(!t->isShared()); 
     535    return t; 
     536} 
    576537 
    577538/********************************** 
    578539 * For our new type 'this', which is type-constructed from t, 
    579540 * fill in the cto, ito, sto, scto shortcuts. 
    580541 */ 
    581542 
    582543void Type::fixTo(Type *t) 
    583544{ 
    584545    ito = t->ito; 
    585546#if 0 
    586547    /* Cannot do these because these are not fully transitive: 
    587548     * there can be a shared ptr to immutable, for example. 
    588549     * Immutable subtypes are always immutable, though. 
    589550     */ 
    590551    cto = t->cto; 
    591552    sto = t->sto; 
    592553    scto = t->scto; 
    593554#endif 
    594555 
    595556    assert(mod != t->mod); 
  • trunk/src/mtype.h

    r221 r223  
    9898    Ttuple, 
    9999    Tslice, 
    100100    Treturn, 
    101101    TMAX 
    102102}; 
    103103typedef unsigned char TY;   // ENUMTY 
    104104 
    105105#define Tascii Tchar 
    106106 
    107107extern int Tsize_t; 
    108108extern int Tptrdiff_t; 
    109109 
    110110 
    111111struct Type : Object 
    112112{ 
    113113    TY ty; 
    114114    unsigned char mod;  // modifiers MODxxxx 
    115115    /* pick this order of numbers so switch statements work better 
    116116     */ 
    117117    #define MODconst     1  // type is const 
    118     #define MODinvariant 4  // type is invariant 
     118    #define MODinvariant 4  // type is immutable 
     119    #define MODimmutable 4  // type is immutable 
    119120    #define MODshared    2  // type is shared 
    120121    char *deco; 
    121122 
    122123    /* These are cached values that are lazily evaluated by constOf(), invariantOf(), etc. 
    123124     * They should not be referenced by anybody but mtype.c. 
    124125     * They can be NULL if not lazily evaluated yet. 
    125126     * Note that there is no "shared immutable", because that is just immutable 
    126127     */ 
    127128 
    128129    Type *cto;      // MODconst ? mutable version of this type : const version 
    129130    Type *ito;      // MODinvariant ? mutable version of this type : invariant version 
    130131    Type *sto;      // MODshared ? mutable version of this type : shared mutable version 
    131132    Type *scto;     // MODshared|MODconst ? mutable version of this type : shared const version 
    132133 
    133134    Type *pto;      // merged pointer to this type 
    134135    Type *rto;      // reference to this type 
    135136    Type *arrayof;  // array of this type 
    136137    TypeInfoDeclaration *vtinfo;    // TypeInfo object for this Type 
    137138 
    138139    type *ctype;    // for back end 
     
    236237    virtual int isreal(); 
    237238    virtual int isimaginary(); 
    238239    virtual int iscomplex(); 
    239240    virtual int isscalar(); 
    240241    virtual int isunsigned(); 
    241242    virtual int isauto(); 
    242243    virtual int isString(); 
    243244    virtual int isAssignable(); 
    244245    virtual int checkBoolean(); // if can be converted to boolean value 
    245246    virtual void checkDeprecated(Loc loc, Scope *sc); 
    246247    int isConst()   { return mod & MODconst; } 
    247248    int isInvariant()   { return mod & MODinvariant; } 
    248249    int isMutable() { return !(mod & (MODconst | MODinvariant)); } 
    249250    int isShared()  { return mod & MODshared; } 
    250251    int isSharedConst() { return mod == (MODshared | MODconst); } 
    251252    Type *constOf(); 
    252253    Type *invariantOf(); 
    253254    Type *mutableOf(); 
    254255    Type *sharedOf(); 
    255256    Type *sharedConstOf(); 
     257    Type *unSharedOf(); 
    256258    void fixTo(Type *t); 
    257259    void check(); 
    258260    Type *castMod(unsigned mod); 
    259261    Type *addMod(unsigned mod); 
    260262    Type *addStorageClass(unsigned stc); 
    261263    Type *pointerTo(); 
    262264    Type *referenceTo(); 
    263265    Type *arrayOf(); 
    264266    virtual Type *makeConst(); 
    265267    virtual Type *makeInvariant(); 
    266268    virtual Type *makeShared(); 
    267269    virtual Type *makeSharedConst(); 
    268270    virtual Dsymbol *toDsymbol(Scope *sc); 
    269271    virtual Type *toBasetype(); 
    270272    virtual Type *toHeadMutable(); 
    271273    virtual int isBaseOf(Type *t, int *poffset); 
    272274    virtual MATCH constConv(Type *to); 
    273275    virtual MATCH implicitConvTo(Type *to); 
    274276    virtual ClassDeclaration *isClassHandle(); 
    275277    virtual Expression *getProperty(Loc loc, Identifier *ident); 
  • trunk/src/template.c

    r202 r223  
    15741574        TemplateParameter *tp = (TemplateParameter *)parameters->data[0]; 
    15751575        loc = tp->loc; 
    15761576        } 
    15771577 
    15781578        /* BUG: what if tparam is a template instance, that 
    15791579         * has as an argument another Tident? 
    15801580         */ 
    15811581        tparam = tparam->semantic(loc, sc); 
    15821582        assert(tparam->ty != Tident); 
    15831583        return deduceType(sc, tparam, parameters, dedtypes); 
    15841584    } 
    15851585 
    15861586    TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 
    15871587 
    15881588    // Found the corresponding parameter tp 
    15891589    if (!tp->isTemplateTypeParameter()) 
    15901590        goto Lnomatch; 
    15911591    Type *tt = this; 
    15921592    Type *at = (Type *)dedtypes->data[i]; 
    15931593 
    1594     // 3*3 == 9 cases 
    1595     if (tparam->isMutable()) 
    1596     {   // foo(U:U) T            => T 
    1597         // foo(U:U) const(T)     => const(T) 
    1598         // foo(U:U) invariant(T) => invariant(T) 
    1599         if (!at) 
    1600         {   dedtypes->data[i] = (void *)this; 
    1601         goto Lexact; 
    1602         } 
    1603     } 
    1604     else if (mod == tparam->mod) 
    1605     {   // foo(U:const(U))     const(T)     => T 
    1606         // foo(U:invariant(U)) invariant(T) => T 
    1607         tt = mutableOf(); 
    1608         if (!at) 
    1609         {   dedtypes->data[i] = (void *)tt; 
    1610         goto Lexact; 
    1611         } 
    1612     } 
    1613     else if (tparam->isConst()) 
    1614     {   // foo(U:const(U)) T            => T 
    1615         // foo(U:const(U)) invariant(T) => T 
    1616         tt = mutableOf(); 
    1617         if (!at) 
    1618         {   dedtypes->data[i] = (void *)tt; 
    1619         goto Lconst; 
    1620         } 
    1621     } 
    1622     else 
    1623     {   // foo(U:invariant(U)) T        => nomatch 
    1624         // foo(U:invariant(U)) const(T) => nomatch 
    1625         if (!at) 
    1626         goto Lnomatch; 
    1627     } 
     1594    // 5*5 == 25 cases 
     1595 
     1596    #define X(U,T)  ((U) << 3) | (T) 
     1597    switch (X(tparam->mod, mod)) 
     1598    { 
     1599        case X(0, 0): 
     1600        case X(0, MODconst): 
     1601        case X(0, MODinvariant): 
     1602        case X(0, MODshared): 
     1603        case X(0, MODconst | MODshared): 
     1604        // foo(U:U) T                              => T 
     1605        // foo(U:U) const(T)                       => const(T) 
     1606        // foo(U:U) immutable(T)                   => immutable(T) 
     1607        // foo(U:U) shared(T)                      => shared(T) 
     1608        // foo(U:U) const(shared(T))               => const(shared(T)) 
     1609        if (!at) 
     1610        {   dedtypes->data[i] = (void *)tt; 
     1611            goto Lexact; 
     1612        } 
     1613        break; 
     1614 
     1615        case X(MODconst, MODconst): 
     1616        case X(MODinvariant, MODinvariant): 
     1617        case X(MODshared, MODshared): 
     1618        case X(MODconst | MODshared, MODconst | MODshared): 
     1619        // foo(U:const(U))        const(T)         => T 
     1620        // foo(U:immutable(U))    immutable(T)     => T 
     1621        // foo(U:shared(U))       shared(T)        => T 
     1622        // foo(U:const(shared(U)) const(shared(T)) => T 
     1623        tt = mutableOf()->unSharedOf(); 
     1624        if (!at) 
     1625        {   dedtypes->data[i] = (void *)tt; 
     1626            goto Lexact; 
     1627        } 
     1628        break; 
     1629 
     1630        case X(MODconst, 0): 
     1631        case X(MODconst, MODimmutable): 
     1632        case X(MODconst, MODconst | MODshared): 
     1633        case X(MODconst | MODshared, MODimmutable): 
     1634        // foo(U:const(U)) T                       => T 
     1635        // foo(U:const(U)) immutable(T)            => T 
     1636        // foo(U:const(U)) const(shared(T))        => shared(T) 
     1637        // foo(U:const(shared(U)) immutable(T)     => T 
     1638        tt = mutableOf(); 
     1639        if (!at) 
     1640        {   dedtypes->data[i] = (void *)tt; 
     1641            goto Lconst; 
     1642        } 
     1643        break; 
     1644 
     1645        case X(MODshared, MODconst | MODshared): 
     1646        case X(MODconst | MODshared, MODshared): 
     1647        // foo(U:shared(U)) const(shared(T))       => const(T) 
     1648        // foo(U:const(shared(U)) shared(T)        => T 
     1649        tt = unSharedOf(); 
     1650        if (!at) 
     1651        {   dedtypes->data[i] = (void *)tt; 
     1652            goto Lconst; 
     1653        } 
     1654        break; 
     1655 
     1656        case X(MODimmutable,         0): 
     1657        case X(MODimmutable,         MODconst): 
     1658        case X(MODimmutable,         MODshared): 
     1659        case X(MODimmutable,         MODconst | MODshared): 
     1660        case X(MODconst,             MODshared): 
     1661        case X(MODshared,            0): 
     1662        case X(MODshared,            MODconst): 
     1663        case X(MODshared,            MODimmutable): 
     1664        case X(MODconst | MODshared, 0): 
     1665        case X(MODconst | MODshared, MODconst): 
     1666        // foo(U:immutable(U)) T                   => nomatch 
     1667        // foo(U:immutable(U)) const(T)            => nomatch 
     1668        // foo(U:immutable(U)) shared(T)           => nomatch 
     1669        // foo(U:immutable(U)) const(shared(T))    => nomatch 
     1670        // foo(U:const(U)) shared(T)               => nomatch 
     1671        // foo(U:shared(U)) T                      => nomatch 
     1672        // foo(U:shared(U)) const(T)               => nomatch 
     1673        // foo(U:shared(U)) immutable(T)           => nomatch 
     1674        // foo(U:const(shared(U)) T                => nomatch 
     1675        // foo(U:const(shared(U)) const(T)         => nomatch 
     1676        //if (!at) 
     1677            goto Lnomatch; 
     1678        break; 
     1679 
     1680        default: 
     1681        assert(0); 
     1682    } 
     1683    #undef X 
    16281684 
    16291685    if (tt->equals(at)) 
    16301686        goto Lexact; 
    16311687    else if (tt->ty == Tclass && at->ty == Tclass) 
    16321688    { 
    16331689        return tt->implicitConvTo(at); 
    16341690    } 
    16351691    else if (tt->ty == Tsarray && at->ty == Tarray && 
    16361692        tt->nextOf()->implicitConvTo(at->nextOf()) >= MATCHconst) 
    16371693    { 
    16381694        goto Lexact; 
    16391695    } 
    16401696    else 
    16411697        goto Lnomatch; 
    16421698    } 
    16431699 
    16441700    if (ty != tparam->ty) 
    16451701    return implicitConvTo(tparam); 
    16461702//  goto Lnomatch; 
    16471703