Retroactively feature gate `ConstArgKind::Path`
This puts the lowering introduced by #125915 under a feature gate until we fix the regressions introduced by it. Alternative to whole sale reverting the PR since it didn't seem like a very clean revert and I think this is generally a step in the right direction and don't want to get stuck landing and reverting the PR over and over :)
cc #129137 ``@camelid,`` tests taken from there. beta is branching soon so I think it makes sense to not try and rush that fix through since it wont have much time to bake and if it has issues we can't simply revert it on beta.
Fixes#128016
Use shorthand field initialization syntax more aggressively in the compiler
Caught these when cleaning up #129344 and decided to run clippy to find the rest
Use `bool` in favor of `Option<()>` for diagnostics
We originally only supported `Option<()>` for optional notes/labels, but we now support `bool`. Let's use that, since it usually leads to more readable code.
I'm not removing the support from the derive macro, though I guess we could error on it... 🤔
Don't consider locals to shadow inner items' generics
We don't want to consider the bindings from a `RibKind::Module` itself, because for an inner item that module will contain the local bindings from the function body or wherever else the inner item is being defined.
Fixes#129265
r? petrochenkov
rm `import.used`
By the way, `import_used_map` will only be used during `build_reduced_graph` and `finalize`, so it can be split from `Resolver` in the future.
r? ``@petrochenkov``
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
Only walk ribs to collect possibly shadowed params if we are adding params in our new rib
No need to collect params from parent ribs if we literally have no params to declare in this new rib.
Attempt to win back some of the perf in https://github.com/rust-lang/rust/pull/128357#issuecomment-2262677031.
Please review with whitespace *off*, the diff should be like 2 lines.
r? petrochenkov
Add `REDUNDANT_IMPORTS` lint for new redundant import detection
Defaults to Allow for now. Stacked on #123744 to avoid merge conflict, but much easier to review all as one.
r? petrochenkov
Structured suggestion for `extern crate foo` when `foo` isn't resolved in import
When encountering a name in an import that could have come from a crate that wasn't imported, use a structured suggestion to suggest `extern crate foo;` pointing at the right place in the crate.
When encountering `_` in an import, do not suggest `extern crate _;`.
```
error[E0432]: unresolved import `spam`
--> $DIR/import-from-missing-star-3.rs:2:9
|
LL | use spam::*;
| ^^^^ maybe a missing crate `spam`?
|
help: consider importing the `spam` crate
|
LL + extern crate spam;
|
```
When encountering a name in an import that could have come from a crate that wasn't imported, use a structured suggestion to suggest `extern crate foo;` pointing at the right place in the crate.
When encountering `_` in an import, do not suggest `extern crate _;`.
```
error[E0432]: unresolved import `spam`
--> $DIR/import-from-missing-star-3.rs:2:9
|
LL | use spam::*;
| ^^^^ maybe a missing crate `spam`?
|
help: consider importing the `spam` crate
|
LL + extern crate spam;
|
```
We don't want to have questions in the diagnostic output. Instead, we use wording that communicates uncertainty, like "might":
```
error[E0432]: unresolved import `spam`
--> $DIR/import-from-missing-star-3.rs:2:9
|
LL | use spam::*;
| ^^^^ you might be missing crate `spam`
|
= help: consider adding `extern crate spam` to use the `spam` crate
```
Clean up a few minor refs in `format!` macro, as it has a performance cost. Apparently the compiler is unable to inline `format!("{}", &variable)`, and does a run-time double-reference instead (format macro already does one level referencing). Inlining format args prevents accidental `&` misuse.
When finding item gated behind a `cfg` flag, point at it
Previously we would only mention that the item was gated out, and opportunisitically mention the feature flag name when possible. We now point to the place where the item was gated, which can be behind layers of macro indirection, or in different modules.
```
error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
--> $DIR/diagnostics-cross-crate.rs:18:23
|
LL | cfged_out::inner::doesnt_exist::hello();
| ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
|
note: found an item that was configured out
--> $DIR/auxiliary/cfged_out.rs:6:13
|
LL | pub mod doesnt_exist {
| ^^^^^^^^^^^^
note: the item is gated here
--> $DIR/auxiliary/cfged_out.rs:5:5
|
LL | #[cfg(FALSE)]
| ^^^^^^^^^^^^^
```
Represent type-level consts with new-and-improved `hir::ConstArg`
### Summary
This is a step toward `min_generic_const_exprs`. We now represent all const
generic arguments using an enum that differentiates between const *paths*
(temporarily just bare const params) and arbitrary anon consts that may perform
computations. This will enable us to cleanly implement the `min_generic_const_args`
plan of allowing the use of generics in paths used as const args, while
disallowing their use in arbitrary anon consts. Here is a summary of the salient
aspects of this change:
- Add `current_def_id_parent` to `LoweringContext`
This is needed to track anon const parents properly once we implement
`ConstArgKind::Path` (which requires moving anon const def-creation
outside of `DefCollector`).
- Create `hir::ConstArgKind` enum with `Path` and `Anon` variants. Use it in the
existing `hir::ConstArg` struct, replacing the previous `hir::AnonConst` field.
- Use `ConstArg` for all instances of const args. Specifically, use it instead
of `AnonConst` for assoc item constraints, array lengths, and const param
defaults.
- Some `ast::AnonConst`s now have their `DefId`s created in
rustc_ast_lowering rather than `DefCollector`. This is because in some
cases they will end up becoming a `ConstArgKind::Path` instead, which
has no `DefId`. We have to solve this in a hacky way where we guess
whether the `AnonConst` could end up as a path const since we can't
know for sure until after name resolution (`N` could refer to a free
const or a nullary struct). If it has no chance as being a const
param, then we create a `DefId` in `DefCollector` -- otherwise we
decide during ast_lowering. This will have to be updated once all path
consts use `ConstArgKind::Path`.
- We explicitly use `ConstArgHasType` for array lengths, rather than
implicitly relying on anon const type feeding -- this is due to the
addition of `ConstArgKind::Path`.
- Some tests have their outputs changed, but the changes are for the
most part minor (including removing duplicate or almost-duplicate
errors). One test now ICEs, but it is for an incomplete, unstable
feature and is now tracked at https://github.com/rust-lang/rust/issues/127009.
### Followup items post-merge
- Use `ConstArgKind::Path` for all const paths, not just const params.
- Fix (no github dont close this issue) #127009
- If a path in generic args doesn't resolve as a type, try to resolve as a const
instead (do this in rustc_resolve). Then remove the special-casing from
`rustc_ast_lowering`, so that all params will automatically be lowered as
`ConstArgKind::Path`.
- (?) Consider making `const_evaluatable_unchecked` a hard error, or at least
trying it in crater
r? `@BoxyUwU`
Fix ambiguous cases of multiple & in elided self lifetimes
This change proposes simpler rules to identify the lifetime on `self` parameters which may be used to elide a return type lifetime.
## The old rules
(copied from [this comment](https://github.com/rust-lang/rust/pull/117967#discussion_r1420554242))
Most of the code can be found in [late.rs](https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_resolve/late.rs.html) and acts on AST types. The function [resolve_fn_params](https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_resolve/late.rs.html#2006), in the success case, returns a single lifetime which can be used to elide the lifetime of return types.
Here's how:
* If the first parameter is called self then we search that parameter using "`self` search rules", below
* If no unique applicable lifetime was found, search all other parameters using "regular parameter search rules", below
(In practice the code does extra work to assemble good diagnostic information, so it's not quite laid out like the above.)
### `self` search rules
This is primarily handled in [find_lifetime_for_self](https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_resolve/late.rs.html#2118) , and is described slightly [here](https://github.com/rust-lang/rust/issues/117715#issuecomment-1813115477) already. The code:
1. Recursively walks the type of the `self` parameter (there's some complexity about resolving various special cases, but it's essentially just walking the type as far as I can see)
2. Each time we find a reference anywhere in the type, if the **direct** referent is `Self` (either spelled `Self` or by some alias resolution which I don't fully understand), then we'll add that to a set of candidate lifetimes
3. If there's exactly one such unique lifetime candidate found, we return this lifetime.
### Regular parameter search rules
1. Find all the lifetimes in each parameter, including implicit, explicit etc.
2. If there's exactly one parameter containing lifetimes, and if that parameter contains exactly one (unique) lifetime, *and if we didn't find a `self` lifetime parameter already*, we'll return this lifetime.
## The new rules
There are no changes to the "regular parameter search rules" or to the overall flow, only to the `self` search rules which are now:
1. Recursively walks the type of the `self` parameter, searching for lifetimes of reference types whose referent **contains** `Self`.[^1]
2. Keep a record of:
* Whether 0, 1 or n unique lifetimes are found on references encountered during the walk
4. If no lifetime was found, we don't return a lifetime. (This means other parameters' lifetimes may be used for return type lifetime elision).
5. If there's one lifetime found, we return the lifetime.
6. If multiple lifetimes were found, we abort elision entirely (other parameters' lifetimes won't be used).
[^1]: this prevents us from considering lifetimes from inside of the self-type
## Examples that were accepted before and will now be rejected
```rust
fn a(self: &Box<&Self>) -> &u32
fn b(self: &Pin<&mut Self>) -> &String
fn c(self: &mut &Self) -> Option<&Self>
fn d(self: &mut &Box<Self>, arg: &usize) -> &usize // previously used the lt from arg
```
### Examples that change the elided lifetime
```rust
fn e(self: &mut Box<Self>, arg: &usize) -> &usize
// ^ new ^ previous
```
## Examples that were rejected before and will now be accepted
```rust
fn f(self: &Box<Self>) -> &u32
```
---
*edit: old PR description:*
```rust
struct Concrete(u32);
impl Concrete {
fn m(self: &Box<Self>) -> &u32 {
&self.0
}
}
```
resulted in a confusing error.
```rust
impl Concrete {
fn n(self: &Box<&Self>) -> &u32 {
&self.0
}
}
```
resulted in no error or warning, despite apparent ambiguity over the elided lifetime.
Fixes https://github.com/rust-lang/rust/issues/117715
Accurate `use` rename suggestion span
When suggesting to rename an import with `as`, use a smaller span to render the suggestion with a better format:
```
error[E0252]: the name `baz` is defined multiple times
--> $DIR/issue-25396.rs:4:5
|
LL | use foo::baz;
| -------- previous import of the module `baz` here
LL | use bar::baz;
| ^^^^^^^^ `baz` reimported here
|
= note: `baz` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | use bar::baz as other_baz;
| ++++++++++++
```
When suggesting to rename an import with `as`, use a smaller span to
render the suggestion with a better format:
```
error[E0252]: the name `baz` is defined multiple times
--> $DIR/issue-25396.rs:4:5
|
LL | use foo::baz;
| -------- previous import of the module `baz` here
LL | use bar::baz;
| ^^^^^^^^ `baz` reimported here
|
= note: `baz` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | use bar::baz as other_baz;
| ++++++++++++
```
This is a very large commit since a lot needs to be changed in order to
make the tests pass. The salient changes are:
- `ConstArgKind` gets a new `Path` variant, and all const params are now
represented using it. Non-param paths still use `ConstArgKind::Anon`
to prevent this change from getting too large, but they will soon use
the `Path` variant too.
- `ConstArg` gets a distinct `hir_id` field and its own variant in
`hir::Node`. This affected many parts of the compiler that expected
the parent of an `AnonConst` to be the containing context (e.g., an
array repeat expression). They have been changed to check the
"grandparent" where necessary.
- Some `ast::AnonConst`s now have their `DefId`s created in
rustc_ast_lowering rather than `DefCollector`. This is because in some
cases they will end up becoming a `ConstArgKind::Path` instead, which
has no `DefId`. We have to solve this in a hacky way where we guess
whether the `AnonConst` could end up as a path const since we can't
know for sure until after name resolution (`N` could refer to a free
const or a nullary struct). If it has no chance as being a const
param, then we create a `DefId` in `DefCollector` -- otherwise we
decide during ast_lowering. This will have to be updated once all path
consts use `ConstArgKind::Path`.
- We explicitly use `ConstArgHasType` for array lengths, rather than
implicitly relying on anon const type feeding -- this is due to the
addition of `ConstArgKind::Path`.
- Some tests have their outputs changed, but the changes are for the
most part minor (including removing duplicate or almost-duplicate
errors). One test now ICEs, but it is for an incomplete, unstable
feature and is now tracked at #127009.
Fix import suggestion ice
Fixes#127302#127302 only crash in edition 2015
#120074 can only reproduced in edition 2021
so I added revisions in test file.
Previously we would only mention that the item was gated out, and opportunisitically mention the feature flag name when possible. We now point to the place where the item was gated, which can be behind layers of macro indirection, or in different modules.
```
error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
--> $DIR/diagnostics-cross-crate.rs:18:23
|
LL | cfged_out::inner::doesnt_exist::hello();
| ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
|
note: found an item that was configured out
--> $DIR/auxiliary/cfged_out.rs:6:13
|
LL | pub mod doesnt_exist {
| ^^^^^^^^^^^^
note: the item is gated here
--> $DIR/auxiliary/cfged_out.rs:5:5
|
LL | #[cfg(FALSE)]
| ^^^^^^^^^^^^^
```
Use field ident spans directly instead of the full field span in diagnostics on local fields
This improves diagnostics and avoids having to store the `DefId`s of fields
The only place it is meaningfully used is in a panic message in
`TokenStream::from_ast`. But `node.span()` doesn't need to be printed
because `node` is also printed and it must contain the span.
rustdoc: update to pulldown-cmark 0.11
r? rustdoc
This pull request updates rustdoc to the latest version of pulldown-cmark. Along with adding new markdown extensions (which this PR doesn't enable), the new pulldown-cmark version also fixes a large number of bugs. Because all text files successfully parse as markdown, these bugfixes change the output, which can break people's existing docs.
A crater run, https://github.com/rust-lang/rust/pull/121659, has already been run for this change.
The first commit upgrades and fixes rustdoc. The second commit adds a lint for the footnote and block quote parser changes, which break the largest numbers of docs in the Crater run. The strikethrough change was mitigated in pulldown-cmark itself.
Unblocks https://github.com/rust-lang/rust-clippy/pull/12876
ast: Standardize visiting order for attributes and node IDs
This should only affect `macro_rules` scopes and order of diagnostics.
Also add a deprecation lint for `macro_rules` called outside of their scope, like in https://github.com/rust-lang/rust/issues/124535.
`StaticForeignItem` and `StaticItem` are the same
The struct `StaticItem` and `StaticForeignItem` are the same, so remove `StaticForeignItem`. Having them be separate is unique to `static` items -- unlike `ForeignItemKind::{Fn,TyAlias}`, which use the normal AST item.
r? ``@spastorino`` or ``@oli-obk``
delegation: Implement glob delegation
Support delegating to all trait methods in one go.
Overriding globs with explicit definitions is also supported.
The implementation is generally based on the design from https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2020869823, but unlike with list delegation in https://github.com/rust-lang/rust/pull/123413 we cannot expand glob delegation eagerly.
We have to enqueue it into the queue of unexpanded macros (most other macros are processed this way too), and then a glob delegation waits in that queue until its trait path is resolved, and enough code expands to generate the identifier list produced from the glob.
Glob delegation is only allowed in impls, and can only point to traits.
Supporting it in other places gives very little practical benefit, but significantly raises the implementation complexity.
Part of https://github.com/rust-lang/rust/issues/118212.
Resolve elided lifetimes in assoc const to static if no other lifetimes are in scope
Implements the change to elided lifetime resolution in *associated consts* subject to FCP here: https://github.com/rust-lang/rust/issues/125190#issue-2301532282
Specifically, walk the enclosing lifetime ribs in an associated const, and if we find no other lifetimes, then resolve to `'static`.
Also make it work for traits, but don't lint -- just give a hard error in that case.
When both `std::` and `core::` items are available, only suggest the
`std::` ones. We ensure that in `no_std` crates we suggest `core::`
items.
Ensure that the list of items suggested to be imported are always in the
order of local crate items, `std`/`core` items and finally foreign crate
items.
Tweak wording of import suggestion: if there are multiple items but they
are all of the same kind, we use the kind name and not the generic "items".
Fix#83564.
Spruce up the diagnostics of some early lints
Implement the various "*(note to myself) in a follow-up PR we should turn parts of this message into a subdiagnostic (help msg or even struct sugg)*" drive-by comments I left in #124417 during my review.
For context, before #124417, only a few early lints touched/decorated/customized their diagnostic because the former API made it a bit awkward. Likely because of that, things that should've been subdiagnostics were just crammed into the primary message. This PR rectifies this.
Change the algorithm which determines whether a self lifetime can be
used for return type lifetime elision, such that we consider lifetimes
attached to any reference in the self type, so long as Self can be found
anywhere inside the type of that reference.
Rollup of 9 pull requests
Successful merges:
- #124840 (resolve: mark it undetermined if single import is not has any bindings)
- #125622 (Winnow private method candidates instead of assuming any candidate of the right name will apply)
- #125648 (Remove unused(?) `~/rustsrc` folder from docker script)
- #125672 (Add more ABI test cases to miri (RFC 3391))
- #125800 (Fix `mut` static task queue in SGX target)
- #125871 (Orphanck[old solver]: Consider opaque types to never cover type parameters)
- #125893 (Handle all GVN binops in a single place.)
- #126008 (Port `tests/run-make-fulldeps/issue-19371` to ui-fulldeps)
- #126032 (Update description of the `IsTerminal` example)
r? `@ghost`
`@rustbot` modify labels: rollup
resolve: mark it undetermined if single import is not has any bindings
- Fixes#124490
- Fixes#125013
This issue arises from incorrect resolution updates, for example:
```rust
mod a {
pub mod b {
pub mod c {}
}
}
use a::*;
use b::c;
use c as b;
fn main() {}
```
1. In the first loop, binding `(root, b)` is refer to `root:🅰️:b` due to `use a::*`.
1. However, binding `(root, c)` isn't defined by `use b::c` during this stage because `use c as b` falls under the `single_imports` of `(root, b)`, where the `imported_module` hasn't been computed yet. This results in marking the `path_res` for `b` as `Indeterminate`.
2. Then, the `imported_module` for `use c as b` will be recorded.
2. In the second loop, `use b::c` will be processed again:
1. Firstly, it attempts to find the `path_res` for `(root, b)`.
2. It will iterate through the `single_imports` of `use b::c`, encounter `use c as b`, attempt to resolve `c` in `root`, and ultimately return `Err(Undetermined)`, thus passing the iterator.
3. Use the binding `(root, b)` -> `root:🅰️:b` introduced by `use a::*` and ultimately return `root:🅰️:b` as the `path_res` of `b`.
4. Then define the binding `(root, c)` -> `root:🅰️🅱️:c`.
3. Then process `use c as b`, update the resolution for `(root, b)` to refer to `root:🅰️🅱️:c`, ultimately causing inconsistency.
In my view, step `2.2` has an issue where it should exit early, similar to the behavior when there's no `imported_module`. Therefore, I've added an attribute called `indeterminate` to `ImportData`. This will help us handle only those single imports that have at least one determined binding.
r? ``@petrochenkov``
Detect when user is trying to create a lending `Iterator` and give a custom explanation
The scope for this diagnostic is to detect lending iterators specifically and it's main goal is to help beginners to understand that what they are trying to implement might not be possible for `Iterator` trait specifically.
I ended up to changing the wording from originally proposed in the ticket because it might be misleading otherwise: `Data` might have a lifetime parameter but it can be unrelated to items user is planning to return.
Fixes https://github.com/rust-lang/rust/issues/125337