Commit Graph

480 Commits

Author SHA1 Message Date
Eric Huss
924ded6b72 Clean up some comments on lint implementation 2024-10-27 04:30:51 -07:00
bors
4d88de2acd Auto merge of #125116 - blyxyas:ignore-allowed-lints-final, r=cjgillot
(Big performance change) Do not run lints that cannot emit

Before this change, adding a lint was a difficult matter because it always had some overhead involved. This was because all lints would run, no matter their default level, or if the user had `#![allow]`ed them. This PR changes that. This change would improve both the Rust lint infrastructure and Clippy, but Clippy will see the most benefit, as it has about 900 registered lints (and growing!)

So yeah, with this little patch we filter all lints pre-linting, and remove any lint that is either:
- Manually `#![allow]`ed in the whole crate,
- Allowed in the command line, or
- Not manually enabled with `#[warn]` or similar, and its default level is `Allow`

As some lints **need** to run, this PR also adds **loadbearing lints**. On a lint declaration, you can use the ``@eval_always` = true` marker to label it as loadbearing. A loadbearing lint will never be filtered (it will always run)

Fixes #106983
2024-10-26 16:37:43 +00:00
Matthias Krüger
8207d89b5e
Rollup merge of #132114 - jieyouxu:features-bundle, r=fee1-dead
Use `Enabled{Lang,Lib}Feature`  instead of n-tuples

Instead of passing around e.g. `(gate_name, attr_span, stable_since)` 3-tuples for enabled lang features or `(gate_name, attr_span)` 2-tuples for enabled lib features, use `Enabled{Lang,Lib}Feature` structs with named fields.

Also did some minor code-golfing of involved iterator chains to hopefully make them easier to follow.

Follow-up to https://github.com/rust-lang/rust/pull/132098#issuecomment-2434523431 cc `@RalfJung.`
2024-10-26 06:29:47 +02:00
Matthias Krüger
280790b9a1
Rollup merge of #132106 - maxcabrajac:ident_ref, r=petrochenkov
Pass Ident by reference in ast Visitor

`MutVisitor`'s version of `visit_ident` passes around `&Ident`, but `Visitor` copies `Ident`. This PR changes that

r? `@petrochenkov`

related to #128974
2024-10-25 20:33:11 +02:00
许杰友 Jieyou Xu (Joe)
3528149f73 Introduce Enabled{Lang,Lib}Feature
Instead of passing around random n-tuples of e.g. `(gate_name, attr_sp,
since)`.
2024-10-25 10:30:37 +08:00
bors
1d4a7670d4 Auto merge of #131985 - compiler-errors:const-pred, r=fee1-dead
Represent trait constness as a distinct predicate

cc `@rust-lang/project-const-traits`
r? `@ghost` for now

Also mirrored everything that is written below on this hackmd here: https://hackmd.io/`@compiler-errors/r12zoixg1l`

# Tl;dr:

* This PR removes the bulk of the old effect desugaring.
* This PR reimplements most of the effect desugaring as a new predicate and set of a couple queries. I believe it majorly simplifies the implementation and allows us to move forward more easily on its implementation.

I'm putting this up both as a request for comments and a vibe-check, but also as a legitimate implementation that I'd like to see land (though no rush of course on that last part).

## Background

### Early days

Once upon a time, we represented trait constness in the param-env and in `TraitPredicate`. This was very difficult to implement correctly; it had bugs and was also incomplete; I don't think this was anyone's fault though, it was just the limit of experimental knowledge we had at that point.

Dealing with `~const` within predicates themselves meant dealing with constness all throughout the trait solver. This was difficult to keep track of, and afaict was not handled well with all the corners of candidate assembly.

Specifically, we had to (in various places) remap constness according to the param-env constness:

574b64a97f/compiler/rustc_trait_selection/src/traits/select/mod.rs (L1498)

This was annoying and manual and also error prone.

### Beginning of the effects desugaring

