Commit graph

508 commits

Author SHA1 Message Date
Nicholas Nethercote
f86f7ad5f2 Move some Map methods onto TyCtxt.
The end goal is to eliminate `Map` altogether.

I added a `hir_` prefix to all of them, that seemed simplest. The
exceptions are `module_items` which became `hir_module_free_items` because
there was already a `hir_module_items`, and `items` which became
`hir_free_items` for consistency with `hir_module_free_items`.
2025-02-17 13:21:02 +11:00
Bastian Kersting
f842ee8245 Rename rustc_middle::Ty::is_unsafe_ptr to is_raw_ptr
The wording unsafe pointer is less common and not mentioned in a lot of
places, instead this is usually called a "raw pointer". For the sake of
uniformity, we rename this method.
This came up during the review of
https://github.com/rust-lang/rust/pull/134424.
2025-02-10 12:49:18 +00:00
bjorn3
1fcae03369 Rustfmt 2025-02-08 22:12:13 +00:00
Nicholas Nethercote
06090e89d3 Convert two rustc_middle::lint functions to Span methods.
`rustc_middle` is a huge crate and it's always good to move stuff out of
it. There are lots of similar methods already on `Span`, so these two
functions, `in_external_macro` and `is_from_async_await`, fit right in.
The diff is big because `in_external_macro` is used a lot by clippy
lints.
2025-02-02 13:57:34 +11:00
Celina G. Val
c22a27130d Refactor FnKind variant to hold &Fn 2025-01-28 11:22:25 -08:00
Kalle Wachsmuth
c1dcbebd0b
implement lint double_negations 2025-01-26 12:18:33 +01:00
Kalle Wachsmuth
d810d426a4
unrelated cleanup 2025-01-26 12:15:11 +01:00
Ralf Jung
a99778c839 remove long-deprecated no-op attributes no_start and crate_id 2025-01-21 17:29:06 -07:00
Matthias Krüger
a1cadeab68
Rollup merge of #135269 - estebank:unneeded-into, r=compiler-errors
Remove some unnecessary `.into()` calls
2025-01-09 09:05:10 +01:00
Esteban Küber
eb917ea24d Remove some unnecessary .into() calls 2025-01-08 21:19:28 +00:00
Urgau
56cba09d1e Remove outdated information in the unreachable_pub lint description 2025-01-07 19:07:06 +01:00
Kevin Reid
2a96478dd8 Mention unnameable_types in unreachable_pub documentation.
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.
2025-01-05 17:13:33 -08:00
Ralf Jung
be65012aa3 turn hir::ItemKind::Fn into a named-field variant 2025-01-04 11:35:31 +01:00
许杰友 Jieyou Xu (Joe)
477f222b02
Rollup merge of #134161 - nnethercote:overhaul-token-cursors, r=spastorino
Overhaul token cursors

Some nice cleanups here.

r? `````@davidtwco`````
2024-12-18 22:56:53 +08:00
Nicholas Nethercote
2620eb42d7 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 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.
2024-12-18 13:38:53 +11:00
Nicholas Nethercote
809975c94a Rename RefTokenTreeCursor.
Because `TokenStreamIter` is a much better name for a `TokenStream`
iterator. Also rename the `TokenStream::trees` method as
`TokenStream::iter`, and some local variables.
2024-12-18 10:39:07 +11:00
Eric Huss
3e80697972 Use links to edition guide for edition migrations 2024-12-15 20:28:16 -08:00
Jonathan Dönszelmann
d50c0a5480
Add hir::Attribute 2024-12-15 19:18:46 +01:00
Esteban Küber
69fb612608 Keep track of parse errors in mods 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. 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.
2024-12-10 18:17:24 +00:00
Jack Wrenn
3ce35a4ec5 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 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
2024-12-07 20:50:00 +00:00
lcnr
e089bead32 remove Ty::is_copy_modulo_regions 2024-12-02 13:57:56 +01:00
Frank King
161221da9e Refactor where predicates, and reserve for attributes support 2024-11-25 16:38:35 +08:00
lcnr
948cec0fad move fn is_item_raw to TypingEnv 2024-11-19 18:06:20 +01:00
lcnr
9cba14b95b use TypingEnv when no infcx is available
the behavior of the type system not only depends on the current
assumptions, but also the currentnphase of the compiler. This is
mostly necessary as we need to decide whether and how to reveal
opaque types. We track this via the `TypingMode`.
2024-11-18 10:38:56 +01:00
Urgau
0bc622d251 Prefer pub(super) in unreachable_pub lint suggestion 2024-11-04 19:09:40 +01:00
Jubilee
847b6fe6b0
Rollup merge of #132246 - workingjubilee:campaign-on-irform, r=compiler-errors
Rename `rustc_abi::Abi` to `BackendRepr`

Remove the confabulation of `rustc_abi::Abi` with what "ABI" actually means by renaming it to `BackendRepr`, and rename `Abi::Aggregate` to `BackendRepr::Memory`. The type never actually represented how things are passed, as that has to have `PassMode` considered, at minimum, but rather it just is how we represented some things to the backend. This conflation arose because LLVM, the primary backend at the time, would lower certain IR forms using certain ABIs. Even that only somewhat was true, as it broke down when one ventured significantly afield of what is described by the System V AMD64 ABI either by using different architectures, ABI-modifying IR annotations, the same architecture **with different ISA extensions enabled**, or other... unexpected delights.

Unfortunately both names are still somewhat of a misnomer right now, as people have written code for years based on this misunderstanding. Still, their original names are even moreso, and for better or worse, this backend code hasn't received as much maintenance as the rest of the compiler, lately. Actually arriving at a correct end-state will simply require us to disentangle a lot of code in order to fix, much of it pointlessly repeated in several places. Thus this is not an "actual fix", just a way to deflect further misunderstandings.
2024-10-30 14:01:37 -07:00
Jubilee Young
7086dd83cc compiler: rustc_abi::Abi => BackendRepr
The initial naming of "Abi" was an awful mistake, conveying wrong ideas
about how psABIs worked and even more about what the enum meant.
It was only meant to represent the way the value would be described to
a codegen backend as it was lowered to that intermediate representation.
It was never meant to mean anything about the actual psABI handling!
The conflation is because LLVM typically will associate a certain form
with a certain ABI, but even that does not hold when the special cases
that actually exist arise, plus the IR annotations that modify the ABI.

Reframe `rustc_abi::Abi` as the `BackendRepr` of the type, and rename
`BackendRepr::Aggregate` as `BackendRepr::Memory`. Unfortunately, due to
the persistent misunderstandings, this too is now incorrect:
- Scattered ABI-relevant code is entangled with BackendRepr
- We do not always pre-compute a correct BackendRepr that reflects how
  we "actually" want this value to be handled, so we leave the backend
  interface to also inject various special-cases here
- In some cases `BackendRepr::Memory` is a "real" aggregate, but in
  others it is in fact using memory, and in some cases it is a scalar!

Our rustc-to-backend lowering code handles this sort of thing right now.
That will eventually be addressed by lifting duplicated lowering code
to either rustc_codegen_ssa or rustc_target as appropriate.
2024-10-29 14:56:00 -07:00
lcnr
f51ec110a7 TypingMode 🤔 2024-10-29 17:01:24 +01:00
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