Skip to content

Commit 052958e

Browse files
authored
Merge pull request #79462 from DougGregor/remove-unsafe-from-inline
Remove "unsafe" keyword from expressions when printing inlinable code
2 parents 83a028d + 13c82c6 commit 052958e

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import ASTBridging
1414
import SwiftDiagnostics
1515
@_spi(Compiler) import SwiftIfConfig
16-
import SwiftParser
17-
import SwiftSyntax
16+
@_spi(ExperimentalLanguageFeatures) import SwiftParser
17+
@_spi(ExperimentalLanguageFeatures) import SwiftSyntax
1818

1919
/// A build configuration that uses the compiler's ASTContext to answer
2020
/// queries.
@@ -517,7 +517,11 @@ public func extractInlinableText(
517517
sourceText: BridgedStringRef
518518
) -> BridgedStringRef {
519519
let textBuffer = UnsafeBufferPointer<UInt8>(start: sourceText.data, count: sourceText.count)
520-
var parser = Parser(textBuffer)
520+
var parser = Parser(
521+
textBuffer,
522+
swiftVersion: Parser.SwiftVersion(from: astContext),
523+
experimentalFeatures: Parser.ExperimentalFeatures(from: astContext)
524+
)
521525
let syntax = SourceFileSyntax.parse(from: &parser)
522526

523527
let configuration = CompilerBuildConfiguration(
@@ -531,6 +535,24 @@ public func extractInlinableText(
531535
retainFeatureCheckIfConfigs: true
532536
).result
533537

538+
// Remove "unsafe" expressions.
539+
let inlineableSyntax = syntaxWithoutInactive.withoutUnsafeExpressions
540+
534541
// Remove comments and return the result.
535-
return allocateBridgedString(syntaxWithoutInactive.descriptionWithoutCommentsAndSourceLocations)
542+
return allocateBridgedString(inlineableSyntax.descriptionWithoutCommentsAndSourceLocations)
543+
}
544+
545+
/// Used by withoutUnsafeExpressions to remove "unsafe" expressions from
546+
/// a syntax tree.
547+
fileprivate class RemoveUnsafeExprSyntaxRewriter: SyntaxRewriter {
548+
override func visit(_ node: UnsafeExprSyntax) -> ExprSyntax {
549+
return node.expression.with(\.leadingTrivia, node.leadingTrivia)
550+
}
551+
}
552+
553+
extension SyntaxProtocol {
554+
/// Return a new syntax tree with all "unsafe" expressions removed.
555+
var withoutUnsafeExpressions: Syntax {
556+
RemoveUnsafeExprSyntaxRewriter().rewrite(self)
557+
}
536558
}

test/Unsafe/module-interface.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -module-name UserModule -enable-experimental-feature AllowUnsafeAttribute -enable-experimental-feature WarnUnsafe
2+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -module-name UserModule
3+
// RUN: %FileCheck %s < %t.swiftinterface
4+
5+
// REQUIRES: swift_feature_AllowUnsafeAttribute
6+
// REQUIRES: swift_feature_WarnUnsafe
7+
8+
// CHECK: #if compiler(>=5.3) && $AllowUnsafeAttribute
9+
// CHECK: @unsafe public func getIntUnsafely() -> Swift.Int
10+
// CHECK: #else
11+
// CHECK: public func getIntUnsafely() -> Swift.Int
12+
// CHECK: #endif
13+
@unsafe public func getIntUnsafely() -> Int { 0 }
14+
15+
// CHECK: @inlinable public func useUnsafeCode()
16+
@inlinable public func useUnsafeCode() {
17+
// CHECK-NOT: unsafe
18+
print( unsafe getIntUnsafely())
19+
}
20+
21+
// CHECK: public protocol P
22+
public protocol P {
23+
func f()
24+
}
25+
26+
// CHECK: public struct X : @unsafe UserModule.P
27+
public struct X: @unsafe P {
28+
// CHECK: #if compiler(>=5.3) && $AllowUnsafeAttribute
29+
// CHECK: @unsafe public func f()
30+
// CHECK: #else
31+
// CHECK: public func f()
32+
// CHECK: #endif
33+
@unsafe public func f() { }
34+
}

0 commit comments

Comments
 (0)