take 2
open up coroutines
tweak the wordings
the lint works up until 2021
We were missing one case, for ADTs, which was
causing `Result` to yield incorrect results.
only include field spans with significant types
deduplicate and eliminate field spans
switch to emit spans to impl Drops
Co-authored-by: Niko Matsakis <nikomat@amazon.com>
collect drops instead of taking liveness diff
apply some suggestions and add explantory notes
small fix on the cache
let the query recurse through coroutine
new suggestion format with extracted variable name
fine-tune the drop span and messages
bugfix on runtime borrows
tweak message wording
filter out ecosystem types earlier
apply suggestions
clippy
check lint level at session level
further restrict applicability of the lint
translate bid into nop for stable mir
detect cycle in type structure
Make deprecated_cfg_attr_crate_type_name a hard error
Turns the forward compatibility lint added by #83744 into a hard error, so now, while the `#![crate_name]` and `#![crate_type]` attributes are still allowed in raw form, they are now forbidden to be nested inside a `#![cfg_attr()]` attribute.
The following will now be an error:
```Rust
#![cfg_attr(foo, crate_name = "foobar")]
#![cfg_attr(foo, crate_type = "bin")]
```
This code will continue working and is not deprecated:
```Rust
#![crate_name = "foobar"]
#![crate_type = "lib"]
```
The reasoning for this is explained in #83744: it allows us to not have to cfg-expand in order to determine the crate's type and name.
As of filing the PR, exactly two years have passed since #99784 has been merged, which has turned the lint's default warning level into an error, so there has been ample time to move off the now-forbidden syntax.
cc #91632 - tracking issue for the lint
Revert "Add recursion limit to FFI safety lint"
It's not necessarily clear if warning when we hit the recursion limit is the right thing to do, first of all.
**More importantly**, this PR was implemented incorrectly in the first place; it was not decrementing the recursion limit when stepping out of a type, so it would trigger when a ctype has more than RECURSION_LIMIT fields *anywhere* in the type's set of recursively reachable fields.
Reverts #130598Reopens#130310Fixes#130757
Rework `non_local_definitions` lint to only use a syntactic heuristic
This PR reworks the `non_local_definitions` lint to only use a syntactic heuristic, i.e. not use a type-system logic for whenever an `impl` is local or not.
Instead the new logic wanted by T-lang in https://github.com/rust-lang/rust/issues/126768#issuecomment-2192634762, which is to consider every paths in `Self` and `Trait` and to no longer use the type-system inference trick.
`@rustbot` labels +L-non_local_definitions
Fixes#126768
Add recursion limit to FFI safety lint
Fixes#130310
Now we check against `tcx.recursion_limit()` and raise an error if it the limit is reached instead of overflowing the stack.
Implement raw lifetimes and labels (`'r#ident`)
This PR does two things:
1. Reserve lifetime prefixes, e.g. `'prefix#lt` in edition 2021.
2. Implements raw lifetimes, e.g. `'r#async` in edition 2021.
This PR additionally extends the `keyword_idents_2024` lint to also check lifetimes.
cc `@traviscross`
r? parser
Add a special case for `CStr`/`CString` in the `improper_ctypes` lint
Revives #120176. Just needed to bless a test and fix an argument, but seemed reasonable to me otherwise.
Instead of saying to "consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct", we now tell users to "Use `*const ffi::c_char` instead, and pass the value from `CStr::as_ptr()`" when the type involved is a `CStr` or a `CString`.
The suggestion is not made for `&mut CString` or `*mut CString`.
r? ``````@cjgillot`````` (since you were the reviewer of the original PR #120176, but feel free to reroll)
Instead of saying to "consider adding a `#[repr(C)]` or
`#[repr(transparent)]` attribute to this struct", we now tell users to
"Use `*const ffi::c_char` instead, and pass the value from
`CStr::as_ptr()`" when the type involved is a `CStr` or a `CString`.
Co-authored-by: Jieyou Xu <jieyouxu@outlook.com>
Make it crystal clear what lint `type_alias_bounds` actually signifies
This is part of my work on https://github.com/rust-lang/rust/labels/F-lazy_type_alias ([tracking issue](#112792)).
---
To recap, the lint `type_alias_bounds` detects bounds on generic parameters and where clauses on (eager) type aliases. These bounds should've never been allowed because they are currently neither enforced[^1] at usage sites of type aliases nor thoroughly checked for correctness at definition sites due to the way type aliases are represented in the compiler. Allowing them was an oversight.
Explicitly label this as a known limitation of the type checker/system and establish the experimental feature `lazy_type_alias` as its eventual proper solution.
Where this becomes a bit tricky (for me as a rustc dev) are the "secondary effects" of these bounds whose existence I sadly can't deny. As a matter of fact, type alias bounds do play some small roles during type checking. However, after a lot of thinking over the last two weeks I've come to the conclusion (not without second-guessing myself though) that these use cases should not trump the fact that these bounds are currently *inherently broken*. Therefore the lint `type_alias_bounds` should and will continue to flag bounds that may have subordinate uses.
The two *known* secondary effects are:
1. They may enable the use of "shorthand" associated type paths `T::Assoc` (as opposed to fully qualified paths `<T as Trait>::Assoc`) where `T` is a type param bounded by some trait `Trait` which defines that assoc ty.
2. They may affect the default lifetime of trait object types passed as a type argument to the type alias. That concept is called (trait) object lifetime default.
The second one is negligible, no question asked. The first one however is actually "kinda nice" (for writability) and comes up in practice from time to time.
So why don't I just special-case trait bounds that "define" shorthand assoc type paths as originally planned in #125709?
1. Starting to permit even a tiny subset of bounds would already be enough to send a signal to users that bounds in type aliases have been legitimized and that they can expect to see type alias bounds in the wild from now on (proliferation). This would be actively misleading and dangerous because those bounds don't behave at all like one would expect, they are *not real*[^2]!
1. Let's take `type A<T: Trait> = T::Proj;` for example. Everywhere else in the language `T: Trait` means `T: Trait + Sized`. For type aliases, that's not the case though: `T: Trait` and `T: Trait + ?Sized` for that matter do neither mean `T: Trait + Sized` nor `T: Trait + ?Sized` (for both!). Instead, whether `T` requires `Sized` or not entirely depends on the definition of `Trait`[^2]. Namely, whether or not it is bounded by `Sized`.
2. Given `type A<T: Trait<AssocA = ()>> = T::AssocB;`, while `X: Trait` gets checked given `A<X>` (by virtue of projection wfchecking post alias expansion[^2]), the associated type constraint `AssocA = ()` gets dropped entirely! While we could choose to warn on such cases, it would inevitably lead to a huge pile of special cases.
3. While it's common knowledge that the body / aliased type / RHS of an (eager) type alias does not get checked for well-formedness, I'm not sure if people would realize that that extends to bounds as well. Namely, `type A<T: Trait<[u8]>> = T::Proj;` compiles even if `Trait`'s generic parameter requires `Sized`. Of course, at usage sites `[u8]: Sized` would still end up getting checked[^2], so it's not a huge problem if you have full control over `A`. However, imagine that `A` was actually part of a public API and was never used inside the defining crate (not unreasonable). In such a scenario, downstream users would be presented with an impossible to use type alias! Remember, bounds may grow arbitrarily complex and nuanced in practice.
4. Even if we allowed trait bounds that "define" shorthand assoc type paths, we would still need to continue to warn in cases where the assoc ty comes from a supertrait despite the fact that the shorthand syntax can be used: `type A<T: Sub> = T::Assoc;` does compile given `trait Sub: Super {}` and `trait Super { type Assoc; }`. However, `A<X>` does not enforce `X: Sub`, only `X: Super`[^2]. All that to say, type alias bounds are simply not real and we shouldn't pretend they are!
5. Summarizing the points above, we would be legitimizing bounds that are completely broken!
2. It's infeasible to implement: Due to the lack of `TypeckResults` in `ItemCtxt` (and a way to propagate it to other parts of the compiler), the resolution of type-dependent paths in non-`Body` items (most notably type aliases) is not recoverable from the HIR alone which would be necessary because the information of whether an associated type path (projection) is a shorthand is only present pre&in-HIR and doesn't survive HIR ty lowering. Of course, I could rerun parts of HIR ty lowering inside the lint `type_alias_bounds` (namely, `probe_single_ty_param_bound_for_assoc_ty` which would need to be exposed or alternatively a stripped-down version of it). This likely has a performance impact and introduces complexity. In short, the "benefits" are not worth the costs.
---
* 3rd commit: Update a diagnostic to avoid suggesting type alias bounds
* 4th commit: Flag type alias bounds even if the RHS contains inherent associated types.
* I started to allow them at some point in the past which was not correct (see commit for details)
* 5th commit: Allow type alias bounds if the RHS contains const projections and GCEs are enabled
* (and add a `FIXME(generic_const_exprs)` to be revisited before (M)GCE's stabilization)
* As a matter of fact type alias bounds are enforced in this case because the contained AnonConsts do get checked for well-formedness and crucially they inherit the generics and predicates of their parent item (here: the type alias)
* Remaining commits: Improve the lint `type_alias_bounds` itself
---
Fixes#125789 (sugg diag fix).
Fixes#125709 (wontfix, acknowledgement, sugg diag applic fix).
Fixes#104918 (sugg diag applic fix).
Fixes#100270 (wontfix, acknowledgement, sugg diag applic fix).
Fixes#94398 (true fix).
r? `@compiler-errors` `@oli-obk`
[^1]: From the perspective of the trait solver.
[^2]: Given `type A<T: Trait> = T::Proj;`, the reason why the trait bound "`T: Trait`" gets *seemingly* enforced at usage sites of the type alias `A` is simply because `A<X>` gets expanded to "`<X as Trait>::Proj`" very early on and it's the *expansion* that gets checked for well-formedness, not the type alias reference.
Implement lint against ambiguous negative literals
This PR implements a lint against ambiguous negative literals with a literal and method calls right after it.
## `ambiguous_negative_literals`
(deny-by-default)
The `ambiguous_negative_literals` lint checks for cases that are confusing between a negative literal and a negation that's not part of the literal.
### Example
```rust,compile_fail
-1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1
```
### Explanation
Method calls take precedence over unary precedence. Setting the precedence explicitly makes the code clearer and avoid potential bugs.
<details>
<summary>Old proposed lint</summary>
## `ambiguous_unary_precedence`
(deny-by-default)
The `ambiguous_unary_precedence` lint checks for use the negative unary operator with a literal and method calls.
### Example
```rust
-1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1
```
### Explanation
Unary operations take precedence on binary operations and method calls take precedence over unary precedence. Setting the precedence explicitly makes the code clearer and avoid potential bugs.
</details>
-----
Note: This is a strip down version of https://github.com/rust-lang/rust/pull/117161, without the binary op precedence.
Fixes https://github.com/rust-lang/rust/issues/117155
`@rustbot` labels +I-lang-nominated
cc `@scottmcm`
r? compiler
Change `binary_asm_labels` to only fire on x86 and x86_64
In <https://github.com/rust-lang/rust/pull/126922>, the `binary_asm_labels` lint was added which flags labels such as `0:` and `1:`. Before that change, LLVM was giving a confusing error on x86/x86_64 because of an incorrect interpretation.
However, targets other than x86 and x86_64 never had the error message and have not been a problem. This means that the lint was causing code that previously worked to start failing (e.g. `compiler_builtins`), rather than only providing a more clear messages where there has always been an error.
Adjust the lint to only fire on x86 and x86_64 assembly to avoid this regression.
Also update the help message.
Fixes: https://github.com/rust-lang/rust/issues/127821
The link pointed to a closed issue. Create a new one and point the link
to it.
Also add a help message to hint what change the user could make.
Fixes: https://github.com/rust-lang/rust/issues/127821
add lint for inline asm labels that look like binary
fixes#94426
Due to a bug/feature in LLVM, labels composed of only the digits `0` and `1` can sometimes be confused with binary literals, even if a binary literal would not be valid in that position.
This PR adds detection for such labels and also as a drive-by change, adds a note to cases such as `asm!(include_str!("file"))` that the label that it found came from an expansion of a macro, it wasn't found in the source code.
I expect this PR to upset some people that were using labels `0:` or `1:` without issue because they never hit the case where LLVM got it wrong, but adding a heuristic to the lint to prevent this is not feasible - it would involve writing a whole assembly parser for every target that we have assembly support for.
[zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202024-06-20/near/445870628)
r? ``@estebank``
Implement simple, unstable lint to suggest turning closure-of-async-block into async-closure
We want to eventually suggest people to turn `|| async {}` to `async || {}`. This begins doing that. It's a pretty rudimentary lint, but I wanted to get something down so I wouldn't lose the code.
Tracking:
* #62290