Skip to content

Commit 0b20963

Browse files
committed
Auto merge of #142070 - matthiaskrgr:rollup-e7lxtuo, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #140638 (UnsafePinned: also include the effects of UnsafeCell) - #141777 (Do not run PGO/BOLT in x64 Linux alt builds) - #141938 (update rust offload bootstrap) - #141962 (rustc-dev-guide subtree update) - #141965 (`tests/ui`: A New Order [3/N]) - #141970 (implement new `x` flag: `--skip-std-check-if-no-download-rustc`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c360e21 + cfe78d9 commit 0b20963

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+560
-204
lines changed

library/core/src/pin/unsafe_pinned.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use crate::cell::UnsafeCell;
12
use crate::marker::{PointerLike, Unpin};
23
use crate::ops::{CoerceUnsized, DispatchFromDyn};
34
use crate::pin::Pin;
45
use crate::{fmt, ptr};
56

6-
/// This type provides a way to opt-out of typical aliasing rules;
7+
/// This type provides a way to entirely opt-out of typical aliasing rules;
78
/// specifically, `&mut UnsafePinned<T>` is not guaranteed to be a unique pointer.
9+
/// This also subsumes the effects of `UnsafeCell`, i.e., `&UnsafePinned<T>` may point to data
10+
/// that is being mutated.
811
///
912
/// However, even if you define your type like `pub struct Wrapper(UnsafePinned<...>)`, it is still
1013
/// very risky to have an `&mut Wrapper` that aliases anything else. Many functions that work
@@ -17,38 +20,24 @@ use crate::{fmt, ptr};
1720
/// the public API of a library. It is an internal implementation detail of libraries that need to
1821
/// support aliasing mutable references.
1922
///
20-
/// Further note that this does *not* lift the requirement that shared references must be read-only!
21-
/// Use `UnsafeCell` for that.
22-
///
2323
/// This type blocks niches the same way `UnsafeCell` does.
2424
#[lang = "unsafe_pinned"]
2525
#[repr(transparent)]
2626
#[unstable(feature = "unsafe_pinned", issue = "125735")]
2727
pub struct UnsafePinned<T: ?Sized> {
28-
value: T,
28+
value: UnsafeCell<T>,
2929
}
3030

31+
// Override the manual `!Sync` in `UnsafeCell`.
32+
#[unstable(feature = "unsafe_pinned", issue = "125735")]
33+
unsafe impl<T: ?Sized + Sync> Sync for UnsafePinned<T> {}
34+
3135
/// When this type is used, that almost certainly means safe APIs need to use pinning to avoid the
3236
/// aliases from becoming invalidated. Therefore let's mark this as `!Unpin`. You can always opt
3337
/// back in to `Unpin` with an `impl` block, provided your API is still sound while unpinned.
3438
#[unstable(feature = "unsafe_pinned", issue = "125735")]
3539
impl<T: ?Sized> !Unpin for UnsafePinned<T> {}
3640

