Pitch 2: Add FilePath to stdlib

Summary of changes from the original pitch:

Focused on the essential core. This revision ships the type, its conformances, ComponentView (as BidirectionalCollection & RangeReplaceableCollection), and real filesystem resolve(). Convenience methods (lastComponent, stem, extension, append, push, starts(with:), etc.) are deferred as future work, back-deployable via ComponentView.

Root type removed. Windows paths like C:foo don't decompose cleanly into a root. Replaced by targeted queries: isAbsolute, isRelative, isRooted (new), and driveLetter (new). A formal Prefix type is future work.

Lexical operations deferred. lexicallyNormalize, isLexicallyNormal, and lexicallyResolving are removed. A real func resolve() throws -> FilePath replaces them.

Trailing separators preserved. The original pitch stripped them on construction. This revision preserves them and makes them significant for equality ("/tmp/foo" != "/tmp/foo/"), with API to query and manipulate them.

ComponentView normalization specified. The view coalesces repeated separators, converts / to \ on Windows, and drops interior . components (except on Windows verbatim paths). .. is always presented.

Components are opaque byte bags. No stem or extension on Component. You get a Span of platform bytes.

Platform prefix handling expanded. XNU resolve flags (/.resolve/1/), volume identifiers (/.vol/1234/5678/), and UNC trailing separators are now correctly recognized.

Conformance changes. Comparable added to FilePath, Component, and ComponentView. Codable dropped. Span-based byte access and C interop (withCString/withWCString) added directly.

2 Likes