Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8eeecb7

Browse files
authoredMar 14, 2025
Rollup merge of #138485 - BoxyUwU:rdg-push, r=jieyouxu
Rustc dev guide subtree update r? `@jieyouxu`
2 parents c42866f + 3d9bf08 commit 8eeecb7

File tree

10 files changed

+202
-105
lines changed

10 files changed

+202
-105
lines changed
 

‎src/doc/rustc-dev-guide/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ cargo +stable install josh-proxy --git https://github.com/josh-project/josh --ta
8282
Older versions of `josh-proxy` may not round trip commits losslessly so it is important to install this exact version.
8383

8484
### Pull changes from `rust-lang/rust` into this repository
85+
8586
1) Checkout a new branch that will be used to create a PR into `rust-lang/rustc-dev-guide`
8687
2) Run the pull command
8788
```
@@ -95,3 +96,15 @@ Older versions of `josh-proxy` may not round trip commits losslessly so it is im
9596
$ cargo run --manifest-path josh-sync/Cargo.toml rustc-push <branch-name> <gh-username>
9697
```
9798
2) Create a PR from `<branch-name>` into `rust-lang/rust`
99+
100+
#### Minimal git config
101+
102+
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.
103+
104+
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).
105+
106+
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.
107+
108+
```
109+
$ GIT_CONFIG_GLOBAL=/path/to/minimal/gitconfig GIT_CONFIG_SYSTEM='' cargo +stable run --manifest-path josh-sync/Cargo.toml -- rustc-pull
110+
```

‎src/doc/rustc-dev-guide/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4ecd70ddd1039a3954056c1071e40278048476fa
1+
8536f201ffdb2c24925d7f9e87996d7dca93428b

‎src/doc/rustc-dev-guide/src/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@
178178
- [Inference details](./opaque-types-impl-trait-inference.md)
179179
- [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md)
180180
- [Region inference restrictions][opaque-infer]
181-
- [Effect checking](./effects.md)
181+
- [Const condition checking](./effects.md)
182182
- [Pattern and Exhaustiveness Checking](./pat-exhaustive-checking.md)
183183
- [Unsafety Checking](./unsafety-checking.md)
184184
- [MIR dataflow](./mir/dataflow.md)

‎src/doc/rustc-dev-guide/src/backend/updating-llvm.md

+9-14
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ so let's go through each in detail.
116116
at the time of the branch,
117117
and the remaining part is the current date.
118118

119-
2. Apply Rust-specific patches to the llvm-project repository.
119+
1. Apply Rust-specific patches to the llvm-project repository.
120120
All features and bugfixes are upstream,
121121
but there's often some weird build-related patches
122122
that don't make sense to upstream.
123123
These patches are typically the latest patches in the
124124
rust-lang/llvm-project branch that rustc is currently using.
125125

126-
3. Build the new LLVM in the `rust` repository.
126+
1. Build the new LLVM in the `rust` repository.
127127
To do this,
128128
you'll want to update the `src/llvm-project` repository to your branch,
129129
and the revision you've created.
@@ -151,7 +151,7 @@ so let's go through each in detail.
151151
download-ci-llvm = false
152152
```
153153

154-
4. Test for regressions across other platforms. LLVM often has at least one bug
154+
1. Test for regressions across other platforms. LLVM often has at least one bug
155155
for non-tier-1 architectures, so it's good to do some more testing before
156156
sending this to bors! If you're low on resources you can send the PR as-is
157157
now to bors, though, and it'll get tested anyway.
@@ -170,22 +170,17 @@ so let's go through each in detail.
170170
* `./src/ci/docker/run.sh dist-various-2`
171171
* `./src/ci/docker/run.sh armhf-gnu`
172172

173-
5. Prepare a PR to `rust-lang/rust`. Work with maintainers of
173+
1. Prepare a PR to `rust-lang/rust`. Work with maintainers of
174174
`rust-lang/llvm-project` to get your commit in a branch of that repository,
175175
and then you can send a PR to `rust-lang/rust`. You'll change at least
176176
`src/llvm-project` and will likely also change [`llvm-wrapper`] as well.
177177

178-
<!-- date-check: Sep 2024 -->
178+
<!-- date-check: mar 2025 -->
179179
> For prior art, here are some previous LLVM updates:
180-
> - [LLVM 11](https://github.com/rust-lang/rust/pull/73526)
181-
> - [LLVM 12](https://github.com/rust-lang/rust/pull/81451)
182-
> - [LLVM 13](https://github.com/rust-lang/rust/pull/87570)
183-
> - [LLVM 14](https://github.com/rust-lang/rust/pull/93577)
184-
> - [LLVM 15](https://github.com/rust-lang/rust/pull/99464)
185-
> - [LLVM 16](https://github.com/rust-lang/rust/pull/109474)
186180
> - [LLVM 17](https://github.com/rust-lang/rust/pull/115959)
187181
> - [LLVM 18](https://github.com/rust-lang/rust/pull/120055)
188182
> - [LLVM 19](https://github.com/rust-lang/rust/pull/127513)
183+
> - [LLVM 20](https://github.com/rust-lang/rust/pull/135763)
189184
190185
Note that sometimes it's easiest to land [`llvm-wrapper`] compatibility as a PR
191186
before actually updating `src/llvm-project`.
@@ -194,17 +189,17 @@ so let's go through each in detail.
194189
others interested in trying out the new LLVM can benefit from work you've done
195190
to update the C++ bindings.
196191

197-
3. Over the next few months,
192+
1. Over the next few months,
198193
LLVM will continually push commits to its `release/a.b` branch.
199194
We will often want to have those bug fixes as well.
200195
The merge process for that is to use `git merge` itself to merge LLVM's
201196
`release/a.b` branch with the branch created in step 2.
202197
This is typically
203198
done multiple times when necessary while LLVM's release branch is baking.
204199

205-
4. LLVM then announces the release of version `a.b`.
200+
1. LLVM then announces the release of version `a.b`.
206201

207-
5. After LLVM's official release,
202+
1. After LLVM's official release,
208203
we follow the process of creating a new branch on the
209204
rust-lang/llvm-project repository again,
210205
this time with a new date.

‎src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need
129129

130130
```rs
131131
#[cfg(feature = "tracing")]
132-
use tracing::{instrument, trace};
132+
use tracing::instrument;
133133

