Make the wasm_c_abi future compat warning a hard error
This is the next step in getting rid of the broken C abi for wasm32-unknown-unknown.
The lint was made deny-by-default in https://github.com/rust-lang/rust/pull/129534 3 months ago. This still keeps the `-Zwasm-c-abi` flag set to `legacy` by default. It will be flipped in a future PR.
cc https://github.com/rust-lang/rust/issues/122532
Improve check-cfg expected names diagnostic
This PR improves the check-cfg `allow-same-level` test by ~~normalizing it's output and by~~ adding more context to the test.
It also filters the well known cfgs from the `expected names are` note, as to reduce the size of the diagnostic. Users can still find the full list on the [rustc book](https://doc.rust-lang.org/nightly/rustc/check-cfg.html#well-known-names-and-values), which is reinforced for Cargo users by adding a note in the Cargo check-cfg specific section.
Fixes https://github.com/rust-lang/rust/issues/135995
r? `@jieyouxu`
Forbid usage of `hir` `Infer` const/ty variants in ambiguous contexts
The feature `generic_arg_infer` allows providing `_` as an argument to const generics in order to infer them. This introduces a syntactic ambiguity as to whether generic arguments are type or const arguments. In order to get around this we introduced a fourth `GenericArg` variant, `Infer` used to represent `_` as an argument to generic parameters when we don't know if its a type or a const argument.
This made hir visitors that care about `TyKind::Infer` or `ConstArgKind::Infer` very error prone as checking for `TyKind::Infer`s in `visit_ty` would find *some* type infer arguments but not *all* of them as they would sometimes be lowered to `GenericArg::Infer` instead.
Additionally the `visit_infer` method would previously only visit `GenericArg::Infer` not *all* infers (e.g. `TyKind::Infer`), this made it very easy to override `visit_infer` and expect it to visit all infers when in reality it would only visit *some* infers.
---
This PR aims to fix those issues by making the `TyKind` and `ConstArgKind` types generic over whether the infer types/consts are represented by `Ty/ConstArgKind::Infer` or out of line (e.g. by a `GenericArg::Infer` or accessible by overiding `visit_infer`). We then make HIR Visitors convert all const args and types to the versions where infer vars are stored out of line and call `visit_infer` in cases where a `Ty`/`Const` would previously have had a `Ty/ConstArgKind::Infer` variant:
API Summary
```rust
enum AmbigArg {}
enum Ty/ConstArgKind<Unambig = ()> {
...
Infer(Unambig),
}
impl Ty/ConstArg {
fn try_as_ambig_ty/ct(self) -> Option<Ty/ConstArg<AmbigArg>>;
}
impl Ty/ConstArg<AmbigArg> {
fn as_unambig_ty/ct(self) -> Ty/ConstArg;
}
enum InferKind {
Ty(Ty),
Const(ConstArg),
Ambig(InferArg),
}
trait Visitor {
...
fn visit_ty/const_arg(&mut self, Ty/ConstArg<AmbigArg>) -> Self::Result;
fn visit_infer(&mut self, id: HirId, sp: Span, kind: InferKind) -> Self::Result;
}
// blanket impl'd, not meant to be overriden
trait VisitorExt {
fn visit_ty/const_arg_unambig(&mut self, Ty/ConstArg) -> Self::Result;
}
fn walk_unambig_ty/const_arg(&mut V, Ty/ConstArg) -> Self::Result;
fn walk_ty/const_arg(&mut V, Ty/ConstArg<AmbigArg>) -> Self::Result;
```
The end result is that `visit_infer` visits *all* infer args and is also the *only* way to visit an infer arg, `visit_ty` and `visit_const_arg` can now no longer encounter a `Ty/ConstArgKind::Infer`. Representing this in the type system means that it is now very difficult to mess things up, either accessing `TyKind::Infer` "just works" and you won't miss *some* type infers- or it doesn't work and you have to look at `visit_infer` or some `GenericArg::Infer` which forces you to think about the full complexity involved.
Unfortunately there is no lint right now about explicitly matching on uninhabited variants, I can't find the context for why this is the case 🤷♀️
I'm not convinced the framing of un/ambig ty/consts is necessarily the right one but I'm not sure what would be better. I somewhat like calling them full/partial types based on the fact that `Ty<Partial>`/`Ty<Full>` directly specifies how many of the type kinds are actually represented compared to `Ty<Ambig>` which which leaves that to the reader to figure out based on the logical consequences of it the type being in an ambiguous position.
---
tool changes have been modified in their own commits for easier reviewing by anyone getting cc'd from subtree changes. I also attempted to split out "bug fixes arising from the refactoring" into their own commit so they arent lumped in with a big general refactor commit
Fixes#112110
Skip `if-let-rescope` lint unless requested by migration
Tracked by #124085
Related to https://github.com/rust-lang/rust/pull/131984#issuecomment-2448329667
Given that `if-let-rescope` is a lint to be enabled globally by an edition migration, there is no point in extracting the precise lint level on the HIR expression. This mitigates the performance regression discovered by the earlier perf-run.
cc `@Kobzol` `@rylev` `@traviscross` I propose a `rust-timer` run to measure how much performance that we can recover from the mitigation. 🙇
[AIX] Lint on structs that have a different alignment in AIX's C ABI
This PR adds a linting diagnostic on AIX for repr(C) structs that are required to follow
the power alignment rule. A repr(C) struct needs to follow the power alignment rule if
the struct:
- Has a floating-point data type (greater than 4-bytes) as its first member, or
- The first member of the struct is an aggregate, whose recursively first member is a
floating-point data type (greater than 4-bytes).
The power alignment rule for eligible structs is currently unimplemented, so a linting
diagnostic is produced when such a struct is encountered.
Fix overflows in the implementation of `overflowing_literals` lint's help
This PR fixes two overflow problems that cause the `overflowing_literals` lint to behave incorrectly in some edge cases.
1. When an integer literal is between `i128::MAX` and `u128::MAX`, an overflowing `as` cast can cause the suggested type to be overly small. It's fixed by using checked type conversion and returning `u128` when it's the only choice. (Fixes#135248)
2. When an integer literal is `i128::MIN` but is of a smaller type, an overflowing negation cause the compiler to panic in debug build. Fixed by checking the number size beforehand and `wrapping_neg`. (Fixes#131849)
Edit: extracted the type conversion part into a standalone function to separate the concern of overflowing.
Make sure to mark `IMPL_TRAIT_REDUNDANT_CAPTURES` as `Allow` in edition 2024
I never got sign-off on #127672 for this lint being warn by default in edition 2024, so let's turn downgrade this lint to allow for now.
Should be backported so it ships with the edition.
```@rustbot``` label: +beta-nominated
Remove outdated information in the `unreachable_pub` lint description
As far as I understand the `unreachable_pub` lint hasn't had false-positives since it started using "effective visibilities". Let's remove that warning from the lint description.
r? `@petrochenkov`
This renames variables named `str` to other names, to make sure `str`
always refers to a type.
It's confusing to read code where `str` (or another standard type name)
is used as an identifier. It also produces misleading syntax
highlighting.
This link makes sense because someone who wishes to avoid unusable `pub`
is likely, but not guaranteed, to be interested in avoiding unnameable
types.
Also fixed some grammar problems I noticed in the area.
Fixes#116604.
Provide structured suggestion for `impl Default` of type where all fields have defaults
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:28:1
|
LL | / impl Default for B {
LL | | fn default() -> Self {
LL | | B {
LL | | x: s(),
| | --- this field has a default value
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
help: to avoid divergence in behavior between `Struct { .. }` and `<Struct as Default>::default()`, derive the `Default`
|
LL ~ #[derive(Default)] struct B {
|
```
Note that above the structured suggestion also includes completely removing the manual `impl`, but the rendering doesn't.
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:28:1
|
LL | / impl Default for B {
LL | | fn default() -> Self {
LL | | B {
LL | | x: s(),
| | --- this field has a default value
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
help: to avoid divergence in behavior between `Struct { .. }` and `<Struct as Default>::default()`, derive the `Default`
|
LL ~ #[derive(Default)] struct B {
|
```
Note that above the structured suggestion also includes completely removing the manual `impl`, but the rendering doesn't.
Implement `default_overrides_default_fields` lint
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
r? `@compiler-errors`
This is a simpler version of #134441, detecting the simpler case when a field with a default should have not been specified in the manual `Default::default()`, instead using `..` for it. It doesn't provide any suggestions, nor the checks for "equivalences" nor whether the value used in the imp being used would be suitable as a default field value.
Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead:
```
error: `Default` impl doesn't use the declared default field values
--> $DIR/manual-default-impl-could-be-derived.rs:14:1
|
LL | / impl Default for A {
LL | | fn default() -> Self {
LL | | A {
LL | | y: 0,
| | - this field has a default value
... |
LL | | }
| |_^
|
= help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time
note: the lint level is defined here
--> $DIR/manual-default-impl-could-be-derived.rs:5:9
|
LL | #![deny(default_overrides_default_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
Begin to implement type system layer of unsafe binders
Mostly TODOs, but there's a lot of match arms that are basically just noops so I wanted to split these out before I put up the MIR lowering/projection part of this logic.
r? oli-obk
Tracking:
- https://github.com/rust-lang/rust/issues/130516
Also lint on option of function pointer comparisons
This PR is the first part of #134536, ie. the linting on `Option<{fn ptr}>` in the `unpredictable_function_pointer_comparisons` lint, which isn't part of the lang nomination that the second part is going trough, and so should be able to be approved independently.
Related to https://github.com/rust-lang/rust/issues/134527
r? `@compiler-errors`
cleanup region handling: add `LateParamRegionKind`
The second commit is to enable a split between `BoundRegionKind` and `LateParamRegionKind`, by avoiding `BoundRegionKind` where it isn't necessary.
The third comment then adds `LateParamRegionKind` to avoid having the same late-param region for separate bound regions. This fixes#124021.
r? `@compiler-errors`
Point at lint name instead of whole attr for gated lints
```
warning: unknown lint: `test_unstable_lint`
--> $DIR/warn-unknown-unstable-lint-inline.rs:4:10
|
LL | #![allow(test_unstable_lint, another_unstable_lint)]
| ^^^^^^^^^^^^^^^^^^
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
note: the lint level is defined here
--> $DIR/warn-unknown-unstable-lint-inline.rs:3:9
|
LL | #![warn(unknown_lints)]
| ^^^^^^^^^^^^^
warning: unknown lint: `test_unstable_lint`
--> $DIR/warn-unknown-unstable-lint-inline.rs:4:29
|
LL | #![allow(test_unstable_lint, another_unstable_lint)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the `another_unstable_lint` lint is unstable
= help: add `#![feature(another_unstable_lint)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
```
This is particularly relevant when there are multiple lints in the same `warn` attribute. Pointing at the smaller span makes it clearer which one the warning is complaining about.
```
warning: unknown lint: `test_unstable_lint`
--> $DIR/warn-unknown-unstable-lint-inline.rs:4:10
|
LL | #![allow(test_unstable_lint, another_unstable_lint)]
| ^^^^^^^^^^^^^^^^^^
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
note: the lint level is defined here
--> $DIR/warn-unknown-unstable-lint-inline.rs:3:9
|
LL | #![warn(unknown_lints)]
| ^^^^^^^^^^^^^
warning: unknown lint: `test_unstable_lint`
--> $DIR/warn-unknown-unstable-lint-inline.rs:4:29
|
LL | #![allow(test_unstable_lint, another_unstable_lint)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the `test_unstable_lint` lint is unstable
= help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
note: the lint level is defined here
--> $DIR/warn-unknown-unstable-lint-inline.rs:3:9
|
LL | #![warn(unknown_lints)]
| ^^^^^^^^^^^^^
```
This is particularly relevant when there are multiple lints in the same `warn` attribute. Pointing at the smaller span makes it clearer which one the warning is complaining about.
Use field init shorthand where possible
Field init shorthand allows writing initializers like `tcx: tcx` as
`tcx`. The compiler already uses it extensively. Fix the last few places
where it isn't yet used.
EDIT: this PR also updates `rustfmt.toml` to set
`use_field_init_shorthand = true`.
Merge some patterns together
just something I noticed while browsing code. No change in functionality, deduplicates the 100% equal match arms by creating one big or pattern
Re-export more `rustc_span::symbol` things from `rustc_span`.
`rustc_span::symbol` defines some things that are re-exported from `rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some closely related things such as `Ident` and `kw`. So you can do `use rustc_span::{Symbol, sym}` but you have to do `use rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good reason.
This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`, and changes many `rustc_span::symbol::` qualifiers to `rustc_span::`. This is a 300+ net line of code reduction, mostly because many files with two `use rustc_span` items can be reduced to one.
r? `@jieyouxu`
`rustc_span::symbol` defines some things that are re-exported from
`rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some
closely related things such as `Ident` and `kw`. So you can do `use
rustc_span::{Symbol, sym}` but you have to do `use
rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good
reason.
This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`,
and changes many `rustc_span::symbol::` qualifiers in `compiler/` to
`rustc_span::`. This is a 200+ net line of code reduction, mostly
because many files with two `use rustc_span` items can be reduced to
one.
Because `TokenStreamIter` is a much better name for a `TokenStream`
iterator. Also rename the `TokenStream::trees` method as
`TokenStream::iter`, and some local variables.
Field init shorthand allows writing initializers like `tcx: tcx` as
`tcx`. The compiler already uses it extensively. Fix the last few places
where it isn't yet used.
Split up attribute parsing code and move data types to `rustc_attr_data_structures`
This change renames `rustc_attr` to `rustc_attr_parsing`, and splits up the parsing code. At the same time, all the data types used move to `rustc_attr_data_structures`. This is in preparation of also having a third crate: `rustc_attr_validation`
I initially envisioned this as two separate PRs, but I think doing it in one go reduces the number of ways others would have to rebase their changes on this. However, I can still split them.
r? `@oli-obk` (we already discussed how this is a first step in a larger plan)
For a more detailed plan on how attributes are going to change, see https://github.com/rust-lang/rust/issues/131229
Edit: this looks like a giant PR, but the changes are actually rather trivial. Each commit is reviewable on its own, and mostly moves code around. No new logic is added.
Use links to edition guide for edition migrations
This switches the migration lints for the 2024 edition to point to the edition guide documentation instead of the tracking issues. I expect the documentation should be easier to understand for a user, compared to most of the issues which don't have any direct information, and can be a bit confusing to navigate, or have outdated information.
`CheckAttrVisitor::check_doc_keyword` checks `#[doc(keyword = "..")]`
attributes to ensure they are on an empty module, and that the value is
a non-empty identifier.
The `rustc::existing_doc_keyword` lint checks these attributes to ensure
that the value is the name of a keyword.
It's silly to have two different checking mechanisms for these
attributes. This commit does the following.
- Changes `check_doc_keyword` to check that the value is the name of a
keyword (avoiding the need for the identifier check, which removes a
dependency on `rustc_lexer`).
- Removes the lint.
- Updates tests accordingly.
There is one hack: the `SelfTy` FIXME case used to used to be handled by
disabling the lint, but now is handled with a special case in
`is_doc_keyword`. That hack will go away if/when the FIXME is fixed.
Co-Authored-By: Guillaume Gomez <guillaume1.gomez@gmail.com>
Update spelling of "referring"
I noticed that `referring` was spelled incorrectly in the output of `unexpected 'cfg' condition name` warnings; it looks like it was also incorrectly spelled in a doc comment. I've update both instances.
Fix `trimmed_def_paths` ICE in the function ptr comparison lint
This PR fixes an ICE with `trimmed_def_paths` ICE in the function ptr comparison lint, specifically when pretty-printing user types but then not using the resulting pretty-printing.
Fixes#134345
r? `@saethlin`
Hir attributes
This PR needs some explanation, it's somewhat large.
- This is step one as described in https://github.com/rust-lang/compiler-team/issues/796. I've added a new `hir::Attribute` which is a lowered version of `ast::Attribute`. Right now, this has few concrete effects, however every place that after this PR parses a `hir::Attribute` should later get a pre-parsed attribute as described in https://github.com/rust-lang/compiler-team/issues/796 and transitively https://github.com/rust-lang/rust/issues/131229.
- an extension trait `AttributeExt` is added, which is implemented for both `ast::Attribute` and `hir::Atribute`. This makes `hir::Attributes` mostly compatible with code that used to parse `ast::Attribute`. All its methods are also added as inherent methods to avoid having to import the trait everywhere in the compiler.
- Incremental can not not hash `ast::Attribute` at all.
Add external macros specific diagnostics for check-cfg
This PR adds specific check-cfg diagnostics for unexpected cfg in external macros.
As well as hiding the some of the Cargo specific help/suggestions as they distraction for external macros and are generally not the right solution.
Follow-up to #132577
`@rustbot` label +L-unexpected_cfgs
r? compiler
Add AST support for unsafe binders
I'm splitting up #130514 into pieces. It's impossible for me to keep up with a huge PR like that. I'll land type system support for this next, probably w/o MIR lowering, which will come later.
r? `@oli-obk`
cc `@BoxyUwU` and `@lcnr` who also may want to look at this, though this PR doesn't do too much yet
Keep track of parse errors in `mod`s and don't emit resolve errors for paths involving them
When we expand a `mod foo;` and parse `foo.rs`, we now track whether that file had an unrecovered parse error that reached the end of the file. If so, we keep that information around in the HIR and mark its `DefId` in the `Resolver`. When resolving a path like `foo::bar`, we do not emit any errors for "`bar` not found in `foo`", as we know that the parse error might have caused `bar` to not be parsed and accounted for.
When this happens in an existing project, every path referencing `foo` would be an irrelevant compile error. Instead, we now skip emitting anything until `foo.rs` is fixed. Tellingly enough, we didn't have any test for errors caused by expansion of `mod`s with parse errors.
Fix https://github.com/rust-lang/rust/issues/97734.
allow `symbol_intern_string_literal` lint in test modules
Since #133545, `x check compiler --stage 1` no longer works because compiler test modules trigger `symbol_intern_string_literal` lint errors. Bootstrap shouldn't control when to ignore or enable this lint in the compiler tree (using `Kind != Test` was ineffective for obvious reasons).
Also, conditionally adding this rustflag invalidates the build cache between `x test` and other commands.
This PR removes the `Kind` check from bootstrap and handles it directly in the compiler tree in a more natural way.
When we expand a `mod foo;` and parse `foo.rs`, we now track whether that file had an unrecovered parse error that reached the end of the file. If so, we keep that information around. When resolving a path like `foo::bar`, we do not emit any errors for "`bar` not found in `foo`", as we know that the parse error might have caused `bar` to not be parsed and accounted for.
When this happens in an existing project, every path referencing `foo` would be an irrelevant compile error. Instead, we now skip emitting anything until `foo.rs` is fixed. Tellingly enough, we didn't have any test for errors caused by `mod` expansion.
Fix#97734.
Make `Copy` unsafe to implement for ADTs with `unsafe` fields
As a rule, the application of `unsafe` to a declaration requires that use-sites of that declaration also entail `unsafe`. For example, a field declared `unsafe` may only be read in the lexical context of an `unsafe` block.
For nearly all safe traits, the safety obligations of fields are explicitly discharged when they are mentioned in method definitions. For example, idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields will require `unsafe` to clone those fields.
Prior to this commit, `Copy` violated this rule. The trait is marked safe, and although it has no explicit methods, its implementation permits reads of `Self`.
This commit resolves this by making `Copy` conditionally safe to implement. It remains safe to implement for ADTs without unsafe fields, but unsafe to implement for ADTs with unsafe fields.
Tracking: #132922
r? ```@compiler-errors```
Actually walk into lifetimes and attrs in `EarlyContextAndPass`
Visitors that don't also call `walk_*` are kinda a footgun...
I believe all the other early lint functions walk into their types correctly at this point.
As a rule, the application of `unsafe` to a declaration requires that use-sites
of that declaration also require `unsafe`. For example, a field declared
`unsafe` may only be read in the lexical context of an `unsafe` block.
For nearly all safe traits, the safety obligations of fields are explicitly
discharged when they are mentioned in method definitions. For example,
idiomatically implementing `Clone` (a safe trait) for a type with unsafe fields
will require `unsafe` to clone those fields.
Prior to this commit, `Copy` violated this rule. The trait is marked safe, and
although it has no explicit methods, its implementation permits reads of `Self`.
This commit resolves this by making `Copy` conditionally safe to implement. It
remains safe to implement for ADTs without unsafe fields, but unsafe to
implement for ADTs with unsafe fields.
Tracking: #132922