Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2025-03-16 05:12:15 +00:00
commit f8c6f8a2bf
10 changed files with 189 additions and 92 deletions

View File

@ -82,6 +82,7 @@ cargo +stable install josh-proxy --git https://github.com/josh-project/josh --ta
Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version.
### Pull changes from `rust-lang/rust` into this repository
1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide`
2) Run the pull command
```
@ -95,3 +96,15 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im
$ cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username>
```
2) Create a PR from `<branch-name>` into `rust-lang/rust`
#### Minimal git config
For simplicity (ease of implementation purposes), the josh-sync script simply calls out to system git. This means that the git invocation may be influenced by global (or local) git configuration.
You may observe "Nothing to pull" even if you *know* rustc-pull has something to pull if your global git config sets `fetch.prunetags = true` (and possibly other configurations may cause unexpected outcomes).
To minimize the likelihood of this happening, you may wish to keep a separate *minimal* git config that *only* has `[user]` entries from global git config, then repoint system git to use the minimal git config instead. E.g.
```
$ GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull
```

View File

@ -1 +1 @@
4ecd70ddd1039a3954056c1071e40278048476fa
8536f201ffdb2c24925d7f9e87996d7dca93428b

View File

@ -178,7 +178,7 @@
- [Inference details](./opaque-types-impl-trait-inference.md)
- [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md)
- [Region inference restrictions][opaque-infer]
- [Effect checking](./effects.md)
- [Const condition checking](./effects.md)
- [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md)
- [Unsafety Checking](./unsafety-checking.md)
- [MIR dataflow](./mir/dataflow.md)

View File

@ -116,14 +116,14 @@ so let's go through each in detail.
at the time of the branch,
and the remaining part is the current date.
2. Apply Rust-specific patches to the llvm-project repository.
1. Apply Rust-specific patches to the llvm-project repository.
All features and bugfixes are upstream,
but there's often some weird build-related patches
that don't make sense to upstream.
These patches are typically the latest patches in the
rust-lang/llvm-project branch that rustc is currently using.
3. Build the new LLVM in the `rust` repository.
1. Build the new LLVM in the `rust` repository.
To do this,
you'll want to update the `src/llvm-project` repository to your branch,
and the revision you've created.
@ -151,7 +151,7 @@ so let's go through each in detail.
download-ci-llvm = false
```
4. Test for regressions across other platforms. LLVM often has at least one bug
1. Test for regressions across other platforms. LLVM often has at least one bug
for non-tier-1 architectures, so it's good to do some more testing before
sending this to bors! If you're low on resources you can send the PR as-is
now to bors, though, and it'll get tested anyway.
@ -170,22 +170,17 @@ so let's go through each in detail.
* `./src/ci/docker/run.sh dist-various-2`
* `./src/ci/docker/run.sh armhf-gnu`
5. Prepare a PR to `rust-lang/rust`. Work with maintainers of
1. Prepare a PR to `rust-lang/rust`. Work with maintainers of
`rust-lang/llvm-project` to get your commit in a branch of that repository,
and then you can send a PR to `rust-lang/rust`. You'll change at least
`src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
<!-- date-check: Sep 2024 -->
<!-- date-check: mar 2025 -->
> For prior art, here are some previous LLVM updates:
> - [LLVM 11](https://github.com/rust-lang/rust/pull/73526)
> - [LLVM 12](https://github.com/rust-lang/rust/pull/81451)
> - [LLVM 13](https://github.com/rust-lang/rust/pull/87570)
> - [LLVM 14](https://github.com/rust-lang/rust/pull/93577)
> - [LLVM 15](https://github.com/rust-lang/rust/pull/99464)
> - [LLVM 16](https://github.com/rust-lang/rust/pull/109474)
> - [LLVM 17](https://github.com/rust-lang/rust/pull/115959)
> - [LLVM 18](https://github.com/rust-lang/rust/pull/120055)
> - [LLVM 19](https://github.com/rust-lang/rust/pull/127513)
> - [LLVM 20](https://github.com/rust-lang/rust/pull/135763)
Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR
before actually updating `src/llvm-project`.
@ -194,7 +189,7 @@ so let's go through each in detail.
others interested in trying out the new LLVM can benefit from work you've done
to update the C++ bindings.
3. Over the next few months,
1. Over the next few months,
LLVM will continually push commits to its `release/a.b` branch.
We will often want to have those bug fixes as well.
The merge process for that is to use `git merge` itself to merge LLVM's
@ -202,9 +197,9 @@ so let's go through each in detail.
This is typically
done multiple times when necessary while LLVM's release branch is baking.
4. LLVM then announces the release of version `a.b`.
1. LLVM then announces the release of version `a.b`.
5. After LLVM's official release,
1. After LLVM's official release,
we follow the process of creating a new branch on the
rust-lang/llvm-project repository again,
this time with a new date.

View File

@ -129,7 +129,7 @@ Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need
```rs
#[cfg(feature = "tracing")]
use tracing::{instrument, trace};
use tracing::instrument;
struct Foo;
@ -138,7 +138,6 @@ impl Step for Foo {
#[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Foo::should_run", skip_all))]
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
#[cfg(feature = "tracing")]
trace!(?run, "entered Foo::should_run");
todo!()
@ -154,7 +153,6 @@ impl Step for Foo {
),
)]
fn run(self, builder: &Builder<'_>) -> Self::Output {
#[cfg(feature = "tracing")]
trace!(?run, "entered Foo::run");
todo!()

View File

@ -4,12 +4,11 @@ These are a set of steps to add support for a new target. There are
numerous end states and paths to get there, so not all sections may be
relevant to your desired goal.
See also the associated documentation in the
[target tier policy][target_tier_policy_add].
See also the associated documentation in the [target tier policy].
<!-- toc -->
[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
[target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
## Specifying a new LLVM

View File

@ -1,66 +1,159 @@
# Effects and effect checking
# Effects and const condition checking
Note: all of this describes the implementation of the unstable `effects` and
`const_trait_impl` features. None of this implementation is usable or visible from
stable Rust.
## The `HostEffect` predicate
The implementation of const traits and `~const` bounds is a limited effect system.
It is used to allow trait bounds on `const fn` to be used within the `const fn` for
method calls. Within the function, in order to know whether a method on a trait
bound is `const`, we need to know whether there is a `~const` bound for the trait.
In order to know whether we can instantiate a `~const` bound on a `const fn`, we
need to know whether there is a `const_trait` impl for the type and trait being
used (or whether the `const fn` is used at runtime, then any type implementing the
trait is ok, just like with other bounds).
[`HostEffectPredicate`]s are a kind of predicate from `~const Tr` or `const Tr`
bounds. It has a trait reference, and a `constness` which could be `Maybe` or
`Const` depending on the bound. Because `~const Tr`, or rather `Maybe` bounds
apply differently based on whichever contexts they are in, they have different
behavior than normal bounds. Where normal trait bounds on a function such as
`T: Tr` are collected within the [`predicates_of`] query to be proven when a
function is called and to be assumed within the function, bounds such as
`T: ~const Tr` will behave as a normal trait bound and add `T: Tr` to the result
from `predicates_of`, but also adds a `HostEffectPredicate` to the
[`const_conditions`] query.
We perform these checks via a const generic boolean that gets attached to all
`const fn` and `const trait`. The following sections will explain the desugarings
and the way we perform the checks at call sites.
On the other hand, `T: const Tr` bounds do not change meaning across contexts,
therefore they will result in `HostEffect(T: Tr, const)` being added to
`predicates_of`, and not `const_conditions`.
The const generic boolean is inverted to the meaning of `const`. In the compiler
it is called `host`, because it enables "host APIs" like `static` items, network
access, disk access, random numbers and everything else that isn't available in
`const` contexts. So `false` means "const", `true` means "not const" and if it's
a generic parameter, it means "maybe const" (meaning we're in a const fn or const
trait).
[`HostEffectPredicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/predicate/struct.HostEffectPredicate.html
[`predicates_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.predicates_of
[`const_conditions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_conditions
## `const fn`
## The `const_conditions` query
All `const fn` have a `#[rustc_host] const host: bool` generic parameter that is
hidden from users. Any `~const Trait` bounds in the generics list or `where` bounds
of a `const fn` get converted to `Trait<host> + Trait<true>` bounds. The `Trait<true>`
exists so that associated types of the generic param can be used from projections
like `<T as Trait>::Assoc`, because there are no `<T as ~const Trait>` projections for now.
`predicates_of` represents a set of predicates that need to be proven to use an
item. For example, to use `foo` in the example below:
## `#[const_trait] trait`s
```rust
fn foo<T>() where T: Default {}
```
The `#[const_trait]` attribute gives the marked trait a `#[rustc_host] const host: bool`
generic parameter. All functions of the trait "inherit" this generic parameter, just like
they have all the regular generic parameters of the trait. Any `~const Trait` super-trait
bounds get desugared to `Trait<host> + Trait<true>` in order to allow using associated
types and consts of the super traits in the trait declaration. This is necessary, because
`<Self as SuperTrait>::Assoc` is always `<Self as SuperTrait<true>>::Assoc` as there is
no `<Self as ~const SuperTrait>` syntax.
We must be able to prove that `T` implements `Default`. In a similar vein,
`const_conditions` represents a set of predicates that need to be proven to use
an item *in const contexts*. If we adjust the example above to use `const` trait
bounds:
## `typeck` performing method and function call checks.
```rust
const fn foo<T>() where T: ~const Default {}
```
When generic parameters are instantiated for any items, the `host` generic parameter
is always instantiated as an inference variable. This is a special kind of inference var
that is not part of the type or const inference variables, similar to how we have
special inference variables for type variables that we know to be an integer, but not
yet which one. These separate inference variables fall back to `true` at
the end of typeck (in `fallback_effects`) to ensure that `let _ = some_fn_item_name;`
will keep compiling.
Then `foo` would get a `HostEffect(T: Default, maybe)` in the `const_conditions`
query, suggesting that in order to call `foo` from const contexts, one must
prove that `T` has a const implementation of `Default`.
All actually used (in function calls, casts, or anywhere else) function items, will
have the `enforce_context_effects` method invoked.
It trivially returns if the function being called has no `host` generic parameter.
## Enforcement of `const_conditions`
In order to error if a non-const function is called in a const context, we have not
yet disabled the const-check logic that happens on MIR, because
`enforce_context_effects` does not yet perform this check.
`const_conditions` are currently checked in various places.
The function call's `host` parameter is then equated to the context's `host` value,
which almost always trivially succeeds, as it was an inference var. If the inference
var has already been bound (since the function item is invoked twice), the second
invocation checks it against the first.
Every call in HIR from a const context (which includes `const fn` and `const`
items) will check that `const_conditions` of the function we are calling hold.
This is done in [`FnCtxt::enforce_context_effects`]. Note that we don't check
if the function is only referred to but not called, as the following code needs
to compile:
```rust
const fn hi<T: ~const Default>() -> T {
T::default()
}
const X: fn() -> u32 = hi::<u32>;
```
For a trait `impl` to be well-formed, we must be able to prove the
`const_conditions` of the trait from the `impl`'s environment. This is checked
in [`wfcheck::check_impl`].
Here's an example:
```rust
#[const_trait]
trait Bar {}
#[const_trait]
trait Foo: ~const Bar {}
// `const_conditions` contains `HostEffect(Self: Bar, maybe)`
impl const Bar for () {}
impl const Foo for () {}
// ^ here we check `const_conditions` for the impl to be well-formed
```
Methods of trait impls must not have stricter bounds than the method of the
trait that they are implementing. To check that the methods are compatible, a
hybrid environment is constructed with the predicates of the `impl` plus the
predicates of the trait method, and we attempt to prove the predicates of the
impl method. We do the same for `const_conditions`:
```rust
#[const_trait]
trait Foo {
fn hi<T: ~const Default>();
}
impl<T: ~const Clone> Foo for Vec<T> {
fn hi<T: ~const PartialEq>();
// ^ we can't prove `T: ~const PartialEq` given `T: ~const Clone` and
// `T: ~const Default`, therefore we know that the method on the impl
// is stricter than the method on the trait.
}
```
These checks are done in [`compare_method_predicate_entailment`]. A similar
function that does the same check for associated types is called
[`compare_type_predicate_entailment`]. Both of these need to consider
`const_conditions` when in const contexts.
In MIR, as part of const checking, `const_conditions` of items that are called
are revalidated again in [`Checker::revalidate_conditional_constness`].
[`compare_method_predicate_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
[`compare_type_predicate_entailment`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_type_predicate_entailment.html
[`FnCtxt::enforce_context_effects`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.enforce_context_effects
[`wfcheck::check_impl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/fn.check_impl.html
[`Checker::revalidate_conditional_constness`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_const_eval/check_consts/check/struct.Checker.html#method.revalidate_conditional_constness
## `explicit_implied_const_bounds` on associated types and traits
Bounds on associated types, opaque types, and supertraits such as
```rust
trait Foo: ~const PartialEq {
type X: ~const PartialEq;
}
fn foo() -> impl ~const PartialEq {
// ^ unimplemented syntax
}
```
Have their bounds represented differently. Unlike `const_conditions` which need
to be proved for callers, and can be assumed inside the definition (e.g. trait
bounds on functions), these bounds need to be proved at definition (at the impl,
or when returning the opaque) but can be assumed for callers. The non-const
equivalent of these bounds are called [`explicit_item_bounds`].
These bounds are checked in [`compare_impl_item::check_type_bounds`] for HIR
typeck, [`evaluate_host_effect_from_item_bounds`] in the old solver and
[`consider_additional_alias_assumptions`] in the new solver.
[`explicit_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.explicit_item_bounds
[`compare_impl_item::check_type_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.check_type_bounds.html
[`evaluate_host_effect_from_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/effects/fn.evaluate_host_effect_from_item_bounds.html
[`consider_additional_alias_assumptions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_next_trait_solver/solve/assembly/trait.GoalKind.html#tymethod.consider_additional_alias_assumptions
## Proving `HostEffectPredicate`s
`HostEffectPredicate`s are implemented both in the [old solver] and the [new
trait solver]. In general, we can prove a `HostEffect` predicate when either of
these conditions are met:
* The predicate can be assumed from caller bounds;
* The type has a `const` `impl` for the trait, *and* that const conditions on
the impl holds, *and* that the `explicit_implied_const_bounds` on the trait
holds; or
* The type has a built-in implementation for the trait in const contexts. For
example, `Fn` may be implemented by function items if their const conditions
are satisfied, or `Destruct` is implemented in const contexts if the type can
be dropped at compile time.
[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html
[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html

View File

@ -2,8 +2,7 @@
This chapter describes how trait solving works with the new WIP solver located in
[`rustc_trait_selection/solve`][solve]. Feel free to also look at the docs for
[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md)
can be found separately.
[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md).
## Core concepts

View File

@ -119,8 +119,7 @@ for more details.
These directives are used to ignore the test in some situations, which
means the test won't be compiled or run.
* `ignore-X` where `X` is a target detail or stage will ignore the test
accordingly (see below)
* `ignore-X` where `X` is a target detail or other criteria on which to ignore the test (see below)
* `only-X` is like `ignore-X`, but will *only* run the test on that target or
stage
* `ignore-test` always ignores the test. This can be used to temporarily disable
@ -139,8 +138,8 @@ Some examples of `X` in `ignore-X` or `only-X`:
matches that target as well as the emscripten targets.
- Pointer width: `32bit`, `64bit`
- Endianness: `endian-big`
- Stage: `stage1`, `stage2`
- Binary format: `elf`
- Stage: `stage0`, `stage1`, `stage2`
- Channel: `stable`, `beta`
- When cross compiling: `cross-compile`
- When [remote testing] is used: `remote`
@ -196,7 +195,6 @@ settings:
The following directives will check LLVM support:
- `no-system-llvm` — ignores if the system llvm is used
- `exact-llvm-major-version: 19` — ignores if the llvm major version does not
match the specified llvm major version.
- `min-llvm-version: 13.0` — ignored if the LLVM version is less than the given

View File

@ -24,8 +24,8 @@ collection.
The test results are cached and previously successful tests are `ignored` during
testing. The stdout/stderr contents as well as a timestamp file for every test
can be found under `build/<target-triple>/test/` for the given
`<target-triple>`. To force-rerun a test (e.g. in case the test runner fails to
can be found under `build/<target-tuple>/test/` for the given
`<target-tuple>`. To force-rerun a test (e.g. in case the test runner fails to
notice a change) you can use the `--force-rerun` CLI option.
> **Note on requirements of external dependencies**
@ -49,7 +49,7 @@ test suite ([`tests/ui`]):
./x test tests/ui
```
This will run the `ui` test suite. Of course, the choice of test suites is
Of course, the choice of test suites is
somewhat arbitrary, and may not suit the task you are doing. For example, if you
are hacking on debuginfo, you may be better off with the debuginfo test suite:
@ -112,8 +112,8 @@ crates, you have to specify those explicitly.
./x test --stage 1 library/std
```
By listing which test suites you want to run you avoid having to run tests for
components you did not change at all.
By listing which test suites you want to run,
you avoid having to run tests for components you did not change at all.
<div class="warning">
Note that bors only runs the tests with the full stage 2 build; therefore, while
@ -172,16 +172,18 @@ additional arguments to the compiler when building the tests.
## Editing and updating the reference files
If you have changed the compiler's output intentionally, or you are making a new
test, you can pass `--bless` to the test subcommand. E.g. if some tests in
`tests/ui` are failing, you can run
test, you can pass `--bless` to the test subcommand.
As an example,
if some tests in `tests/ui` are failing, you can run this command:
```text
./x test tests/ui --bless
```
to automatically adjust the `.stderr`, `.stdout` or `.fixed` files of
all tests. Of course you can also target just specific tests with the
`--test-args your_test_name` flag, just like when running the tests.
It automatically adjusts the `.stderr`, `.stdout`, or `.fixed` files of all `test/ui` tests.
Of course you can also target just specific tests with the `--test-args your_test_name` flag,
just like when running the tests without the `--bless` flag.
## Configuring test running
@ -190,7 +192,7 @@ There are a few options for running tests:
* `config.toml` has the `rust.verbose-tests` option. If `false`, each test will
print a single dot (the default). If `true`, the name of every test will be
printed. This is equivalent to the `--quiet` option in the [Rust test
harness](https://doc.rust-lang.org/rustc/tests/)
harness](https://doc.rust-lang.org/rustc/tests/).
* The environment variable `RUST_TEST_THREADS` can be set to the number of
concurrent threads to use for testing.