You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 :(
0 commit comments