The projection may contain inference variables. These inference
variables are local to the local inference context. Using
`tcx.normalize_erasing_regions` doesn't work here because this method is
global and does not have access to the inference context. It's therefore
unable to deal with the inference variables. We normalize in the local
inference context instead, which knowns about the inference variables.
Show note for type ascription on a local binding interpreted as a constant pattern and not a new variable
Given the code
```rust
pub fn main() {
const y: i32 = 4;
let y: i32 = 3;
}
```
`y` in the let binding is actually interpreted as a constant pattern and is not a new variable, causing confusing diagnostics about refutable patterns in local binding.
This PR extends the note for type ascription of a constant pattern to `AscribeUserType` patterns which have `Constant` subpatterns.
Fixes#112269.
- Switch TypeId to 128 bits
- Hack around the fact that tracing-subscriber dislikes how TypeId is hashed
- Remove lowering of type_id128 from rustc_codegen_llvm
- Remove unnecessary `type_id128` intrinsic (just change return type of `type_id`)
- Only hash the lower 64 bits of the TypeId
- Reword comment
Given the code
```rust
pub fn main() {
const y: i32 = 4;
let y: i32 = 3;
}
```
`y` in the let binding is actually interpreted as a constant pattern
and is not a new variable, causing confusing diagnostics about
refutable patterns in local binding.
This commit extends the note for type ascription as a constant pattern
to `AscribeUserType` patterns as well.
The type inference of argument-position closures and async blocks
regressed in 1.70 as the evaluation order of async blocks changed, as
they are not implicitly wrapped in an identity-function anymore.
Fixes#112225 by making sure the evaluation order stays the same as it
used to.
Only check inlining counter after recursing.
This PR aims to reduce the strength of https://github.com/rust-lang/rust/pull/105119 even more.
In the current implementation, we check the inline count before recursing. This means that we never actually reach inlining depth 3.
This PR checks the counter after recursion, to give a chance to inline at depth >= 3.
r? `@scottmcm`
cc `@JakobDegen`
only suppress coercion error if type is definitely unsized
we previously suppressed coercion errors when the return type was `dyn Trait` because we expect a far more descriptive `Sized` trait error to be emitted instead, however the code that does this suppression does not consider where-clause predicates since it just looked at the HIR. let's do that instead by creating an obligation and checking if it may hold.
fixes#110683fixes#112208
suggest `Option::as_deref(_mut)` on type mismatch in option combinator if it passes typeck
Fixes#106342.
This adds a suggestion to call `.as_deref()` (or `.as_deref_mut()` resp.) if typeck fails due to a type mismatch in the function passed to an `Option` combinator such as `.map()` or `.and_then()`.
For example:
```rs
fn foo(_: &str) {}
Some(String::new()).map(foo);
```
The `.map()` method requires its argument to satisfy `F: FnOnce(String)`, but it received `fn(&str)`, which won't pass. However, placing a `.as_deref()` before the `.map()` call fixes this since `&str == &<String as Deref>::Target`
Don't use `can_eq` in `derive(..)` suggestion for missing method
Unsatisfied predicates returned from method probe may reference inference vars from that probe, so drop this extra check I added in #110877 for more accurate derive suggestions...
Fixes#111500
Update dependencies with reported vulnerabilities
Vulnerable dependencies:
* bumpalo 3.12.1 (yanked)
* updated to 3.13.0
* tokio 1.8.4 - https://rustsec.org/advisories/RUSTSEC-2023-0001
* updated to 1.28.2
* remove_dir_all 0.5.3 - https://rustsec.org/advisories/RUSTSEC-2023-0018
* removed by using the standard library function in `rust-installer` instead and updating to `tempfile@3.5.0` (which also removes the dependency).
The new dependencies come from `tempfile@3.5.0` which adds the dependency on `rustix`
Normalize anon consts in new solver
We don't do any of that `expand_abstract_consts` stuff so this isn't sufficient to make GCE work, but it does allow, e.g. `[(); 1]: Default`, to solve.
r? `@BoxyUwU`
use c literals in compiler and library
Use c literals #108801 in compiler and library
currently blocked on:
* <strike>rustfmt: don't know how to format c literals</strike> nope, nightly one works.
* <strike>bootstrap</strike>
r? `@ghost`
`@rustbot` blocked
Support 128-bit atomics on all x86_64 Apple targets
On x86_64, we currently set `max_atomic_width` to 128 only on macOS.
ad8304a0d5/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs (L8)
However, other x86_64 Apple targets (iOS, tvOS, and watchOS) are also core2+ and support cmpxchg16b.
ad8304a0d5/compiler/rustc_target/src/spec/apple_base.rs (L71-L76)
```console
# Script to get targets that support cmpxchg16b by default:
$ (for target in $(rustc --print target-list); do [[ $target == "x86_64"* ]] && rustc --print cfg --target "$target" | grep -q cmpxchg16b && echo "$target"; done)
x86_64-apple-darwin
x86_64-apple-ios
x86_64-apple-ios-macabi
x86_64-apple-tvos
x86_64-apple-watchos-sim
x86_64h-apple-darwin
```
r? `@Amanieu`
Require that const param tys implement `ConstParamTy`
1. Require that const param tys implement `ConstParamTy` instead of using `search_for_adt_const_param_violation`
2. Add `StructuralPartialEq` as a supertrait for `ConstParamTy`, since we need to make sure that we derive *both* `PartialEq` and `Eq`
3. Implement `ConstParamTy` for tuples up to 12 (or whatever the default for tuples is)
4. Add some custom diagnostics to `ConstParamTy` errors, to avoid regressions from (1.). It's still not as great as it could be -- will point out inline in comments.
r? `@BoxyUwU`
Use translatable diagnostics in `rustc_const_eval`
This PR:
* adds a `no_span` parameter to `note` / `help` attributes when using `Subdiagnostic` to allow adding notes/helps without using a span
* has minor tweaks and changes to error messages
I found this confusing because it includes the root item, plus the
inlined items reachable from the root item. The new formulation
separates the two parts more clearly.
Currently it overwrites all the CGUs with new CGUs. But those new CGUs
are just copies of the old CGUs, possibly with some things added. This
commit changes things so that each CGU just gets added to in place,
which makes things simpler and clearer.
It currently uses ranges, which index into `UsageMap::used_items`. This
commit changes it to just use `Vec`, which is much simpler to construct
and use. This change does result in more allocations, but it is few
enough that the perf impact is negligible.
`UsageMap` contains `used_map`, which maps from an item to the item it
uses. This commit add `user_map`, which is the inverse.
We already compute this inverse, but later on, and it is only held as a
local variable. Its simpler and nicer to put it next to `used_map`.
Currently, the code uses multiple words to describe when a mono item `f`
uses a mono item `g`, all of which have problems.
- `f` references `g`: confusing because there are multiple kinds of use,
e.g. "`f` calls `g`" is one, but "`f` takes a (`&T`-style) reference
of `g`" is another, and that's two subtly different meanings of
"reference" in play.
- `f` accesses `g`: meh, "accesses" makes me think of data, and this is
code.
- `g` is a neighbor (or neighbour) of `f`: is verbose, and doesn't
capture the directionality.
This commit changes the code to use "`f` uses `g`" everywhere. I think
it's better than the current terminology, and the consistency is
important.
Also, `InliningMap` is renamed `UsageMap` because (a) it was always
mostly about usage, and (b) the inlining information it did record was
removed in a recent commit.
Extra context for unreachable_pub lint
While experienced Rustaceans no doubt know this sort of thing already, as more of a newbie I had trouble understanding why I was triggering the lint. Hopefully this expanded explanation saves someone else some head-scratching.
Fixes#110922
`#[cfg]`s are frequently used to gate crate content behind cargo
features. This can lead to very confusing errors when features are
missing. For example, `serde` doesn't have the `derive` feature by
default. Therefore, `serde::Serialize` fails to resolve with a generic
error, even though the macro is present in the docs.
This commit adds a list of all stripped item names to metadata. This is
filled during macro expansion and then, through a fed query, persisted
in metadata. The downstream resolver can then access the metadata to
look at possible candidates for mentioning in the errors.
This slightly increases metadata (800k->809k for the feature-heavy
windows crate), but not enough to really matter.
Enable ConstGoto and SeparateConstSwitch passes by default
These 2 passes implement a limited form of jump-threading.
Filing this PR to see if enabling them would be lighter than https://github.com/rust-lang/rust/pull/107009.
Enable ScalarReplacementOfAggregates in optimized builds
Like MatchBranchSimplification, this pass is known to produce significant runtime improvements in Cranelift artifacts, and I believe based on the perf runs here that the primary effect of this pass is to empower MatchBranchSimplification. ScalarReplacementOfAggregates on its own has little effect on anything, but when this was rebased up to include https://github.com/rust-lang/rust/pull/112001 we started seeing significant and majority-positive results.
Based on the fact that we see most of the regressions in debug builds (https://github.com/rust-lang/rust/pull/112002#issuecomment-1566270144) and some rather significant ones in cycles and wall time, I'm only enabling this in optimized builds at the moment.
Don't compute inlining status of mono items in advance.
We record inlining status for mono items in `MonoItems`, and then transfer it to `InliningMap`, for later use in
`InliningMap::with_inlining_candidates`.
But we can just compute inlining status directly in `InliningMap::with_inlining_candidates`, because the mono item is right there. There's no need to compute it in advance.
This commit changes the code to do that, removing the need for `MonoItems` and `InliningMap::inlines`. This does result in more calls to `instantiation_mode` (one per static occurrence) but the performance effect is negligible.
r? ``@wesleywiser``
Preserve substs in opaques recorded in typeck results
This means that we now prepopulate MIR with opaques with the right substs.
The first commit is a hack that I think we discussed, having to do with `DefiningAnchor::Bubble` basically being equivalent to `DefiningAnchor::Error` in the new solver, so having to use `DefiningAnchor::Bind` instead, lol.
r? `@lcnr`
Add a distinct `OperandValue::ZeroSized` variant for ZSTs
These tend to have special handling in a bunch of places anyway, so the variant helps remember that. And I think it's easier to grok than `Aggregate`s sometimes being `Immediates` (after all, I previously got that wrong and caused #109992). As a minor bonus, it means we don't need to generate poison LLVM values for ZSTs to pass around in `OperandValue::Immediate`s.
Inspired by https://github.com/rust-lang/rust/pull/110021#discussion_r1160486991, so
r? `@compiler-errors`
Replace const eval limit by a lint and add an exponential backoff warning
The lint triggers at the first power of 2 that comes after 1 million function calls or traversed back-edges (takes less than a second on usual programs). After the first emission, an unsilenceable warning is repeated at every following power of 2 terminators, causing it to get reported less and less the longer the evaluation runs.
cc `@rust-lang/wg-const-eval`
fixes#93481closes#67217
These tend to have special handling in a bunch of places anyway, so the variant helps remember that. And I think it's easier to grok than non-Scalar Aggregates sometimes being `Immediates` (like I got wrong and caused 109992). As a minor bonus, it means we don't need to generate poison LLVM values for them to pass around in `OperandValue::Immediate`s.
Uplift `clippy::cast_ref_to_mut` lint
This PR aims at uplifting the `clippy::cast_ref_to_mut` lint into rustc.
## `cast_ref_to_mut`
(deny-by-default)
The `cast_ref_to_mut` lint checks for casts of `&T` to `&mut T` without using interior mutability.
### Example
```rust,compile_fail
fn x(r: &i32) {
unsafe {
*(r as *const i32 as *mut i32) += 1;
}
}
```
### Explanation
Casting `&T` to `&mut T` without interior mutability is undefined behavior, as it's a violation of Rust reference aliasing requirements.
-----
Mostly followed the instructions for uplifting a clippy lint described here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751
`@rustbot` label: +I-lang-nominated
r? compiler
-----
For Clippy:
changelog: Moves: Uplifted `clippy::cast_ref_to_mut` into rustc
linker: Report linker flavors incompatible with the current target
The linker flavor is checked for target compatibility even if linker is never used (e.g. we are producing a rlib).
If it causes trouble, we can move the check to `link.rs` so it will run if the linker (flavor) is actually used.
And also feature gate explicitly specifying linker flavors for tier 3 targets.
The next step is supporting all the internal linker flavors in user-visible interfaces (command line and json).
Only rewrite valtree-constants to patterns and keep other constants opaque
Now that we can reliably fall back to comparing constants with `PartialEq::eq` to the match scrutinee, we can
1. eagerly try to convert constants to valtrees
2. then deeply convert the valtree to a pattern
3. if the to-valtree conversion failed, create an "opaque constant" pattern.
This PR specifically avoids any behavioral changes or major cleanups. What we can now do as follow ups is
* move the two remaining call sites to `destructure_mir_constant` off that query
* make valtree to pattern conversion infallible
* this needs to be done after careful analysis of the effects. There may be user visible changes from that.
based on https://github.com/rust-lang/rust/pull/111768
We record inlining status for mono items in `MonoItems`, and then
transfer it to `InliningMap`, for later use in
`InliningMap::with_inlining_candidates`.
But we can just compute inlining status directly in
`InliningMap::with_inlining_candidates`, because the mono item is right
there. There's no need to compute it in advance.
This commit changes the code to do that, removing the need for
`MonoItems` and `InliningMap::inlines`. This does result in more calls
to `instantiation_mode` (one per static occurrence) but the performance
effect is negligible.
Rollup of 5 pull requests
Successful merges:
- #111772 (Fix linkage for large binaries on mips64 platforms)
- #111975 (Stop normalizing so many different prefixes)
- #111979 (Respect CARGOFLAGS in bootstrap.py)
- #112089 (Add `--warnings warn` flag to `x.py`)
- #112103 (Bootstrap update to 1.71 beta)
r? `@ghost`
`@rustbot` modify labels: rollup
Stop normalizing so many different prefixes
Previously, we would normalize *all* of
- the absolute path to the repository checkout
- the /rustc/$sha for stage1 (if `remap-debuginfo` was enabled)
- the /rustc/$sha for download-rustc
- the sysroot for download-rustc
Now, we consistently only normalize /rustc/FAKE_PREFIX. Not only is this much simpler, but it also avoids ongoing maintenance for download-rustc and makes it much less likely that tests break by accident.
- Change `tests/ui/track-diagnostics/track6.rs` to use a relative path instead of an absolute one. I am not actually sure why `track_caller` works here, but it does seem to work 🤷
- Pass `-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX` to all suites, not just UI. In particular, mir-opt tests emit /rustc/ paths in their output.
r? ```@cjgillot``` since you reviewed https://github.com/rust-lang/rust/pull/110699 - this is the test that it doesn't regress :)
Fix linkage for large binaries on mips64 platforms
This pull request fixes the linkage for large binaries on mips64 platforms by enabling the `xgot` feature in LLVM.
It is well understood that the generated binary will gain a hefty performance penalty where the external symbol jumps now cost at least three instructions each.
Also, this pull request does not address the same issue on the mips32 counterparts (due to being unable to test the changes thoroughly).
Should fix#52108
move `super_relate_consts` hack to `normalize_param_env_or_error`
`super_relate_consts` has as hack in it to work around the fact that `normalize_param_env_or_error` is broken. When relating two constants we attempt to evaluate them (aka normalize them). This is not an issue in any way specific to const generics, type aliases also have the same issue as demonstrated in [this code](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=84b6d3956a2c852a04b60782476b56c9).
Since the hack in `super_relate_consts` only exists to make `normalize_param_env_or_error` emit less errors move it to `normalize_param_env_or_error`. This makes `super_relate_consts` act more like the normal plain structural equality its supposed to and should help ensure that the hack doesnt accidentally affect other situations.
r? `@compiler-errors`
offset_of: don't require type to be `Sized`
Fixes#112051
~~The RFC [explicitly forbids](https://rust-lang.github.io/rfcs/3308-offset_of.html#limitations) non-`Sized` types, but it looks like only the fields being recursed into were checked. The sized check also seemed to have been completely missing for tuples~~
Remove `-Zcgu-partitioning-strategy`.
This option was introduced three years ago, but it's never been meaningfully used, and `default` is the only acceptable value.
Also, I think the `Partition` trait presents an interface that is too closely tied to the existing strategy and would probably be wrong for other strategies. (My rule of thumb is to not make something generic until there are at least two instances of it, to avoid this kind of problem.)
Also, I don't think providing multiple partitioning strategies to the user is a good idea, because the compiler already has enough obscure knobs.
This commit removes the option, along with the `Partition` trait, and the `Partitioner` and `DefaultPartitioning` types. I left the existing code in `compiler/rustc_monomorphize/src/partitioning/default.rs`, though I could be persuaded that moving it into
`compiler/rustc_monomorphize/src/partitioning/mod.rs` is better.
r? ``@wesleywiser``
change `BorrowKind::Unique` to be a mutating `PlaceContext`
fixes#112056
I believe that `BorrowKind::Unique` is a footgun in general, so I added a FIXME and opened https://github.com/rust-lang/rust/issues/112072. This is a bit too involved for this PR though.
refactor and cleanup the leak check, add it to new solver
ended up being a bit more involved than I wanted but is hopefully still easy enough to review as a single PR, can split it into separate ones otherwise.
this can be reviewed commit by commit:
a473d55cdb9284aa2b01282d1b529a2a4d26547b 31a686646534ca006d906ec757ece4e771d6f973 949039c107852a5e36361c08b62821a0613656f5 242917bf5170d9a723c6c8e23e9d9d0c2fa8dc9d ed2b25a7aa28be3184be9e3022c2796a30eaad87 are all pretty straightforward.
03dd83b4c3f4ff27558f5c8ab859bd9f83db1d04 makes it easier to refactor coherence in a later commit, see the commit description, cc `@oli-obk`
4fe311d807a77b6270f384e41689bf5d58f46aec I don't quite remember what we wanted to test here, this definitely doesn't test that the occurs check doesn't cause incorrect errors in coherence, also cc `@oli-obk` here. I may end up writing a new test for this myself later.
5c200d88a91b75bd0875b973150655bd581ef97a is the main refactor of the leak check, changing it to take the `outer_universe` instead of getting it from a snapshot. Using a snapshot requires us to be in a probe which we aren't in the new solver, it also just feels dirty as snapshots don't really have anything to do with universes.
with all of this cfc230d54188d9c7ed867a9a0d1f51be77b485f9 is now kind of trivial.
r? `@nikomatsakis`
Don't typecheck recovered method call from suggestion
Only make the use-dot-operator-to-call-method suggestion, but do not double down and use the recovered type to perform method call typechecking as it will produce confusing diagnostics relevant for the *fixed* code.
### Code Sample
```rust
struct Client;
impl Client {
fn post<T: std::ops::Add>(&self, _: T, _: T) {}
}
fn f() {
let c = Client;
post(c, ());
}
```
### Before This PR
```
error[[E0277]](https://doc.rust-lang.org/stable/error_codes/E0277.html): cannot add `()` to `()`
--> src/lib.rs:9:5
|
9 | post(c, ());
| ^^^^^^^^^^^ no implementation for `() + ()`
|
= help: the trait `Add` is not implemented for `()`
note: required by a bound in `Client::post`
--> src/lib.rs:4:16
|
4 | fn post<T: std::ops::Add>(&self, _: T, _: T) {}
| ^^^^^^^^^^^^^ required by this bound in `Client::post`
error[[E0061]](https://doc.rust-lang.org/stable/error_codes/E0061.html): this function takes 2 arguments but 1 argument was supplied
--> src/lib.rs:9:5
|
9 | post(c, ());
| ^^^^ an argument of type `()` is missing
|
note: method defined here
--> src/lib.rs:4:8
|
4 | fn post<T: std::ops::Add>(&self, _: T, _: T) {}
| ^^^^ ----- ---- ----
help: provide the argument
|
9 | post((), ())(c, ());
| ++++++++
error[[E0425]](https://doc.rust-lang.org/stable/error_codes/E0425.html): cannot find function `post` in this scope
--> src/lib.rs:9:5
|
9 | post(c, ());
| ^^^^ not found in this scope
|
help: use the `.` operator to call the method `post` on `&Client`
|
9 - post(c, ());
9 + c.post(());
|
Some errors have detailed explanations: E0061, E0277, E0425.
For more information about an error, try `rustc --explain E0061`.
```
### After This PR
```
error[E0425]: cannot find function `post` in this scope
--> tests/ui/typeck/issue-106929.rs:9:5
|
9 | post(c, ());
| ^^^^ not found in this scope
|
help: use the `.` operator to call the method `post` on `&Client`
|
9 - post(c, ());
9 + c.post(());
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
```
Fixes#106929.
`EarlyBinder::new` -> `EarlyBinder::bind`
for consistency with `Binder::bind`. it may make sense to also add `EarlyBinder::dummy` in places where we know that no parameters exist, but I left that out of this PR.
r? `@jackh726` `@kylematsuda`
fix: dedup `static_candidates` before report
Fixes https://github.com/rust-lang/rust/issues/103646
`record_static_candidate` had been executed twice, resulting in the presence of two identical `CandidateSource::Trait(Cat)` in static_candidates. This PR aims to deduplication the `static_candidates` list, allowing it to execute `suggest_associated_call_syntax` properly.
Uplift `clippy::invalid_utf8_in_unchecked` lint
This PR aims at uplifting the `clippy::invalid_utf8_in_unchecked` lint into two lints.
## `invalid_from_utf8_unchecked`
(deny-by-default)
The `invalid_from_utf8_unchecked` lint checks for calls to `std::str::from_utf8_unchecked` and `std::str::from_utf8_unchecked_mut` with an invalid UTF-8 literal.
### Example
```rust
unsafe {
std::str::from_utf8_unchecked(b"cl\x82ippy");
}
```
### Explanation
Creating such a `str` would result in undefined behavior as per documentation for `std::str::from_utf8_unchecked` and `std::str::from_utf8_unchecked_mut`.
## `invalid_from_utf8`
(warn-by-default)
The `invalid_from_utf8` lint checks for calls to `std::str::from_utf8` and `std::str::from_utf8_mut` with an invalid UTF-8 literal.
### Example
```rust
std::str::from_utf8(b"ru\x82st");
```
### Explanation
Trying to create such a `str` would always return an error as per documentation for `std::str::from_utf8` and `std::str::from_utf8_mut`.
-----
Mostly followed the instructions for uplifting a clippy lint described here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751
````@rustbot```` label: +I-lang-nominated
r? compiler
-----
For Clippy:
changelog: Moves: Uplifted `clippy::invalid_utf8_in_unchecked` into rustc
we can otherwise assign a hidden type to the opaque which
causes ICE if we don't use `take_opaque_types` during
coherence. This is annoying so I didn't bother. Added a test
showing the behavior this prevents.
Optimize scalar and scalar pair representations loaded from ByRef in llvm
in https://github.com/rust-lang/rust/pull/105653 I noticed that we were generating suboptimal LLVM IR if we had a `ConstValue::ByRef` that could be represented by a `ScalarPair`. Before https://github.com/rust-lang/rust/pull/105653 this is probably rare, but after it, every slice will go down this suboptimal code path that requires LLVM to untangle a bunch of indirections and translate static allocations that are only used once to read a scalar pair from.
Only make the use-dot-operator-to-call-method suggestion, but do not
double down and use the recovered type to perform method call
typechecking as it will produce confusing diagnostics on the "fixed"
code.
This option was introduced three years ago, but it's never been
meaningfully used, and `default` is the only acceptable value.
Also, I think the `Partition` trait presents an interface that is too
closely tied to the existing strategy and would probably be wrong for
other strategies. (My rule of thumb is to not make something generic
until there are at least two instances of it, to avoid this kind of
problem.)
Also, I don't think providing multiple partitioning strategies to the
user is a good idea, because the compiler already has enough obscure
knobs.
This commit removes the option, along with the `Partition` trait, and
the `Partitioner` and `DefaultPartitioning` types. I left the existing
code in `compiler/rustc_monomorphize/src/partitioning/default.rs`,
though I could be persuaded that moving it into
`compiler/rustc_monomorphize/src/partitioning/mod.rs` is better.
Make `TyKind: Debug` have less verbose output
Current `TyKind: Debug` impl is basically unusable for debugging, its too verbose even for verbose debugging 🤣 This PR replaces the debug logic for `TyKind` with a more manual debug impl instead of a hand expanded derived impl. This should help make #107084 more reasonable to land since the output of `Ty: Debug` will be better.
This isn't a fully completed change to the `Debug` impl of `TyKind` as there's still logic from the derive macro for some variants. Some of the variants are also not consisten with the `-Zverbose` printing of `Ty`, ideally `-Zverbose` printing of `Ty` would also just defer to the debug impl instead of having lots of checks in pretty printing. I plan on fixing this in follow up PRs since it seems tricky to do in this one and its already a large PR 😅