This commit adds basic support for reborrowing `Pin` types in argument
position. At the moment it only supports reborrowing `Pin<&mut T>` as
`Pin<&mut T>` by inserting a call to `Pin::as_mut()`, and only in
argument position (not as the receiver in a method call).
- Replace non-standard names like 's, 'p, 'rg, 'ck, 'parent, 'this, and
'me with vanilla 'a. These are cases where the original name isn't
really any more informative than 'a.
- Replace names like 'cx, 'mir, and 'body with vanilla 'a when the lifetime
applies to multiple fields and so the original lifetime name isn't
really accurate.
- Put 'tcx last in lifetime lists, and 'a before 'b.
Rescope temp lifetime in if-let into IfElse with migration lint
Tracking issue #124085
This PR shortens the temporary lifetime to cover only the pattern matching and consequent branch of a `if let`.
At the expression location, means that the lifetime is shortened from previously the deepest enclosing block or statement in Edition 2021. This warrants an Edition change.
Coming with the Edition change, this patch also implements an edition lint to warn about the change and a safe rewrite suggestion to preserve the 2021 semantics in most cases.
Related to #103108.
Related crater runs: https://github.com/rust-lang/rust/pull/129466.
Simplify some nested `if` statements
Applies some but not all instances of `clippy::collapsible_if`. Some ended up looking worse afterwards, though, so I left those out. Also applies instances of `clippy::collapsible_else_if`
Review with whitespace disabled please.
There are four related dataflow structs: `MaybeInitializedPlaces`,
`MaybeUninitializedPlaces`, and `EverInitializedPlaces`,
`DefinitelyInitializedPlaces`. They all have a `&Body` and a
`&MoveData<'tcx>` field. The first three use different lifetimes for the
two fields, but the last one uses the same lifetime for both.
This commit changes the first three to use the same lifetime, removing
the need for one of the lifetimes. Other structs that also lose a
lifetime as a result of this are `LivenessContext`, `LivenessResults`,
`InitializationData`.
It then does similar things in various other structs.
Make `Ty::boxed_ty` return an `Option`
Looks like a good place to use Rust's type system.
---
Most of 4ac7bcbaad/compiler/rustc_middle/src/ty/sty.rs (L971-L1963) looks like it could be moved to `TyKind` (then I guess `Ty` should be made to deref to `TyKind`).
Check WF of source type's signature on fn pointer cast
This PR patches the implied bounds holes slightly for #129005, #25860.
Like most implied bounds related unsoundness fixes, this isn't complete w.r.t. higher-ranked function signatures, but I believe it implements a pretty good heuristic for now.
### What does this do?
This PR makes a partial patch for a soundness hole in a `FnDef` -> `FnPtr` "reifying" pointer cast where we were never checking that the signature we are casting *from* is actually well-formed. Because of this, and because `FnDef` doesn't require its signature to be well-formed (just its predicates must hold), we are essentially allowed to "cast away" implied bounds that are assumed within the body of the `FnDef`:
```
fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
fn bad<'short, T>(x: &'short T) -> &'static T {
let f: fn(_, &'short T) -> &'static T = foo;
f(&&(), x)
}
```
In this example, subtyping ends up casting the `_` type (which should be `&'static &'short ()`) to some other type that no longer serves as a "witness" to the lifetime relationship `'short: 'static` which would otherwise be required for this call to be WF. This happens regardless of if `foo`'s lifetimes are early- or late-bound.
This PR implements two checks:
1. We check that the signature of the `FnDef` is well-formed *before* casting it. This ensures that there is at least one point in the MIR where we ensure that the `FnDef`'s implied bounds are actually satisfied by the caller.
2. Implements a special case where if we're casting from a higher-ranked `FnDef` to a non-higher-ranked, we instantiate the binder of the `FnDef` with *infer vars* and ensure that it is a supertype of the target of the cast.
The (2.) is necessary to validate that these pointer casts are valid for higher-ranked `FnDef`. Otherwise, the example above would still pass even if `help`'s `'a` lifetime were late-bound.
### Further work
The WF checks for function calls are scattered all over the MIR. We check the WF of args in call terminators, we check the WF of `FnDef` when we create a `const` operand referencing it, and we check the WF of the return type in #115538, to name a few.
One way to make this a bit cleaner is to simply extend #115538 to always check that the signature is WF for `FnDef` types. I may do this as a follow-up, but I wanted to keep this simple since this leads to some pretty bad NLL diagnostics regressions, and AFAICT this solution is *complete enough*.
### Crater triage
Done here: https://github.com/rust-lang/rust/pull/129021#issuecomment-2297702647
r? lcnr
Remove `#[macro_use] extern crate tracing`, round 4
Because explicit importing of macros via use items is nicer (more standard and readable) than implicit importing via #[macro_use]. Continuing the work from #124511, #124914, and #125434. After this PR no `rustc_*` crates use `#[macro_use] extern crate tracing` except for `rustc_codegen_gcc` which is a special case and I will do separately.
r? ```@jieyouxu```
Remove Duplicate E0381 Label
Aims to resolve https://github.com/rust-lang/rust/issues/129274, and adds a test for the case.
Essentially, we are duplicating this span for some reason. For now, I'm just using a set to collect the spans rather than the vec. I imagine there's probably no real reason to inspect duplicates in this area, but if I'm wrong I can adjust to collect "seen spans" in just the point where this label is applied.
I'm not sure why it's producing duplicate spans. Looks like this has been this way for a while? I think it gives the duplicate label on 1.75.0 for example.
Add `#[warn(unreachable_pub)]` to a bunch of compiler crates
By default `unreachable_pub` identifies things that need not be `pub` and tells you to make them `pub(crate)`. But sometimes those things don't need any kind of visibility. So they way I did these was to remove the visibility entirely for each thing the lint identifies, and then add `pub(crate)` back in everywhere the compiler said it was necessary. (Or occasionally `pub(super)` when context suggested that was appropriate.) Tedious, but results in more `pub` removal.
There are plenty more crates to do but this seems like enough for a first PR.
r? `@compiler-errors`
Record the correct target type when coercing fn items/closures to pointers
Self-explanatory. We were previously not recording the *target* type of a coercion as the output of an adjustment. This should remedy that.
We must also modify the function pointer casts in MIR typeck to use subtyping, since those broke since #118247.
r? lcnr
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`
Normalize struct tail properly for `dyn` ptr-to-ptr casting in new solver
Realized that the new solver didn't handle ptr-to-ptr casting correctly.
r? lcnr
Built on #128694
Use more slice patterns inside the compiler
Nothing super noteworthy. Just replacing the common 'fragile' pattern of "length check followed by indexing or unwrap" with slice patterns for legibility and 'robustness'.
r? ghost
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.
Peel off explicit (or implicit) deref before suggesting clone on move error in borrowck, remove some hacks
Also remove a heck of a lot of weird hacks in `suggest_cloning` that I don't think we should have around.
I know this regresses tests, but I don't believe most of these suggestions were accurate, b/c:
1. They either produced type errors (e.g. turning `&x` into `x.clone()`)
2. They don't fix the issue
3. They fix the issue ostensibly, but introduce logic errors (e.g. cloning a `&mut Option<T>` to then `Option::take` out...)
Most of the suggestions are still wrong, but they're not particularly *less* wrong IMO.
Stacked on top of #128241, which is an "obviously worth landing" subset of this PR.
r? estebank
Remove logic to suggest clone of function output
I can't exactly tell, but I believe that this suggestion is operating off of a heuristic that the lifetime of a function's input is correlated with the lifetime of a function's output in such a way that cloning would fix an error. I don't think that actually manages to hit the bar of "actually provides useful suggestions" most of the time.
Specifically, I've hit false-positives due to this suggestion *twice* when fixing ICEs in the compiler, so I don't think it's worthwhile having this logic around. Neither of the two affected UI tests are actually fixed by the suggestion.
Reword E0626 to mention static coroutine, add structured suggestion for adding `static`
Not certain how to make the example feel less artificial. 🤷
My main point though is that we should probably emphasize that the first solution to making a coroutine allow a borrow across an await is making it `static`.
Also adds a structured suggestion.
Invert infer `error_reporting` mod struture
Parallel change to #127493, which moves `rustc_infer::infer::error_reporting` to `rustc_infer::error_reporting::infer`. After this, we should just be able to merge this into `rustc_trait_selection::error_reporting::infer`, and pull down `TypeErrCtxt` into that crate. 👍
r? lcnr
Suggest borrowing on fn argument that is `impl AsRef`
When encountering a move conflict, on an expression that is `!Copy` passed as an argument to an `fn` that is `impl AsRef`, suggest borrowing the expression.
```
error[E0382]: use of moved value: `bar`
--> f204.rs:14:15
|
12 | let bar = Bar;
| --- move occurs because `bar` has type `Bar`, which does not implement the `Copy` trait
13 | foo(bar);
| --- value moved here
14 | let baa = bar;
| ^^^ value used here after move
|
help: borrow the value to avoid moving it
|
13 | foo(&bar);
| +
```
Fix#41708
Consolidate region error reporting in `rustc_infer`
More work on https://github.com/rust-lang/rust/issues/127492. Separate but important step, since I'm gonna likely pull everything else here into another module.
I don't think I'm confident whether `nice_region_error` should be a submodule of the new `rustc_infer::infer::error_reporting::region` module, so I left it alone for now.
r? lcnr
Make casts of pointers to trait objects stricter
This is an attempt to `fix` https://github.com/rust-lang/rust/issues/120222 and https://github.com/rust-lang/rust/issues/120217.
This is done by adding restrictions on casting pointers to trait objects.
Before this PR the rules were as follows:
> When casting `*const X<dyn A>` -> `*const Y<dyn B>`, principal traits in `A` and `B` must refer to the same trait definition (or no trait).
With this PR the rules are changed to
> When casting `*const X<dyn Src>` -> `*const Y<dyn Dst>`
> - if `Dst` has a principal trait `DstP`,
> - `Src` must have a principal trait `SrcP`
> - `dyn SrcP` and `dyn DstP` must be the same type (modulo the trait object lifetime, `dyn T+'a` -> `dyn T+'b` is allowed)
> - Auto traits in `Dst` must be a subset of auto traits in `Src`
> - Not adhering to this is currently a FCW (warn-by-default + `FutureReleaseErrorReportInDeps`), instead of an error
> - if `Src` has a principal trait `Dst` must as well
> - this restriction will be removed in a follow up PR
This ensures that
1. Principal trait's generic arguments match (no `*const dyn Tr<A>` -> `*const dyn Tr<B>` casts, which are a problem for [#120222](https://github.com/rust-lang/rust/issues/120222))
2. Principal trait's lifetime arguments match (no `*const dyn Tr<'a>` -> `*const dyn Tr<'b>` casts, which are a problem for [#120217](https://github.com/rust-lang/rust/issues/120217))
3. No auto traits can be _added_ (this is a problem for arbitrary self types, see [this comment](https://github.com/rust-lang/rust/pull/120248#discussion_r1463835350))
Some notes:
- We only care about the metadata/last field, so you can still cast `*const dyn T` to `*const WithHeader<dyn T>`, etc
- The lifetime of the trait object itself (`dyn A + 'lt`) is not checked, so you can still cast `*mut FnOnce() + '_` to `*mut FnOnce() + 'static`, etc
- This feels fishy, but I couldn't come up with a reason it must be checked
The diagnostics are currently not great, to say the least, but as far as I can tell this correctly fixes the issues.
cc `@oli-obk` `@compiler-errors` `@lcnr`
Support tail calls in mir via `TerminatorKind::TailCall`
This is one of the interesting bits in tail call implementation — MIR support.
This adds a new `TerminatorKind` which represents a tail call:
```rust
TailCall {
func: Operand<'tcx>,
args: Vec<Operand<'tcx>>,
fn_span: Span,
},
```
*Structurally* this is very similar to a normal `Call` but is missing a few fields:
- `destination` — tail calls don't write to destination, instead they pass caller's destination to the callee (such that eventual `return` will write to the caller of the function that used tail call)
- `target` — similarly to `destination` tail calls pass the caller's return address to the callee, so there is nothing to do
- `unwind` — I _think_ this is applicable too, although it's a bit confusing
- `call_source` — `become` forbids operators and is not created as a lowering of something else; tail calls always come from HIR (at least for now)
It might be helpful to read the interpreter implementation to understand what `TailCall` means exactly, although I've tried documenting it too.
-----
There are a few `FIXME`-questions still left, ideally we'd be able to answer them during review ':)
-----
r? `@oli-obk`
cc `@scottmcm` `@DrMeepster` `@JakobDegen`
Rollup of 9 pull requests
Successful merges:
- #123043 (Disable dead variant removal for `#[repr(C)]` enums.)
- #126405 (Migrate some rustc_builtin_macros to SessionDiagnostic)
- #127037 (Remove some duplicated tests)
- #127283 (Reject SmartPointer constructions not serving the purpose)
- #127301 (Tweak some structured suggestions to be more verbose and accurate)
- #127307 (Allow to have different types for arguments of `Rustc::remap_path_prefix`)
- #127309 (jsondocck: add `$FILE` built-in variable)
- #127314 (Trivial update on tidy bless note)
- #127319 (Remove a use of `StructuredDiag`, which is incompatible with automatic error tainting and error translations)
r? `@ghost`
`@rustbot` modify labels: rollup
The rules for casting `*mut X<dyn A>` -> `*mut Y<dyn B>` are as follows:
- If `B` has a principal
- `A` must have exactly the same principal (including generics)
- Auto traits of `B` must be a subset of autotraits in `A`
Note that `X<_>` and `Y<_>` can be identity, or arbitrary structs with last field being the dyn type.
The lifetime of the trait object itself (`dyn ... + 'a`) is not checked.
This prevents a few soundness issues with `#![feature(arbitrary_self_types)]` and trait upcasting.
Namely, these checks make sure that vtable is always valid for the pointee.
Stop using specialization in rustc_index and rustc_borrowck
For rustc_borrowck the version with specialization isn't much more readable anyway IMO. For rustc_index it probably doesn't affect perf in any noticeable way anyway.
Re-implement a type-size based limit
r? lcnr
This PR reintroduces the type length limit added in #37789, which was accidentally made practically useless by the caching changes to `Ty::walk` in #72412, which caused the `walk` function to no longer walk over identical elements.
Hitting this length limit is not fatal unless we are in codegen -- so it shouldn't affect passes like the mir inliner which creates potentially very large types (which we observed, for example, when the new trait solver compiles `itertools` in `--release` mode).
This also increases the type length limit from `1048576 == 2 ** 20` to `2 ** 24`, which covers all of the code that can be reached with craterbot-check. Individual crates can increase the length limit further if desired.
Perf regression is mild and I think we should accept it -- reinstating this limit is important for the new trait solver and to make sure we don't accidentally hit more type-size related regressions in the future.
Fixes#125460
Rewrite handling of universe-leaking placeholder regions into outlives constraints
This commit prepares for Polonius by moving handling of leak check/universe errors out of the inference step by rewriting any universe error into an outlives-static constraint.
This variant is a work in progress but seems to pass most tests.
Note that a few debug assertions no longer hold; a few extra eyes on those changes are appreciated!
This version is a squash-rebased version of a series
of exiermental commits, since large parts of them
were broken out into PR #125069.
It explicitly handles universe violations in higher-kinded
outlives constraints by adding extra outlives static constraints.
Automatically taint InferCtxt when errors are emitted
r? `@nnethercote`
Basically `InferCtxt::dcx` now returns a `DiagCtxt` that refers back to the `Cell<Option<ErrorGuaranteed>>` of the `InferCtxt` and thus when invoking `Diag::emit`, and the diagnostic is an error, we taint the `InferCtxt` directly.
That change on its own has no effect at all, because `InferCtxt` already tracks whether errors have been emitted by recording the global error count when it gets opened, and checking at the end whether the count changed. So I removed that error count check, which had a bit of fallout that I immediately fixed by invoking `InferCtxt::dcx` instead of `TyCtxt::dcx` in a bunch of places.
The remaining new errors are because an error was reported in another query, and never bubbled up. I think they are minor enough for this to be ok, and sometimes it actually improves diagnostics, by not silencing useful diagnostics anymore.
fixes#126485 (cc `@olafes)`
There are more improvements we can do (like tainting in hir ty lowering), but I would rather do that in follow up PRs, because it requires some refactorings.
Do not ICE when suggesting dereferencing closure arg
Account for `for` lifetimes when constructing closure to see if dereferencing the return value would be valid.
Fix#125634, fix#124563.
Remove confusing `use_polonius` flag and do less cloning
The `use_polonius` flag is both redundant and confusing since every function it's propagated to also checks if `all_facts` is `Some`, the true test of whether to generate Polonius facts for Polonius or for external consumers. This PR makes that path clearer by simply doing away with the argument and handling the logic in precisely two places: where facts are populated (check for `Some`), and where `all_facts` are initialised. It also delays some statements until after that check to avoid the miniscule performance penalty of executing them when Polonius is disabled.
This also addresses `@lqd's` concern in #125652 by reducing the size of what is cloned out of Polonius facts to just the facts being added, as opposed to the entire vector of potential inputs, and added descriptive comments.
*Reviewer note*: the comments in `add_extra_drop_facts` should be inspected by a reviewer, in particular the one on [L#259](https://github.com/rust-lang/rust/compare/master...amandasystems:you-dropped-this-again?expand=1#diff-aa727290e6670264df2face84f012897878e11a70e9c8b156543cfcd9619bac3R259) in this PR, which should be trivial for someone with the right background knowledge to address.
I also included some lints I found on the way there that I couldn't help myself from addressing.
Rename `InstanceDef` -> `InstanceKind`
Renames `InstanceDef` to `InstanceKind`. The `Def` here is confusing, and makes it hard to distinguish `Instance` and `InstanceDef`. `InstanceKind` makes this more obvious, since it's really just describing what *kind* of instance we have.
Not sure if this is large enough to warrant a types team MCP -- it's only 53 files. I don't personally think it does, but happy to write one if anyone disagrees. cc ``@rust-lang/types``
r? types
Convert a `span_bug` to a `span_delayed_bug`.
PR #121208 converted this from a `span_delayed_bug` to a `span_bug` because nothing in the test suite caused execution to hit this path. But now fuzzing has found a test case that does hit it. So this commit converts it back to `span_delayed_bug` and adds the relevant test.
Fixes#126385.
r? `@lcnr`
Make suggestion to change `Fn` to `FnMut` work with methods as well
Fixes#125325
The issue occurred because the code that emitted the suggestion to change `Fn` to `FnMut` worked only for function calls and not method calls. This PR makes it work with methods as well.
PR #121208 converted this from a `span_delayed_bug` to a `span_bug`
because nothing in the test suite caused execution to hit this path. But
now fuzzing has found a test case that does hit it. So this commit
converts it back to `span_delayed_bug` and adds the relevant test.
Fixes#126385.
Make uninitialized_error_reported a set of locals
Another artifact of how places used to be able to be based on statics and not just locals. This set is exclusively filled with PlaceRefs that are just locals, so it should just contain locals directly.
smir: merge identical Constant and ConstOperand types
The first commit renames the const operand visitor functions on regular MIR to match the type name, that was forgotten in the original rename.
The second commit changes stable MIR, fixing https://github.com/rust-lang/project-stable-mir/issues/71. Previously there were two different smir types for the MIR type `ConstOperand`, one used in `Operand` and one in `VarDebugInfoContents`.
Maybe we should have done this with https://github.com/rust-lang/rust/pull/125967, so there's only a single breaking change... but I saw that PR too late.
Fixes https://github.com/rust-lang/project-stable-mir/issues/71
Use `Variance` glob imported variants everywhere
Fully commit to using the globbed variance. Could be convinced the other way, and change this PR to not use the globbed variants anywhere, but I'd rather we do one or the other.
r? lcnr
Extend SCC construction to enable extra functionality
Do YOU feel like your SCC construction doesn't do enough? Then I have a patch for you! SCCs can now do *everything*! Well, almost.
This patch has been extracted from #123720. It specifically enhances
`Sccs` to allow tracking arbitrary commutative properties (think min/max mappings on nodes vs arbitrary closures) of strongly connected components, including
- reachable values (max/min)
- SCC-internal values (max/min)
This helps with among other things universe computation. We can now identify
SCC universes as a reasonably straightforward "find max/min" operation during SCC construction. This is also included in this patch.
It's also more or less zero-cost; don't use the new features, don't pay for them.
This commit also vastly extends the documentation of the SCCs module, which I had a very hard time following. It may or may not have gotten easier to read for someone else.
I believe this logic can also be used in leak check, but haven't checked. Ha. ha. Ha.
This patch has been extracted from #123720. It specifically enhances
`Sccs` to allow tracking arbitrary commutative properties of SCCs, including
- reachable values (max/min)
- SCC-internal values (max/min)
This helps with among other things universe computation: we can now identify
SCC universes as a straightforward "find max/min" operation during SCC construction.
It's also more or less zero-cost; don't use the new features, don't pay for them.
This commit also vastly extends the documentation of the SCCs module, which I had a very hard time following.
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order.
- Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`.
This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`).
r? `@davidtwco`
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).