By just emitting them immediately, because it does happen in practice,
when errors are downgraded to delayed bugs.
We already had one case in `lint.rs` where we handled this at the
callsite. This commit changes things so it's handled within
`stash_diagnostic` instead, because #121812 identified a second case,
and it's possible there are more.
Fixes#121812.
change equate for binders to not rely on subtyping
*summary by `@spastorino` and `@lcnr*`
### Context
The following code:
```rust
type One = for<'a> fn(&'a (), &'a ());
type Two = for<'a, 'b> fn(&'a (), &'b ());
mod my_api {
use std::any::Any;
use std::marker::PhantomData;
pub struct Foo<T: 'static> {
a: &'static dyn Any,
_p: PhantomData<*mut T>, // invariant, the type of the `dyn Any`
}
impl<T: 'static> Foo<T> {
pub fn deref(&self) -> &'static T {
match self.a.downcast_ref::<T>() {
None => unsafe { std::hint::unreachable_unchecked() },
Some(a) => a,
}
}
pub fn new(a: T) -> Foo<T> {
Foo::<T> {
a: Box::leak(Box::new(a)),
_p: PhantomData,
}
}
}
}
use my_api::*;
fn main() {
let foo = Foo::<One>::new((|_, _| ()) as One);
foo.deref();
let foo: Foo<Two> = foo;
foo.deref();
}
```
has UB from hitting the `unreachable_unchecked`. This happens because `TypeId::of::<One>()` is not the same as `TypeId::of::<Two>()` despite them being considered the same types by the type checker.
Currently the type checker considers binders to be equal if subtyping succeeds in both directions: `for<'a> T<'a> eq for<'b> U<'b>` holds if `for<'a> exists<'b> T<'b> <: T'<a> AND for<'b> exists<'a> T<'a> <: T<'b>` holds. This results in `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` being equal in the type system.
`TypeId` is computed by looking at the *structure* of a type. Even though these types are semantically equal, they have a different *structure* resulting in them having different `TypeId`. This can break invariants of unsafe code at runtime and is unsound when happening at compile time, e.g. when using const generics.
So as seen in `main`, we can assign a value of type `Foo::<One>` to a binding of type `Foo<Two>` given those are considered the same type but then when we call `deref`, it calls `downcast_ref` that relies on `TypeId` and we would hit the `None` arm as these have different `TypeId`s.
As stated in https://github.com/rust-lang/rust/issues/97156#issuecomment-1879030033, this causes the API of existing crates to be unsound.
## What should we do about this
The same type resulting in different `TypeId`s is a significant footgun, breaking a very reasonable assumptions by authors of unsafe code. It will also be unsound by itself once they are usable in generic contexts with const generics.
There are two options going forward here:
- change how the *structure* of a type is computed before relying on it. i.e. continue considering `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` to be equal, but normalize them to a common representation so that their `TypeId` are also the same.
- change how the semantic equality of binders to match the way we compute the structure of types. i.e. `for<'a> fn(&'a (), &'a ())` and `for<'a, 'b> fn(&'a (), &'b ())` still have different `TypeId`s but are now also considered to not be semantically equal.
---
Advantages of the first approach:
- with the second approach some higher ranked types stop being equal, even though they are subtypes of each other
General thoughts:
- changing the approach in the future will be breaking
- going from first to second may break ordinary type checking, as types which were previously equal are now distinct
- going from second to first may break coherence, because previously disjoint impls overlap as the used types are now equal
- both of these are quite unlikely. This PR did not result in any crater failures, so this should not matter too much
Advantages of the second approach:
- the soundness of the first approach requires more non-local reasoning. We have to make sure that changes to subtyping do not cause the representative computation to diverge from semantic equality
- e.g. we intend to consider higher ranked implied bounds when subtyping to [fix] https://github.com/rust-lang/rust/issues/25860, I don't know how this will interact and don't feel confident making any prediction here.
- computing a representative type is non-trivial and soundness critical, therefore adding complexity to the "core type system"
---
This PR goes with the second approach. A crater run did not result in any regressions. I am personally very hesitant about trying the first approach due to the above reasons. It feels like there are more unknowns when going that route.
### Changing the way we equate binders
Relating bound variables from different depths already results in a universe error in equate. We therefore only need to make sure that there is 1-to-1 correspondence between bound variables when relating binders. This results in concrete types being structurally equal after anonymizing their bound variables.
We implement this by instantiating one of the binder with placeholders and the other with inference variables and then equating the instantiated types. We do so in both directions.
More formally, we change the typing rules as follows:
```
for<'r0, .., 'rn> exists<'l0, .., 'ln> LHS<'l0, .., 'ln> <: RHS<'r0, .., 'rn>
for<'l0, .., 'ln> exists<'r0, .., 'rn> RHS<'r0, .., 'rn> <: LHS<'l0, .., 'ln>
--------------------------------------------------------------------------
for<'l0, .., 'ln> LHS<'l0, .., 'ln> eq for<'r0, .., 'rn> RHS<'r0, .., 'rn>
```
to
```
for<'r0, .., 'rn> exists<'l0, .., 'ln> LHS<'l0, .., 'ln> eq RHS<'r0, .., 'rn>
for<'l0, .., 'ln> exists<'r0, .., 'rn> RHS<'r0, .., 'rn> eq LHS<'l0, .., 'ln>
--------------------------------------------------------------------------
for<'l0, .., 'ln> LHS<'l0, .., 'ln> eq for<'r0, .., 'rn> RHS<'r0, .., 'rn>
```
---
Fixes#97156
r? `@lcnr`
Count stashed errors again
Stashed diagnostics are such a pain. Their "might be emitted, might not" semantics messes with lots of things.
#120828 and #121206 made some big changes to how they work, improving some things, but still leaving some problems, as seen by the issues caused by #121206. This PR aims to fix all of them by restricting them in a way that eliminates the "might be emitted, might not" semantics while still allowing 98% of their benefit. Details in the individual commit logs.
r? `@oli-obk`
Deeply normalize obligations in `refining_impl_trait`
We somewhat awkwardly use semantic comparison when checking the `refining_impl_trait` lint. This relies on us being able to normalize bounds eagerly to avoid cases where an unnormalized alias is not considered equal to a normalized alias. Since `normalize` in the new solver is a noop, let's use `deeply_normalize` instead.
r? lcnr
cc ``@tmandry,`` this should fix your bug lol
Stashed errors used to be counted as errors, but could then be
cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed
that, closing the soundness hole. But it introduced other difficulties
because you sometimes have to account for pending stashed errors when
making decisions about whether errors have occured/will occur and it's
easy to overlook these.
This commit aims for a middle ground.
- Stashed errors (not warnings) are counted immediately as emitted
errors, avoiding the possibility of forgetting to consider them.
- The ability to cancel (or downgrade) stashed errors is eliminated, by
disallowing the use of `steal_diagnostic` with errors, and introducing
the more restrictive methods `try_steal_{modify,replace}_and_emit_err`
that can be used instead.
Other things:
- `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both
return `Option<ErrorGuaranteed>`, which enables the removal of two
`delayed_bug` calls and one `Ty::new_error_with_message` call. This is
possible because we store error guarantees in
`DiagCtxt::stashed_diagnostics`.
- Storing the guarantees also saves us having to maintain a counter.
- Calls to the `stashed_err_count` method are no longer necessary
alongside calls to `has_errors`, which is a nice simplification, and
eliminates two more `span_delayed_bug` calls and one FIXME comment.
- Tests are added for three of the four fixed PRs mentioned below.
- `issue-121108.rs`'s output improved slightly, omitting a non-useful
error message.
Fixes#121451.
Fixes#121477.
Fixes#121504.
Fixes#121508.
Diagnostic renaming
Renaming various diagnostic types from `Diagnostic*` to `Diag*`. Part of https://github.com/rust-lang/compiler-team/issues/722. There are more to do but this is enough for one PR.
r? `@davidtwco`
Split rustc_type_ir to avoid rustc_ast from depending on it
unblocks #121576
and resolves a FIXME in `rustc_ast`'s `Cargo.toml`
The new crate is tiny, but it will get bigger in #121576
Delayed bug audit
I went through all the calls to `delayed_bug` and `span_delayed_bug` and found a few places where they could be avoided.
r? `@compiler-errors`
rename 'try' intrinsic to 'catch_unwind'
The intrinsic has nothing to do with `try` blocks, and corresponds to the stable `catch_unwind` function, so this makes a lot more sense IMO.
Also rename Miri's special function while we are at it, to reflect the level of abstraction it works on: it's an unwinding mechanism, on which Rust implements panics.
Fix more #121208 fallout (round 3)
#121208 converted lots of delayed bugs to bugs. Unsurprisingly, there were a few invalid conversion found via fuzzing.
r? `@lcnr`
Prevent cycle in implied predicates computation
Makes #65913 from hang -> fail. I believe fail is the correct state for this test to remain for the long term.
Add newtypes for bool fields/params/return types
Fixed all the cases of this found with some simple searches for `*/ bool` and `bool /*`; probably many more
Don't ICE on anonymous struct in enum variant
Fixes#121446
Computing `adt_def` for the anon struct calls `adt_def` on the parent to find its repr. If the parent is a non-item (e.g. an enum variant) we should have already emitted at least one error, so we just use the repr of the anonymous struct to avoid an ICE.
cc ``@frank-king``
Fix more #121208 fallout
#121208 converted lots of delayed bugs to bugs. Unsurprisingly, there were a few invalid conversion found via fuzzing.
r? `@lcnr`
Add "algebraic" fast-math intrinsics, based on fast-math ops that cannot return poison
Setting all of LLVM's fast-math flags makes our fast-math intrinsics very dangerous, because some inputs are UB. This set of flags permits common algebraic transformations, but according to the [LangRef](https://llvm.org/docs/LangRef.html#fastmath), only the flags `nnan` (no nans) and `ninf` (no infs) can produce poison.
And this uses the algebraic float ops to fix https://github.com/rust-lang/rust/issues/120720
cc `@orlp`
Convert `delayed_bug`s to `bug`s.
I have a suspicion that quite a few delayed bug paths are impossible to reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite, then converted back every `bug` that was hit. A surprising number were never hit.
This is too dangerous to merge. Increased coverage (fuzzing or a crater run) would likely hit more cases. But it might be useful for people to look at and think about which paths are genuinely unreachable.
r? `@ghost`
Warn (or error) when `Self` ctor from outer item is referenced in inner nested item
This implements a warning `SELF_CONSTRUCTOR_FROM_OUTER_ITEM` when a self constructor from an outer impl is referenced in an inner nested item. This is a proper fix mentioned https://github.com/rust-lang/rust/pull/117246#discussion_r1374648388.
This warning is additionally bumped to a hard error when the self type references generic parameters, since it's almost always going to ICE, and is basically *never* correct to do.
This also reverts part of https://github.com/rust-lang/rust/pull/117246, since I believe this is the proper fix and we shouldn't need the helper functions (`opt_param_at`/`opt_type_param`) any longer, since they shouldn't really ever be used in cases where we don't have this problem.
I have a suspicion that quite a few delayed bug paths are impossible to
reach, so I did an experiment.
I converted every `delayed_bug` to a `bug`, ran the full test suite,
then converted back every `bug` that was hit. A surprising number were
never hit.
The next commit will convert some more back, based on human judgment.
Overhaul `Diagnostic` and `DiagnosticBuilder`
Implements the first part of https://github.com/rust-lang/compiler-team/issues/722, which moves functionality and use away from `Diagnostic`, onto `DiagnosticBuilder`.
Likely follow-ups:
- Move things around, because this PR was written to minimize diff size, so some things end up in sub-optimal places. E.g. `DiagnosticBuilder` has impls in both `diagnostic.rs` and `diagnostic_builder.rs`.
- Rename `Diagnostic` as `DiagInner` and `DiagnosticBuilder` as `Diag`.
r? `@davidtwco`
Always evaluate free constants and statics, even if previous errors occurred
work towards https://github.com/rust-lang/rust/issues/79738
We will need to evaluate static items before the `definitions.freeze()` below, as we will start creating new `DefId`s (for nested allocations) within the `eval_static_initializer` query.
But even without that motivation, this is a good change. Hard errors should always be reported and not silenced if other errors happened earlier.
Drive-by `DUMMY_SP` -> `Span` and fmt changes
Noticed these while doing something else. There's no practical change, but it's preferable to use `DUMMY_SP` as little as possible, particularly when we have perfectlly useful `Span`s available.
Change leak check and suspicious auto trait lint warning messages
The leak check lint message "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" is misleading as some cases may not be phased out and could end being accepted. This is under discussion still.
The suspicious auto trait lint the change in behavior already happened, so the new message is probably more accurate.
r? `@lcnr`
Closes#93367
Noticed these while doing something else. There's no practical change, but it's preferable to use `DUMMY_SP` as little as possible, particularly when we have perfectlly useful `Span`s available.
There are lots of functions that modify a diagnostic. This can be via a
`&mut Diagnostic` or a `&mut DiagnosticBuilder`, because the latter type
wraps the former and impls `DerefMut`.
This commit converts all the `&mut Diagnostic` occurrences to `&mut
DiagnosticBuilder`. This is a step towards greatly simplifying
`Diagnostic`. Some of the relevant function are made generic, because
they deal with both errors and warnings. No function bodies are changed,
because all the modifier methods are available on both `Diagnostic` and
`DiagnosticBuilder`.
Add help to `hir_analysis_unrecognized_intrinsic_function`
To help remind forgetful people like me what step they forgot.
(If this just ICE'd, https://github.com/rust-lang/compiler-team/issues/620 style, the stack trace would point me here, but since there's a "nice" error that information is lost.)
Tracking import use types for more accurate redundant import checking
fixes#117448
By tracking import use types to check whether it is scope uses or the other situations like module-relative uses, we can do more accurate redundant import checking.
For example unnecessary imports in std::prelude that can be eliminated:
```rust
use std::option::Option::Some;//~ WARNING the item `Some` is imported redundantly
use std::option::Option::None; //~ WARNING the item `None` is imported redundantly
```
fixes#117448
For example unnecessary imports in std::prelude that can be eliminated:
```rust
use std::option::Option::Some;//~ WARNING the item `Some` is imported redundantly
use std::option::Option::None; //~ WARNING the item `None` is imported redundantly
```
Rollup of 7 pull requests
Successful merges:
- #120526 (rustdoc: Correctly handle long crate names on mobile)
- #121100 (Detect when method call on argument could be removed to fulfill failed trait bound)
- #121160 (rustdoc: fix and refactor HTML rendering a bit)
- #121198 (Add more checks for `unnamed_fields` during HIR analysis)
- #121218 (Fix missing trait impls for type in rustc docs)
- #121221 (AstConv: Refactor lowering of associated item bindings a bit)
- #121237 (Use better heuristic for printing Cargo specific diagnostics)
r? `@ghost`
`@rustbot` modify labels: rollup
AstConv: Refactor lowering of associated item bindings a bit
Split off from #119385 as discussed, namely the first two commits (modulo one `FIXME` getting turned into a `NOTE`).
The second commit removes `astconv::ConvertedBinding{,Kind}` in favor of `hir::TypeBinding{,Kind}`. The former was a — in my opinion — super useless intermediary. As you can tell from the diff, its removal shaves off some code. Furthermore, yeeting it will make it easier to implement the type resolution fixes in #119385.
Nothing in this PR should have any semantic effect.
r? `@compiler-errors`
<sub>**Addendum** as in #118668: What I call “associated item bindings” are commonly referred to as “type bindings” for historical reasons. Nowadays, “type bindings” include assoc type bindings, assoc const bindings and RTN (return type notation) which is why I prefer not to use this outdated term.</sub>
Properly deal with weak alias types as self types of impls
Fixes#114216.
Fixes#116100.
Not super happy about the two ad hoc “normalization” implementations for weak alias types:
1. In `inherent_impls`: The “peeling”, normalization to [“WHNF”][whnf]: Semantically that's exactly what we want (neither proper normalization nor shallow normalization would be correct here). Basically a weak alias type is “nominal” (well...^^) if the WHNF is nominal. [#97974](https://github.com/rust-lang/rust/pull/97974) followed the same approach.
2. In `constrained_generic_params`: Generic parameters are constrained by a weak alias type if the corresp. “normalized” type constrains them (where we only normalize *weak* alias types not arbitrary ones). Weak alias types are injective if the corresp. “normalized” type is injective.
Both have ad hoc overflow detection mechanisms.
**Coherence** is handled in #117164.
r? `@oli-obk` or types
[whnf]: https://en.wikipedia.org/wiki/Lambda_calculus_definition#Weak_head_normal_form
Implement intrinsics with fallback bodies
fixes#93145 (though we can port many more intrinsics)
cc #63585
The way this works is that the backend logic for generating custom code for intrinsics has been made fallible. The only failure path is "this intrinsic is unknown". The `Instance` (that was `InstanceDef::Intrinsic`) then gets converted to `InstanceDef::Item`, which represents the fallback body. A regular function call to that body is then codegenned. This is currently implemented for
* codegen_ssa (so llvm and gcc)
* codegen_cranelift
other backends will need to adjust, but they can just keep doing what they were doing if they prefer (though adding new intrinsics to the compiler will then require them to implement them, instead of getting the fallback body).
cc `@scottmcm` `@WaffleLapkin`
### todo
* [ ] miri support
* [x] default intrinsic name to name of function instead of requiring it to be specified in attribute
* [x] make sure that the bodies are always available (must be collected for metadata)
Continue compilation after check_mod_type_wf errors
The ICEs fixed here were probably reachable through const eval gymnastics before, but now they are easily reachable without that, too.
The new errors are often bugfixes, where useful errors were missing, because they were reported after the early abort. In other cases sometimes they are just duplication of already emitted errors, which won't be user-visible due to deduplication.
fixes https://github.com/rust-lang/rust/issues/120860
Use fewer delayed bugs.
For some cases where it's clear that an error has already occurred, e.g.:
- there's a comment stating exactly that, or
- things like HIR lowering, where we are lowering an error kind
The commit also tweaks some comments around delayed bug sites.
r? `@oli-obk`
Be less confident when `dyn` suggestion is not checked for object safety
#120275 no longer checks bare traits for object safety when making a `dyn` suggestion on Rust < 2021. In this case, qualify the suggestion with a note that the trait must be object safe, to prevent user confusion as seen in #116434
r? ```@fmease```
For some cases where it's clear that an error has already occurred,
e.g.:
- there's a comment stating exactly that, or
- things like HIR lowering, where we are lowering an error kind
The commit also tweaks some comments around delayed bug sites.
Fully stop using the HIR in trait impl checks
At least I hope I found all happy path usages. I'll need to check if I can figure out a way to make queries declare that they don't access the HIR except in error paths
Merge `impl_polarity` and `impl_trait_ref` queries
Hopefully this is perf neutral. I want to finish https://github.com/rust-lang/rust/pull/120835 and stop using the HIR in `coherent_trait`, which should then give us a perf improvement.
Dejargonize `subst`
In favor of #110793, replace almost every occurence of `subst` and `substitution` from rustc codes, but they still remains in subtrees under `src/tools/` like clippy and test codes (I'd like to replace them after this)
Rollup of 11 pull requests
Successful merges:
- #120765 (Reorder diagnostics API)
- #120833 (More internal emit diagnostics cleanups)
- #120899 (Gracefully handle non-WF alias in `assemble_alias_bound_candidates_recur`)
- #120917 (Remove a bunch of dead parameters in functions)
- #120928 (Add test for recently fixed issue)
- #120933 (check_consts: fix duplicate errors, make importance consistent)
- #120936 (improve `btree_cursors` functions documentation)
- #120944 (Check that the ABI of the instance we are inlining is correct)
- #120956 (Clean inlined type alias with correct param-env)
- #120962 (Add myself to library/std review)
- #120972 (fix ICE for deref coercions with type errors)
r? `@ghost`
`@rustbot` modify labels: rollup
fix ICE for deref coercions with type errors
Follow-up to https://github.com/rust-lang/rust/pull/120895, where I made types with errors go through the full coercion code, which is necessary if we want to build MIR for bodies with errors (https://github.com/rust-lang/rust/pull/120550).
The code for coercing `&T` to `&U` currently assumes that autoderef for `&T` will succeed for at least two steps (`&T` and `T`):
b17491c8f6/compiler/rustc_hir_typeck/src/coercion.rs (L339-L464)
But for types with errors, we previously only returned the no-op autoderef step (`&{type error}` -> `&{type error}`) and then stopped early. This PR changes autoderef for types with errors to still go through the built-in derefs (e.g. `&&{type error}` -> `&{type error}` -> `{type error}`) and only stop early when it would have to go looking for `Deref` trait impls.
fixes https://github.com/rust-lang/rust/issues/120945
r? ``@compiler-errors`` or compiler
Remove a bunch of dead parameters in functions
Found this kind of issue when working on https://github.com/rust-lang/rust/pull/119650
I wrote a trivial toy lint and manual review to find these.
Lowering unnamed fields and anonymous adt
This implements #49804.
Goals:
- [x] lowering anonymous ADTs from AST to HIR
- [x] generating definitions of anonymous ADTs
- [x] uniqueness check of the unnamed fields
- [x] field projection of anonymous ADTs
- [x] `#[repr(C)]` check of the anonymous ADTs
Non-Goals (will be in the next PRs)
- capturing generic params for the anonymous ADTs from the parent ADT
- pattern matching of anonymous ADTs
- structural expressions of anonymous ADTs
- rustdoc support of anonymous ADTs
Avoid accessing the HIR in the happy path of `coherent_trait`
Unfortunately the hir is still used in unsafety checks, and we do not have a way to avoid that. An impl's unsafety is not part of any query other than hir.
So this PR does not affect perf, but could still be considered a cleanup
A trait's local impls are trivially coherent if there are no impls.
This avoids creating a dependency edge on the hir or the specialization graph
This may resolve part of the performance issue of https://github.com/rust-lang/rust/pull/120558
- improve diagnostics of field uniqueness check and representation check
- simplify the implementation of field uniqueness check
- remove some useless codes and improvement neatness
Assert that params with the same *index* have the same *name*
Found this bug when trying to build libcore with the new solver, since it will canonicalize two params with the same index into *different* placeholders if those params differ by name.
Allow restricted trait impls under `#[allow_internal_unstable(min_specialization)]`
This is a follow-up to #119963 and a companion to #120866, though it can land independently from the latter.
---
We have several compiler crates that only enable `#[feature(min_specialization)]` because it is required by their expansions of `newtype_index!`, in order to implement traits marked with `#[rustc_specialization_trait]`.
This PR allows those traits to be implemented internally by macros with `#[allow_internal_unstable(min_specialization)]`, without needing specialization to be enabled in the enclosing crate.
These crates all needed specialization for `newtype_index!`, which will no
longer be necessary when the current nightly eventually becomes the next
bootstrap compiler.
Implementing traits marked with `#[rustc_specialization_trait]` normally
requires (min-)specialization to be enabled for the enclosing crate.
With this change, that permission can also be granted by an
`allow_internal_unstable` attribute on the macro that generates the impl.
The meaning of this assertion changed in #120828 when the meaning of
`has_errors` changed to exclude stashed errors. Evidently the new
meaning is too restrictive.
Fixes#120856.
Invert diagnostic lints.
That is, change `diagnostic_outside_of_impl` and `untranslatable_diagnostic` from `allow` to `deny`, because more than half of the compiler has been converted to use translated diagnostics.
This commit removes more `deny` attributes than it adds `allow` attributes, which proves that this change is warranted.
r? ````@davidtwco````
Toggle assert_unsafe_precondition in codegen instead of expansion
The goal of this PR is to make some of the unsafe precondition checks in the standard library available in debug builds. Some UI tests are included to verify that it does that.
The diff is large, but most of it is blessing mir-opt tests and I've also split up this PR so it can be reviewed commit-by-commit.
This PR:
1. Adds a new intrinsic, `debug_assertions` which is lowered to a new MIR NullOp, and only to a constant after monomorphization
2. Rewrites `assume_unsafe_precondition` to check the new intrinsic, and be monomorphic.
3. Skips codegen of the `assume` intrinsic in unoptimized builds, because that was silly before but with these checks it's *very* silly
4. The checks with the most overhead are `ptr::read`/`ptr::write` and `NonNull::new_unchecked`. I've simply added `#[cfg(debug_assertions)]` to the checks for `ptr::read`/`ptr::write` because I was unable to come up with any (good) ideas for decreasing their impact. But for `NonNull::new_unchecked` I found that the majority of callers can use a different function, often a safe one.
Yes, this PR slows down the compile time of some programs. But in our benchmark suite it's never more than 1% icount, and the average icount change in debug-full programs is 0.22%. I think that is acceptable for such an improvement in developer experience.
https://github.com/rust-lang/rust/issues/120539#issuecomment-1922687101
Remove unused args from functions
`#[instrument]` suppresses the unused arguments from a function, *and* suppresses unused methods too! This PR removes things which are only used via `#[instrument]` calls, and fixes some other errors (privacy?) that I will comment inline.
It's possible that some of these arguments were being passed in for the purposes of being instrumented, but I am unconvinced by most of them.
Rollup of 9 pull requests
Successful merges:
- #119592 (resolve: Unload speculatively resolved crates before freezing cstore)
- #120103 (Make it so that async-fn-in-trait is compatible with a concrete future in implementation)
- #120206 (hir: Make sure all `HirId`s have corresponding HIR `Node`s)
- #120214 (match lowering: consistently lower bindings deepest-first)
- #120688 (GVN: also turn moves into copies with projections)
- #120702 (docs: also check the inline stmt during redundant link check)
- #120727 (exhaustiveness: Prefer "`0..MAX` not covered" to "`_` not covered")
- #120734 (Add `SubdiagnosticMessageOp` as a trait alias.)
- #120739 (improve pretty printing for associated items in trait objects)
r? `@ghost`
`@rustbot` modify labels: rollup
Make it so that async-fn-in-trait is compatible with a concrete future in implementation
There's no technical reason why an AFIT like `async fn foo()` cannot be satisfied with an implementation signature like `fn foo() -> Pin<Box<dyn Future<Output = ()> + 'static>>`.
We rejected this previously because we were uncertain about how AFITs worked with refinement, but I don't believe this needs to be a restriction any longer.
r? oli-obk
Stop bailing out from compilation just because there were incoherent traits
fixes#120343
but also has a lot of "type annotations needed" fallout. Some are fixed in the second commit.
That is, change `diagnostic_outside_of_impl` and
`untranslatable_diagnostic` from `allow` to `deny`, because more than
half of the compiler has be converted to use translated diagnostics.
This commit removes more `deny` attributes than it adds `allow`
attributes, which proves that this change is warranted.
Rollup of 8 pull requests
Successful merges:
- #119759 (Add FileCheck annotations to dataflow-const-prop tests)
- #120323 (On E0277 be clearer about implicit `Sized` bounds on type params and assoc types)
- #120473 (Only suggest removal of `as_*` and `to_` conversion methods on E0308)
- #120540 (add test for try-block-in-match-arm)
- #120547 (`#![feature(inline_const_pat)]` is no longer incomplete)
- #120552 (Correctly check `never_type` feature gating)
- #120555 (put pnkfelix (me) back on the review queue.)
- #120556 (Improve the diagnostics for unused generic parameters)
r? `@ghost`
`@rustbot` modify labels: rollup
Improve the diagnostics for unused generic parameters
* Don't emit two errors (namely E0091 *and* E0392) for unused type parameters on *lazy* type aliases
* Fix the diagnostic help message of E0392 for *lazy* type aliases: Don't talk about the “fields” of lazy type aliases (use the term “body” instead) and don't suggest `PhantomData` for them, it doesn't make much sense
* Consolidate the diagnostics for E0091 (unused type parameters in type aliases) and E0392 (unused generic parameters due to bivariance) and make it translatable
* Still keep the error codes distinct (for now)
* Naturally leads to better diagnostics for E0091
r? ```@oli-obk``` (to ballast your review load :P) or compiler
- `emitted_at` isn't used outside the crate.
- `code` and `messages` are public fields, so there's no point have
trivial getters/setters for them.
- `suggestions` is public, so the comment about "functionality on
`Diagnostic`" isn't needed.
```
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> f100.rs:2:33
|
2 | let _ = std::mem::size_of::<[i32]>();
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[i32]`
note: required by an implicit `Sized` bound in `std::mem::size_of`
--> /home/gh-estebank/rust/library/core/src/mem/mod.rs:312:22
|
312 | pub const fn size_of<T>() -> usize {
| ^ required by the implicit `Sized` requirement on this bound in `size_of`
```
Fix#120178.
Normalize region obligation in lexical region resolution with next-gen solver
This normalizes region obligations when we `resolve_regions`, since they may be unnormalized with deferred projection equality.
It's pretty hard to add tests that exercise this without also triggering MIR borrowck errors (because we don't normalize there yet). I've added one test with two revisions that should test that we both 1. normalize region obligations in the param env, and 2. normalize registered region obligations during lexical region resolution.
Do not attempt to provide an accurate suggestion for `impl Trait`
in bare trait types when linting. Instead, only do the object
safety check when an E0782 is already going to be emitted in the
2021 edition.
Fix#120241.
Error codes are integers, but `String` is used everywhere to represent
them. Gross!
This commit introduces `ErrCode`, an integral newtype for error codes,
replacing `String`. It also introduces a constant for every error code,
e.g. `E0123`, and removes the `error_code!` macro. The constants are
imported wherever used with `use rustc_errors::codes::*`.
With the old code, we have three different ways to specify an error code
at a use point:
```
error_code!(E0123) // macro call
struct_span_code_err!(dcx, span, E0123, "msg"); // bare ident arg to macro call
\#[diag(name, code = "E0123")] // string
struct Diag;
```
With the new code, they all use the `E0123` constant.
```
E0123 // constant
struct_span_code_err!(dcx, span, E0123, "msg"); // constant
\#[diag(name, code = E0123)] // constant
struct Diag;
```
The commit also changes the structure of the error code definitions:
- `rustc_error_codes` now just defines a higher-order macro listing the
used error codes and nothing else.
- Because that's now the only thing in the `rustc_error_codes` crate, I
moved it into the `lib.rs` file and removed the `error_codes.rs` file.
- `rustc_errors` uses that macro to define everything, e.g. the error
code constants and the `DIAGNOSTIC_TABLES`. This is in its new
`codes.rs` file.
Remove `track_errors` entirely
follow up to https://github.com/rust-lang/rust/pull/119869
r? `@matthewjasper`
There are some diagnostic changes adding new diagnostics or not emitting some anymore. We can improve upon that in follow-up work imo.
Replacement of #114390: Add new intrinsic `is_var_statically_known` and optimize pow for powers of two
This adds a new intrinsic `is_val_statically_known` that lowers to [``@llvm.is.constant.*`](https://llvm.org/docs/LangRef.html#llvm-is-constant-intrinsic).` It also applies the intrinsic in the int_pow methods to recognize and optimize the idiom `2isize.pow(x)`. See #114390 for more discussion.
While I have extended the scope of the power of two optimization from #114390, I haven't added any new uses for the intrinsic. That can be done in later pull requests.
Note: When testing or using the library, be sure to use `--stage 1` or higher. Otherwise, the intrinsic will be a noop and the doctests will be skipped. If you are trying out edits, you may be interested in [`--keep-stage 0`](https://rustc-dev-guide.rust-lang.org/building/suggested.html#faster-builds-with---keep-stage).
Fixes#47234Resolves#114390
`@Centri3`
Rollup of 9 pull requests
Successful merges:
- #112806 (Small code improvements in `collect_intra_doc_links.rs`)
- #119766 (Split tait and impl trait in assoc items logic)
- #120139 (Do not normalize closure signature when building `FnOnce` shim)
- #120160 (Manually implement derived `NonZero` traits.)
- #120171 (Fix assume and assert in jump threading)
- #120183 (Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`)
- #120195 (add several resolution test cases)
- #120259 (Split Diagnostics for Uncommon Codepoints: Add List to Display Characters Involved)
- #120261 (Provide structured suggestion to use trait objects in some cases of `if` arm type divergence)
r? `@ghost`
`@rustbot` modify labels: rollup
A bunch of random modifications
r? oli-obk
Kitchen sink of changes that I didn't know where to put elsewhere. Documentation tweaks mostly, but also removing some unreachable code and simplifying the pretty printing for closures/coroutines.
Rollup of 10 pull requests
Successful merges:
- #117910 (Refactor uses of `objc_msgSend` to no longer have clashing definitions)
- #118639 (Undeprecate lint `unstable_features` and make use of it in the compiler)
- #119801 (Fix deallocation with wrong allocator in (A)Rc::from_box_in)
- #120058 (bootstrap: improvements for compiler builds)
- #120059 (Make generic const type mismatches not hide trait impls from the trait solver)
- #120097 (Report unreachable subpatterns consistently)
- #120137 (Validate AggregateKind types in MIR)
- #120164 (`maybe_lint_impl_trait`: separate `is_downgradable` from `is_object_safe`)
- #120181 (Allow any `const` expression blocks in `thread_local!`)
- #120218 (rustfmt: Check that a token can begin a nonterminal kind before parsing it as a macro arg)
r? `@ghost`
`@rustbot` modify labels: rollup
`maybe_lint_impl_trait`: separate `is_downgradable` from `is_object_safe`
https://github.com/rust-lang/rust/pull/119752 leveraged and overloaded `is_object_safe` to prevent an ICE, but accurate object safety information is needed for precise suggestions. This separates out `is_downgradable`, used for the ICE prevention, and `is_object_safe`, which returns to its original meaning.
Don't actually make bound ty/const for RTN
Avoid creating an unnecessary non-lifetime binder when we do RTN on a method that has ty/const params.
Fixes#120208
r? oli-obk
We have several methods indicating the presence of errors, lint errors,
and delayed bugs. I find it frustrating that it's very unclear which one
you should use in any particular spot. This commit attempts to instill a
basic principle of "use the least general one possible", because that
reflects reality in practice -- `has_errors` is the least general one
and has by far the most uses (esp. via `abort_if_errors`).
Specifics:
- Add some comments giving some usage guidelines.
- Prefer `has_errors` to comparing `err_count` to zero.
- Remove `has_errors_or_span_delayed_bugs` because it's a weird one: in
the cases where we need to count delayed bugs, we should really be
counting lint errors as well.
- Rename `is_compilation_going_to_fail` as
`has_errors_or_lint_errors_or_span_delayed_bugs`, for consistency with
`has_errors` and `has_errors_or_lint_errors`.
- Change a few other `has_errors_or_lint_errors` calls to `has_errors`,
as per the "least general" principle.
This didn't turn out to be as neat as I hoped when I started, but I
think it's still an improvement.
Don't forget that the lifetime on hir types is `'tcx`
This PR just tracks the `'tcx` lifetime to wherever the original objects actually have that lifetime. This code is needed for https://github.com/rust-lang/rust/pull/107606 (now #120131) so that `ast_ty_to_ty` can invoke `lit_to_const` on an argument passed to it. Currently the argument is `&hir::Ty<'_>`, but after this PR it is `&'tcx hir::Ty<'tcx>`.
Fix overflow check
Make MIRI choose the path randomly and rename the intrinsic
Add back test
Add miri test and make it operate on `ptr`
Define `llvm.is.constant` for primitives
Update MIRI comment and fix test in stage2
Add const eval test
Clarify that both branches must have the same side effects
guaranteed non guarantee
use immediate type instead
Co-Authored-By: Ralf Jung <post@ralfj.de>
Rollup of 8 pull requests
Successful merges:
- #119172 (Detect `NulInCStr` error earlier.)
- #119833 (Make tcx optional from StableMIR run macro and extend it to accept closures)
- #119967 (Add `PatKind::Err` to AST/HIR)
- #119978 (Move async closure parameters into the resultant closure's future eagerly)
- #120021 (don't store const var origins for known vars)
- #120038 (Don't create a separate "basename" when naming and opening a MIR dump file)
- #120057 (Don't ICE when deducing future output if other errors already occurred)
- #120073 (Remove spastorino from users_on_vacation)
r? `@ghost`
`@rustbot` modify labels: rollup
error on incorrect implied bounds in wfcheck except for Bevy dependents
Rebase of #109763
Additionally, special cases Bevy `ParamSet` types to not trigger the lint. This is tracked in #119956.
Fixes#109628
Don't ICE if TAIT-defining fn contains a closure with `_` in return type
The `delay_span_bug` got added in 0e82aaeb67 to reduce the amount of errors emitted for functions that have `_` in their return type, because inference doesn't apply to function items. But this logic shouldn't apply to closures, because their return types *can* be inferred.
Fixes https://github.com/rust-lang/rust/issues/119916.
Rework how diagnostic lints are stored.
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
r? `@oli-obk`
Use `zip_eq` to enforce that things being zipped have equal sizes
Some `zip`s are best enforced to be equal, since size mismatches suggest deeper bugs in the compiler.
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
Suggest Upgrading Compiler for Gated Features
This PR addresses #117318
I have a few questions:
1. Do we want to specify the current version and release date of the compiler? I have added this in via environment variables, which I found in the code for the rustc cli where it handles the `--version` flag
a. How can I handle the changing message in the tests?
3. Do we want to only show this message when the compiler is old?
a. How can we determine when the compiler is old?
I'll wait until we figure out the message to bless the tests
Taint `_` placeholder types in trait impl method signatures
We report an error right below for them, but that kind of broken type can cause subsequent ICEs.
fixes#119867
Varargs support for system ABI
This PR allows functions with the `system` ABI to be variadic (under the `extended_varargs_abi_support` feature tracked in #100189). On x86 windows, the `system` ABI is equivalent to `C` for variadic functions. On other platforms, `system` is already equivalent to `C`.
Fixes#110505
Remove special-casing around `AliasKind::Opaque` when structurally resolving in new solver
This fixes a few inconsistencies around where we don't eagerly resolve opaques to their (locally-defined) hidden types in the new solver. It essentially allows this code to work:
```rust
fn main() {
type Tait = impl Sized;
struct S {
i: i32,
}
let x: Tait = S { i: 0 };
println!("{}", x.i);
}
```
Since `Tait` is defined in `main`, we are able to poke through the type of `x` with deref.
r? lcnr
Silence some follow-up errors [1/x]
this is one piece of the requested cleanups from https://github.com/rust-lang/rust/pull/117449
When we use `-> impl SomeTrait<_>` as a return type, we are both using the "infer return type suggestion" code path, and the infer opaque type code path within the same function. That can lead to confusing diagnostics, so silence all opaque type diagnostics in that case.
Diagnostic API fixes
Some improvements to diagnostic APIs: improve some naming, use shortcuts in more places, and add a couple of missing methods.
r? `@compiler-errors`
Avoid silencing relevant follow-up errors
r? `@matthewjasper`
This PR only adds new errors to tests that are already failing and fixes one ICE.
Several tests were changed to not emit new errors. I believe all of them were faulty tests, and not explicitly testing for the code that had new errors.
In #119606 I added them and used a `_mv` suffix, but that wasn't great.
A `with_` prefix has three different existing uses.
- Constructors, e.g. `Vec::with_capacity`.
- Wrappers that provide an environment to execute some code, e.g.
`with_session_globals`.
- Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`.
The third case is exactly what we want, so this commit changes
`DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`.
Thanks to @compiler-errors for the suggestion.
We have `span_delayed_bug` and often pass it a `DUMMY_SP`. This commit
adds `delayed_bug`, which matches pairs like `err`/`span_err` and
`warn`/`span_warn`.
- `struct_foo` + `emit` -> `foo`
- `create_foo` + `emit` -> `emit_foo`
I have made recent commits in other PRs that have removed some of these
shortcuts for combinations with few uses, e.g.
`struct_span_err_with_code`. But for the remaining combinations that
have high levels of use, we might as well use them wherever possible.
Because it takes an error code after the span. This avoids the confusing
overlap with the `DiagCtxt::struct_span_err` method, which doesn't take
an error code.
`~const` trait and projection bounds do not imply their non-const counterparts
This PR removes the hack where we install a non-const trait and projection bound for every `const_trait` and `~const` projection bound we have in the AST. It ends up messing up more things than it fixes, see words below.
Fixes#119718
cc `@fmease` `@fee1-dead` `@oli-obk`
r? fee1-dead or one of y'all i don't care
---
My understanding is that this hack was added to support the following code:
```rust
pub trait Owo<X = <Self as Uwu>::T> {}
#[const_trait]
pub trait Uwu: Owo {}
```
Which is concretely lifted from in the `FromResidual` and `Try` traits. Since within the param-env of `trait Uwu`, we only know that `Self: ~const Uwu` and not `Self: Uwu`, the projection `<Self as Uwu>::T` is not satsifyable.
This causes problems such as #119718, since instantiations of `FnDef` types coming from `const fn` really do **only** implement one of `FnOnce` or `const FnOnce`!
---
In the long-term, I believe that such code should really look something more like:
```rust
#[const_trait]
pub trait Owo<X = <Self as ~const Uwu>::T> {}
#[const_trait]
pub trait Uwu: Owo {}
```
... and that we should introduce some sort of `<T as ~const Foo>::Bar` bound syntax, since due to the fact that `~const` bounds can be present in item bounds, e.g.
```rust
#[const_trait] trait Foo { type Bar: ~const Destruct; }
```
It's easy to see that `<T as Foo>::Bar` and `<T as ~const Foo>::Bar` (or `<T as const Foo>::Bar`) can be distinct types with distinct item bounds!
**Admission**: I know I've said before that I don't like `~const` projection syntax, I do at this point believe they're necessary to fully express bounds and types in a maybe-const world.
This works for most of its call sites. This is nice, because `emit` very
much makes sense as a consuming operation -- indeed,
`DiagnosticBuilderState` exists to ensure no diagnostic is emitted
twice, but it uses runtime checks.
For the small number of call sites where a consuming emit doesn't work,
the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will
be removed in subsequent commits.)
Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes
consuming, while `delay_as_bug_without_consuming` is added (which will
also be removed in subsequent commits.)
All this requires significant changes to `DiagnosticBuilder`'s chaining
methods. Currently `DiagnosticBuilder` method chaining uses a
non-consuming `&mut self -> &mut Self` style, which allows chaining to
be used when the chain ends in `emit()`, like so:
```
struct_err(msg).span(span).emit();
```
But it doesn't work when producing a `DiagnosticBuilder` value,
requiring this:
```
let mut err = self.struct_err(msg);
err.span(span);
err
```
This style of chaining won't work with consuming `emit` though. For
that, we need to use to a `self -> Self` style. That also would allow
`DiagnosticBuilder` production to be chained, e.g.:
```
self.struct_err(msg).span(span)
```
However, removing the `&mut self -> &mut Self` style would require that
individual modifications of a `DiagnosticBuilder` go from this:
```
err.span(span);
```
to this:
```
err = err.span(span);
```
There are *many* such places. I have a high tolerance for tedious
refactorings, but even I gave up after a long time trying to convert
them all.
Instead, this commit has it both ways: the existing `&mut self -> Self`
chaining methods are kept, and new `self -> Self` chaining methods are
added, all of which have a `_mv` suffix (short for "move"). Changes to
the existing `forward!` macro lets this happen with very little
additional boilerplate code. I chose to add the suffix to the new
chaining methods rather than the existing ones, because the number of
changes required is much smaller that way.
This doubled chainging is a bit clumsy, but I think it is worthwhile
because it allows a *lot* of good things to subsequently happen. In this
commit, there are many `mut` qualifiers removed in places where
diagnostics are emitted without being modified. In subsequent commits:
- chaining can be used more, making the code more concise;
- more use of chaining also permits the removal of redundant diagnostic
APIs like `struct_err_with_code`, which can be replaced easily with
`struct_err` + `code_mv`;
- `emit_without_diagnostic` can be removed, which simplifies a lot of
machinery, removing the need for `DiagnosticBuilderState`.
Rollup of 8 pull requests
Successful merges:
- #119151 (Hide foreign `#[doc(hidden)]` paths in import suggestions)
- #119350 (Imply outlives-bounds on lazy type aliases)
- #119354 (Make `negative_bounds` internal & fix some of its issues)
- #119506 (Use `resolutions(()).effective_visiblities` to avoid cycle errors in `report_object_error`)
- #119554 (Fix scoping for let chains in match guards)
- #119563 (Check yield terminator's resume type in borrowck)
- #119589 (cstore: Remove unnecessary locking from `CrateMetadata`)
- #119622 (never patterns: Document behavior of never patterns with macros-by-example)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix scoping for let chains in match guards
If let guards were previously represented as a different type of guard in HIR and THIR. This meant that let chains in match guards were not handled correctly because they were treated exactly like normal guards.
- Remove `hir::Guard` and `thir::Guard`.
- Make the scoping different between normal guards and if let guards also check for let chains.
closes#118593
Replace a number of FxHashMaps/Sets with stable-iteration-order alternatives
This PR replaces almost all of the remaining `FxHashMap`s in query results with either `FxIndexMap` or `UnordMap`. The only case that is missing is the `EffectiveVisibilities` struct which turned out to not be straightforward to transform. Once that is done too, we can remove the `HashStable` implementation from `HashMap`.
The first commit adds the `StableCompare` trait which is a companion trait to `StableOrd`. Some types like `Symbol` can be compared in a cross-session stable way, but their `Ord` implementation is not stable. In such cases, a `StableCompare` implementation can be provided to offer a lightweight way for stable sorting. The more heavyweight option is to sort via `ToStableHashKey`, but then sorting needs to have access to a stable hashing context and `ToStableHashKey` can also be expensive as in the case of `Symbol` where it has to allocate a `String`.
The rest of the commits are rather mechanical and don't overlap, so they are best reviewed individually.
Part of [MCP 533](https://github.com/rust-lang/compiler-team/issues/533).
Tweak suggestions for bare trait used as a type
```
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/not-on-bare-trait-2021.rs:11:11
|
LL | fn bar(x: Foo) -> Foo {
| ^^^
|
help: use a generic type parameter, constrained by the trait `Foo`
|
LL | fn bar<T: Foo>(x: T) -> Foo {
| ++++++++ ~
help: you can also use `impl Foo`, but users won't be able to specify the type paramer when calling the `fn`, having to rely exclusively on type inference
|
LL | fn bar(x: impl Foo) -> Foo {
| ++++
help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch
|
LL | fn bar(x: &dyn Foo) -> Foo {
| ++++
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/not-on-bare-trait-2021.rs:11:19
|
LL | fn bar(x: Foo) -> Foo {
| ^^^
|
help: use `impl Foo` to return an opaque type, as long as you return a single underlying type
|
LL | fn bar(x: Foo) -> impl Foo {
| ++++
help: alternatively, you can return an owned trait object
|
LL | fn bar(x: Foo) -> Box<dyn Foo> {
| +++++++ +
```
Fix#119525:
```
error[E0038]: the trait `Ord` cannot be made into an object
--> $DIR/bare-trait-dont-suggest-dyn.rs:3:33
|
LL | fn ord_prefer_dot(s: String) -> Ord {
| ^^^ `Ord` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
::: $SRC_DIR/core/src/cmp.rs:LL:COL
|
= note: the trait cannot be made into an object because it uses `Self` as a type parameter
help: consider using an opaque type instead
|
LL | fn ord_prefer_dot(s: String) -> impl Ord {
| ++++
```
Match guards with an if let guard or an if let chain guard should have a
temporary scope of the whole arm. This is to allow ref bindings to
temporaries to borrow check.
Reorder check_item_type diagnostics so they occur next to the corresponding `check_well_formed` diagnostics
The first commit is just a cleanup.
The second commit moves most checks from `check_mod_item_types` into `check_well_formed`, invoking the checks in lockstep per-item instead of iterating over all items twice.
Add the following suggestions:
```
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/not-on-bare-trait-2021.rs:11:11
|
LL | fn bar(x: Foo) -> Foo {
| ^^^
|
help: use a generic type parameter, constrained by the trait `Foo`
|
LL | fn bar<T: Foo>(x: T) -> Foo {
| ++++++++ ~
help: you can also use `impl Foo`, but users won't be able to specify the type paramer when calling the `fn`, having to rely exclusively on type inference
|
LL | fn bar(x: impl Foo) -> Foo {
| ++++
help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch
|
LL | fn bar(x: &dyn Foo) -> Foo {
| ++++
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/not-on-bare-trait-2021.rs:11:19
|
LL | fn bar(x: Foo) -> Foo {
| ^^^
|
help: use `impl Foo` to return an opaque type, as long as you return a single underlying type
|
LL | fn bar(x: Foo) -> impl Foo {
| ++++
help: alternatively, you can return an owned trait object
|
LL | fn bar(x: Foo) -> Box<dyn Foo> {
| +++++++ +
```
`Diagnostic` has 40 methods that return `&mut Self` and could be
considered setters. Four of them have a `set_` prefix. This doesn't seem
necessary for a type that implements the builder pattern. This commit
removes the `set_` prefixes on those four methods.
Make closures carry their own ClosureKind
Right now, we use the "`movability`" field of `hir::Closure` to distinguish a closure and a coroutine. This is paired together with the `CoroutineKind`, which is located not in the `hir::Closure`, but the `hir::Body`. This is strange and redundant.
This PR introduces `ClosureKind` with two variants -- `Closure` and `Coroutine`, which is put into `hir::Closure`. The `CoroutineKind` is thus removed from `hir::Body`, and `Option<Movability>` no longer needs to be a stand-in for "is this a closure or a coroutine".
r? eholk
Remove `DiagCtxt` API duplication
`DiagCtxt` defines the internal API for creating and emitting diagnostics: methods like `struct_err`, `struct_span_warn`, `note`, `create_fatal`, `emit_bug`. There are over 50 methods.
Some of these methods are then duplicated across several other types: `Session`, `ParseSess`, `Parser`, `ExtCtxt`, and `MirBorrowckCtxt`. `Session` duplicates the most, though half the ones it does are unused. Each duplicated method just calls forward to the corresponding method in `DiagCtxt`. So this duplication exists to (in the best case) shorten chains like `ecx.tcx.sess.parse_sess.dcx.emit_err()` to `ecx.emit_err()`.
This API duplication is ugly and has been bugging me for a while. And it's inconsistent: there's no real logic about which methods are duplicated, and the use of `#[rustc_lint_diagnostic]` and `#[track_caller]` attributes vary across the duplicates.
This PR removes the duplicated API methods and makes all diagnostic creation and emission go through `DiagCtxt`. It also adds `dcx` getter methods to several types to shorten chains. This approach scales *much* better than API duplication; indeed, the PR adds `dcx()` to numerous types that didn't have API duplication: `TyCtxt`, `LoweringCtxt`, `ConstCx`, `FnCtxt`, `TypeErrCtxt`, `InferCtxt`, `CrateLoader`, `CheckAttrVisitor`, and `Resolver`. These result in a lot of changes from `foo.tcx.sess.emit_err()` to `foo.dcx().emit_err()`. (You could do this with more types, but it gets into diminishing returns territory for types that don't emit many diagnostics.)
After all these changes, some call sites are more verbose, some are less verbose, and many are the same. The total number of lines is reduced, mostly because of the removed API duplication. And consistency is increased, because calls to `emit_err` and friends are always preceded with `.dcx()` or `.dcx`.
r? `@compiler-errors`
Give temporaries in if let guards correct scopes
Temporaries in if-let guards have scopes that escape the match arm, this causes problems because the drops might be for temporaries that are not storage live. This PR changes the scope of temporaries in if-let guards to be limited to the arm:
```rust
_ if let Some(s) = std::convert::identity(&Some(String::new())) => {}
// Temporary for Some(String::new()) is dropped here ^
```
We also now deduplicate temporaries between copies of the guard created for or-patterns:
```rust
// Only create a single Some(String::new()) temporary variable
_ | _ if let Some(s) = std::convert::identity(&Some(String::new())) => {}
```
This changes MIR building to pass around `ExprId`s rather than `Expr`s so that we have a way to index different expressions.
cc #51114Closes#116079
remove dead inferred outlives testing code
The `test_inferred_outlives` function was never run, because the code that's actually used for the tests was part of the `inferred_outlives_of` query, which ran before `test_inferred_outlives` during type collecting. This PR separates the test code from the query and moves it inside the dedicated function.
Clean up `check_consts` and misc fixes
1. Remove most of the logic around erroring with trait methods. I have kept the part resolving it to a concrete impl, as that is used for const stability checks.
2. Turning on `effects` causes ICE with generic args, due to `~const Tr` when `Tr` is not `#[const_trait]` tripping up expectation in code that handles generic args, more specifically here:
8681e077b8/compiler/rustc_hir_analysis/src/astconv/generics.rs (L377)
We set `arg_count.correct` to `Err` to correctly signal that an error has already been reported.
3. UI test blesses.
Edit(fmease): Fixes#117244 (UI test is in #119099 for now).
r? compiler-errors
`IntoDiagnostic` defaults to `ErrorGuaranteed`, because errors are the
most common diagnostic level. It makes sense to do likewise for the
closely-related (and much more widely used) `DiagnosticBuilder` type,
letting us write `DiagnosticBuilder<'a, ErrorGuaranteed>` as just
`DiagnosticBuilder<'a>`. This cuts over 200 lines of code due to many
multi-line things becoming single line things.
- Make temporaries in if-let guards be the same variable in MIR when
the guard is duplicated due to or-patterns.
- Change the "destruction scope" for match arms to be the arm scope rather
than the arm body scope.
- Add tests.
Give `VariantData::Struct` named fields, to clairfy `recovered`.
Implements https://github.com/rust-lang/rust/pull/119121#discussion_r1431467066. Supersedes #119121
This way, it's clear what the bool fields means, instead of having to find where it's generated. Changes both ast and hir.
r? `@compiler-errors`
And make all hand-written `IntoDiagnostic` impls generic, by using
`DiagnosticBuilder::new(dcx, level, ...)` instead of e.g.
`dcx.struct_err(...)`.
This means the `create_*` functions are the source of the error level.
This change will let us remove `struct_diagnostic`.
Note: `#[rustc_lint_diagnostics]` is added to `DiagnosticBuilder::new`,
it's necessary to pass diagnostics tests now that it's used in
`into_diagnostic` functions.
Don't pass lint back out of lint decorator
Change the decorator function in the signature of the `emit_lint`/`span_lint`/etc family of methods from `impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>` to `impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>)`. I consider it easier to read this way, especially when there's control flow involved.
r? nnethercote though feel free to reassign
Collect lang items from AST, get rid of `GenericBound::LangItemTrait`
r? `@cjgillot`
cc #115178
Looking forward, the work to remove `QPath::LangItem` will also be significantly more difficult, but I plan on doing it as well. Specifically, we have to change:
1. A lot of `rustc_ast_lowering` for things like expr `..`
2. A lot of astconv, since we actually instantiate lang and non-lang paths quite differently.
3. A ton of diagnostics and clippy lints that are special-cased via `QPath::LangItem`
Meanwhile, it was pretty easy to remove `GenericBound::LangItemTrait`, so I just did that here.
Renamings:
- find -> opt_hir_node
- get -> hir_node
- find_by_def_id -> opt_hir_node_by_def_id
- get_by_def_id -> hir_node_by_def_id
Fix rebase changes using removed methods
Use `tcx.hir_node_by_def_id()` whenever possible in compiler
Fix clippy errors
Fix compiler
Apply suggestions from code review
Co-authored-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Add FIXME for `tcx.hir()` returned type about its removal
Simplify with with `tcx.hir_node_by_def_id`
detects redundant imports that can be eliminated.
for #117772 :
In order to facilitate review and modification, split the checking code and
removing redundant imports code into two PR.
Resolve associated item bindings by namespace
This is the 3rd commit split off from #118360 with tests reblessed (they no longer contain duplicated diags which were caused by 4c0addc80a) & slightly adapted (removed supertraits from a UI test, cc #118040).
> * Resolve all assoc item bindings (type, const, fn (feature `return_type_notation`)) by namespace instead of trying to resolve a type first (in the non-RTN case) and falling back to consts afterwards. This is consistent with RTN. E.g., for `Tr<K = {…}>` we now always try to look up assoc consts (this extends to supertrait bounds). This gets rid of assoc tys shadowing assoc consts in assoc item bindings which is undesirable & inconsistent (types and consts live in different namespaces after all)
> * Consolidate the resolution of assoc {ty, const} bindings and RTN (dedup, better diags for RTN)
> * Fix assoc consts being labeled as assoc *types* in several diagnostics
> * Make a bunch of diagnostics translatable
Fixes#112560 (error → pass).
As discussed
r? `@compiler-errors`
---
**Addendum**: What I call “associated item bindings” are commonly referred to as “type bindings” for historical reasons. Nowadays, “type bindings” include assoc type bindings, assoc const bindings and RTN (return type notation) which is why I prefer not to use this outdated term.
Remove `#[rustc_host]`, use internal desugaring
Also removed a way for users to explicitly specify the host param since that isn't particularly useful. This should eliminate any pain with encoding attributes across crates and etc.
r? `@compiler-errors`
Added shadowed hint for overlapping associated types
Previously, when you tried to set an associated type that is shadowed by an associated type in a subtrait, like this:
```rust
trait A {
type X;
}
trait B: A {
type X; // note: this is legal
}
impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
fn clone(&self) -> Self {
todo!()
}
}
you got a confusing error message, that says nothing about the shadowing:
error[E0719]: the value of the associated type `X` (from trait `B`) is already specified
--> test.rs:9:34
|
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| --- ^^^ re-bound here
| |
| `X` bound here first
error[E0191]: the value of the associated type `X` (from trait `A`) must be specified
--> test.rs:9:27
|
2 | type X;
| ------ `X` defined here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| ^^^^^^^^^^^ help: specify the associated type: `B<X=Y, X=Y, X = Type>`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
```
Now instead, the error shows that the associated type is shadowed, and suggests renaming as a potential fix.
```rust
error[E0719]: the value of the associated type `X` in trait `B` is already specified
--> test.rs:9:34
|
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| --- ^^^ re-bound here
| |
| `X` bound here first
error[E0191]: the value of the associated type `X` in `A` must be specified
--> test.rs:9:27
|
2 | type X;
| ------ `A::X` defined here
...
6 | type X; // note: this is legal
| ------ `A::X` shadowed here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| ^^^^^^^^^^^ associated type `X` must be specified
|
help: consider renaming this associated type
--> test.rs:2:5
|
2 | type X;
| ^^^^^^
help: consider renaming this associated type
--> test.rs:6:5
|
6 | type X; // note: this is legal
| ^^^^^^
```
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
The rename help message is only emitted when the trait is local. This is true both for the supertrait as for the subtrait.
There might be cases where you can use the fully qualified path (for instance, in a where clause), but this PR currently does not deal with that.
fixes#100109
(continues from #117642, because I didn't know renaming the branch would close the PR)
Shadowing the associated type of a supertrait is allowed.
This however makes it impossible to set the associated type
of the supertrait in a dyn object.
This PR makes the error message for that case clearer, like
adding a note that shadowing is happening, as well as suggesting
renaming of one of the associated types.
r=petrochenckov
Pretty print `Fn<(..., ...)>` trait refs with parentheses (almost) always
It's almost always better, at least in diagnostics, to print `Fn(i32, u32)` instead of `Fn<(i32, u32)>`.
Related to but doesn't fix#118225. That needs a separate fix.
Add `never_patterns` feature gate
This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment.
`@scottmcm` has agreed to be my lang-team liaison for this experiment.
Do not erase late bound regions when selecting inherent associated types
In the fix for #97156 we would want the following code:
```rust
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
struct Foo<T>(T);
impl Foo<fn(&'static ())> {
type Assoc = u32;
}
trait Other {}
impl Other for u32 {}
// FIXME(inherent_associated_types): Avoid emitting two diagnostics (they only differ in span).
// FIXME(inherent_associated_types): Enhancement: Spruce up the diagnostic by saying something like
// "implementation is not general enough" as is done for traits via
// `try_report_trait_placeholder_mismatch`.
fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
//~^ ERROR mismatched types
//~| ERROR mismatched types
fn main() {}
```
to fail with ...
```
error[E0220]: associated type `Assoc` not found for `Foo<for<'a> fn(&'a ())>` in the current scope
--> tests/ui/associated-inherent-types/issue-109789.rs:18:36
|
4 | struct Foo<T>(T);
| ------------- associated item `Assoc` not found for this struct
...
18 | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
| ^^^^^ associated item not found in `Foo<for<'a> fn(&'a ())>`
|
= note: the associated type was found for
- `Foo<fn(&'static ())>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0220`.
```
This PR fixes the ICE we are currently getting "was a subtype of Foo<Binder(fn(&ReStatic ()), [])> during selection but now it is not"
Also fixes#112631
r? `@lcnr`
Currently we always do this:
```
use rustc_fluent_macro::fluent_messages;
...
fluent_messages! { "./example.ftl" }
```
But there is no need, we can just do this everywhere:
```
rustc_fluent_macro::fluent_messages! { "./example.ftl" }
```
which is shorter.
The `fluent_messages!` macro produces uses of
`crate::{D,Subd}iagnosticMessage`, which means that every crate using
the macro must have this import:
```
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
```
This commit changes the macro to instead use
`rustc_errors::{D,Subd}iagnosticMessage`, which avoids the need for the
imports.
Allow defining opaques in `check_coroutine_obligations`
In the new trait solver, when an obligation stalls on an unresolved coroutine witness, we will stash away the *root* obligation, even if the stalled obligation is only a distant descendent of the root obligation, since the new solver is purely recursive.
This means that we may need to reprocess alias-relate obligations (and others) which may define opaque types in the new solver. Currently, we use the coroutine's def id as the defining anchor in `check_coroutine_obligations`, which will allow defining no opaque types, resulting in errors like:
```
error[E0271]: type mismatch resolving `{coroutine@<source>:6:5: 6:17} <: impl Clone`
--> <source>:6:5
|
6 | / move |_: ()| {
7 | | let () = yield ();
8 | | }
| |_____^ types differ
```
So this PR fixes the defining anchor and does the same trick as `check_opaque_well_formed`, where we manually compare opaques that were defined against their hidden types to make sure they weren't defined differently when processing these stalled coroutine obligations.
r? `@lcnr` cc `@cjgillot`
By default, `newtype_index!` types get a default `Encodable`/`Decodable`
impl. You can opt out of this with `custom_encodable`. Opting out is the
opposite to how Rust normally works with autogenerated (derived) impls.
This commit inverts the behaviour, replacing `custom_encodable` with
`encodable` which opts into the default `Encodable`/`Decodable` impl.
Only 23 of the 59 `newtype_index!` occurrences need `encodable`.
Even better, there were eight crates with a dependency on
`rustc_serialize` just from unused default `Encodable`/`Decodable`
impls. This commit removes that dependency from those eight crates.
Make regionck care about placeholders in outlives components
Currently, we don't consider a placeholder type `!T` to be a type component when it comes to processing type-outlives obligations. This means that they are essentially treated like unit values with no sub-components, and always outlive any region. This is problematic for `non_lifetime_binders`, and even more problematic for `with_negative_coherence`, since negative coherence uses placeholders as universals.
This PR adds `Component::Placeholder` which acts much like `Component::Param`. This currently causes a regression in some non-lifetime-binders tests because `for<T> T: 'static` doesn't imply itself when processing outlives obligations, so code like this will fail:
```
fn foo() where for<T> T: 'static {
foo() //~ fails
}
```
Since the where clause doesn't imply itself. This requires making the `MatchAgainstHigherRankedOutlives` relation smarter when it comes to binders.
r? types
Remove option_payload_ptr; redundant to offset_of
The `option_payload_ptr` intrinsic is no longer required as `offset_of` supports traversing enums (#114208). This PR removes it in order to dogfood offset_of (as suggested at https://github.com/rust-lang/rust/issues/106655#issuecomment-1790907626). However, it will not build until those changes reach beta (which I think is within the next 8 days?) so I've opened it as a draft.
`ReLateBound` -> `ReBound`
first step of https://github.com/rust-lang/types-team/issues/95
already fairly large xx
there's some future work here I intentionally did not contribute as part of this PR, from my notes:
- `DescriptionCtx` to `DescriptionCtxt`
- what is `CheckRegions::Bound`?
- `collect_late_bound_regions` et al
- `erase_late_bound_regions` -> `instantiate_bound_regions_with_erased`?
- `EraseEarlyRegions` should be removed, feels duplicate
r? `@BoxyUwU`
Most notably, this commit changes the `pub use crate::*;` in that file
to `use crate::*;`. This requires a lot of `use` items in other crates
to be adjusted, because everything defined within `rustc_span::*` was
also available via `rustc_span::source_map::*`, which is bizarre.
The commit also removes `SourceMap::span_to_relative_line_string`, which
is unused.
Also consider TAIT to be uncomputable if the MIR body is tainted
Not totally sure if this is the best solution. We could, alternatively, look at the hir typeck results and try to take a type from there instead of just falling back to type error, inferring `u8` instead of `{type error}`. Not certain it really matters, though.
Happy to iterate on this.
Fixes#117413
r? ``@oli-obk`` cc ``@Nadrieril``
Detect object safety errors when assoc type is missing
When an associated type with GATs isn't specified in a `dyn Trait`, emit an object safety error instead of only complaining about the missing associated type, as it will lead the user down a path of three different errors before letting them know that what they were trying to do is impossible to begin with.
Fix#103155.
When an associated type with GATs isn't specified in a `dyn Trait`, emit
an object safety error instead of only complaining about the missing
associated type, as it will lead the user down a path of three different
errors before letting them know that what they were trying to do is
impossible to begin with.
Fix#103155.
Improve some diagnostics around `?Trait` bounds
* uses better spans
* clarifies a message that was only talking about generic params, but applies to `dyn ?Trait` and `impl ?Trait` as well
Rollup of 7 pull requests
Successful merges:
- #117111 (Remove support for alias `-Z instrument-coverage`)
- #117141 (Require target features to match exactly during inlining)
- #117152 (Fix unwrap suggestion for async fn)
- #117154 (implement C ABI lowering for CSKY)
- #117159 (Work around the fact that `check_mod_type_wf` may spuriously return `ErrorGuaranteed`)
- #117163 (compiletest: Display compilation errors in mir-opt tests)
- #117173 (Make `Iterator` a lang item)
r? `@ghost`
`@rustbot` modify labels: rollup
Merge `impl_wf_inference` (`check_mod_impl_wf`) check into coherence checking
Problem here is that we call `collect_impl_trait_in_trait_types` when checking `check_mod_impl_wf` which is performed before coherence. Due to the `tcx.sess.track_errors`, since we end up reporting an error, we never actually proceed to coherence checking, where we would be emitting a more useful impl overlap error.
This change means that we may report more errors in some cases, but can at least proceed far enough to leave a useful message for overlapping traits with RPITITs in them.
Fixes#116982
r? types
Avoid a `track_errors` by bubbling up most errors from `check_well_formed`
I believe `track_errors` is mostly papering over issues that a sufficiently convoluted query graph can hit. I made this change, while the actual change I want to do is to stop bailing out early on errors, and instead use this new `ErrorGuaranteed` to invoke `check_well_formed` for individual items before doing all the `typeck` logic on them.
This works towards resolving https://github.com/rust-lang/rust/issues/97477 and various other ICEs, as well as allowing us to use parallel rustc more (which is currently rather limited/bottlenecked due to the very sequential nature in which we do `rustc_hir_analysis::check_crate`)
cc `@SparrowLii` `@Zoxc` for the new `try_par_for_each_in` function
Point at assoc fn definition on type param divergence
When the number of type parameters in the associated function of an impl and its trait differ, we now *always* point at the trait one, even if it comes from a foreign crate. When it is local, we point at the specific params, when it is foreign, we point at the whole associated item.
Fix#69944.
When the number of type parameters in the associated function of an impl
and its trait differ, we now *always* point at the trait one, even if it
comes from a foreign crate. When it is local, we point at the specific
params, when it is foreign, we point at the whole associated item.
Fix#69944.
Don't compare host param by name
Seems sketchy to be searching for `sym::host` by name, especially when we can get the actual index with not very much work.
r? fee1-dead
Fix implied outlives check for GAT in RPITIT
We enforce certain `Self: 'lt` bounds for GATs to save space for more sophisticated implied bounds, but those currently operate on the HIR. Code was easily reworked to operate on def-ids so that we can properly let these suggestions propagate through synthetic associated types like RPITITs and AFITs.
r? `@jackh726` or `@aliemjay`
Fixes#116789
Suggest trait bounds for used associated type on type param
Fix#101351.
When an associated type on a type parameter is used, and the type parameter isn't constrained by the correct trait, suggest the appropriate trait bound:
```
error[E0220]: associated type `Associated` not found for `T`
--> file.rs:6:15
|
6 | field: T::Associated,
| ^^^^^^^^^^ there is a similarly named associated type `Associated` in the trait `Foo`
|
help: consider restricting type parameter `T`
|
5 | struct Generic<T: Foo> {
| +++++
```
When an associated type on a type parameter has a typo, suggest fixing
it:
```
error[E0220]: associated type `Baa` not found for `T`
--> $DIR/issue-55673.rs:9:8
|
LL | T::Baa: std::fmt::Debug,
| ^^^ there is a similarly named associated type `Bar` in the trait `Foo`
|
help: change the associated type name to use `Bar` from `Foo`
|
LL | T::Bar: std::fmt::Debug,
| ~~~
```
Format all the let-chains in compiler crates
Since rust-lang/rustfmt#5910 has landed, soon we will have support for formatting let-chains (as soon as rustfmt syncs and beta gets bumped).
This PR applies the changes [from master rustfmt to rust-lang/rust eagerly](https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/out.20formatting.20of.20prs/near/374997516), so that the next beta bump does not have to deal with a 200+ file diff and can remain concerned with other things like `cfg(bootstrap)` -- #113637 was a pain to land, for example, because of let-else.
I will also add this commit to the ignore list after it has landed.
The commands that were run -- I'm not great at bash-foo, but this applies rustfmt to every compiler crate, and then reverts the two crates that should probably be formatted out-of-tree.
```
~/rustfmt $ ls -1d ~/rust/compiler/* | xargs -I@ cargo run --bin rustfmt -- `@/src/lib.rs` --config-path ~/rust --edition=2021 # format all of the compiler crates
~/rust $ git checkout HEAD -- compiler/rustc_codegen_{gcc,cranelift} # revert changes to cg-gcc and cg-clif
```
cc `@rust-lang/rustfmt`
r? `@WaffleLapkin` or `@Nilstrieb` who said they may be able to review this purely mechanical PR :>
cc `@Mark-Simulacrum` and `@petrochenkov,` who had some thoughts on the order of operations with big formatting changes in https://github.com/rust-lang/rust/pull/95262#issue-1178993801. I think the situation has changed since then, given that let-chains support exists on master rustfmt now, and I'm fairly confident that this formatting PR should land even if *bootstrap* rustfmt doesn't yet format let-chains in order to lessen the burden of the next beta bump.
Fix#101351.
When an associated type on a type parameter is used, and the type
parameter isn't constrained by the correct trait, suggest the
appropriate trait bound:
```
error[E0220]: associated type `Associated` not found for `T`
--> file.rs:6:15
|
6 | field: T::Associated,
| ^^^^^^^^^^ there is a similarly named associated type `Associated` in the trait `Foo`
|
help: consider restricting type parameter `T`
|
5 | struct Generic<T: Foo> {
| +++++
```
When an associated type on a type parameter has a typo, suggest fixing
it:
```
error[E0220]: associated type `Baa` not found for `T`
--> $DIR/issue-55673.rs:9:8
|
LL | T::Baa: std::fmt::Debug,
| ^^^ there is a similarly named associated type `Bar` in the trait `Foo`
|
help: change the associated type name to use `Bar` from `Foo`
|
LL | T::Bar: std::fmt::Debug,
| ~~~
```
Fix suggestion span involving wrongly placed generic arg on variant
Fixes#116473
The span computation was wrong. It went from the end of the variant to the end of the (wrongly placed) args. However, the variant lived in a different expansion and this resulted in a nonsensical span that overlaps with another and thereby leads to the ICE.
In the fix I've changed span computation to not be based on the location of the variant, but purely on the location of the args. I simply extend the start of the args span 2 positions to the left and that includes the `::` and that's all we need apparently.
This approach produces a correct span regardless of which macro/expansion the args reside in and where the variant is.
When the variant and the (wrongly placed) args are at separate
source locations such as being in different macos or one in a macro and
the other somwhere outside of it, the arg spans we computed spanned
the entire distance between such locations and were hence invalid.
.
Show more information when multiple `impl`s apply
- When there are `impl`s without type params, show only those (to avoid showing overly generic `impl`s).
```
error[E0283]: type annotations needed
--> $DIR/multiple-impl-apply.rs:34:9
|
LL | let y = x.into();
| ^ ---- type must be known at this point
|
note: multiple `impl`s satisfying `_: From<Baz>` found
--> $DIR/multiple-impl-apply.rs:14:1
|
LL | impl From<Baz> for Bar {
| ^^^^^^^^^^^^^^^^^^^^^^
...
LL | impl From<Baz> for Foo {
| ^^^^^^^^^^^^^^^^^^^^^^
= note: required for `Baz` to implement `Into<_>`
help: consider giving `y` an explicit type
|
LL | let y: /* Type */ = x.into();
| ++++++++++++
```
- Lower the importance of `T: Sized`, `T: WellFormed` and coercion errors, to prioritize more relevant errors. The pre-existing deduplication logic deals with hiding redundant errors better that way, and we show errors with more metadata that is useful to the user.
- Show `<SelfTy as Trait>::assoc_fn` suggestion in more cases.
```
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> $DIR/cross-return-site-inference.rs:38:16
|
LL | return Err(From::from("foo"));
| ^^^^^^^^^^ cannot call associated function of trait
|
help: use a fully-qualified path to a specific available implementation
|
LL | return Err(</* self type */ as From>::from("foo"));
| +++++++++++++++++++ +
```
Fix#88284.
More accurately point to where default return type should go
When getting the "default return type" span, instead of pointing to the low span of the next token, point to the high span of the previous token. This:
1. Makes forming return type suggestions more uniform, since we expect them all in the same place.
2. Arguably makes labels easier to understand, since we're pointing to where the implicit `-> ()` would've gone, rather than the starting brace or the semicolon.
r? ```@estebank```
Remove the `TypedArena::alloc_from_iter` specialization.
It was added in #78569. It's complicated and doesn't actually help
performance.
r? `@cjgillot`
In `report_fullfillment_errors` push back `T: Sized`, `T: WellFormed`
and coercion errors to the end of the list. The pre-existing
deduplication logic eliminates redundant errors better that way, keeping
the resulting output with fewer errors than before, while also having
more detail.
a small wf and clause cleanup
- remove `Clause::from_projection_clause`, instead use `ToPredicate`
- change `predicate_obligations` to directly take a `Clause`
- remove some unnecessary `&`
- use clause in `min_specialization` checks where easily applicable
Prototype using const generic for simd_shuffle IDX array
cc https://github.com/rust-lang/rust/issues/85229
r? `@workingjubilee` on the design
TLDR: there is now a `fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;` intrinsic that allows replacing
```rust
simd_shuffle(a, b, const { stuff })
```
with
```rust
simd_shuffle_generic::<_, _, {&stuff}>(a, b)
```
which makes the compiler implementations much simpler, if we manage to at some point eliminate `simd_shuffle`.
There are some issues with this today though (can't do math without bubbling it up in the generic arguments). With this change, we can start porting the simple cases and get better data on the others.
fix(suggestion): insert projection to associated types
Fixes#98562
This PR has fixed some help suggestions for unsupported syntax, such as `fn f<T>(_:T) where T: IntoIterator, std::iter::IntoIterator::Item = () {}` to `fn f<T: IntoIterator<Item = ()>>(_T) {}`.
Make `adt_const_params` feature suggestion consistent with other features and improve when it is emitted
Makes the suggestion to add `adt_const_params` formatted like every other feature gate (notably this makes it such that the playground recognizes it). Additionally improves the situations in which that help is emitted so that it's only emitted when the type would be valid or the type *could* be valid (using a slightly incorrect heuristic that favors suggesting the feature over not) instead of, for example, implying that adding the feature would allow the use of `String`.
Also adds the "the only supported types are integers, `bool` and `char`" note to the errors on fn and raw pointers.
r? `@compiler-errors`
Stabilize `impl_trait_projections`
Closes#115659
## TL;DR:
This allows us to mention `Self` and `T::Assoc` in async fn and return-position `impl Trait`, as you would expect you'd be able to.
Some examples:
```rust
#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
// (just needed for final tests below)
// ---------------------------------------- //
struct Wrapper<'a, T>(&'a T);
impl Wrapper<'_, ()> {
async fn async_fn() -> Self {
//^ Previously rejected because it returns `-> Self`, not `-> Wrapper<'_, ()>`.
Wrapper(&())
}
fn impl_trait() -> impl Iterator<Item = Self> {
//^ Previously rejected because it mentions `Self`, not `Wrapper<'_, ()>`.
std::iter::once(Wrapper(&()))
}
}
// ---------------------------------------- //
trait Trait<'a> {
type Assoc;
fn new() -> Self::Assoc;
}
impl Trait<'_> for () {
type Assoc = ();
fn new() {}
}
impl<'a, T: Trait<'a>> Wrapper<'a, T> {
async fn mk_assoc() -> T::Assoc {
//^ Previously rejected because `T::Assoc` doesn't mention `'a` in the HIR,
// but ends up resolving to `<T as Trait<'a>>::Assoc`, which does rely on `'a`.
// That's the important part -- the elided trait.
T::new()
}
fn a_few_assocs() -> impl Iterator<Item = T::Assoc> {
//^ Previously rejected for the same reason
[T::new(), T::new(), T::new()].into_iter()
}
}
// ---------------------------------------- //
trait InTrait {
async fn async_fn() -> Self;
fn impl_trait() -> impl Iterator<Item = Self>;
}
impl InTrait for &() {
async fn async_fn() -> Self { &() }
//^ Previously rejected just like inherent impls
fn impl_trait() -> impl Iterator<Item = Self> {
//^ Previously rejected just like inherent impls
[&()].into_iter()
}
}
```
## Technical:
Lifetimes in return-position `impl Trait` (and `async fn`) are duplicated as early-bound generics local to the opaque in order to make sure we are able to substitute any late-bound lifetimes from the function in the opaque's hidden type. (The [dev guide](https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html#aside-opaque-lifetime-duplication) has a small section about why this is necessary -- this was written for RPITITs, but it applies to all RPITs)
Prior to #103491, all of the early-bound lifetimes not local to the opaque were replaced with `'static` to avoid issues where relating opaques caused their *non-captured* lifetimes to be related. This `'static` replacement led to strange and possibly unsound behaviors (https://github.com/rust-lang/rust/issues/61949#issuecomment-508836314) (https://github.com/rust-lang/rust/issues/53613) when referencing the `Self` type alias in an impl or indirectly referencing a lifetime parameter via a projection type (via a `T::Assoc` projection without an explicit trait), since lifetime resolution is performed on the HIR, when neither `T::Assoc`-style projections or `Self` in impls are expanded.
Therefore an error was implemented in #62849 to deny this subtle behavior as a known limitation of the compiler. It was attempted by `@cjgillot` to fix this in #91403, which was subsequently unlanded. Then it was re-attempted to much success (🎉) in #103491, which is where we currently are in the compiler.
The PR above (#103491) fixed this issue technically by *not* replacing the opaque's parent lifetimes with `'static`, but instead using variance to properly track which lifetimes are captured and are not. The PR gated any of the "side-effects" of the PR behind a feature gate (`impl_trait_projections`) presumably to avoid having to involve T-lang or T-types in the PR as well. `@cjgillot` can clarify this if I'm misunderstanding what their intention was with the feature gate.
Since we're not replacing (possibly *invariant*!) lifetimes with `'static` anymore, there are no more soundness concerns here. Therefore, this PR removes the feature gate.
Tests:
* `tests/ui/async-await/feature-self-return-type.rs`
* `tests/ui/impl-trait/feature-self-return-type.rs`
* `tests/ui/async-await/issues/issue-78600.rs`
* `tests/ui/impl-trait/capture-lifetime-not-in-hir.rs`
---
r? cjgillot on the impl (not much, just removing the feature gate)
I'm gonna mark this as FCP for T-lang and T-types.
Anonymize binders for `refining_impl_trait` check
We're naively using the equality impl for `ty::Clause` in the refinement check, which is okay *except* for binders, which carry some information about where they come from in the AST. Those locations are not gonna be equal between traits and impls, so anonymize those clauses so that this doesn't matter.
Fixes#116135
Don't store lazyness in `DefKind::TyAlias`
1. Don't store lazyness of a type alias in its `DefKind`, but instead via a query.
2. This allows us to treat type aliases as lazy if `#[feature(lazy_type_alias)]` *OR* if the alias contains a TAIT, rather than having checks for both in separate parts of the codebase.
r? `@oli-obk` cc `@fmease`
subst -> instantiate
continues #110793, there are still quite a few uses of `subst` and `substitute`, but changing them all in the same PR was a bit too much, so I've stopped here for now.
Use placeholders to prevent using inferred RPITIT types to imply their own well-formedness
The issue here is that we use the same signature to do RPITIT inference as we do to compute implied bounds. To fix this, when gathering the assumed wf types for the method, we replace all of the infer vars (that will be eventually used to infer RPITIT types) with type placeholders, which imply nothing about lifetime bounds.
This solution kind of sucks, but I'm not certain there's another feasible way to fix this. If anyone has a better solution, I'd be glad to hear it.
My naive first solution was, instead of using placeholders, to replace the signature with the RPITIT projections that it originally started out with. But turns out that we can't just use the unnormalized signature of the trait method in `implied_outlives_bounds` since we normalize during WF computation -- that would cause a query cycle in `collect_return_position_impl_trait_in_trait_tys`.
idk who to request review...
r? `@lcnr` or `@aliemjay` i guess.
Fixes#116060
Check that closure/generator's interior/capture types are sized
check that closure upvars and generator interiors are sized. this check is only necessary when `unsized_fn_params` or `unsized_locals` is enabled, so only check if those are active.
Fixes#93622Fixes#61335Fixes#68543
This happens because variances are constructed from ty generics,
and ty generics are always constructed with lifetimes first.
See compiler/rustc_hir_analysis/src/collect/generics_of.rs:248-269
Fixes#83556
rustc_hir_analysis: add a helper to check function the signature mismatches
This function is now used to check `#[panic_handler]`, `start` lang item, `main`, `#[start]` and intrinsic functions.
The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.
This is the first time I do anything with rustc_hir_analysis/rustc_hir_typeck, so comments and suggestions about things I did wrong or that could be improved will be appreciated.
clean up unneeded `ToPredicate` impls
Part of #107250.
Removed all totally unused impls. And inlined two impls not need to satisify trait bound.
r? `@oli-obk`
Correctly deny late-bound lifetimes from parent in anon consts and TAITs
Reuse the `AnonConstBoundary` scope (introduced in #108553, renamed in this PR to `LateBoundary`) to deny late-bound vars of *all* kinds (ty/const/lifetime) in anon consts and TAITs.
Side-note, but I would like to consolidate this with the error reporting for RPITs (E0657):
c4f25777a0/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs (L733-L754) but the semantics about what we're allowed to capture there are slightly different, so I'm leaving that untouched.
Fixes#115474
This function is now used to check `#[panic_handler]`, `start` lang item, `main`, `#[start]` and intrinsic functions.
The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.
repr(transparent): it's fine if the one non-1-ZST field is a ZST
This code currently gets rejected:
```rust
#[repr(transparent)]
struct MyType([u16; 0])
```
That clearly seems like a bug to me: `repr(transparent)` [got defined ](https://github.com/rust-lang/rust/issues/77841#issuecomment-716575747) as having any number of 1-ZST fields plus optionally one more field; `MyType` clearly satisfies that definition.
This PR changes the `repr(transparent)` logic to actually match that definition.
Improve invalid let expression handling
- Move all of the checks for valid let expression positions to parsing.
- Add a field to ExprKind::Let in AST/HIR to mark whether it's in a valid location.
- Suppress some later errors and MIR construction for invalid let expressions.
- Fix a (drop) scope issue that was also responsible for #104172.
Fixes#104172Fixes#104868
interpret: change ABI-compat test to be type-based
This makes the test consistent across targets. Otherwise the chances are very high that ABI mismatches get accepted on x86_64 but still fail on many other targets with more complicated ABIs.
This implements (most of) the rules described in https://github.com/rust-lang/rust/pull/115476.
There was an incomplete version of the check in parsing and a second
version in AST validation. This meant that some, but not all, invalid
uses were allowed inside macros/disabled cfgs. It also means that later
passes have a hard time knowing when the let expression is in a valid
location, sometimes causing ICEs.
- Add a field to ExprKind::Let in AST/HIR to mark whether it's in a
valid location.
- Suppress later errors and MIR construction for invalid let
expressions.
Add `FreezeLock` type and use it to store `Definitions`
This adds a `FreezeLock` type which allows mutation using a lock until the value is frozen where it can be accessed lock-free. It's used to store `Definitions` in `Untracked` instead of a `RwLock`. Unlike the current scheme of leaking read guards this doesn't deadlock if definitions is written to after no mutation are expected.
Permit recursive weak type aliases
I saw #63097 and thought "we can do ~~better~~ funnier". So here it is. It's not useful, but it's certainly something. This may actually become feasible with lazy norm (so in 5 years (constant, not reducing over time)).
r? `@estebank`
cc `@GuillaumeGomez`
Don't add associated type bound for non-types
We had this fix for equality constraints (#99890), but for some reason not trait constraints 😅Fixes#114744
fixed *const [type error] does not implement the Copy trait
Removes "error: arguments for inline assembly must be copyable" when moving an unknown type
Fixes: #113788
Select obligations before processing wf obligation in `compare_method_predicate_entailment`
We need to select obligations before processing the WF obligation for the `IMPLIED_BOUNDS_ENTAILMENT` lint, since it skips over type variables.
Fixes#114783
r? `@jackh726`
Map RPIT duplicated lifetimes back to fn captured lifetimes
Use the [`lifetime_mapping`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.OpaqueTy.html#structfield.lifetime_mapping) to map an RPIT's captured lifetimes back to the early- or late-bound lifetimes from its parent function. We may be going thru several layers of mapping, since opaques can be nested, so we introduce `TyCtxt::map_rpit_lifetime_to_fn_lifetime` to loop through several opaques worth of mapping, and handle turning it into a `ty::Region` as well.
We can then use this instead of the identity substs for RPITs in `check_opaque_meets_bounds` to address #114285.
We can then also use `map_rpit_lifetime_to_fn_lifetime` to properly install bidirectional-outlives predicates for both RPITs and RPITITs. This addresses #114601.
I based this on #114574, but I don't actually know how much of that PR we still need, so some code may be redundant now... 🤷
---
Fixes#114597Fixes#114579Fixes#114285
Also fixes#114601, since it turns out we had other bugs with RPITITs and their duplicated lifetime params 😅.
Supersedes #114574
r? `@oli-obk`
Structurally normalize weak and inherent in new solver
It seems pretty obvious to me that we should be normalizing weak and inherent aliases too, since they can always be normalized. This PR still leaves open the question of what to do with opaques, though 💀
**Also**, we need to structurally resolve the target of a coercion, for the UI test to work.
r? `@lcnr`
Store the laziness of type aliases in their `DefKind`
Previously, we would treat paths referring to type aliases as *lazy* type aliases if the current crate had lazy type aliases enabled independently of whether the crate which the alias was defined in had the feature enabled or not.
With this PR, the laziness of a type alias depends on the crate it is defined in. This generally makes more sense to me especially if / once lazy type aliases become the default in a new edition and we need to think about *edition interoperability*:
Consider the hypothetical case where the dependency crate has an older edition (and thus eager type aliases), it exports a type alias with bounds & a where-clause (which are void but technically valid), the dependent crate has the latest edition (and thus lazy type aliases) and it uses that type alias. Arguably, the bounds should *not* be checked since at any time, the dependency crate should be allowed to change the bounds at will with a *non*-major version bump & without negatively affecting downstream crates.
As for the reverse case (dependency: lazy type aliases, dependent: eager type aliases), I guess it rules out anything from slight confusion to mild annoyance from upstream crate authors that would be caused by the compiler ignoring the bounds of their type aliases in downstream crates with older editions.
---
This fixes#114468 since before, my assumption that the type alias associated with a given weak projection was lazy (and therefore had its variances computed) did not necessarily hold in cross-crate scenarios (which [I kinda had a hunch about](https://github.com/rust-lang/rust/pull/114253#discussion_r1278608099)) as outlined above. Now it does hold.
`@rustbot` label F-lazy_type_alias
r? `@oli-obk`
Don't check unnecessarily that impl trait is RPIT
We have this random `return_type_impl_trait` function to detect if a function returns an RPIT which is used in outlives suggestions, but removing it doesn't actually change any diagnostics. Let's just remove it.
Also, suppress a spurious outlives error from a ReError.
Fixes#114274
Map RPITIT's opaque type bounds back from projections to opaques
An RPITIT in a program's AST is eventually translated into both a projection GAT and an opaque. The opaque is used for default trait methods, like:
```
trait Foo {
fn bar() -> impl Sized { 0i32 }
}
```
The item bounds for both the projection and opaque are identical, and both have a *projection* self ty. This is mostly okay, since we can normalize this projection within the default trait method body to the opaque, but it does two things:
1. it leads to bugs in places where we don't normalize item bounds, like `deduce_future_output_from_obligations`
2. it leads to extra match arms that are both suspicious looking and also easy to miss
This PR maps the opaque type bounds of the RPITIT's *opaque* back to the opaque's self type to avoid this quirk. Then we can fix the UI test for #108304 (1.) and also remove a bunch of match arms (2.).
Fixes#108304
r? `@spastorino`
Rollup of 7 pull requests
Successful merges:
- #114099 (privacy: no nominal visibility for assoc fns )
- #114128 (When flushing delayed span bugs, write to the ICE dump file even if it doesn't exist)
- #114138 (Adjust spans correctly for fn -> method suggestion)
- #114146 (Skip reporting item name when checking RPITIT GAT's associated type bounds hold)
- #114147 (Insert RPITITs that were shadowed by missing ADTs that resolve to [type error])
- #114155 (Replace a lazy `RefCell<Option<T>>` with `OnceCell<T>`)
- #114164 (Add regression test for `--cap-lints allow` and trait bounds warning)
r? `@ghost`
`@rustbot` modify labels: rollup