1*67e74705SXin Li// RUN: %clang_cc1 -fblocks -fsyntax-only -std=c++11 %s -verify 2*67e74705SXin Li// 3*67e74705SXin Li// Test the substitution of type arguments for type parameters when 4*67e74705SXin Li// using parameterized classes in Objective-C. 5*67e74705SXin Li 6*67e74705SXin Li__attribute__((objc_root_class)) 7*67e74705SXin Li@interface NSObject 8*67e74705SXin Li+ (instancetype)alloc; 9*67e74705SXin Li- (instancetype)init; 10*67e74705SXin Li@end 11*67e74705SXin Li 12*67e74705SXin Li@protocol NSCopying 13*67e74705SXin Li@end 14*67e74705SXin Li 15*67e74705SXin Li@interface NSString : NSObject <NSCopying> 16*67e74705SXin Li@end 17*67e74705SXin Li 18*67e74705SXin Li@interface NSMutableString : NSString 19*67e74705SXin Li@end 20*67e74705SXin Li 21*67e74705SXin Li@interface NSNumber : NSObject <NSCopying> 22*67e74705SXin Li@end 23*67e74705SXin Li 24*67e74705SXin Li@interface NSArray<T> : NSObject <NSCopying> { 25*67e74705SXin Li@public 26*67e74705SXin Li T *data; // don't try this at home 27*67e74705SXin Li} 28*67e74705SXin Li- (T)objectAtIndexedSubscript:(int)index; 29*67e74705SXin Li+ (NSArray<T> *)array; 30*67e74705SXin Li@property (copy,nonatomic) T lastObject; 31*67e74705SXin Li@end 32*67e74705SXin Li 33*67e74705SXin Li@interface NSMutableArray<T> : NSArray<T> 34*67e74705SXin Li-(instancetype)initWithArray:(NSArray<T> *)array; // expected-note{{passing argument}} 35*67e74705SXin Li- (void)setObject:(T)object atIndexedSubscript:(int)index; // expected-note 2{{passing argument to parameter 'object' here}} 36*67e74705SXin Li@end 37*67e74705SXin Li 38*67e74705SXin Li@interface NSStringArray : NSArray<NSString *> 39*67e74705SXin Li@end 40*67e74705SXin Li 41*67e74705SXin Li@interface NSSet<T> : NSObject <NSCopying> 42*67e74705SXin Li- (T)firstObject; 43*67e74705SXin Li@property (nonatomic, copy) NSArray<T> *allObjects; 44*67e74705SXin Li@end 45*67e74705SXin Li 46*67e74705SXin Li// Parameterized inheritance (simple case) 47*67e74705SXin Li@interface NSMutableSet<U : id<NSCopying>> : NSSet<U> 48*67e74705SXin Li- (void)addObject:(U)object; // expected-note 7{{passing argument to parameter 'object' here}} 49*67e74705SXin Li@end 50*67e74705SXin Li 51*67e74705SXin Li@interface Widget : NSObject <NSCopying> 52*67e74705SXin Li@end 53*67e74705SXin Li 54*67e74705SXin Li// Non-parameterized class inheriting from a specialization of a 55*67e74705SXin Li// parameterized class. 56*67e74705SXin Li@interface WidgetSet : NSMutableSet<Widget *> 57*67e74705SXin Li@end 58*67e74705SXin Li 59*67e74705SXin Li// Parameterized inheritance with a more interesting transformation in 60*67e74705SXin Li// the specialization. 61*67e74705SXin Li@interface MutableSetOfArrays<T> : NSMutableSet<NSArray<T>*> 62*67e74705SXin Li@end 63*67e74705SXin Li 64*67e74705SXin Li// Inheriting from an unspecialized form of a parameterized type. 65*67e74705SXin Li@interface UntypedMutableSet : NSMutableSet 66*67e74705SXin Li@end 67*67e74705SXin Li 68*67e74705SXin Li@interface Window : NSObject 69*67e74705SXin Li@end 70*67e74705SXin Li 71*67e74705SXin Li@interface NSDictionary<K, V> : NSObject <NSCopying> 72*67e74705SXin Li- (V)objectForKeyedSubscript:(K)key; // expected-note 2{{parameter 'key'}} 73*67e74705SXin Li@end 74*67e74705SXin Li 75*67e74705SXin Li@interface NSMutableDictionary<K : id<NSCopying>, V> : NSDictionary<K, V> // expected-note 2{{type parameter 'K' declared here}} \ 76*67e74705SXin Li// expected-note 2{{'NSMutableDictionary' declared here}} 77*67e74705SXin Li- (void)setObject:(V)object forKeyedSubscript:(K)key; 78*67e74705SXin Li// expected-note@-1 {{parameter 'object' here}} 79*67e74705SXin Li// expected-note@-2 {{parameter 'object' here}} 80*67e74705SXin Li// expected-note@-3 {{parameter 'key' here}} 81*67e74705SXin Li// expected-note@-4 {{parameter 'key' here}} 82*67e74705SXin Li 83*67e74705SXin Li@property (strong) K someRandomKey; 84*67e74705SXin Li@end 85*67e74705SXin Li 86*67e74705SXin Li@interface WindowArray : NSArray<Window *> 87*67e74705SXin Li@end 88*67e74705SXin Li 89*67e74705SXin Li@interface NSSet<T> (Searching) 90*67e74705SXin Li- (T)findObject:(T)object; 91*67e74705SXin Li@end 92*67e74705SXin Li 93*67e74705SXin Li 94*67e74705SXin Li// -------------------------------------------------------------------------- 95*67e74705SXin Li// Message sends. 96*67e74705SXin Li// -------------------------------------------------------------------------- 97*67e74705SXin Livoid test_message_send_result( 98*67e74705SXin Li NSSet<NSString *> *stringSet, 99*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 100*67e74705SXin Li WidgetSet *widgetSet, 101*67e74705SXin Li UntypedMutableSet *untypedMutSet, 102*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 103*67e74705SXin Li NSSet *set, 104*67e74705SXin Li NSMutableSet *mutSet, 105*67e74705SXin Li MutableSetOfArrays *mutArraySet, 106*67e74705SXin Li NSArray<NSString *> *stringArray, 107*67e74705SXin Li void (^block)(void)) { 108*67e74705SXin Li int *ip; 109*67e74705SXin Li ip = [stringSet firstObject]; // expected-error{{from incompatible type 'NSString *'}} 110*67e74705SXin Li ip = [mutStringSet firstObject]; // expected-error{{from incompatible type 'NSString *'}} 111*67e74705SXin Li ip = [widgetSet firstObject]; // expected-error{{from incompatible type 'Widget *'}} 112*67e74705SXin Li ip = [untypedMutSet firstObject]; // expected-error{{from incompatible type 'id'}} 113*67e74705SXin Li ip = [mutStringArraySet firstObject]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 114*67e74705SXin Li ip = [set firstObject]; // expected-error{{from incompatible type 'id'}} 115*67e74705SXin Li ip = [mutSet firstObject]; // expected-error{{from incompatible type 'id'}} 116*67e74705SXin Li ip = [mutArraySet firstObject]; // expected-error{{from incompatible type 'id'}} 117*67e74705SXin Li ip = [block firstObject]; // expected-error{{from incompatible type 'id'}} 118*67e74705SXin Li 119*67e74705SXin Li ip = [stringSet findObject:@"blah"]; // expected-error{{from incompatible type 'NSString *'}} 120*67e74705SXin Li 121*67e74705SXin Li // Class messages. 122*67e74705SXin Li ip = [NSSet<NSString *> alloc]; // expected-error{{from incompatible type 'NSSet<NSString *> *'}} 123*67e74705SXin Li ip = [NSSet alloc]; // expected-error{{from incompatible type 'NSSet *'}} 124*67e74705SXin Li ip = [MutableSetOfArrays<NSString *> alloc]; // expected-error{{from incompatible type 'MutableSetOfArrays<NSString *> *'}} 125*67e74705SXin Li ip = [MutableSetOfArrays alloc]; // expected-error{{from incompatible type 'MutableSetOfArrays *'}} 126*67e74705SXin Li ip = [NSArray<NSString *> array]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 127*67e74705SXin Li ip = [NSArray<NSString *><NSCopying> array]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 128*67e74705SXin Li 129*67e74705SXin Li ip = [[NSMutableArray<NSString *> alloc] init]; // expected-error{{from incompatible type 'NSMutableArray<NSString *> *'}} 130*67e74705SXin Li 131*67e74705SXin Li [[NSMutableArray alloc] initWithArray: stringArray]; // okay 132*67e74705SXin Li [[NSMutableArray<NSString *> alloc] initWithArray: stringArray]; // okay 133*67e74705SXin Li [[NSMutableArray<NSNumber *> alloc] initWithArray: stringArray]; // expected-error{{parameter of type 'NSArray<NSNumber *> *' with an lvalue of type 'NSArray<NSString *> *'}} 134*67e74705SXin Li} 135*67e74705SXin Li 136*67e74705SXin Livoid test_message_send_param( 137*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 138*67e74705SXin Li WidgetSet *widgetSet, 139*67e74705SXin Li UntypedMutableSet *untypedMutSet, 140*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 141*67e74705SXin Li NSMutableSet *mutSet, 142*67e74705SXin Li MutableSetOfArrays *mutArraySet, 143*67e74705SXin Li void (^block)(void)) { 144*67e74705SXin Li Window *window; 145*67e74705SXin Li 146*67e74705SXin Li [mutStringSet addObject: window]; // expected-error{{parameter of type 'NSString *'}} 147*67e74705SXin Li [widgetSet addObject: window]; // expected-error{{parameter of type 'Widget *'}} 148*67e74705SXin Li [untypedMutSet addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}} 149*67e74705SXin Li [mutStringArraySet addObject: window]; // expected-error{{parameter of type 'NSArray<NSString *> *'}} 150*67e74705SXin Li [mutSet addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}} 151*67e74705SXin Li [mutArraySet addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}} 152*67e74705SXin Li [block addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}} 153*67e74705SXin Li} 154*67e74705SXin Li 155*67e74705SXin Li// -------------------------------------------------------------------------- 156*67e74705SXin Li// Property accesses. 157*67e74705SXin Li// -------------------------------------------------------------------------- 158*67e74705SXin Livoid test_property_read( 159*67e74705SXin Li NSSet<NSString *> *stringSet, 160*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 161*67e74705SXin Li WidgetSet *widgetSet, 162*67e74705SXin Li UntypedMutableSet *untypedMutSet, 163*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 164*67e74705SXin Li NSSet *set, 165*67e74705SXin Li NSMutableSet *mutSet, 166*67e74705SXin Li MutableSetOfArrays *mutArraySet, 167*67e74705SXin Li NSMutableDictionary *mutDict) { 168*67e74705SXin Li int *ip; 169*67e74705SXin Li ip = stringSet.allObjects; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 170*67e74705SXin Li ip = mutStringSet.allObjects; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 171*67e74705SXin Li ip = widgetSet.allObjects; // expected-error{{from incompatible type 'NSArray<Widget *> *'}} 172*67e74705SXin Li ip = untypedMutSet.allObjects; // expected-error{{from incompatible type 'NSArray *'}} 173*67e74705SXin Li ip = mutStringArraySet.allObjects; // expected-error{{from incompatible type 'NSArray<NSArray<NSString *> *> *'}} 174*67e74705SXin Li ip = set.allObjects; // expected-error{{from incompatible type 'NSArray *'}} 175*67e74705SXin Li ip = mutSet.allObjects; // expected-error{{from incompatible type 'NSArray *'}} 176*67e74705SXin Li ip = mutArraySet.allObjects; // expected-error{{from incompatible type 'NSArray *'}} 177*67e74705SXin Li 178*67e74705SXin Li ip = mutDict.someRandomKey; // expected-error{{from incompatible type '__kindof id<NSCopying>'}} 179*67e74705SXin Li} 180*67e74705SXin Li 181*67e74705SXin Livoid test_property_write( 182*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 183*67e74705SXin Li WidgetSet *widgetSet, 184*67e74705SXin Li UntypedMutableSet *untypedMutSet, 185*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 186*67e74705SXin Li NSMutableSet *mutSet, 187*67e74705SXin Li MutableSetOfArrays *mutArraySet, 188*67e74705SXin Li NSMutableDictionary *mutDict) { 189*67e74705SXin Li int *ip; 190*67e74705SXin Li 191*67e74705SXin Li mutStringSet.allObjects = ip; // expected-error{{to 'NSArray<NSString *> *'}} 192*67e74705SXin Li widgetSet.allObjects = ip; // expected-error{{to 'NSArray<Widget *> *'}} 193*67e74705SXin Li untypedMutSet.allObjects = ip; // expected-error{{to 'NSArray *'}} 194*67e74705SXin Li mutStringArraySet.allObjects = ip; // expected-error{{to 'NSArray<NSArray<NSString *> *> *'}} 195*67e74705SXin Li mutSet.allObjects = ip; // expected-error{{to 'NSArray *'}} 196*67e74705SXin Li mutArraySet.allObjects = ip; // expected-error{{to 'NSArray *'}} 197*67e74705SXin Li 198*67e74705SXin Li mutDict.someRandomKey = ip; // expected-error{{to 'id<NSCopying>'}} 199*67e74705SXin Li} 200*67e74705SXin Li 201*67e74705SXin Li// -------------------------------------------------------------------------- 202*67e74705SXin Li// Subscripting 203*67e74705SXin Li// -------------------------------------------------------------------------- 204*67e74705SXin Livoid test_subscripting( 205*67e74705SXin Li NSArray<NSString *> *stringArray, 206*67e74705SXin Li NSMutableArray<NSString *> *mutStringArray, 207*67e74705SXin Li NSArray *array, 208*67e74705SXin Li NSMutableArray *mutArray, 209*67e74705SXin Li NSDictionary<NSString *, Widget *> *stringWidgetDict, 210*67e74705SXin Li NSMutableDictionary<NSString *, Widget *> *mutStringWidgetDict, 211*67e74705SXin Li NSDictionary *dict, 212*67e74705SXin Li NSMutableDictionary *mutDict) { 213*67e74705SXin Li int *ip; 214*67e74705SXin Li NSString *string; 215*67e74705SXin Li Widget *widget; 216*67e74705SXin Li Window *window; 217*67e74705SXin Li 218*67e74705SXin Li ip = stringArray[0]; // expected-error{{from incompatible type 'NSString *'}} 219*67e74705SXin Li 220*67e74705SXin Li ip = mutStringArray[0]; // expected-error{{from incompatible type 'NSString *'}} 221*67e74705SXin Li mutStringArray[0] = ip; // expected-error{{parameter of type 'NSString *'}} 222*67e74705SXin Li 223*67e74705SXin Li ip = array[0]; // expected-error{{from incompatible type 'id'}} 224*67e74705SXin Li 225*67e74705SXin Li ip = mutArray[0]; // expected-error{{from incompatible type 'id'}} 226*67e74705SXin Li mutArray[0] = ip; // expected-error{{parameter of type 'id'}} 227*67e74705SXin Li 228*67e74705SXin Li ip = stringWidgetDict[string]; // expected-error{{from incompatible type 'Widget *'}} 229*67e74705SXin Li widget = stringWidgetDict[widget]; // expected-error{{parameter of type 'NSString *'}} 230*67e74705SXin Li 231*67e74705SXin Li ip = mutStringWidgetDict[string]; // expected-error{{from incompatible type 'Widget *'}} 232*67e74705SXin Li widget = mutStringWidgetDict[widget]; // expected-error{{parameter of type 'NSString *'}} 233*67e74705SXin Li mutStringWidgetDict[string] = ip; // expected-error{{parameter of type 'Widget *'}} 234*67e74705SXin Li mutStringWidgetDict[widget] = widget; // expected-error{{parameter of type 'NSString *'}} 235*67e74705SXin Li 236*67e74705SXin Li ip = dict[string]; // expected-error{{from incompatible type 'id'}} 237*67e74705SXin Li 238*67e74705SXin Li ip = mutDict[string]; // expected-error{{incompatible type 'id'}} 239*67e74705SXin Li mutDict[string] = ip; // expected-error{{parameter of type 'id'}} 240*67e74705SXin Li 241*67e74705SXin Li widget = mutDict[window]; 242*67e74705SXin Li mutDict[window] = widget; // expected-error{{parameter of type 'id<NSCopying>'}} 243*67e74705SXin Li} 244*67e74705SXin Li 245*67e74705SXin Li// -------------------------------------------------------------------------- 246*67e74705SXin Li// Instance variable access. 247*67e74705SXin Li// -------------------------------------------------------------------------- 248*67e74705SXin Livoid test_instance_variable(NSArray<NSString *> *stringArray, 249*67e74705SXin Li NSArray *array) { 250*67e74705SXin Li int *ip; 251*67e74705SXin Li 252*67e74705SXin Li ip = stringArray->data; // expected-error{{from incompatible type 'NSString **'}} 253*67e74705SXin Li ip = array->data; // expected-error{{from incompatible type 'id *'}} 254*67e74705SXin Li} 255*67e74705SXin Li 256*67e74705SXin Li@implementation WindowArray 257*67e74705SXin Li- (void)testInstanceVariable { 258*67e74705SXin Li int *ip; 259*67e74705SXin Li 260*67e74705SXin Li ip = data; // expected-error{{from incompatible type 'Window **'}} 261*67e74705SXin Li} 262*67e74705SXin Li@end 263*67e74705SXin Li 264*67e74705SXin Li// -------------------------------------------------------------------------- 265*67e74705SXin Li// Implicit conversions. 266*67e74705SXin Li// -------------------------------------------------------------------------- 267*67e74705SXin Livoid test_implicit_conversions(NSArray<NSString *> *stringArray, 268*67e74705SXin Li NSArray<NSNumber *> *numberArray, 269*67e74705SXin Li NSMutableArray<NSString *> *mutStringArray, 270*67e74705SXin Li NSArray *array, 271*67e74705SXin Li NSMutableArray *mutArray) { 272*67e74705SXin Li // Specialized -> unspecialized (same level) 273*67e74705SXin Li array = stringArray; 274*67e74705SXin Li 275*67e74705SXin Li // Unspecialized -> specialized (same level) 276*67e74705SXin Li stringArray = array; 277*67e74705SXin Li 278*67e74705SXin Li // Specialized -> specialized failure (same level). 279*67e74705SXin Li stringArray = numberArray; // expected-error{{assigning to 'NSArray<NSString *> *' from incompatible type 'NSArray<NSNumber *> *'}} 280*67e74705SXin Li 281*67e74705SXin Li // Specialized -> specialized (different levels). 282*67e74705SXin Li stringArray = mutStringArray; 283*67e74705SXin Li 284*67e74705SXin Li // Specialized -> specialized failure (different levels). 285*67e74705SXin Li numberArray = mutStringArray; // expected-error{{assigning to 'NSArray<NSNumber *> *' from incompatible type 'NSMutableArray<NSString *> *'}} 286*67e74705SXin Li 287*67e74705SXin Li // Unspecialized -> specialized (different levels). 288*67e74705SXin Li stringArray = mutArray; 289*67e74705SXin Li 290*67e74705SXin Li // Specialized -> unspecialized (different levels). 291*67e74705SXin Li array = mutStringArray; 292*67e74705SXin Li} 293*67e74705SXin Li 294*67e74705SXin Li@interface NSCovariant1<__covariant T> 295*67e74705SXin Li@end 296*67e74705SXin Li 297*67e74705SXin Li@interface NSContravariant1<__contravariant T> 298*67e74705SXin Li@end 299*67e74705SXin Li 300*67e74705SXin Livoid test_variance(NSCovariant1<NSString *> *covariant1, 301*67e74705SXin Li NSCovariant1<NSMutableString *> *covariant2, 302*67e74705SXin Li NSCovariant1<NSString *(^)(void)> *covariant3, 303*67e74705SXin Li NSCovariant1<NSMutableString *(^)(void)> *covariant4, 304*67e74705SXin Li NSCovariant1<id> *covariant5, 305*67e74705SXin Li NSCovariant1<id<NSCopying>> *covariant6, 306*67e74705SXin Li NSContravariant1<NSString *> *contravariant1, 307*67e74705SXin Li NSContravariant1<NSMutableString *> *contravariant2) { 308*67e74705SXin Li covariant1 = covariant2; // okay 309*67e74705SXin Li covariant2 = covariant1; // expected-warning{{incompatible pointer types assigning to 'NSCovariant1<NSMutableString *> *' from 'NSCovariant1<NSString *> *'}} 310*67e74705SXin Li 311*67e74705SXin Li covariant3 = covariant4; // okay 312*67e74705SXin Li covariant4 = covariant3; // expected-warning{{incompatible pointer types assigning to 'NSCovariant1<NSMutableString *(^)()> *' from 'NSCovariant1<NSString *(^)()> *'}} 313*67e74705SXin Li 314*67e74705SXin Li covariant5 = covariant1; // okay 315*67e74705SXin Li covariant1 = covariant5; // okay: id is promiscuous 316*67e74705SXin Li 317*67e74705SXin Li covariant5 = covariant3; // okay 318*67e74705SXin Li covariant3 = covariant5; // okay 319*67e74705SXin Li 320*67e74705SXin Li contravariant1 = contravariant2; // expected-warning{{incompatible pointer types assigning to 'NSContravariant1<NSString *> *' from 'NSContravariant1<NSMutableString *> *'}} 321*67e74705SXin Li contravariant2 = contravariant1; // okay 322*67e74705SXin Li} 323*67e74705SXin Li 324*67e74705SXin Li// -------------------------------------------------------------------------- 325*67e74705SXin Li// Ternary operator 326*67e74705SXin Li// -------------------------------------------------------------------------- 327*67e74705SXin Livoid test_ternary_operator(NSArray<NSString *> *stringArray, 328*67e74705SXin Li NSArray<NSNumber *> *numberArray, 329*67e74705SXin Li NSMutableArray<NSString *> *mutStringArray, 330*67e74705SXin Li NSStringArray *stringArray2, 331*67e74705SXin Li NSArray *array, 332*67e74705SXin Li NSMutableArray *mutArray, 333*67e74705SXin Li int cond) { 334*67e74705SXin Li int *ip; 335*67e74705SXin Li id object; 336*67e74705SXin Li 337*67e74705SXin Li ip = cond ? stringArray : mutStringArray; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 338*67e74705SXin Li ip = cond ? mutStringArray : stringArray; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 339*67e74705SXin Li 340*67e74705SXin Li ip = cond ? stringArray2 : mutStringArray; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 341*67e74705SXin Li ip = cond ? mutStringArray : stringArray2; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 342*67e74705SXin Li 343*67e74705SXin Li ip = cond ? stringArray : mutArray; // expected-error{{from incompatible type 'NSArray *'}} 344*67e74705SXin Li 345*67e74705SXin Li ip = cond ? stringArray2 : mutArray; // expected-error{{from incompatible type 'NSArray *'}} 346*67e74705SXin Li 347*67e74705SXin Li ip = cond ? mutArray : stringArray; // expected-error{{from incompatible type 'NSArray *'}} 348*67e74705SXin Li 349*67e74705SXin Li ip = cond ? mutArray : stringArray2; // expected-error{{from incompatible type 'NSArray *'}} 350*67e74705SXin Li 351*67e74705SXin Li object = cond ? stringArray : numberArray; // expected-warning{{incompatible operand types ('NSArray<NSString *> *' and 'NSArray<NSNumber *> *')}} 352*67e74705SXin Li} 353*67e74705SXin Li 354*67e74705SXin Li// -------------------------------------------------------------------------- 355*67e74705SXin Li// super 356*67e74705SXin Li// -------------------------------------------------------------------------- 357*67e74705SXin Li@implementation NSStringArray 358*67e74705SXin Li- (void)useSuperMethod { 359*67e74705SXin Li int *ip; 360*67e74705SXin Li ip = super.lastObject; // expected-error{{from incompatible type 'NSString *'}} 361*67e74705SXin Li ip = [super objectAtIndexedSubscript:0]; // expected-error{{from incompatible type 'NSString *'}} 362*67e74705SXin Li} 363*67e74705SXin Li 364*67e74705SXin Li+ (void)useSuperMethod { 365*67e74705SXin Li int *ip; 366*67e74705SXin Li ip = super.array; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 367*67e74705SXin Li ip = [super array]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}} 368*67e74705SXin Li} 369*67e74705SXin Li@end 370*67e74705SXin Li 371*67e74705SXin Li// -------------------------------------------------------------------------- 372*67e74705SXin Li// Template instantiation 373*67e74705SXin Li// -------------------------------------------------------------------------- 374*67e74705SXin Litemplate<typename K, typename V> 375*67e74705SXin Listruct NSMutableDictionaryOf { 376*67e74705SXin Li typedef NSMutableDictionary<K, V> *type; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'K'}} 377*67e74705SXin Li}; 378*67e74705SXin Li 379*67e74705SXin Litemplate<typename ...Args> 380*67e74705SXin Listruct VariadicNSMutableDictionaryOf { 381*67e74705SXin Li typedef NSMutableDictionary<Args...> *type; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'K'}} 382*67e74705SXin Li // expected-error@-1{{too many type arguments for class 'NSMutableDictionary' (have 3, expected 2)}} 383*67e74705SXin Li // expected-error@-2{{too few type arguments for class 'NSMutableDictionary' (have 1, expected 2)}} 384*67e74705SXin Li}; 385*67e74705SXin Li 386*67e74705SXin Livoid testInstantiation() { 387*67e74705SXin Li int *ip; 388*67e74705SXin Li 389*67e74705SXin Li typedef NSMutableDictionaryOf<NSString *, NSObject *>::type Dict1; 390*67e74705SXin Li Dict1 d1 = ip; // expected-error{{cannot initialize a variable of type 'Dict1' (aka 'NSMutableDictionary<NSString *,NSObject *> *')}} 391*67e74705SXin Li 392*67e74705SXin Li typedef NSMutableDictionaryOf<NSObject *, NSString *>::type Dict2; // expected-note{{in instantiation of template}} 393*67e74705SXin Li} 394*67e74705SXin Li 395*67e74705SXin Livoid testVariadicInstantiation() { 396*67e74705SXin Li int *ip; 397*67e74705SXin Li 398*67e74705SXin Li typedef VariadicNSMutableDictionaryOf<NSString *, NSObject *>::type Dict1; 399*67e74705SXin Li Dict1 d1 = ip; // expected-error{{cannot initialize a variable of type 'Dict1' (aka 'NSMutableDictionary<NSString *,NSObject *> *')}} 400*67e74705SXin Li 401*67e74705SXin Li typedef VariadicNSMutableDictionaryOf<NSObject *, NSString *>::type Dict2; // expected-note{{in instantiation of template}} 402*67e74705SXin Li 403*67e74705SXin Li typedef VariadicNSMutableDictionaryOf<NSString *, NSObject *, NSObject *>::type Dict3; // expected-note{{in instantiation of template}} 404*67e74705SXin Li 405*67e74705SXin Li typedef VariadicNSMutableDictionaryOf<NSString *>::type Dict3; // expected-note{{in instantiation of template}} 406*67e74705SXin Li} 407*67e74705SXin Li 408*67e74705SXin Li// -------------------------------------------------------------------------- 409*67e74705SXin Li// Parameterized classes are not templates 410*67e74705SXin Li// -------------------------------------------------------------------------- 411*67e74705SXin Litemplate<template<typename T, typename U> class TT> 412*67e74705SXin Listruct AcceptsTemplateTemplate { }; 413*67e74705SXin Li 414*67e74705SXin Litypedef AcceptsTemplateTemplate<NSMutableDictionary> TemplateTemplateFail1; // expected-error{{template argument for template template parameter must be a class template or type alias template}} 415*67e74705SXin Li 416*67e74705SXin Litemplate<typename T> 417*67e74705SXin Listruct DependentTemplate { 418*67e74705SXin Li typedef typename T::template apply<NSString *, NSObject *> type; // expected-error{{'apply' following the 'template' keyword does not refer to a template}} 419*67e74705SXin Li}; 420*67e74705SXin Li 421*67e74705SXin Listruct NSMutableDictionaryBuilder { 422*67e74705SXin Li typedef NSMutableDictionary apply; 423*67e74705SXin Li}; 424*67e74705SXin Li 425*67e74705SXin Litypedef DependentTemplate<NSMutableDictionaryBuilder>::type DependentTemplateFail1; // expected-note{{in instantiation of template class}} 426*67e74705SXin Li 427*67e74705SXin Litemplate<typename K, typename V> 428*67e74705SXin Listruct NonDependentTemplate { 429*67e74705SXin Li typedef NSMutableDictionaryBuilder::template apply<NSString *, NSObject *> type; // expected-error{{'apply' following the 'template' keyword does not refer to a template}} 430*67e74705SXin Li // expected-error@-1{{expected member name or }} 431*67e74705SXin Li}; 432*67e74705SXin Li 433*67e74705SXin Li// However, one can use an alias template to turn a parameterized 434*67e74705SXin Li// class into a template. 435*67e74705SXin Litemplate<typename K, typename V> 436*67e74705SXin Liusing NSMutableDictionaryAlias = NSMutableDictionary<K, V>; 437*67e74705SXin Li 438*67e74705SXin Litypedef AcceptsTemplateTemplate<NSMutableDictionaryAlias> TemplateTemplateAlias1; // okay 439*67e74705SXin Li 440*67e74705SXin Li 441