Add a filePath property to SourceLocation
February 24, 2026 · View on GitHub
- Proposal: ST-0020
- Authors: Jonathan Grynspan
- Review Manager: Rachel Brindle
- Status: Implemented (Swift 6.3)
- Bug: rdar://152999195
- Implementation: swiftlang/swift-testing#1334, swiftlang/swift-testing#1472
- Review: (pitch) (review) (acceptance)
Introduction
Swift Testing represents the in-source location of tests, issues, errors, etc.
using a structure called SourceLocation.
This structure contains the line, column, and file ID for a given location in a
Swift source file. I propose adding the file path to this structure for use by
developers and tools.
Motivation
When we initially designed Swift Testing and SourceLocation, our expectation
was that tools like Visual Studio Code or Xcode would be able to translate Swift
file IDs to file paths where needed.
At the time, Swift 6 had not yet been introduced and we were working off the
assumption that #filePath would eventually be deprecated (possibly in Swift 6).
This assumption was based on the history behind #fileID:
- SE-0274
originally proposed repurposing
#fileto generate file IDs (and added#filePathfor use cases that still needed full paths.) - SE-0285
modified the plan to leave
#fileas-is in Swift 5 and introduced#fileIDand planned to have#fileequal#fileIDin Swift 6 onward. - In September 2024, the Language Steering Group discussed
#file,#filePath, and#fileID, and decided to maintain the status quo.
Because the future of these magic values (now expression macros) was unclear, we
opted to provide only a fileID property on SourceLocation. SourceLocation
does gather a full file path, but does not expose a public property to access
this value at runtime or later.
It has become clear since we shipped Swift Testing that tools are much better equipped to handle file paths than Swift file IDs, and the translation from a file ID back to the original path on a developer's system may be non-trivial or even impossible (in the case of strict sandboxing around a tool).
Proposed solution
I propose adding a filePath property to SourceLocation and to the JSON event
stream schema.
Detailed design
The following property is added:
extension SourceLocation {
/// The path to the source file.
public var filePath: String { get set }
}
Swift Testing's JSON schema (version "6.3" onward) is updated to add a
"filePath" key to source location values and to make the "fileID" key
optional:
<source-location> ::= {
- "fileID": <string>, ; the Swift file ID of the file
+ ["fileID": <string>,] ; the Swift file ID of the file if available, as per
+ ; SE-0274 § "Specification of the #file string format"
+ "filePath": <string>, ; the compile-time path to the file
"line": <number>,
"column": <number>,
}
The value of the "filePath" key is an absolute file system path. It is not
guaranteed to refer to an existing file (for instance, it may refer to a file on
a build system that isn't present at runtime). The path style used (POSIX,
Windows, or otherwise) is implementation-defined.
If the "fileID" key is not present when Swift Testing decodes an instance of
SourceLocation, it is synthesized from "filePath" and the module name is
assumed to be "__C"1. This change allows Swift Testing to support source
location information generated in other languages like Objective-C or C++. For
example, a test written in Objective-C could construct a <source-location>
JSON value as follows:
id jsonObject = @{
@"line": @(__LINE__),
@"column": @(__builtin_COLUMN()),
@"filePath": @(__file__)
};
And, assuming __file__ equals "/foo/bar/quux.m", Swift Testing would infer a
file ID of "__C/quux.m".
Source compatibility
There are no source compatibility concerns.
Integration with supporting tools
Supporting tools will be able to migrate from the unsupported "_filePath" JSON
key to the new "filePath" key. We will continue to emit "_filePath" where
needed until the ecosystem has moved to "filePath".
Future directions
N/A
Alternatives considered
- None.
Footnotes
-
The Swift compiler and runtime assume a module name of
__Cfor most imported foreign types. ↩