rustdoc: shrink GenericArgs/PathSegment with boxed slices
This PR also contains a few cleanup bits and pieces, but one of them is a broken intra-doc link, and the other is removing an unused Hash impl. The last commit is the one that matters.
Permit `asm_const` and `asm_sym` to reference generic params
Related #96557
These constructs will be allowed:
```rust
fn foofoo<const N: usize>() {}
unsafe fn foo<const N: usize>() {
asm!("/* {0} */", const N);
asm!("/* {0} */", const N + 1);
asm!("/* {0} */", sym foofoo::<N>);
}
fn barbar<T>() {}
unsafe fn bar<T>() {
asm!("/* {0} */", const std::mem::size_of::<T>());
asm!("/* {0} */", const std::mem::size_of::<(T, T)>());
asm!("/* {0} */", sym barbar::<T>);
asm!("/* {0} */", sym barbar::<(T, T)>);
}
```
`@Amanieu,` I didn't switch inline asms to use `DefKind::InlineAsm`, as I see little value doing that; given that no type inference is needed, it will only make typecking slower and more complex but will have no real gains. I did switch them to follow the same code path as inline asm during symbol resolution, though.
The `error: unconstrained generic constant` you mentioned in #76001 is due to the fact that `to_const` will actually add a wfness obligation to the constant, which we don't need for `asm_const`, so I have that removed.
`@rustbot` label: +A-inline-assembly +F-asm
don't encode only locally used attrs
Part of https://github.com/rust-lang/compiler-team/issues/505.
We now filter builtin attributes before encoding them in the crate metadata in case they should only be used in the local crate. To prevent accidental misuse `get_attrs` now requires the caller to state which attribute they are interested in. For places where that isn't trivially possible, I've added a method `fn get_attrs_unchecked` which I intend to remove in a followup PR.
After this pull request landed, we can then slowly move all attributes to only be used in the local crate while being certain that we don't accidentally try to access them from extern crates.
cc https://github.com/rust-lang/rust/pull/94963#issuecomment-1082924289
Implement a lint to warn about unused macro rules
This implements a new lint to warn about unused macro rules (arms/matchers), similar to the `unused_macros` lint added by #41907 that warns about entire macros.
```rust
macro_rules! unused_empty {
(hello) => { println!("Hello, world!") };
() => { println!("empty") }; //~ ERROR: 1st rule of macro `unused_empty` is never used
}
fn main() {
unused_empty!(hello);
}
```
Builds upon #96149 and #96156.
Fixes#73576
Begin fixing all the broken doctests in `compiler/`
Begins to fix#95994.
All of them pass now but 24 of them I've marked with `ignore HELP (<explanation>)` (asking for help) as I'm unsure how to get them to work / if we should leave them as they are.
There are also a few that I marked `ignore` that could maybe be made to work but seem less important.
Each `ignore` has a rough "reason" for ignoring after it parentheses, with
- `(pseudo-rust)` meaning "mostly rust-like but contains foreign syntax"
- `(illustrative)` a somewhat catchall for either a fragment of rust that doesn't stand on its own (like a lone type), or abbreviated rust with ellipses and undeclared types that would get too cluttered if made compile-worthy.
- `(not-rust)` stuff that isn't rust but benefits from the syntax highlighting, like MIR.
- `(internal)` uses `rustc_*` code which would be difficult to make work with the testing setup.
Those reason notes are a bit inconsistently applied and messy though. If that's important I can go through them again and try a more principled approach. When I run `rg '```ignore \(' .` on the repo, there look to be lots of different conventions other people have used for this sort of thing. I could try unifying them all if that would be helpful.
I'm not sure if there was a better existing way to do this but I wrote my own script to help me run all the doctests and wade through the output. If that would be useful to anyone else, I put it here: https://github.com/Elliot-Roberts/rust_doctest_fixing_tool
Allow inline consts to reference generic params
Tracking issue: #76001
The RFC says that inline consts cannot reference to generic parameters (for now), same as array length expressions. And expresses that it's desirable for it to reference in-scope generics, when array length expressions gain that feature as well.
However it is possible to implement this for inline consts before doing this for all anon consts, because inline consts are only used as values and they won't be used in the type system. So we can have:
```rust
fn foo<T>() {
let x = [4i32; std::mem::size_of::<T>()]; // NOT ALLOWED (for now)
let x = const { std::mem::size_of::<T>() }; // ALLOWED with this PR!
let x = [4i32; const { std::mem::size_of::<T>() }]; // NOT ALLOWED (for now)
}
```
This would make inline consts super useful for compile-time checks and assertions:
```rust
fn assert_zst<T>() {
const { assert!(std::mem::size_of::<T>() == 0) };
}
```
This would create an error during monomorphization when `assert_zst` is instantiated with non-ZST `T`s. A error during mono might sound scary, but this is exactly what a "desugared" inline const would do:
```rust
fn assert_zst<T>() {
struct F<T>(T);
impl<T> F<T> {
const V: () = assert!(std::mem::size_of::<T>() == 0);
}
let _ = F::<T>::V;
}
```
It should also be noted that the current inline const implementation can already reference the type params via type inference, so this resolver-level restriction is not any useful either:
```rust
fn foo<T>() -> usize {
let (_, size): (PhantomData<T>, usize) = const {
const fn my_size_of<T>() -> (PhantomData<T>, usize) {
(PhantomData, std::mem::size_of::<T>())
}
my_size_of()
};
size
}
```
```@rustbot``` label: F-inline_const
do not suggest when trait_ref is some
Update compiler/rustc_resolve/src/late/diagnostics.rs
Co-authored-by: lcnr <rust@lcnr.de>
use helper struct
add a test for functions with some params
refactor debug log
When suggesting to import an item, also suggest changing the path if appropriate
When we don't find an item we search all of them for an appropriate
import and suggest `use`ing it. This is sometimes done for expressions
that have paths with more than one segment. We now also suggest changing
that path to work with the `use`.
Fix#95413
When we don't find an item we search all of them for an appropriate
import and suggest `use`ing it. This is sometimes done for expressions
that have paths with more than one segment. We now also suggest changing
that path to work with the `use`.
Fix#95413
rustc: Panic by default in `DefIdTree::parent`
Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root.
So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root.
Same applies to `local_parent`/`opt_local_parent`.
Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root.
So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root.
Same applies to `local_parent`/`opt_local_parent`.
rustdoc: Resolve doc links referring to `macro_rules` items
cc https://github.com/rust-lang/rust/issues/81633
UPD: the fallback to considering *all* `macro_rules` in the crate for unresolved names is not removed in this PR, it will be removed separately and will be run through crater.
Enforce static lifetimes in consts during late resolution
This PR moves the handling of implicitly and explicitly static lifetimes in constants from HIR to the AST.
Change `span_suggestion` (and variants) to take `impl ToString` rather
than `String` for the suggested code, as this simplifies the
requirements on the diagnostic derive.
Signed-off-by: David Wood <david.wood@huawei.com>
Perform lifetime resolution on the AST for lowering
Lifetime resolution is currently implemented several times. Once during lowering in order to introduce in-band lifetimes, and once in the resolve_lifetimes query. However, due to the global nature of lifetime resolution and how it interferes with hygiene, it is better suited on the AST.
This PR implements a first draft of lifetime resolution on the AST. For now, we specifically target named lifetimes and everything we need to remove lifetime resolution from lowering. Some diagnostics have already been ported, and sometimes made more precise using available hygiene information. Follow-up PRs will address in particular the resolution of anonymous lifetimes on the AST.
We reuse the rib design of the current resolution framework. Specific `LifetimeRib` and `LifetimeRibKind` types are introduced. The most important variant is `LifetimeRibKind::Generics`, which happens each time we encounter something which may introduce generic lifetime parameters. It can be an item or a `for<...>` binder. The `LifetimeBinderKind` specifies how this rib behaves with respect to in-band lifetimes.
r? `@petrochenkov`
Add `BoundKind` in `visit_param_bounds` to check questions in bounds
From the FIXME in the impl of `AstValidator`. Better bound checks by adding `BoundCtxt` type parameter to `visit_param_bound`
cc `@ecstatic-morse`
Stop using CRATE_DEF_INDEX outside of metadata encoding.
`CRATE_DEF_ID` and `CrateNum::as_def_id` are almost always what we want. We should not manipulate raw `DefIndex` outside of metadata encoding.
resolve: Create dummy bindings for all unresolved imports
Apparently such bindings weren't previously created for all unresolved imports, causing issues like https://github.com/rust-lang/rust/issues/95879.
In this PR I'm trying to create such dummy bindings in a more centralized way by calling `import_dummy_binding` once for all imports in `finalize_imports`.
Fixes https://github.com/rust-lang/rust/issues/95879.
Move name resolution logic to a dedicated file
The code resolution logic from an Ident is scattered between several files.
The first commits creates `rustc_resolve::probe` module to hold the different mutually recursive functions together. Just a move, no code change.
The following commits attempt to make the logic a bit more readable.
The two fields `last_import_segment` and `unusable_binding` are replaced by function parameters.
In order to manage the fallout, `maybe_` variants of the function are added, dedicated to speculative resolution.
r? `@petrochenkov`
refactor: simplify few string related interactions
Few small optimizations:
check_doc_keyword: don't alloc string for emptiness check
check_doc_alias_value: get argument as Symbol to prevent needless string convertions
check_doc_attrs: don't alloc vec, iterate over slice.
replace as_str() check with symbol check
get_single_str_from_tts: don't prealloc string
trivial string to str replace
LifetimeScopeForPath::NonElided use Vec<Symbol> instead of Vec<String>
AssertModuleSource use FxHashSet<Symbol> instead of BTreeSet<String>
CrateInfo.crate_name replace FxHashMap<CrateNum, String> with FxHashMap<CrateNum, Symbol>
check_doc_alias_value: get argument as Symbol to prevent needless string convertions
check_doc_attrs: don't alloc vec, iterate over slice. Vec introduced in #83149, but no perf run posted on merge
replace as_str() check with symbol check
get_single_str_from_tts: don't prealloc string
trivial string to str replace
LifetimeScopeForPath::NonElided use Vec<Symbol> instead of Vec<String>
AssertModuleSource use BTreeSet<Symbol> instead of BTreeSet<String>
CrateInfo.crate_name replace FxHashMap<CrateNum, String> with FxHashMap<CrateNum, Symbol>
diagnostics: translation infrastructure
An implementation of the infrastructure required to have translatable diagnostic messages.
- Introduces a `DiagnosticMessage` type which can represent both the current non-translatable messages and identifiers for [Fluent](https://projectfluent.org/).
- Modifies current diagnostic API so that existing calls still work but `DiagnosticMessage`s can be provided too.
- Adds support for always loading a "fallback bundle" containing the English diagnostic messages, which are used when a `DiagnosticMessage::FluentIdentifier` is used in a diagnostic being emitted.
- Adds support for loading a "primary bundle" which contains the user's preferred language translation, and is used preferentially when it contains a diagnostic message being emitted. Primary bundles are loaded either from the path provided to `-Ztranslate-alternate-ftl` (for testing), or from the sysroot at `$sysroot/locale/$locale/*.ftl` given a locale with `-Ztranslate-lang` (which is parsed as a language identifier).
- Adds "diagnostic args" which enable normally-interpolated variables to be made available as variables for Fluent messages to use.
- Updates `#[derive(SessionDiagnostic)]` so that it can only be used for translatable diagnostics and update the handful of diagnostics which used the derive to be translatable.
For example, the following diagnostic...
```rust
#[derive(SessionDiagnostic)]
#[error = "E0195"]
pub struct LifetimesOrBoundsMismatchOnTrait {
#[message = "lifetime parameters or bounds on {item_kind} `{ident}` do not match the trait declaration"]
#[label = "lifetimes do not match {item_kind} in trait"]
pub span: Span,
#[label = "lifetimes in impl do not match this {item_kind} in trait"]
pub generics_span: Option<Span>,
pub item_kind: &'static str,
pub ident: Ident,
}
```
...becomes...
```rust
#[derive(SessionDiagnostic)]
#[error(code = "E0195", slug = "typeck-lifetimes-or-bounds-mismatch-on-trait")]
pub struct LifetimesOrBoundsMismatchOnTrait {
#[primary_span]
#[label]
pub span: Span,
#[label = "generics-label"]
pub generics_span: Option<Span>,
pub item_kind: &'static str,
pub ident: Ident,
}
```
```fluent
typeck-lifetimes-or-bounds-mismatch-on-trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
.generics-label = lifetimes in impl do not match this {$item_kind} in trait
```
r? `@estebank`
cc `@oli-obk` `@Manishearth`
This commit updates the signatures of all diagnostic functions to accept
types that can be converted into a `DiagnosticMessage`. This enables
existing diagnostic calls to continue to work as before and Fluent
identifiers to be provided. The `SessionDiagnostic` derive just
generates normal diagnostic calls, so these APIs had to be modified to
accept Fluent identifiers.
In addition, loading of the "fallback" Fluent bundle, which contains the
built-in English messages, has been implemented.
Each diagnostic now has "arguments" which correspond to variables in the
Fluent messages (necessary to render a Fluent message) but no API for
adding arguments has been added yet. Therefore, diagnostics (that do not
require interpolation) can be converted to use Fluent identifiers and
will be output as before.
`MultiSpan` contains labels, which are more complicated with the
introduction of diagnostic translation and will use types from
`rustc_errors` - however, `rustc_errors` depends on `rustc_span` so
`rustc_span` cannot use types like `DiagnosticMessage` without
dependency cycles. Introduce a new `rustc_error_messages` crate that can
contain `DiagnosticMessage` and `MultiSpan`.
Signed-off-by: David Wood <david.wood@huawei.com>
rustdoc: Fix resolution of `crate`-relative paths in doc links
Resolve `crate::foo` paths transparently to rustdoc, so their resolution no longer affects diagnostics and modules used for determining traits in scope.
The proper solution is to account for the current `module_id`/`parent_scope` in `fn resolve_crate_root`, but it's a slightly larger compiler changes. This PR moves the code closer to it, but keeps it rustdoc-specific.
Fixes https://github.com/rust-lang/rust/issues/78696
Fixes https://github.com/rust-lang/rust/issues/94924
Spellchecking compiler comments
This PR cleans up the rest of the spelling mistakes in the compiler comments. This PR does not change any literal or code spelling issues.
This allows to compute the `BodyOwnerKind` from `DefKind` only, and
removes a direct dependency of some MIR queries onto HIR.
As a side effect, it also simplifies metadata, since we don't need 4
flavours of `EntryKind::*Static` any more.
Also remove a redundant parameter from `fn resolve_path(_with_ribs)`, `crate_lint: CrateLint` is a more detailed version of `record_used: bool` with `CrateLint::No` meaning `false` and anything else meaning `true`.
There are a few places were we have to construct it, though, and a few
places that are more invasive to change. To do this, we create a
constructor with a long obvious name.