Compute lifetimes in scope at diagnostic time
The set of available lifetimes is currently computed during lifetime resolution on HIR. It is only used for one diagnostic.
In this PR, HIR lifetime resolution just reports whether elided lifetimes are well-defined at the place of use. The diagnostic code is responsible for building a list of lifetime names if elision is not allowed.
This will allow to remove lifetime resolution on HIR eventually.
Replace `&Vec<_>`s with `&[_]`s
It's generally preferable to use `&[_]` since it's one less indirection and it can be created from types other that `Vec`.
I've left `&Vec` in some locals where it doesn't really matter, in cases where `TypeFoldable` is expected (`TypeFoldable: Clone` so slice can't implement it) and in cases where it's `&TypeAliasThatIsActiallyVec`. Nothing important, really, I was just a little annoyed by `visit_generic_param_vec` :D
r? `@compiler-errors`
Handle more cases in cfg_accessible
This PR tries to handle more cases in the cfg_accessible implementation by only emitting a "not sure" error only if we have partially resolved a path.
This PR also adds many tests for the "not sure" cases and for private items.
r? `@petrochenkov`
Iterate over `maybe_unused_trait_imports` when checking dead trait imports
Closes#96873
r? `@cjgillot`
Some questions, if you have time:
- Is there a way to shorten the `rustc_data_structures::fx::FxIndexSet` path in the query declaration? I wasn't sure where to put a `use`.
- Was returning by reference from the query the right choice here?
- How would I go about evaluating the importance of the `is_dummy()` call in `check_crate`? I don't see failing tests when I comment it out. Should I just try to determine whether dummy spans can ever be put into `maybe_unused_trait_imports`?
- Am I doing anything silly with the various ID types?
- Is that `let-else` with `unreachable!()` bad? (i.e is there a better idiom? Would `panic!("<explanation>")` be better?)
- If I want to evaluate the perf of using a `Vec` as mentioned in #96873, is the best way to use the CI or is it feasible locally?
Thanks :)
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