`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>
The checks in `is_eligible_for_coverage` include `is_fn_like`, but will also
exclude various function-like things that cannot possibly have coverage
instrumentation.
Since the previos commit renamed `assignment_rhs_span` to just
`rhs_span` there is no need for a variable just to shorten the
expression on the next line. Inline the variable.
Some trait method vs impl method signature difference diagnostic cleanups
Just some things I noticed while debugging a weird diagnostic in https://github.com/rust-lang/rust/pull/134353
best reviewed commit by commit
Check for array lengths that aren't actually `usize`
I wish typeck wouldn't give us `ty::Array`s that have this problem in the first place, but we can check for it.
Fixes#134352
cc ``@matthiaskrgr``
reject unsound toggling of RISCV target features
~~Stacked on top of https://github.com/rust-lang/rust/pull/133417, only the last commit is new.~~
Works towards https://github.com/rust-lang/rust/issues/132618 (but more [remains to be done](https://github.com/rust-lang/rust/pull/134337#issuecomment-2544228958))
Part of https://github.com/rust-lang/rust/issues/116344
Cc ``@beetrees`` I hope I got everything. I didn't do anything about "The f and zfinx features are incompatible" and that's not an ABI thing (right?) and I am not sure how to handle it with these ABI checks.
r? ``@workingjubilee``
Ideally we'd also reject target specs that disable the `f` feature but set an ABI that requires `f`... but I don't want to duplicate this logic. I have some ideas for how maybe the entire float ABI check logic should be different, now that we have some examples of what these ABI checks look like, but that will be a future PR.
Keep track of patterns that could have introduced a binding, but didn't
When we recover from a pattern parse error, or a pattern uses `..`, we keep track of that and affect resolution error for missing bindings that could have been provided by that pattern. We differentiate between `..` and parse recovery. We silence resolution errors likely caused by the pattern parse error.
```
error[E0425]: cannot find value `title` in this scope
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30
|
LL | if let Website { url, .. } = website {
| ------------------- this pattern doesn't include `title`, which is available in `Website`
LL | println!("[{}]({})", title, url);
| ^^^^^ not found in this scope
```
Fix#74863.
rustc_mir_build: Clarify that 'mirrored' does not mean 'flipped' or 'reversed'
My intuition for 'mirrored' is that it means 'flipped' or 'reversed'. Clarify that that is not what is meant to 'mirror' the THIR from the HIR.
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`
Make sure to use normalized ty for unevaluated const in default struct value
This cleans up the way that we construct the `mir::Const::Unevaluated` for default struct values. We were previously using `from_unevaluated`, which doesn't normalize the type, and is really only used for inline assembly. Other codepaths (such as `ExprKind::NamedConst`) use the type from the body.
Also, let's stop using `literal_operand`, which also is really not meant for calls other than for literal comparisons in pattern lowering.
Also move all of the tests to a separate subdirectory so they don't need to have the same prefix on all the test files.
Fixes#134298
r? estebank or reassign
It is possible to avoid the clone as suggested in the comment. It would
require introducing an enum with two variants
`CloneBeforeModifying(&Domain)` and `Modifiable(&mut Domain)`. But it's
not worth the effort, because this code path just isn't very hot. E.g.
when compiling a large benchmark like `cargo-0.60.0` it's only hit a few
thousand times.
Switches to the idiom used elsewhere of calling `Analysis::bottom_value`
to initialize a `state` value outside a loop, and then using
`clone_from` to update it within the loop. This is simpler and has no
impact on performance.
Current `SwitchInt` handling has complicated control flow.
- The dataflow engine calls `Analysis::apply_switch_int_edge_effects`,
passing in an "applier" that impls `SwitchIntEdgeEffects`.
- `apply_switch_int_edge_effects` possibly calls `apply` on the applier,
passing it a closure.
- The `apply` method calls the closure on each `SwitchInt` edge.
- The closure operates on the edge.
I.e. control flow goes from the engine, to the analysis, to the applier
(which came from the engine), to the closure (which came from the
analysis). It took me a while to work this out.
This commit changes to a simpler structure that maintains the important
characteristics.
- The dataflow engine calls `Analysis::get_switch_int_data`.
- `get_switch_int_data` returns an `Option<Self::SwitchIntData>` value.
- If that returned value was `Some`, the dataflow engine calls
`Analysis::apply_switch_int_edge_effect` on each edge, passing the
`Self::SwitchIntData` value.
- `Analysis::apply_switch_int_edge_effect` operates on the edge.
I.e. control flow goes from the engine, to the analysis, to the
engine, to the analysis.
Added:
- The `Analysis::SwitchIntData` assoc type and the
`Analysis::get_switch_int_data` method. Both only need to be
defined by analyses that look at `SwitchInt` terminators.
- The `MaybePlacesSwitchIntData` struct, which has three fields.
Changes:
- `Analysis::apply_switch_int_edge_effects` becomes
`Analysis::apply_switch_int_edge_effect`, which is a little simpler
because it's dealing with a single edge instead of all edges.
Removed:
- The `SwitchIntEdgeEffects` trait, and its two impls:
`BackwardSwitchIntEdgeEffectsApplier` (which has six fields) and
`ForwardSwitchIntEdgeEffectsApplier` structs (which has four fields).
- The closure.
The new structure is more concise and simpler.
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.
Pass `TyCtxt` to early diagostics decoration
This PR pass a `TyCtxt` to the early diagnostics decoration code so that diagnostics code that take advantage of (a very limited but still useful) `TyCtxt` in their note, help, suggestions, ...
This is particulary useful for #133221 which wants to get the crate name of a `DefId`, which is possible with `tcx.crate_name(...)`.
I highly recommend reviewing this PR commit by commit.
r? `@jieyouxu`
reject aarch64 target feature toggling that would change the float ABI
~~Stacked on top of https://github.com/rust-lang/rust/pull/133099. Only the last two commits are new.~~
The first new commit lays the groundwork for separately controlling whether a feature may be enabled or disabled. The second commit uses that to make it illegal to *disable* the `neon` feature (which is only possible via `-Ctarget-feature`, and so the new check just adds a warning). Enabling the `neon` feature remains allowed on targets that don't disable `neon` or `fp-armv8`, which is all our built-in targets. This way, the entire PR is not a breaking change.
Fixes https://github.com/rust-lang/rust/issues/131058 for hardfloat targets (together with https://github.com/rust-lang/rust/pull/133102 which fixed it for softfloat targets).
Part of https://github.com/rust-lang/rust/issues/116344.
- integrate it within existing fact generation instead of being called
in typeck
- simplify access fact extraction
- also remove single use fact emit functions in root fact generation
Modifies the index instruction from `gep [0 x %Type]` to `gep %Type`
Fixes#133979.
This PR modifies the index instruction from `gep [0 x %Type]` to `gep %Type`, which is the same with pointer offset calculation.
This will help LLVM calculate various formats of GEP instructions. According to [[RFC] Replacing getelementptr with ptradd](https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699), we ultimately aim to canonicalize everything to `gep i8`. Based on the results from https://github.com/rust-lang/rust/pull/134117#issuecomment-2531717076, I think we still need to investigate some missing optimizations, so this PR is just a small step forward.
r? compiler
A couple of polonius fact generation cleanups
This PR is extracted from #134268 for easier review and contains its first two commits. They have already been reviewed by `@jackh726.`
r? `@jackh726`
Don't make a def id for `impl_trait_in_bindings`
The def collector is awkward, so for now just wrap let statements in a new `ImplTraitContext::InBinding` which tells `visit_ty` not to make a def id for the type. This will not generalize to other ITIB cases, like if we allow them in turbofishes (e.g. `foo::<impl Fn()>(|| {})`).
Fixes#134307
r? oli-obk
Add some convenience helper methods on `hir::Safety`
Makes a lot of call sites simpler and should make any refactorings needed for https://github.com/rust-lang/rust/pull/134090#issuecomment-2541332415 simpler, as fewer sites have to be touched in case we end up storing some information in the variants of `hir::Safety`
don't show the full linker args unless `--verbose` is passed
the linker arguments can be *very* long, especially for crates with many dependencies. often they are not useful. omit them unless the user specifically requests them.
split out from https://github.com/rust-lang/rust/pull/119286. fixes https://github.com/rust-lang/rust/issues/109979.
r? `@bjorn3`
try-build: i686-mingw
Remove support for specializing ToString outside the standard library
This is the only trait specializable outside of the standard library. Before stabilizing specialization we will probably want to remove support for this. It was originally made specializable to allow a more efficient ToString in libproc_macro back when this way the only way to get any data out of a TokenStream. We now support getting individual tokens, so proc macros no longer need to call it as often.
the linker arguments can be *very* long, especially for crates with many dependencies. some parts of them are not very useful. unless specifically requested:
- omit object files specific to the current invocation
- fold rlib files into a single braced argument (in shell expansion format)
this shortens the output significantly without removing too much information.
Rollup of 7 pull requests
Successful merges:
- #132939 (Suggest using deref in patterns)
- #133293 (Updates Solaris target information, adds Solaris maintainer)
- #133392 (Fix ICE when multiple supertrait substitutions need assoc but only one is provided)
- #133986 (Add documentation for anonymous pipe module)
- #134022 (Doc: Extend for tuples to be stabilized in 1.85.0)
- #134259 (Clean up `infer_return_ty_for_fn_sig`)
- #134264 (Arbitrary self types v2: Weak & NonNull diagnostics)
r? `@ghost`
`@rustbot` modify labels: rollup
Arbitrary self types v2: Weak & NonNull diagnostics
This builds on top of #134262 which is more urgent to review and merge first. I'll likely rebase this PR once that lands.
This is the first part of the diagnostic enhancements planned for Arbitrary Self Types v2.
Various types can be used as method receivers, such as `Rc<>`, `Box<>` and `Arc<>`. The arbitrary self types v2 work allows further types to be made method receivers by implementing the Receiver trait.
With that in mind, it may come as a surprise to people when certain common types do not implement Receiver and thus cannot be used as a method receiver.
The RFC for arbitrary self types v2 therefore proposes emitting specific
lint hints for these cases:
* `NonNull`
* `Weak`
* Raw pointers
The code already emits a hint for this third case, in that it advises folks that the `arbitrary_self_types_pointers` feature may meet their need. This PR adds diagnostic hints for the `Weak` and `NonNull` cases.
Tracking issue #44874
r? `@wesleywiser`
Clean up `infer_return_ty_for_fn_sig`
The code for lowering fn signatures from HIR currently is structured to prefer the recovery path (where users write `-> _`) over the good path. This PR pulls the recovery code out into a separate fn.
Review w/o whitespace
Fix ICE when multiple supertrait substitutions need assoc but only one is provided
Dyn traits must have all of their associated types constrained either by:
1. writing them in the dyn trait itself as an associated type bound, like `dyn Iterator<Item = u32>`,
2. A supertrait bound, like `trait ConstrainedIterator: Iterator<Item = u32> {}`, then you may write `dyn ConstrainedIterator` which doesn't need to mention `Item`.
However, the object type lowering code did not consider the fact that there may be multiple supertraits with different substitutions, so it just used the associated type's *def id* as a key for keeping track of which associated types are missing:
1fc691e6dd/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs (L131)
This means that we can have missing associated types when there are mutliple supertraits with different substitutions and only one of them is constrained, like:
```rust
trait Sup<T> {
type Assoc: Default;
}
impl<T: Default> Sup<T> for () {
type Assoc = T;
}
impl<T: Default, U: Default> Dyn<T, U> for () {}
trait Dyn<A, B>: Sup<A, Assoc = A> + Sup<B> {}
```
The above example allows you to name `<dyn Dyn<i32, u32> as Sup<u32>>::Assoc` even though it is not possible to project since it's neither constrained by a manually written projection bound or a supertrait bound. This successfully type-checks, but leads to a codegen ICE since we are not able to project the associated type.
This PR fixes the validation for checking that a dyn trait mentions all of its associated type bounds. This is theoretically a breaking change, since you could technically use that `dyn Dyn<A, B>` type mentionedin the example above without actually *projecting* to the bad associated type, but I don't expect it to ever be relevant to a user since it's almost certainly a bug. This is corroborated with the crater results[^crater], which show no failures[^unknown].
Crater: https://github.com/rust-lang/rust/pull/133392#issuecomment-2508769703Fixes#133388
[^crater]: I cratered this originally with #133397, which is a PR that is stacked on top, then re-ran crater with just the failures from that PR.
[^unknown]: If you look at the crater results, it shows all of the passes as "unknown". I believe this is a crater bug, since looking at the results manually shows them as passes.
Suggest using deref in patterns
Fixes#132784
This changes the following code:
```rs
use std::sync::Arc;
fn main() {
let mut x = Arc::new(Some(1));
match x {
Some(_) => {}
None => {}
}
}
```
to output
```rs
error[E0308]: mismatched types
--> src/main.rs:5:9
|
LL | match x {
| - this expression has type `Arc<Option<{integer}>>`
...
LL | Some(_) => {}
| ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
|
= note: expected struct `Arc<Option<{integer}>>`
found enum `Option<_>`
help: consider dereferencing to access the inner value using the Deref trait
|
LL | match *x {
| ~~
```
instead of
```rs
error[E0308]: mismatched types
--> src/main.rs:5:9
|
4 | match x {
| - this expression has type `Arc<Option<{integer}>>`
5 | Some(_) => {}
| ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
|
= note: expected struct `Arc<Option<{integer}>>`
found enum `Option<_>`
```
This makes it more obvious that a Deref is available, and gives a suggestion on how to use it in order to fix the issue at hand.
Bounds-check with PtrMetadata instead of Len in MIR
Rather than emitting `Len(*_n)` in array index bounds checks, emit `PtrMetadata(copy _n)` instead -- with some asterisks for arrays and `&mut` that need it to be done slightly differently.
We're getting pretty close to removing `Len` entirely, actually. I think just one more PR after this (for slice drop shims).
r? mir
Various types can be used as method receivers, such as Rc<>, Box<> and
Arc<>. The arbitrary self types v2 work allows further types to be made
method receivers by implementing the Receiver trait.
With that in mind, it may come as a surprise to people when certain
common types do not implement Receiver and thus cannot be used as a
method receiver.
The RFC for arbitrary self types v2 therefore proposes emitting specific
lint hints for these cases:
* NonNull
* Weak
* Raw pointers
The code already emits a hint for this third case, in that it advises
folks that the `arbitrary_self_types_pointers` feature may meet their
need. This PR adds diagnostic hints for the Weak and NonNull cases.
Rollup of 6 pull requests
Successful merges:
- #133221 (Add external macros specific diagnostics for check-cfg)
- #133386 (Update linux_musl base to dynamically link the crt by default)
- #134191 (Make some types and methods related to Polonius + Miri public)
- #134227 (Update wasi-sdk used to build WASI targets)
- #134279 ((Re-)return adjustment target if adjust kind is never-to-any)
- #134295 (Encode coroutine-closures in SMIR)
r? `@ghost`
`@rustbot` modify labels: rollup
- use consistent names
- inline single use functions
- dedupe and simplify some paths
- fix fact generation timer activity: it was missing the walk and
extraction process
(Re-)return adjustment target if adjust kind is never-to-any
This PR fixes#134162 where we ICE'd on
```rs
fn main() {
struct X;
let _ = [X] == [panic!(); 2];
}
```
In https://github.com/rust-lang/rust/pull/121208#discussion_r1494187622, there was a change
```diff
- if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
- let reported = self.dcx().span_delayed_bug(
- expr.span,
- "expression with never type wound up being adjusted",
- );
- return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
- target.to_owned()
- } else {
- Ty::new_error(self.tcx(), reported)
- };
- }
+ if let Some(_) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
+ self.dcx()
+ .span_bug(expr.span, "expression with never type wound up being adjusted");
+ }
```
It turned out returning the adjustment target if the adjustment kind is `NeverToAny` is necessary, as otherwise we will go through a series of `delay_bug`s and eventually find that we constructed a `TyKind::Error` without having actually emitted an error.
This PR addresses that by re-returning the adjustment target if the adjustment kind is `NeverToAny`, partially reverting this change from #121208.
This PR has two commits:
1. The first commit adds a regression test for #134162, which will ICE (on stable 1.83.0, beta and nightly 2024-12-13).
2. The second commit is the partial revert, which will fix the ICE.
cc `@nnethercote` FYI as this is related to #121208 changes. The changes from #121208 exposed that we lacked test coverage for the code pattern reported in #134162.
Make some types and methods related to Polonius + Miri public
We have a tool, [Aquascope](https://github.com/cognitive-engineering-lab/aquascope/), which uses Polonius and Miri to visualize the compile-time and run-time semantics of a Rust program. Changes in the last few months to both APIs have hidden away details we depend upon. This PR re-exposes some of those details, specifically:
**Polonius:**
- `BorrowSet` and `BorrowData` are added to `rustc_borrowck::consumers`, and their fields are made `pub` instead of `pub(crate)`. We need this to interpret the `BorrowIndex`es generated by Polonius.
- `BorrowSet::build` is now `pub`. We need this because the borrowck API doesn't provide access to the `BorrowSet` constructed during checking.
- `PoloniusRegionVid` is added to `rustc_borrowck::consumers`. We need this because it's also contained in the Polonius facts.
**Miri:**
- `InterpCx::local_to_op` is now a special case of `local_at_frame_to_op`, which allows querying locals in any frame. We need this because we walk the whole stack at each step to collect the state of memory.
- `InterpCx::layout_of_local` is now `pub`. We need this because we need to know the layout of every local at each step.
If these changes go against some design goal for keeping certain types private, please let me know so we can hash out a better solution. Additionally, if there's a better way to document that it's important that certain types stay public, also let me know. For example, `BorrowSet` was previously public but was hidden in 6676cec, breaking our build.
cc ```@RalfJung``` ```@nnethercote``` ```@gavinleroy```
Update linux_musl base to dynamically link the crt by default
However, don't change the behavior of any existing targets at this time. For targets that used the old default, explicitly set `crt_static_default = true`.
This makes it easier for new targets to use the correct defaults while leaving the changing of individual targets to future PRs.
Related to https://github.com/rust-lang/compiler-team/issues/422
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
Rollup of 6 pull requests
Successful merges:
- #132150 (Fix powerpc64 big-endian FreeBSD ABI)
- #133942 (Clarify how to use `black_box()`)
- #134081 (Try to evaluate constants in legacy mangling)
- #134192 (Remove `Lexer`'s dependency on `Parser`.)
- #134208 (coverage: Tidy up creation of covmap and covfun records)
- #134211 (On Neutrino QNX, reduce the need to set archiver via environment variables)
r? `@ghost`
`@rustbot` modify labels: rollup
(Re-)Implement `impl_trait_in_bindings`
This reimplements the `impl_trait_in_bindings` feature for local bindings.
"`impl Trait` in bindings" serve as a form of *trait* ascription, where the type basically functions as an infer var but additionally registering the `impl Trait`'s trait bounds for the infer type. These trait bounds can be used to enforce that predicates hold, and can guide inference (e.g. for closure signature inference):
```rust
let _: impl Fn(&u8) -> &u8 = |x| x;
```
They are implemented as an additional set of bounds that are registered when the type is lowered during typeck, and then these bounds are tied to a given `CanonicalUserTypeAscription` for borrowck. We enforce these `CanonicalUserTypeAscription` bounds during borrowck to make sure that the `impl Trait` types are sensitive to lifetimes:
```rust
trait Static: 'static {}
impl<T> Static for T where T: 'static {}
let local = 1;
let x: impl Static = &local;
//~^ ERROR `local` does not live long enough
```
r? oli-obk
cc #63065
---
Why can't we just use TAIT inference or something? Well, TAITs in bodies have the problem that they cannot reference lifetimes local to a body. For example:
```rust
type TAIT = impl Display;
let local = 0;
let x: TAIT = &local;
//~^ ERROR `local` does not live long enough
```
That's because TAITs requires us to do *opaque type inference* which is pretty strict, since we need to remap all of the lifetimes of the hidden type to universal regions. This is simply not possible here.
---
I consider this part of the "impl trait everywhere" experiment. I'm not certain if this needs yet another lang team experiment.
Without doing so, we'll run into a series of delayed bugs then find that
we have a `TyKind::Error` constructed yet fail to emit an error.
This partially reverts a change in
<https://github.com/rust-lang/rust/pull/121208> related to never type
adjustments in expr typecheck errors.
Rollup of 8 pull requests
Successful merges:
- #134252 (Fix `Path::is_absolute` on Hermit)
- #134254 (Fix building `std` for Hermit after `c_char` change)
- #134255 (Update includes in `/library/core/src/error.rs`.)
- #134261 (Document the symbol Visibility enum)
- #134262 (Arbitrary self types v2: adjust diagnostic.)
- #134265 (Rename `ty_def_id` so people will stop using it by accident)
- #134271 (Arbitrary self types v2: better feature gate test)
- #134274 (Add check-pass test for `&raw`)
r? `@ghost`
`@rustbot` modify labels: rollup
coverage: Tidy up creation of covmap and covfun records
This is a small follow-up to #134163 that mostly just inlines and renames some variables, and adds a few comments.
It also slightly defers the creation of the LLVM value that holds the filename table, to just before the value is needed.
---
try-job: x86_64-mingw-2
try-job: dist-x86_64-linux
Remove `Lexer`'s dependency on `Parser`.
Lexing precedes parsing, as you'd expect: `Lexer` creates a `TokenStream` and `Parser` then parses that `TokenStream`.
But, in a horrendous violation of layering abstractions and common sense, `Lexer` depends on `Parser`! The `Lexer::unclosed_delim_err` method does some error recovery that relies on creating a `Parser` to do some post-processing of the `TokenStream` that the `Lexer` just created.
This commit just removes `unclosed_delim_err`. This change removes `Lexer`'s dependency on `Parser`, and also means that `lex_token_tree`'s return value can have a more typical form.
The cost is slightly worse error messages in two obscure cases, as shown in these tests:
- tests/ui/parser/brace-in-let-chain.rs: there is slightly less explanation in this case involving an extra `{`.
- tests/ui/parser/diff-markers/unclosed-delims{,-in-macro}.rs: the diff marker detection is no longer supported (because that detection is implemented in the parser).
In my opinion this cost is outweighed by the magnitude of the code cleanup.
r? ```````@chenyukang```````
Try to evaluate constants in legacy mangling
Best reviewed commit by commit.
It seems kind of odd to treat literals differently from unevaluated free constants. So let's evaluate those constants and only fall back to `_` rendering if that fails to result in an integral constant
Rename `ty_def_id` so people will stop using it by accident
This function is just for cycle detection, but people keep using it because they think it's the right way of getting the def id from a `Ty` (and I can't blame them necessarily).
Arbitrary self types v2: adjust diagnostic.
The recently landed PR #132961 to adjust arbitrary self types was a bit overenthusiastic, advising folks to use the new Receiver trait even before it's been stabilized. Revert to the older wording of the lint in such cases.
Tracking issue #44874
r? ``@wesleywiser``
A bunch of cleanups (part 2)
Just like https://github.com/rust-lang/rust/pull/133567 these were all found while looking at the respective code, but are not blocking any other changes I want to make in the short term.
rustc_borrowck: Stop suggesting the invalid syntax `&mut raw const`
A legitimate suggestion would be to change from
&raw const val
to
&raw mut val
But until we have figured out how to make that happen we should at least
stop suggesting invalid syntax.
I recommend review commit-by-commit.
Part of #127562
Tweak multispan rendering to reduce output length
Consider comments and bare delimiters the same as an "empty line" for purposes of hiding rendered code output of long multispans. This results in more aggressive shortening of rendered output without losing too much context, specially in `*.stderr` tests that have "hidden" comments. We do that check not only on the first 4 lines of the multispan, but now also on the previous to last line as well.
Rollup of 7 pull requests
Successful merges:
- #133900 (Advent of `tests/ui` (misc cleanups and improvements) [1/N])
- #133937 (Keep track of parse errors in `mod`s and don't emit resolve errors for paths involving them)
- #133938 (`rustc_mir_dataflow` cleanups, including some renamings)
- #134058 (interpret: reduce usage of TypingEnv::fully_monomorphized)
- #134130 (Stop using driver queries in the public API)
- #134140 (Add AST support for unsafe binders)
- #134229 (Fix typos in docs on provenance)
r? `@ghost`
`@rustbot` modify labels: rollup
When we recover from a pattern parse error, or a pattern uses `..`, we keep track of that and affect resolution error for missing bindings that could have been provided by that pattern. We differentiate between `..` and parse recovery. We silence resolution errors likely caused by the pattern parse error.
```
error[E0425]: cannot find value `title` in this scope
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:19:30
|
LL | println!("[{}]({})", title, url);
| ^^^^^ not found in this scope
|
note: `Website` has a field `title` which could have been included in this pattern, but it wasn't
--> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:17:12
|
LL | / struct Website {
LL | | url: String,
LL | | title: Option<String> ,
| | ----- defined here
LL | | }
| |_-
...
LL | if let Website { url, .. } = website {
| ^^^^^^^^^^^^^^^^^^^ this pattern doesn't include `title`, which is available in `Website`
```
Fix#74863.
forbid toggling x87 and fpregs on hard-float targets
Part of https://github.com/rust-lang/rust/issues/116344, follow-up to https://github.com/rust-lang/rust/pull/129884:
The `x87` target feature on x86 and the `fpregs` target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, *enabling* `fpregs` on ARM is [explicitly requested](https://github.com/rust-lang/rust/issues/130988) as it seems to be useful. Therefore, we need to refine the distinction of "forbidden" target features and "allowed" target features: all (un)stable target features can determine on a per-target basis whether they should be allowed to be toggled or not. `fpregs` then checks whether the current target has the `soft-float` feature, and if yes, `fpregs` is permitted -- otherwise, it is not. (Same for `x87` on x86).
Also fixes https://github.com/rust-lang/rust/issues/132351. Since `fpregs` and `x87` can be enabled on some builds and disabled on others, it would make sense that one can query it via `cfg`. Therefore, I made them behave in `cfg` like any other unstable target feature.
The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up `fpregs` and `x87` with that new infrastructure.
r? `@workingjubilee`
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
Stop using driver queries in the public API
Follow up to https://github.com/rust-lang/rust/pull/132410 and https://github.com/rust-lang/rust/pull/133567
The next PR will completely get rid of driver queries. That PR will also contains some non-trivial refactorings enabled by no longer needing to support entering TyCtxt multiple times after it is constructed. The changes in the current PR have been split out to make it easier to review the api changes and to reduce the size of the next PR to review.
## Custom driver breaking change
The `after_crate_root_parsing` and `after_expansion` callbacks now accept `ast::Crate` and `TyCtxt` respectively rather than `Queries`. The only safe query in `Queries` to call inside these callbacks are `parse()` and `global_ctxt()` respectively which allows you to access the `ast::Crate` and `TyCtxt` either way. To fix your custom driver, replace the `queries: &'tcx Queries<'tcx>` argument with `crate_: ast::Crate` and `tcx: TyCtxt<'tcx>` respectively and for `after_expansion` remove your `queries.global_ctxt().unwrap().enter(|tcx| { ... })` call and only keep the contents of the closure.
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.
Move impl constness into impl trait header
This PR is kind of the opposite of the rejected https://github.com/rust-lang/rust/pull/134114
Instead of moving more things into the `constness` query, we want to keep them where their corresponding hir nodes are lowered. So I gave this a spin for impls, which have an obvious place to be (the impl trait header). And surprisingly it's also a perf improvement (likely just slightly better query & cache usage).
The issue was that removing anything from the `constness` query makes it just return `NotConst`, which is wrong. So I had to change it to `bug!` out if used wrongly, and only then remove the impl blocks from the `constness` query. I think this change is good in general, because it makes using `constness` more robust (as can be seen by how few sites that had to be changed, so it was almost solely used specifically for the purpose of asking for functions' constness). The main thing where this change was not great was in clippy, which was using the `constness` query as a general DefId -> constness map. I added a `DefKind` filter in front of that. If it becomes a more common pattern we can always move that helper into rustc.
The recently landed PR to adjust arbitrary self types was a bit
overenthusiastic, advising folks to use the new Receiver trait even
before it's been stabilized. Revert to the older wording of the lint in
such cases.
A legitimate suggestion would be to change from
&raw const val
to
&raw mut val
But until we have figured out how to make that happen we should at least
stop suggesting invalid syntax.
This is the only trait specializable outside of the standard library.
Before stabilizing specialization we will probably want to remove
support for this. It was originally made specializable to allow a more
efficient ToString in libproc_macro back when this way the only way to
get any data out of a TokenStream. We now support getting individual
tokens, so proc macros no longer need to call it as often.
It is treated as a map already. This is using FxIndexMap rather than
UnordMap because the latter doesn't provide an api to pick a single
value iff all values are equal, which each_linked_rlib depends on.
It only exists to pass some information from one part of the driver to
another part. We can directly pass this information to the function that
needs it to reduce the amount of mutation of the Session.
We don't need `NonNull::as_ptr` debuginfo
In order to stop pessimizing the use of local variables in core, skip debug info for MIR temporaries in tiny (single-BB) functions.
For functions as simple as this -- `Pin::new`, etc -- nobody every actually wants debuginfo for them in the first place. They're more like intrinsics than real functions, and stepping over them is good.
Stabilize async closures (RFC 3668)
# Async Closures Stabilization Report
This report proposes the stabilization of `#![feature(async_closure)]` ([RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html)). This is a long-awaited feature that increases the expressiveness of the Rust language and fills a pressing gap in the async ecosystem.
## Stabilization summary
* You can write async closures like `async || {}` which return futures that can borrow from their captures and can be higher-ranked in their argument lifetimes.
* You can express trait bounds for these async closures using the `AsyncFn` family of traits, analogous to the `Fn` family.
```rust
async fn takes_an_async_fn(f: impl AsyncFn(&str)) {
futures::join(f("hello"), f("world")).await;
}
takes_an_async_fn(async |s| { other_fn(s).await }).await;
```
## Motivation
Without this feature, users hit two major obstacles when writing async code that uses closures and `Fn` trait bounds:
- The inability to express higher-ranked async function signatures.
- That closures cannot return futures that borrow from the closure captures.
That is, for the first, we cannot write:
```rust
// We cannot express higher-ranked async function signatures.
async fn f<Fut>(_: impl for<'a> Fn(&'a u8) -> Fut)
where
Fut: Future<Output = ()>,
{ todo!() }
async fn main() {
async fn g(_: &u8) { todo!() }
f(g).await;
//~^ ERROR mismatched types
//~| ERROR one type is more general than the other
}
```
And for the second, we cannot write:
```rust
// Closures cannot return futures that borrow closure captures.
async fn f<Fut: Future<Output = ()>>(_: impl FnMut() -> Fut)
{ todo!() }
async fn main() {
let mut xs = vec![];
f(|| async {
async fn g() -> u8 { todo!() }
xs.push(g().await);
});
//~^ ERROR captured variable cannot escape `FnMut` closure body
}
```
Async closures provide a first-class solution to these problems.
For further background, please refer to the [motivation section](https://rust-lang.github.io/rfcs/3668-async-closures.html#motivation) of the RFC.
## Major design decisions since RFC
The RFC had left open the question of whether we would spell the bounds syntax for async closures...
```rust
// ...as this...
fn f() -> impl AsyncFn() -> u8 { todo!() }
// ...or as this:
fn f() -> impl async Fn() -> u8 { todo!() }
```
We've decided to spell this as `AsyncFn{,Mut,Once}`.
The `Fn` family of traits is special in many ways. We had originally argued that, due to this specialness, that perhaps the `async Fn` syntax could be adopted without having to decide whether a general `async Trait` mechanism would ever be adopted. However, concerns have been raised that we may not want to use `async Fn` syntax unless we would pursue more general trait modifiers. Since there remain substantial open questions on those -- and we don't want to rush any design work there -- it makes sense to ship this needed feature using the `AsyncFn`-style bounds syntax.
Since we would, in no case, be shipping a generalized trait modifier system anytime soon, we'll be continuing to see `AsyncFoo` traits appear across the ecosystem regardless. If we were to ever later ship some general mechanism, we could at that time manage the migration from `AsyncFn` to `async Fn`, just as we'd be enabling and managing the migration of many other traits.
Note that, as specified in RFC 3668, the details of the `AsyncFn*` traits are not exposed and they can only be named via the "parentheses sugar". That is, we can write `T: AsyncFn() -> u8` but not `T: AsyncFn<Output = u8>`.
Unlike the `Fn` traits, we cannot project to the `Output` associated type of the `AsyncFn` traits. That is, while we can write...
```rust
fn f<F: Fn() -> u8>(_: F::Output) {}
```
...we cannot write:
```rust
fn f<F: AsyncFn() -> u8>(_: F::Output) {}
//~^ ERROR
```
The choice of `AsyncFn{,Mut,Once}` bounds syntax obviates, for our purposes here, another question decided after that RFC, which was how to order bound modifiers such as `for<'a> async Fn()`.
Other than answering the open question in the RFC on syntax, nothing has changed about the design of this feature between RFC 3668 and this stabilization.
## What is stabilized
For those interested in the technical details, please see [the dev guide section](https://rustc-dev-guide.rust-lang.org/coroutine-closures.html) I authored.
#### Async closures
Other than in how they solve the problems described above, async closures act similarly to closures that return async blocks, and can have parts of their signatures specified:
```rust
// They can have arguments annotated with types:
let _ = async |_: u8| { todo!() };
// They can have their return types annotated:
let _ = async || -> u8 { todo!() };
// They can be higher-ranked:
let _ = async |_: &str| { todo!() };
// They can capture values by move:
let x = String::from("hello, world");
let _ = async move || do_something(&x).await };
```
When called, they return an anonymous future type corresponding to the (not-yet-executed) body of the closure. These can be awaited like any other future.
What distinguishes async closures is that, unlike closures that return async blocks, the futures returned from the async closure can capture state from the async closure. For example:
```rust
let vec: Vec<String> = vec![];
let closure = async || {
vec.push(ready(String::from("")).await);
};
```
The async closure captures `vec` with some `&'closure mut Vec<String>` which lives until the closure is dropped. Every call to `closure()` returns a future which reborrows that mutable reference `&'call mut Vec<String>` which lives until the future is dropped (e.g. it is `await`ed).
As another example:
```rust
let string: String = "Hello, world".into();
let closure = async move || {
ready(&string).await;
};
```
The closure is marked with `move`, which means it takes ownership of the string by *value*. The future that is returned by calling `closure()` returns a future which borrows a reference `&'call String` which lives until the future is dropped (e.g. it is `await`ed).
#### Async fn trait family
To support the lending capability of async closures, and to provide a first-class way to express higher-ranked async closures, we introduce the `AsyncFn*` family of traits. See the [corresponding section](https://rust-lang.github.io/rfcs/3668-async-closures.html#asyncfn) of the RFC.
We stabilize naming `AsyncFn*` via the "parenthesized sugar" syntax that normal `Fn*` traits can be named. The `AsyncFn*` trait can be used anywhere a `Fn*` trait bound is allowed, such as:
```rust
/// In return-position impl trait:
fn closure() -> impl AsyncFn() { async || {} }
/// In trait bounds:
trait Foo<F>: Sized
where
F: AsyncFn()
{
fn new(f: F) -> Self;
}
/// in GATs:
trait Gat {
type AsyncHasher<T>: AsyncFn(T) -> i32;
}
```
Other than using them in trait bounds, the definitions of these traits are not directly observable, but certain aspects of their behavior can be indirectly observed such as the fact that:
* `AsyncFn::async_call` and `AsyncFnMut::async_call_mut` return a future which is *lending*, and therefore borrows the `&self` lifetime of the callee.
```rust
fn by_ref_call(c: impl AsyncFn()) {
let fut = c();
drop(c);
// ^ Cannot drop `c` since it is borrowed by `fut`.
}
```
* `AsyncFnOnce::async_call_once` returns a future that takes ownership of the callee.
```rust
fn by_ref_call(c: impl AsyncFnOnce()) {
let fut = c();
let _ = c();
// ^ Cannot call `c` since calling it takes ownership the callee.
}
```
* All currently-stable callable types (i.e., closures, function items, function pointers, and `dyn Fn*` trait objects) automatically implement `AsyncFn*() -> T` if they implement `Fn*() -> Fut` for some output type `Fut`, and `Fut` implements `Future<Output = T>`.
* This is to make sure that `AsyncFn*()` trait bounds have maximum compatibility with existing callable types which return futures, such as async function items and closures which return boxed futures.
* For now, this only works currently for *concrete* callable types -- for example, a argument-position impl trait like `impl Fn() -> impl Future<Output = ()>` does not implement `AsyncFn()`, due to the fact that a `AsyncFn`-if-`Fn` blanket impl does not exist in reality. This may be relaxed in the future. Users can work around this by wrapping their type in an async closure and calling it. I expect this to not matter much in practice, as users are encouraged to write `AsyncFn` bounds directly.
```rust
fn is_async_fn(_: impl AsyncFn(&str)) {}
async fn async_fn_item(s: &str) { todo!() }
is_async_fn(s);
// ^^^ This works.
fn generic(f: impl Fn() -> impl Future<Output = ()>) {
is_async_fn(f);
// ^^^ This does not work (yet).
}
```
#### The by-move future
When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped.
To work around around this limitation, we synthesize a separate future type for calling the async closure via `AsyncFnOnce`.
This future executes identically to the by-ref future returned from calling the async closure, except for the fact that it has a different set of captures, since we must *move* the captures from the parent async into the child future.
#### Interactions between async closures and the `Fn*` family of traits
Async closures always implement `FnOnce`, since they always can be called once. They may also implement `Fn` or `FnMut` if their body is compatible with the calling mode (i.e. if they do not mutate their captures, or they do not capture their captures, respectively) and if the future returned by the async closure is not *lending*.
```rust
let id = String::new();
let mapped: Vec</* impl Future */> =
[/* elements */]
.into_iter()
// `Iterator::map` takes an `impl FnMut`
.map(async |element| {
do_something(&id, element).await;
})
.collect();
```
See [the dev guide](https://rustc-dev-guide.rust-lang.org/coroutine-closures.html#follow-up-when-do-async-closures-implement-the-regular-fn-traits) for a detailed explanation for the situations where this may not be possible due to the lending nature of async closures.
#### Other notable features of async closures shared with synchronous closures
* Async closures are `Copy` and/or `Clone` if their captures are `Copy`/`Clone`.
* Async closures do closure signature inference: If an async closure is passed to a function with a `AsyncFn` or `Fn` trait bound, we can eagerly infer the argument types of the closure. More details are provided in [the dev guide](https://rustc-dev-guide.rust-lang.org/coroutine-closures.html#closure-signature-inference).
#### Lints
This PR also stabilizes the `CLOSURE_RETURNING_ASYNC_BLOCK` lint as an `allow` lint. This lints on "old-style" async closures:
```rust
#![warn(closure_returning_async_block)]
let c = |x: &str| async {};
```
We should encourage users to use `async || {}` where possible. This lint remains `allow` and may be refined in the future because it has a few false positives (namely, see: "Where do we expect rewriting `|| async {}` into `async || {}` to fail?")
An alternative that could be made at the time of stabilization is to put this lint behind another gate, so we can decide to stabilize it later.
## What isn't stabilized (aka, potential future work)
#### `async Fn*()` bound syntax
We decided to stabilize async closures without the `async Fn*()` bound modifier syntax. The general direction of this syntax and how it fits is still being considered by T-lang (e.g. in [RFC 3710](https://github.com/rust-lang/rfcs/pull/3710)).
#### Naming the futures returned by async closures
This stabilization PR does not provide a way of naming the futures returned by calling `AsyncFn*`.
Exposing a stable way to refer to these futures is important for building async-closure-aware combinators, and will be an important future step.
#### Return type notation-style bounds for async closures
The RFC described an RTN-like syntax for putting bounds on the future returned by an async closure:
```rust
async fn foo(x: F) -> Result<()>
where
F: AsyncFn(&str) -> Result<()>,
// The future from calling `F` is `Send` and `'static`.
F(..): Send + 'static,
{}
```
This stabilization PR does not stabilize that syntax yet, which remains unimplemented (though will be soon).
#### `dyn AsyncFn*()`
`AsyncFn*` are not dyn-compatible yet. This will likely be implemented in the future along with the dyn-compatibility of async fn in trait, since the same issue (dealing with the future returned by a call) applies there.
## Tests
Tests exist for this feature in [`tests/ui/async-await/async-closures`](5b54286640/tests/ui/async-await/async-closures).
<details>
<summary>A selected set of tests:</summary>
* Lending behavior of async closures
* `tests/ui/async-await/async-closures/mutate.rs`
* `tests/ui/async-await/async-closures/captures.rs`
* `tests/ui/async-await/async-closures/precise-captures.rs`
* `tests/ui/async-await/async-closures/no-borrow-from-env.rs`
* Async closures may be higher-ranked
* `tests/ui/async-await/async-closures/higher-ranked.rs`
* `tests/ui/async-await/async-closures/higher-ranked-return.rs`
* Async closures may implement `Fn*` traits
* `tests/ui/async-await/async-closures/is-fn.rs`
* `tests/ui/async-await/async-closures/implements-fnmut.rs`
* Async closures may be cloned
* `tests/ui/async-await/async-closures/clone-closure.rs`
* Ownership of the upvars when `AsyncFnOnce` is called
* `tests/ui/async-await/async-closures/drop.rs`
* `tests/ui/async-await/async-closures/move-is-async-fn.rs`
* `tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs`
* `tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs`
* Closure signature inference
* `tests/ui/async-await/async-closures/signature-deduction.rs`
* `tests/ui/async-await/async-closures/sig-from-bare-fn.rs`
* `tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs`
</details>
## Remaining bugs and open issues
* https://github.com/rust-lang/rust/issues/120694 tracks moving onto more general `LendingFn*` traits. No action needed, since it's not observable.
* https://github.com/rust-lang/rust/issues/124020 - Polymorphization ICE. Polymorphization needs to be heavily reworked. No action needed.
* https://github.com/rust-lang/rust/issues/127227 - Tracking reworking the way that rustdoc re-sugars bounds.
* The part relevant to to `AsyncFn` is fixed by https://github.com/rust-lang/rust/pull/132697.
## Where do we expect rewriting `|| async {}` into `async || {}` to fail?
* Fn pointer coercions
* Currently, it is not possible to coerce an async closure to an fn pointer like regular closures can be. This functionality may be implemented in the future.
```rust
let x: fn() -> _ = async || {};
```
* Argument capture
* Like async functions, async closures always capture their input arguments. This is in contrast to something like `|t: T| async {}`, which doesn't capture `t` unless it is used in the async block. This may affect the `Send`-ness of the future or affect its outlives.
```rust
fn needs_send_future(_: impl Fn(NotSendArg) -> Fut)
where
Fut: Future<Output = ()>,
{}
needs_send_future(async |_| {});
```
## History
#### Important feature history
- https://github.com/rust-lang/rust/pull/51580
- https://github.com/rust-lang/rust/pull/62292
- https://github.com/rust-lang/rust/pull/120361
- https://github.com/rust-lang/rust/pull/120712
- https://github.com/rust-lang/rust/pull/121857
- https://github.com/rust-lang/rust/pull/123660
- https://github.com/rust-lang/rust/pull/125259
- https://github.com/rust-lang/rust/pull/128506
- https://github.com/rust-lang/rust/pull/127482
## Acknowledgements
Thanks to `@oli-obk` for reviewing the bulk of the work for this feature. Thanks to `@nikomatsakis` for his design blog posts which generated interest for this feature, `@traviscross` for feedback and additions to this stabilization report. All errors are my own.
r? `@ghost`
Consider comments and bare delimiters the same as an "empty line" for purposes of hiding rendered code output of long multispans. This results in more aggressive shortening of rendered output without losing too much context, specially in `*.stderr` tests that have "hidden" comments.
Arbitrary self types v2: main compiler changes
This is the main PR in a series of PRs related to Arbitrary Self Types v2, tracked in #44874. Specifically this is step 7 of the plan [described here](https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688), for [RFC 3519](https://github.com/rust-lang/rfcs/pull/3519).
Overall this PR:
* Switches from the `Deref` trait to the new `Receiver` trait when the unstable `arbitrary_self_types` feature is enabled (the simple bit)
* Introduces new algorithms to spot "shadowing"; that is, the case where a newly-added method in an outer smart pointer might end up overriding a pre-existing method in the pointee (the complex bit). Most of this bit was explored in [this earlier perf-testing PR](https://github.com/rust-lang/rust/pull/127812#issuecomment-2236911900).
* Lots of tests
This should not break compatibility for:
* Stable users, where it should have no effect
* Users of the existing `arbitrary_self_types` feature (because we implement `Receiver` for `T: Deref`) _unless_ those folks have added methods which may shadow methods in inner types, which we no longer want to allow
Subsequent PRs will add better diagnostics.
It's probably easiest to review this commit-by-commit.
r? `@wesleywiser`
Lexing precedes parsing, as you'd expect: `Lexer` creates a
`TokenStream` and `Parser` then parses that `TokenStream`.
But, in a horrendous violation of layering abstractions and common
sense, `Lexer` depends on `Parser`! The `Lexer::unclosed_delim_err`
method does some error recovery that relies on creating a `Parser` to do
some post-processing of the `TokenStream` that the `Lexer` just created.
This commit just removes `unclosed_delim_err`. This change removes
`Lexer`'s dependency on `Parser`, and also means that `lex_token_tree`'s
return value can have a more typical form.
The cost is slightly worse error messages in two obscure cases, as shown
in these tests:
- tests/ui/parser/brace-in-let-chain.rs: there is slightly less
explanation in this case involving an extra `{`.
- tests/ui/parser/diff-markers/unclosed-delims{,-in-macro}.rs: the diff
marker detection is no longer supported (because that detection is
implemented in the parser).
In my opinion this cost is outweighed by the magnitude of the code
cleanup.
Fix our `llvm::Bool` typedef to be signed, to match `LLVMBool`
In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`, but our Rust-side typedef was using `c_uint` instead.
Signed and unsigned integers have the same ABI on most platforms, but that isn't universally true, so we should prefer to be consistent with LLVM.
https://github.com/rust-lang/llvm-project/blob/1268e87/llvm/include/llvm-c/Types.h#L28
ABI checks: add support for loongarch
LoongArch psABI[^1] specifies that LSX vector types are passed via general-purpose registers, while LASX vector types are passed indirectly through the stack.
This patch addresses the following warnings:
```
warning: this function call uses a SIMD vector type that is not currently supported with the chosen ABI
--> .../library/core/src/../../stdarch/crates/core_arch/src/loongarch64/lsx/generated.rs:3695:5
|
3695 | __lsx_vreplgr2vr_b(a)
| ^^^^^^^^^^^^^^^^^^^^^ function called here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= note: `#[warn(abi_unsupported_vector_types)]` on by default
```
[^1]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc
r? `@workingjubilee`
Add unpolished, experimental support for AFIDT (async fn in dyn trait)
This allows us to begin messing around `async fn` in `dyn Trait`. Calling an async fn from a trait object always returns a `dyn* Future<Output = ...>`.
To make it work, Implementations are currently required to return something that can be coerced to a `dyn* Future` (see the example in `tests/ui/async-await/dyn/works.rs`). If it's not the right size, then it'll raise an error at the coercion site (see the example in `tests/ui/async-await/dyn/wrong-size.rs`). Currently the only practical way of doing this is wrapping the body in `Box::pin(async move { .. })`.
This PR does not implement a helper type like a "`Boxing`"[^boxing] adapter, and I'll probably follow-up with another PR to improve the error message for the `PointerLike` trait (something that explains in just normal prose what is happening here, rather than a trait error).
[^boxing]: https://rust-lang.github.io/async-fundamentals-initiative/explainer/user_guide_future.html#the-boxing-adapter
This PR also does not implement new trait solver support for AFIDT; I'll need to think how best to integrate it into candidate assembly, and that's a bit of a matter of taste, but I don't think it will be difficult to do.
This could also be generalized:
* To work on functions that are `-> impl Future` (soon).
* To work on functions that are `-> impl Iterator` and other "dyn rpitit safe" traits. We still need to nail down exactly what is needed for this to be okay (not soon).
Tracking:
* https://github.com/rust-lang/rust/issues/133119
In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`, but our
Rust-side typedef was using `c_uint` instead.
Signed and unsigned integers have the same ABI on most platforms, but that
isn't universally true, so we should prefer to be consistent with LLVM.
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.
suppress field expr with generics error message if it's a method
Don't emit "field expressions may not have generic arguments" if it's a method call without `()`
r? estebank
Fixes#67680
Is this the best way to go? It's by far the simplest I could come up with.
Simplify `rustc_mir_dataflow::abs_domain`.
`rustc_mir_dataflow` has a typedef `AbstractElem` that is equal to `ProjectionElem<AbstractOperand, AbstractType>`. `AbstractOperand` and `AbstractType` are both unit types. There is also has a trait `Lift` to convert a `PlaceElem` to an `AbstractElem`.
But `rustc_mir_middle` already has a typedef `ProjectionKind` that is equal to `ProjectionElem<(), ()>`, which is equivalent to `AbstractElem`. So this commit reuses `ProjectionKind` in `rustc_mir_dataflow`, removes `AbstractElem`, and simplifies the `Lift` trait.
r? ``@pnkfelix``
Some asm! diagnostic adjustments and a papercut fix
Best reviewed commit by commit.
We forgot a `normalize` call in intrinsic checking, causing us to allow literal integers, but not named constants containing that literal. This can in theory affect stable code, but only if libstd contains a stable SIMD type that has an array length that is a named constant. I'd assume we'd have noticed by now due to asm! rejecting those outright.
The error message left me scratching my head for a bit, so I added some extra information to the diagnostic, too.
Pass end position of span through inline ASM cookie
Before this PR, only the start position of the span was passed though the inline ASM cookie to diagnostics. LLVM 19 has full support for 64-bit inline ASM cookies; this PR uses that to pass the end position of the span in the upper 32 bits, meaning inline ASM diagnostics now point at the entire line the error occurred on, not just the first character of it.
codegen `#[naked]` functions using global asm
tracking issue: https://github.com/rust-lang/rust/issues/90957Fixes#124375
This implements the approach suggested in the tracking issue: use the existing global assembly infrastructure to emit the body of `#[naked]` functions. The main advantage is that we now have full control over what gets generated, and are no longer dependent on LLVM not sneakily messing with our output (inlining, adding extra instructions, etc).
I discussed this approach with `@Amanieu` and while I think the general direction is correct, there is probably a bunch of stuff that needs to change or move around here. I'll leave some inline comments on things that I'm not sure about.
Combined with https://github.com/rust-lang/rust/pull/127853, if both accepted, I think that resolves all steps from the tracking issue.
r? `@Amanieu`
coverage: Rearrange the code for embedding per-function coverage metadata
This is a series of refactorings to the code that prepares and embeds per-function coverage metadata records (“covfun records”) in the `__llvm_covfun` linker section of the final binary. The `llvm-cov` tool reads this metadata from the binary when preparing a coverage report.
Beyond general cleanup, a big motivation behind these changes is to pave the way for re-landing an updated version of #133418.
---
There should be no change in compiler output, as demonstrated by the absence of (meaningful) changes to coverage tests.
The first patch is just moving code around, so I suggest looking at the other patches to see the actual changes.
---
try-job: x86_64-gnu
try-job: x86_64-msvc
try-job: aarch64-apple
A previous commit added a search for certain types of "shadowing"
situation where one method (in an outer smart pointer type, typically)
might hide or shadow the method in the pointee.
Performance investigation showed that the naïve approach is too slow -
this commit speeds it up, while being functionally the same.
This still does not actually cause the deshadowing check to emit any
errors; that comes in a subsequent commit which is where all the tests
live.
This is the first part of a series of commits which impact the
"deshadowing detection" in the arbitrary self types v2 RFC.
This commit should not have any functional changes, but may impact
performance. Subsequent commits add back the performance, and add error
checking to this new code such that it has a functional effect.
Rust prioritizes method candidates in this order:
1. By value;
2. By reference;
3. By mutable reference;
4. By const ptr.
5. By reborrowed pin.
Previously, if a suitable candidate was found in one of these earlier
categories, Rust wouldn't even move onto probing the other categories.
As part of the arbitrary self types work, we're going to need to change
that - even if we choose a method from one of the earlier categories, we
will sometimes need to probe later categories to search for methods that
we may be shadowing.
This commit adds those extra searches for shadowing, but it does not yet
produce an error when such shadowing problems are found. That will come
in a subsequent commit, by filling out the 'check_for_shadowing'
method.
This commit contains a naive approach to detecting these shadowing
problems, which shows what we've functionally looking to do. However,
it's too slow. The performance of this approach was explored in this
PR:
https://github.com/rust-lang/rust/pull/127812#issuecomment-2236911900
Subsequent commits will improve the speed of the search.
This commit makes no (intentional) functional change.
Previously, the picking process maintained two lists of extra
information useful for diagnostics:
* any unstable candidates which might have been picked
* any unsatisfied predicates
Previously, these were dealt with quite differently - the former list
was passed around as a function parameter; the latter lived in a RefCell
in the ProbeCtxt.
With this change we increase consistency by keeping them together in a
new PickDiagHints structure, passed as a parameter, with no need for
interior mutability.
The lifecycle of each of these lists remains fairly complex, so it's
explained with new comments in pick_core.
A further cleanup here would be to package the widely-used tuple
(ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>)
into a named struct for UnsatisfiedPredicate. This seems worth doing but
it turns out that this tuple is used in dozens of places, so if we're
going to do this we should do it as a separate PR to avoid constant
rebase trouble.
In this new version of Arbitrary Self Types, we no longer use the Deref trait
exclusively when working out which self types are valid. Instead, we follow a
chain of Receiver traits. This enables methods to be called on smart pointer
types which fundamentally cannot support Deref (for instance because they are
wrappers for pointers that don't follow Rust's aliasing rules).
This includes:
* Changes to tests appropriately
* New tests for:
* The basics of the feature
* Ensuring lifetime elision works properly
* Generic Receivers
* A copy of the method subst test enhanced with Receiver
This is really the heart of the 'arbitrary self types v2' feature, and
is the most critical commit in the current PR.
Subsequent commits are focused on:
* Detecting "shadowing" problems, where a smart pointer type can hide
methods in the pointee.
* Diagnostics and cleanup.
Naming: in this commit, the "Autoderef" type is modified so that it no
longer solely focuses on the "Deref" trait, but can now consider the
"Receiver" trait instead. Should it be renamed, to something like
"TraitFollower"? This was considered, but rejected, because
* even in the Receiver case, it still considers built-in derefs
* the name Autoderef is short and snappy.
LoongArch psABI[^1] specifies that LSX vector types are passed via general-purpose
registers, while LASX vector types are passed indirectly through the stack.
This patch addresses the following warnings:
```
warning: this function call uses a SIMD vector type that is not currently supported with the chosen ABI
--> .../library/core/src/../../stdarch/crates/core_arch/src/loongarch64/lsx/generated.rs:3695:5
|
3695 | __lsx_vreplgr2vr_b(a)
| ^^^^^^^^^^^^^^^^^^^^^ function called here
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
= note: `#[warn(abi_unsupported_vector_types)]` on by default
```
[^1]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc
Rename `projection_def_id` to `item_def_id`
Renames `projection_def_id` to `item_def_id`, since `item_def_id` is what we call the analogous method for ~~`AliasTerm`/`AliasTy`~~ `PolyExistentialProjection`. I keep forgetting that this one is not called `item_def_id`.
Rudimentary heuristic to insert parentheses when needed for RPIT overcaptures lint
We don't have basically any preexisting machinery to detect when parentheses are needed for *types*. AFAICT, all of the diagnostics we have for opaques just... fail when they suggest `+ 'a` when that's ambiguous.
Fixes#132853
[AIX] keep profile-rt symbol alive
Clang passes `-u __llvm_profile_runtime` on AIX. https://reviews.llvm.org/D136192
We want to preserve the symbol in the case there are no instrumented object files.
Validate self in host predicates correctly
`assert_only_contains_predicates_from` was added to make sure that we are computing predicates for the correct self type for a given `PredicateFilter`. That was not implemented correctly for `PredicateFilter::SelfOnly` when there are const predicates.
Fixes#133526
`rustc_mir_dataflow` has a typedef `AbstractElem` that is equal to
`ProjectionElem<AbstractOperand, AbstractType>`. `AbstractOperand` and
`AbstractType` are both unit types. There is also has a trait `Lift` to
convert a `PlaceElem` to an `AbstractElem`.
But `rustc_mir_middle` already has a typedef `ProjectionKind` that is
equal to `ProjectionElem<(), ()>`, which is equivalent to
`AbstractElem`. So this commit reuses `ProjectionKind` in
`rustc_mir_dataflow`, removes `AbstractElem`, and simplifies the `Lift`
trait.
rustc_target: ppc64 target string fixes for LLVM 20
LLVM continues to clean these up, and we continue to make this consistent. This is similar to 9caced7bad, e985396145, and
a10e744faf.
```@rustbot``` label: +llvm-main
Add the `power8-crypto` target feature
Add the `power8-crypto` target feature. This will enable adding some new PPC intrinsics in stdarch (specifically AES, SHA and CLMUL intrinsics). The implied target feature is from [here](https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/PowerPC/PPC.td)
```@rustbot``` label A-target-feature O-PowerPC
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.
Don't use `AsyncFnOnce::CallOnceFuture` bounds for signature deduction
We shouldn't be using `AsyncFnOnce::CallOnceFuture` projection bounds to deduce anything about the return type of an async closure, **only** `AsyncFnOnce::Output`. This was accidental b/c all we were looking at was the def id of the trait, rather than the projection. This PR fixes that.
This doesn't affect stable code, since `CallOnceFuture` bounds cannot be written on stable.
Fixes#134015
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```
[AIX] Pass -bnoipath when adding rust upstream dynamic crates
Unlike ELF linkers, AIX doesn't feature `DT_SONAME` to override
the dependency name when outputing a shared library, which is something
we rely on for dylib crates.
See for reference:
bc145cec45/compiler/rustc_codegen_ssa/src/back/linker.rs (L464))
Thus, `ld` on AIX will use the full path to shared libraries as the dependency if passed it
by default unless `noipath` is passed, so pass it here so we don't end up with full path dependencies
for dylib crates.
LLVM continues to clean these up, and we continue to make this
consistent. This is similar to 9caced7bad,
e985396145, and
a10e744faf.
`@rustbot` label: +llvm-main
Stop pessimizing the use of local variables in core by skipping debug info for MIR temporaries in tiny (single-BB) functions.
For functions as simple as this -- `Pin::new`, etc -- nobody every actually wants debuginfo for them in the first place. They're more like intrinsics than real functions, and stepping over them is good.
coverage: Use a query to find counters/expressions that must be zero
As of #133446, this query (`coverage_ids_info`) determines which counter/expression IDs are unused. So with only a little extra work, we can take the code that was using that information to determine which coverage counters/expressions must be zero, and move that inside the query as well.
There should be no change in compiler output.
fix ICE on type error in promoted
Fixes https://github.com/rust-lang/rust/issues/133968
Ensure that when we turn a type error into a "this promoted failed to evaluate" error, we do record this as something that may happen even in "infallible" promoteds.
coverage: Prefer to visit nodes whose predecessors have been visited
In coverage instrumentation, we need to traverse the control-flow graph and decide what kind of counter (physical counter or counter-expression) should be used for each node that needs a counter.
The existing traversal order is complex and hard to tweak. This new traversal order tries to be a bit more principled, by always preferring to visit nodes whose predecessors have already been visited, which is a good match for how the counter-creation code ends up dealing with a node's in-edges and out-edges.
For several of the coverage tests, this ends up being a strict improvement in reducing the size of the coverage metadata, and also reducing the number of physical counters needed.
(The new traversal should hopefully also allow some further code simplifications in the future.)
---
This is made possible by the separate simplification pass introduced by #133849. Without that, almost any change to the traversal order ends up increasing the size of the expression table or the number of physical counters.
Lint on combining `#[no_mangle]` and `#[export_name]`
This is my very first contribution to the compiler, even though I read the [chapter about lints](https://rustc-dev-guide.rust-lang.org/diagnostics.html) I'm not very certain that this ~~new lint is done right as a builtin lint~~ PR is right. I appreciate any guidance on how to improve the code.
- Add test for issue #47446
- ~~Implement the new lint `mixed_export_name_and_no_mangle` as a builtin lint (not sure if that is the right way to go)~~ Extend `unused_attributes` lint
- Add suggestion how to fix it
<details>
<summary>Old proposed new lint</summary>
> The `mixed_export_name_and_no_mangle` lint detects usage of both `#[export_name]` and `#[no_mangle]` on the same item which results on `#[no_mangle]` being ignored.
>
> *warn-by-default*
>
> ### Example
>
> ```rust
> #[no_mangle] // ignored
> #[export_name = "foo"] // takes precedences
> pub fn bar() {}
> ```
>
> ### Explanation
>
> The compiler will not respect the `#[no_mangle]` attribute when generating the symbol name for the function, as the `#[export_name]` attribute takes precedence. This can lead to confusion and is unnecessary.
</details>
In most places, the `early` method is listed before the corresponding
`primary` method, like you'd expect. This commit fixes two places where
that isn't the case.
The words "before" and "after" have an obvious temporal meaning, e.g.
`seek_before_primary_effect`,
`visit_statement_{before,after}_primary_effect`. But "before" is also
used to name the effect that occurs before the primary effect of a
statement/terminator; this is `Effect::Before`. This leads to the
confusing possibility of talking about things happening "before/after
the before event".
This commit removes this awkward overloading of "before" by renaming
`Effect::Before` as `Effect::Early`. It also renames some of the
`Analysis` and `ResultsVisitor` methods to be more consistent.
Here are the before and after names:
- `Effect::{Before,Primary}` -> `Effect::{Early,Primary}`
- `apply_before_statement_effect` -> `apply_early_statement_effect`
- `apply_statement_effect` -> `apply_primary_statement_effect`
- `visit_statement_before_primary_effect` -> `visit_after_early_statement_effect`
- `visit_statement_after_primary_effect` -> `visit_after_primary_statement_effect`
(And s/statement/terminator/ for all the terminator events.)
It uses `MaybeInitializedPlaces` and `MaybeUninitializedPlaces`, but
calls the results `live` and `dead`. This is very confusing given that
there are also analyses called `MaybeLiveLocals` and `MaybeStorageLive`
and `MaybeStorageDead`.
This commit changes it to use `maybe_init` and `maybe_uninit`.
Currently they are called (most common) `state`, or `trans`, or (rare)
`on_entry`. I think `trans` is short for "transfer function", which
perhaps made more sense when `GenKillAnalysis` existed. Using `state`
everywhere now is more consistent.
They are only present because it's currently defined in terms of the
domains of `Borrows` and `MaybeUninitializedPlaces` and
`EverInitializedPlaces` via associated types. This commit introduces
typedefs for those domains, avoiding the lifetimes.
Introduce `default_field_values` feature
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
We now parse const expressions after a `=` in a field definition, to specify a `struct` field default value.
We now allow `Struct { field, .. }` where there's no base after `..`.
`#[derive(Default)]` now uses the default value if present, continuing to use `Default::default()` if not.
```rust
#[derive(Debug)]
pub struct S;
#[derive(Debug, Default)]
pub struct Foo {
pub bar: S = S,
pub baz: i32 = 42 + 3,
}
fn main () {
let x = Foo { .. };
let y = Foo::default();
let z = Foo { baz: 1, .. };
assert_eq!(45, x.baz);
assert_eq!(45, y.baz);
assert_eq!(1, z.baz);
}
```
interpret: clean up deduplicating allocation functions
The "align" and "kind" arguments would be largely ignored in the "dedup" case, so let's move that to entirely separate function.
Let's also remove support for old-style miri_resolve_frame while we are at it. The docs have already said for a while that this must be set to 1.
Add test to check unicode identifier version
This adds a test to verify which version of Unicode is used for identifiers. This is part of the language, documented at https://doc.rust-lang.org/nightly/reference/identifiers.html#r-ident.unicode. The version here often changes implicitly due to dependency updates pulling in new versions, and thus we often don't notice it has changed leaving the documentation out of date. The intent here is to have a canary to give us a notification when it changes so that we can update the documentation.
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681.
Support default fields in enum struct variant
Allow default values in an enum struct variant definition:
```rust
pub enum Bar {
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Allow using `..` without a base on an enum struct variant
```rust
Bar::Foo { .. }
```
`#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants.
Support `#[derive(Default)]` on enum struct variants with all defaulted fields
```rust
pub enum Bar {
#[default]
Foo {
bar: S = S,
baz: i32 = 42 + 3,
}
}
```
Check for missing fields in typeck instead of mir_build.
Expand test with `const` param case (needs `generic_const_exprs` enabled).
Properly instantiate MIR const
The following works:
```rust
struct S<A> {
a: Vec<A> = Vec::new(),
}
S::<i32> { .. }
```
Add lint for default fields that will always fail const-eval
We *allow* this to happen for API writers that might want to rely on users'
getting a compile error when using the default field, different to the error
that they would get when the field isn't default. We could change this to
*always* error instead of being a lint, if we wanted.
This will *not* catch errors for partially evaluated consts, like when the
expression relies on a const parameter.
Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`:
- Suggest adding a base expression if there are missing fields.
- Suggest enabling the feature if all the missing fields have optional values.
- Suggest removing `..` if there are no missing fields.
Revert #131669 due to ICEs
Revert [lint: change help for pointers to dyn types in FFI #131669](https://github.com/rust-lang/rust/pull/131669) due to ICE reports:
- <https://github.com/rust-lang/rust/issues/134059> (real-world)
- <https://github.com/rust-lang/rust/issues/134060> (fuzzing)
Closes#134060.
The revert criteria I used to assess whether to post this revert was:
1. It's not trivial to fix-forward. (1) The implementation itself is tricky due to `tcx.is_sized` query not being very trivial. (2) It will need more extensive test coverage for different ty kinds.
2. It is impacting real-world crates, i.e. #134059.
3. `improper_ctypes_definitions` is a warn-by-default lint.
This revert is without prejudice to relanding the changes. The changes can be re-landed with those cases addressed and stronger test coverage.
A rough regression test corresponding to the fuzzed example reported in #134060 is added to check that the revert worked, it is not sufficient for the lint test coverage when the lint improvements are to be relanded. Please feel free to improve the test in the reland.
r? `@workingjubilee` (or compiler)
cc `@niacdoial` (PR author)
The part about zero-sized structures is totally wrong. The rest of
it has almost no explanatory value; there are better explanations in
comments elsewhere.
Introduce `MixedBitSet`
`ChunkedBitSet` is good at avoiding excessive memory usage for programs with very large functgions where dataflow bitsets have very large domain sizes. But it's overly heavyweight for small bitsets, because any non-empty `ChunkedBitSet` takes up at least 256 bytes.
This PR introduces `MixedBitSet`, which is a simple bitset that uses `BitSet` for small/medium bitsets and `ChunkedBitSet` for large bitsets. It's a speed and memory usage win.
r? `@Mark-Simulacrum`
A bunch of cleanups
These are all extracted from a branch I have to get rid of driver queries. Most of the commits are not directly necessary for this, but were found in the process of implementing the removal of driver queries.
Previous PR: https://github.com/rust-lang/rust/pull/132410
A `ChunkedBitSet` has to be at least 2048 bits for it to outperform a
`BitSet`, because that's the chunk size. The largest `SparseBitMatrix`
encountered when compiling the compiler and the entire rustc-perf
benchmark suite is less than 600 bits.
This change is a tiny perf win, but the motivation is more about
avoiding uses of `ChunkedBitSet` outside of `MixedBitSet`.
The test change is necessary to avoid hitting the `<BitSet<T> as
BitRelations<ChunkedBitSet<T>>>::subtract` method that has
`unimplemented!` in its body and isn't otherwise used.
Remove unnecessary `int_type_width_signed` function
This can just use `Ty::int_size_and_signed` instead of making its own version.
You might want to look at this [ignoring whitespace](https://github.com/rust-lang/rust/pull/134020/files?w=1) since a huge bunch of code got un-indented.
Fix: typo in E0751 error explanation
Corrected a grammatical error in the explanation for E0751. Changed "exists" to "exist" to improve clarity and ensure proper grammar in the error message.
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.
Add allocate_bytes and refactor allocate_str in InterpCx for raw byte…
Fixes https://github.com/rust-lang/miri/issues/4025
This PR introduces a new `allocate_bytes` function in InterpCx and refactors `allocate_str` to use it internally. This change improves memory allocation handling in the interpreter by:
1. Adding `allocate_bytes`:
- Direct byte slice allocation support
- Handles both mutable and immutable allocations
- Maintains proper memory alignment and deduplication
2. Refactoring `allocate_str`:
- Now uses `allocate_bytes` internally
- Adds string-specific metadata handling
- Preserves existing string allocation behavior
This is part 1 of the planned changes to improve timezone string handling in Miri. A follow-up PR will update Miri's timezone logic to use this new allocation mechanism.
Related: https://github.com/rust-lang/miri/pull/4069
Add more info on type/trait mismatches for different crate versions
When encountering a type or trait mismatch for two types coming from two different crates with the same name, detect if it is either mixing two types/traits from the same crate on different versions:
```
error[E0308]: mismatched types
--> replaced
|
LL | do_something_type(Type);
| ----------------- ^^^^ expected `dependency::Type`, found `dep_2_reexport::Type`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub struct Type(pub i32);
| ^^^^^^^^^^^^^^^ this is the expected type `dependency::Type`
|
::: replaced
|
LL | pub struct Type;
| ^^^^^^^^^^^^^^^ this is the found type `dep_2_reexport::Type`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_type(_: Type) {}
| ^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> replaced
|
LL | do_something_trait(Box::new(Type) as Box<dyn Trait2>);
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `dependency::Trait2`, found trait `dep_2_reexport::Trait2`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the expected trait `dependency::Trait2`
|
::: replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the found trait `dep_2_reexport::Trait2`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_trait(_: Box<dyn Trait2>) {}
| ^^^^^^^^^^^^^^^^^^
```
or if it is different crates that were renamed to the same name:
```
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:21:20
|
LL | a::try_foo(foo2);
| ---------- ^^^^ expected `main:🅰️:Foo`, found a different `main:🅰️:Foo`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the found type `crate_a2::Foo`
|
::: $DIR/auxiliary/crate_a1.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the expected type `crate_a1::Foo`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one type comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one type comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:10:8
|
LL | pub fn try_foo(x: Foo){}
| ^^^^^^^
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:27:20
|
LL | a::try_bar(bar2);
| ---------- ^^^^ expected trait `main:🅰️:Bar`, found a different trait `main:🅰️:Bar`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the found trait `crate_a2::Bar`
|
::: $DIR/auxiliary/crate_a1.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the expected trait `crate_a1::Bar`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one trait comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one trait comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:11:8
|
LL | pub fn try_bar(x: Box<Bar>){}
| ^^^^^^^
```
This new output unifies the E0308 errors detail with the pre-existing E0277 errors, and better differentiates the "`extern crate` renamed" and "same crate, different versions" cases.
lint: change help for pointers to dyn types in FFI
### Context
while playing around, I encountered the warning for dyn types in `extern "C"` functions, but even after that I assumed that a (rust) raw pointer could be interpreted in C ('s ABI) as a `void *`... to be fair part of why I ignored the warning is because I wanted to poke at the generated assembly, not make useful code.
### Example
```rust
extern "C"
fn caller(callee: *const dyn Fn(i32)->i32){
// -- snip --
}
```
old warning:
```
warning: `extern` fn uses type `dyn Fn(i32) -> i32`, which is not FFI-safe
--> file/name.rs:42:19
|
42 | fn caller(callee: *const dyn Fn(i32)->i32) {
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: trait objects have no C equivalent
= note: `#[warn(improper_ctypes_definitions)]` on by default
```
new warning:
```
warning: `extern` fn uses type `dyn Fn(i32) -> i32`, which is not FFI-safe
--> file/name.rs:42:19
|
42 | fn caller(callee: *const dyn Fn(i32)->i32) -> (){
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: this pointer to an unsized type contains metadata, which makes it incompatible with a C pointer
= note: `#[warn(improper_ctypes_definitions)]` on by default
```
This query (`coverage_ids_info`) already determines which counter/expression
IDs are unused, so it only takes a little extra effort to also determine which
counters/expressions must have a value of zero.
On nightly, we mention the trait is unstable
```
error[E0277]: the trait bound `T: Unstable` is not satisfied
--> $DIR/unstable-trait-suggestion.rs:13:9
|
LL | foo(t)
| --- ^ the trait `Unstable` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/unstable-trait-suggestion.rs:9:11
|
LL | fn foo<T: Unstable>(_: T) {}
| ^^^^^^^^ required by this bound in `foo`
help: consider restricting type parameter `T` but it is an `unstable` trait
|
LL | pub fn demo<T: Unstable>(t: T) {
| ++++++++++
```
On stable, we don't suggest the trait at all
```
error[E0277]: the trait bound `T: Unstable` is not satisfied
--> $DIR/unstable-trait-suggestion.rs:13:9
|
LL | foo(t)
| --- ^ the trait `Unstable` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/unstable-trait-suggestion.rs:9:11
|
LL | fn foo<T: Unstable>(_: T) {}
| ^^^^^^^^ required by this bound in `foo`
```
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
When encountering a type or trait mismatch for two types coming from two different crates with the same name, detect if it is either mixing two types/traits from the same crate on different versions:
```
error[E0308]: mismatched types
--> replaced
|
LL | do_something_type(Type);
| ----------------- ^^^^ expected `dependency::Type`, found `dep_2_reexport::Type`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub struct Type(pub i32);
| ^^^^^^^^^^^^^^^ this is the expected type `dependency::Type`
|
::: replaced
|
LL | pub struct Type;
| ^^^^^^^^^^^^^^^ this is the found type `dep_2_reexport::Type`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_type(_: Type) {}
| ^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> replaced
|
LL | do_something_trait(Box::new(Type) as Box<dyn Trait2>);
| ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `dependency::Trait2`, found trait `dep_2_reexport::Trait2`
| |
| arguments to this function are incorrect
|
note: two different versions of crate `dependency` are being used; two types coming from two different versions of the same crate are different types even if they look the same
--> replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the expected trait `dependency::Trait2`
|
::: replaced
|
LL | pub trait Trait2 {}
| ^^^^^^^^^^^^^^^^ this is the found trait `dep_2_reexport::Trait2`
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
= help: you can use `cargo tree` to explore your dependency tree
note: function defined here
--> replaced
|
LL | pub fn do_something_trait(_: Box<dyn Trait2>) {}
| ^^^^^^^^^^^^^^^^^^
```
or if it is different crates that were renamed to the same name:
```
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:21:20
|
LL | a::try_foo(foo2);
| ---------- ^^^^ expected `main:🅰️:Foo`, found a different `main:🅰️:Foo`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the found type `crate_a2::Foo`
|
::: $DIR/auxiliary/crate_a1.rs:1:1
|
LL | pub struct Foo;
| ^^^^^^^^^^^^^^ this is the expected type `crate_a1::Foo`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one type comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one type comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:10:8
|
LL | pub fn try_foo(x: Foo){}
| ^^^^^^^
error[E0308]: mismatched types
--> $DIR/type-mismatch-same-crate-name.rs:27:20
|
LL | a::try_bar(bar2);
| ---------- ^^^^ expected trait `main:🅰️:Bar`, found a different trait `main:🅰️:Bar`
| |
| arguments to this function are incorrect
|
note: two types coming from two different crates are different types even if they look the same
--> $DIR/auxiliary/crate_a2.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the found trait `crate_a2::Bar`
|
::: $DIR/auxiliary/crate_a1.rs:3:1
|
LL | pub trait Bar {}
| ^^^^^^^^^^^^^ this is the expected trait `crate_a1::Bar`
|
::: $DIR/type-mismatch-same-crate-name.rs:13:17
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
| --------------------------- one trait comes from crate `crate_a2` is used here, which is renamed locally to `a`
...
LL | extern crate crate_a1 as a;
| --------------------------- one trait comes from crate `crate_a1` is used here, which is renamed locally to `a`
note: function defined here
--> $DIR/auxiliary/crate_a1.rs:11:8
|
LL | pub fn try_bar(x: Box<Bar>){}
| ^^^^^^^
```
This new output unifies the E0308 errors detail with the pre-existing E0277 errors, and better differentiates the "`extern crate` renamed" and "same crate, different versions" cases.
Remove a lit_to_const call
We have so many special cases of `match expr.kind { Lit() => {}, Unary(Neg, Lit()) => {} }`... I'm trying to figure out how to get these all unified, but outright removing some is good, too. So let's try it.
Tho we don't have many `const {}` blocks in the perf test suite... But I also don't know how common `const { 42 }` blocks are, I'd expect these to occur mostly from macros (like `thread_local!`)
Corrected a grammatical error in the explanation for E0751. Changed "exists" to "exist" to improve clarity and ensure proper grammar in the error message.
Hide errors whose suggestions would contain error constants or types
best reviewed commit-by-commit.
This is work towards cleaning up everything around `lit_to_const` and its mir equivalent.
fixes#123809
Do not implement unsafe auto traits for types with unsafe fields
If a type has unsafe fields, its safety invariants are not simply the conjunction of its field types' safety invariants. Consequently, it's invalid to reason about the safety properties of these types in a purely structural manner — i.e., the manner in which `auto` traits are implemented. Consequently, auto implementations of unsafe auto traits should not be generated for types with unsafe fields.
Tracking: #132922
r? `@compiler-errors`
It was inconsistently done (sometimes even within a single function) and
most of the rest of the compiler uses fatal errors instead, which need
to be caught using catch_with_exit_code anyway. Using fatal errors
instead of ErrorGuaranteed everywhere in the driver simplifies things a
bit.
Sync cg clif 2024 12 06
The main highlights this time are a Cranelift update disabling the clif ir verifier by default for better performance.
r? `@ghost`
`@rustbot` label +A-codegen +A-cranelift +T-compiler
Only allow PassMode::Direct for aggregates on wasm when using the C ABI
For the Rust ABI we don't have any ABI compat reasons to allow PassMode::Direct for aggregates.
Extend Miri to correctly pass mutable pointers through FFI
Based off of https://github.com/rust-lang/rust/pull/129684, this PR further extends Miri to execute native calls that make use of pointers to *mutable* memory.
We adapt Miri's bookkeeping of internal state upon any FFI call that gives external code permission to mutate memory.
Native code may now possibly write and therefore initialize and change the pointer provenance of bytes it has access to: Such memory is assumed to be *initialized* afterwards and bytes are given *arbitrary (wildcard) provenance*. This enables programs that correctly use mutating FFI calls to run Miri without errors, at the cost of possibly missing Undefined Behaviour caused by incorrect usage of mutating FFI.
> <details>
>
> <summary> Simple example </summary>
>
> ```rust
> extern "C" {
> fn init_int(ptr: *mut i32);
> }
>
> fn main() {
> let mut x = std::mem::MaybeUninit::<i32>::uninit();
> let x = unsafe {
> init_int(x.as_mut_ptr());
> x.assume_init()
> };
>
> println!("C initialized my memory to: {x}");
> }
> ```
> ```c
> void init_int(int *ptr) {
> *ptr = 42;
> }
> ```
> should now show `C initialized my memory to: 42`.
>
> </details>
r? ``@RalfJung``
rust_for_linux: -Zreg-struct-return commandline flag for X86 (#116973)
Command line flag `-Zreg-struct-return` for X86 (32-bit) for rust-for-linux.
This flag enables the same behavior as the `abi_return_struct_as_int` target spec key.
- Tracking issue: https://github.com/rust-lang/rust/issues/116973
If a type has unsafe fields, its safety invariants are not simply
the conjunction of its field types' safety invariants. Consequently,
it's invalid to reason about the safety properties of these types
in a purely structural manner — i.e., the manner in which `auto`
traits are implemented.
Makes progress towards #132922.
implement checks for tail calls
Quoting the [RFC draft](https://github.com/phi-go/rfcs/blob/guaranteed-tco/text/0000-explicit-tail-calls.md):
> The argument to become is a function (or method) call, that exactly matches the function signature and calling convention of the callee. The intent is to ensure a matching ABI. Note that lifetimes may differ as long as they pass borrow checking, see [below](https://github.com/phi-go/rfcs/blob/guaranteed-tco/text/0000-explicit-tail-calls.md#return-type-coercion) for specifics on the return type.
> Tail calling closures and tail calling from closures is not allowed. This is due to the high implementation effort, see below, this restriction can be lifted by a future RFC.
> Invocations of operators were considered as valid targets but were rejected on grounds of being too error-prone. In any case, these can still be called as methods.
> Tail calling [variadic functions](https://doc.rust-lang.org/beta/unstable-book/language-features/c-variadic.html) and tail calling from variadic functions is not allowed. As support for variadic function is stabilized on a per target level, support for tail-calls regarding variadic functions would need to follow a similar approach. To avoid this complexity and to minimize implementation effort for backends, this interaction is currently not allowed but support can be added with a future RFC.
-----
The checks are implemented as a query, similarly to `check_unsafety`.
The code is cherry-picked straight out of #112657 which was written more than a year ago, so I expect we might need to change some things ^^"
Fix "std" support status of some tier 3 targets
https://github.com/rust-lang/rust/pull/127265 marked targets with empty "std" support status as no-std targets in target-spec metadata:
> * Where a targets 'std' or 'host tools' support is listed as '?' in the rust docs, these are left as 'None' with this PR. The corresponding changes in cargo will only reject an attempt to build std if the 'std' field is 'Some(false)'. In the case it is 'None', cargo will continue trying to build
However, this is not accurate because "std" support status has a marker indicating that it is a no-std target. (empty status is just invalid.)
https://doc.rust-lang.org/nightly/rustc/platform-support.html#tier-3
> The `std` column in the table below has the following meanings:
>
> * ✓ indicates the full standard library is available.
> * \* indicates the target only supports [`no_std`] development.
> * ? indicates the standard library support is unknown or a work-in-progress.
>
> [`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
This PR fixes the status of targets whose "std" support status is currently set to empty and update target-spec metadata.
The new status is set based on the following criteria:
- Set to ✓ for targets that I regularly check in [rust-cross-toolchain](https://github.com/taiki-e/rust-cross-toolchain) that the `cargo test` works. (riscv32-unknown-linux-gnu,{riscv64,s390x}-unknown-linux-musl)
- Targets where `cargo run` works but `cargo test` does not work tend to have incomplete std support (e.g., riscv32 musl f3068b66e0), so I included them in the group below that means “work in progress” rather than in this group.
- Set powerpc64le FreeBSD to ✓ on both std and host_tools, because the [Rust package](https://www.freshports.org/lang/rust/) is available.
- Set to ? (which means "unknown" or “work in progress”) for all other affected targets because these are Linux, Android, FreeBSD, or Fuchsia, all of which are operating systems that support std if properly supported.
r? Noratrieb
cc ``@harmou01``
It's a performance win because `MixedBitSet` is faster and uses less
memory than `ChunkedBitSet`.
Also reflow some overlong comment lines in
`lint_tail_expr_drop_order.rs`.
It just uses `BitSet` for small/medium sizes (<= 2048 bits) and
`ChunkedBitSet` for larger sizes. This is good because `ChunkedBitSet`
is slow and memory-hungry at smaller sizes.
Rollup of 10 pull requests
Successful merges:
- #118833 (Add lint against function pointer comparisons)
- #122161 (Fix suggestion when shorthand `self` has erroneous type)
- #133233 (Add context to "const in pattern" errors)
- #133761 (Update books)
- #133843 (Do not emit empty suggestion)
- #133863 (Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro`)
- #133872 (No need to create placeholders for GAT args in confirm_object_candidate)
- #133874 (`fn_sig_for_fn_abi` should return a `ty::FnSig`, no need for a binder)
- #133890 (Add a new test ui/incoherent-inherent-impls/no-other-unrelated-errors to check E0116 does not cause unrelated errors)
- #133892 (Revert #133817)
r? `@ghost`
`@rustbot` modify labels: rollup
No need to create placeholders for GAT args in confirm_object_candidate
We no longer need this logic to add placeholders for GAT args since with the removal of the `gat_extended` feature gate (https://github.com/rust-lang/rust/pull/133768) we no longer allow GATs in dyn trait anyways.
r? oli-obk
Do not emit empty suggestion
The `println!();` statement's span doesn't include the `;`, and the modified suggestions where trying to get the `;` by getting the differenece between the statement's and the expression's spans, which was an empty suggestion.
Fix#133833, fix#133834.
Add context to "const in pattern" errors
*Each commit addresses specific diagnostics.*
- Add primary span labels
- Point at `const` item, and `const` generic param definition
- Reword messages and notes
- Point at generic param through which an associated `const` is being referenced
- Silence const in pattern with evaluation errors when they come from `const` items that already emit a diagnostic
- On non-structural type in const used as pattern, point at the type that should derive `PartialEq`
Add lint against function pointer comparisons
This is kind of a follow-up to https://github.com/rust-lang/rust/pull/117758 where we added a lint against wide pointer comparisons for being ambiguous and unreliable; well function pointer comparisons are also unreliable. We should IMO follow a similar logic and warn people about it.
-----
## `unpredictable_function_pointer_comparisons`
*warn-by-default*
The `unpredictable_function_pointer_comparisons` lint checks comparison of function pointer as the operands.
### Example
```rust
fn foo() {}
let a = foo as fn();
let _ = a == foo;
```
### Explanation
Function pointers comparisons do not produce meaningful result since they are never guaranteed to be unique and could vary between different code generation units. Furthermore different function could have the same address after being merged together.
----
This PR also uplift the very similar `clippy::fn_address_comparisons` lint, which only linted on if one of the operand was an `ty::FnDef` while this PR lints proposes to lint on all `ty::FnPtr` and `ty::FnDef`.
```@rustbot``` labels +I-lang-nominated
~~Edit: Blocked on https://github.com/rust-lang/libs-team/issues/323 being accepted and it's follow-up pr~~
Make sure to record deps from cached task in new solver on first run
We weren't actually performing a read of the dep node in `with_cached_task` in the new solver, which meant that all queries that computed a goal for the first time were just not recording the query dependencies that we call in that query.
In the incremental test, the typeck query for `fn poll` isn't being marked red even tho it's invalidated due to its writeback results changing. This happens b/c we normalize `Self::Error` into `Error`, which should call `type_of` which is a red query (since `ty::Adt` contains an `AdtDef`, and that `AdtDef`'s stable hash changes since it's ). However, since we weren't tracking deps in that normalize query, the typeck result was remaining green, and we were trying to decode a def id that no longer exists (the field that got removed).
r? lcnr
Point at types that need to be marked with `#[derive(PartialEq)]`.
We use a visitor to look at a type that isn't structural, looking for all ADTs that don't derive `PartialEq`. These can either be manual `impl PartialEq`s or no `impl` at all, so we differentiate between those two cases to provide more context to the user. We also only point at types and impls from the local crate, otherwise show only a note.
```
error: constant of non-structural type `&[B]` in a pattern
--> $DIR/issue-61188-match-slice-forbidden-without-eq.rs:15:9
|
LL | struct B(i32);
| -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
LL |
LL | const A: &[B] = &[];
| ------------- constant defined here
...
LL | A => (),
| ^ constant of non-structural type
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
```
- Point at type that should derive `PartialEq` to be structural.
- Point at manual `impl PartialEq`, explaining that it is not sufficient to be structural.
```
error: constant of non-structural type `MyType` in a pattern
--> $DIR/const-partial_eq-fallback-ice.rs:14:12
|
LL | struct MyType;
| ------------- `MyType` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
LL | const CONSTANT: &&MyType = &&MyType;
| ------------------------ constant defined here
...
LL | if let CONSTANT = &&MyType {
| ^^^^^^^^ constant of non-structural type
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
--> $DIR/const-partial_eq-fallback-ice.rs:5:1
|
LL | impl PartialEq<usize> for MyType {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
```
error: trait object `dyn Send` cannot be used in patterns
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
LL | const F: &'static dyn Send = &7u32;
| -------------------------- constant defined here
...
LL | F => panic!(),
| ^ trait object can't be used in patterns
```
- Add primary span labels.
- Point at const generic parameter used as pattern.
- Point at statics used as pattern.
- Point at let bindings used in const pattern.
Centralize emitting an error in `const_to_pat` so that all errors from that evaluating a `const` in a pattern can add addditional information. With this, now point at the `const` item's definition:
```
error[E0158]: constant pattern depends on a generic parameter
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | A::X => println!("A::X"),
| ^^^^
```
The `println!();` statement's span doesn't include the `;`, and the modified suggestions where trying to get the `;` by getting the differenece between the statement's and the expression's spans, which was an empty suggestion.
Fix#133833, fix#133834.
Avoid `opaque type not constrained` errors in the presence of other errors
pulled out of https://github.com/rust-lang/rust/pull/128440
These errors carry no new information if the opaque type was actually used in a constraining (but erroneous) way somewhere.
coverage: Use a separate counter type and simplification step during counter creation
When instrumenting a function's MIR for coverage, there is a point where we need to decide, for each node in the control-flow graph, whether its execution count will be tracked by a physical counter, or by an expression that combines physical counters from other parts of the graph.
Currently the code for doing that is heavily tied to the final form of the LLVM coverage mapping format, and performs some important simplification steps on-the-fly. These factors make the code extremely difficult to modify without breaking or massively worsening the resulting coverage-instrumentation metadata.
---
This PR aims to improve that situation somewhat by adding an extra intermediate representation between the code that chooses how each node will be counted, and the code that converts those decisions into actual tables of physical counters and trees of counter expressions.
As part of doing that, some of the simplifications that are currently performed during the main counter creation step have been pulled out into a separate step.
In most cases the resulting coverage metadata is equivalent, slightly better, or slightly worse. The biggest outlier is `counters.rs`, where the coverage metadata ends up about 10% larger. This seems to be the result of the new approach having less subexpression sharing (because it relies on flatten-sort-cancel), and therefore being less effective at taking advantage of MIR optimizations to replace counters for unused control-flow with zeroes. I think the modest downside is acceptable in light of the future possibilities opened up by this decoupling.
Remove `-Zshow-span`.
It's very old (added in #12087). It's strange, and it's not clear what its use cases are. It only works with the crate root file because it runs before expansion. I suspect it won't be missed.
r? `@estebank`
Don't try and handle unfed `type_of` on anon consts
The `type_of` query for anon consts in the type system is actually implemented by feeding the return value during hir ty lowering, not the hir-based logic in `const_arg_anon_type_of`. The HIR based logic is incomplete (doesn't handle all hir nodes) and also generally wrong to call (re-lowers HIR or invokes typeck which can result in query cycles).
r? `@compiler-errors`
Make CoercePointee errors translatable
Tracked by #123430
Just in case that a translatable error message would become a blocker to stabilization, this PR switches over to fluent error messages, which also slightly improve the wordings and use more accurate span information.
cc `@Darksonn` `@traviscross`
It's very old (added in #12087). It's strange, and it's not clear what
its use cases are. It only works with the crate root file because it
runs before expansion. I suspect it won't be missed.