From `impl Into<DiagnosticMessage>` to `impl Into<Cow<'static, str>>`.
Because these functions don't produce user-facing output and we don't
want their strings to be translated.
interpret/cast: make more matches on FloatTy properly exhaustive
Actually implementing these is pretty trivial (at least once all the scalar methods are added, which happens in https://github.com/rust-lang/rust/pull/121926), but I'm staying consistent with the other f16/f128 PRs. Also adding adding all the tests to Miri would be quite a lot of work.
There's probably some way to reduce the code duplication here with more use of generics... but that's a future refactor.^^
r? ```@tgross35```
pattern analysis: abort on arity mismatch
This is one more PR replacing panics by `Err()` aborts. I recently audited all the `unwrap()` calls, but I had forgotten about array accesses. (Again [discovered by rust-analyzer](https://github.com/rust-lang/rust-analyzer/issues/16746)).
r? ```@compiler-errors```
Use the correct logic for nested impl trait in assoc types
Previously we accidentally continued with the TAIT visitor, which allowed more than we wanted to.
r? ```@compiler-errors```
Use root obligation on E0277 for some cases
When encountering trait bound errors that satisfy some heuristics that tell us that the relevant trait for the user comes from the root obligation and not the current obligation, we use the root predicate for the main message.
This allows to talk about "X doesn't implement Pattern<'_>" over the most specific case that just happened to fail, like "char doesn't implement Fn(&mut char)" in
`tests/ui/traits/suggest-dereferences/root-obligation.rs`
The heuristics are:
- the type of the leaf predicate is (roughly) the same as the type from the root predicate, as a proxy for "we care about the root"
- the leaf trait and the root trait are different, so as to avoid talking about `&mut T: Trait` and instead remain talking about `T: Trait` instead
- the root trait is not `Unsize`, as to avoid talking about it in `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
```
error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
--> $DIR/root-obligation.rs:6:38
|
LL | .filter(|c| "aeiou".contains(c))
| -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
| |
| required by a bound introduced by this call
|
= note: required for `&char` to implement `FnOnce<(char,)>`
= note: required for `&char` to implement `Pattern<'_>`
note: required by a bound in `core::str::<impl str>::contains`
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
help: consider dereferencing here
|
LL | .filter(|c| "aeiou".contains(*c))
| +
```
Fix#79359, fix#119983, fix#118779, cc #118415 (the suggestion needs to change), cc #121398 (doesn't fix the underlying issue).
Adjust error `yield`/`await` lowering
Adjust the lowering of `yield`/`await` outside of their correct scopes so that we no longer make orpan HIR exprs.
Previously, `yield EXPR` would be lowered directly to `hir::TyKind::Error` (which I'll call `<error>`) which means that `EXPR` was not present in the HIR, but now we lower it to `{ EXPR; <error> }` so that `EXPR` is not orphaned.
Fixes#121096
They are two different ways of creating dummy results, with two
different purposes. Their implementations are separate except for
crates, where `DummyResult` depends on `DummyAstNode`.
This commit removes that dependency, so they are now fully separate. It
also expands the comment on `DummyAstNode`.
Add a scheme for moving away from `extern "rust-intrinsic"` entirely
All `rust-intrinsic`s can become free functions now, either with a fallback body, or with a dummy body and an attribute, requiring backends to actually implement the intrinsic.
This PR demonstrates the dummy-body scheme with the `vtable_size` intrinsic.
cc https://github.com/rust-lang/rust/issues/63585
follow-up to #120500
MCP at https://github.com/rust-lang/compiler-team/issues/720
Rollup of 10 pull requests
Successful merges:
- #120976 (constify a couple thread_local statics)
- #121683 (Fix LVI tests after frame pointers are enabled by default)
- #121703 (Add a way to add constructors for `rustc_type_ir` types)
- #121732 (Improve assert_matches! documentation)
- #121928 (Extract an arguments struct for `Builder::then_else_break`)
- #121939 (Small enhancement to description of From trait)
- #121968 (Don't run test_get_os_named_thread on win7)
- #121969 (`ParseSess` cleanups)
- #121977 (Doc: Fix incorrect reference to integer in Atomic{Ptr,Bool}::as_ptr.)
- #121994 (Update platform-support.md with supported musl version)
r? `@ghost`
`@rustbot` modify labels: rollup
Extract an arguments struct for `Builder::then_else_break`
Most of this method's arguments are usually or always forwarded as-is to recursive invocations.
Wrapping them in a dedicated struct allows us to document each struct field, and lets us use struct-update syntax to indicate which arguments are being modified when making a recursive call.
---
While trying to understand the lowering of `if` expressions, I found it difficult to keep track of the half-dozen arguments passed through to every call to `then_else_break`. I tried switching over to an arguments struct, and I found that it really helps to make sense of what each argument does, and how each call is modifying the arguments.
I have some further ideas for how to streamline these recursive calls, but I've kept those out of this PR so that it's a pure refactoring with no behavioural changes.
Add a way to add constructors for `rustc_type_ir` types
Introduces a module called `rustc_type_ir`, in which we can place traits which are named `Ty`/`Region`/`Const`/etc. which expose constructors for the `rustc_type_ir` types. This means we can construct things `Interner::Ty` with `Ty::new_x(...)`, which is needed to uplift the new trait solver into an interner-agnostic crate.
These traits are placed into a *separate* module because they're only intended to be used in interner-agnostic code, and they should mirror the constructors that are provided by the inherent constructor methods in `rustc_middle`.
Putting this up for vibe-check mostly. I haven't copied over any of the type constructors, except for one to create bound types for use in the canonicalizer.
r? lcnr
Existing names for values of this type are `sess`, `parse_sess`,
`parse_session`, and `ps`. `sess` is particularly annoying because
that's also used for `Session` values, which are often co-located, and
it can be difficult to know which type a value named `sess` refers to.
(That annoyance is the main motivation for this change.) `psess` is nice
and short, which is good for a name used this much.
The commit also renames some `parse_sess_created` values as
`psess_created`.
Add a new `wasm32-wasip1` target to rustc
This commit adds a new target called `wasm32-wasip1` to rustc. This new target is explained in these two MCPs:
* https://github.com/rust-lang/compiler-team/issues/607
* https://github.com/rust-lang/compiler-team/issues/695
In short, the previous `wasm32-wasi` target is going to be renamed to `wasm32-wasip1` to better live alongside the [new `wasm32-wasip2` target](https://github.com/rust-lang/rust/pull/119616). This new target is added alongside the `wasm32-wasi` target and has the exact same definition as the previous target. This PR is effectively a rename of `wasm32-wasi` to `wasm32-wasip1`. Note, however, that as explained in rust-lang/compiler-team#695 the previous `wasm32-wasi` target is not being removed at this time. This change will reach stable Rust before even a warning about the rename will be printed. At this time this change is just the start where a new target is introduced and users can start migrating if they support only Nightly for example.
For the former, it's fine for `inbounds` offsets to be one-past-the-end,
so it's okay even if the ZST is the last field in the layout:
> The base pointer has an in bounds address of an allocated object,
> which means that it points into an allocated object, or to its end.
https://llvm.org/docs/LangRef.html#getelementptr-instruction
For the latter, even DST fields must always be inside the layout
(or to its end for ZSTs), so using inbounds is also fine there.
Unnamed union fields with enums are checked for, but if `find_field`
causes an ICE then the compiler won't get to that point.
Signed-off-by: David Wood <david@davidtw.co>
Rollup of 3 pull requests
Successful merges:
- #121130 (Suggest moving definition if non-found macro_rules! is defined later)
- #121912 (Properly deal with GATs when looking for method chains to point at)
- #121927 (Add a proper `with_no_queries` to printing)
r? `@ghost`
`@rustbot` modify labels: rollup
Most of this method's arguments are usually or always forwarded as-is to
recursive invocations.
Wrapping them in a dedicated struct allows us to document each struct field,
and lets us use struct-update syntax to indicate which arguments are being
modified when making a recursive call.
Properly deal with GATs when looking for method chains to point at
Fixes#121898.
~~While it prevents an ICE and the structured suggestion is correct, the method chain diagnostic notes are weird / useless / incorrect judging by a quick look. I guess I should improve that in this PR.~~ Sufficiently taken care of.
r? estebank or compiler-errors (#105332, #105674).
With rust 1.75 the absolute build path is embedding into '.rustc' section and which causes reproducibility issues. Detailed issue is here.
https://github.com/rust-lang/rust/issues/120825#issuecomment-1964307219
With this change the 'absolute path' changed back to '/rust/$hash' format.
Rollup of 5 pull requests
Successful merges:
- #121248 (Move some tests)
- #121528 (Consider middle segments of paths in `unused_qualifications`)
- #121749 (Don't lint on executable crates with `non_snake_case` names)
- #121935 (library/ptr: mention that ptr::without_provenance is equivalent to deriving from the null ptr)
- #121945 (Run some ui-fulldeps tests on stage 1 again)
r? `@ghost`
`@rustbot` modify labels: rollup
Consider middle segments of paths in `unused_qualifications`
Currently `unused_qualifications` looks at the last segment of a path to see if it can be trimmed, this PR extends the check to the middle segments also
```rust
// currently linted
use std::env::args();
std::env::args(); // Removes `std::env::`
```
```rust
// newly linted
use std::env;
std::env::args(); // Removes `std::`
```
Paths with generics in them are now linted as long as the part being trimmed is before any generic args, e.g. it will now suggest trimming `std::vec::` from `std::vec::Vec<usize>`
Paths with any segments that are from an expansion are no longer linted
Fixes#100979Fixes#96698
```
error[E0599]: no method named `map` found for struct `Vec<bool>` in the current scope
--> $DIR/vec-on-unimplemented.rs:3:23
|
LL | vec![true, false].map(|v| !v).collect::<Vec<_>>();
| ^^^ `Vec<bool>` is not an iterator
|
help: call `.into_iter()` first
|
LL | vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>();
| ++++++++++++
```
We used to provide some help through `rustc_on_unimplemented` on non-`impl Trait` and non-type-params, but this lets us get rid of some otherwise unnecessary conditions in the annotation on `Iterator`.
When encountering trait bound errors that satisfy some heuristics that
tell us that the relevant trait for the user comes from the root
obligation and not the current obligation, we use the root predicate for
the main message.
This allows to talk about "X doesn't implement Pattern<'_>" over the
most specific case that just happened to fail, like "char doesn't
implement Fn(&mut char)" in
`tests/ui/traits/suggest-dereferences/root-obligation.rs`
The heuristics are:
- the type of the leaf predicate is (roughly) the same as the type
from the root predicate, as a proxy for "we care about the root"
- the leaf trait and the root trait are different, so as to avoid
talking about `&mut T: Trait` and instead remain talking about
`T: Trait` instead
- the root trait is not `Unsize`, as to avoid talking about it in
`tests/ui/coercion/coerce-issue-49593-box-never.rs`.
```
error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
--> $DIR/root-obligation.rs:6:38
|
LL | .filter(|c| "aeiou".contains(c))
| -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
| |
| required by a bound introduced by this call
|
= note: required for `&char` to implement `FnOnce<(char,)>`
= note: required for `&char` to implement `Pattern<'_>`
note: required by a bound in `core::str::<impl str>::contains`
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
help: consider dereferencing here
|
LL | .filter(|c| "aeiou".contains(*c))
| +
```
Fix#79359, fix#119983, fix#118779, cc #118415 (the suggestion needs
to change).
Add new `pattern_complexity` attribute to add possibility to limit and check recursion in pattern matching
Needed for https://github.com/rust-lang/rust-analyzer/issues/9528.
This PR adds a new attribute only available when running rust testsuite called `pattern_complexity` which allows to set the maximum recursion for the pattern matching. It is quite useful to ensure the complexity doesn't grow, like in `tests/ui/pattern/usefulness/issue-118437-exponential-time-on-diagonal-match.rs`.
r? `@Nadrieril`
Rollup of 5 pull requests
Successful merges:
- #120761 (Add initial support for DataFlowSanitizer)
- #121622 (Preserve same vtable pointer when cloning raw waker, to fix Waker::will_wake)
- #121716 (match lowering: Lower bindings in a predictable order)
- #121731 (Now that inlining, mir validation and const eval all use reveal-all, we won't be constraining hidden types here anymore)
- #121841 (`f16` and `f128` step 2: intrinsics)
r? `@ghost`
`@rustbot` modify labels: rollup
`f16` and `f128` step 2: intrinsics
Continuation of https://github.com/rust-lang/rust/pull/121728, another portion of https://github.com/rust-lang/rust/pull/114607.
This PR adds `f16` and `f128` intrinsics, and hooks them up to both HIR and LLVM. This is all still unexposed to the frontend, which will probably be the next step. Also update itanium mangling per `@rcvalle's` in https://github.com/rust-lang/rust/pull/121728/files#r1506570300, and fix a typo from step 1.
Once these types are usable in code, I will add the codegen tests from #114607 (codegen is passing on that branch)
This does add more `unimplemented!`s to Clippy, but I still don't think we can do better until library support is added.
r? `@compiler-errors`
cc `@Nilstrieb`
`@rustbot` label +T-compiler +F-f16_and_f128
Now that inlining, mir validation and const eval all use reveal-all, we won't be constraining hidden types here anymore
r? `@compiler-errors`
one bubble down, two more to go
the test is unrelated, just something I noticed would be good to test in both the old solver and the new.
match lowering: Lower bindings in a predictable order
After the recent refactorings, we can now lower bindings in a truly predictable order. The order in https://github.com/rust-lang/rust/pull/120214 was an improvement but not very clear. With this PR, we lower bindings from left to right, with the special case that `x @ pat` is traversed as `pat @ x` (i.e. `x` is lowered after any bindings in `pat`).
This description only applies in the absence of or-patterns. Or-patterns make everything complicated, because the binding place depends on the subpattern. Until I have a better idea I leave them to be handled in whatever weird order arises from today's code.
r? `@matthewjasper`
Add initial support for DataFlowSanitizer
Adds initial support for DataFlowSanitizer to the Rust compiler. It currently supports `-Zsanitizer-dataflow-abilist`. Additional options for it can be passed to LLVM command line argument processor via LLVM arguments using `llvm-args` codegen option (e.g., `-Cllvm-args=-dfsan-combine-pointer-labels-on-load=false`).
This commit adds a new target called `wasm32-wasip1` to rustc.
This new target is explained in these two MCPs:
* https://github.com/rust-lang/compiler-team/issues/607
* https://github.com/rust-lang/compiler-team/issues/695
In short, the previous `wasm32-wasi` target is going to be renamed to
`wasm32-wasip1` to better live alongside the [new
`wasm32-wasip2` target](https://github.com/rust-lang/rust/pull/119616).
This new target is added alongside the `wasm32-wasi` target and has the
exact same definition as the previous target. This PR is effectively a
rename of `wasm32-wasi` to `wasm32-wasip1`. Note, however, that
as explained in rust-lang/compiler-team#695 the previous `wasm32-wasi`
target is not being removed at this time. This change will reach stable
Rust before even a warning about the rename will be printed. At this
time this change is just the start where a new target is introduced and
users can start migrating if they support only Nightly for example.
The ordinary lowering of `thir::ExprKind::Let` is unreachable
After desugaring, `let` expressions should only appear inside `if` expressions or `match` guards, possibly nested within a let-chain. In both cases they are specifically handled by the lowerings of those expressions, so this case is currently unreachable.
---
Context: https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Lowering.20of.20.60thir.3A.3AExprKind.3A.3ALet.60.20is.20unreachable
My conclusions are partly based on the observation that stubbing out this match arm doesn't cause any test failures. So either this really is unreachable, or it can be reached in some obscure circumstances that our test suite doesn't cover.
If we end up needing this code (or something like it) for an implementation of https://github.com/rust-lang/rfcs/pull/3573, it should be easy enough to pull it back out of version control history.
I looked into having the `if`/`match` lowerings call back into `expr_into_dest`, but from what I can tell that won't work well, because there are extra scoping considerations that require some awareness of the enclosing if/match.
r? ```@Nadrieril```
After desugaring, `let` expressions should only appear inside `if` expressions
or `match` guards, possibly nested within a let-chain. In both cases they are
specifically handled by the lowerings of those expressions, so this case is
currently unreachable.
Account for unmet T: !Copy in E0277 message
```
error[E0277]: the trait bound `T: !Copy` is not satisfied
--> $DIR/simple.rs:10:16
|
LL | not_copy::<T>();
| ^ the trait bound `T: !Copy` is not satisfied
```
instead of the current
```
error[E0277]: the trait bound `T: !Copy` is not satisfied
--> $DIR/simple.rs:10:16
|
LL | not_copy::<T>();
| ^ the trait `!Copy` is not implemented for `T`
```
Display short types for unimplemented trait
Shortens unimplemented trait diagnostics. Now shows:
```
error[E0277]: `Option<Option<Option<...>>>` doesn't implement `std::fmt::Display`
--> $DIR/on_unimplemented_long_types.rs:4:17
|
LL | pub fn foo() -> impl std::fmt::Display {
| ^^^^^^^^^^^^^^^^^^^^^^ `Option<Option<Option<...>>>` cannot be formatted with the default formatter
LL |
LL | / Some(Some(Some(Some(Some(Some(Some(Some(Some(S...
LL | | Some(Some(Some(Some(Some(Some(Some(Some(So...
LL | | Some(Some(Some(Some(Some(Some(Some(Som...
LL | | Some(Some(Some(Some(Some(Some(Some...
... |
LL | | ))))))))))),
LL | | )))))))))))
| |_______________- return type was inferred to be `Option<Option<Option<...>>>` here
|
= help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.
```
I'm not 100% sure if this is desirable, or if we should just let the long types remain long. This is also kinda a short-term bandaid solution. The real long term solution is to properly migrate `rustc_trait_selection`'s error reporting to use translatable diagnostics and then properly handle type name printing.
Fixes#121687.
match lowering: pre-simplify or-patterns too
This is the final part of my work to simplify match pairs early: now we do it for or-patterns too. This makes it possible to collect fake borrows separately from the main match lowering algorithm. That'll enable more simplifications of or-pattern handling.
Note: I was tempted to have `Candidate` contain a `FlatPat`, but there are so many places that use `candidate.match_pairs` etc directly that I chose not to.
r? `@matthewjasper`
Update E0716.md for clarity
When reading through this, I got slightly hung up thinking the `let` it was referring to was the `let tmp` on line 25, which was confusing considering the comment states that the temporary is freed at the end of the block. I think adding this clarification could potentially help some beginners like myself without being overly verbose.
Don't grab variances in `TypeRelating` relation if we're invariant
Since `Invariant.xform(var) = Invariant` always, so just copy what the generalizer relation does.
Fixes#110106
Detect more cases of `=` to `:` typo
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span arround and mention it. If the type could continue being parsed as an expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix#119665.
Adds initial support for DataFlowSanitizer to the Rust compiler. It
currently supports `-Zsanitizer-dataflow-abilist`. Additional options
for it can be passed to LLVM command line argument processor via LLVM
arguments using `llvm-args` codegen option (e.g.,
`-Cllvm-args=-dfsan-combine-pointer-labels-on-load=false`).
Implement missing ABI structures in StableMIR
Add implementations for Scalar, Primitive and WrappingRange for StableMIR.
FYI, I thought about reusing the `rustc_abi` module, since it is designed to not necessarily depend on the `rustc` internals, but the maintenance burden to maintain this crate in crates.io doesn't seem worth it at this point.
Fixes https://github.com/rust-lang/project-stable-mir/issues/58
Never say "`Trait` is implemented for `{type error}`"
When a trait bound error occurs, we look for alternative types that would have made the bound succeed. For some reason `{type error}` sometimes would appear as a type that would do so.
We now remove `{type error}` from the list in every case to avoid nonsensical `note`s.
match lowering: Separate the `bool` case from other integers in `TestKind`
`TestKind::SwitchInt` had a special case for `bool` essentially everywhere it's used, so I made `TestKind::If` to handle the bool case on its own.
r? `@matthewjasper`
Add profiling support to AIX
AIX ld needs special option to merge objects with profiling. Also, profiler_builtins should include builtins for AIX from compiler-rt.
match lowering: Remove hacky branch in sort_candidate
Reusing `self.test()` there wasn't actually pulling a lot of weight. In particular the `TestKind::Len` cases were all already correctly handled.
r? `@matthewjasper`
Suggest removing superfluous semicolon when statements used as expression
Fixes#105431
- it's not a pure recursive visitor, so I guess there may be some more complex scenarios not covered.
- moved `consider_removing_semicolon` to `compiler/rustc_infer` for reusing this helper function.
Handle stashing of delayed bugs
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.
r? ````@oli-obk````
Make the success arms of `if lhs || rhs` meet up in a separate block
Extracted from #118305, where this is necessary to avoid introducing a bug when injecting marker statements into the then/else arms.
---
In the previous code (#111752), the success block of `lhs` would jump directly to the success block of `rhs`. However, `rhs_success_block` could already contain statements that are specific to the RHS, and the direct goto causes them to be executed in the LHS success path as well.
This patch therefore creates a fresh block that the LHS and RHS success blocks can both jump to.
---
I think the reason we currently get away with this is that `rhs_success_block` usually doesn't contain anything other than StorageDead statements for locals used by the RHS, and those statements don't seem to cause problems in the LHS success path (which never makes those locals live).
But if we start adding meaningful statements for branch coverage (or MC/DC coverage), it's important to keep the LHS and RHS blocks separate.
make unused_imports less assertive in test modules
closes#121502
This is a fairly small change and I used the fix suggested in the example expected error message.
Not sure if I should've rather used the alternatives but this one seems the most descriptive.
Some alternatives:
- if this is meant to be a test module, add `#[cfg(test)]` to the containing module
- try adding #[cfg(test)] to this test module
- consider adding #[allow(unused_imports)] if you want to silent the lint on the unused import
- consider removing the unused import
Improve error messages for generics with default parameters
Fixes#120785
Issue: Previously, all type parameters with default types were deliberately ignored to simplify error messages. For example, an error message for Box type would display `Box<T>` instead of `Box<T, _>`. But, this resulted in unclear error message when a concrete type was used instead of the default type.
Fix: This PR fixes it by checking if a concrete type is specified after a default type to display the entire type name or the simplified type name.
Combine `Sub` and `Equate`
Combine `Sub` and `Equate` into a new relation called `TypeRelating` (that name sounds familiar...)
Tracks the difference between `Sub` and `Equate` via `ambient_variance: ty::Variance` much like the `NllTypeRelating` relation, but implemented slightly jankier because it's a more general purpose relation.
r? lcnr
Add stubs in IR and ABI for `f16` and `f128`
This is the very first step toward the changes in https://github.com/rust-lang/rust/pull/114607 and the [`f16` and `f128` RFC](https://rust-lang.github.io/rfcs/3453-f16-and-f128.html). It adds the types to `rustc_type_ir::FloatTy` and `rustc_abi::Primitive`, and just propagates those out as `unimplemented!` stubs where necessary.
These types do not parse yet so there is no feature gate, and it should be okay to use `unimplemented!`.
The next steps will probably be AST support with parsing and the feature gate.
r? `@compiler-errors`
cc `@Nilstrieb` suggested breaking the PR up in https://github.com/rust-lang/rust/pull/120645#issuecomment-1925900572
When a trait bound error occurs, we look for alternative types that
would have made the bound succeed. For some reason `{type error}`
sometimes would appear as a type that would do so.
We now remove `{type error}` from the list in every case to avoid
nonsensical `note`s.
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix#119665.
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.
allow statics pointing to mutable statics
Fixes https://github.com/rust-lang/rust/issues/120450 for good. We can even simplify our checks: no need to specifically go looking for mutable references in const, we can just reject any reference that points to something mutable.
r? `@oli-obk`
Safe Transmute: Revise safety analysis
This PR migrates `BikeshedIntrinsicFrom` to a simplified safety analysis (described [here](https://github.com/rust-lang/project-safe-transmute/issues/15)) that does not rely on analyzing the visibility of types and fields.
The revised analysis treats primitive types as safe, and user-defined types as potentially carrying safety invariants. If Rust gains explicit (un)safe fields, this PR is structured so that it will be fairly easy to thread support for those annotations into the analysis.
Notably, this PR removes the `Context` type parameter from `BikeshedIntrinsicFrom`. Most of the files changed by this PR are just UI tests tweaked to accommodate the removed parameter.
r? `@compiler-errors`
rustc: Fix wasm64 metadata object files
It looks like LLD will detect object files being either 32 or 64-bit depending on any memory present. LLD will additionally reject 32-bit objects during a 64-bit link. Previously metadata objects did not have any memories in them which led LLD to conclude they were 32-bit objects which broke 64-bit targets for wasm.
This commit fixes this by ensuring that for 64-bit targets there's a memory object present to get LLD to detect it's a 64-bit target. Additionally this commit moves away from a hand-crafted wasm encoder to the `wasm-encoder` crate on crates.io as the complexity grows for the generated object file.
Closes#121460
Detect empty leading where clauses on type aliases
1. commit: refactor the AST of type alias where clauses
* I could no longer bear the look of `.0.1` and `.1.0`
* Arguably moving `split` out of `TyAlias` into a substruct might not make that much sense from a semantic standpoint since it reprs an index into `TyAlias.predicates` but it's alright and it cleans up the usage sites of `TyAlias`
2. commit: fix an oversight: An empty leading where clause is still a leading where clause
* semantically reject empty leading where clauses on lazy type aliases
* e.g., on `#![feature(lazy_type_alias)] type X where = ();`
* make empty leading where clauses on assoc types trigger lint `deprecated_where_clause_location`
* e.g., `impl Trait for () { type X where = (); }`
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`
Emitter cleanups
Some cleanups I made when reading emitter code. In particular, `HumanEmitter` and `JsonEmitter` have gone from three constructors to one.
r? `@oli-obk`
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`
Skip unnecessary comparison with half-open range patterns
This is the last remaining detail in the implementation of half-open range patterns. Until now, a half-open range pattern like `10..` was converted to `10..T::MAX` before lowering to MIR, which generated an extra pointless comparison. With this PR we don't generate it.
pattern_analysis: rework how we hide empty private fields
Consider this:
```rust
mod foo {
pub struct Bar {
pub a: bool,
b: !,
}
}
fn match_a_bar(bar: foo::Bar) -> bool {
match bar {
Bar { a, .. } => a,
}
}
```
Because the field `b` is private, matches outside the module are not allowed to observe the fact that `Bar` is empty. In particular `match bar {}` is valid within the module `foo` but an error outside (assuming `exhaustive_patterns`).
We currently handle this by hiding the field `b` when it's both private and empty. This means that the pattern `Bar { a, .. }` is lowered to `Bar(a, _)` if we're inside of `foo` and to `Bar(a)` outside. This involves a bit of a dance to keep field indices straight. But most importantly this makes pattern lowering depend on the module.
In this PR, I instead do nothing special when lowering. Only during analysis do we track whether a place must be skipped.
r? `@compiler-errors`
Improve renaming suggestion when item starts with underscore
Fixes https://github.com/rust-lang/rust/issues/121776.
It goes from:
```terminal
error[E0433]: failed to resolve: use of undeclared type `Foo`
--> src/foo.rs:6:13
|
6 | let _ = Foo::Bar;
| ^^^ use of undeclared type `Foo`
|
help: an enum with a similar name exists, consider changing it
|
1 | enum Foo {
| ~~~
```
to:
```terminal
error[E0433]: failed to resolve: use of undeclared type `Foo`
--> foo.rs:6:13
|
6 | let _ = Foo::Bar;
| ^^^ use of undeclared type `Foo`
|
help: an enum with a similar name exists, consider renaming `_Foo` into `Foo`
|
1 | enum Foo {
| ~~~
error: aborting due to 1 previous error
```
Fix `async Fn` confirmation for `FnDef`/`FnPtr`/`Closure` types
Fixes three issues:
1. The code in `extract_tupled_inputs_and_output_from_async_callable` was accidentally getting the *future* type and the *output* type (returned by the future) messed up for fnptr/fndef/closure types. :/
2. We have a (class of) bug(s) in the old solver where we don't really support higher ranked built-in `Future` goals for generators. This is not possible to hit on stable code, but [can be hit with `unboxed_closures`](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e935de7181e37e13515ad01720bcb899) (#121653).
* I'm opting not to fix that in this PR. Instead, I just instantiate placeholders when confirming `async Fn` goals.
4. Fixed a bug when generating `FnPtr` shims for `async Fn` trait goals.
r? oli-obk
Fix typo in `rustc_passes/messages.ftl`
Line 190 contains unpaired parentheses:
```
passes_doc_cfg_hide_takes_list =
`#[doc(cfg_hide(...)]` takes a list of attributes
```
The `#[doc(cfg_hide(...)]` contains unpaired parentheses. This PR changes it to `#[doc(cfg_hide(...))]`, which made the parentheses paired.
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
In the previous code, the success block of `lhs` would jump directly to the
success block of `rhs`. However, `rhs_success_block` could already contain
statements that are specific to the RHS, and the direct goto causes them to be
executed in the LHS success path as well.
This patch therefore creates a fresh block that the LHS and RHS success blocks
can both jump to.
And likewise with `ColorConfig::suggests_using_colors`. They both have a
single call site. And note that `BufWriter::supports_color()` always
returns false, which enables a small bit of constant folding along the
way.
In practice, 'a and 'b and 'c are always the same. This change makes
`UnusedExterns` more like `ArtifactNotification`, which uses a single
lifetime 'a in multiple ways.
I removed it in #121206 because I thought thought it wasn't necessary.
But then I had to add an `emit_stashed_diagnostics` call elsewhere in
rustfmt to avoid the assertion failure (which took two attempts to get
right, #121487 and #121615), and now there's an assertion failure in
clippy as well (https://github.com/rust-lang/rust-clippy/issues/12364).
So this commit just reinstates the call in `DiagCtxtInner::drop`. It
also reverts the rustfmt changes from #121487 and #121615, though it
keeps the tests added for those PRs.
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.
This commit:
- Moves the ICE file create/open outside the loop. (Redoing it on every
loop iteration works, but is really weird.)
- Moves the explanatory note emission above the loop, which removes the
need for the `enumerate` call.
- Introduces a `decorate` local.
This gives one extra error message on two tests, but is necessary to fix
bigger problems caused by the cancellation of stashed errors.
(Note: why not just avoid stashing altogether? Because that resulted in
additional output changes.)
This gives one extra error message on one test, but is necessary to fix
bigger problems caused by the cancellation of stashed errors.
(Note: why not just avoid stashing altogether? Because that resulted in
additional output changes.)
Opportunistically resolve regions when processing region outlives obligations
Due to the matching in `TypeOutlives` being structural, we should attempt to opportunistically resolve regions before processing region obligations. Thanks ``@lcnr`` for finding this.
r? lcnr
Use `LitKind::Err` for malformed floats
#121120 changed `StringReader::cook_lexer_literal` to return `LitKind::Err` for malformed integer literals. This commit does the same for float literals, for consistency.
r? ``@fmease``
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`
Process alias-relate obligations in CoerceUnsized loop
After #119106, we now emit `AliasRelate` goals when relating `?0` and `Alias<T, ..>` in the new solver. In the ad-hoc `CoerceUnsized` selection loop, we now may have `AliasRelate` goals which must be processed to constrain type variables which are mentioned in other goals.
---
For example, in the included test, we try to coerce `&<ManuallyDrop<T> as Deref>::Target` to `&dyn Foo`. This requires proving:
* 1 `&<ManuallyDrop<T> as Deref>::Target: CoerceUnsized<&dyn Foo>`
* 2 `<ManuallyDrop<T> as Deref>::Target alias-relate ?0`
* 3 `?0: Unsize<dyn Foo>`
* 4 `?0: Foo`
* 5 `?0: Sized`
If we don't process goal (2.) before processing goal (3.), then we hit ambiguity since `?0` is never constrained, and therefore we bail out, refusing to coerce the types. After processing (2.), we know `?0 := T`, and the rest of the goals can be processed normally.
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
Adjust printing for RPITITs
1. Call RPITITs `{synthetic#N}` instead of `{opaque#N}`.
2. Fall back to printing the RPITIT like an opaque even when printed as an `AliasTy`, just like we do for `ty::Alias`.
You could argue that (2.) is misleading, but I believe it's more consistent than naming `{synthetic#N}`, which I assume approximately nobody knows where that def path name comes from.
r? lcnr
Changing some attributes to only_local.
Modified according to https://github.com/rust-lang/compiler-team/issues/505.
By running test cases, I found that modifying the attribute's only_local tag sometimes causes some unintuitive error reports, so I tend to split it into multiple PRs and edit a small number of attributes each time to prevent too many changes at once. Prevent possible subsequent difficulties in locating problems.
r? ``@lcnr``
Remove the `UntranslatableDiagnosticTrivial` lint.
It's a specialized form of the `UntranslatableDiagnostic` lint that is deny-by-default.
Now that `UntranslatableDiagnostic` has been changed from allow-by-default to deny-by-default, the trivial variant is no longer needed.
r? ``@davidtwco``