@@ -271,156 +271,12 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
271
271
void visitDerivativeAttr (DerivativeAttr *attr);
272
272
void visitTransposeAttr (TransposeAttr *attr);
273
273
274
- void visitAsyncHandlerAttr (AsyncHandlerAttr *attr) {
275
- auto func = dyn_cast<FuncDecl>(D);
276
- if (!func) {
277
- diagnoseAndRemoveAttr (attr, diag::asynchandler_non_func);
278
- return ;
279
- }
280
-
281
- // Trigger the request to check for @asyncHandler.
282
- (void )func->isAsyncHandler ();
283
- }
284
-
285
- void visitActorAttr (ActorAttr *attr) {
286
- auto classDecl = dyn_cast<ClassDecl>(D);
287
- if (!classDecl)
288
- return ; // already diagnosed
289
-
290
- (void )classDecl->isActor ();
291
- }
292
-
293
- void visitActorIndependentAttr (ActorIndependentAttr *attr) {
294
- // @actorIndependent can be applied to global and static/class variables
295
- // that do not have storage.
296
- auto dc = D->getDeclContext ();
297
- if (auto var = dyn_cast<VarDecl>(D)) {
298
- // @actorIndependent is meaningless on a `let`.
299
- if (var->isLet ()) {
300
- diagnoseAndRemoveAttr (attr, diag::actorindependent_let);
301
- return ;
302
- }
303
-
304
- // @actorIndependent can not be applied to stored properties, unless if
305
- // the 'unsafe' option was specified
306
- if (var->hasStorage ()) {
307
- switch (attr->getKind ()) {
308
- case ActorIndependentKind::Safe:
309
- diagnoseAndRemoveAttr (attr, diag::actorindependent_mutable_storage);
310
- return ;
311
-
312
- case ActorIndependentKind::Unsafe:
313
- break ;
314
- }
315
- }
316
-
317
- // @actorIndependent can not be applied to local properties.
318
- if (dc->isLocalContext ()) {
319
- diagnoseAndRemoveAttr (attr, diag::actorindependent_local_var);
320
- return ;
321
- }
322
-
323
- // If this is a static or global variable, we're all set.
324
- if (dc->isModuleScopeContext () ||
325
- (dc->isTypeContext () && var->isStatic ())) {
326
- return ;
327
- }
328
- }
329
-
330
- if (auto VD = dyn_cast<ValueDecl>(D)) {
331
- (void )getActorIsolation (VD);
332
- }
333
- }
334
-
335
- void visitGlobalActorAttr (GlobalActorAttr *attr) {
336
- auto nominal = dyn_cast<NominalTypeDecl>(D);
337
- if (!nominal)
338
- return ; // already diagnosed
339
-
340
- (void )nominal->isGlobalActor ();
341
- }
342
-
343
- void visitAsyncAttr (AsyncAttr *attr) {
344
- auto var = dyn_cast<VarDecl>(D);
345
- if (!var)
346
- return ;
347
-
348
- auto patternBinding = var->getParentPatternBinding ();
349
- if (!patternBinding)
350
- return ; // already diagnosed
351
-
352
- // "Async" modifier can only be applied to local declarations.
353
- if (!patternBinding->getDeclContext ()->isLocalContext ()) {
354
- diagnoseAndRemoveAttr (attr, diag::async_let_not_local);
355
- return ;
356
- }
357
-
358
- // Check each of the pattern binding entries.
359
- bool diagnosedVar = false ;
360
- for (unsigned index : range (patternBinding->getNumPatternEntries ())) {
361
- auto pattern = patternBinding->getPattern (index);
362
-
363
- // Look for variables bound by this pattern.
364
- bool foundAnyVariable = false ;
365
- bool isLet = true ;
366
- pattern->forEachVariable ([&](VarDecl *var) {
367
- if (!var->isLet ())
368
- isLet = false ;
369
- foundAnyVariable = true ;
370
- });
371
-
372
- // Each entry must bind at least one named variable, so that there is
373
- // something to "await".
374
- if (!foundAnyVariable) {
375
- diagnose (pattern->getLoc (), diag::async_let_no_variables);
376
- attr->setInvalid ();
377
- return ;
378
- }
379
-
380
- // Async can only be used on an "async let".
381
- if (!isLet && !diagnosedVar) {
382
- diagnose (patternBinding->getLoc (), diag::async_not_let)
383
- .fixItReplace (patternBinding->getLoc (), " let" );
384
- diagnosedVar = true ;
385
- }
386
-
387
- // Each pattern entry must have an initializer expression.
388
- if (patternBinding->getEqualLoc (index).isInvalid ()) {
389
- diagnose (pattern->getLoc (), diag::async_let_not_initialized);
390
- attr->setInvalid ();
391
- return ;
392
- }
393
- }
394
- }
395
-
396
- void visitMarkerAttr (MarkerAttr *attr) {
397
- auto proto = dyn_cast<ProtocolDecl>(D);
398
- if (!proto)
399
- return ;
400
-
401
- // A marker protocol cannot inherit a non-marker protocol.
402
- for (auto inheritedProto : proto->getInheritedProtocols ()) {
403
- if (!inheritedProto->isMarkerProtocol ()) {
404
- proto->diagnose (
405
- diag::marker_protocol_inherit_nonmarker,
406
- proto->getName (), inheritedProto->getName ());
407
- inheritedProto->diagnose (
408
- diag::decl_declared_here, inheritedProto->getName ());
409
- }
410
- }
411
-
412
- // A marker protocol cannot have any requirements.
413
- for (auto member : proto->getAllMembers ()) {
414
- auto value = dyn_cast<ValueDecl>(member);
415
- if (!value)
416
- continue ;
417
-
418
- if (value->isProtocolRequirement ()) {
419
- value->diagnose (diag::marker_protocol_requirement, proto->getName ());
420
- break ;
421
- }
422
- }
423
- }
274
+ void visitAsyncHandlerAttr (AsyncHandlerAttr *attr);
275
+ void visitActorAttr (ActorAttr *attr);
276
+ void visitActorIndependentAttr (ActorIndependentAttr *attr);
277
+ void visitGlobalActorAttr (GlobalActorAttr *attr);
278
+ void visitAsyncAttr (AsyncAttr *attr);
279
+ void visitMarkerAttr (MarkerAttr *attr);
424
280
};
425
281
} // end anonymous namespace
426
282
@@ -5467,3 +5323,154 @@ void AttributeChecker::visitTransposeAttr(TransposeAttr *attr) {
5467
5323
// Set the resolved linearity parameter indices in the attribute.
5468
5324
attr->setParameterIndices (linearParamIndices);
5469
5325
}
5326
+
5327
+ void AttributeChecker::visitAsyncHandlerAttr (AsyncHandlerAttr *attr) {
5328
+ auto func = dyn_cast<FuncDecl>(D);
5329
+ if (!func) {
5330
+ diagnoseAndRemoveAttr (attr, diag::asynchandler_non_func);
5331
+ return ;
5332
+ }
5333
+
5334
+ // Trigger the request to check for @asyncHandler.
5335
+ (void )func->isAsyncHandler ();
5336
+ }
5337
+
5338
+ void AttributeChecker::visitActorAttr (ActorAttr *attr) {
5339
+ auto classDecl = dyn_cast<ClassDecl>(D);
5340
+ if (!classDecl)
5341
+ return ; // already diagnosed
5342
+
5343
+ (void )classDecl->isActor ();
5344
+ }
5345
+
5346
+ void AttributeChecker::visitActorIndependentAttr (ActorIndependentAttr *attr) {
5347
+ // @actorIndependent can be applied to global and static/class variables
5348
+ // that do not have storage.
5349
+ auto dc = D->getDeclContext ();
5350
+ if (auto var = dyn_cast<VarDecl>(D)) {
5351
+ // @actorIndependent is meaningless on a `let`.
5352
+ if (var->isLet ()) {
5353
+ diagnoseAndRemoveAttr (attr, diag::actorindependent_let);
5354
+ return ;
5355
+ }
5356
+
5357
+ // @actorIndependent can not be applied to stored properties, unless if
5358
+ // the 'unsafe' option was specified
5359
+ if (var->hasStorage ()) {
5360
+ switch (attr->getKind ()) {
5361
+ case ActorIndependentKind::Safe:
5362
+ diagnoseAndRemoveAttr (attr, diag::actorindependent_mutable_storage);
5363
+ return ;
5364
+
5365
+ case ActorIndependentKind::Unsafe:
5366
+ break ;
5367
+ }
5368
+ }
5369
+
5370
+ // @actorIndependent can not be applied to local properties.
5371
+ if (dc->isLocalContext ()) {
5372
+ diagnoseAndRemoveAttr (attr, diag::actorindependent_local_var);
5373
+ return ;
5374
+ }
5375
+
5376
+ // If this is a static or global variable, we're all set.
5377
+ if (dc->isModuleScopeContext () ||
5378
+ (dc->isTypeContext () && var->isStatic ())) {
5379
+ return ;
5380
+ }
5381
+ }
5382
+
5383
+ if (auto VD = dyn_cast<ValueDecl>(D)) {
5384
+ (void )getActorIsolation (VD);
5385
+ }
5386
+ }
5387
+
5388
+ void AttributeChecker::visitGlobalActorAttr (GlobalActorAttr *attr) {
5389
+ auto nominal = dyn_cast<NominalTypeDecl>(D);
5390
+ if (!nominal)
5391
+ return ; // already diagnosed
5392
+
5393
+ (void )nominal->isGlobalActor ();
5394
+ }
5395
+
5396
+ void AttributeChecker::visitAsyncAttr (AsyncAttr *attr) {
5397
+ auto var = dyn_cast<VarDecl>(D);
5398
+ if (!var)
5399
+ return ;
5400
+
5401
+ auto patternBinding = var->getParentPatternBinding ();
5402
+ if (!patternBinding)
5403
+ return ; // already diagnosed
5404
+
5405
+ // "Async" modifier can only be applied to local declarations.
5406
+ if (!patternBinding->getDeclContext ()->isLocalContext ()) {
5407
+ diagnoseAndRemoveAttr (attr, diag::async_let_not_local);
5408
+ return ;
5409
+ }
5410
+
5411
+ // Check each of the pattern binding entries.
5412
+ bool diagnosedVar = false ;
5413
+ for (unsigned index : range (patternBinding->getNumPatternEntries ())) {
5414
+ auto pattern = patternBinding->getPattern (index);
5415
+
5416
+ // Look for variables bound by this pattern.
5417
+ bool foundAnyVariable = false ;
5418
+ bool isLet = true ;
5419
+ pattern->forEachVariable ([&](VarDecl *var) {
5420
+ if (!var->isLet ())
5421
+ isLet = false ;
5422
+ foundAnyVariable = true ;
5423
+ });
5424
+
5425
+ // Each entry must bind at least one named variable, so that there is
5426
+ // something to "await".
5427
+ if (!foundAnyVariable) {
5428
+ diagnose (pattern->getLoc (), diag::async_let_no_variables);
5429
+ attr->setInvalid ();
5430
+ return ;
5431
+ }
5432
+
5433
+ // Async can only be used on an "async let".
5434
+ if (!isLet && !diagnosedVar) {
5435
+ diagnose (patternBinding->getLoc (), diag::async_not_let)
5436
+ .fixItReplace (patternBinding->getLoc (), " let" );
5437
+ diagnosedVar = true ;
5438
+ }
5439
+
5440
+ // Each pattern entry must have an initializer expression.
5441
+ if (patternBinding->getEqualLoc (index).isInvalid ()) {
5442
+ diagnose (pattern->getLoc (), diag::async_let_not_initialized);
5443
+ attr->setInvalid ();
5444
+ return ;
5445
+ }
5446
+ }
5447
+ }
5448
+
5449
+ void AttributeChecker::visitMarkerAttr (MarkerAttr *attr) {
5450
+ auto proto = dyn_cast<ProtocolDecl>(D);
5451
+ if (!proto)
5452
+ return ;
5453
+
5454
+ // A marker protocol cannot inherit a non-marker protocol.
5455
+ for (auto inheritedProto : proto->getInheritedProtocols ()) {
5456
+ if (!inheritedProto->isMarkerProtocol ()) {
5457
+ proto->diagnose (
5458
+ diag::marker_protocol_inherit_nonmarker,
5459
+ proto->getName (), inheritedProto->getName ());
5460
+ inheritedProto->diagnose (
5461
+ diag::decl_declared_here, inheritedProto->getName ());
5462
+ }
5463
+ }
5464
+
5465
+ // A marker protocol cannot have any requirements.
5466
+ for (auto member : proto->getAllMembers ()) {
5467
+ auto value = dyn_cast<ValueDecl>(member);
5468
+ if (!value)
5469
+ continue ;
5470
+
5471
+ if (value->isProtocolRequirement ()) {
5472
+ value->diagnose (diag::marker_protocol_requirement, proto->getName ());
5473
+ break ;
5474
+ }
5475
+ }
5476
+ }
0 commit comments