@@ -543,6 +543,112 @@ static Identifier makeIdentifier(ASTContext &ctx, std::nullptr_t) {
543
543
return Identifier ();
544
544
}
545
545
546
+ bool swift::diagnoseInvalidAttachedMacro (MacroRole role,
547
+ Decl *attachedTo) {
548
+ switch (role) {
549
+ case MacroRole::Expression:
550
+ case MacroRole::Declaration:
551
+ case MacroRole::CodeItem:
552
+ llvm_unreachable (" Invalid macro role for attached macro" );
553
+
554
+ case MacroRole::Accessor:
555
+ // Only var decls and subscripts have accessors.
556
+ if (isa<AbstractStorageDecl>(attachedTo) && !isa<ParamDecl>(attachedTo))
557
+ return false ;
558
+
559
+ break ;
560
+
561
+ case MacroRole::MemberAttribute:
562
+ case MacroRole::Member:
563
+ // Nominal types and extensions can have members.
564
+ if (isa<NominalTypeDecl>(attachedTo) || isa<ExtensionDecl>(attachedTo))
565
+ return false ;
566
+
567
+ break ;
568
+
569
+ case MacroRole::Peer:
570
+ // Peer macros are allowed on everything except parameters.
571
+ if (!isa<ParamDecl>(attachedTo))
572
+ return false ;
573
+
574
+ break ;
575
+
576
+ case MacroRole::Conformance:
577
+ case MacroRole::Extension:
578
+ // Only primary declarations of nominal types
579
+ if (isa<NominalTypeDecl>(attachedTo))
580
+ return false ;
581
+
582
+ break ;
583
+ }
584
+
585
+ attachedTo->diagnose (diag::macro_attached_to_invalid_decl,
586
+ getMacroRoleString (role),
587
+ attachedTo->getDescriptiveKind ());
588
+ return true ;
589
+ }
590
+
591
+ static void diagnoseInvalidDecl (Decl *decl,
592
+ MacroDecl *macro,
593
+ llvm::function_ref<bool (DeclName)> coversName) {
594
+ auto &ctx = decl->getASTContext ();
595
+
596
+ // Diagnose invalid declaration kinds.
597
+ if (isa<ImportDecl>(decl) ||
598
+ isa<OperatorDecl>(decl) ||
599
+ isa<PrecedenceGroupDecl>(decl) ||
600
+ isa<MacroDecl>(decl) ||
601
+ isa<ExtensionDecl>(decl)) {
602
+ decl->diagnose (diag::invalid_decl_in_macro_expansion,
603
+ decl->getDescriptiveKind ());
604
+ decl->setInvalid ();
605
+
606
+ if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
607
+ extension->setExtendedNominal (nullptr );
608
+ }
609
+
610
+ return ;
611
+ }
612
+
613
+ // Diagnose `@main` types.
614
+ if (auto *mainAttr = decl->getAttrs ().getAttribute <MainTypeAttr>()) {
615
+ ctx.Diags .diagnose (mainAttr->getLocation (),
616
+ diag::invalid_main_type_in_macro_expansion);
617
+ mainAttr->setInvalid ();
618
+ }
619
+
620
+ // Diagnose default literal type overrides.
621
+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(decl)) {
622
+ auto name = typeAlias->getBaseIdentifier ();
623
+ #define EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME (_, __, typeName, \
624
+ supportsOverride) \
625
+ if (supportsOverride && name == makeIdentifier (ctx, typeName)) { \
626
+ typeAlias->diagnose (diag::literal_type_in_macro_expansion, \
627
+ makeIdentifier (ctx, typeName)); \
628
+ typeAlias->setInvalid (); \
629
+ return ; \
630
+ }
631
+ #include " swift/AST/KnownProtocols.def"
632
+ #undef EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME
633
+ }
634
+
635
+ // Diagnose value decls with names not covered by the macro
636
+ if (auto *value = dyn_cast<ValueDecl>(decl)) {
637
+ auto name = value->getName ();
638
+
639
+ // Unique names are always permitted.
640
+ if (MacroDecl::isUniqueMacroName (name.getBaseName ().userFacingName ()))
641
+ return ;
642
+
643
+ if (coversName (name)) {
644
+ return ;
645
+ }
646
+
647
+ value->diagnose (diag::invalid_macro_introduced_name,
648
+ name, macro->getBaseName ());
649
+ }
650
+ }
651
+
546
652
// / Diagnose macro expansions that produce any of the following declarations:
547
653
// / - Import declarations
548
654
// / - Operator and precedence group declarations
@@ -559,75 +665,33 @@ static void validateMacroExpansion(SourceFile *expansionBuffer,
559
665
llvm::SmallVector<DeclName, 2 > introducedNames;
560
666
macro->getIntroducedNames (role, attachedTo, introducedNames);
561
667
562
- llvm::SmallDenseSet<DeclName, 2 > coversName (introducedNames. begin (),
563
- introducedNames.end ());
668
+ llvm::SmallDenseSet<DeclName, 2 > introducedNameSet (
669
+ introducedNames. begin (), introducedNames.end ());
564
670
565
- for (auto *decl : expansionBuffer->getTopLevelDecls ()) {
566
- auto &ctx = decl->getASTContext ();
671
+ auto coversName = [&](DeclName name) -> bool {
672
+ return (introducedNameSet.count (name) ||
673
+ introducedNameSet.count (name.getBaseName ()) ||
674
+ introducedNameSet.count (MacroDecl::getArbitraryName ()));
675
+ };
567
676
677
+ for (auto *decl : expansionBuffer->getTopLevelDecls ()) {
568
678
// Certain macro roles can generate special declarations.
569
679
if ((isa<AccessorDecl>(decl) && role == MacroRole::Accessor) ||
570
- (isa<ExtensionDecl>(decl) && role == MacroRole::Conformance) ||
571
- (isa<ExtensionDecl>(decl) && role == MacroRole::Extension)) { // FIXME: Check extension for generated names.
680
+ (isa<ExtensionDecl>(decl) && role == MacroRole::Conformance)) {
572
681
continue ;
573
682
}
574
683
575
- // Diagnose invalid declaration kinds.
576
- if (isa<ImportDecl>(decl) ||
577
- isa<OperatorDecl>(decl) ||
578
- isa<PrecedenceGroupDecl>(decl) ||
579
- isa<MacroDecl>(decl) ||
580
- isa<ExtensionDecl>(decl)) {
581
- decl->diagnose (diag::invalid_decl_in_macro_expansion,
582
- decl->getDescriptiveKind ());
583
- decl->setInvalid ();
584
-
585
- if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
586
- extension->setExtendedNominal (nullptr );
684
+ if (role == MacroRole::Extension) {
685
+ auto *extension = dyn_cast<ExtensionDecl>(decl);
686
+
687
+ for (auto *member : extension->getMembers ()) {
688
+ diagnoseInvalidDecl (member, macro, coversName);
587
689
}
588
690
589
691
continue ;
590
692
}
591
693
592
- // Diagnose `@main` types.
593
- if (auto *mainAttr = decl->getAttrs ().getAttribute <MainTypeAttr>()) {
594
- ctx.Diags .diagnose (mainAttr->getLocation (),
595
- diag::invalid_main_type_in_macro_expansion);
596
- mainAttr->setInvalid ();
597
- }
598
-
599
- // Diagnose default literal type overrides.
600
- if (auto *typeAlias = dyn_cast<TypeAliasDecl>(decl)) {
601
- auto name = typeAlias->getBaseIdentifier ();
602
- #define EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME (_, __, typeName, \
603
- supportsOverride) \
604
- if (supportsOverride && name == makeIdentifier (ctx, typeName)) { \
605
- typeAlias->diagnose (diag::literal_type_in_macro_expansion, \
606
- makeIdentifier (ctx, typeName)); \
607
- typeAlias->setInvalid (); \
608
- continue ; \
609
- }
610
- #include " swift/AST/KnownProtocols.def"
611
- #undef EXPRESSIBLE_BY_LITERAL_PROTOCOL_WITH_NAME
612
- }
613
-
614
- // Diagnose value decls with names not covered by the macro
615
- if (auto *value = dyn_cast<ValueDecl>(decl)) {
616
- auto name = value->getName ();
617
-
618
- // Unique names are always permitted.
619
- if (MacroDecl::isUniqueMacroName (name.getBaseName ().userFacingName ()))
620
- continue ;
621
-
622
- if (coversName.count (name) ||
623
- coversName.count (name.getBaseName ()) ||
624
- coversName.count (MacroDecl::getArbitraryName ())) {
625
- continue ;
626
- }
627
-
628
- value->diagnose (diag::invalid_macro_introduced_name,
629
- name, macro->getBaseName ());
630
- }
694
+ diagnoseInvalidDecl (decl, macro, coversName);
631
695
}
632
696
}
633
697
@@ -1572,6 +1636,50 @@ llvm::Optional<unsigned> swift::expandExtensions(CustomAttr *attr,
1572
1636
if (auto file = dyn_cast<FileUnit>(
1573
1637
decl->getDeclContext ()->getModuleScopeContext ()))
1574
1638
file->getOrCreateSynthesizedFile ().addTopLevelDecl (extension);
1639
+
1640
+ // Don't validate documented conformances for the 'conformance' role.
1641
+ if (role == MacroRole::Conformance)
1642
+ continue ;
1643
+
1644
+ // Extension macros can only add conformances that are documented by
1645
+ // the `@attached(extension)` attribute.
1646
+ for (auto inherited : extension->getInherited ()) {
1647
+ auto constraint =
1648
+ TypeResolution::forInterface (
1649
+ extension->getDeclContext (),
1650
+ TypeResolverContext::GenericRequirement,
1651
+ /* unboundTyOpener*/ nullptr ,
1652
+ /* placeholderHandler*/ nullptr ,
1653
+ /* packElementOpener*/ nullptr )
1654
+ .resolveType (inherited.getTypeRepr ());
1655
+
1656
+ // Already diagnosed or will be diagnosed later.
1657
+ if (constraint->is <ErrorType>() || !constraint->isConstraintType ())
1658
+ continue ;
1659
+
1660
+ std::function<bool (Type)> isUndocumentedConformance =
1661
+ [&](Type constraint) -> bool {
1662
+ if (auto *proto = constraint->getAs <ParameterizedProtocolType>())
1663
+ return !llvm::is_contained (potentialConformances,
1664
+ proto->getProtocol ());
1665
+
1666
+ if (auto *proto = constraint->getAs <ProtocolType>())
1667
+ return !llvm::is_contained (potentialConformances,
1668
+ proto->getDecl ());
1669
+
1670
+ return llvm::any_of (
1671
+ constraint->castTo <ProtocolCompositionType>()->getMembers (),
1672
+ isUndocumentedConformance);
1673
+ };
1674
+
1675
+ if (isUndocumentedConformance (constraint)) {
1676
+ extension->diagnose (
1677
+ diag::undocumented_conformance_in_expansion,
1678
+ constraint, macro->getBaseName ());
1679
+
1680
+ extension->setInvalid ();
1681
+ }
1682
+ }
1575
1683
}
1576
1684
1577
1685
return macroSourceFile->getBufferID ();
0 commit comments