[libSyntax] Explicitly return 0 as length of missing deferred tokens

Previously, we were always accessing the `DeferredTokenNode`’s `Range`, which is not valid if the token is missing, thus causing an assertion failure when asked for its length.

Fixes rdar://77391988 [SR-14552]
This commit is contained in:
Alex Hoppen
2021-05-04 14:51:57 +02:00
parent c7b383c1e7
commit 6095053fe1
2 changed files with 15 additions and 2 deletions

View File

@@ -6,3 +6,6 @@ let x: a[i] & b
let x2: a & b[1] let x2: a & b[1]
// CHECK: |x2| // CHECK: |x2|
let x3: (A -> B)
// CHECK: |x3|

View File

@@ -111,6 +111,16 @@ struct DeferredTokenNode {
: IsMissing(IsMissing), TokenKind(TokenKind), : IsMissing(IsMissing), TokenKind(TokenKind),
LeadingTrivia(LeadingTrivia), TrailingTrivia(TrailingTrivia), LeadingTrivia(LeadingTrivia), TrailingTrivia(TrailingTrivia),
Range(Range) {} Range(Range) {}
/// Returns the length of this token or \c 0 if the token is missing.
size_t getLength() const {
if (IsMissing) {
return 0;
} else {
assert(Range.isValid());
return Range.getByteLength();
}
}
}; };
struct DeferredLayoutNode { struct DeferredLayoutNode {
@@ -272,7 +282,7 @@ private:
break; break;
case RecordedOrDeferredNode::Kind::DeferredToken: case RecordedOrDeferredNode::Kind::DeferredToken:
length += static_cast<const DeferredTokenNode *>(child.getOpaque()) length += static_cast<const DeferredTokenNode *>(child.getOpaque())
->Range.getByteLength(); ->getLength();
break; break;
} }
} }
@@ -373,7 +383,7 @@ private:
case RecordedOrDeferredNode::Kind::DeferredToken: case RecordedOrDeferredNode::Kind::DeferredToken:
StartLoc = StartLoc.getAdvancedLoc( StartLoc = StartLoc.getAdvancedLoc(
static_cast<const DeferredTokenNode *>(Child.getOpaque()) static_cast<const DeferredTokenNode *>(Child.getOpaque())
->Range.getByteLength()); ->getLength());
break; break;
} }
} }