Later on, #113210 reimplemented a new desugaring for const traits via a `<const HOST: bool>` predicate. This essentially "reified" the const checking and separated it from any of the remapping or separate tracking in param-envs. For example, if I was in a const-if-const environment, but I wanted to call a trait that was non-const, this reification would turn the constness mismatch into a simple *type* mismatch of the effect parameter.

While this was a monumental step towards straightening out const trait checking in the trait system, it had its own issues, since that meant that the constness of a trait (or any item within it, like an associated type) was *early-bound*. This essentially meant that `<T as Trait>::Assoc` was *distinct* from `<T as ~const Trait>::Assoc`, which was bad.

### Associated-type bound based effects desugaring

After this, #120639 implemented a new effects desugaring. This used an associated type to more clearly represent the fact that the constness is not an input parameter of a trait, but a property that could be computed of a impl. The write-up linked in that PR explains it better than I could.

However, I feel like it really reached the limits of what can comfortably be expressed in terms of associated type and trait calculus. Also, `<const HOST: bool>` remains a synthetic const parameter, which is observable in nested items like RPITs and closures, and comes with tons of its own hacks in the astconv and middle layer.

For example, there are pieces of unintuitive code that are needed to represent semantics like elaboration, and eventually will be needed to make error reporting intuitive, and hopefully in the future assist us in implementing built-in traits (eventually we'll want something like `~const Fn` trait bounds!).

elaboration hack: 8069f8d17a/compiler/rustc_type_ir/src/elaborate.rs (L133-L195)

trait bound remapping hack for diagnostics: 8069f8d17a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs (L2370-L2413)

I want to be clear that I don't think this is a issue of implementation quality or anything like that; I think it's simply a very clear sign that we're using types and traits in a way that they're not fundamentally supposed to be used, especially given that constness deserves to be represented as a first-class concept.

### What now?

This PR implements a new desugaring for const traits. Specifically, it introduces a `HostEffect` predicate to represent the obligation an impl is const, rather than using associated type bounds and the compat trait that exists for effects today.

### `HostEffect` predicate

A `HostEffect` clause has two parts -- the `TraitRef` we're trying to prove, and a `HostPolarity::{Maybe, Const}`.

`HostPolarity::Const` corresponds to `T: const Trait` bounds, which must *always* be proven as const, and which can be written in any context. These are lowered directly into the predicates of an item, since they're not "context-specific".

On the other hand, `HostPolarity::Maybe` corresponds to `T: ~const Trait` bounds which must only exist in a conditionally-const context like a method in a `#[const_trait]`, or a `const fn` free function. We do not lower these immediately into the predicates of an item; instead, we collect them into a new query called the **`const_conditions`**. These are the set of trait refs that we need to prove have const implementations for an item to be const.

Notably, they're represented as bare (poly) trait refs because they are meant to be paired back together with a `HostPolarity` when they're being registered in typeck (see next section).

For example, given:

```rust
const fn foo<T: ~const A + const B>() {}
```

`foo`'s const conditions would contain `T: A`, but not `T: B`. On the flip side, foo's predicates (`predicates_of`) query would contain `HostEffect(T: B, HostPolarity::Const)` but not `HostEffect(T: A, HostPolarity::Maybe)` since we don't need to prove that predicate in a non-const environment (and it's not even the right predicate to prove in an unconditionally const environment).

### Type checking const bodies

