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
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`
Add proper cfg to keep only one AlignmentEnum definition for different target_pointer_widths
Detected by #121752
Only one AlignmentEnum would be used with a specified target_pointer_width
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`
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`
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`
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
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 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``
[rustdoc] Prevent inclusion of whitespace character after macro_rules ident
Discovered this bug randomly when looking at:
![image](https://github.com/rust-lang/rust/assets/3050060/dca38047-9085-4377-bfac-f98890224be4)
We were too eagerly trying to merge tokens that shouldn't be merged together (for example if you have a code comment followed by a code comment, we merge them in one attribute to reduce the DOM size).
r? ``@notriddle``
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.
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
Fix link generation for foreign macro in jump to definition feature
The crate name is already added to the link so it shouldn't be added a second time for local foreign macros.
r? ``@notriddle``
unix_sigpipe: Simple fixes and improvements in tests
In https://github.com/rust-lang/rust/pull/120832 I included 5 preparatory commits.
It will take a while before discussions there and in https://github.com/rust-lang/rust/issues/62569 is settled, so here is a PR that splits out 4 of the commits that are easy to review, to get them out of the way.
r? ``@davidtwco`` who already approved these commits in https://github.com/rust-lang/rust/pull/120832 (but I have tweaked them a bit and rebased them since then).
For the convenience of my reviewer, here are the full commit messages of the commits:
<details>
<summary>Click to expand</summary>
```
commit 948b1d68ab (HEAD -> unix_sigpipe-tests-fixes, origin/unix_sigpipe-tests-fixes)
Author: Martin Nordholts <martin.nordholts@codetale.se>
Date: Fri Feb 9 07:57:27 2024 +0100
tests: Add unix_sigpipe-different-duplicates.rs test variant
To make sure that
#[unix_sigpipe = "x"]
#[unix_sigpipe = "y"]
behaves like
#[unix_sigpipe = "x"]
#[unix_sigpipe = "x"]
commit d14f15862d
Author: Martin Nordholts <martin.nordholts@codetale.se>
Date: Fri Feb 9 08:47:47 2024 +0100
tests: Combine unix_sigpipe-not-used.rs and unix_sigpipe-only-feature.rs
The only difference between the files is the presence/absence of
#![feature(unix_sigpipe)]
attribute. Avoid duplication by using revisions instead.
commit a1cb3dba84
Author: Martin Nordholts <martin.nordholts@codetale.se>
Date: Fri Feb 9 06:44:56 2024 +0100
tests: Rename unix_sigpipe.rs to unix_sigpipe-bare.rs for clarity
The test is for the "bare" variant of the attribute that looks like this:
#[unix_sigpipe]
which is not allowed, because it must look like this:
#[unix_sigpipe = "sig_ign"]
commit e060274e55
Author: Martin Nordholts <martin.nordholts@codetale.se>
Date: Fri Feb 9 05:48:24 2024 +0100
tests: Fix typo unix_sigpipe-error.rs -> unix_sigpipe-sig_ign.rs
There is no error expected. It's simply the "regular" test for sig_ign.
So rename it.
```
</details>
Tracking issue: https://github.com/rust-lang/rust/issues/97889
- Put every literal in its own braces, rather than just some of them,
for maximal error recovery.
- Add a blank line between every case, for readability.