diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 34ad8a947a1..9d9ed4ca6ba 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -2885,29 +2885,27 @@ struct BridgedRequirementRepr { BridgedNullableTypeRepr SecondType; BridgedLayoutConstraint LayoutConstraint; BridgedSourceLoc LayoutConstraintLoc; - - // TODO: bool IsExpansionPattern; + bool IsExpansionPattern; swift::RequirementRepr unbridged() const; }; -SWIFT_NAME( - "BridgedRequirementRepr.createTypeConstraint(subject:colonLoc:constraint:)") -BridgedRequirementRepr -BridgedRequirementRepr_createTypeConstraint(BridgedTypeRepr cSubject, - BridgedSourceLoc cColonLoc, - BridgedTypeRepr cConstraint); -SWIFT_NAME( - "BridgedRequirementRepr.createSameType(firstType:equalLoc:secondType:)") -BridgedRequirementRepr -BridgedRequirementRepr_createSameType(BridgedTypeRepr cFirstType, - BridgedSourceLoc cEqualLoc, - BridgedTypeRepr cSecondType); +SWIFT_NAME("BridgedRequirementRepr.createTypeConstraint(subject:colonLoc:" + "constraint:isExpansionPattern:)") +BridgedRequirementRepr BridgedRequirementRepr_createTypeConstraint( + BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc, + BridgedTypeRepr cConstraint, bool isExpansionPattern); +SWIFT_NAME("BridgedRequirementRepr.createSameType(firstType:equalLoc:" + "secondType:isExpansionPattern:)") +BridgedRequirementRepr BridgedRequirementRepr_createSameType( + BridgedTypeRepr cFirstType, BridgedSourceLoc cEqualLoc, + BridgedTypeRepr cSecondType, bool isExpansionPattern); SWIFT_NAME("BridgedRequirementRepr.createLayoutConstraint(subject:colonLoc:" - "layout:layoutLoc:)") + "layout:layoutLoc:isExpansionPattern:)") BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint( BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc, - BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc); + BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc, + bool isExpansionPattern); enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedGenericTypeParamKind : size_t { /// A regular generic type parameter: 'T' diff --git a/lib/AST/Bridging/GenericsBridging.cpp b/lib/AST/Bridging/GenericsBridging.cpp index 2a354cc1cd1..6794eb9f89c 100644 --- a/lib/AST/Bridging/GenericsBridging.cpp +++ b/lib/AST/Bridging/GenericsBridging.cpp @@ -101,23 +101,22 @@ RequirementRepr BridgedRequirementRepr::unbridged() const { case BridgedRequirementReprKindTypeConstraint: return RequirementRepr::getTypeConstraint( FirstType.unbridged(), SeparatorLoc.unbridged(), SecondType.unbridged(), - /*IsExpansionPattern=*/false); + IsExpansionPattern); case BridgedRequirementReprKindSameType: return RequirementRepr::getSameType( FirstType.unbridged(), SeparatorLoc.unbridged(), SecondType.unbridged(), - /*IsExpansionPattern=*/false); + IsExpansionPattern); case BridgedRequirementReprKindLayoutConstraint: return RequirementRepr::getLayoutConstraint( FirstType.unbridged(), SeparatorLoc.unbridged(), {LayoutConstraint.unbridged(), LayoutConstraintLoc.unbridged()}, - /*IsExpansionPattern=*/false); + IsExpansionPattern); } } -BridgedRequirementRepr -BridgedRequirementRepr_createTypeConstraint(BridgedTypeRepr cSubject, - BridgedSourceLoc cColonLoc, - BridgedTypeRepr cConstraint) { +BridgedRequirementRepr BridgedRequirementRepr_createTypeConstraint( + BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc, + BridgedTypeRepr cConstraint, bool isExpansionPattern) { return { /*SeparatorLoc=*/cColonLoc, /*Kind=*/BridgedRequirementReprKindTypeConstraint, @@ -125,13 +124,13 @@ BridgedRequirementRepr_createTypeConstraint(BridgedTypeRepr cSubject, /*SecondType=*/cConstraint.unbridged(), /*LayoutConstraint=*/{}, /*LayoutConstraintLoc=*/{}, + /*IsExpansionPattern=*/isExpansionPattern, }; } -BridgedRequirementRepr -BridgedRequirementRepr_createSameType(BridgedTypeRepr cFirstType, - BridgedSourceLoc cEqualLoc, - BridgedTypeRepr cSecondType) { +BridgedRequirementRepr BridgedRequirementRepr_createSameType( + BridgedTypeRepr cFirstType, BridgedSourceLoc cEqualLoc, + BridgedTypeRepr cSecondType, bool isExpansionPattern) { return { /*SeparatorLoc=*/cEqualLoc, /*Kind=*/BridgedRequirementReprKindSameType, @@ -139,12 +138,14 @@ BridgedRequirementRepr_createSameType(BridgedTypeRepr cFirstType, /*SecondType=*/cSecondType.unbridged(), /*LayoutConstraint=*/{}, /*LayoutConstraintLoc=*/{}, + /*IsExpansionPattern=*/isExpansionPattern, }; } BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint( BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc, - BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc) { + BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc, + bool isExpansionPattern) { return { /*SeparatorLoc=*/cColonLoc, /*Kind=*/BridgedRequirementReprKindLayoutConstraint, @@ -152,6 +153,7 @@ BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint( /*SecondType=*/nullptr, /*LayoutConstraint=*/cLayout, /*LayoutConstraintLoc=*/cLayoutLoc, + /*IsExpansionPattern=*/isExpansionPattern, }; } diff --git a/lib/ASTGen/Sources/ASTGen/Generics.swift b/lib/ASTGen/Sources/ASTGen/Generics.swift index b6a1ce9bead..341c73fe206 100644 --- a/lib/ASTGen/Sources/ASTGen/Generics.swift +++ b/lib/ASTGen/Sources/ASTGen/Generics.swift @@ -111,25 +111,41 @@ extension ASTGenVisitor { func generate(genericWhereClause node: GenericWhereClauseSyntax) -> BridgedTrailingWhereClause { let requirements = node.requirements.lazy.map { elem -> BridgedRequirementRepr in + + // Unwrap 'repeat T' to (isRequirementExpansion: true, type: T) + func generateIsExpansionPattern(type node: Node) -> (isExpansionPattern: Bool, type: Node) { + if let expansion = node.as(PackExpansionTypeSyntax.self) { + // Force unwrapping is safe because both 'TypeSyntax' and 'SameTypeRequirementSyntax.LeftType' accept 'TypeSyntax'. + return (true, Node(expansion.repetitionPattern)!) + } + return (false, node) + } + switch elem.requirement { case .conformanceRequirement(let conformance): + let (isExpansionPattern, leftType) = generateIsExpansionPattern(type: conformance.leftType) return .createTypeConstraint( - subject: self.generate(type: conformance.leftType), + subject: self.generate(type: leftType), colonLoc: self.generateSourceLoc(conformance.colon), - constraint: self.generate(type: conformance.rightType) + constraint: self.generate(type: conformance.rightType), + isExpansionPattern: isExpansionPattern ) case .sameTypeRequirement(let sameType): + let (isExpansionPattern, leftType) = generateIsExpansionPattern(type: sameType.leftType) return .createSameType( - firstType: self.generate(sameTypeLeftType: sameType.leftType), + firstType: self.generate(sameTypeLeftType: leftType), equalLoc: self.generateSourceLoc(sameType.equal), - secondType: self.generate(sameTypeRightType: sameType.rightType) + secondType: self.generate(sameTypeRightType: sameType.rightType), + isExpansionPattern: isExpansionPattern ) case .layoutRequirement(let layout): + let (isExpansionPattern, leftType) = generateIsExpansionPattern(type: layout.type) return .createLayoutConstraint( - subject: self.generate(type: layout.type), + subject: self.generate(type: leftType), colonLoc: self.generateSourceLoc(layout.colon), layout: self.generate(layoutRequirement: layout), - layoutLoc: self.generateSourceLoc(layout.layoutSpecifier) + layoutLoc: self.generateSourceLoc(layout.layoutSpecifier), + isExpansionPattern: isExpansionPattern ) } } diff --git a/test/ASTGen/decls.swift b/test/ASTGen/decls.swift index 316802f841b..33d3a0b218a 100644 --- a/test/ASTGen/decls.swift +++ b/test/ASTGen/decls.swift @@ -346,3 +346,5 @@ func testBuilder() { 1 } } + +struct ExpansionRequirementTest where repeat each T: Comparable {} diff --git a/test/ASTGen/diagnostics.swift b/test/ASTGen/diagnostics.swift index fb8505ad214..50eab0c1667 100644 --- a/test/ASTGen/diagnostics.swift +++ b/test/ASTGen/diagnostics.swift @@ -33,3 +33,6 @@ struct S { subscript(x: Int) { _ = 1 } // expected-error@:23 {{expected '->' and return type in subscript}} // expected-note@-1:23 {{insert '->' and return type}} } + +struct ExpansionRequirementTest {} +extension ExpansionRequirementTest where repeat each T == Int {} // expected-error {{same-element requirements are not yet supported}}