When type checking bodies in HIR, when we encounter a call expression, we additionally register the callee item's const conditions with the `HostPolarity` from the body we're typechecking (`Const` for unconditionally const things like `const`/`static` items, and `Maybe` for conditionally const things like const fns; and we don't register `HostPolarity` predicates for non-const bodies).

When type-checking a conditionally const body, we augment its param-env with `HostEffect(..., Maybe)` predicates.

### Checking that const impls are WF

We extend the logic in `compare_method_predicate_entailment` to also check the const-conditions of the impl method, to make sure that we error for:

```rust
#[const_trait] Bar {}
#[const_trait] trait Foo {
    fn method<T: Bar>();
}

impl Foo for () {
    fn method<T: ~const Bar>() {} // stronger assumption!
}
```

We also extend the WF check for impls to register the const conditions of the trait that is being implemented. This is to make sure we error for:

```rust
#[const_trait] trait Bar {}
#[const_trait] trait Foo<T> where T: ~const Bar {}

impl<T> const Foo<T> for () {}
//~^ `T: ~const Bar` is missing!
```

### Proving a `HostEffect` predicate

We have several ways of proving a `HostEffect` predicate:

1. Matching a `HostEffect` predicate from the param-env
2. From an impl - we do impl selection very similar to confirming a trait goal, except we filter for only const impls, and we additionally register the impl's const conditions (i.e. the impl's `~const` where clauses).

Later I expect that we will add more built-in implementations for things like `Fn`.

## What next?

After this PR, I'd like to split out the work more so it can proceed in parallel and probably amongst others that are not me.

* Register `HostEffect` goal for places in HIR typeck that correspond to call terminators, like autoderef.
* Make traits in libstd const again.
    * Probably need to impl host effect preds in old solver.
* Implement built-in `HostEffect` rules for traits like `Fn`.
* Rip out const checking from MIR altogether.

## So what?

This ends up being super convenient basically everywhere in the compiler. Due to the design of the new trait solver, we end up having an almost parallel structure to the existing trait and projection predicates for assembling `HostEffect` predicates; adding new candidates and especially new built-in implementations is now basically trivial, and it's quite straightforward to understand the confirmation logic for these predicates.

Same with diagnostics reporting; since we have predicates which represent the obligation to prove an impl is const, we can simplify and make these diagnostics richer without having to write a ton of logic to intercept and rewrite the existing `Compat` trait errors.

Finally, it gives us a much more straightforward path for supporting the const effect on the old trait solver. I'm personally quite passionate about getting const trait support into the hands of users without having to wait until the new solver lands[^1], so I think after this PR lands we can begin to gauge how difficult it would be to implement constness in the old trait solver too. This PR will not do this yet.

[^1]: Though this is not a prerequisite or by any means the only justification for this PR.
2024-10-24 17:33:42 +00:00
maxcabrajac
64a3451835 Pass Ident by reference in ast Visitor 2024-10-24 11:10:49 -03:00
Michael Goulet
cde29b9ec9 Implement const effect predicate in new solver 2024-10-24 09:46:36 +00:00
Matthias Krüger
93bf791e8b
Rollup merge of #129248 - compiler-errors:raw-ref-deref, r=nnethercote
Taking a raw ref (`&raw (const|mut)`) of a deref of pointer (`*ptr`) is always safe

T-opsem decided in https://github.com/rust-lang/reference/pull/1387 that `*ptr` is only unsafe if the place is accessed. This means that taking a raw ref of a deref expr is always safe, since it doesn't constitute a read.

This also relaxes the `DEREF_NULLPTR` lint to stop warning in the case of raw ref of a deref'd nullptr, and updates its docs to reflect that change in the UB specification.

This does not change the behavior of `addr_of!((*ptr).field)`, since field projections still require the projection is in-bounds.

