Merge pull request #4190 from rust-lang/rustup-2025-02-13

Automatic Rustup
This commit is contained in:
Ralf Jung 2025-02-13 06:11:48 +00:00 committed by GitHub
commit 922dbb48bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 159 additions and 92 deletions

View File

@ -3,8 +3,8 @@ name: rustc-pull
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
# Run at 04:00 UTC every Monday # Run at 04:00 UTC every Monday and Thursday
- cron: '0 4 * * 1' - cron: '0 4 * * 1,4'
jobs: jobs:
pull: pull:
@ -34,8 +34,25 @@ jobs:
git config --global user.name 'The rustc-dev-guide Cronjob Bot' git config --global user.name 'The rustc-dev-guide Cronjob Bot'
git config --global user.email 'github-actions@github.com' git config --global user.email 'github-actions@github.com'
- name: Perform rustc-pull - name: Perform rustc-pull
run: cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull id: rustc-pull
# Turn off -e to disable early exit
shell: bash {0}
run: |
cargo run --manifest-path josh-sync/Cargo.toml -- rustc-pull
exitcode=$?
# If no pull was performed, we want to mark this job as successful,
# but we do not want to perform the follow-up steps.
if [ $exitcode -eq 0 ]; then
echo "pull_result=pull-finished" >> $GITHUB_OUTPUT
elif [ $exitcode -eq 2 ]; then
echo "pull_result=skipped" >> $GITHUB_OUTPUT
exitcode=0
fi
exit ${exitcode}
- name: Push changes to a branch - name: Push changes to a branch
if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }}
run: | run: |
# Update a sticky branch that is used only for rustc pulls # Update a sticky branch that is used only for rustc pulls
BRANCH="rustc-pull" BRANCH="rustc-pull"
@ -43,6 +60,9 @@ jobs:
git push -u origin $BRANCH --force git push -u origin $BRANCH --force
- name: Create pull request - name: Create pull request
id: update-pr id: update-pr
if: ${{ steps.rustc-pull.outputs.pull_result == 'pull-finished' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
# Check if an open pull request for an rustc pull update already exists # Check if an open pull request for an rustc pull update already exists
# If it does, the previous push has just updated it # If it does, the previous push has just updated it
@ -54,26 +74,35 @@ jobs:
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
else else
PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title` PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title`
echo "Updating pull request ${PR_URL}"
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
fi fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
send-zulip-message: send-zulip-message:
needs: [pull] needs: [pull]
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4
- name: Compute message - name: Compute message
id: message id: create-message
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
if [ "${{ needs.pull.result }}" == "failure" ]; if [ "${{ needs.pull.result }}" == "failure" ]; then
then
WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" WORKFLOW_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT echo "message=Rustc pull sync failed. Check out the [workflow URL]($WORKFLOW_URL)." >> $GITHUB_OUTPUT
else else
echo "message=Rustc pull sync succeeded. Check out the [PR](${{ needs.pull.outputs.pr_url }})." >> $GITHUB_OUTPUT CREATED_AT=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].createdAt' --json createdAt,title`
PR_URL=`gh pr list --author github-actions[bot] --state open -q 'map(select(.title=="Rustc pull update")) | .[0].url' --json url,title`
week_ago=$(date +%F -d '7 days ago')
# If there is an open PR that is at least a week old, post a message about it
if [[ -n $DATE_GH && $DATE_GH < $week_ago ]]; then
echo "message=A PR with a Rustc pull has been opened for more a week. Check out the [PR](${PR_URL})." >> $GITHUB_OUTPUT
fi
fi fi
- name: Send a Zulip message about updated PR - name: Send a Zulip message about updated PR
if: ${{ steps.create-message.outputs.message != '' }}
uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5 uses: zulip/github-actions-zulip/send-message@e4c8f27c732ba9bd98ac6be0583096dea82feea5
with: with:
api-key: ${{ secrets.ZULIP_API_TOKEN }} api-key: ${{ secrets.ZULIP_API_TOKEN }}

View File

@ -1,5 +1,5 @@
use clap::Parser; use clap::Parser;
use crate::sync::GitSync; use crate::sync::{GitSync, RustcPullError};
mod sync; mod sync;
@ -22,7 +22,18 @@ fn main() -> anyhow::Result<()> {
let sync = GitSync::from_current_dir()?; let sync = GitSync::from_current_dir()?;
match args { match args {
Args::RustcPull => { Args::RustcPull => {
sync.rustc_pull(None)?; if let Err(error) = sync.rustc_pull(None) {
match error {
RustcPullError::NothingToPull => {
eprintln!("Nothing to pull");
std::process::exit(2);
}
RustcPullError::PullFailed(error) => {
eprintln!("Pull failure: {error:?}");
std::process::exit(1);
}
}
}
} }
Args::RustcPush { github_username, branch } => { Args::RustcPush { github_username, branch } => {
sync.rustc_push(github_username, branch)?; sync.rustc_push(github_username, branch)?;

View File

@ -11,6 +11,19 @@ const JOSH_FILTER: &str = ":/src/doc/rustc-dev-guide";
const JOSH_PORT: u16 = 42042; const JOSH_PORT: u16 = 42042;
const UPSTREAM_REPO: &str = "rust-lang/rust"; const UPSTREAM_REPO: &str = "rust-lang/rust";
pub enum RustcPullError {
/// No changes are available to be pulled.
NothingToPull,
/// A rustc-pull has failed, probably a git operation error has occurred.
PullFailed(anyhow::Error)
}
impl<E> From<E> for RustcPullError where E: Into<anyhow::Error> {
fn from(error: E) -> Self {
Self::PullFailed(error.into())
}
}
pub struct GitSync { pub struct GitSync {
dir: PathBuf, dir: PathBuf,
} }
@ -24,7 +37,7 @@ impl GitSync {
}) })
} }
pub fn rustc_pull(&self, commit: Option<String>) -> anyhow::Result<()> { pub fn rustc_pull(&self, commit: Option<String>) -> Result<(), RustcPullError> {
let sh = Shell::new()?; let sh = Shell::new()?;
sh.change_dir(&self.dir); sh.change_dir(&self.dir);
let commit = commit.map(Ok).unwrap_or_else(|| { let commit = commit.map(Ok).unwrap_or_else(|| {
@ -38,7 +51,7 @@ impl GitSync {
})?; })?;
// Make sure the repo is clean. // Make sure the repo is clean.
if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() { if cmd!(sh, "git status --untracked-files=no --porcelain").read()?.is_empty().not() {
bail!("working directory must be clean before performing rustc pull"); return Err(anyhow::anyhow!("working directory must be clean before performing rustc pull").into());
} }
// Make sure josh is running. // Make sure josh is running.
let josh = Self::start_josh()?; let josh = Self::start_josh()?;
@ -47,7 +60,7 @@ impl GitSync {
let previous_base_commit = sh.read_file("rust-version")?.trim().to_string(); let previous_base_commit = sh.read_file("rust-version")?.trim().to_string();
if previous_base_commit == commit { if previous_base_commit == commit {
return Err(anyhow::anyhow!("No changes since last pull")); return Err(RustcPullError::NothingToPull);
} }
// Update rust-version file. As a separate commit, since making it part of // Update rust-version file. As a separate commit, since making it part of
@ -94,12 +107,13 @@ impl GitSync {
cmd!(sh, "git reset --hard HEAD^") cmd!(sh, "git reset --hard HEAD^")
.run() .run()
.expect("FAILED to clean up after creating the preparation commit"); .expect("FAILED to clean up after creating the preparation commit");
return Err(anyhow::anyhow!("No merge was performed, nothing to pull. Rolled back the preparation commit.")); eprintln!("No merge was performed, no changes to pull were found. Rolled back the preparation commit.");
return Err(RustcPullError::NothingToPull);
} }
// Check that the number of roots did not increase. // Check that the number of roots did not increase.
if num_roots()? != num_roots_before { if num_roots()? != num_roots_before {
bail!("Josh created a new root commit. This is probably not the history you want."); return Err(anyhow::anyhow!("Josh created a new root commit. This is probably not the history you want.").into());
} }
drop(josh); drop(josh);

View File

@ -1 +1 @@
66d6064f9eb888018775e08f84747ee6f39ba28e 124cc92199ffa924f6b4c7cc819a85b65e0c3984

View File

@ -82,7 +82,7 @@ Rust, as well as publications about Rust.
* [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf) * [Ownership is Theft: Experiences Building an Embedded OS in Rust - Amit Levy, et. al.](https://amitlevy.com/papers/tock-plos2015.pdf)
* [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). Aria Beingessner's master's thesis. * [You can't spell trust without Rust](https://faultlore.com/blah/papers/thesis.pdf). Aria Beingessner's master's thesis.
* [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). Johannes Köster * [Rust-Bio: a fast and safe bioinformatics library](https://rust-bio.github.io/). Johannes Köster
* [Safe, Correct, and Fast Low-Level Networking](https://octarineparrot.com/assets/msci_paper.pdf). Robert Clipsham's master's thesis. * [Safe, Correct, and Fast Low-Level Networking](https://csperkins.org/research/thesis-msci-clipsham.pdf). Robert Clipsham's master's thesis.
* [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). Jonatan Milewski's master's thesis. * [Formalizing Rust traits](https://open.library.ubc.ca/cIRcle/collections/ubctheses/24/items/1.0220521). Jonatan Milewski's master's thesis.
* [Rust as a Language for High Performance GC Implementation](https://dl.acm.org/doi/pdf/10.1145/3241624.2926707) * [Rust as a Language for High Performance GC Implementation](https://dl.acm.org/doi/pdf/10.1145/3241624.2926707)
* [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). Sebastian Ullrich's master's thesis. * [Simple Verification of Rust Programs via Functional Purification](https://github.com/Kha/electrolysis). Sebastian Ullrich's master's thesis.

View File

@ -332,28 +332,21 @@ git worktree add -b my-feature ../rust2 master
You can then use that rust2 folder as a separate workspace for modifying and You can then use that rust2 folder as a separate workspace for modifying and
building `rustc`! building `rustc`!
## Using nix-shell ## Working with nix
If you're using nix, you can use the following nix-shell to work on Rust: Several nix configurations are defined in `src/tools/nix-dev-shell`.
```nix If you're using direnv, you can create a symbol link to `src/tools/nix-dev-shell/envrc-flake` or `src/tools/nix-dev-shell/envrc-shell`
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell { ```bash
name = "rustc"; ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc # Use flake
nativeBuildInputs = with pkgs; [
binutils cmake ninja pkg-config python3 git curl cacert patchelf nix
];
buildInputs = with pkgs; [
openssl glibc.out glibc.static
];
# Avoid creating text files for ICEs.
RUSTC_ICE = "0";
# Provide `libstdc++.so.6` for the self-contained lld.
LD_LIBRARY_PATH = "${with pkgs; lib.makeLibraryPath [
stdenv.cc.cc.lib
]}";
}
``` ```
or
```bash
ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell
```
### Note
Note that when using nix on a not-NixOS distribution, it may be necessary to set Note that when using nix on a not-NixOS distribution, it may be necessary to set
**`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect **`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect

View File

@ -601,8 +601,8 @@ The trait implementation allows you to check certain syntactic constructs
as the linter walks the AST. You can then choose to emit lints in a as the linter walks the AST. You can then choose to emit lints in a
very similar way to compile errors. very similar way to compile errors.
You also declare the metadata of a particular lint via the `declare_lint!` You also declare the metadata of a particular lint via the [`declare_lint!`]
macro. [This macro](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html) includes the name, the default level, a short description, and some macro. This macro includes the name, the default level, a short description, and some
more details. more details.
Note that the lint and the lint pass must be registered with the compiler. Note that the lint and the lint pass must be registered with the compiler.
@ -671,6 +671,8 @@ example-use-loop = denote infinite loops with `loop {"{"} ... {"}"}`
.suggestion = use `loop` .suggestion = use `loop`
``` ```
[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/macro.declare_lint.html
### Edition-gated lints ### Edition-gated lints
Sometimes we want to change the behavior of a lint in a new edition. To do this, Sometimes we want to change the behavior of a lint in a new edition. To do this,

View File

@ -101,7 +101,6 @@ it's easy to pick up work without a large time commitment:
- [Rustdoc Askama Migration](https://github.com/rust-lang/rust/issues/108868) - [Rustdoc Askama Migration](https://github.com/rust-lang/rust/issues/108868)
- [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717) - [Diagnostic Translation](https://github.com/rust-lang/rust/issues/100717)
- [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) - [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494)
- [Port run-make tests from Make to Rust](https://github.com/rust-lang/rust/issues/121876)
If you find more recurring work, please feel free to add it here! If you find more recurring work, please feel free to add it here!

View File

@ -9,7 +9,11 @@ smoothly.
**NOTE: this section is for *language* features, not *library* features, **NOTE: this section is for *language* features, not *library* features,
which use [a different process].** which use [a different process].**
See also [the Rust Language Design Team's procedures][lang-propose] for
proposing changes to the language.
[a different process]: ./stability.md [a different process]: ./stability.md
[lang-propose]: https://lang-team.rust-lang.org/how_to/propose.html
## The @rfcbot FCP process ## The @rfcbot FCP process

View File

@ -21,7 +21,7 @@ Creating an env from an arbitrary set of where clauses is usually unnecessary an
Creating an empty environment via `ParamEnv::empty` is almost always wrong. There are very few places where we actually know that the environment should be empty. One of the only places where we do actually know this is after monomorphization, however the `ParamEnv` there should be constructed via `ParamEnv::reveal_all` instead as at this point we should be able to determine the hidden type of opaque types. Codegen/Post-mono is one of the only places that should be using `ParamEnv::reveal_all`. Creating an empty environment via `ParamEnv::empty` is almost always wrong. There are very few places where we actually know that the environment should be empty. One of the only places where we do actually know this is after monomorphization, however the `ParamEnv` there should be constructed via `ParamEnv::reveal_all` instead as at this point we should be able to determine the hidden type of opaque types. Codegen/Post-mono is one of the only places that should be using `ParamEnv::reveal_all`.
An additional piece of complexity here is specifying the [`Reveal`][reveal] (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead. An additional piece of complexity here is specifying the `Reveal` (see linked docs for explanation of what reveal does) used for the `ParamEnv`. When constructing a param env using the `param_env` query it will have `Reveal::UserFacing`, if `Reveal::All` is desired then the [`tcx.param_env_reveal_all_normalized`][env_reveal_all_normalized] query can be used instead.
The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_reveal_all] which converts an existing `ParamEnv` into one with `Reveal::All` specified. Where possible the previously mentioned query should be preferred as it is more efficient. The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_reveal_all] which converts an existing `ParamEnv` into one with `Reveal::All` specified. Where possible the previously mentioned query should be preferred as it is more efficient.
@ -38,7 +38,6 @@ The `ParamEnv` type has a method [`ParamEnv::with_reveal_all_normalized`][with_r
[with_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.with_reveal_all_normalized [with_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.with_reveal_all_normalized
[env_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.reveal_all [env_reveal_all]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.reveal_all
[env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty [env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty
[reveal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/enum.Reveal.html
[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
[param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env [param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env
[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html

View File

@ -3,7 +3,7 @@
The type system relies on information in the environment in order for it to function correctly. This information is stored in the [`ParamEnv`][pe] type and it is important to use the correct `ParamEnv` when interacting with the type system. The type system relies on information in the environment in order for it to function correctly. This information is stored in the [`ParamEnv`][pe] type and it is important to use the correct `ParamEnv` when interacting with the type system.
The information represented by `ParamEnv` is a list of in-scope where-clauses, and a [`Reveal`][reveal] (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds. The information represented by `ParamEnv` is a list of in-scope where-clauses, and a `Reveal` (see linked docs for more information). A `ParamEnv` typically corresponds to a specific item's where clauses, some clauses are not explicitly written bounds and instead are implicitly added in [`predicates_of`][predicates_of] such as `ConstArgHasType` or some implied bounds.
A `ParamEnv` can also be created with arbitrary data that is not derived from a specific item such as in [`compare_method_predicate_entailment`][method_pred_entailment] which creates a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary data that is not derived from a specific item such as in [`compare_method_predicate_entailment`][method_pred_entailment] which creates a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses.
@ -57,4 +57,3 @@ It's very important to use the correct `ParamEnv` when interacting with the type
[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html [method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html
[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
[query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env [query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env
[reveal]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/traits/enum.Reveal.html

View File

@ -46,8 +46,8 @@ For space savings, it's also written without newlines or spaces.
] ]
``` ```
[`src/librustdoc/html/static/js/externs.js`] [`src/librustdoc/html/static/js/rustdoc.d.ts`]
defines an actual schema in a Closure `@typedef`. defines an actual schema in a TypeScript `type`.
| Key | Name | Description | | Key | Name | Description |
| --- | -------------------- | ------------ | | --- | -------------------- | ------------ |
@ -68,7 +68,7 @@ with a free function called `function_name` and a struct called `Data`,
with the type signature `Data, i32 -> str`, with the type signature `Data, i32 -> str`,
and an alias, `get_name`, that equivalently refers to `function_name`. and an alias, `get_name`, that equivalently refers to `function_name`.
[`src/librustdoc/html/static/js/externs.js`]: https://github.com/rust-lang/rust/blob/79b710c13968a1a48d94431d024d2b1677940866/src/librustdoc/html/static/js/externs.js#L204-L258 [`src/librustdoc/html/static/js/rustdoc.d.ts`]: https://github.com/rust-lang/rust/blob/2f92f050e83bf3312ce4ba73c31fe843ad3cbc60/src/librustdoc/html/static/js/rustdoc.d.ts#L344-L390
The search index needs to fit the needs of the `rustdoc` compiler, The search index needs to fit the needs of the `rustdoc` compiler,
the `search.js` frontend, the `search.js` frontend,
@ -469,7 +469,7 @@ want the libs team to be able to add new items without causing unrelated
tests to fail, but standalone tests will use it more often. tests to fail, but standalone tests will use it more often.
The `ResultsTable` and `ParsedQuery` types are specified in The `ResultsTable` and `ParsedQuery` types are specified in
[`externs.js`](https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/js/externs.js). [`rustdoc.d.ts`](https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/js/rustdoc.d.ts).
For example, imagine we needed to fix a bug where a function named For example, imagine we needed to fix a bug where a function named
`constructor` couldn't be found. To do this, write two files: `constructor` couldn't be found. To do this, write two files:

View File

@ -322,7 +322,7 @@ Our CI workflow uses various caching mechanisms, mainly for two things:
### Docker images caching ### Docker images caching
The Docker images we use to run most of the Linux-based builders take a *long* The Docker images we use to run most of the Linux-based builders take a *long*
time to fully build. To speed up the build, we cache it using [Docker registry time to fully build. To speed up the build, we cache them using [Docker registry
caching], with the intermediate artifacts being stored on [ghcr.io]. We also caching], with the intermediate artifacts being stored on [ghcr.io]. We also
push the built Docker images to ghcr, so that they can be reused by other tools push the built Docker images to ghcr, so that they can be reused by other tools
(rustup) or by developers running the Docker build locally (to speed up their (rustup) or by developers running the Docker build locally (to speed up their
@ -334,6 +334,13 @@ override the cache for the others. Instead, we store the images under different
tags, identifying them with a custom hash made from the contents of all the tags, identifying them with a custom hash made from the contents of all the
Dockerfiles and related scripts. Dockerfiles and related scripts.
The CI calculates a hash key, so that the cache of a Docker image is
invalidated if one of the following changes:
- Dockerfile
- Files copied into the Docker image in the Dockerfile
- The architecture of the GitHub runner (x86 or ARM)
[ghcr.io]: https://github.com/rust-lang-ci/rust/pkgs/container/rust-ci [ghcr.io]: https://github.com/rust-lang-ci/rust/pkgs/container/rust-ci
[Docker registry caching]: https://docs.docker.com/build/cache/backends/registry/ [Docker registry caching]: https://docs.docker.com/build/cache/backends/registry/
@ -341,9 +348,18 @@ Dockerfiles and related scripts.
We build some C/C++ stuff in various CI jobs, and we rely on [sccache] to cache We build some C/C++ stuff in various CI jobs, and we rely on [sccache] to cache
the intermediate LLVM artifacts. Sccache is a distributed ccache developed by the intermediate LLVM artifacts. Sccache is a distributed ccache developed by
Mozilla, which can use an object storage bucket as the storage backend. In our Mozilla, which can use an object storage bucket as the storage backend.
case, the artefacts are uploaded to an S3 bucket that we control
(`rust-lang-ci-sccache2`). With sccache there's no need to calculate the hash key ourselves. Sccache
invalidates the cache automatically when it detects changes to relevant inputs,
such as the source code, the version of the compiler, and important environment
variables.
So we just pass the sccache wrapper on top of cargo and sccache does the rest.
We store the persistent artifacts on the S3 bucket `rust-lang-ci-sccache2`. So
when the CI runs, if sccache sees that LLVM is being compiled with the same C/C++
compiler and the LLVM source code is the same, sccache retrieves the individual
compiled translation units from S3.
[sccache]: https://github.com/mozilla/sccache [sccache]: https://github.com/mozilla/sccache

View File

@ -192,6 +192,8 @@ settings:
specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8, specified atomic widths, e.g. the test with `//@ needs-target-has-atomic: 8,
16, ptr` will only run if it supports the comma-separated list of atomic 16, ptr` will only run if it supports the comma-separated list of atomic
widths. widths.
- `needs-dynamic-linking` - ignores if target does not support dynamic linking
(which is orthogonal to it being unable to create `dylib` and `cdylib` crate types)
The following directives will check LLVM support: The following directives will check LLVM support:

View File

@ -1,36 +1,44 @@
# Testing with Docker # Testing with Docker
The Rust tree includes [Docker] image definitions for the platforms used on The [`src/ci/docker`] directory includes [Docker] image definitions for Linux-based jobs executed on GitHub Actions (non-Linux jobs run outside Docker). You can run these jobs on your local development machine, which can be
GitHub Actions in [`src/ci/docker`]. helpful to test environments different from your local system. You will
The script [`src/ci/docker/run.sh`] is used to build the Docker image, run it,
build Rust within the image, and run the tests.
You can run these images on your local development machine. This can be
helpful to test environments different from your local system. First you will
need to install Docker on a Linux, Windows, or macOS system (typically Linux need to install Docker on a Linux, Windows, or macOS system (typically Linux
will be much faster than Windows or macOS because the latter use virtual will be much faster than Windows or macOS because the latter use virtual
machines to emulate a Linux environment). To enter interactive mode which will machines to emulate a Linux environment).
start a bash shell in the container, run `src/ci/docker/run.sh --dev <IMAGE>`
where `<IMAGE>` is one of the directory names in `src/ci/docker` (for example
`x86_64-gnu` is a fairly standard Ubuntu environment).
The docker script will mount your local Rust source tree in read-only mode, Jobs running in CI are configured through a set of bash scripts, and it is not always trivial to reproduce their behavior locally. If you want to run a CI job locally in the simplest way possible, you can use a provided helper Python script that tries to replicate what happens on CI as closely as possible:
and an `obj` directory in read-write mode. All of the compiler artifacts will
be stored in the `obj` directory. The shell will start out in the `obj`
directory. From there, you can run `../src/ci/run.sh` which will run the build
as defined by the image.
Alternatively, you can run individual commands to do specific tasks. For ```bash
example, you can run `../x test tests/ui` to just run UI tests. python3 src/ci/github-actions/ci.py run-local <job-name>
Note that there is some configuration in the [`src/ci/run.sh`] script that you # For example:
may need to recreate. Particularly, set `submodules = false` in your python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt
`config.toml` so that it doesn't attempt to modify the read-only directory. ```
Some additional notes about using the Docker images: If the above script does not work for you, you would like to have more control of the Docker image execution, or you want to understand what exactly happens during Docker job execution, then continue reading below.
## The `run.sh` script
The [`src/ci/docker/run.sh`] script is used to build a specific Docker image, run it,
build Rust within the image, and either run tests or prepare a set of archives designed for distribution. The script will mount your local Rust source tree in read-only mode, and an `obj` directory in read-write mode. All the compiler artifacts will be stored in the `obj` directory. The shell will start out in the `obj`directory. From there, it will execute `../src/ci/run.sh` which starts the build as defined by the Docker image.
You can run `src/ci/docker/run.sh <image-name>` directly. A few important notes regarding the `run.sh` script:
- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `config.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though).
- `<image-name>` corresponds to a single directory located in one of the `src/ci/docker/host-*` directories. Note that image name does not necessarily correspond to a job name, as some jobs execute the same image, but with different environment variables or Docker build arguments (this is a part of the complexity that makes it difficult to run CI jobs locally).
- If you are executing a "dist" job (job beginning with `dist-`), you should set the `DEPLOY=1` environment variable.
- If you are executing an "alternative dist" job (job beginning with `dist-` and ending with `-alt`), you should set the `DEPLOY_ALT=1` environment variable.
- Some of the std tests require IPv6 support. Docker on Linux seems to have it - Some of the std tests require IPv6 support. Docker on Linux seems to have it
disabled by default. Run the commands in [`enable-docker-ipv6.sh`] to enable disabled by default. Run the commands in [`enable-docker-ipv6.sh`] to enable
IPv6 before creating the container. This only needs to be done once. IPv6 before creating the container. This only needs to be done once.
### Interactive mode
Sometimes, it can be useful to build a specific Docker image, and then run custom commands inside it, so that you can experiment with how the given system behaves. You can do that using an interactive mode, which will
start a bash shell in the container, using `src/ci/docker/run.sh --dev <image-name>`.
When inside the Docker container, you can run individual commands to do specific tasks. For
example, you can run `../x test tests/ui` to just run UI tests.
Some additional notes about using the interactive mode:
- The container will be deleted automatically when you exit the shell, however - The container will be deleted automatically when you exit the shell, however
the build artifacts persist in the `obj` directory. If you are switching the build artifacts persist in the `obj` directory. If you are switching
between different Docker images, the artifacts from previous environments between different Docker images, the artifacts from previous environments
@ -45,15 +53,6 @@ Some additional notes about using the Docker images:
containers. With the container name, run `docker exec -it <CONTAINER> containers. With the container name, run `docker exec -it <CONTAINER>
/bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`. /bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`.
The approach described above is a relatively low-level interface for running the Docker images
directly. If you want to run a full CI Linux job locally with Docker, in a way that is as close to CI as possible, you can use the following command:
```bash
python3 src/ci/github-actions/ci.py run-local <job-name>
# For example:
python3 src/ci/github-actions/ci.py run-local dist-x86_64-linux-alt
```
[Docker]: https://www.docker.com/ [Docker]: https://www.docker.com/
[`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker [`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker
[`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh [`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh

View File

@ -40,7 +40,7 @@ requirements of impls and functions as explicit predicates.
### using implicit implied bounds as assumptions ### using implicit implied bounds as assumptions
These bounds are not added to the `ParamEnv` of the affected item itself. For lexical These bounds are not added to the `ParamEnv` of the affected item itself. For lexical
region resolution they are added using [`fn OutlivesEnvironment::new`]. region resolution they are added using [`fn OutlivesEnvironment::from_normalized_bounds`].
Similarly, during MIR borrowck we add them using Similarly, during MIR borrowck we add them using
[`fn UniversalRegionRelationsBuilder::add_implied_bounds`]. [`fn UniversalRegionRelationsBuilder::add_implied_bounds`].
@ -55,7 +55,7 @@ The assumed outlives constraints for implicit bounds are computed using the
MIR borrowck adds the outlives constraints for both the normalized and unnormalized types, MIR borrowck adds the outlives constraints for both the normalized and unnormalized types,
lexical region resolution [only uses the unnormalized types][notnorm]. lexical region resolution [only uses the unnormalized types][notnorm].
[`fn OutlivesEnvironment::new`]: TODO [`fn OutlivesEnvironment::from_normalized_bounds`]: https://github.com/rust-lang/rust/blob/8239a37f9c0951a037cfc51763ea52a20e71e6bd/compiler/rustc_infer/src/infer/outlives/env.rs#L50-L55
[`fn UniversalRegionRelationsBuilder::add_implied_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L316 [`fn UniversalRegionRelationsBuilder::add_implied_bounds`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L316
[mir]: https://github.com/rust-lang/rust/blob/91cae1dcdcf1a31bd8a92e4a63793d65cfe289bb/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L258-L332 [mir]: https://github.com/rust-lang/rust/blob/91cae1dcdcf1a31bd8a92e4a63793d65cfe289bb/compiler/rustc_borrowck/src/type_check/free_region_relations.rs#L258-L332
[`fn assumed_wf_types`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_ty_utils/src/implied_bounds.rs#L21 [`fn assumed_wf_types`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_ty_utils/src/implied_bounds.rs#L21