Begin to implement type system layer of unsafe binders
Mostly TODOs, but there's a lot of match arms that are basically just noops so I wanted to split these out before I put up the MIR lowering/projection part of this logic.
r? oli-obk
Tracking:
- https://github.com/rust-lang/rust/issues/130516
cleanup `TypeVerifier`
We should merge it with the `TypeChecker` as we no longer bail in cases where it encounters an error since #111863.
It's quite inconsistent whether a check lives in the verifier or the `TypeChecker`, so this feels like a quite impactful cleanup. I expect that for this we may want to change the `TypeChecker` to also be a MIR visitor 🤔 this is non-trivial so I didn't fully do it in this PR.
Best reviewed commit by commit.
r? `@compiler-errors` feel free to reassign however
coroutine_clone: add comments
I was very surprised to learn that coroutines can be cloned. This has non-trivial semantic consequences that I do not think have been considered. Lucky enough, it's still unstable. Let's add some comments and pointers so we hopefully become aware when a MIR opt actually is in conflict with this.
Cc `@rust-lang/wg-mir-opt`
Foundations of location-sensitive polonius
I'd like to land the prototype I'm describing in the [polonius project goal](https://github.com/rust-lang/rust-project-goals/issues/118). It still is incomplete and naive and terrible but it's working "well enough" to consider landing.
I'd also like to make review easier by not opening a huge PR, but have a couple small-ish ones (the +/- line change summary of this PR looks big, but >80% is moving datalog to a single place).
This PR starts laying the foundation for that work:
- it refactors and collects 99% of the old datalog fact gen, which was spread around everywhere, into a single dedicated module. It's still present at 3 small places (one of which we should revert anyways) that are kinda deep within localized components and are not as easily extractable into the rest of fact gen, so it's fine for now.
- starts introducing the localized constraints, the building blocks of the naive way of implementing the location-sensitive analysis in-tree, which is roughly sketched out in https://smallcultfollowing.com/babysteps/blog/2023/09/22/polonius-part-1/ and https://smallcultfollowing.com/babysteps/blog/2023/09/29/polonius-part-2/ but with a different vibe than per-point environments described in these posts, just `r1@p: r2@q` constraints.
- sets up the skeleton of generating these localized constraints: converting NLL typeck constraints, and creating liveness constraints
- introduces the polonius dual to NLL MIR to help development and debugging. It doesn't do much currently but is a way to see these localized constraints: it's an NLL MIR dump + a dumb listing of the constraints, that can be dumped with `-Zdump-mir=polonius -Zpolonius=next`. Its current state is not intended to be a long-term thing, just for testing purposes -- I will replace its contents in the future with a different approach (an HTML+js file where we can more easily explore/filter/trace these constraints and loan reachability, have mermaid graphs of the usual graphviz dumps, etc).
I've started documenting the approach in this PR, I'll add more in the future. It's quite simple, and should be very clear when more constraints are introduced anyways.
r? `@matthewjasper`
Best reviewed per commit so that the datalog move is less bothersome to read, but if you'd prefer we separate that into a different PR, I can do that (and michael has offered to review these more mechanical changes if it'd help).
handle member constraints directly in the mir type checker
cleaner, faster, easier to change going forward :> fixes#109654
r? `@oli-obk` `@compiler-errors`
unimplement `PointerLike` for trait objects
Values of type `dyn* PointerLike` or `dyn PointerLike` are not pointer-like so these types should not implement `PointerLike`.
After https://github.com/rust-lang/rust/pull/133226, `PointerLike` allows user implementations, so we can't just mark it with `#[rustc_deny_explicit_impl(implement_via_object = false)]`. Instead, this PR splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute into two separate attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]` so that we opt out of the automatic `impl PointerLike for dyn PointerLike` and still allow user implementations.
For traits that are marked with `#[do_not_implement_via_object]` but not `#[rustc_deny_explicit_impl]` I've also made it possible to add a manual `impl Trait for dyn Trait`. There is no immediate need for this, but it was one line to implement and seems nice to have.
fixes https://github.com/rust-lang/rust/issues/134545
fixes https://github.com/rust-lang/rust/issues/134543
r? `@compiler-errors`
This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute
into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`.
This allows us to have special traits that can have user-defined impls but do not have the
automatic trait impl for trait objects (`impl Trait for dyn Trait`).
Improve dependency_format a bit
* Make `DependencyList` an `IndexVec` rather than emulating one using a `Vec` (which was off-by-one as LOCAL_CRATE was intentionally skipped)
* Update some comments for the fact that we now use `#[global_allocator]` rather than `extern crate alloc_system;`/`extern crate alloc_jemalloc;` for specifying which allocator to use. We still use a similar mechanism for the panic runtime, so refer to the panic runtime in those comments instead.
* An unrelated refactor to `create_and_enter_global_ctxt` I forgot to include in https://github.com/rust-lang/rust/pull/134302. This refactor is too small to be worth it's own PR.
coverage: Store coverage source regions as `Span` until codegen (take 2)
This is an attempt to re-land #133418:
> Historically, coverage spans were converted into line/column coordinates during the MIR instrumentation pass.
> This PR moves that conversion step into codegen, so that coverage spans spend most of their time stored as Span instead.
> In addition to being conceptually nicer, this also reduces the size of coverage mappings in MIR, because Span is smaller than 4x u32.
That PR was reverted by #133608, because in some circumstances not covered by our test suite we were emitting coverage metadata that was causing `llvm-cov` to exit with an error (#133606).
---
The implementation here is *mostly* the same, but adapted for subsequent changes in the relevant code (e.g. #134163).
I believe that the changes in #134163 should be sufficient to prevent the problem that required the original PR to be reverted. But I haven't been able to reproduce the original breakage in a regression test, and the `llvm-cov` error message is extremely unhelpful, so I can't completely rule out the possibility of this breaking again.
r? jieyouxu (reviewer of the original PR)
Some destructor/drop related tweaks
Two random tweaks I got from investigating some stuff around drops in edition 2024:
1. Use the `TypingEnv` of the mir builder, rather than making it over again.
2. Rename the `id` field from `Scope` to `local_id`, to reflect that it's a local id, and remove the `item_local_id()` accessor which just returned the id field.
Variants::Single: do not use invalid VariantIdx for uninhabited enums
~~Stacked on top of https://github.com/rust-lang/rust/pull/133681, only the last commit is new.~~
Currently, `Variants::Single` for an empty enum contains a `VariantIdx` of 0; looking that up in the enum variant list will ICE. That's quite confusing. So let's fix that by adding a new `Variants::Empty` case for types that have 0 variants.
try-job: i686-msvc
cleanup region handling: add `LateParamRegionKind`
The second commit is to enable a split between `BoundRegionKind` and `LateParamRegionKind`, by avoiding `BoundRegionKind` where it isn't necessary.
The third comment then adds `LateParamRegionKind` to avoid having the same late-param region for separate bound regions. This fixes#124021.
r? `@compiler-errors`
-Znext-solver: modify candidate preference rules
This implements the design proposed in the FCP in #132325 and matches the old solver behavior. I hope the inline comments are all sufficiently clear, I personally think this is a fairly clear improvement over the existing approach using `fn discard_impls_shadowed_by_env`. This fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/96.
This also fixes#133639 which encounters an ICE in negative coherence when evaluating the where-clause. Given the features required to trigger this ICE 🤷
r? ``@compiler-errors``
Clarify the match ergonomics 2024 migration lint's output
This makes a few changes:
- Rather than using the whole pattern as a span for the lint, this collects spans for each problematic default binding mode reset and labels them with why they're problems.
- The lint's suggestions are now verbose-styled, so that it's clear what's being suggested vs. what's problematic.
- The wording is now less technical, and the hard error version of this diagnostic now links to the same reference material as the lint (currently an unwritten page of the edition guide).
I'm not totally confident in the wording or formatting, so I'd appreciate feedback on that in particular. I tried to draw a connection with word choice between the labels and the suggestion, but it might be imprecise, unclear, or cluttered. If so, it might be worth making the labels more terse and adding notes that explain them, but that's harder to read in a way too.
cc ```@Nadrieril``` ```@Jules-Bertholet```
Closes#133854. For reference, the error from that issue becomes:
```
error: pattern uses features incompatible with edition 2024
--> $DIR/remove-me.rs:6:25
|
LL | map.iter().filter(|(&(_x, _y), &_c)| false);
| ^ ^ cannot implicitly match against multiple layers of reference
| |
| cannot implicitly match against multiple layers of reference
|
help: make the implied reference pattern explicit
|
LL | map.iter().filter(|&(&(_x, _y), &_c)| false);
| +
```
Re-export more `rustc_span::symbol` things from `rustc_span`.
`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 to `rustc_span::`. This is a 300+ net line of code reduction, mostly because many files with two `use rustc_span` items can be reduced to one.
r? `@jieyouxu`
`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.
Split up attribute parsing code and move data types to `rustc_attr_data_structures`
This change renames `rustc_attr` to `rustc_attr_parsing`, and splits up the parsing code. At the same time, all the data types used move to `rustc_attr_data_structures`. This is in preparation of also having a third crate: `rustc_attr_validation`
I initially envisioned this as two separate PRs, but I think doing it in one go reduces the number of ways others would have to rebase their changes on this. However, I can still split them.
r? `@oli-obk` (we already discussed how this is a first step in a larger plan)
For a more detailed plan on how attributes are going to change, see https://github.com/rust-lang/rust/issues/131229
Edit: this looks like a giant PR, but the changes are actually rather trivial. Each commit is reviewable on its own, and mostly moves code around. No new logic is added.
Remove queries from the driver interface
All uses of driver queries in the public api of rustc_driver have been removed in https://github.com/rust-lang/rust/pull/134130 already. This removes driver queries from rustc_interface and does a couple of cleanups around TyCtxt construction and entering enabled by this removal.
Finishes the removal of driver queries started with https://github.com/rust-lang/rust/pull/126834.
Add some convenience helper methods on `hir::Safety`
Makes a lot of call sites simpler and should make any refactorings needed for https://github.com/rust-lang/rust/pull/134090#issuecomment-2541332415 simpler, as fewer sites have to be touched in case we end up storing some information in the variants of `hir::Safety`
Rollup of 7 pull requests
Successful merges:
- #132939 (Suggest using deref in patterns)
- #133293 (Updates Solaris target information, adds Solaris maintainer)
- #133392 (Fix ICE when multiple supertrait substitutions need assoc but only one is provided)
- #133986 (Add documentation for anonymous pipe module)
- #134022 (Doc: Extend for tuples to be stabilized in 1.85.0)
- #134259 (Clean up `infer_return_ty_for_fn_sig`)
- #134264 (Arbitrary self types v2: Weak & NonNull diagnostics)
r? `@ghost`
`@rustbot` modify labels: rollup
Suggest using deref in patterns
Fixes#132784
This changes the following code:
```rs
use std::sync::Arc;
fn main() {
let mut x = Arc::new(Some(1));
match x {
Some(_) => {}
None => {}
}
}
```
to output
```rs
error[E0308]: mismatched types
--> src/main.rs:5:9
|
LL | match x {
| - this expression has type `Arc<Option<{integer}>>`
...
LL | Some(_) => {}
| ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
|
= note: expected struct `Arc<Option<{integer}>>`
found enum `Option<_>`
help: consider dereferencing to access the inner value using the Deref trait
|
LL | match *x {
| ~~
```
instead of
```rs
error[E0308]: mismatched types
--> src/main.rs:5:9
|
4 | match x {
| - this expression has type `Arc<Option<{integer}>>`
5 | Some(_) => {}
| ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
|
= note: expected struct `Arc<Option<{integer}>>`
found enum `Option<_>`
```
This makes it more obvious that a Deref is available, and gives a suggestion on how to use it in order to fix the issue at hand.
Bounds-check with PtrMetadata instead of Len in MIR
Rather than emitting `Len(*_n)` in array index bounds checks, emit `PtrMetadata(copy _n)` instead -- with some asterisks for arrays and `&mut` that need it to be done slightly differently.
We're getting pretty close to removing `Len` entirely, actually. I think just one more PR after this (for slice drop shims).
r? mir
(Re-)Implement `impl_trait_in_bindings`
This reimplements the `impl_trait_in_bindings` feature for local bindings.
"`impl Trait` in bindings" serve as a form of *trait* ascription, where the type basically functions as an infer var but additionally registering the `impl Trait`'s trait bounds for the infer type. These trait bounds can be used to enforce that predicates hold, and can guide inference (e.g. for closure signature inference):
```rust
let _: impl Fn(&u8) -> &u8 = |x| x;
```
They are implemented as an additional set of bounds that are registered when the type is lowered during typeck, and then these bounds are tied to a given `CanonicalUserTypeAscription` for borrowck. We enforce these `CanonicalUserTypeAscription` bounds during borrowck to make sure that the `impl Trait` types are sensitive to lifetimes:
```rust
trait Static: 'static {}
impl<T> Static for T where T: 'static {}
let local = 1;
let x: impl Static = &local;
//~^ ERROR `local` does not live long enough
```
r? oli-obk
cc #63065
---
Why can't we just use TAIT inference or something? Well, TAITs in bodies have the problem that they cannot reference lifetimes local to a body. For example:
```rust
type TAIT = impl Display;
let local = 0;
let x: TAIT = &local;
//~^ ERROR `local` does not live long enough
```
That's because TAITs requires us to do *opaque type inference* which is pretty strict, since we need to remap all of the lifetimes of the hidden type to universal regions. This is simply not possible here.
---
I consider this part of the "impl trait everywhere" experiment. I'm not certain if this needs yet another lang team experiment.
Rollup of 8 pull requests
Successful merges:
- #134252 (Fix `Path::is_absolute` on Hermit)
- #134254 (Fix building `std` for Hermit after `c_char` change)
- #134255 (Update includes in `/library/core/src/error.rs`.)
- #134261 (Document the symbol Visibility enum)
- #134262 (Arbitrary self types v2: adjust diagnostic.)
- #134265 (Rename `ty_def_id` so people will stop using it by accident)
- #134271 (Arbitrary self types v2: better feature gate test)
- #134274 (Add check-pass test for `&raw`)
r? `@ghost`
`@rustbot` modify labels: rollup