From 6cf56e9eb712d8fffee0ea7142d2644603b6e13d Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 7 Mar 2025 10:17:45 -0800 Subject: [PATCH] SE-0458: Disambiguate postfix expressions vs. unsafe expressions more generally Handle call-vs-tuple and subscript-vs-collection-expr disambiguation using the same "no trivia" rule that we used to disambiguite "unsafe.x" (which we treat as a member access) from "unsafe .x" (which we treat as an unsafe expression with a leading-dot member access). Fixes rdar://146459104. --- lib/Parse/ParseExpr.cpp | 4 +++- test/Unsafe/safe.swift | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index a87247d5fc333..d3fbc3a614ffc 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -441,7 +441,9 @@ ParserResult Parser::parseExprSequenceElement(Diag<> message, peekToken().isAny(tok::r_paren, tok::r_brace, tok::r_square, tok::equal, tok::colon, tok::comma) || (isExprBasic && peekToken().is(tok::l_brace)) || - peekToken().is(tok::period))) { + peekToken().is(tok::period) || + (peekToken().isAny(tok::l_paren, tok::l_square) && + peekToken().getRange().getStart() == Tok.getRange().getEnd()))) { Tok.setKind(tok::contextual_keyword); SourceLoc unsafeLoc = consumeToken(); ParserResult sub = diff --git a/test/Unsafe/safe.swift b/test/Unsafe/safe.swift index 299e8e199dd37..e2e80ccd00c8f 100644 --- a/test/Unsafe/safe.swift +++ b/test/Unsafe/safe.swift @@ -183,6 +183,8 @@ func acceptBools(_: Bool, _: Bool) { } func acceptBoolsUnsafeLabel(unsafe _: Bool, _: Bool) { } +func unsafe(_: Int) { } + func unsafeFun() { var unsafe = true unsafe = false @@ -200,6 +202,20 @@ func unsafeFun() { if unsafe { } } +func moreUnsafeFunc(unsafe: [Int]) { + let _: [Int] = unsafe [] + // expected-warning@-1{{no unsafe operations occur within 'unsafe' expression}} + + _ = unsafe[1] +} + +func yetMoreUnsafeFunc(unsafe: () -> Void) { + unsafe() + + _ = unsafe () + // expected-warning@-1{{no unsafe operations occur within 'unsafe' expression}} +} + // @safe suppresses unsafe-type-related diagnostics on an entity struct MyArray { @safe func withUnsafeBufferPointer(