diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 2a5efd1fb0191..c7a7ee4b8d050 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -1217,15 +1217,25 @@ class Parser { //===--------------------------------------------------------------------===// // Type Parsing - + + enum class ParseTypeReason { + /// Any type parsing context. + Unspecified, + + /// Whether the type is for a closure attribute. + CustomAttribute, + }; + ParserResult parseType(); - ParserResult parseType(Diag<> MessageID, - bool IsSILFuncDecl = false); + ParserResult parseType( + Diag<> MessageID, + ParseTypeReason reason = ParseTypeReason::Unspecified); ParserResult - parseTypeSimpleOrComposition(Diag<> MessageID); + parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason); - ParserResult parseTypeSimple(Diag<> MessageID); + ParserResult parseTypeSimple( + Diag<> MessageID, ParseTypeReason reason); /// Parse layout constraint. LayoutConstraint parseLayoutConstraint(Identifier LayoutConstraintID); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 99fb2a474bb39..0b75061217fd8 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2821,7 +2821,7 @@ ParserResult Parser::parseCustomAttribute( SyntaxContext->setCreateSyntax(SyntaxKind::CustomAttribute); // Parse a custom attribute. - auto type = parseType(diag::expected_type); + auto type = parseType(diag::expected_type, ParseTypeReason::CustomAttribute); if (type.hasCodeCompletion() || type.isNull()) { if (Tok.is(tok::l_paren) && isCustomAttributeArgument()) skipSingle(); diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index 0255c095bb6da..99fb00fa6d5fc 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -374,7 +374,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, } if (isBareType && paramContext == ParameterContextKind::EnumElement) { - auto type = parseType(diag::expected_parameter_type, false); + auto type = parseType(diag::expected_parameter_type); status |= type; param.Type = type.getPtrOrNull(); param.FirstName = Identifier(); @@ -389,7 +389,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, // the user is about to type the parameter label and we shouldn't // suggest types. SourceLoc typeStartLoc = Tok.getLoc(); - auto type = parseType(diag::expected_parameter_type, false); + auto type = parseType(diag::expected_parameter_type); status |= type; param.Type = type.getPtrOrNull(); diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index cde01afc77391..99a10893efe4f 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -157,7 +157,8 @@ LayoutConstraint Parser::parseLayoutConstraint(Identifier LayoutConstraintID) { /// type-simple '!' /// type-collection /// type-array -ParserResult Parser::parseTypeSimple(Diag<> MessageID) { +ParserResult Parser::parseTypeSimple( + Diag<> MessageID, ParseTypeReason reason) { ParserResult ty; if (Tok.is(tok::kw_inout) || @@ -242,7 +243,7 @@ ParserResult Parser::parseTypeSimple(Diag<> MessageID) { continue; } // Parse legacy array types for migration. - if (Tok.is(tok::l_square)) { + if (Tok.is(tok::l_square) && reason != ParseTypeReason::CustomAttribute) { ty = parseTypeArray(ty); continue; } @@ -329,8 +330,8 @@ ParserResult Parser::parseSILBoxType(GenericParamList *generics, /// type-function: /// type-composition 'async'? 'throws'? '->' type /// -ParserResult Parser::parseType(Diag<> MessageID, - bool IsSILFuncDecl) { +ParserResult Parser::parseType( + Diag<> MessageID, ParseTypeReason reason) { // Start a context for creating type syntax. SyntaxParsingContext TypeParsingContext(SyntaxContext, SyntaxContextKind::Type); @@ -369,7 +370,7 @@ ParserResult Parser::parseType(Diag<> MessageID, return parseSILBoxType(generics, attrs); } - ParserResult ty = parseTypeSimpleOrComposition(MessageID); + ParserResult ty = parseTypeSimpleOrComposition(MessageID, reason); status |= ParserStatus(ty); if (ty.isNull()) return status; @@ -762,7 +763,7 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) { /// 'some'? type-simple /// type-composition '&' type-simple ParserResult -Parser::parseTypeSimpleOrComposition(Diag<> MessageID) { +Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) { SyntaxParsingContext SomeTypeContext(SyntaxContext, SyntaxKind::SomeType); // Check for the opaque modifier. // This is only semantically allowed in certain contexts, but we parse it @@ -786,7 +787,7 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID) { SyntaxParsingContext CompositionContext(SyntaxContext, SyntaxContextKind::Type); // Parse the first type - ParserResult FirstType = parseTypeSimple(MessageID); + ParserResult FirstType = parseTypeSimple(MessageID, reason); if (FirstType.isNull()) return FirstType; if (!Tok.isContextualPunctuator("&")) { @@ -844,7 +845,7 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID) { // Parse next type. ParserResult ty = - parseTypeSimple(diag::expected_identifier_for_type); + parseTypeSimple(diag::expected_identifier_for_type, reason); if (ty.hasCodeCompletion()) return makeParserCodeCompletionResult(); Status |= ty; diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 2aa19a770547e..455bddee629b3 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -1259,8 +1259,7 @@ bool SILParser::parseSILType(SILType &Result, TypeAttributes::Convention::makeSwiftConvention("thin"); } - ParserResult TyR = P.parseType(diag::expected_sil_type, - /*isSILFuncDecl*/ IsFuncDecl); + ParserResult TyR = P.parseType(diag::expected_sil_type); if (TyR.isNull()) return true; diff --git a/test/Concurrency/global_actor_function_types.swift b/test/Concurrency/global_actor_function_types.swift index 4172598edc239..975173415473f 100644 --- a/test/Concurrency/global_actor_function_types.swift +++ b/test/Concurrency/global_actor_function_types.swift @@ -33,7 +33,7 @@ func someSlowOperation() async -> Int { 5 } func acceptOnSomeGlobalActor(_: @SomeGlobalActor () -> T) { } -func testClosures() async { +func testClosures(i: Int) async { // Global actors on synchronous closures become part of the type let cl1 = { @SomeGlobalActor in onSomeGlobalActor() @@ -46,6 +46,10 @@ func testClosures() async { } let _: Double = cl2 // expected-error{{cannot convert value of type '() async -> Int' to specified type 'Double'}} + let cl3 = { @SomeGlobalActor [i] in + print(i + onSomeGlobalActor()) + } + // okay to be explicit acceptOnSomeGlobalActor { @SomeGlobalActor in onSomeGlobalActor()