Compute polonius loan scopes over the region graph
In issue #117146 a loan flows into an SCC containing a placeholder, and whose representative is an existential region. Since we currently compute loan scopes by looking at SCCs and their representatives only, polonius would compute kill points for this loan here whereas NLLs would not of course.
There are a few ways to fix this:
- don't try to be efficient by doing the computation over SCCs, and simply look for free regions and placeholders in the successors of the issuing region.
- change how the SCC representatives are picked, biasing towards placeholders over existential regions. They *shouldn't* matter much, but some downstream code may subtly depend on the current scheme (though no tests fail if we do such a change). This is for unrelated reasons also the way #116891 changes the representative computation. So that PR would also fix issue #117146.
- try to remove placeholders from the main path, and contain them to a pre-pass + a post-pass kind of polonius leak check. If possible, it would fix this issue by turning an outlives constraints to a placeholder into a constraint to 'static. This should also fix the issue, as the representative would be the free region in the SCC. We want to prototype this change to see if it's possible to try to simplify the borrowck main path from having to deal with placeholders and higher-ranked subtyping 🤞.
I'd like to take advantage of fuzzing and a crater run sooner rather than later, so that we grow more confidence that the 2 models are indeed equivalent empirically. Therefore this PR implements option 1 to fix the issue now.
We can take care of efficiency later after validation, and once we implement option 3 (which could also impact option 2 and that associated PR, maybe the lack of placeholders could remove the need to change the representative computation) to traverse SCCs and their representative again.
(Or we maybe will have some kind of naive position-dependent outlives propagation by then and this code would have been changed)
Fixes#117146.
r? `@matthewjasper`
Add -Zcross-crate-inline-threshold=yes
``@thomcc`` says this would be useful for
> seeing if it makes a difference in some code if i do it when building the sysroot, since -Zbuild-std + lto helps more than it seems like it should
And I've changed the possible values as a reference to ``@Manishearth`` saying
> LLVM's inlining heuristic is "yes".
Only use `normalize_param_env` when normalizing predicate in `check_item_bounds`
Only use the `normalize_param_env` when normalizing the item bound predicate in `check_item_bounds`, instead of using it when processing this obligation as well. This causes <BUG> to reoccur, but hopefully with better caching in the future, we can fix this would having such bad effects on perf.
This PR also fixes#117598. It turns out that the GAT predicate that we install is actually wrong -- given code like:
```
impl<'r> HasValueRef<'r> for Any {
type Database = Any;
}
```
We currently generate a predicate that looks like `<Any as HasValueRef<'r>>::Database = Any`, where `'r` is an early-bound variable. Really this GAT assumption should be universally quantified over the impl's args, i.e. `for<'r> <Any as HasValueRef<'r>>::Database = Any`, but then we'd need the binder to also include all the WC of the impl as well, which we don't support yet, lol.
To avoid `!matches!(...)`, which is hard to think about. Instead every
case now uses direct pattern matching and returns true or false.
Also add a couple of cases to the `stringify.rs` test that currently
print badly.
Method suggestion code tweaks
I was rummaging around the method suggestion code after https://github.com/rust-lang/rust/pull/117006#discussion_r1384153722 and saw a few things to simplify.
This is two unrelated commits, both in the same file. Review them separately, if you'd like.
r? estebank
Fix some clippy perf lints
`@matthiaskrgr` gave me the output of a clippy run with perf lints enabled. This PR fixes ones that I thought were worth fixing.
r? `@cuviper`
llvm-wrapper: Remove include of non-existant Vectorize.h
LLVM recently removed the header: 2400c54c37
It only contained a declaration of `createLoadStoreVectorizerPass()`, which Rust doesn't reference.
warn when using an unstable feature with -Ctarget-feature
Setting or unsetting the wrong target features can cause ABI incompatibility (https://github.com/rust-lang/rust/issues/116344, https://github.com/rust-lang/rust/issues/116558). We need to carefully audit features for their ABI impact before stabilization. I just learned that we currently accept arbitrary unstable features on stable and if they are in the list of Rust target features, even unstable, then we don't even warn about that!1 That doesn't seem great, so I propose we introduce a warning here.
This has an obvious loophole via `-Ctarget-cpu`. I'm not sure how to best deal with that, but it seems better to fix what we can and think about the other cases later, maybe once we have a better idea for how to resolve the general mess that are ABI-affecting target features.
Give a better diagnostic for missing parens in Fn* bounds
Fixes#108109
It would be nice to try and recover here, but I'm not sure it's worth the effort, especially as the bounds on the recovered function would be incorrect.
Thir unsafeck fixes
- Recognise thread local statics in THIR unsafeck
- Add suggestion for unsafe_op_in_unsafe_fn
- Fix unsafe checking of let expressions
Only instantiate binder during dyn's built-in trait candidate probe once
See UI test for demonstration of the issue.
This was "caused" by #117131, but only because we're using the `normalize_param_env` (which has been augmented with a projection clause used to normalize GATs) which features non-lifetime bound vars in it.
Fixes#117602 technically, though that's also fixed by #117542.
r? types
Build a better MIR body when errors are encountered
Doesn't really have much of an effect on its own, but it does lead to a less confusing phony MIR body being generated when an error is detected during THIR/MIR/match building. This was quite confusing when I hacked `-Zunpretty=mir` to emit `mir_built` rather than `instance_mir`.
This coincidentually also fixes#117413, but not as generally as #117416.
cc `@Nadrieril`
When not finding assoc fn on type, look for builder fn
When we have a resolution error when looking at a fully qualified path on a type, look for all associated functions on inherent impls that return `Self` and mention them to the user.
```
error[E0599]: no function or associated item named `new` found for struct `TcpStream` in the current scope
--> tests/ui/resolve/fn-new-doesnt-exist.rs:4:28
|
4 | let stream = TcpStream::new();
| ^^^ function or associated item not found in `TcpStream`
|
note: if you're trying to build a new `TcpStream` consider using one of the following associated functions:
TcpStream::connect
TcpStream::connect_timeout
--> /home/gh-estebank/rust/library/std/src/net/tcp.rs:156:5
|
156 | pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
172 | pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Fix#69512.
When we have a resolution error when looking at a fully qualified path
on a type, look for all associated functions on inherent impls that
return `Self` and mention them to the user.
Fix#69512.
Emit explanatory note for move errors in packed struct derives
Derive expansions for packed structs with non-`Copy` fields cause move errors because they prefer copying over borrowing since borrowing the fields of a packed struct can result in unaligned access.
This underlying cause of the errors, however, is not apparent to the user. This PR adds a diagnostic note to make it clear to the user (the new note is on the second last line):
```
tests/ui/derives/deriving-with-repr-packed-move-errors.rs:13:16
|
12 | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Default)]
| ----- in this derive macro expansion
13 | struct StructA(String);
| ^^^^^^ move occurs because `self.0` has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Fixes#117406
Partially addresses #110777
Rollup of 4 pull requests
Successful merges:
- #117190 (add test for #113381)
- #117516 (add test for #113375)
- #117631 (Documentation cleanup for core::error::Request.)
- #117637 (Check binders with bound vars for global bounds that don't hold)
r? `@ghost`
`@rustbot` modify labels: rollup
Detect misparsed binop caused by missing semi
When encountering
```rust
foo()
*bar = baz;
```
We currently emit potentially two errors, one for the return type of
`foo` not being multiplicative by the type of `bar`, and another for
`foo() * bar` not being assignable.
We now check for this case and suggest adding a semicolon in the right
place and emit only a single error.
Fix#80446.
Make the randomize feature of rustc_abi additive
The goal here is to make rust-analyzer able to build with the `rustc_private` versions of the rustc crates it depends on. See #116847
This updates all ICU4X crates and regenerates rustc_baked_icu_data.
Since the new unicode license under which they are licensed does not
have an SPDX identifier yet, we define some exceptions. The license has
to be reviewed to make sure it is still fine to use here, but I assume
that is the case.
I also added an exception for rustc_icu_data to the unexplained ignore
doctest tidy lint. This is a bit hacky but the whole style.rs in tidy is
a mess so I didn't want to touch it more than this small hack.
Rollup of 3 pull requests
Successful merges:
- #117592 (Use the correct span when emitting the `env!` result)
- #117613 (Remove from vacation and compiler review group)
- #117615 (Couple of small changes)
r? `@ghost`
`@rustbot` modify labels: rollup
Couple of small changes
These are unrelated to each other, but they are each small enough that opening separate PR's doesn't make sense to me either.
* Remove a place where the parse driver query is stolen.
* Update an outdated doc comment
* Use correct crate name in `-Zprint-vtable-sizes` when using `#![crate_name = "..."]`.
Use the correct span when emitting the `env!` result
The span used for the `env!` resut changed in 1.73, due to 75df62d4a2 (from https://github.com/rust-lang/rust/pull/114014).
This prevents [a lint in `plrustc`](https://github.com/tcdi/plrust/blob/main/plrustc/plrustc/src/lints/builtin_macros.rs#L54-L60)[^1] from working well, because the resulting span is not inside the region where the lint is `#[deny()]`ed.
[^1]: Perhaps worth noting that the `env_macro` diagnostic item comes from [the std fork used with PL/Rust](https://github.com/tcdi/postgrestd/blob/rust-1.73.0/library/core/src/macros/mod.rs#L944).
Unfortunately, I have no idea how to write a test for this since I don't think we can have a custom lint in a test. A suggestion was made to use a custom proc macro for it, but that seems pretty involved (frankly, I might not have time to do it).
r? ``@davidtwco`` (since they're the author of the PR with the regression)
P.S. We generally try to avoid bothering upstream about PL/Rust-specific stuff (we don't want to nag), but this seems like an actual bug, since the other similar macros, such as `option_env` use the other span (and are lintable as a result).
Derive `TyEncodable`/`TyDecodable` in `rustc_type_ir`
when `derive(TyEncodable)` or `derive(TyDecodable)` sees an `I` type parameter on a struct that has no `'tcx`, then parameterize the `TyEncoder`/`TyDecoder`'s interner over that variable rather than `TyCtxt<'tcx>`.
Also, emit where clauses for fields rather than generics.
enable parallel rustc front end in nightly builds
Refers to the [MCP](https://github.com/rust-lang/compiler-team/issues/681), this pr does:
1. Enable the parallel front end in nightly builds, and keep the default number of threads as 1. Then users can use the parallel rustc front end via -Z threads=n option.
2. Set it up to serial front end for beta/stable builds via bootstrap.
3. Switch over the alt builders from parallel rustc to serial, so we have artifacts without parallel to test against the artifacts with parallel.
r? `@oli-obk`
cc `@cjgillot` `@nnethercote` `@bjorn3` `@Kobzol`
Make sure that predicates with unmentioned bound vars are still considered global in the old solver
In the old solver, we consider predicates with late-bound vars to not be "global":
9c8a2694fa/compiler/rustc_trait_selection/src/traits/select/mod.rs (L1840-L1844)
The implementation of `has_late_bound_vars` was modified in #115834 so that we'd properly anonymize binders that had late-bound vars but didn't reference them. This fixed an ICE.
However, this also led to a behavioral change in https://github.com/rust-lang/rust/issues/117056#issuecomment-1775014545 for a couple of crates, which now consider `for<'a> GL33: Shader` (note the binder var that is *not* used in the predicate) to not be "global". This forces associated types to not be normalizable due to the old trait solver being dumb.
This PR distinguishes types which *reference* late-bound vars and binders which *have* late-bound vars. The latter is represented with the new type flag `TypeFlags::HAS_BINDER_VARS`, which is used when we only care about knowing whether binders have vars in their bound var list (even if they're not used, like for binder anonymization).
This should fix (after beta backport) the `luminance-gl` and `luminance-webgl` crates in #117056.
r? types
**(priority is kinda high on a review here given beta becomes stable on November 16.)**
Rollup of 6 pull requests
Successful merges:
- #110340 (Deref docs: expand and remove "smart pointer" qualifier)
- #116894 (Guarantee that `char` has the same size and alignment as `u32`)
- #117534 (clarify that the str invariant is a safety, not validity, invariant)
- #117562 (triagebot no-merges: exclude different case)
- #117570 (fallback for `construct_generic_bound_failure`)
- #117583 (Remove `'tcx` lifetime on `PlaceholderConst`)
r? `@ghost`
`@rustbot` modify labels: rollup
fallback for `construct_generic_bound_failure`
Fixes#117547
This case regressed at #115882.
In this context, `generic_param_scope` is produced by `RPITVisitor` and not included by `hir_owner`. Therefore, I've added a fallback to address this.
Update the alignment checks to match rust-lang/reference#1387
Previously, we had a special case to not check `Rvalue::AddressOf` in this pass because we weren't quite sure if pointers needed to be aligned in the Place passed to it: https://github.com/rust-lang/rust/pull/112026
Since https://github.com/rust-lang/reference/pull/1387 merged, this PR updates this pass to match. The behavior of the check is nearly unchanged, except we also avoid inserting a check for creating references. Most of the changes in this PR are cleanup and new tests.
consts: remove dead code around `i1` constant values
`LLVMConstZext` recently got deleted, and it turns out (thanks to `@nikic` for knowing!) that this is dead code. Tests all pass for me without this logic, and per nikic:
> We always generate constants in "relocatable bag of bytes"
> representation, so you're never going to get a plain bool.
So this should be a safe thing to do.
r? `@nikic`
`@rustbot` label: +llvm-main
Use `filter_map` in `try_par_for_each_in`
This simplifies the expression, especially for the rayon part, and also
lets us drop the `E: Copy` constraint.
Cleanup `rustc_mir_build/../check_match.rs`
The file had become pretty unwieldy, with a fair amount of duplication. As a bonus, I discovered that we weren't running some pattern checks in if-let chains.
I recommend looking commit-by-commit. The last commit is a whim, I think it makes more sense that way but I don't hold this opinion strongly.
By using SCC for better performance, we also have to take into account
SCCs whose representative is an existential region but also contains a
placeholder.
By only checking the representative, we may miss that the loan escapes
the function. This can be fixed by picking a better representative, or
removing placeholders from the main path.
This is the simplest fix: forgo efficiency and traverse the region graph
instead of the SCCs.
They've been deprecated for four years.
This commit includes the following changes.
- It eliminates the `rustc_plugin_impl` crate.
- It changes the language used for lints in
`compiler/rustc_driver_impl/src/lib.rs` and
`compiler/rustc_lint/src/context.rs`. External lints are now called
"loaded" lints, rather than "plugins" to avoid confusion with the old
plugins. This only has a tiny effect on the output of `-W help`.
- E0457 and E0498 are no longer used.
- E0463 is narrowed, now only relating to unfound crates, not plugins.
- The `plugin` feature was moved from "active" to "removed".
- It removes the entire plugins chapter from the unstable book.
- It removes quite a few tests, mostly all of those in
`tests/ui-fulldeps/plugin/`.
Closes#29597.
`LLVMConstZext` recently got deleted, and it turns out (thanks to @nikic
for knowing!) that this is dead code. Tests all pass for me without this
logic, and per nikic:
> We always generate constants in "relocatable bag of bytes"
> representation, so you're never going to get a plain bool.
So this should be a safe thing to do.
r? @nikic
@rustbot label: +llvm-main
Fix incorrect trait bound restriction suggestion
Suggest
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B {
| +++++++
```
instead of
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait + <T = B>, B>(a: A) -> B {
| +++++++++
```
Fix#117501.
Pretty print `Fn` traits in `rustc_on_unimplemented`
I don't think that users really ever should need to think about `Fn*` traits' tupled args for a simple trait error.
r? diagnostics
Derive expansions for packed structs cause move errors because
they prefer copying over borrowing since borrowing the fields of a
packed struct can result in unaligned access and therefore undefined
behaviour.
This underlying cause of the errors, however, is not apparent
to the user. We add a diagnostic note here to remedy that.
Add all RPITITs when augmenting param-env with GAT bounds in `check_type_bounds`
When checking that associated type definitions actually satisfy their associated type bounds in `check_type_bounds`, we construct a "`normalize_param_env`" which adds a projection predicate that allows us to assume that we can project the GAT to the definition we're checking. For example, in:
```rust
type Foo {
type Bar: Display = i32;
}
```
We would add `<Self as Foo>::Bar = i32` as a projection predicate when checking that `i32: Display` holds.
That `normalize_param_env` was, for some reason, only being used to normalize the predicate before it was registered. This is sketchy, because a nested obligation may require the GAT bound to hold, and also the projection cache is broken and doesn't differentiate projection cache keys that differ by param-envs 😿.
This `normalize_param_env` is also not sufficient when we have nested RPITITs and default trait methods, since we need to be able to assume we can normalize both the RPITIT and all of its child RPITITs to sufficiently prove all of its bounds. This is the cause of #117104, which only starts to fail for RPITITs that are nested 3 and above due to the projection-cache bug above.[^1]
## First fix
Use the `normalize_param_env` everywhere in `check_type_bounds`. This is reflected in a test I've constructed that fixes a GAT-only failure.
## Second fix
For RPITITs, install projection predicates for each RPITIT in the same function in `check_type_bounds`. This fixes#117104.
not sure who to request, so...
r? `@lcnr` hehe feel free to reassign :3
[^1]: The projection cache bug specifically occurs because we try normalizing the `assumed_wf_types` with the non-normalization param-env. This causes us to insert a projection cache entry that keeps the outermost RPITIT rigid, and it trivially satisifes all its own bounds. Super sketchy![^2]
[^2]: I haven't actually gone and fixed the projection cache bug because it's only marginally related, but I could, and it should no longer be triggered here.
Suggest
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B {
| +++++++
```
instead of
```
error[E0308]: mismatched types
--> $DIR/restrict-assoc-type-of-generic-bound.rs:9:12
|
LL | pub fn foo<A: MyTrait, B>(a: A) -> B {
| - - expected `B` because of return type
| |
| expected this type parameter
LL | return a.bar();
| ^^^^^^^ expected type parameter `B`, found associated type
|
= note: expected type parameter `B`
found associated type `<A as MyTrait>::T`
help: consider further restricting this bound
|
LL | pub fn foo<A: MyTrait + <T = B>, B>(a: A) -> B {
| +++++++++
```
Fix#117501.
Remove support for alias `-Z symbol-mangling-version`
(This is very similar to the removal of `-Z instrument-coverage` in #117111.)
`-C symbol-mangling-version` was stabilized back in rustc 1.59.0 (2022-02-24) via #90128, with the old unstable flag kept around (with a warning) as an alias to ease migration.
use global cache when computing proof trees
we're writing the solver while relying on the existence of the global cache to avoid exponential blowup. By disabling the global cache when building proof trees, it is easy to get hangs, e.g. when computing intercrate ambiguity causes.
Removes the unstable `-Zdump_solver_proof_tree_use_cache` option, as we now always return a full proof tree.
r? `@compiler-errors`
Don't check for alias bounds in liveness when aliases have escaping bound vars
I actually have no idea how we *should* be treating aliases with escaping bound vars here... but the simplest behavior is just doing what we used to do before.
r? aliemjay
Fixes#117455
Most notably, this commit changes the `pub use crate::*;` in that file
to `use crate::*;`. This requires a lot of `use` items in other crates
to be adjusted, because everything defined within `rustc_span::*` was
also available via `rustc_span::source_map::*`, which is bizarre.
The commit also removes `SourceMap::span_to_relative_line_string`, which
is unused.
The comment just below the first one describes how the `impl !Send for
FatalError` makes it impossible to `panic!(FatalError)`.
And the second one should be `panic_any` instead of `panic!`.
Do not assert in op_to_const.
`op_to_const` is used in `try_destructure_mir_constant_for_diagnostics`, which may encounter invalid constants created by optimizations and debugging.
r? ``@oli-obk``
Fixes https://github.com/rust-lang/rust/issues/117368
Avoid the path trimming ICE lint in error reporting
Types or really anything in MIR should never be formatted without path trimming disabled, because its formatting often tries to construct trimmed paths. In this case, the lint turns a nice error report into an irrelevant ICE.
Account for `ref` and `mut` in the wrong place for pattern ident renaming
If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest the correct code.
Fix#72298.