Use ident.span instead of def_span in dead-code pass
Hello! First time contributor! :)
This should fix#58729.
According to @estebank in the duplicate #63064, def_span scans forward on the line until it finds a {,
and if it can't find one, falls back to the span for the whole item. This
was apparently written before the identifier span was explicitly tracked on
each node.
This means that if an unused function signature spans multiple lines, the
entire function (potentially hundreds of lines) gets flagged as dead code.
This could, for example, cause IDEs to add error squiggly's to the whole
function.
By using the span from the ident instead, we narrow the scope of this in
most cases. In a wider sense, it's probably safe to use ident.span
instead of def_span in most locations throughout the whole code base,
but since this is my first contribution, I kept it small.
Some interesting points that came up while I was working on this:
- I reorganized the tests a bit to bring some of the dead code ones all
into the same location
- A few tests were for things unrelated to dead code (like the
path-lookahead for parens), so I added #![allow(dead_code)] and
cleaned up the stderr file to reduce noise in the future
- The same fix doesn't apply to const and static declarations. I tried
adding these cases to the match expression, but that created a much
wider change to tests and error messages, so I left it off until I
could get some code review to validate the approach.
If item.span is part of a macro invocation, this has several downstream
implications. To name two that were found while working on this:
- The dead-code error gets annotated with a "in this macro invocation"
- Some errors get canceled if they refer to remote crates
Ideally, we should annotate item.ident.span with the same macro info,
but this is a larger change (see: #66095), so for now we just fall
back to the old behavior if this item was generated by a macro.
I use span.macro_backtrace().len() to detect if it's part of a macro,
because that (among other things) is what is used by the code which
adds the "in this macro invocation" annotations mentioned above.
According to @estebank, def_span scans forward on the line until it finds a {,
and if it can't find one, fallse back to the span for the whole item. This
was apparently written before the identifier span was explicitly tracked on
each node.
This means that if an unused function signature spans multiple lines, the
entire function (potentially hundreds of lines) gets flagged as dead code.
This could, for example, cause IDEs to add error squiggly's to the whole
function.
By using the span from the ident instead, we narrow the scope of this in
most cases. In a wider sense, it's probably safe to use ident.span
instead of def_span in most locations throughout the whole code base,
but since this is my first contribution, I kept it small.
Some interesting points that came up while I was working on this:
- I reorganized the tests a bit to bring some of the dead code ones all
into the same location
- A few tests were for things unrelated to dead code (like the
path-lookahead for parens), so I added #![allow(dead_code)] and
cleaned up the stderr file to reduce noise in the future
- The same fix doesn't apply to const and static declarations. I tried
adding these cases to the match expression, but that created a much
wider change to tests and error messages, so I left it off until I
could get some code review to validate the approach.
This commit improves the suggestions provided when function parameters
do not have types:
- A new suggestion is added for arbitrary self types, which suggests
adding `self: ` before the type.
- Existing suggestions are now provided when a `<` is found where a `:`
was expected (previously only `,` and `)` or trait items), this gives
suggestions in the case where the unnamed parameter type is generic
in a free function.
- The suggestion that a type name be provided (e.g. `fn foo(HashMap<u32>)`
-> `fn foo(HashMap: TypeName<u32>)`) will no longer occur when a `<` was
found instead of `:`.
- The ident will not be used for recovery when a `<` was found instead
of `:`.
Signed-off-by: David Wood <david@davidtw.co>
Fully implement or-pattern parsing
Builds upon the initial parsing in https://github.com/rust-lang/rust/pull/61708 to fully implement or-pattern (`p | q`) parsing as specified in [the grammar section of RFC 2535](https://github.com/rust-lang/rfcs/blob/master/text/2535-or-patterns.md#grammar).
Noteworthy:
- We allow or-patterns in `[p | q, ...]`.
- We allow or-patterns in `let` statements and `for` expressions including with leading `|`.
- We improve recovery for `p || q` (+ tests for that in `multiple-pattern-typo.rs`).
- We improve recovery for `| p | q` in inner patterns (tests in `or-patterns-syntactic-fail.rs`).
- We rigorously test or-pattern parsing (in `or-patterns-syntactic-{pass,fail}.rs`).
- We harden the feature gating tests.
- We do **_not_** change `ast.rs`. That is, `ExprKind::Let.0` and `Arm.pats` still accept `Vec<P<Pat>>`.
I was starting work on that but it would be cleaner to do this in a separate PR so this one has a narrower scope.
cc @dlrobertson
cc the tracking issue https://github.com/rust-lang/rust/issues/54883.
r? @estebank
Move `Resolver` fields specific to late resolution to the new visitor.
The `current_module` field from `Resolver` is replaced with two `current_module`s in `LateResolutionVisitor` and `BuildReducedGraphVisitor`.
Outside of those visitors `current_module` is replaced by passing `parent_scope` to more functions and using the parent module from it.
Visibility resolution no longer have access to later resolution methods and has to use early resolution, so its diagnostics in case of errors regress slightly.
Suggest trait bound on type parameter when it is unconstrained
Given
```
trait Foo { fn method(&self) {} }
fn call_method<T>(x: &T) {
x.method()
}
```
suggest constraining `T` with `Foo`.
Fix#21673, fix#41030.
resolve: Improve candidate search for unresolved macro suggestions
Use same scope visiting machinery for both collecting suggestion candidates and actually resolving the names.
The PR is better read in per-commit fashion with whitespace changes ignored (the first commit in particular moves some code around).
This should be the last pre-requisite for https://github.com/rust-lang/rust/pull/62086.
r? @davidtwco
Normally `#![feature(...)]` shouldn't change behavior, but custom attributes in particular are in the process of retirement, and we should not produce a message telling to enable them.
It also helps with unifying diagnostics for unresolved macros.
When encountering code where type inference fails, add more actionable
information:
```
fn main() {
let foo = Vec::new();
}
```
```
error[E0282]: type annotations needed for `std::vec::Vec<_>`
--> $DIR/vector-no-ann.rs:2:16
|
LL | let foo = Vec::new();
| --- ^^^^^^^^ cannot infer type for `T`
| |
| consider giving `foo` the type `std::vec::Vec<_>` with the type parameter `T` specified
```
We still need to modify type printing to optionally accept a
`TypeVariableTable` in order to properly print `std::vec::Vec<T>`.
CC #25633.