37-
/// The type is `Copy` when `T` is to avoid people assuming that `Copy` implies there is no
38-
/// `UnsafePinned` anywhere. (This is an issue with `UnsafeCell`: people use `Copy` bounds to mean
39-
/// `Freeze`.) Given that there is no `unsafe impl Copy for ...`, this is also the option that
40-
/// leaves the user more choices (as they can always wrap this in a `!Copy` type).
41-
// FIXME(unsafe_pinned): this may be unsound or a footgun?
42-
#[unstable(feature = "unsafe_pinned", issue = "125735")]
43-
impl<T: Copy> Copy for UnsafePinned<T> {}
44-
45-
#[unstable(feature = "unsafe_pinned", issue = "125735")]
46-
impl<T: Copy> Clone for UnsafePinned<T> {
47-
fn clone(&self) -> Self {
48-
*self
49-
}
50-
}
51-
5241
// `Send` and `Sync` are inherited from `T`. This is similar to `SyncUnsafeCell`, since
5342
// we eventually concluded that `UnsafeCell` implicitly making things `!Sync` is sometimes
5443
// unergonomic. A type that needs to be `!Send`/`!Sync` should really have an explicit
@@ -63,7 +52,7 @@ impl<T> UnsafePinned<T> {
6352
#[must_use]
6453
#[unstable(feature = "unsafe_pinned", issue = "125735")]
6554
pub const fn new(value: T) -> Self {
66-
UnsafePinned { value }
55+
UnsafePinned { value: UnsafeCell::new(value) }
6756
}
6857

6958
/// Unwraps the value, consuming this `UnsafePinned`.
@@ -72,7 +61,7 @@ impl<T> UnsafePinned<T> {
7261
#[unstable(feature = "unsafe_pinned", issue = "125735")]
7362
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
7463
pub const fn into_inner(self) -> T {
75-
self.value
64+
self.value.into_inner()
7665
}
7766
}
7867

src/bootstrap/src/core/build_steps/check.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ impl Step for Std {
7777
}
7878

7979
fn run(self, builder: &Builder<'_>) {
80+
if !builder.download_rustc() && builder.config.skip_std_check_if_no_download_rustc {
81+
eprintln!(
82+
"WARNING: `--skip-std-check-if-no-download-rustc` flag was passed and `rust.download-rustc` is not available. Skipping."
83+
);
84+
return;
85+
}
86+
8087
builder.require_submodule("library/stdarch", None);
8188

8289
let stage = self.custom_stage.unwrap_or(builder.top_stage);

src/bootstrap/src/core/build_steps/llvm.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -443,23 +443,26 @@ impl Step for Llvm {
443443
// See https://github.com/rust-lang/rust/pull/50104
444444
cfg.define("LLVM_ENABLE_LIBXML2", "OFF");
445445

446-
if !enabled_llvm_projects.is_empty() {
447-
enabled_llvm_projects.sort();
448-
enabled_llvm_projects.dedup();
449-
cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";"));
450-
}
451-
452446
let mut enabled_llvm_runtimes = Vec::new();
453447

454448
if helpers::forcing_clang_based_tests() {
455449
enabled_llvm_runtimes.push("compiler-rt");
456450
}
457451

452+
// This is an experimental flag, which likely builds more than necessary.
453+
// We will optimize it when we get closer to releasing it on nightly.
458454
if builder.config.llvm_offload {
459455
enabled_llvm_runtimes.push("offload");
460456
//FIXME(ZuseZ4): LLVM intends to drop the offload dependency on openmp.
461457
//Remove this line once they achieved it.
462458
enabled_llvm_runtimes.push("openmp");
459+
enabled_llvm_projects.push("compiler-rt");
460+
}
461+
462+
if !enabled_llvm_projects.is_empty() {
463+
enabled_llvm_projects.sort();
464+
enabled_llvm_projects.dedup();
465+
cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";"));
463466
}
464467

