@@ -5666,6 +5666,29 @@ ParserResult<ImportDecl> Parser::parseDeclImport(ParseDeclOptions Flags,
56665666 return DCC.fixupParserResult (ID);
56675667}
56685668
5669+ static void addMoveOnlyAttrIf (SourceLoc const &parsedTildeCopyable,
5670+ ASTContext &Context,
5671+ Decl *decl) {
5672+ if (parsedTildeCopyable.isInvalid ())
5673+ return ;
5674+
5675+ auto &attrs = decl->getAttrs ();
5676+
5677+ // Don't add if it's already explicitly written on the decl, but error about
5678+ // the duplication and point to the `~Copyable`.
5679+ if (auto attr = attrs.getAttribute <MoveOnlyAttr>()) {
5680+ const bool sayModifier = false ;
5681+ Context.Diags .diagnose (attr->getLocation (), diag::duplicate_attribute,
5682+ sayModifier)
5683+ .fixItRemove (attr->getRange ());
5684+ Context.Diags .diagnose (parsedTildeCopyable, diag::previous_attribute,
5685+ sayModifier);
5686+ return ;
5687+ }
5688+
5689+ attrs.add (new (Context) MoveOnlyAttr (/* IsImplicit=*/ true ));
5690+ }
5691+
56695692// / Parse an inheritance clause.
56705693// /
56715694// / \verbatim
@@ -5675,15 +5698,19 @@ ParserResult<ImportDecl> Parser::parseDeclImport(ParseDeclOptions Flags,
56755698// / inherited:
56765699// / 'class'
56775700// / type-identifier
5701+ // / '~' 'Copyable'
56785702// / \endverbatim
56795703ParserStatus Parser::parseInheritance (
56805704 SmallVectorImpl<InheritedEntry> &Inherited,
5681- bool allowClassRequirement, bool allowAnyObject) {
5705+ bool allowClassRequirement,
5706+ bool allowAnyObject,
5707+ SourceLoc *parseTildeCopyable) {
56825708 consumeToken (tok::colon);
56835709
56845710 SourceLoc classRequirementLoc;
56855711
56865712 ParserStatus Status;
5713+ SourceLoc TildeCopyableLoc;
56875714 SourceLoc prevComma;
56885715 bool HasNextType;
56895716 do {
@@ -5737,6 +5764,38 @@ ParserStatus Parser::parseInheritance(
57375764 continue ;
57385765 }
57395766
5767+ // Is suppression permitted?
5768+ if (parseTildeCopyable) {
5769+ // Try to find '~' 'Copyable'
5770+ //
5771+ // We do this knowing that Copyable is not a real type as of now, so we
5772+ // can't rely on parseType.
5773+ if (Tok.isTilde ()) {
5774+ const auto &nextTok = peekToken (); // lookahead
5775+ if (isIdentifier (nextTok, Context.Id_Copyable .str ())) {
5776+ auto tildeLoc = consumeToken ();
5777+ consumeToken (); // the 'Copyable' token
5778+
5779+ if (TildeCopyableLoc)
5780+ diagnose (tildeLoc, diag::already_suppressed, Context.Id_Copyable );
5781+ else
5782+ TildeCopyableLoc = tildeLoc;
5783+
5784+ continue ;
5785+ }
5786+
5787+ // can't suppress whatever is between '~' and ',' or '{'.
5788+ diagnose (Tok, diag::only_suppress_copyable);
5789+ consumeToken ();
5790+ }
5791+
5792+ } else if (Tok.isTilde ()) {
5793+ // a suppression isn't allowed here, so emit an error eat the token to
5794+ // prevent further parsing errors.
5795+ diagnose (Tok, diag::cannot_suppress_here);
5796+ consumeToken ();
5797+ }
5798+
57405799 auto ParsedTypeResult = parseType ();
57415800 Status |= ParsedTypeResult;
57425801
@@ -5745,6 +5804,9 @@ ParserStatus Parser::parseInheritance(
57455804 Inherited.push_back (InheritedEntry (ParsedTypeResult.get ()));
57465805 } while (HasNextType);
57475806
5807+ if (parseTildeCopyable)
5808+ *parseTildeCopyable = TildeCopyableLoc;
5809+
57485810 return Status;
57495811}
57505812
@@ -8207,10 +8269,14 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
82078269 // Parse optional inheritance clause within the context of the enum.
82088270 if (Tok.is (tok::colon)) {
82098271 SmallVector<InheritedEntry, 2 > Inherited;
8272+ SourceLoc parsedTildeCopyable;
82108273 Status |= parseInheritance (Inherited,
82118274 /* allowClassRequirement=*/ false ,
8212- /* allowAnyObject=*/ false );
8275+ /* allowAnyObject=*/ false ,
8276+ &parsedTildeCopyable);
82138277 ED->setInherited (Context.AllocateCopy (Inherited));
8278+
8279+ addMoveOnlyAttrIf (parsedTildeCopyable, Context, ED);
82148280 }
82158281
82168282 diagnoseWhereClauseInGenericParamList (GenericParams);
@@ -8470,10 +8536,14 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
84708536 // Parse optional inheritance clause within the context of the struct.
84718537 if (Tok.is (tok::colon)) {
84728538 SmallVector<InheritedEntry, 2 > Inherited;
8539+ SourceLoc parsedTildeCopyable;
84738540 Status |= parseInheritance (Inherited,
84748541 /* allowClassRequirement=*/ false ,
8475- /* allowAnyObject=*/ false );
8542+ /* allowAnyObject=*/ false ,
8543+ &parsedTildeCopyable);
84768544 SD->setInherited (Context.AllocateCopy (Inherited));
8545+
8546+ addMoveOnlyAttrIf (parsedTildeCopyable, Context, SD);
84778547 }
84788548
84798549 diagnoseWhereClauseInGenericParamList (GenericParams);
0 commit comments