I'm on the fence whether this requires an FCP, since it's something that is guaranteed by the reference you could ostensibly call this a bugfix since we were counting truly safe operations as unsafe. Perhaps someone on opsem has a strong opinion? cc `@rust-lang/opsem`
2024-10-24 10:35:39 +02:00
Ralf Jung
ad3991d303 nightly feature tracking: get rid of the per-feature bool fields 2024-10-23 09:14:41 +01:00
Ralf Jung
1381773e01 make some rustc_feature internals private, and ensure invariants with debug assertions 2024-10-22 07:37:55 +01:00
Ralf Jung
46ce5cbf33 terminology: #[feature] *enables* a feature (instead of "declaring" or "activating" it) 2024-10-22 07:37:54 +01:00
Michael Goulet
e83e4e8112 Get rid of const eval_* and try_eval_* helpers 2024-10-19 18:07:35 +00:00
blyxyas
637d5cc56f Remove module passes filtering 2024-10-19 16:20:51 +02:00
blyxyas
71b4d108c7 Follow review comments (optimize the filtering) 2024-10-19 16:20:33 +02:00
blyxyas
b4da058595 Do not run lints that cannot emit
Before this change, adding a lint was a difficult matter
because it always had some overhead involved. This was
because all lints would run, no matter their default level,
or if the user had #![allow]ed them. This PR changes that
2024-10-19 16:19:44 +02:00
Michael Goulet
367183bc0c Don't emit null pointer lint for raw ref of null deref 2024-10-06 22:36:51 -04:00
Michael Goulet
c682aa162b Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
Michael Goulet
954419aab0 Simplify some nested if statements 2024-09-11 13:45:23 -04:00
bors
33855f80d4 Auto merge of #130025 - Urgau:missing_docs-expect, r=petrochenkov
Also emit `missing_docs` lint with `--test` to fulfil expectations

This PR removes the "test harness" suppression of the `missing_docs` lint to be able to fulfil `#[expect]` (expectations) as it is now "relevant".

I think the goal was to maybe avoid false-positive while linting on public items under `#[cfg(test)]` but with effective visibility we should no longer have any false-positive.

Another possibility would be to query the lint level and only emit the lint if it's of expect level, but that is even more hacky.

Fixes https://github.com/rust-lang/rust/issues/130021

try-job: x86_64-gnu-aux
2024-09-10 14:54:09 +00:00
Michael Goulet
5054e8cba8 Lint against keyword lifetimes in keyword_idents 2024-09-06 10:32:48 -04:00
Urgau
7dd1be1d0d Also emit missing_docs lint with --test to fulfill expectations 2024-09-06 12:20:36 +02:00
Camille GILLOT
c51f2d24d1 Use a LocalDefId in ResolvedArg. 2024-08-22 01:17:01 +00:00
Michael Goulet
25ff9b6bcb Use bool in favor of Option<()> for diagnostics 2024-08-21 01:31:11 -04:00
Nicholas Nethercote
7923b20dd9 Use impl PartialEq<TokenKind> for Token more.
This lets us compare a `Token` with a `TokenKind`. It's used a lot, but
can be used even more, avoiding the need for some `.kind` uses.
2024-08-14 16:37:09 +10:00
Michael Howell
4dc13c5471 diagnostics: do not warn when a lifetime bound infers itself 2024-08-09 16:16:16 -07:00
Nicholas Nethercote
84ac80f192 Reformat use declarations.
The previous commit updated `rustfmt.toml` appropriately. This commit is
the outcome of running `x fmt --all` with the new formatting options.
2024-07-29 08:26:52 +10:00
León Orell Valerian Liehr
5859dff742
Update the description of lint type_alias_bounds 2024-07-23 01:49:00 +02:00
León Orell Valerian Liehr
d67b61637e
Make lint type_alias_bounds's removal sugg maybe-incorrect if the RHS contains shorthand assoc tys 2024-07-23 01:48:58 +02:00
León Orell Valerian Liehr
fdf8f024ad
Improve the impl and diag output of lint type_alias_bounds 2024-07-23 01:48:03 +02:00
León Orell Valerian Liehr
a8b3dfd253
Suppress lint type_alias_bounds for ty aliases containing const projections under GCE 2024-07-23 01:26:26 +02:00
León Orell Valerian Liehr
63a54d93be
Don't suppress lint type_alias_bounds for ty aliases containing inherent assoc tys 2024-07-23 01:26:26 +02:00
Trevor Gross
5686720a57 Update the binary_asm_label documentation
Disable a test that now only passes on x86 and make the link point to
the new (open) LLVM bug.
2024-07-19 01:21:15 -05:00
Trevor Gross
9387a7523e 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.
2024-07-18 15:00:56 -05:00
Jubilee
2e0591b1e9
Rollup merge of #127535 - spastorino:unsafe_code-unsafe_extern_blocks, r=oli-obk
Fire unsafe_code lint on unsafe extern blocks

