Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce strongly-typed strings, starting with TargetTriple
As discussed, for the price of having to think about `TargetTriple` (like `String`) vs `&TargetTripleRef` (like `&str`), we get: * No accidentally passing some other kind of string to a thing expecting a `TargetTriple` * Serialization/deserialization is still transparent, no schema changes or anything * We can add methods to it (like `is_windows()` in this PR - note that I dream of a `ParsedTargetTriple` in a separate PR) * Those methods are the only place where we check properties of the string (before this commit, we have `.contains("windows")` and `.contains("pc-windows")` for example) * We can "find all references" to the type itself ("where do we care about targets?") * We can "find all references" to `TargetTriple::new` ("where do we build targets from strings?") * We can "find all references" to `TargetTripleRef::as_str` ("where do we coerce it back into a string to pass it to a tool like cargo/wix/etc.) That kind of change is invaluable for me when working on cross-compilation support, and I suspect it will be invaluable for any current and future maintainers of cargo-dist as well (I've used it with great success in other large codebases). You can still treat `TargetTriple` as a string, but it'll be uglier (on purpose). There is however, some ugliness that isn't on purpose. In this changeset I discovered some annoyances around `.iter()` (which returns an `Iterator<Item = &TargetTriple>` instead of an `Iterator<Item = &TargetTripleRef>`. I've added `.as_explicit_ref` to work around those cases. Similarly, calling `Vec<TargetTriple>::contains()` with a `&TargetTripleRef` doesn't work (and you cannot convert a `&TargetTripleRef` into a `&TargetTriple`, the same way you cannot convert a `&str` back into a `&String` - you don't know where it's allocated from!). Finally, I ran into <rust-lang/rfcs#1445> while making this change: there was a big `match` for converting target triples to their display names, and although that works with `&str` constants, it doesn't work with `&TargetTripleRef` constants, due to Rust limitations right now. That explains the lazy_static (which we already depended on transitively, so at least that). I would've used `LazyLock` but our MSRV is currently 1.79 and LazyLock is since 1.80 :(
- Loading branch information