From c460947a73cd9d5e1531f825cb91eb6973bd80f9 Mon Sep 17 00:00:00 2001 From: Rintaro Ishizaki Date: Thu, 20 Feb 2025 12:12:35 -0800 Subject: [PATCH 1/3] [ASTGen] Wrap optional binding pattern with type annotation --- lib/ASTGen/Sources/ASTGen/Stmts.swift | 8 ++++++++ test/ASTGen/stmts.swift | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/ASTGen/Sources/ASTGen/Stmts.swift b/lib/ASTGen/Sources/ASTGen/Stmts.swift index ab059d73baf6f..97280f48e9d99 100644 --- a/lib/ASTGen/Sources/ASTGen/Stmts.swift +++ b/lib/ASTGen/Sources/ASTGen/Stmts.swift @@ -161,6 +161,14 @@ extension ASTGenVisitor { // I'm not sure this should really be implicit. pat.setImplicit() + if let typeAnnotation = node.typeAnnotation { + pat = BridgedTypedPattern.createParsed( + self.ctx, + pattern: pat, + type: self.generate(type: typeAnnotation.type) + ).asPattern + } + let initializer: BridgedExpr if let initNode = node.initializer { initializer = self.generate(expr: initNode.value) diff --git a/test/ASTGen/stmts.swift b/test/ASTGen/stmts.swift index 5b0817284f8f4..730d86282bd8f 100644 --- a/test/ASTGen/stmts.swift +++ b/test/ASTGen/stmts.swift @@ -116,6 +116,17 @@ func testThen() { } } +func intOrString() -> Int? { 1 } +func intOrString() -> String? { "" } +func testIf() { + if + let i: Int = intOrString(), + case let str? = intOrString() as String? + { + _ = (i, str) + } +} + struct GenericTypeWithYields { var storedProperty: T? From f48282c92baf219021d8c10acd08c8a2fb488176 Mon Sep 17 00:00:00 2001 From: Rintaro Ishizaki Date: Thu, 20 Feb 2025 14:50:48 -0800 Subject: [PATCH 2/3] [ASTGen] Generate trailing where clause for SubscriptDecl It was just missing. --- include/swift/AST/ASTBridging.h | 5 +++-- lib/AST/ASTDumper.cpp | 1 + lib/AST/Bridging/DeclBridging.cpp | 7 +++++-- lib/ASTGen/Sources/ASTGen/Decls.swift | 3 ++- lib/ASTGen/Sources/ASTGen/Stmts.swift | 17 ++++++++--------- test/ASTGen/decls.swift | 4 ++++ 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 5241d609be9c9..617e3dafd1b21 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -1568,14 +1568,15 @@ BridgedImportDecl BridgedImportDecl_createParsed( SWIFT_NAME("BridgedSubscriptDecl.createParsed(_:declContext:staticLoc:" "staticSpelling:subscriptKeywordLoc:genericParamList:parameterList:" - "arrowLoc:returnType:)") + "arrowLoc:returnType:genericWhereClause:)") BridgedSubscriptDecl BridgedSubscriptDecl_createParsed( BridgedASTContext cContext, BridgedDeclContext cDeclContext, BridgedSourceLoc cStaticLoc, BridgedStaticSpelling cStaticSpelling, BridgedSourceLoc cSubscriptKeywordLoc, BridgedNullableGenericParamList cGenericParamList, BridgedParameterList cParamList, BridgedSourceLoc cArrowLoc, - BridgedTypeRepr returnType); + BridgedTypeRepr returnType, + BridgedNullableTrailingWhereClause genericWhereClause); SWIFT_NAME("BridgedTopLevelCodeDecl.create(_:declContext:)") BridgedTopLevelCodeDecl diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index ca6cf5de3deef..e25b50b7f44c7 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -2192,6 +2192,7 @@ namespace { Label::optional("generic_signature")); } else { printParsedGenericParams(GC->getParsedGenericParams()); + printWhereRequirements(GC); } } diff --git a/lib/AST/Bridging/DeclBridging.cpp b/lib/AST/Bridging/DeclBridging.cpp index a3f55f5f0a04d..0672113b7f463 100644 --- a/lib/AST/Bridging/DeclBridging.cpp +++ b/lib/AST/Bridging/DeclBridging.cpp @@ -615,12 +615,15 @@ BridgedSubscriptDecl BridgedSubscriptDecl_createParsed( BridgedSourceLoc cSubscriptKeywordLoc, BridgedNullableGenericParamList cGenericParamList, BridgedParameterList cParamList, BridgedSourceLoc cArrowLoc, - BridgedTypeRepr returnType) { - return SubscriptDecl::createParsed( + BridgedTypeRepr returnType, + BridgedNullableTrailingWhereClause genericWhereClause) { + auto *decl = SubscriptDecl::createParsed( cContext.unbridged(), cStaticLoc.unbridged(), unbridged(cStaticSpelling), cSubscriptKeywordLoc.unbridged(), cParamList.unbridged(), cArrowLoc.unbridged(), returnType.unbridged(), cDeclContext.unbridged(), cGenericParamList.unbridged()); + decl->setTrailingWhereClause(genericWhereClause.unbridged()); + return decl; } BridgedTopLevelCodeDecl diff --git a/lib/ASTGen/Sources/ASTGen/Decls.swift b/lib/ASTGen/Sources/ASTGen/Decls.swift index 02b26ddcf74c0..bdadbe59809cd 100644 --- a/lib/ASTGen/Sources/ASTGen/Decls.swift +++ b/lib/ASTGen/Sources/ASTGen/Decls.swift @@ -630,7 +630,8 @@ extension ASTGenVisitor { genericParamList: self.generate(genericParameterClause: node.genericParameterClause), parameterList: self.generate(functionParameterClause: node.parameterClause, for: .subscript), arrowLoc: self.generateSourceLoc(node.returnClause.arrow), - returnType: self.generate(type: node.returnClause.type) + returnType: self.generate(type: node.returnClause.type), + genericWhereClause: self.generate(genericWhereClause: node.genericWhereClause) ) subscriptDecl.asDecl.attachParsedAttrs(attrs.attributes) diff --git a/lib/ASTGen/Sources/ASTGen/Stmts.swift b/lib/ASTGen/Sources/ASTGen/Stmts.swift index 97280f48e9d99..20bc872980b9e 100644 --- a/lib/ASTGen/Sources/ASTGen/Stmts.swift +++ b/lib/ASTGen/Sources/ASTGen/Stmts.swift @@ -148,17 +148,16 @@ extension ASTGenVisitor { var pat = self.generate(pattern: node.pattern) let keywordLoc = self.generateSourceLoc(node.bindingSpecifier) let isLet = node.bindingSpecifier.keywordKind == .let - pat = - BridgedBindingPattern.createParsed( - self.ctx, - keywordLoc: keywordLoc, - isLet: isLet, - subPattern: pat - ).asPattern + pat = BridgedBindingPattern.createParsed( + self.ctx, + keywordLoc: keywordLoc, + isLet: isLet, + subPattern: pat + ).asPattern // NOTE: (From the comment in libParse) The let/var pattern is part of the - // statement. But since the statement doesn't have the information. But, - // I'm not sure this should really be implicit. + // statement. But since the statement doesn't have the information, I'm not + // sure this should really be implicit. pat.setImplicit() if let typeAnnotation = node.typeAnnotation { diff --git a/test/ASTGen/decls.swift b/test/ASTGen/decls.swift index ae29d1c0ceeef..316802f841bdb 100644 --- a/test/ASTGen/decls.swift +++ b/test/ASTGen/decls.swift @@ -174,6 +174,10 @@ struct TestSubscripts { } set(x) {} } + + subscript(i: I, j: J) -> Int where I.A == J.B { + 1 + } } protocol Proto1 {} From efea164d04c435059dfb55458516a328e4c7800a Mon Sep 17 00:00:00 2001 From: Rintaro Ishizaki Date: Thu, 20 Feb 2025 16:13:57 -0800 Subject: [PATCH 3/3] [ASTGen] Generate from 'MissingTypeSyntax' Just emit ErrorTypeRepr --- include/swift/AST/ASTBridging.h | 4 ++++ include/swift/AST/Decl.h | 2 ++ lib/AST/ASTDumper.cpp | 2 ++ lib/AST/Bridging/TypeReprBridging.cpp | 5 +++++ lib/AST/Decl.cpp | 5 +++++ lib/ASTGen/Sources/ASTGen/Types.swift | 11 +++++++++-- test/ASTGen/diagnostics.swift | 5 +++++ 7 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 617e3dafd1b21..37e382a976bd6 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -2510,6 +2510,10 @@ BridgedDictionaryTypeRepr BridgedDictionaryTypeRepr_createParsed( BridgedTypeRepr keyType, BridgedSourceLoc cColonloc, BridgedTypeRepr valueType, BridgedSourceLoc cRSquareLoc); +SWIFT_NAME("BridgedErrorTypeRepr.create(_:range:)") +BridgedErrorTypeRepr BridgedErrorTypeRepr_create(BridgedASTContext cContext, + BridgedSourceRange cRange); + SWIFT_NAME("BridgedFunctionTypeRepr.createParsed(_:argsType:asyncLoc:throwsLoc:" "thrownType:arrowLoc:resultType:)") BridgedFunctionTypeRepr BridgedFunctionTypeRepr_createParsed( diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index a1aaff68fca48..6e5210886e3c5 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -7459,6 +7459,8 @@ class SubscriptDecl : public GenericContext, public AbstractStorageDecl { /// operation. Type getElementInterfaceType() const; + std::optional getCachedElementInterfaceType() const; + TypeRepr *getElementTypeRepr() const { return ElementTy.getTypeRepr(); } SourceRange getElementTypeSourceRange() const { return ElementTy.getSourceRange(); diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index e25b50b7f44c7..b48a2b1fb510b 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -2563,6 +2563,8 @@ namespace { printCommon(SD, "subscript_decl", label); printStorageImpl(SD); printAttributes(SD); + printTypeOrTypeRepr(SD->getCachedElementInterfaceType(), + SD->getElementTypeRepr(), Label::always("element")); printAccessors(SD); printFoot(); } diff --git a/lib/AST/Bridging/TypeReprBridging.cpp b/lib/AST/Bridging/TypeReprBridging.cpp index 06bf893aafa02..7c5f5b359e7c1 100644 --- a/lib/AST/Bridging/TypeReprBridging.cpp +++ b/lib/AST/Bridging/TypeReprBridging.cpp @@ -95,6 +95,11 @@ BridgedDictionaryTypeRepr BridgedDictionaryTypeRepr_createParsed( SourceRange{lSquareLoc, rSquareLoc}); } +BridgedErrorTypeRepr BridgedErrorTypeRepr_create(BridgedASTContext cContext, + BridgedSourceRange cRange) { + return ErrorTypeRepr::create(cContext.unbridged(), cRange.unbridged()); +} + BridgedInverseTypeRepr BridgedInverseTypeRepr_createParsed(BridgedASTContext cContext, BridgedSourceLoc cTildeLoc, diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 4b1e4ecb96faf..55f5fde070457 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -9343,6 +9343,11 @@ Type SubscriptDecl::getElementInterfaceType() const { return ErrorType::get(ctx); } +std::optional SubscriptDecl::getCachedElementInterfaceType() const { + auto mutableThis = const_cast(this); + return ResultTypeRequest{mutableThis}.getCachedResult(); +} + ObjCSubscriptKind SubscriptDecl::getObjCSubscriptKind() const { // If the index type is an integral type, we have an indexed // subscript. diff --git a/lib/ASTGen/Sources/ASTGen/Types.swift b/lib/ASTGen/Sources/ASTGen/Types.swift index 436c1fac6989e..c656272a12e50 100644 --- a/lib/ASTGen/Sources/ASTGen/Types.swift +++ b/lib/ASTGen/Sources/ASTGen/Types.swift @@ -44,8 +44,8 @@ extension ASTGenVisitor { return self.generate(memberType: node).asTypeRepr case .metatypeType(let node): return self.generate(metatypeType: node) - case .missingType: - fatalError("unimplemented") + case .missingType(let node): + return self.generate(missingType: node) case .namedOpaqueReturnType(let node): return self.generate(namedOpaqueReturnType: node).asTypeRepr case .optionalType(let node): @@ -164,6 +164,13 @@ extension ASTGenVisitor { } } + func generate(missingType node: MissingTypeSyntax) -> BridgedTypeRepr { + return BridgedErrorTypeRepr.create( + self.ctx, + range: self.generateSourceRange(node) + ).asTypeRepr + } + func generate( implicitlyUnwrappedOptionalType node: ImplicitlyUnwrappedOptionalTypeSyntax ) -> BridgedImplicitlyUnwrappedOptionalTypeRepr { diff --git a/test/ASTGen/diagnostics.swift b/test/ASTGen/diagnostics.swift index c217ca638f36f..fb8505ad214d2 100644 --- a/test/ASTGen/diagnostics.swift +++ b/test/ASTGen/diagnostics.swift @@ -28,3 +28,8 @@ func dummy() {} @_silgen_name("whatever", extra) // expected-error@:27 {{unexpected arguments in '_silgen_name' attribute}} func _whatever() + +struct S { + subscript(x: Int) { _ = 1 } // expected-error@:23 {{expected '->' and return type in subscript}} + // expected-note@-1:23 {{insert '->' and return type}} +}