134134
struct Foo;
135135

@@ -138,7 +138,6 @@ impl Step for Foo {
138138

139139
#[cfg_attr(feature = "tracing", instrument(level = "trace", name = "Foo::should_run", skip_all))]
140140
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
141-
#[cfg(feature = "tracing")]
142141
trace!(?run, "entered Foo::should_run");
143142

144143
todo!()
@@ -154,7 +153,6 @@ impl Step for Foo {
154153
),
155154
)]
156155
fn run(self, builder: &Builder<'_>) -> Self::Output {
157-
#[cfg(feature = "tracing")]
158156
trace!(?run, "entered Foo::run");
159157

160158
todo!()

‎src/doc/rustc-dev-guide/src/building/new-target.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ These are a set of steps to add support for a new target. There are
44
numerous end states and paths to get there, so not all sections may be
55
relevant to your desired goal.
66

7-
See also the associated documentation in the
8-
[target tier policy][target_tier_policy_add].
7+
See also the associated documentation in the [target tier policy].
98

109
<!-- toc -->
1110

12-
[target_tier_policy_add]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
11+
[target tier policy]: https://doc.rust-lang.org/rustc/target-tier-policy.html#adding-a-new-target
1312

1413
## Specifying a new LLVM
1514

+159-66
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,159 @@
1-
# Effects and effect checking
2-
3-
Note: all of this describes the implementation of the unstable `effects` and
4-
`const_trait_impl` features. None of this implementation is usable or visible from
5-
stable Rust.
6-
7-
The implementation of const traits and `~const` bounds is a limited effect system.
8-
It is used to allow trait bounds on `const fn` to be used within the `const fn` for
9-
method calls. Within the function, in order to know whether a method on a trait
10-
bound is `const`, we need to know whether there is a `~const` bound for the trait.
11-
In order to know whether we can instantiate a `~const` bound on a `const fn`, we
12-
need to know whether there is a `const_trait` impl for the type and trait being
13-
used (or whether the `const fn` is used at runtime, then any type implementing the
14-
trait is ok, just like with other bounds).
15-
16-
We perform these checks via a const generic boolean that gets attached to all
17-
`const fn` and `const trait`. The following sections will explain the desugarings
18-
and the way we perform the checks at call sites.
19-
20-
The const generic boolean is inverted to the meaning of `const`. In the compiler
21-
it is called `host`, because it enables "host APIs" like `static` items, network
22-
access, disk access, random numbers and everything else that isn't available in
23-
`const` contexts. So `false` means "const", `true` means "not const" and if it's
24-
a generic parameter, it means "maybe const" (meaning we're in a const fn or const
25-
trait).
26-
27-
## `const fn`
28-
29-
All `const fn` have a `#[rustc_host] const host: bool` generic parameter that is
30-
hidden from users. Any `~const Trait` bounds in the generics list or `where` bounds
31-
of a `const fn` get converted to `Trait<host> + Trait<true>` bounds. The `Trait<true>`
32-
exists so that associated types of the generic param can be used from projections
33-
like `<T as Trait>::Assoc`, because there are no `<T as ~const Trait>` projections for now.
34-
35-
## `#[const_trait] trait`s
36-
37-
The `#[const_trait]` attribute gives the marked trait a `#[rustc_host] const host: bool`
38-
generic parameter. All functions of the trait "inherit" this generic parameter, just like
39-
they have all the regular generic parameters of the trait. Any `~const Trait` super-trait
40-
bounds get desugared to `Trait<host> + Trait<true>` in order to allow using associated
41-
types and consts of the super traits in the trait declaration. This is necessary, because
42-
`<Self as SuperTrait>::Assoc` is always `<Self as SuperTrait<true>>::Assoc` as there is
43-
no `<Self as ~const SuperTrait>` syntax.
44-
45-
## `typeck` performing method and function call checks.
46-
47-
When generic parameters are instantiated for any items, the `host` generic parameter
48-
is always instantiated as an inference variable. This is a special kind of inference var
49-
that is not part of the type or const inference variables, similar to how we have
50-
special inference variables for type variables that we know to be an integer, but not
51-
yet which one. These separate inference variables fall back to `true` at
52-
the end of typeck (in `fallback_effects`) to ensure that `let _ = some_fn_item_name;`
53-
will keep compiling.
54-
55-
All actually used (in function calls, casts, or anywhere else) function items, will
56-
have the `enforce_context_effects` method invoked.
57-
It trivially returns if the function being called has no `host` generic parameter.
58-
59-
In order to error if a non-const function is called in a const context, we have not
60-
yet disabled the const-check logic that happens on MIR, because
61-
`enforce_context_effects` does not yet perform this check.
62-
63-
The function call's `host` parameter is then equated to the context's `host` value,
64-
which almost always trivially succeeds, as it was an inference var. If the inference
65-
var has already been bound (since the function item is invoked twice), the second
66-
invocation checks it against the first.
1+
# Effects and const condition checking
2+
3+
## The `HostEffect` predicate
4+
5+
[`HostEffectPredicate`]s are a kind of predicate from `~const Tr` or `const Tr`
6+
bounds. It has a trait reference, and a `constness` which could be `Maybe` or
7+
`Const` depending on the bound. Because `~const Tr`, or rather `Maybe` bounds
8+
apply differently based on whichever contexts they are in, they have different
9+
behavior than normal bounds. Where normal trait bounds on a function such as
10+
`T: Tr` are collected within the [`predicates_of`] query to be proven when a
11+
function is called and to be assumed within the function, bounds such as
12+
`T: ~const Tr` will behave as a normal trait bound and add `T: Tr` to the result
13+
from `predicates_of`, but also adds a `HostEffectPredicate` to the
14+
[`const_conditions`] query.
15+
16+
On the other hand, `T: const Tr` bounds do not change meaning across contexts,
17+
therefore they will result in `HostEffect(T: Tr, const)` being added to
18+
`predicates_of`, and not `const_conditions`.
19+
20+
[`HostEffectPredicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/predicate/struct.HostEffectPredicate.html
21+
[`predicates_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.predicates_of
22+
[`const_conditions`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_conditions
23+
24+
## The `const_conditions` query
25+
26+
`predicates_of` represents a set of predicates that need to be proven to use an
27+
item. For example, to use `foo` in the example below:
28+
29+
```rust
30+
fn foo<T>() where T: Default {}
31+
```
32+
33+
We must be able to prove that `T` implements `Default`. In a similar vein,
34+
`const_conditions` represents a set of predicates that need to be proven to use
35+
an item *in const contexts*. If we adjust the example above to use `const` trait
36+
bounds:
37+
38+
```rust
39+
const fn foo<T>() where T: ~const Default {}
40+
```
41+
42+
Then `foo` would get a `HostEffect(T: Default, maybe)` in the `const_conditions`
43+
query, suggesting that in order to call `foo` from const contexts, one must
44+
prove that `T` has a const implementation of `Default`.
45+
46+
## Enforcement of `const_conditions`
47+
48+
`const_conditions` are currently checked in various places.
49+
50+
Every call in HIR from a const context (which includes `const fn` and `const`
51+
items) will check that `const_conditions` of the function we are calling hold.
52+
This is done in [`FnCtxt::enforce_context_effects`]. Note that we don't check
53+
if the function is only referred to but not called, as the following code needs
54+
to compile:
55+
56+
```rust
57+
const fn hi<T: ~const Default>() -> T {
58+
T::default()
59+
}
60+
const X: fn() -> u32 = hi::<u32>;
61+
```
62+
63+
For a trait `impl` to be well-formed, we must be able to prove the
64+
`const_conditions` of the trait from the `impl`'s environment. This is checked
65+
in [`wfcheck::check_impl`].
66+
67+
Here's an example:
68+
69+
```rust
70+
#[const_trait]
71+
trait Bar {}
72+
#[const_trait]
73+
trait Foo: ~const Bar {}
74+
// `const_conditions` contains `HostEffect(Self: Bar, maybe)`
75+
76+
impl const Bar for () {}
77+
impl const Foo for () {}
78+
// ^ here we check `const_conditions` for the impl to be well-formed
79+
```
80+
81+
Methods of trait impls must not have stricter bounds than the method of the
82+
trait that they are implementing. To check that the methods are compatible, a
83+
hybrid environment is constructed with the predicates of the `impl` plus the
84+
predicates of the trait method, and we attempt to prove the predicates of the
85+
impl method. We do the same for `const_conditions`:
86+
87+
```rust
88+
#[const_trait]
89+
trait Foo {
90+
fn hi<T: ~const Default>();
91+
}
92+
93+
impl<T: ~const Clone> Foo for Vec<T> {
94+
fn hi<T: ~const PartialEq>();
95+
// ^ we can't prove `T: ~const PartialEq` given `T: ~const Clone` and
96+
// `T: ~const Default`, therefore we know that the method on the impl
97+
// is stricter than the method on the trait.
98+
}
99+
```
100+
101+
These checks are done in [`compare_method_predicate_entailment`]. A similar
102+
function that does the same check for associated types is called
103+
[`compare_type_predicate_entailment`]. Both of these need to consider
104+
`const_conditions` when in const contexts.
105+
106+
In MIR, as part of const checking, `const_conditions` of items that are called
107+
are revalidated again in [`Checker::revalidate_conditional_constness`].
108+
109+
[`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
110+
[`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
111+
[`FnCtxt::enforce_context_effects`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#method.enforce_context_effects
112+
[`wfcheck::check_impl`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/fn.check_impl.html
113+
[`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
114+
115+
## `explicit_implied_const_bounds` on associated types and traits
116+
117+
Bounds on associated types, opaque types, and supertraits such as
118+
```rust
119+
trait Foo: ~const PartialEq {
120+
type X: ~const PartialEq;
121+
}
122+
123+
fn foo() -> impl ~const PartialEq {
124+
// ^ unimplemented syntax
125+
}
126+
```
127+
128+
Have their bounds represented differently. Unlike `const_conditions` which need
129+
to be proved for callers, and can be assumed inside the definition (e.g. trait
130+
bounds on functions), these bounds need to be proved at definition (at the impl,
131+
or when returning the opaque) but can be assumed for callers. The non-const
132+
equivalent of these bounds are called [`explicit_item_bounds`].
133+
134+
These bounds are checked in [`compare_impl_item::check_type_bounds`] for HIR
135+
typeck, [`evaluate_host_effect_from_item_bounds`] in the old solver and
136+
[`consider_additional_alias_assumptions`] in the new solver.
137+
138+
[`explicit_item_bounds`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.explicit_item_bounds
139+
[`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
140+
[`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
141+
[`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
142+
143+
## Proving `HostEffectPredicate`s
144+
145+
`HostEffectPredicate`s are implemented both in the [old solver] and the [new
146+
trait solver]. In general, we can prove a `HostEffect` predicate when either of
147+
these conditions are met:
148+
149+
* The predicate can be assumed from caller bounds;
150+
* The type has a `const` `impl` for the trait, *and* that const conditions on
151+
the impl holds, *and* that the `explicit_implied_const_bounds` on the trait
152+
holds; or
153+
* The type has a built-in implementation for the trait in const contexts. For
154+
example, `Fn` may be implemented by function items if their const conditions
155+
are satisfied, or `Destruct` is implemented in const contexts if the type can
156+
be dropped at compile time.
157+
158+
[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html
159+
[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html

‎src/doc/rustc-dev-guide/src/solve/trait-solving.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
This chapter describes how trait solving works with the new WIP solver located in
44
[`rustc_trait_selection/solve`][solve]. Feel free to also look at the docs for
5-
[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md)
6-
can be found separately.
5+
[the current solver](../traits/resolution.md) and [the chalk solver](../traits/chalk.md).
76

87
## Core concepts
98

There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.