465468
if !enabled_llvm_runtimes.is_empty() {

src/bootstrap/src/core/config/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ pub struct Config {
423423

424424
/// Cache for determining path modifications
425425
pub path_modification_cache: Arc<Mutex<HashMap<Vec<&'static str>, PathFreshness>>>,
426+
427+
/// Skip checking the standard library if `rust.download-rustc` isn't available.
428+
/// This is mostly for RA as building the stage1 compiler to check the library tree
429+
/// on each code change might be too much for some computers.
430+
pub skip_std_check_if_no_download_rustc: bool,
426431
}
427432

428433
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
@@ -1507,6 +1512,7 @@ impl Config {
15071512
config.enable_bolt_settings = flags.enable_bolt_settings;
15081513
config.bypass_bootstrap_lock = flags.bypass_bootstrap_lock;
15091514
config.is_running_on_ci = flags.ci.unwrap_or(CiEnv::is_ci());
1515+
config.skip_std_check_if_no_download_rustc = flags.skip_std_check_if_no_download_rustc;
15101516

15111517
// Infer the rest of the configuration.
15121518

src/bootstrap/src/core/config/flags.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ pub struct Flags {
182182
/// Make bootstrap to behave as it's running on the CI environment or not.
183183
#[arg(global = true, long, value_name = "bool")]
184184
pub ci: Option<bool>,
185+
/// Skip checking the standard library if `rust.download-rustc` isn't available.
186+
/// This is mostly for RA as building the stage1 compiler to check the library tree
187+
/// on each code change might be too much for some computers.
188+
#[arg(global = true, long)]
189+
pub skip_std_check_if_no_download_rustc: bool,
185190
}
186191

187192
impl Flags {

src/bootstrap/src/utils/change_tracker.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,4 +416,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
416416
severity: ChangeSeverity::Warning,
417417
summary: "Stage0 library no longer matches the in-tree library, which means stage1 compiler now uses the beta library.",
418418
},
419+
ChangeInfo {
420+
change_id: 141970,
421+
severity: ChangeSeverity::Info,
422+
summary: "Added new bootstrap flag `--skip-std-check-if-no-download-rustc` that skips std checks when download-rustc is unavailable. Mainly intended for developers to reduce RA overhead.",
423+
},
419424
];

src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,13 @@ ENV RUST_CONFIGURE_ARGS \
9696
--set rust.lto=thin \
9797
--set rust.codegen-units=1
9898

99-
# Note that `rust.debug` is set to true *only* for `opt-dist`
100-
ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
101-
./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
102-
--host $HOSTS --target $HOSTS \
103-
--include-default-paths \
104-
build-manifest bootstrap && \
105-
# Use GCC for building GCC, as it seems to behave badly when built with Clang
106-
CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc
99+
ARG SCRIPT_ARG
100+
101+
COPY host-x86_64/dist-x86_64-linux/dist.sh /scripts/
102+
COPY host-x86_64/dist-x86_64-linux/dist-alt.sh /scripts/
103+
104+
ENV SCRIPT /scripts/${SCRIPT_ARG}
105+
107106
ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
108107

109108
# This is the only builder which will create source tarballs
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
set -eux
4+
5+
python3 ../x.py dist \
6+
--host $HOSTS --target $HOSTS \
7+
--include-default-paths \
8+
build-manifest bootstrap
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
set -eux
4+
5+
python3 ../x.py build --set rust.debug=true opt-dist
6+
7+
./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
8+
--host $HOSTS --target $HOSTS \
9+
--include-default-paths \
10+
build-manifest bootstrap
11+
12+
# Use GCC for building GCC, as it seems to behave badly when built with Clang
13+
CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ python3 ../x.py dist gcc

src/ci/github-actions/jobs.yml

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ runners:
1010
free_disk: true
1111
<<: *base-job
1212

13+
- &job-linux-4c-largedisk
14+
os: ubuntu-24.04-4core-16gb
15+
<<: *base-job
16+
1317
- &job-linux-8c
1418
os: ubuntu-24.04-8core-32gb
1519
<<: *base-job
@@ -105,6 +109,15 @@ envs:
105109
pr:
106110
PR_CI_JOB: 1
107111

112+
jobs:
113+
dist-x86_64-linux: &job-dist-x86_64-linux
114+
name: dist-x86_64-linux
115+
env:
116+
CODEGEN_BACKENDS: llvm,cranelift
117+
DOCKER_SCRIPT: dist.sh
118+
<<: *job-linux-36c-codebuild
119+
120+
108121
# Jobs that run on each push to a pull request (PR)
109122
# These jobs automatically inherit envs.pr, to avoid repeating
110123
# it in each job definition.
@@ -138,10 +151,7 @@ pr:
138151
# These jobs automatically inherit envs.try, to avoid repeating
139152
# it in each job definition.
140153
try:
141-
- name: dist-x86_64-linux
142-
env:
143-
CODEGEN_BACKENDS: llvm,cranelift
144-
<<: *job-linux-36c-codebuild
154+
- <<: *job-dist-x86_64-linux
145155

146156
# Main CI jobs that have to be green to merge a commit into master
147157
# These jobs automatically inherit envs.auto, to avoid repeating
@@ -234,16 +244,14 @@ auto:
234244
- name: dist-x86_64-illumos
235245
<<: *job-linux-4c
236246

237-
- name: dist-x86_64-linux
238-
env:
239-
CODEGEN_BACKENDS: llvm,cranelift
240-
<<: *job-linux-36c-codebuild
247+
- <<: *job-dist-x86_64-linux
241248

242249
- name: dist-x86_64-linux-alt
243250
env:
244251
IMAGE: dist-x86_64-linux
245252
CODEGEN_BACKENDS: llvm,cranelift
246-
<<: *job-linux-16c
253+
DOCKER_SCRIPT: dist-alt.sh
254+
<<: *job-linux-4c-largedisk
247255

248256
- name: dist-x86_64-musl
249257
env:

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
99e7c15e81385b38a8186b51edc4577d5d7b5bdd
1+
c68032fd4c442d275f4daa571ba19c076106b490

src/doc/rustc-dev-guide/src/autodiff/flags.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ LooseTypes // Risk incorrect derivatives instead of aborting when missing Type I
1616
```
1717

1818
<div class="warning">
19+
1920
`LooseTypes` is often helpful to get rid of Enzyme errors stating `Can not deduce type of <X>` and to be able to run some code. But please keep in mind that this flag absolutely has the chance to cause incorrect gradients. Even worse, the gradients might be correct for certain input values, but not for others. So please create issues about such bugs and only use this flag temporarily while you wait for your bug to be fixed.
21+
2022
</div>
2123

2224
### Benchmark flags

src/doc/rustc-dev-guide/src/building/suggested.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ always overrides the inner ones.
5959

6060
## Configuring `rust-analyzer` for `rustc`
6161

62+
### Checking the "library" tree
63+
64+
Checking the "library" tree requires a stage1 compiler, which can be a heavy process on some computers.
65+
For this reason, bootstrap has a flag called `--skip-std-check-if-no-download-rustc` that skips checking the
66+
"library" tree if `rust.download-rustc` isn't available. If you want to avoid putting a heavy load on your computer
67+
with `rust-analyzer`, you can add the `--skip-std-check-if-no-download-rustc` flag to your `./x check` command in
68+
the `rust-analyzer` configuration.
69+
6270
### Project-local rust-analyzer setup
6371

6472
`rust-analyzer` can help you check and format your code whenever you save a

src/doc/rustc-dev-guide/src/coroutine-closures.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1+
# Async closures/"coroutine-closures"
2+
3+
<!-- toc -->
4+
15
Please read [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) to understand the general motivation of the feature. This is a very technical and somewhat "vertical" chapter; ideally we'd split this and sprinkle it across all the relevant chapters, but for the purposes of understanding async closures *holistically*, I've put this together all here in one chapter.
26

3-
# Coroutine-closures -- a technical deep dive
7+
## Coroutine-closures -- a technical deep dive
48

59
Coroutine-closures are a generalization of async closures, being special syntax for closure expressions which return a coroutine, notably one that is allowed to capture from the closure's upvars.
610

711
For now, the only usable kind of coroutine-closure is the async closure, and supporting async closures is the extent of this PR. We may eventually support `gen || {}`, etc., and most of the problems and curiosities described in this document apply to all coroutine-closures in general.
812

913
As a consequence of the code being somewhat general, this document may flip between calling them "async closures" and "coroutine-closures". The future that is returned by the async closure will generally be called the "coroutine" or the "child coroutine".
1014

11-
## HIR
15+
### HIR
1216

13-
Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure` whose closure-kind is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`) and whose closure-kind is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].
17+
Async closures (and in the future, other coroutine flavors such as `gen`) are represented in HIR as a `hir::Closure`.
18+
The closure-kind of the `hir::Closure` is `ClosureKind::CoroutineClosure(_)`[^k1], which wraps an async block, which is also represented in HIR as a `hir::Closure`.
19+
The closure-kind of the async block is `ClosureKind::Closure(CoroutineKind::Desugared(_, CoroutineSource::Closure))`[^k2].
1420

1521
[^k1]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_ast_lowering/src/expr.rs#L1147>
1622

@@ -24,7 +30,7 @@ Like `async fn`, when lowering an async closure's body, we need to unconditional
2430

2531
[^l3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_hir_typeck/src/upvar.rs#L250-L256>
2632

27-
## `rustc_middle::ty` Representation
33+
### `rustc_middle::ty` Representation
2834

2935
For the purposes of keeping the implementation mostly future-compatible (i.e. with gen `|| {}` and `async gen || {}`), most of this section calls async closures "coroutine-closures".
3036

@@ -72,7 +78,7 @@ To most easily construct the `Coroutine` that a coroutine-closure returns, you c
7278

7379
Most of the args to that function will be components that you can get out of the `CoroutineArgs`, except for the `goal_kind: ClosureKind` which controls which flavor of coroutine to return based off of the `ClosureKind` passed in -- i.e. it will prepare the by-ref coroutine if `ClosureKind::Fn | ClosureKind::FnMut`, and the by-move coroutine if `ClosureKind::FnOnce`.
7480

75-
## Trait Hierarchy
81+
### Trait Hierarchy
7682

7783
We introduce a parallel hierarchy of `Fn*` traits that are implemented for . The motivation for the introduction was covered in a blog post: [Async Closures](https://hackmd.io/@compiler-errors/async-closures).
7884

@@ -98,11 +104,11 @@ We mention above that "regular" callable types can implement `AsyncFn*`, but the
98104

99105
See the "follow-up: when do..." section below for an elaborated answer. The full answer describes a pretty interesting and hopefully thorough heuristic that is used to ensure that most async closures "just work".
100106

101-
## Tale of two bodies...
107+
### Tale of two bodies...
102108

103109
When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped.
104110

105-
To work around around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.
111+
To work around this limitation, we synthesize a separate by-move MIR body for calling `AsyncFnOnce::call_once` on a coroutine-closure that can be called by-ref.
106112

107113
This body operates identically to the "normal" coroutine returned from calling the coroutine-closure, except for the fact that it has a different set of upvars, since we must *move* the captures from the parent coroutine-closure into the child coroutine.
108114

@@ -120,7 +126,7 @@ Since we've synthesized a new def id, this query is also responsible for feeding
120126

121127
[^b3]: <https://github.com/rust-lang/rust/blob/5ca0e9fa9b2f92b463a0a2b0b34315e09c0b7236/compiler/rustc_mir_transform/src/lib.rs#L339-L342>
122128

123-
## Closure signature inference
129+
### Closure signature inference
124130

125131
The closure signature inference algorithm for async closures is a bit more complicated than the inference algorithm for "traditional" closures. Like closures, we iterate through all of the clauses that may be relevant (for the expectation type passed in)[^deduce1].
126132

@@ -173,7 +179,7 @@ s.as_bytes();
173179

174180
So *instead*, we use this alias (in this case, a projection: `AsyncFnKindHelper::Upvars<'env, ...>`) to delay the computation of the *tupled upvars* and give us something to put in its place, while still allowing us to return a `TyKind::Coroutine` (which is a rigid type) and we may successfully confirm the built-in traits we need (in our case, `Future`), since the `Future` implementation doesn't depend on the upvars at all.
175181

176-
## Upvar analysis
182+
### Upvar analysis
177183

178184
By and large, the upvar analysis for coroutine-closures and their child coroutines proceeds like normal upvar analysis. However, there are several interesting bits that happen to account for async closures' special natures:
179185

@@ -262,7 +268,7 @@ let c = async || {
262268

263269
If either of these cases apply, then we should capture the borrow with the lifetime of the parent coroutine-closure's env. Luckily, if this function is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors.
264270

265-
## Instance resolution
271+
### Instance resolution
266272

267273
If a coroutine-closure has a closure-kind of `FnOnce`, then its `AsyncFnOnce::call_once` and `FnOnce::call_once` implementations resolve to the coroutine-closure's body[^res1], and the `Future::poll` of the coroutine that gets returned resolves to the body of the child closure.
268274

@@ -282,7 +288,7 @@ This is represented by the `ConstructCoroutineInClosureShim`[^i1]. The `receiver
282288

283289
[^i3]: <https://github.com/rust-lang/rust/blob/07cbbdd69363da97075650e9be24b78af0bcdd23/compiler/rustc_middle/src/ty/instance.rs#L841>
284290

285-
## Borrow-checking
291+
### Borrow-checking
286292

287293
It turns out that borrow-checking async closures is pretty straightforward. After adding a new `DefiningTy::CoroutineClosure`[^bck1] variant, and teaching borrowck how to generate the signature of the coroutine-closure[^bck2], borrowck proceeds totally fine.
288294

0 commit comments

Comments
 (0)