Skip to content

Commit ef9edbd

Browse files
committed
[ASTGen] Handle composition types parsed through parseType().
Protocol composition types such as `P & Q` are similar to nested types like `A.B` because the innermost type syntax node at the given position doesn't cover the whole type. Adjust by looking back up the tree. This all feels like a hack, and there should be a better way. While here, fix the source ranges passed in to create `CompositionTypeRepr`. We were tripping assertions due to missing source-location information.
1 parent 584299d commit ef9edbd

File tree

5 files changed

+24
-6
lines changed

5 files changed

+24
-6
lines changed

include/swift/AST/CASTBridging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ void *GenericIdentTypeRepr_create(void *ctx, BridgedIdentifier name,
348348
void *lAngle, void *rAngle);
349349
void *EmptyCompositionTypeRepr_create(void *ctx, void *anyLoc);
350350
void *CompositionTypeRepr_create(void *ctx, BridgedArrayRef types,
351-
void *firstTypeLoc);
351+
void *firstTypeLoc, void *firstAmpLoc);
352352
void *FunctionTypeRepr_create(void *ctx, void *argsTy, void *_Nullable asyncLoc,
353353
void *_Nullable throwsLoc, void *arrowLoc,
354354
void *returnType);

lib/AST/CASTBridging.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,12 +611,15 @@ void *EmptyCompositionTypeRepr_create(void *ctx, void *anyLocPtr) {
611611
return CompositionTypeRepr::createEmptyComposition(Context, anyLoc);
612612
}
613613

614-
void *CompositionTypeRepr_create(void *ctx, BridgedArrayRef types,
615-
void *firstTypeLoc) {
614+
void *CompositionTypeRepr_create(void *ctx, BridgedArrayRef typesPtr,
615+
void *firstTypeLoc, void *firstAmpLocPtr) {
616616
ASTContext &Context = *static_cast<ASTContext *>(ctx);
617617
SourceLoc firstType = getSourceLocFromPointer(firstTypeLoc);
618-
return CompositionTypeRepr::create(Context, getArrayRef<TypeRepr *>(types),
619-
firstType, SourceRange{});
618+
SourceLoc firstAmpLoc = getSourceLocFromPointer(firstAmpLocPtr);
619+
auto types = getArrayRef<TypeRepr *>(typesPtr);
620+
return CompositionTypeRepr::create(
621+
Context, types, firstType,
622+
SourceRange{firstAmpLoc, types.back()->getEndLoc()});
620623
}
621624

622625
void *FunctionTypeRepr_create(void *ctx, void *argsTy, void *_Nullable asyncLoc,

lib/ASTGen/Sources/ASTGen/Macros.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,18 @@ func findSyntaxNodeInSourceFile<Node: SyntaxProtocol>(
682682
}
683683

684684
// If we want the outermost node, keep looking.
685+
// FIXME: This is VERY SPECIFIC to handling of types. We must be able to
686+
// do better.
685687
if wantOutermost {
686688
while let parentSyntax = resultSyntax.parent {
689+
// Look through type compositions.
690+
if let compositionElement = parentSyntax.as(CompositionTypeElementSyntax.self),
691+
let compositionList = compositionElement.parent?.as(CompositionTypeElementListSyntax.self),
692+
let typedParent = compositionList.parent?.as(type) {
693+
resultSyntax = typedParent
694+
continue
695+
}
696+
687697
guard let typedParent = parentSyntax.as(type),
688698
typedParent.position == resultSyntax.position else {
689699
break

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,11 @@ extension ASTGenVisitor {
128128
assert(node.elements.count > 1)
129129
let types = node.elements.map { visit($0.type) }.map { $0.rawValue }
130130
let firstTypeLoc = self.base.advanced(by: node.elements.first!.type.position.utf8Offset).raw
131+
let firstAmpOffset = node.elements.first?.ampersand.map { $0.position.utf8Offset } ?? 0
132+
let firstAmpLoc = self.base.advanced(by: firstAmpOffset).raw
131133
return .type(
132134
types.withBridgedArrayRef { types in
133-
return CompositionTypeRepr_create(self.ctx, types, firstTypeLoc)
135+
return CompositionTypeRepr_create(self.ctx, types, firstTypeLoc, firstAmpLoc)
134136
})
135137
}
136138

test/ASTGen/types.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// -enable-experimental-feature requires an asserts build
44
// REQUIRES: asserts
55

6+
protocol P { }
7+
protocol Q { }
8+
typealias PQ = P & Q
69

710
func test7(_ b: inout Bool) {
811
b = true

0 commit comments

Comments
 (0)