Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 6 additions & 23 deletions compiler/rustc_query_impl/src/from_cycle_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, MultiSpan, pluralize, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::bug;
use rustc_middle::queries::{QueryVTables, TaggedQueryKey};
use rustc_middle::query::CycleError;
use rustc_middle::query::erase::erase_val;
use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{ErrorGuaranteed, Span};

Expand All @@ -31,9 +31,9 @@ pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) {
vtables.check_representability_adt_ty.value_from_cycle_error =
|tcx, _, cycle, _err| check_representability(tcx, cycle);

vtables.variances_of.value_from_cycle_error = |tcx, _, cycle, err| {
vtables.variances_of.value_from_cycle_error = |tcx, key, _, err| {
let _guar = err.delay_as_bug();
erase_val(variances_of(tcx, cycle))
erase_val(variances_of(tcx, key))
};

vtables.layout_of.value_from_cycle_error = |tcx, _, cycle, err| {
Expand Down Expand Up @@ -103,26 +103,9 @@ fn check_representability<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError<'tcx>
guar.raise_fatal()
}

fn variances_of<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError<'tcx>) -> &'tcx [ty::Variance] {
search_for_cycle_permutation(
&cycle_error.cycle,
|cycle| {
if let Some(frame) = cycle.get(0)
&& let TaggedQueryKey::variances_of(def_id) = frame.node.tagged_key
{
let n = tcx.generics_of(def_id).own_params.len();
ControlFlow::Break(tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n)))
} else {
ControlFlow::Continue(())
}
},
|| {
span_bug!(
cycle_error.usage.as_ref().unwrap().span,
"only `variances_of` returns `&[ty::Variance]`"
)
},
)
fn variances_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [ty::Variance] {
let n = tcx.generics_of(def_id).own_params.len();
tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n))
}