Fixes #126738
2024-07-12 13:47:08 -07:00
Santiago Pastorino
a3ef94e80e
Fire unsafe_code lint on unsafe extern blocks 2024-07-09 17:35:51 -03:00
asquared31415
87856c4461 add lint for inline asm labels that look like binary 2024-07-09 01:23:49 +00:00
Nicholas Nethercote
c053e8939b Remove the box_pointers lint.
As the comment says, this lint "is mostly historical, and not
particularly useful". It's not worth keeping it around.
2024-06-27 08:55:28 +10:00
许杰友 Jieyou Xu (Joe)
ecc0046fb6
Rollup merge of #125659 - tbu-:pr_rm_isize, r=pnkfelix
Remove usage of `isize` in example

`isize` is a rare integer type, replace it with a more common one.
2024-06-11 21:27:45 +01:00
Jubilee
6a42df7517
Rollup merge of #126040 - Urgau:unreachable_pub-fields-less, r=petrochenkov
Don't warn on fields in the `unreachable_pub` lint

This PR restrict the `unreachable_pub` lint by not linting on `pub` fields of `pub(restricted)` structs and unions. This is done because that can quickly clutter the code for an uncertain value, in particular since the "real" visibility is defined by the parent (the struct it-self).

This is meant to address one of the last concern of the `unreachable_pub` lint.

r? ``@petrochenkov``
2024-06-06 21:10:10 -07:00
Urgau
89d86ae5bd Don't warn on fields in the unreachable_pub lint 2024-06-06 19:07:05 +02:00
Nicholas Nethercote
22ca74f2b0 Fix up comments.
Wrap overly long ones, etc.
2024-06-03 08:44:33 +10:00
Tobias Bucher
eb0ed28ced Remove usage of isize in example
`isize` is a rare integer type, replace it with a more common one.
2024-05-28 15:31:26 +02:00
Boxy
ed8e436916 move generics_of call outside of iter 2024-05-24 20:15:54 +01:00
Boxy
fe2d7794ca Remove DefId from EarlyParamRegion (tedium/diagnostics) 2024-05-24 18:06:53 +01:00
bors
8679004993 Auto merge of #125434 - nnethercote:rm-more-extern-tracing, r=jackh726
Remove more `#[macro_use] extern crate tracing`

Because explicit importing of macros via use items is nicer (more standard and readable) than implicit importing via `#[macro_use]`. Continuing the work from #124511 and #124914.

r? `@jackh726`
2024-05-23 21:36:54 +00:00
Nicholas Nethercote
c7da1a5bb8 Remove #[macro_use] extern crate tracing from rustc_lint. 2024-05-23 18:02:17 +10:00
Michael Goulet
8369dbba43 Use correct param-env in MissingCopyImplementations 2024-05-22 12:46:08 -04:00
Xiretza
bac6b6248b Convert NAMED_ASM_LABELS lint to diag struct 2024-05-21 20:11:42 +00:00
bors
eb1a5c9bb3 Auto merge of #125077 - spastorino:add-new-fnsafety-enum2, r=jackh726
Rename Unsafe to Safety

Alternative to #124455, which is to just have one Safety enum to use everywhere, this opens the posibility of adding `ast::Safety::Safe` that's useful for unsafe extern blocks.

This leaves us today with:

```rust
enum ast::Safety {
    Unsafe(Span),
    Default,
    // Safe (going to be added for unsafe extern blocks)
}

enum hir::Safety {
    Unsafe,
    Safe,
}
```

We would convert from `ast::Safety::Default` into the right Safety level according the context.
2024-05-18 19:35:24 +00:00