mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ASTGen] Generate 'IsExpansionPattern' generic requirements
E.g. `where repeat each T: Comparable`
This commit is contained in:
@@ -2885,29 +2885,27 @@ struct BridgedRequirementRepr {
|
|||||||
BridgedNullableTypeRepr SecondType;
|
BridgedNullableTypeRepr SecondType;
|
||||||
BridgedLayoutConstraint LayoutConstraint;
|
BridgedLayoutConstraint LayoutConstraint;
|
||||||
BridgedSourceLoc LayoutConstraintLoc;
|
BridgedSourceLoc LayoutConstraintLoc;
|
||||||
|
bool IsExpansionPattern;
|
||||||
// TODO: bool IsExpansionPattern;
|
|
||||||
|
|
||||||
swift::RequirementRepr unbridged() const;
|
swift::RequirementRepr unbridged() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
SWIFT_NAME(
|
SWIFT_NAME("BridgedRequirementRepr.createTypeConstraint(subject:colonLoc:"
|
||||||
"BridgedRequirementRepr.createTypeConstraint(subject:colonLoc:constraint:)")
|
"constraint:isExpansionPattern:)")
|
||||||
BridgedRequirementRepr
|
BridgedRequirementRepr BridgedRequirementRepr_createTypeConstraint(
|
||||||
BridgedRequirementRepr_createTypeConstraint(BridgedTypeRepr cSubject,
|
BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc,
|
||||||
BridgedSourceLoc cColonLoc,
|
BridgedTypeRepr cConstraint, bool isExpansionPattern);
|
||||||
BridgedTypeRepr cConstraint);
|
SWIFT_NAME("BridgedRequirementRepr.createSameType(firstType:equalLoc:"
|
||||||
SWIFT_NAME(
|
"secondType:isExpansionPattern:)")
|
||||||
"BridgedRequirementRepr.createSameType(firstType:equalLoc:secondType:)")
|
BridgedRequirementRepr BridgedRequirementRepr_createSameType(
|
||||||
BridgedRequirementRepr
|
BridgedTypeRepr cFirstType, BridgedSourceLoc cEqualLoc,
|
||||||
BridgedRequirementRepr_createSameType(BridgedTypeRepr cFirstType,
|
BridgedTypeRepr cSecondType, bool isExpansionPattern);
|
||||||
BridgedSourceLoc cEqualLoc,
|
|
||||||
BridgedTypeRepr cSecondType);
|
|
||||||
SWIFT_NAME("BridgedRequirementRepr.createLayoutConstraint(subject:colonLoc:"
|
SWIFT_NAME("BridgedRequirementRepr.createLayoutConstraint(subject:colonLoc:"
|
||||||
"layout:layoutLoc:)")
|
"layout:layoutLoc:isExpansionPattern:)")
|
||||||
BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint(
|
BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint(
|
||||||
BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc,
|
BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc,
|
||||||
BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc);
|
BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc,
|
||||||
|
bool isExpansionPattern);
|
||||||
|
|
||||||
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedGenericTypeParamKind : size_t {
|
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedGenericTypeParamKind : size_t {
|
||||||
/// A regular generic type parameter: 'T'
|
/// A regular generic type parameter: 'T'
|
||||||
|
|||||||
@@ -101,23 +101,22 @@ RequirementRepr BridgedRequirementRepr::unbridged() const {
|
|||||||
case BridgedRequirementReprKindTypeConstraint:
|
case BridgedRequirementReprKindTypeConstraint:
|
||||||
return RequirementRepr::getTypeConstraint(
|
return RequirementRepr::getTypeConstraint(
|
||||||
FirstType.unbridged(), SeparatorLoc.unbridged(), SecondType.unbridged(),
|
FirstType.unbridged(), SeparatorLoc.unbridged(), SecondType.unbridged(),
|
||||||
/*IsExpansionPattern=*/false);
|
IsExpansionPattern);
|
||||||
case BridgedRequirementReprKindSameType:
|
case BridgedRequirementReprKindSameType:
|
||||||
return RequirementRepr::getSameType(
|
return RequirementRepr::getSameType(
|
||||||
FirstType.unbridged(), SeparatorLoc.unbridged(), SecondType.unbridged(),
|
FirstType.unbridged(), SeparatorLoc.unbridged(), SecondType.unbridged(),
|
||||||
/*IsExpansionPattern=*/false);
|
IsExpansionPattern);
|
||||||
case BridgedRequirementReprKindLayoutConstraint:
|
case BridgedRequirementReprKindLayoutConstraint:
|
||||||
return RequirementRepr::getLayoutConstraint(
|
return RequirementRepr::getLayoutConstraint(
|
||||||
FirstType.unbridged(), SeparatorLoc.unbridged(),
|
FirstType.unbridged(), SeparatorLoc.unbridged(),
|
||||||
{LayoutConstraint.unbridged(), LayoutConstraintLoc.unbridged()},
|
{LayoutConstraint.unbridged(), LayoutConstraintLoc.unbridged()},
|
||||||
/*IsExpansionPattern=*/false);
|
IsExpansionPattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BridgedRequirementRepr
|
BridgedRequirementRepr BridgedRequirementRepr_createTypeConstraint(
|
||||||
BridgedRequirementRepr_createTypeConstraint(BridgedTypeRepr cSubject,
|
BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc,
|
||||||
BridgedSourceLoc cColonLoc,
|
BridgedTypeRepr cConstraint, bool isExpansionPattern) {
|
||||||
BridgedTypeRepr cConstraint) {
|
|
||||||
return {
|
return {
|
||||||
/*SeparatorLoc=*/cColonLoc,
|
/*SeparatorLoc=*/cColonLoc,
|
||||||
/*Kind=*/BridgedRequirementReprKindTypeConstraint,
|
/*Kind=*/BridgedRequirementReprKindTypeConstraint,
|
||||||
@@ -125,13 +124,13 @@ BridgedRequirementRepr_createTypeConstraint(BridgedTypeRepr cSubject,
|
|||||||
/*SecondType=*/cConstraint.unbridged(),
|
/*SecondType=*/cConstraint.unbridged(),
|
||||||
/*LayoutConstraint=*/{},
|
/*LayoutConstraint=*/{},
|
||||||
/*LayoutConstraintLoc=*/{},
|
/*LayoutConstraintLoc=*/{},
|
||||||
|
/*IsExpansionPattern=*/isExpansionPattern,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
BridgedRequirementRepr
|
BridgedRequirementRepr BridgedRequirementRepr_createSameType(
|
||||||
BridgedRequirementRepr_createSameType(BridgedTypeRepr cFirstType,
|
BridgedTypeRepr cFirstType, BridgedSourceLoc cEqualLoc,
|
||||||
BridgedSourceLoc cEqualLoc,
|
BridgedTypeRepr cSecondType, bool isExpansionPattern) {
|
||||||
BridgedTypeRepr cSecondType) {
|
|
||||||
return {
|
return {
|
||||||
/*SeparatorLoc=*/cEqualLoc,
|
/*SeparatorLoc=*/cEqualLoc,
|
||||||
/*Kind=*/BridgedRequirementReprKindSameType,
|
/*Kind=*/BridgedRequirementReprKindSameType,
|
||||||
@@ -139,12 +138,14 @@ BridgedRequirementRepr_createSameType(BridgedTypeRepr cFirstType,
|
|||||||
/*SecondType=*/cSecondType.unbridged(),
|
/*SecondType=*/cSecondType.unbridged(),
|
||||||
/*LayoutConstraint=*/{},
|
/*LayoutConstraint=*/{},
|
||||||
/*LayoutConstraintLoc=*/{},
|
/*LayoutConstraintLoc=*/{},
|
||||||
|
/*IsExpansionPattern=*/isExpansionPattern,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint(
|
BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint(
|
||||||
BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc,
|
BridgedTypeRepr cSubject, BridgedSourceLoc cColonLoc,
|
||||||
BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc) {
|
BridgedLayoutConstraint cLayout, BridgedSourceLoc cLayoutLoc,
|
||||||
|
bool isExpansionPattern) {
|
||||||
return {
|
return {
|
||||||
/*SeparatorLoc=*/cColonLoc,
|
/*SeparatorLoc=*/cColonLoc,
|
||||||
/*Kind=*/BridgedRequirementReprKindLayoutConstraint,
|
/*Kind=*/BridgedRequirementReprKindLayoutConstraint,
|
||||||
@@ -152,6 +153,7 @@ BridgedRequirementRepr BridgedRequirementRepr_createLayoutConstraint(
|
|||||||
/*SecondType=*/nullptr,
|
/*SecondType=*/nullptr,
|
||||||
/*LayoutConstraint=*/cLayout,
|
/*LayoutConstraint=*/cLayout,
|
||||||
/*LayoutConstraintLoc=*/cLayoutLoc,
|
/*LayoutConstraintLoc=*/cLayoutLoc,
|
||||||
|
/*IsExpansionPattern=*/isExpansionPattern,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,25 +111,41 @@ extension ASTGenVisitor {
|
|||||||
|
|
||||||
func generate(genericWhereClause node: GenericWhereClauseSyntax) -> BridgedTrailingWhereClause {
|
func generate(genericWhereClause node: GenericWhereClauseSyntax) -> BridgedTrailingWhereClause {
|
||||||
let requirements = node.requirements.lazy.map { elem -> BridgedRequirementRepr in
|
let requirements = node.requirements.lazy.map { elem -> BridgedRequirementRepr in
|
||||||
|
|
||||||
|
// Unwrap 'repeat T' to (isRequirementExpansion: true, type: T)
|
||||||
|
func generateIsExpansionPattern<Node: SyntaxProtocol>(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 {
|
switch elem.requirement {
|
||||||
case .conformanceRequirement(let conformance):
|
case .conformanceRequirement(let conformance):
|
||||||
|
let (isExpansionPattern, leftType) = generateIsExpansionPattern(type: conformance.leftType)
|
||||||
return .createTypeConstraint(
|
return .createTypeConstraint(
|
||||||
subject: self.generate(type: conformance.leftType),
|
subject: self.generate(type: leftType),
|
||||||
colonLoc: self.generateSourceLoc(conformance.colon),
|
colonLoc: self.generateSourceLoc(conformance.colon),
|
||||||
constraint: self.generate(type: conformance.rightType)
|
constraint: self.generate(type: conformance.rightType),
|
||||||
|
isExpansionPattern: isExpansionPattern
|
||||||
)
|
)
|
||||||
case .sameTypeRequirement(let sameType):
|
case .sameTypeRequirement(let sameType):
|
||||||
|
let (isExpansionPattern, leftType) = generateIsExpansionPattern(type: sameType.leftType)
|
||||||
return .createSameType(
|
return .createSameType(
|
||||||
firstType: self.generate(sameTypeLeftType: sameType.leftType),
|
firstType: self.generate(sameTypeLeftType: leftType),
|
||||||
equalLoc: self.generateSourceLoc(sameType.equal),
|
equalLoc: self.generateSourceLoc(sameType.equal),
|
||||||
secondType: self.generate(sameTypeRightType: sameType.rightType)
|
secondType: self.generate(sameTypeRightType: sameType.rightType),
|
||||||
|
isExpansionPattern: isExpansionPattern
|
||||||
)
|
)
|
||||||
case .layoutRequirement(let layout):
|
case .layoutRequirement(let layout):
|
||||||
|
let (isExpansionPattern, leftType) = generateIsExpansionPattern(type: layout.type)
|
||||||
return .createLayoutConstraint(
|
return .createLayoutConstraint(
|
||||||
subject: self.generate(type: layout.type),
|
subject: self.generate(type: leftType),
|
||||||
colonLoc: self.generateSourceLoc(layout.colon),
|
colonLoc: self.generateSourceLoc(layout.colon),
|
||||||
layout: self.generate(layoutRequirement: layout),
|
layout: self.generate(layoutRequirement: layout),
|
||||||
layoutLoc: self.generateSourceLoc(layout.layoutSpecifier)
|
layoutLoc: self.generateSourceLoc(layout.layoutSpecifier),
|
||||||
|
isExpansionPattern: isExpansionPattern
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,3 +346,5 @@ func testBuilder() {
|
|||||||
1
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ExpansionRequirementTest<each T> where repeat each T: Comparable {}
|
||||||
|
|||||||
@@ -33,3 +33,6 @@ struct S {
|
|||||||
subscript(x: Int) { _ = 1 } // expected-error@:23 {{expected '->' and return type in subscript}}
|
subscript(x: Int) { _ = 1 } // expected-error@:23 {{expected '->' and return type in subscript}}
|
||||||
// expected-note@-1:23 {{insert '->' and return type}}
|
// expected-note@-1:23 {{insert '->' and return type}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ExpansionRequirementTest<each T> {}
|
||||||
|
extension ExpansionRequirementTest where repeat each T == Int {} // expected-error {{same-element requirements are not yet supported}}
|
||||||
|
|||||||
Reference in New Issue
Block a user