// Take a cycle of `Q` and try `try_cycle` on every permutation, falling back to `otherwise`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_infer::traits::util::elaborate;
use rustc_infer::traits::{
Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation,
};
use rustc_middle::ty::print::PrintPolyTraitPredicateExt;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _};
use rustc_session::parse::feature_err_unstable_feature_bound;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
Expand Down Expand Up @@ -306,8 +307,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
err.cancel();
return e;
}
let pred = self.tcx.short_string(predicate, &mut err.long_ty_path());
err.note(format!("cannot satisfy `{pred}`"));
if let Some(clause) = predicate.as_trait_clause()
&& let ty::Infer(_) = clause.self_ty().skip_binder().kind()
{
let tr = self.tcx.short_string(
clause.print_modifiers_and_trait_path(),
&mut err.long_ty_path(),
);
err.note(format!("the type must implement `{tr}`"));
} else {
let pred = self.tcx.short_string(predicate, &mut err.long_ty_path());
err.note(format!("cannot satisfy `{pred}`"));
}
let impl_candidates =
self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap());
if impl_candidates.len() < 40 {
Expand Down
66 changes: 36 additions & 30 deletions compiler/rustc_type_ir/src/region_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,26 @@ rustc_index::newtype_index! {
/// In general, the region lattice looks like
///
/// ```text
/// static ----------+-----...------+ (greatest)
/// empty(Un) -------- (smallest)
/// | \
/// ... \
/// | \
/// empty(U1) -- \
/// | \ placeholder(Un)
/// | \ |
/// empty(root) placeholder(U1) |
/// | | |
/// param regions | |
/// | | |
/// | | |
/// param regions | |
/// | | |
/// empty(root) placeholder(U1) |
/// | / |
/// | / placeholder(Un)
/// empty(U1) -- /
/// | /
/// ... /
/// | /
/// empty(Un) -------- (smallest)
/// static ----------+-----...------+ (greatest)
/// ```
///
/// Early-bound/free regions are the named lifetimes in scope from the
/// function declaration. They have relationships to one another
/// determined based on the declared relationships from the
/// function.
/// Lifetimes in scope from a function declaration are represented via
/// [`RegionKind::ReEarlyParam`]/[`RegionKind::ReLateParam`]. They
/// have relationships to one another and `'static` based on the
/// declared relationships from the function.
///
/// Note that inference variables and bound regions are not included
/// in this diagram. In the case of inference variables, they should
Expand All @@ -62,29 +62,36 @@ rustc_index::newtype_index! {
/// include -- the diagram indicates the relationship between free
/// regions.
///
/// You can read more about the distinction between early and late bound
/// parameters in the rustc dev guide: [Early vs Late bound parameters].
///
/// A note on subtyping: If we assume that references take their region
/// covariantly, and use that to define the subtyping relationship of regions,
/// it may be somewhat surprising that `'empty` is Top and `'static` is Bottom,
/// and that "`'a` is a subtype of `'b`" is defined as "`'a` is bigger than
/// `'b`" - good to keep in mind.
///
/// ## Inference variables
///
/// During region inference, we sometimes create inference variables,
/// represented as `ReVar`. These will be inferred by the code in
/// `infer::lexical_region_resolve` to some free region from the
/// lattice above (the minimal region that meets the
/// represented as [`RegionKind::ReVar`]. These will be inferred by
/// the code in `infer::lexical_region_resolve` to some free region
/// from the lattice above (the minimal region that meets the
/// constraints).
///
/// During NLL checking, where regions are defined differently, we
/// also use `ReVar` -- in that case, the index is used to index into
/// the NLL region checker's data structures. The variable may in fact
/// represent either a free region or an inference variable, in that
/// case.
/// also use [`RegionKind::ReVar`] -- in that case, the index is used
/// to index into the NLL region checker's data structures. The
/// variable may in fact represent either a free region or an
/// inference variable, in that case.
///
/// ## Bound Regions
///
/// These are regions that are stored behind a binder and must be instantiated
/// with some concrete region before being used. There are two kind of
/// bound regions: early-bound, which are bound in an item's `Generics`,
/// and are instantiated by an `GenericArgs`, and late-bound, which are part of
/// higher-ranked types (e.g., `for<'a> fn(&'a ())`), and are instantiated by
/// the likes of `liberate_late_bound_regions`. The distinction exists
/// because higher-ranked lifetimes aren't supported in all places. See [1][2].
/// with some concrete region before being used. A type can be wrapped in a
/// `Binder`, which introduces new type/const/lifetime variables (e.g., `for<'a>
/// fn(&'a ())`). These parameters are referred to via [`RegionKind::ReBound`].
/// You can instantiate them by the likes of `liberate_late_bound_regions`.
///
/// Unlike `Param`s, bound regions are not supposed to exist "in the wild"
/// outside their binder, e.g., in types passed to type inference, and
Expand Down Expand Up @@ -123,8 +130,7 @@ rustc_index::newtype_index! {
/// happen, you can use `leak_check`. This is more clearly explained
/// by the [rustc dev guide].
///
/// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
/// [Early vs Late bound parameters]: https://rustc-dev-guide.rust-lang.org/early-late-parameters.html
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
#[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)]
#[derive(GenericTypeVisitable)]
Expand Down Expand Up @@ -160,7 +166,7 @@ pub enum RegionKind<I: Interner> {
/// more info about early and late bound lifetime parameters.
ReLateParam(I::LateParamRegion),

/// Static data that has an "infinite" lifetime. Top in the region lattice.
/// Static data that has an "infinite" lifetime. Bottom in the region lattice.
ReStatic,

/// A region variable. Should not exist outside of type inference.
Expand Down
10 changes: 4 additions & 6 deletions src/ci/docker/host-x86_64/dist-various-1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -152,16 +152,14 @@ ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft
CC_riscv64gc_unknown_none_elf=riscv64-unknown-elf-gcc \
CFLAGS_riscv64gc_unknown_none_elf=-march=rv64gc -mabi=lp64

ENV RUST_CONFIGURE_ARGS \
--musl-root-armv5te=/musl-armv5te \
ENV RUST_CONFIGURE_ARGS="--musl-root-armv5te=/musl-armv5te \
--musl-root-arm=/musl-arm \
--musl-root-armhf=/musl-armhf \
--musl-root-armv7hf=/musl-armv7hf \
--disable-docs
--disable-docs"

ENV SCRIPT \
python3 ../x.py --stage 2 test --host='' --target $RUN_MAKE_TARGETS tests/run-make tests/run-make-cargo && \
python3 ../x.py dist --host='' --target $TARGETS
ENV SCRIPT="python3 ../x.py --stage 2 test --host= --target $RUN_MAKE_TARGETS tests/run-make tests/run-make-cargo && \
python3 ../x.py dist --host= --target $TARGETS"

# sccache
COPY scripts/sccache.sh /scripts/
Expand Down
20 changes: 9 additions & 11 deletions src/ci/docker/host-x86_64/dist-various-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,14 @@ RUN /tmp/freebsd-toolchain.sh i686
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_AR /usr/local/bin/llvm-ar
ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS \
-C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot \
ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_AR="/usr/local/bin/llvm-ar"
ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot \
-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot/lib \
-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib
ENV CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_AR /usr/local/bin/llvm-ar
ENV CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_RUSTFLAGS \
-C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot \
-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib"
ENV CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_AR="/usr/local/bin/llvm-ar"
ENV CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot \
-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/sysroot/lib \
-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/lib
-Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/arm64/lib"

ENV TARGETS=x86_64-unknown-fuchsia
ENV TARGETS=$TARGETS,aarch64-unknown-fuchsia
Expand Down Expand Up @@ -136,8 +134,8 @@ RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm
# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths.
RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/

ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
--musl-root-armv7=/musl-armv7 \
--musl-root-riscv64gc=/musl-riscv64gc
--musl-root-riscv64gc=/musl-riscv64gc"

ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS && python3 ../x.py dist --host='' --set build.sanitizers=true --target $TARGETS_SANITIZERS
ENV SCRIPT="python3 ../x.py dist --host= --target $TARGETS && python3 ../x.py dist --host= --set build.sanitizers=true --target $TARGETS_SANITIZERS"
23 changes: 11 additions & 12 deletions src/ci/docker/host-x86_64/test-various/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-3
tar -xz
ENV WASI_SDK_PATH=/wasi-sdk-30.0-x86_64-linux

ENV RUST_CONFIGURE_ARGS \
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
--set rust.lld
ENV RUST_CONFIGURE_ARGS="--musl-root-x86_64=/usr/local/x86_64-linux-musl \
--set rust.lld"

# Some run-make tests have assertions about code size, and enabling debug
# assertions in libstd causes the binary to be much bigger than it would
Expand All @@ -58,29 +57,29 @@ ENV NO_OVERFLOW_CHECKS=1

RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v38.0.4/wasmtime-v38.0.4-x86_64-linux.tar.xz | \
tar -xJ
ENV PATH "$PATH:/wasmtime-v38.0.4-x86_64-linux"
ENV PATH="$PATH:/wasmtime-v38.0.4-x86_64-linux"

ENV WASM_WASIP_TARGET=wasm32-wasip1
ENV WASM_WASIP_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_WASIP_TARGET \
ENV WASM_WASIP_SCRIPT="python3 /checkout/x.py --stage 2 test --host= --target $WASM_WASIP_TARGET \
tests/run-make \
tests/run-make-cargo \
tests/ui \
tests/mir-opt \
tests/codegen-units \
tests/codegen-llvm \
tests/assembly-llvm \
library/core
library/core"

ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
ENV NVPTX_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $NVPTX_TARGETS \
ENV NVPTX_SCRIPT="python3 /checkout/x.py --stage 2 test --host= --target $NVPTX_TARGETS \
tests/run-make \
tests/run-make-cargo \
tests/assembly-llvm
tests/assembly-llvm"

ENV MUSL_TARGETS=x86_64-unknown-linux-musl \
CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \
CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++
ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS
ENV MUSL_SCRIPT="python3 /checkout/x.py --stage 2 test --host= --target $MUSL_TARGETS"

ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \
CC_aarch64_unknown_uefi=clang-11 \
Expand All @@ -89,9 +88,9 @@ ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \
CXX_i686_unknown_uefi=clang++-11 \
CC_x86_64_unknown_uefi=clang-11 \
CXX_x86_64_unknown_uefi=clang++-11
ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \
ENV UEFI_SCRIPT="python3 /checkout/x.py --stage 2 build --host= --target $UEFI_TARGETS && \
python3 /checkout/x.py --stage 2 test tests/run-make-cargo/uefi-qemu/rmake.rs --target aarch64-unknown-uefi && \
python3 /checkout/x.py --stage 2 test tests/run-make-cargo/uefi-qemu/rmake.rs --target i686-unknown-uefi && \
python3 /checkout/x.py --stage 2 test tests/run-make-cargo/uefi-qemu/rmake.rs --target x86_64-unknown-uefi
python3 /checkout/x.py --stage 2 test tests/run-make-cargo/uefi-qemu/rmake.rs --target x86_64-unknown-uefi"

ENV SCRIPT $WASM_WASIP_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT
ENV SCRIPT="$WASM_WASIP_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT"
6 changes: 6 additions & 0 deletions src/doc/rustc-dev-guide/src/early-late-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

> **NOTE**: This chapter largely talks about early/late bound as being solely relevant when discussing function item types/function definitions. This is potentially not completely true, async blocks and closures should likely be discussed somewhat in this chapter.

See also these blog posts from when the distinction between early and late bound parameters was
introduced: [Intermingled parameter lists] and [Intermingled parameter lists, take 2].

[Intermingled parameter lists]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
[Intermingled parameter lists, take 2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/

## What does it mean to be "early" bound or "late" bound

Every function definition has a corresponding ZST that implements the `Fn*` traits known as a [function item type][function_item_type]. This part of the chapter will talk a little bit about the "desugaring" of function item types as it is useful context for explaining the difference between early bound and late bound generic parameters.
Expand Down
17 changes: 17 additions & 0 deletions src/doc/rustc-dev-guide/src/tests/compiletest.md
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,20 @@ In CI, compare modes are only used in one Linux builder, and only with the follo
Note that compare modes are separate to [revisions](#revisions).
All revisions are tested when running `./x test tests/ui`, however compare-modes must be
manually run individually via the `--compare-mode` flag.

## Parallel frontend

Compiletest can be run with the `--parallel-frontend-threads` flag to run the compiler in parallel mode.
This can be used to check that the compiler produces the same output in parallel mode as in non-parallel mode, and to check for any issues that might arise in parallel mode.

To run the tests in parallel mode, you need to pass the `--parallel-frontend-threads` CLI flag:

```bash
./x test tests/ui -- --parallel-frontend-threads=N --iteration-count=M
```

Where `N` is the number of threads to use for the parallel frontend, and `M` is the number of times to run each test in parallel mode (to increase the chances of catching any non-determinism).

Also, when running with `--parallel-frontend-threads`, the `compare-output-by-lines` directive would be implied for all tests, since the output from the parallel frontend can be non-deterministic in terms of the order of lines.

The parallel frontend is available in UI tests only at the moment, and is not currently supported in other test suites.
2 changes: 2 additions & 0 deletions src/doc/rustc-dev-guide/src/tests/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ Some examples of `X` in `ignore-X` or `only-X`:
- When [remote testing] is used: `remote`
- When particular debuggers are being tested: `cdb`, `gdb`, `lldb`
- When particular debugger versions are matched: `ignore-gdb-version`
- When the [parallel frontend] is enabled: `ignore-parallel-frontend`
- Specific [compare modes]: `compare-mode-polonius`, `compare-mode-chalk`,
`compare-mode-split-dwarf`, `compare-mode-split-dwarf-single`
- The two different test modes used by coverage tests:
Expand Down Expand Up @@ -233,6 +234,7 @@ The following directives will check LLVM support:
See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ignoring debuggers.

[remote testing]: running.md#running-tests-on-a-remote-machine
[parallel frontend]: compiletest.md#parallel-frontend
[compare modes]: ui.md#compare-modes
[`x86_64-gnu-debug`]: https://github.com/rust-lang/rust/blob/ab3dba92db355b8d97db915a2dca161a117e959c/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile#L32
[`aarch64-gnu-debug`]: https://github.com/rust-lang/rust/blob/20c909ff9cdd88d33768a4ddb8952927a675b0ad/src/ci/docker/host-aarch64/aarch64-gnu-debug/Dockerfile#L32
Expand Down
Loading
Loading