`rustc_span::symbol` defines some things that are re-exported from
`rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some
closely related things such as `Ident` and `kw`. So you can do `use
rustc_span::{Symbol, sym}` but you have to do `use
rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good
reason.
This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`,
and changes many `rustc_span::symbol::` qualifiers in `compiler/` to
`rustc_span::`. This is a 200+ net line of code reduction, mostly
because many files with two `use rustc_span` items can be reduced to
one.
check local cache even if global is usable
we store overflow errors locally, even if we can otherwise use the global cache for this goal. should fix#133616, didn't test it locally yet as diesel tends to hit an unrelated debug assertion in rustdoc.
r? types
Only disable cache if predicate has opaques within it
This is an alternative to https://github.com/rust-lang/rust/pull/132075.
This refines the check implemented in https://github.com/rust-lang/rust/pull/126024 to only disable the global cache if the predicate being considered has opaques in it. This is still theoretically unsound, since goals can indirectly rely on opaques in the defining scope, but we're much less likely to hit it.
It doesn't totally fix https://github.com/rust-lang/rust/issues/132064: for example, `lemmy` goes from 1:29 (on rust 1.81) to 9:53 (on nightly) to 4:07 (after this PR). But I think it's at least *more* sound than a total revert :/
r? lcnr
Allow instantiating object trait binder when upcasting
This PR fixes two bugs (that probably need an FCP).
### We use equality rather than subtyping for upcasting dyn conversions
This code should be valid:
```rust
#![feature(trait_upcasting)]
trait Foo: for<'h> Bar<'h> {}
trait Bar<'a> {}
fn foo(x: &dyn Foo) {
let y: &dyn Bar<'static> = x;
}
```
But instead:
```
error[E0308]: mismatched types
--> src/lib.rs:7:32
|
7 | let y: &dyn Bar<'static> = x;
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'h> Bar<'h>`
found existential trait ref `Bar<'_>`
```
And so should this:
```rust
#![feature(trait_upcasting)]
fn foo(x: &dyn for<'h> Fn(&'h ())) {
let y: &dyn FnOnce(&'static ()) = x;
}
```
But instead:
```
error[E0308]: mismatched types
--> src/lib.rs:4:39
|
4 | let y: &dyn FnOnce(&'static ()) = x;
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'h> FnOnce<(&'h (),)>`
found existential trait ref `FnOnce<(&(),)>`
```
Specifically, both of these fail because we use *equality* when comparing the supertrait to the *target* of the unsize goal. For the first example, since our supertrait is `for<'h> Bar<'h>` but our target is `Bar<'static>`, there's a higher-ranked type mismatch even though we *should* be able to instantiate that supertrait binder when upcasting. Similarly for the second example.
### New solver uses equality rather than subtyping for no-op (i.e. non-upcasting) dyn conversions
This code should be valid in the new solver, like it is with the old solver:
```rust
// -Znext-solver
fn foo<'a>(x: &mut for<'h> dyn Fn(&'h ())) {
let _: &mut dyn Fn(&'a ()) = x;
}
```
But instead:
```
error: lifetime may not live long enough
--> <source>:2:11
|
1 | fn foo<'a>(x: &mut dyn for<'h> Fn(&'h ())) {
| -- lifetime `'a` defined here
2 | let _: &mut dyn Fn(&'a ()) = x;
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
= note: requirement occurs because of a mutable reference to `dyn Fn(&())`
```
Specifically, this fails because we try to coerce `&mut dyn for<'h> Fn(&'h ())` to `&mut dyn Fn(&'a ())`, which registers an `dyn for<'h> Fn(&'h ()): dyn Fn(&'a ())` goal. This fails because the new solver uses *equating* rather than *subtyping* in `Unsize` goals.
This is *mostly* not a problem... You may wonder why the same code passes on the new solver for immutable references:
```
// -Znext-solver
fn foo<'a>(x: &dyn Fn(&())) {
let _: &dyn Fn(&'a ()) = x; // works
}
```
That's because in this case, we first try to coerce via `Unsize`, but due to the leak check the goal fails. Then, later in coercion, we fall back to a simple subtyping operation, which *does* work.
Since `&T` is covariant over `T`, but `&mut T` is invariant, that's where the discrepancy between these two examples crops up.
---
r? lcnr or reassign :D
Shrink `TyKind::FnPtr`.
By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and `FnHeader`, which can be packed more efficiently. This reduces the size of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms. This reduces peak memory usage by a few percent on some benchmarks. It also reduces cache misses and page faults similarly, though this doesn't translate to clear cycles or wall-time improvements on CI.
r? `@compiler-errors`
By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and
`FnHeader`, which can be packed more efficiently. This reduces the size
of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms.
This reduces peak memory usage by a few percent on some benchmarks. It
also reduces cache misses and page faults similarly, though this doesn't
translate to clear cycles or wall-time improvements on CI.