diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index c3fc21a92854a..70331b72353e4 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -44,10 +44,10 @@ pub trait DerivedTypeCodegenMethods<'tcx>:
BaseTypeCodegenMethods + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx> + HasTypingEnv<'tcx>
{
fn type_int(&self) -> Self::Type {
- match &self.sess().target.c_int_width[..] {
- "16" => self.type_i16(),
- "32" => self.type_i32(),
- "64" => self.type_i64(),
+ match &self.sess().target.c_int_width {
+ 16 => self.type_i16(),
+ 32 => self.type_i32(),
+ 64 => self.type_i64(),
width => bug!("Unsupported c_int_width: {}", width),
}
}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 1dae858b7ef1a..1953eef81700b 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1649,34 +1649,7 @@ impl<'a> CrateMetadataRef<'a> {
old_name
&& let Ok(rest) = virtual_name.strip_prefix(virtual_dir)
{
- // The std library crates are in
- // `$sysroot/lib/rustlib/src/rust/library`, whereas other crates
- // may be in `$sysroot/lib/rustlib/src/rust/` directly. So we
- // detect crates from the std libs and handle them specially.
- const STD_LIBS: &[&str] = &[
- "core",
- "alloc",
- "std",
- "test",
- "term",
- "unwind",
- "proc_macro",
- "panic_abort",
- "panic_unwind",
- "profiler_builtins",
- "rtstartup",
- "rustc-std-workspace-core",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-std",
- "backtrace",
- ];
- let is_std_lib = STD_LIBS.iter().any(|l| rest.starts_with(l));
-
- let new_path = if is_std_lib {
- real_dir.join("library").join(rest)
- } else {
- real_dir.join(rest)
- };
+ let new_path = real_dir.join(rest);
debug!(
"try_to_translate_virtual_to_real: `{}` -> `{}`",
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 378cbb846379d..555ab3cdb2b6e 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -180,9 +180,14 @@ pub fn check_attribute_safety(
let diag_span = attr_item.span();
// Attributes can be safe in earlier editions, and become unsafe in later ones.
+ //
+ // Use the span of the attribute's name to determine the edition: the span of the
+ // attribute as a whole may be inaccurate if it was emitted by a macro.
+ //
+ // See https://github.com/rust-lang/rust/issues/142182.
let emit_error = match unsafe_since {
None => true,
- Some(unsafe_since) => attr.span.edition() >= unsafe_since,
+ Some(unsafe_since) => path_span.edition() >= unsafe_since,
};
if emit_error {
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 38cdfa72a14dd..58942474e3233 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -119,7 +119,7 @@ resolve_const_param_in_enum_discriminant =
const parameters may not be used in enum discriminant values
resolve_const_param_in_non_trivial_anon_const =
- const parameters may only be used as standalone arguments, i.e. `{$name}`
+ const parameters may only be used as standalone arguments here, i.e. `{$name}`
resolve_constructor_private_if_any_field_private =
a constructor is private if any of the fields is private
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 4461b4ae1250c..45936857d3383 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -743,6 +743,14 @@ crate_def! {
pub ClosureDef;
}
+impl ClosureDef {
+ /// Retrieves the body of the closure definition. Returns None if the body
+ /// isn't available.
+ pub fn body(&self) -> Option
{
+ with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
+ }
+}
+
crate_def! {
#[derive(Serialize)]
pub CoroutineDef;
diff --git a/compiler/rustc_target/src/spec/base/xtensa.rs b/compiler/rustc_target/src/spec/base/xtensa.rs
index 47a532dfdd48d..a7cc748973c42 100644
--- a/compiler/rustc_target/src/spec/base/xtensa.rs
+++ b/compiler/rustc_target/src/spec/base/xtensa.rs
@@ -6,7 +6,7 @@ pub(crate) fn opts() -> TargetOptions {
TargetOptions {
os: "none".into(),
endian: Endian::Little,
- c_int_width: "32".into(),
+ c_int_width: 32,
linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
executables: true,
panic_strategy: PanicStrategy::Abort,
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 039056a5a25a9..6c716f8712530 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -80,6 +80,12 @@ impl Target {
base.$key_name = s;
}
} );
+ ($key_name:ident = $json_name:expr, u64 as $int_ty:ty) => ( {
+ let name = $json_name;
+ if let Some(s) = obj.remove(name).and_then(|b| b.as_u64()) {
+ base.$key_name = s as $int_ty;
+ }
+ } );
($key_name:ident, bool) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
@@ -554,7 +560,7 @@ impl Target {
}
}
- key!(c_int_width = "target-c-int-width");
+ key!(c_int_width = "target-c-int-width", u64 as u16);
key!(c_enum_min_bits, Option); // if None, matches c_int_width
key!(os);
key!(env);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 6ceb5e80f2138..c360fe63a0082 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2213,18 +2213,10 @@ impl Target {
});
}
- dl.c_enum_min_size = self
- .c_enum_min_bits
- .map_or_else(
- || {
- self.c_int_width
- .parse()
- .map_err(|_| String::from("failed to parse c_int_width"))
- },
- Ok,
- )
- .and_then(|i| Integer::from_size(Size::from_bits(i)))
- .map_err(|err| TargetDataLayoutErrors::InvalidBitsSize { err })?;
+ dl.c_enum_min_size = Integer::from_size(Size::from_bits(
+ self.c_enum_min_bits.unwrap_or(self.c_int_width as _),
+ ))
+ .map_err(|err| TargetDataLayoutErrors::InvalidBitsSize { err })?;
Ok(dl)
}
@@ -2286,7 +2278,7 @@ pub struct TargetOptions {
/// Used as the `target_endian` `cfg` variable. Defaults to little endian.
pub endian: Endian,
/// Width of c_int type. Defaults to "32".
- pub c_int_width: StaticCow,
+ pub c_int_width: u16,
/// OS name to use for conditional compilation (`target_os`). Defaults to "none".
/// "none" implies a bare metal target without `std` library.
/// A couple of targets having `std` also use "unknown" as an `os` value,
@@ -2783,7 +2775,7 @@ impl Default for TargetOptions {
fn default() -> TargetOptions {
TargetOptions {
endian: Endian::Little,
- c_int_width: "32".into(),
+ c_int_width: 32,
os: "none".into(),
env: "".into(),
abi: "".into(),
diff --git a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
index 6a83835059eee..4902dc37d13cc 100644
--- a/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7_sony_vita_newlibeabihf.rs
@@ -31,7 +31,7 @@ pub(crate) fn target() -> Target {
options: TargetOptions {
os: "vita".into(),
endian: Endian::Little,
- c_int_width: "32".into(),
+ c_int_width: 32,
env: "newlib".into(),
vendor: "sony".into(),
abi: "eabihf".into(),
diff --git a/compiler/rustc_target/src/spec/targets/avr_none.rs b/compiler/rustc_target/src/spec/targets/avr_none.rs
index 91d3197d0998e..07ed2a37803fb 100644
--- a/compiler/rustc_target/src/spec/targets/avr_none.rs
+++ b/compiler/rustc_target/src/spec/targets/avr_none.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
llvm_target: "avr-unknown-unknown".into(),
pointer_width: 16,
options: TargetOptions {
- c_int_width: "16".into(),
+ c_int_width: 16,
exe_suffix: ".elf".into(),
linker: Some("avr-gcc".into()),
eh_frame_header: false,
diff --git a/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs b/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs
index b067ac1e54a1a..caf77bb8669d7 100644
--- a/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/msp430_none_elf.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
arch: "msp430".into(),
options: TargetOptions {
- c_int_width: "16".into(),
+ c_int_width: 16,
// The LLVM backend currently can't generate object files. To
// workaround this LLVM generates assembly files which then we feed
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
index c5b4d472fad31..8a6773811e882 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_espidf.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
options: TargetOptions {
endian: Endian::Little,
- c_int_width: "32".into(),
+ c_int_width: 32,
families: cvs!["unix"],
os: "espidf".into(),
env: "newlib".into(),
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
index cffdaa9072738..f38d771f2579a 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
options: TargetOptions {
endian: Endian::Little,
- c_int_width: "32".into(),
+ c_int_width: 32,
families: cvs!["unix"],
os: "espidf".into(),
env: "newlib".into(),
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
index 2e4afc005414d..4ec6e319fd4f2 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
@@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
options: TargetOptions {
endian: Endian::Little,
- c_int_width: "32".into(),
+ c_int_width: 32,
families: cvs!["unix"],
os: "espidf".into(),
env: "newlib".into(),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index fc5be11114401..0c88bd3dcbc54 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -2558,32 +2558,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
rustc_transmute::Reason::SrcIsNotYetSupported => {
format!("analyzing the transmutability of `{src}` is not yet supported")
}
-
rustc_transmute::Reason::DstIsNotYetSupported => {
format!("analyzing the transmutability of `{dst}` is not yet supported")
}
-
rustc_transmute::Reason::DstIsBitIncompatible => {
format!(
"at least one value of `{src}` isn't a bit-valid value of `{dst}`"
)
}
-
rustc_transmute::Reason::DstUninhabited => {
format!("`{dst}` is uninhabited")
}
-
rustc_transmute::Reason::DstMayHaveSafetyInvariants => {
format!("`{dst}` may carry safety invariants")
}
rustc_transmute::Reason::DstIsTooBig => {
format!("the size of `{src}` is smaller than the size of `{dst}`")
}
- rustc_transmute::Reason::DstRefIsTooBig { src, dst } => {
- let src_size = src.size;
- let dst_size = dst.size;
+ rustc_transmute::Reason::DstRefIsTooBig {
+ src,
+ src_size,
+ dst,
+ dst_size,
+ } => {
format!(
- "the referent size of `{src}` ({src_size} bytes) \
+ "the size of `{src}` ({src_size} bytes) \
is smaller than that of `{dst}` ({dst_size} bytes)"
)
}
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 7acf0f990d1b3..786afd7cf48c3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -9,13 +9,12 @@
use std::ops::ControlFlow;
-use rustc_ast::Mutability;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk};
use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
-use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, Upcast, elaborate};
+use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, Upcast, elaborate};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::DefId;
use thin_vec::thin_vec;
@@ -286,99 +285,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> Result, SelectionError<'tcx>> {
use rustc_transmute::{Answer, Assume, Condition};
- /// Generate sub-obligations for reference-to-reference transmutations.
- fn reference_obligations<'tcx>(
- tcx: TyCtxt<'tcx>,
- obligation: &PolyTraitObligation<'tcx>,
- (src_lifetime, src_ty, src_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability),
- (dst_lifetime, dst_ty, dst_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability),
- assume: Assume,
- ) -> PredicateObligations<'tcx> {
- let make_transmute_obl = |src, dst| {
- let transmute_trait = obligation.predicate.def_id();
- let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2);
- let trait_ref = ty::TraitRef::new(
- tcx,
- transmute_trait,
- [
- ty::GenericArg::from(dst),
- ty::GenericArg::from(src),
- ty::GenericArg::from(assume),
- ],
- );
- Obligation::with_depth(
- tcx,
- obligation.cause.clone(),
- obligation.recursion_depth + 1,
- obligation.param_env,
- trait_ref,
- )
- };
-
- let make_freeze_obl = |ty| {
- let trait_ref = ty::TraitRef::new(
- tcx,
- tcx.require_lang_item(LangItem::Freeze, obligation.cause.span),
- [ty::GenericArg::from(ty)],
- );
- Obligation::with_depth(
- tcx,
- obligation.cause.clone(),
- obligation.recursion_depth + 1,
- obligation.param_env,
- trait_ref,
- )
- };
-
- let make_outlives_obl = |target, region| {
- let outlives = ty::OutlivesPredicate(target, region);
- Obligation::with_depth(
- tcx,
- obligation.cause.clone(),
- obligation.recursion_depth + 1,
- obligation.param_env,
- outlives,
- )
- };
-
- // Given a transmutation from `&'a (mut) Src` and `&'dst (mut) Dst`,
- // it is always the case that `Src` must be transmutable into `Dst`,
- // and that that `'src` must outlive `'dst`.
- let mut obls = PredicateObligations::with_capacity(1);
- obls.push(make_transmute_obl(src_ty, dst_ty));
- if !assume.lifetimes {
- obls.push(make_outlives_obl(src_lifetime, dst_lifetime));
- }
-
- // Given a transmutation from `&Src`, both `Src` and `Dst` must be
- // `Freeze`, otherwise, using the transmuted value could lead to
- // data races.
- if src_mut == Mutability::Not {
- obls.extend([make_freeze_obl(src_ty), make_freeze_obl(dst_ty)])
- }
-
- // Given a transmutation into `&'dst mut Dst`, it also must be the
- // case that `Dst` is transmutable into `Src`. For example,
- // transmuting bool -> u8 is OK as long as you can't update that u8
- // to be > 1, because you could later transmute the u8 back to a
- // bool and get undefined behavior. It also must be the case that
- // `'dst` lives exactly as long as `'src`.
- if dst_mut == Mutability::Mut {
- obls.push(make_transmute_obl(dst_ty, src_ty));
- if !assume.lifetimes {
- obls.push(make_outlives_obl(dst_lifetime, src_lifetime));
- }
- }
-
- obls
- }
-
/// Flatten the `Condition` tree into a conjunction of obligations.
#[instrument(level = "debug", skip(tcx, obligation))]
fn flatten_answer_tree<'tcx>(
tcx: TyCtxt<'tcx>,
obligation: &PolyTraitObligation<'tcx>,
- cond: Condition>,
+ cond: Condition, Ty<'tcx>>,
assume: Assume,
) -> PredicateObligations<'tcx> {
match cond {
@@ -388,13 +300,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.into_iter()
.flat_map(|cond| flatten_answer_tree(tcx, obligation, cond, assume))
.collect(),
- Condition::IfTransmutable { src, dst } => reference_obligations(
- tcx,
- obligation,
- (src.lifetime, src.ty, src.mutability),
- (dst.lifetime, dst.ty, dst.mutability),
- assume,
- ),
+ Condition::Immutable { ty } => {
+ let trait_ref = ty::TraitRef::new(
+ tcx,
+ tcx.require_lang_item(LangItem::Freeze, obligation.cause.span),
+ [ty::GenericArg::from(ty)],
+ );
+ thin_vec![Obligation::with_depth(
+ tcx,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ obligation.param_env,
+ trait_ref,
+ )]
+ }
+ Condition::Outlives { long, short } => {
+ let outlives = ty::OutlivesPredicate(long, short);
+ thin_vec![Obligation::with_depth(
+ tcx,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ obligation.param_env,
+ outlives,
+ )]
+ }
+ Condition::Transmutable { src, dst } => {
+ let transmute_trait = obligation.predicate.def_id();
+ let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2);
+ let trait_ref = ty::TraitRef::new(
+ tcx,
+ transmute_trait,
+ [
+ ty::GenericArg::from(dst),
+ ty::GenericArg::from(src),
+ ty::GenericArg::from(assume),
+ ],
+ );
+ thin_vec![Obligation::with_depth(
+ tcx,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ obligation.param_env,
+ trait_ref,
+ )]
+ }
}
}
diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs
index 6d072c336af23..6fc40ce42d88c 100644
--- a/compiler/rustc_transmute/src/layout/dfa.rs
+++ b/compiler/rustc_transmute/src/layout/dfa.rs
@@ -2,32 +2,35 @@ use std::fmt;
use std::iter::Peekable;
use std::sync::atomic::{AtomicU32, Ordering};
-use super::{Byte, Ref, Tree, Uninhabited};
+use super::{Byte, Reference, Region, Tree, Type, Uninhabited};
use crate::{Map, Set};
#[derive(PartialEq)]
#[cfg_attr(test, derive(Clone))]
-pub(crate) struct Dfa
+pub(crate) struct Dfa
where
- R: Ref,
+ R: Region,
+ T: Type,
{
- pub(crate) transitions: Map>,
+ pub(crate) transitions: Map>,
pub(crate) start: State,
pub(crate) accept: State,
}
#[derive(PartialEq, Clone, Debug)]
-pub(crate) struct Transitions
+pub(crate) struct Transitions
where
- R: Ref,
+ R: Region,
+ T: Type,
{
byte_transitions: EdgeSet,
- ref_transitions: Map,
+ ref_transitions: Map, State>,
}
-impl Default for Transitions
+impl Default for Transitions
where
- R: Ref,
+ R: Region,
+ T: Type,
{
fn default() -> Self {
Self { byte_transitions: EdgeSet::empty(), ref_transitions: Map::default() }
@@ -51,9 +54,10 @@ impl fmt::Debug for State {
}
}
-impl Dfa
+impl Dfa
where
- R: Ref,
+ R: Region,
+ T: Type,
{
#[cfg(test)]
pub(crate) fn bool() -> Self {
@@ -64,7 +68,7 @@ where
}
pub(crate) fn unit() -> Self {
- let transitions: Map> = Map::default();
+ let transitions: Map> = Map::default();
let start = State::new();
let accept = start;
@@ -78,21 +82,21 @@ where
})
}
- pub(crate) fn from_ref(r: R) -> Self {
+ pub(crate) fn from_ref(r: Reference) -> Self {
Self::from_transitions(|accept| Transitions {
byte_transitions: EdgeSet::empty(),
ref_transitions: [(r, accept)].into_iter().collect(),
})
}
- fn from_transitions(f: impl FnOnce(State) -> Transitions) -> Self {
+ fn from_transitions(f: impl FnOnce(State) -> Transitions) -> Self {
let start = State::new();
let accept = State::new();
Self { transitions: [(start, f(accept))].into_iter().collect(), start, accept }
}
- pub(crate) fn from_tree(tree: Tree) -> Result {
+ pub(crate) fn from_tree(tree: Tree) -> Result {
Ok(match tree {
Tree::Byte(b) => Self::from_byte(b),
Tree::Ref(r) => Self::from_ref(r),
@@ -125,7 +129,7 @@ where
let start = self.start;
let accept = other.accept;
- let mut transitions: Map> = self.transitions;
+ let mut transitions: Map> = self.transitions;
for (source, transition) in other.transitions {
let fix_state = |state| if state == other.start { self.accept } else { state };
@@ -169,7 +173,7 @@ where
};
let start = mapped((Some(a.start), Some(b.start)));
- let mut transitions: Map> = Map::default();
+ let mut transitions: Map> = Map::default();
let empty_transitions = Transitions::default();
struct WorkQueue {
@@ -257,7 +261,7 @@ where
.flat_map(|transitions| transitions.byte_transitions.iter())
}
- pub(crate) fn refs_from(&self, start: State) -> impl Iterator {
+ pub(crate) fn refs_from(&self, start: State) -> impl Iterator, State)> {
self.transitions
.get(&start)
.into_iter()
@@ -297,9 +301,10 @@ where
}
/// Serialize the DFA using the Graphviz DOT format.
-impl fmt::Debug for Dfa
+impl fmt::Debug for Dfa
where
- R: Ref,
+ R: Region,
+ T: Type,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "digraph {{")?;
diff --git a/compiler/rustc_transmute/src/layout/mod.rs b/compiler/rustc_transmute/src/layout/mod.rs
index c08bf440734e2..acbce258f39be 100644
--- a/compiler/rustc_transmute/src/layout/mod.rs
+++ b/compiler/rustc_transmute/src/layout/mod.rs
@@ -78,16 +78,41 @@ impl From for Byte {
}
}
+/// A reference, i.e., `&'region T` or `&'region mut T`.
+#[derive(Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)]
+pub(crate) struct Reference
+where
+ R: Region,
+ T: Type,
+{
+ pub(crate) region: R,
+ pub(crate) is_mut: bool,
+ pub(crate) referent: T,
+ pub(crate) referent_size: usize,
+ pub(crate) referent_align: usize,
+}
+
+impl fmt::Display for Reference
+where
+ R: Region,
+ T: Type,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("&")?;
+ if self.is_mut {
+ f.write_str("mut ")?;
+ }
+ self.referent.fmt(f)
+ }
+}
+
pub(crate) trait Def: Debug + Hash + Eq + PartialEq + Copy + Clone {
fn has_safety_invariants(&self) -> bool;
}
-pub trait Ref: Debug + Hash + Eq + PartialEq + Copy + Clone {
- fn min_align(&self) -> usize;
- fn size(&self) -> usize;
+pub(crate) trait Region: Debug + Hash + Eq + PartialEq + Copy + Clone {}
- fn is_mutable(&self) -> bool;
-}
+pub(crate) trait Type: Debug + Hash + Eq + PartialEq + Copy + Clone {}
impl Def for ! {
fn has_safety_invariants(&self) -> bool {
@@ -95,79 +120,21 @@ impl Def for ! {
}
}
-impl Ref for ! {
- fn min_align(&self) -> usize {
- unreachable!()
- }
- fn size(&self) -> usize {
- unreachable!()
- }
- fn is_mutable(&self) -> bool {
- unreachable!()
- }
-}
+impl Region for ! {}
-#[cfg(test)]
-impl Ref for [(); N] {
- fn min_align(&self) -> usize {
- N
- }
+impl Type for ! {}
- fn size(&self) -> usize {
- N
- }
+#[cfg(test)]
+impl Region for usize {}
- fn is_mutable(&self) -> bool {
- false
- }
-}
+#[cfg(test)]
+impl Type for () {}
#[cfg(feature = "rustc")]
pub mod rustc {
- use std::fmt::{self, Write};
-
use rustc_abi::Layout;
- use rustc_middle::mir::Mutability;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, LayoutError};
- use rustc_middle::ty::{self, Ty};
-
- /// A reference in the layout.
- #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
- pub struct Ref<'tcx> {
- pub lifetime: ty::Region<'tcx>,
- pub ty: Ty<'tcx>,
- pub mutability: Mutability,
- pub align: usize,
- pub size: usize,
- }
-
- impl<'tcx> super::Ref for Ref<'tcx> {
- fn min_align(&self) -> usize {
- self.align
- }
-
- fn size(&self) -> usize {
- self.size
- }
-
- fn is_mutable(&self) -> bool {
- match self.mutability {
- Mutability::Mut => true,
- Mutability::Not => false,
- }
- }
- }
- impl<'tcx> Ref<'tcx> {}
-
- impl<'tcx> fmt::Display for Ref<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_char('&')?;
- if self.mutability == Mutability::Mut {
- f.write_str("mut ")?;
- }
- self.ty.fmt(f)
- }
- }
+ use rustc_middle::ty::{self, Region, Ty};
/// A visibility node in the layout.
#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)]
@@ -187,6 +154,10 @@ pub mod rustc {
}
}
+ impl<'tcx> super::Region for Region<'tcx> {}
+
+ impl<'tcx> super::Type for Ty<'tcx> {}
+
pub(crate) fn layout_of<'tcx>(
cx: LayoutCx<'tcx>,
ty: Ty<'tcx>,
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index ff665695b5a36..372b4f5353abb 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -1,6 +1,6 @@
use std::ops::{ControlFlow, RangeInclusive};
-use super::{Byte, Def, Ref};
+use super::{Byte, Def, Reference, Region, Type};
#[cfg(test)]
mod tests;
@@ -15,10 +15,11 @@ mod tests;
/// 2. A `Seq` is never directly nested beneath another `Seq`.
/// 3. `Seq`s and `Alt`s with a single member do not exist.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
-pub(crate) enum Tree
+pub(crate) enum Tree
where
D: Def,
- R: Ref,
+ R: Region,
+ T: Type,
{
/// A sequence of successive layouts.
Seq(Vec),
@@ -27,7 +28,7 @@ where
/// A definition node.
Def(D),
/// A reference node.
- Ref(R),
+ Ref(Reference),
/// A byte node.
Byte(Byte),
}
@@ -48,10 +49,11 @@ impl From for Endian {
}
}
-impl Tree
+impl Tree
where
D: Def,
- R: Ref,
+ R: Region,
+ T: Type,
{
/// A `Tree` consisting only of a definition node.
pub(crate) fn def(def: D) -> Self {
@@ -138,7 +140,7 @@ where
/// Remove all `Def` nodes, and all branches of the layout for which `f`
/// produces `true`.
- pub(crate) fn prune(self, f: &F) -> Tree
+ pub(crate) fn prune(self, f: &F) -> Tree
where
F: Fn(D) -> bool,
{
@@ -198,13 +200,13 @@ where
/// Produces a `Tree` where each of the trees in `trees` are sequenced one
/// after another.
- pub(crate) fn seq(trees: [Tree; N]) -> Self {
+ pub(crate) fn seq(trees: [Tree; N]) -> Self {
trees.into_iter().fold(Tree::unit(), Self::then)
}
/// Produces a `Tree` where each of the trees in `trees` are accepted as
/// alternative layouts.
- pub(crate) fn alt(trees: [Tree; N]) -> Self {
+ pub(crate) fn alt(trees: [Tree; N]) -> Self {
trees.into_iter().fold(Tree::uninhabited(), Self::or)
}
@@ -251,11 +253,14 @@ pub(crate) mod rustc {
FieldIdx, FieldsShape, Layout, Size, TagEncoding, TyAndLayout, VariantIdx, Variants,
};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, LayoutError};
- use rustc_middle::ty::{self, AdtDef, AdtKind, List, ScalarInt, Ty, TyCtxt, TypeVisitableExt};
+ use rustc_middle::ty::{
+ self, AdtDef, AdtKind, List, Region, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
+ };
use rustc_span::ErrorGuaranteed;
use super::Tree;
- use crate::layout::rustc::{Def, Ref, layout_of};
+ use crate::layout::Reference;
+ use crate::layout::rustc::{Def, layout_of};
#[derive(Debug, Copy, Clone)]
pub(crate) enum Err {
@@ -281,7 +286,7 @@ pub(crate) mod rustc {
}
}
- impl<'tcx> Tree, Ref<'tcx>> {
+ impl<'tcx> Tree, Region<'tcx>, Ty<'tcx>> {
pub(crate) fn from_ty(ty: Ty<'tcx>, cx: LayoutCx<'tcx>) -> Result {
use rustc_abi::HasDataLayout;
let layout = layout_of(cx, ty)?;
@@ -353,16 +358,17 @@ pub(crate) mod rustc {
}
}
- ty::Ref(lifetime, ty, mutability) => {
+ ty::Ref(region, ty, mutability) => {
let layout = layout_of(cx, *ty)?;
- let align = layout.align.abi.bytes_usize();
- let size = layout.size.bytes_usize();
- Ok(Tree::Ref(Ref {
- lifetime: *lifetime,
- ty: *ty,
- mutability: *mutability,
- align,
- size,
+ let referent_align = layout.align.abi.bytes_usize();
+ let referent_size = layout.size.bytes_usize();
+
+ Ok(Tree::Ref(Reference {
+ region: *region,
+ is_mut: mutability.is_mut(),
+ referent: *ty,
+ referent_align,
+ referent_size,
}))
}
diff --git a/compiler/rustc_transmute/src/layout/tree/tests.rs b/compiler/rustc_transmute/src/layout/tree/tests.rs
index 8c3dbbe37ab21..bc47b19c681f4 100644
--- a/compiler/rustc_transmute/src/layout/tree/tests.rs
+++ b/compiler/rustc_transmute/src/layout/tree/tests.rs
@@ -20,13 +20,13 @@ mod prune {
#[test]
fn seq_1() {
- let layout: Tree = Tree::def(Def::NoSafetyInvariants).then(Tree::byte(0x00));
+ let layout: Tree = Tree::def(Def::NoSafetyInvariants).then(Tree::byte(0x00));
assert_eq!(layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)), Tree::byte(0x00));
}
#[test]
fn seq_2() {
- let layout: Tree =
+ let layout: Tree =
Tree::byte(0x00).then(Tree::def(Def::NoSafetyInvariants)).then(Tree::byte(0x01));
assert_eq!(
@@ -41,7 +41,7 @@ mod prune {
#[test]
fn invisible_def() {
- let layout: Tree = Tree::def(Def::HasSafetyInvariants);
+ let layout: Tree = Tree::def(Def::HasSafetyInvariants);
assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
Tree::uninhabited()
@@ -50,7 +50,7 @@ mod prune {
#[test]
fn invisible_def_in_seq_len_2() {
- let layout: Tree =
+ let layout: Tree =
Tree::def(Def::NoSafetyInvariants).then(Tree::def(Def::HasSafetyInvariants));
assert_eq!(
layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)),
@@ -60,7 +60,7 @@ mod prune {
#[test]
fn invisible_def_in_seq_len_3() {
- let layout: Tree = Tree::def(Def::NoSafetyInvariants)
+ let layout: Tree = Tree::def(Def::NoSafetyInvariants)
.then(Tree::byte(0x00))
.then(Tree::def(Def::HasSafetyInvariants));
assert_eq!(
@@ -75,20 +75,20 @@ mod prune {
#[test]
fn visible_def() {
- let layout: Tree = Tree::def(Def::NoSafetyInvariants);
+ let layout: Tree = Tree::def(Def::NoSafetyInvariants);
assert_eq!(layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)), Tree::unit());
}
#[test]
fn visible_def_in_seq_len_2() {
- let layout: Tree =
+ let layout: Tree =
Tree::def(Def::NoSafetyInvariants).then(Tree::def(Def::NoSafetyInvariants));
assert_eq!(layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)), Tree::unit());
}
#[test]
fn visible_def_in_seq_len_3() {
- let layout: Tree = Tree::def(Def::NoSafetyInvariants)
+ let layout: Tree = Tree::def(Def::NoSafetyInvariants)
.then(Tree::byte(0x00))
.then(Tree::def(Def::NoSafetyInvariants));
assert_eq!(layout.prune(&|d| matches!(d, Def::HasSafetyInvariants)), Tree::byte(0x00));
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index ce18dad55179c..36281ff16bceb 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -19,23 +19,29 @@ pub struct Assume {
/// Either transmutation is allowed, we have an error, or we have an optional
/// Condition that must hold.
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
-pub enum Answer {
+pub enum Answer {
Yes,
- No(Reason),
- If(Condition),
+ No(Reason),
+ If(Condition),
}
/// A condition which must hold for safe transmutation to be possible.
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
-pub enum Condition {
+pub enum Condition {
/// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`.
- IfTransmutable { src: R, dst: R },
+ Transmutable { src: T, dst: T },
+
+ /// The region `long` must outlive `short`.
+ Outlives { long: R, short: R },
+
+ /// The `ty` is immutable.
+ Immutable { ty: T },
/// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met.
- IfAll(Vec>),
+ IfAll(Vec>),
/// `Src` is transmutable into `Dst` if any of the enclosed requirements are met.
- IfAny(Vec>),
+ IfAny(Vec>),
}
/// Answers "why wasn't the source type transmutable into the destination type?"
@@ -53,12 +59,16 @@ pub enum Reason {
DstMayHaveSafetyInvariants,
/// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
DstIsTooBig,
- /// A referent of `Dst` is larger than a referent in `Src`.
+ /// `Dst` is larger `Src`.
DstRefIsTooBig {
/// The referent of the source type.
src: T,
+ /// The size of the source type's referent.
+ src_size: usize,
/// The too-large referent of the destination type.
dst: T,
+ /// The size of the destination type's referent.
+ dst_size: usize,
},
/// Src should have a stricter alignment than Dst, but it does not.
DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize },
@@ -79,7 +89,7 @@ pub enum Reason {
#[cfg(feature = "rustc")]
mod rustc {
use rustc_hir::lang_items::LangItem;
- use rustc_middle::ty::{Const, Ty, TyCtxt};
+ use rustc_middle::ty::{Const, Region, Ty, TyCtxt};
use super::*;
@@ -105,7 +115,7 @@ mod rustc {
&mut self,
types: Types<'tcx>,
assume: crate::Assume,
- ) -> crate::Answer> {
+ ) -> crate::Answer, Ty<'tcx>> {
crate::maybe_transmutable::MaybeTransmutableQuery::new(
types.src, types.dst, assume, self.tcx,
)
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
index f76abe50ed343..062de4b5d08a7 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs
@@ -5,7 +5,7 @@ pub(crate) mod query_context;
#[cfg(test)]
mod tests;
-use crate::layout::{self, Def, Dfa, Ref, Tree, dfa, union};
+use crate::layout::{self, Def, Dfa, Reference, Tree, dfa, union};
use crate::maybe_transmutable::query_context::QueryContext;
use crate::{Answer, Condition, Map, Reason};
@@ -41,7 +41,10 @@ mod rustc {
/// This method begins by converting `src` and `dst` from `Ty`s to `Tree`s,
/// then computes an answer using those trees.
#[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))]
- pub(crate) fn answer(self) -> Answer< as QueryContext>::Ref> {
+ pub(crate) fn answer(
+ self,
+ ) -> Answer< as QueryContext>::Region, as QueryContext>::Type>
+ {
let Self { src, dst, assume, context } = self;
let layout_cx = LayoutCx::new(context, TypingEnv::fully_monomorphized());
@@ -67,7 +70,11 @@ mod rustc {
}
}
-impl MaybeTransmutableQuery::Def, ::Ref>, C>
+impl
+ MaybeTransmutableQuery<
+ Tree<::Def, ::Region, ::Type>,
+ C,
+ >
where
C: QueryContext,
{
@@ -77,7 +84,7 @@ where
/// then converts `src` and `dst` to `Dfa`s, and computes an answer using those DFAs.
#[inline(always)]
#[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))]
- pub(crate) fn answer(self) -> Answer<::Ref> {
+ pub(crate) fn answer(self) -> Answer<::Region, ::Type> {
let Self { src, dst, assume, context } = self;
// Unconditionally remove all `Def` nodes from `src`, without pruning away the
@@ -130,12 +137,12 @@ where
}
}
-impl MaybeTransmutableQuery::Ref>, C>
+impl MaybeTransmutableQuery::Region, ::Type>, C>
where
C: QueryContext,
{
/// Answers whether a `Dfa` is transmutable into another `Dfa`.
- pub(crate) fn answer(self) -> Answer<::Ref> {
+ pub(crate) fn answer(self) -> Answer<::Region, ::Type> {
self.answer_memo(&mut Map::default(), self.src.start, self.dst.start)
}
@@ -143,10 +150,13 @@ where
#[instrument(level = "debug", skip(self))]
fn answer_memo(
&self,
- cache: &mut Map<(dfa::State, dfa::State), Answer<::Ref>>,
+ cache: &mut Map<
+ (dfa::State, dfa::State),
+ Answer<::Region, ::Type>,
+ >,
src_state: dfa::State,
dst_state: dfa::State,
- ) -> Answer<::Ref> {
+ ) -> Answer<::Region, ::Type> {
if let Some(answer) = cache.get(&(src_state, dst_state)) {
answer.clone()
} else {
@@ -160,10 +170,13 @@ where
fn answer_impl(
&self,
- cache: &mut Map<(dfa::State, dfa::State), Answer<::Ref>>,
+ cache: &mut Map<
+ (dfa::State, dfa::State),
+ Answer<::Region, ::Type>,
+ >,
src_state: dfa::State,
dst_state: dfa::State,
- ) -> Answer<::Ref> {
+ ) -> Answer<::Region, ::Type> {
debug!(?src_state, ?dst_state);
debug!(src = ?self.src);
debug!(dst = ?self.dst);
@@ -247,27 +260,51 @@ where
// ...there exists a reference transition out of `dst_state`...
Quantifier::ThereExists.apply(self.dst.refs_from(dst_state).map(
|(dst_ref, dst_state_prime)| {
- if !src_ref.is_mutable() && dst_ref.is_mutable() {
+ if !src_ref.is_mut && dst_ref.is_mut {
Answer::No(Reason::DstIsMoreUnique)
} else if !self.assume.alignment
- && src_ref.min_align() < dst_ref.min_align()
+ && src_ref.referent_align < dst_ref.referent_align
{
Answer::No(Reason::DstHasStricterAlignment {
- src_min_align: src_ref.min_align(),
- dst_min_align: dst_ref.min_align(),
+ src_min_align: src_ref.referent_align,
+ dst_min_align: dst_ref.referent_align,
+ })
+ } else if dst_ref.referent_size > src_ref.referent_size {
+ Answer::No(Reason::DstRefIsTooBig {
+ src: src_ref.referent,
+ src_size: src_ref.referent_size,
+ dst: dst_ref.referent,
+ dst_size: dst_ref.referent_size,
})
- } else if dst_ref.size() > src_ref.size() {
- Answer::No(Reason::DstRefIsTooBig { src: src_ref, dst: dst_ref })
} else {
- // ...such that `src` is transmutable into `dst`, if
- // `src_ref` is transmutability into `dst_ref`.
- and(
- Answer::If(Condition::IfTransmutable {
- src: src_ref,
- dst: dst_ref,
- }),
- self.answer_memo(cache, src_state_prime, dst_state_prime),
- )
+ let mut conditions = Vec::with_capacity(4);
+ let mut is_transmutable =
+ |src: Reference<_, _>, dst: Reference<_, _>| {
+ conditions.push(Condition::Transmutable {
+ src: src.referent,
+ dst: dst.referent,
+ });
+ if !self.assume.lifetimes {
+ conditions.push(Condition::Outlives {
+ long: src.region,
+ short: dst.region,
+ });
+ }
+ };
+
+ is_transmutable(src_ref, dst_ref);
+
+ if dst_ref.is_mut {
+ is_transmutable(dst_ref, src_ref);
+ } else {
+ conditions.push(Condition::Immutable { ty: dst_ref.referent });
+ }
+
+ Answer::If(Condition::IfAll(conditions)).and(self.answer_memo(
+ cache,
+ src_state_prime,
+ dst_state_prime,
+ ))
}
},
))
@@ -275,67 +312,65 @@ where
);
if self.assume.validity {
- or(bytes_answer, refs_answer)
+ bytes_answer.or(refs_answer)
} else {
- and(bytes_answer, refs_answer)
+ bytes_answer.and(refs_answer)
}
}
}
}
-fn and(lhs: Answer, rhs: Answer) -> Answer
-where
- R: PartialEq,
-{
- match (lhs, rhs) {
- // If both are errors, then we should return the more specific one
- (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason))
- | (Answer::No(reason), Answer::No(_))
- // If either is an error, return it
- | (Answer::No(reason), _) | (_, Answer::No(reason)) => Answer::No(reason),
- // If only one side has a condition, pass it along
- | (Answer::Yes, other) | (other, Answer::Yes) => other,
- // If both sides have IfAll conditions, merge them
- (Answer::If(Condition::IfAll(mut lhs)), Answer::If(Condition::IfAll(ref mut rhs))) => {
- lhs.append(rhs);
- Answer::If(Condition::IfAll(lhs))
- }
- // If only one side is an IfAll, add the other Condition to it
- (Answer::If(cond), Answer::If(Condition::IfAll(mut conds)))
- | (Answer::If(Condition::IfAll(mut conds)), Answer::If(cond)) => {
- conds.push(cond);
- Answer::If(Condition::IfAll(conds))
+impl Answer {
+ fn and(self, rhs: Answer) -> Answer {
+ let lhs = self;
+ match (lhs, rhs) {
+ // If both are errors, then we should return the more specific one
+ (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason))
+ | (Answer::No(reason), Answer::No(_))
+ // If either is an error, return it
+ | (Answer::No(reason), _) | (_, Answer::No(reason)) => Answer::No(reason),
+ // If only one side has a condition, pass it along
+ | (Answer::Yes, other) | (other, Answer::Yes) => other,
+ // If both sides have IfAll conditions, merge them
+ (Answer::If(Condition::IfAll(mut lhs)), Answer::If(Condition::IfAll(ref mut rhs))) => {
+ lhs.append(rhs);
+ Answer::If(Condition::IfAll(lhs))
+ }
+ // If only one side is an IfAll, add the other Condition to it
+ (Answer::If(cond), Answer::If(Condition::IfAll(mut conds)))
+ | (Answer::If(Condition::IfAll(mut conds)), Answer::If(cond)) => {
+ conds.push(cond);
+ Answer::If(Condition::IfAll(conds))
+ }
+ // Otherwise, both lhs and rhs conditions can be combined in a parent IfAll
+ (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAll(vec![lhs, rhs])),
}
- // Otherwise, both lhs and rhs conditions can be combined in a parent IfAll
- (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAll(vec![lhs, rhs])),
}
-}
-fn or(lhs: Answer, rhs: Answer) -> Answer
-where
- R: PartialEq,
-{
- match (lhs, rhs) {
- // If both are errors, then we should return the more specific one
- (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason))
- | (Answer::No(reason), Answer::No(_)) => Answer::No(reason),
- // Otherwise, errors can be ignored for the rest of the pattern matching
- (Answer::No(_), other) | (other, Answer::No(_)) => or(other, Answer::Yes),
- // If only one side has a condition, pass it along
- (Answer::Yes, other) | (other, Answer::Yes) => other,
- // If both sides have IfAny conditions, merge them
- (Answer::If(Condition::IfAny(mut lhs)), Answer::If(Condition::IfAny(ref mut rhs))) => {
- lhs.append(rhs);
- Answer::If(Condition::IfAny(lhs))
- }
- // If only one side is an IfAny, add the other Condition to it
- (Answer::If(cond), Answer::If(Condition::IfAny(mut conds)))
- | (Answer::If(Condition::IfAny(mut conds)), Answer::If(cond)) => {
- conds.push(cond);
- Answer::If(Condition::IfAny(conds))
+ fn or(self, rhs: Answer) -> Answer {
+ let lhs = self;
+ match (lhs, rhs) {
+ // If both are errors, then we should return the more specific one
+ (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason))
+ | (Answer::No(reason), Answer::No(_)) => Answer::No(reason),
+ // Otherwise, errors can be ignored for the rest of the pattern matching
+ (Answer::No(_), other) | (other, Answer::No(_)) => other.or(Answer::Yes),
+ // If only one side has a condition, pass it along
+ (Answer::Yes, other) | (other, Answer::Yes) => other,
+ // If both sides have IfAny conditions, merge them
+ (Answer::If(Condition::IfAny(mut lhs)), Answer::If(Condition::IfAny(ref mut rhs))) => {
+ lhs.append(rhs);
+ Answer::If(Condition::IfAny(lhs))
+ }
+ // If only one side is an IfAny, add the other Condition to it
+ (Answer::If(cond), Answer::If(Condition::IfAny(mut conds)))
+ | (Answer::If(Condition::IfAny(mut conds)), Answer::If(cond)) => {
+ conds.push(cond);
+ Answer::If(Condition::IfAny(conds))
+ }
+ // Otherwise, both lhs and rhs conditions can be combined in a parent IfAny
+ (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAny(vec![lhs, rhs])),
}
- // Otherwise, both lhs and rhs conditions can be combined in a parent IfAny
- (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAny(vec![lhs, rhs])),
}
}
@@ -345,24 +380,25 @@ enum Quantifier {
}
impl Quantifier {
- fn apply(&self, iter: I) -> Answer
+ fn apply(&self, iter: I) -> Answer
where
- R: layout::Ref,
- I: IntoIterator>,
+ R: layout::Region,
+ T: layout::Type,
+ I: IntoIterator>,
{
use std::ops::ControlFlow::{Break, Continue};
let (init, try_fold_f): (_, fn(_, _) -> _) = match self {
Self::ThereExists => {
- (Answer::No(Reason::DstIsBitIncompatible), |accum: Answer, next| {
- match or(accum, next) {
- Answer::Yes => Break(Answer::Yes),
- maybe => Continue(maybe),
- }
+ (Answer::No(Reason::DstIsBitIncompatible), |accum: Answer, next| match accum
+ .or(next)
+ {
+ Answer::Yes => Break(Answer::Yes),
+ maybe => Continue(maybe),
})
}
- Self::ForAll => (Answer::Yes, |accum: Answer, next| {
- let answer = and(accum, next);
+ Self::ForAll => (Answer::Yes, |accum: Answer, next| {
+ let answer = accum.and(next);
match answer {
Answer::No(_) => Break(answer),
maybe => Continue(maybe),
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
index 214da101be375..6be0cb1190436 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs
@@ -3,7 +3,8 @@ use crate::layout;
/// Context necessary to answer the question "Are these types transmutable?".
pub(crate) trait QueryContext {
type Def: layout::Def;
- type Ref: layout::Ref;
+ type Region: layout::Region;
+ type Type: layout::Type;
}
#[cfg(test)]
@@ -12,9 +13,9 @@ pub(crate) mod test {
use super::QueryContext;
- pub(crate) struct UltraMinimal(PhantomData);
+ pub(crate) struct UltraMinimal(PhantomData<(R, T)>);
- impl Default for UltraMinimal {
+ impl Default for UltraMinimal {
fn default() -> Self {
Self(PhantomData)
}
@@ -32,20 +33,26 @@ pub(crate) mod test {
}
}
- impl QueryContext for UltraMinimal {
+ impl QueryContext for UltraMinimal
+ where
+ R: crate::layout::Region,
+ T: crate::layout::Type,
+ {
type Def = Def;
- type Ref = R;
+ type Region = R;
+ type Type = T;
}
}
#[cfg(feature = "rustc")]
mod rustc {
- use rustc_middle::ty::TyCtxt;
+ use rustc_middle::ty::{Region, Ty, TyCtxt};
use super::*;
impl<'tcx> super::QueryContext for TyCtxt<'tcx> {
type Def = layout::rustc::Def<'tcx>;
- type Ref = layout::rustc::Ref<'tcx>;
+ type Region = Region<'tcx>;
+ type Type = Ty<'tcx>;
}
}
diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
index 0227ad71ae660..8440ace260883 100644
--- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
+++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs
@@ -3,17 +3,17 @@ extern crate test;
use itertools::Itertools;
use super::query_context::test::{Def, UltraMinimal};
-use crate::{Answer, Assume, Reason, layout};
+use crate::{Answer, Assume, Condition, Reason, layout};
-type Tree = layout::Tree;
-type Dfa = layout::Dfa;
+type Tree = layout::Tree;
+type Dfa = layout::Dfa;
trait Representation {
- fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer;
+ fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer;
}
impl Representation for Tree {
- fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer {
+ fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer {
crate::maybe_transmutable::MaybeTransmutableQuery::new(
src,
dst,
@@ -25,7 +25,7 @@ impl Representation for Tree {
}
impl Representation for Dfa {
- fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer {
+ fn is_transmutable(src: Self, dst: Self, assume: Assume) -> Answer {
crate::maybe_transmutable::MaybeTransmutableQuery::new(
src,
dst,
@@ -40,7 +40,7 @@ fn is_transmutable(
src: &R,
dst: &R,
assume: Assume,
-) -> crate::Answer {
+) -> crate::Answer {
let src = src.clone();
let dst = dst.clone();
// The only dimension of the transmutability analysis we want to test
@@ -53,7 +53,7 @@ mod safety {
use super::*;
use crate::Answer;
- const DST_HAS_SAFETY_INVARIANTS: Answer =
+ const DST_HAS_SAFETY_INVARIANTS: Answer =
Answer::No(crate::Reason::DstMayHaveSafetyInvariants);
#[test]
@@ -177,14 +177,15 @@ mod bool {
#[test]
fn should_permit_validity_expansion_and_reject_contraction() {
- let b0 = layout::Tree::::byte(0);
- let b1 = layout::Tree::::byte(1);
- let b2 = layout::Tree::::byte(2);
+ let b0 = layout::Tree::::byte(0);
+ let b1 = layout::Tree::::byte(1);
+ let b2 = layout::Tree::::byte(2);
let alts = [b0, b1, b2];
let into_layout = |alts: Vec<_>| {
- alts.into_iter().fold(layout::Tree::::uninhabited(), layout::Tree::::or)
+ alts.into_iter()
+ .fold(layout::Tree::::uninhabited(), layout::Tree::::or)
};
let into_set = |alts: Vec<_>| {
@@ -277,7 +278,7 @@ mod alt {
#[test]
fn should_permit_identity_transmutation() {
- type Tree = layout::Tree;
+ type Tree = layout::Tree;
let x = Tree::Seq(vec![Tree::byte(0), Tree::byte(0)]);
let y = Tree::Seq(vec![Tree::bool(), Tree::byte(1)]);
@@ -331,7 +332,7 @@ mod char {
fn should_permit_valid_transmutation() {
for order in [Endian::Big, Endian::Little] {
use Answer::*;
- let char_layout = layout::Tree::::char(order);
+ let char_layout = layout::Tree::::char(order);
// `char`s can be in the following ranges:
// - [0, 0xD7FF]
@@ -353,7 +354,7 @@ mod char {
(0xFFFFFFFF, no),
] {
let src_layout =
- layout::tree::Tree::::from_big_endian(order, src.to_be_bytes());
+ layout::tree::Tree::::from_big_endian(order, src.to_be_bytes());
let a = is_transmutable(&src_layout, &char_layout, Assume::default());
assert_eq!(a, answer, "endian:{order:?},\nsrc:{src:x}");
@@ -371,7 +372,7 @@ mod nonzero {
#[test]
fn should_permit_identity_transmutation() {
for width in NONZERO_BYTE_WIDTHS {
- let layout = layout::Tree::::nonzero(width);
+ let layout = layout::Tree::::nonzero(width);
assert_eq!(is_transmutable(&layout, &layout, Assume::default()), Answer::Yes);
}
}
@@ -381,8 +382,8 @@ mod nonzero {
for width in NONZERO_BYTE_WIDTHS {
use Answer::*;
- let num = layout::Tree::::number(width);
- let nz = layout::Tree::::nonzero(width);
+ let num = layout::Tree::::number(width);
+ let nz = layout::Tree::::nonzero(width);
let a = is_transmutable(&num, &nz, Assume::default());
assert_eq!(a, No(Reason::DstIsBitIncompatible), "width:{width}");
@@ -395,13 +396,23 @@ mod nonzero {
mod r#ref {
use super::*;
+ use crate::layout::Reference;
#[test]
fn should_permit_identity_transmutation() {
- type Tree = crate::layout::Tree;
+ type Tree = crate::layout::Tree;
for validity in [false, true] {
- let layout = Tree::Seq(vec![Tree::byte(0x00), Tree::Ref([()])]);
+ let layout = Tree::Seq(vec![
+ Tree::byte(0x00),
+ Tree::Ref(Reference {
+ region: 42,
+ is_mut: false,
+ referent: (),
+ referent_size: 0,
+ referent_align: 1,
+ }),
+ ]);
let assume = Assume { validity, ..Assume::default() };
@@ -414,7 +425,11 @@ mod r#ref {
.answer();
assert_eq!(
answer,
- Answer::If(crate::Condition::IfTransmutable { src: [()], dst: [()] })
+ Answer::If(Condition::IfAll(vec![
+ Condition::Transmutable { src: (), dst: () },
+ Condition::Outlives { long: 42, short: 42 },
+ Condition::Immutable { ty: () },
+ ]))
);
}
}
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index 911a51b0e161b..f47873590a17b 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -89,7 +89,7 @@ impl Step for Std {
let stage = self.custom_stage.unwrap_or(builder.top_stage);
let target = self.target;
- let compiler = builder.compiler(stage, builder.config.build);
+ let compiler = builder.compiler(stage, builder.config.host_target);
if stage == 0 {
let mut is_explicitly_called =
@@ -244,7 +244,7 @@ impl Step for Rustc {
/// the `compiler` targeting the `target` architecture. The artifacts
/// created will also be linked into the sysroot directory.
fn run(self, builder: &Builder<'_>) {
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
let target = self.target;
if compiler.stage != 0 {
@@ -327,7 +327,7 @@ impl Step for CodegenBackend {
return;
}
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
let target = self.target;
let backend = self.backend;
@@ -382,7 +382,7 @@ impl Step for RustAnalyzer {
}
fn run(self, builder: &Builder<'_>) {
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
let target = self.target;
builder.ensure(Rustc::new(target, builder));
@@ -448,7 +448,7 @@ impl Step for Compiletest {
let compiler = builder.compiler(
if mode == Mode::ToolBootstrap { 0 } else { builder.top_stage },
- builder.config.build,
+ builder.config.host_target,
);
if mode != Mode::ToolBootstrap {
@@ -527,7 +527,7 @@ fn run_tool_check_step(
path: &str,
) {
let display_name = path.rsplit('/').next().unwrap();
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
builder.ensure(Rustc::new(target, builder));
@@ -614,7 +614,7 @@ impl Step for CoverageDump {
// Make sure we haven't forgotten any fields, if there are any.
let Self {} = self;
let display_name = "coverage-dump";
- let host = builder.config.build;
+ let host = builder.config.host_target;
let target = host;
let mode = Mode::ToolBootstrap;
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index 0652c08ff496e..788a3b9601d9d 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -144,7 +144,7 @@ impl Step for Std {
builder.require_submodule("library/stdarch", None);
let target = self.target;
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
let mut cargo = builder::Cargo::new(
builder,
@@ -204,7 +204,7 @@ impl Step for Rustc {
/// This will lint the compiler for a particular stage of the build using
/// the `compiler` targeting the `target` architecture.
fn run(self, builder: &Builder<'_>) {
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
let target = self.target;
if !builder.download_rustc() {
@@ -285,7 +285,7 @@ macro_rules! lint_any {
}
fn run(self, builder: &Builder<'_>) -> Self::Output {
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
let target = self.target;
if !builder.download_rustc() {
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 5ecce31fe1562..560925abba6a9 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -35,6 +35,7 @@ use crate::utils::helpers::{
};
use crate::{CLang, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode, debug, trace};
+/// Build a standard library for the given `target` using the given `compiler`.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Std {
pub target: TargetSelection,
@@ -159,7 +160,7 @@ impl Step for Std {
let compiler = if builder.download_rustc() && self.force_recompile {
// When there are changes in the library tree with CI-rustc, we want to build
// the stageN library and that requires using stageN-1 compiler.
- builder.compiler(self.compiler.stage.saturating_sub(1), builder.config.build)
+ builder.compiler(self.compiler.stage.saturating_sub(1), builder.config.host_target)
} else {
self.compiler
};
@@ -301,7 +302,7 @@ impl Step for Std {
builder.ensure(StdLink::from_std(
self,
- builder.compiler(compiler.stage, builder.config.build),
+ builder.compiler(compiler.stage, builder.config.host_target),
));
}
}
@@ -960,11 +961,18 @@ fn cp_rustc_component_to_ci_sysroot(builder: &Builder<'_>, sysroot: &Path, conte
}
}
+/// Build rustc using the passed `build_compiler`.
+///
+/// - Makes sure that `build_compiler` has a standard library prepared for its host target,
+/// so that it can compile build scripts and proc macros when building this `rustc`.
+/// - Makes sure that `build_compiler` has a standard library prepared for `target`,
+/// so that the built `rustc` can *link to it* and use it at runtime.
#[derive(Debug, PartialOrd, Ord, Clone, PartialEq, Eq, Hash)]
pub struct Rustc {
+ /// The target on which rustc will run (its host).
pub target: TargetSelection,
- /// The **previous** compiler used to compile this compiler.
- pub compiler: Compiler,
+ /// The **previous** compiler used to compile this rustc.
+ pub build_compiler: Compiler,
/// Whether to build a subset of crates, rather than the whole compiler.
///
/// This should only be requested by the user, not used within bootstrap itself.
@@ -974,8 +982,8 @@ pub struct Rustc {
}
impl Rustc {
- pub fn new(compiler: Compiler, target: TargetSelection) -> Self {
- Self { target, compiler, crates: Default::default() }
+ pub fn new(build_compiler: Compiler, target: TargetSelection) -> Self {
+ Self { target, build_compiler, crates: Default::default() }
}
}
@@ -1007,7 +1015,7 @@ impl Step for Rustc {
fn make_run(run: RunConfig<'_>) {
let crates = run.cargo_crates_in_set();
run.builder.ensure(Rustc {
- compiler: run
+ build_compiler: run
.builder
.compiler(run.builder.top_stage.saturating_sub(1), run.build_triple()),
target: run.target,
@@ -1018,7 +1026,7 @@ impl Step for Rustc {
/// Builds the compiler.
///
/// This will build the compiler for a particular stage of the build using
- /// the `compiler` targeting the `target` architecture. The artifacts
+ /// the `build_compiler` targeting the `target` architecture. The artifacts
/// created will also be linked into the sysroot directory.
#[cfg_attr(
feature = "tracing",
@@ -1026,54 +1034,58 @@ impl Step for Rustc {
level = "debug",
name = "Rustc::run",
skip_all,
- fields(previous_compiler = ?self.compiler, target = ?self.target),
+ fields(previous_compiler = ?self.build_compiler, target = ?self.target),
),
)]
fn run(self, builder: &Builder<'_>) -> u32 {
- let compiler = self.compiler;
+ let build_compiler = self.build_compiler;
let target = self.target;
// NOTE: the ABI of the stage0 compiler is different from the ABI of the downloaded compiler,
// so its artifacts can't be reused.
- if builder.download_rustc() && compiler.stage != 0 {
- trace!(stage = compiler.stage, "`download_rustc` requested");
+ if builder.download_rustc() && build_compiler.stage != 0 {
+ trace!(stage = build_compiler.stage, "`download_rustc` requested");
- let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
+ let sysroot =
+ builder.ensure(Sysroot { compiler: build_compiler, force_recompile: false });
cp_rustc_component_to_ci_sysroot(
builder,
&sysroot,
builder.config.ci_rustc_dev_contents(),
);
- return compiler.stage;
+ return build_compiler.stage;
}
- builder.ensure(Std::new(compiler, target));
+ // Build a standard library for `target` using the `build_compiler`.
+ // This will be the standard library that the rustc which we build *links to*.
+ builder.ensure(Std::new(build_compiler, target));
- if builder.config.keep_stage.contains(&compiler.stage) {
- trace!(stage = compiler.stage, "`keep-stage` requested");
+ if builder.config.keep_stage.contains(&build_compiler.stage) {
+ trace!(stage = build_compiler.stage, "`keep-stage` requested");
builder.info("WARNING: Using a potentially old librustc. This may not behave well.");
builder.info("WARNING: Use `--keep-stage-std` if you want to rebuild the compiler when it changes");
- builder.ensure(RustcLink::from_rustc(self, compiler));
+ builder.ensure(RustcLink::from_rustc(self, build_compiler));
- return compiler.stage;
+ return build_compiler.stage;
}
- let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
- if compiler_to_use != compiler {
+ let compiler_to_use =
+ builder.compiler_for(build_compiler.stage, build_compiler.host, target);
+ if compiler_to_use != build_compiler {
builder.ensure(Rustc::new(compiler_to_use, target));
let msg = if compiler_to_use.host == target {
format!(
"Uplifting rustc (stage{} -> stage{})",
compiler_to_use.stage,
- compiler.stage + 1
+ build_compiler.stage + 1
)
} else {
format!(
"Uplifting rustc (stage{}:{} -> stage{}:{})",
compiler_to_use.stage,
compiler_to_use.host,
- compiler.stage + 1,
+ build_compiler.stage + 1,
target
)
};
@@ -1082,22 +1094,26 @@ impl Step for Rustc {
return compiler_to_use.stage;
}
- // Ensure that build scripts and proc macros have a std / libproc_macro to link against.
+ // Build a standard library for the current host target using the `build_compiler`.
+ // This standard library will be used when building `rustc` for compiling
+ // build scripts and proc macros.
+ // If we are not cross-compiling, the Std build above will be the same one as the one we
+ // prepare here.
builder.ensure(Std::new(
- builder.compiler(self.compiler.stage, builder.config.build),
- builder.config.build,
+ builder.compiler(self.build_compiler.stage, builder.config.host_target),
+ builder.config.host_target,
));
let mut cargo = builder::Cargo::new(
builder,
- compiler,
+ build_compiler,
Mode::Rustc,
SourceType::InTree,
target,
Kind::Build,
);
- rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
+ rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates);
// NB: all RUSTFLAGS should be added to `rustc_cargo()` so they will be
// consistently applied by check/doc/test modes too.
@@ -1106,19 +1122,19 @@ impl Step for Rustc {
cargo.arg("-p").arg(krate);
}
- if builder.build.config.enable_bolt_settings && compiler.stage == 1 {
+ if builder.build.config.enable_bolt_settings && build_compiler.stage == 1 {
// Relocations are required for BOLT to work.
cargo.env("RUSTC_BOLT_LINK_FLAGS", "1");
}
let _guard = builder.msg_sysroot_tool(
Kind::Build,
- compiler.stage,
+ build_compiler.stage,
format_args!("compiler artifacts{}", crate_description(&self.crates)),
- compiler.host,
+ build_compiler.host,
target,
);
- let stamp = build_stamp::librustc_stamp(builder, compiler, target);
+ let stamp = build_stamp::librustc_stamp(builder, build_compiler, target);
run_cargo(
builder,
cargo,
@@ -1150,10 +1166,10 @@ impl Step for Rustc {
builder.ensure(RustcLink::from_rustc(
self,
- builder.compiler(compiler.stage, builder.config.build),
+ builder.compiler(build_compiler.stage, builder.config.host_target),
));
- compiler.stage
+ build_compiler.stage
}
}
@@ -1161,7 +1177,7 @@ pub fn rustc_cargo(
builder: &Builder<'_>,
cargo: &mut Cargo,
target: TargetSelection,
- compiler: &Compiler,
+ build_compiler: &Compiler,
crates: &[String],
) {
cargo
@@ -1190,11 +1206,11 @@ pub fn rustc_cargo(
// We want to link against registerEnzyme and in the future we want to use additional
// functionality from Enzyme core. For that we need to link against Enzyme.
if builder.config.llvm_enzyme {
- let arch = builder.build.build;
+ let arch = builder.build.host_target;
let enzyme_dir = builder.build.out.join(arch).join("enzyme").join("lib");
cargo.rustflag("-L").rustflag(enzyme_dir.to_str().expect("Invalid path"));
- if let Some(llvm_config) = builder.llvm_config(builder.config.build) {
+ if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) {
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}"));
}
@@ -1208,7 +1224,7 @@ pub fn rustc_cargo(
cargo.rustflag("-Zdefault-visibility=protected");
}
- if is_lto_stage(compiler) {
+ if is_lto_stage(build_compiler) {
match builder.config.rust_lto {
RustcLto::Thin | RustcLto::Fat => {
// Since using LTO for optimizing dylibs is currently experimental,
@@ -1241,7 +1257,7 @@ pub fn rustc_cargo(
// is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
// https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
// https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
- if builder.config.lld_mode.is_used() && !compiler.host.is_msvc() {
+ if builder.config.lld_mode.is_used() && !build_compiler.host.is_msvc() {
cargo.rustflag("-Clink-args=-Wl,--icf=all");
}
@@ -1249,7 +1265,7 @@ pub fn rustc_cargo(
panic!("Cannot use and generate PGO profiles at the same time");
}
let is_collecting = if let Some(path) = &builder.config.rust_profile_generate {
- if compiler.stage == 1 {
+ if build_compiler.stage == 1 {
cargo.rustflag(&format!("-Cprofile-generate={path}"));
// Apparently necessary to avoid overflowing the counters during
// a Cargo build profile
@@ -1259,7 +1275,7 @@ pub fn rustc_cargo(
false
}
} else if let Some(path) = &builder.config.rust_profile_use {
- if compiler.stage == 1 {
+ if build_compiler.stage == 1 {
cargo.rustflag(&format!("-Cprofile-use={path}"));
if builder.is_verbose() {
cargo.rustflag("-Cllvm-args=-pgo-warn-missing-function");
@@ -1284,20 +1300,20 @@ pub fn rustc_cargo(
// useful.
// This is only performed for non-incremental builds, as ccache cannot deal with these.
if let Some(ref ccache) = builder.config.ccache
- && compiler.stage == 0
+ && build_compiler.stage == 0
&& !builder.config.incremental
{
cargo.env("RUSTC_WRAPPER", ccache);
}
- rustc_cargo_env(builder, cargo, target, compiler.stage);
+ rustc_cargo_env(builder, cargo, target, build_compiler.stage);
}
pub fn rustc_cargo_env(
builder: &Builder<'_>,
cargo: &mut Cargo,
target: TargetSelection,
- stage: u32,
+ build_stage: u32,
) {
// Set some configuration variables picked up by build scripts and
// the compiler alike
@@ -1364,7 +1380,7 @@ pub fn rustc_cargo_env(
crate::core::build_steps::llvm::prebuilt_llvm_config(builder, target, false)
.should_build();
// `top_stage == stage` might be false for `check --stage 1`, if we are building the stage 1 compiler
- let can_skip_build = builder.kind == Kind::Check && builder.top_stage == stage;
+ let can_skip_build = builder.kind == Kind::Check && builder.top_stage == build_stage;
let should_skip_build = building_is_expensive && can_skip_build;
if !should_skip_build {
rustc_llvm_env(builder, cargo, target)
@@ -1475,7 +1491,7 @@ impl RustcLink {
fn from_rustc(rustc: Rustc, host_compiler: Compiler) -> Self {
Self {
compiler: host_compiler,
- previous_stage_compiler: rustc.compiler,
+ previous_stage_compiler: rustc.build_compiler,
target: rustc.target,
crates: rustc.crates,
}
@@ -1813,7 +1829,7 @@ impl Step for Sysroot {
// If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0.
if builder.download_rustc() && compiler.stage != 0 {
assert_eq!(
- builder.config.build, compiler.host,
+ builder.config.host_target, compiler.host,
"Cross-compiling is not yet supported with `download-rustc`",
);
@@ -1967,7 +1983,7 @@ impl Step for Assemble {
if target_compiler.stage == 0 {
trace!("stage 0 build compiler is always available, simply returning");
assert_eq!(
- builder.config.build, target_compiler.host,
+ builder.config.host_target, target_compiler.host,
"Cannot obtain compiler for non-native build triple at stage 0"
);
// The stage 0 compiler for the build triple is always pre-built.
@@ -2080,15 +2096,16 @@ impl Step for Assemble {
debug!(
"ensuring build compiler is available: compiler(stage = {}, host = {:?})",
target_compiler.stage - 1,
- builder.config.build,
+ builder.config.host_target,
);
- let mut build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build);
+ let mut build_compiler =
+ builder.compiler(target_compiler.stage - 1, builder.config.host_target);
// Build enzyme
if builder.config.llvm_enzyme && !builder.config.dry_run() {
debug!("`llvm_enzyme` requested");
let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host });
- let llvm_config = builder.llvm_config(builder.config.build).unwrap();
+ let llvm_config = builder.llvm_config(builder.config.host_target).unwrap();
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
let lib_ext = std::env::consts::DLL_EXTENSION;
let libenzyme = format!("libEnzyme-{llvm_version_major}");
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 7aa9e6cc2b53e..e0f632eda0e29 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -422,7 +422,7 @@ impl Step for Rustc {
}
let ra_proc_macro_srv_compiler =
- builder.compiler_for(compiler.stage, builder.config.build, compiler.host);
+ builder.compiler_for(compiler.stage, builder.config.host_target, compiler.host);
builder.ensure(compile::Rustc::new(ra_proc_macro_srv_compiler, compiler.host));
if let Some(ra_proc_macro_srv) = builder.ensure_if_default(
@@ -696,7 +696,7 @@ impl Step for Std {
run.builder.ensure(Std {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -748,7 +748,7 @@ impl Step for RustcDev {
run.builder.ensure(RustcDev {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -815,7 +815,7 @@ impl Step for Analysis {
// through the sysroot uplifting.
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -1168,7 +1168,7 @@ impl Step for Cargo {
run.builder.ensure(Cargo {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -1224,7 +1224,7 @@ impl Step for RustAnalyzer {
run.builder.ensure(RustAnalyzer {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -1268,7 +1268,7 @@ impl Step for Clippy {
run.builder.ensure(Clippy {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -1317,7 +1317,7 @@ impl Step for Miri {
run.builder.ensure(Miri {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -1462,7 +1462,7 @@ impl Step for Rustfmt {
run.builder.ensure(Rustfmt {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
@@ -1507,7 +1507,7 @@ impl Step for Extended {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Extended {
stage: run.builder.top_stage,
- host: run.builder.config.build,
+ host: run.builder.config.host_target,
target: run.target,
});
}
@@ -2157,7 +2157,7 @@ fn maybe_install_llvm(
cmd.arg("--libfiles");
builder.verbose(|| println!("running {cmd:?}"));
let files = cmd.run_capture_stdout(builder).stdout();
- let build_llvm_out = &builder.llvm_out(builder.config.build);
+ let build_llvm_out = &builder.llvm_out(builder.config.host_target);
let target_llvm_out = &builder.llvm_out(target);
for file in files.trim_end().split(' ') {
// If we're not using a custom LLVM, make sure we package for the target.
@@ -2341,7 +2341,7 @@ impl Step for LlvmBitcodeLinker {
run.builder.ensure(LlvmBitcodeLinker {
compiler: run.builder.compiler_for(
run.builder.top_stage,
- run.builder.config.build,
+ run.builder.config.host_target,
run.target,
),
target: run.target,
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 7fccf85a0ea9f..215c155651a23 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -209,7 +209,7 @@ impl Step for TheBook {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(TheBook {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -329,7 +329,7 @@ impl Step for Standalone {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Standalone {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -431,7 +431,7 @@ impl Step for Releases {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Releases {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -449,7 +449,7 @@ impl Step for Releases {
t!(fs::create_dir_all(&out));
builder.ensure(Standalone {
- compiler: builder.compiler(builder.top_stage, builder.config.build),
+ compiler: builder.compiler(builder.top_stage, builder.config.host_target),
target,
});
@@ -700,7 +700,7 @@ fn doc_std(
extra_args: &[&str],
requested_crates: &[String],
) {
- let compiler = builder.compiler(stage, builder.config.build);
+ let compiler = builder.compiler(stage, builder.config.host_target);
let target_doc_dir_name = if format == DocumentationFormat::Json { "json-doc" } else { "doc" };
let target_dir = builder.stage_out(compiler, Mode::Std).join(target).join(target_doc_dir_name);
@@ -803,8 +803,8 @@ impl Step for Rustc {
// Build the standard library, so that proc-macros can use it.
// (Normally, only the metadata would be necessary, but proc-macros are special since they run at compile-time.)
- let compiler = builder.compiler(stage, builder.config.build);
- builder.ensure(compile::Std::new(compiler, builder.config.build));
+ let compiler = builder.compiler(stage, builder.config.host_target);
+ builder.ensure(compile::Std::new(compiler, builder.config.host_target));
let _guard = builder.msg_sysroot_tool(
Kind::Doc,
@@ -946,7 +946,7 @@ macro_rules! tool_doc {
let out = builder.compiler_doc_out(target);
t!(fs::create_dir_all(&out));
- let compiler = builder.compiler(stage, builder.config.build);
+ let compiler = builder.compiler(stage, builder.config.host_target);
builder.ensure(compile::Std::new(compiler, target));
if true $(&& $rustc_tool)? {
@@ -1174,7 +1174,7 @@ impl Step for RustcBook {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RustcBook {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
validate: false,
});
@@ -1261,7 +1261,7 @@ impl Step for Reference {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Reference {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -1272,7 +1272,7 @@ impl Step for Reference {
// This is needed for generating links to the standard library using
// the mdbook-spec plugin.
- builder.ensure(compile::Std::new(self.compiler, builder.config.build));
+ builder.ensure(compile::Std::new(self.compiler, builder.config.host_target));
// Run rustbook/mdbook to generate the HTML pages.
builder.ensure(RustbookSrc {
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index ee8bd8286daec..899e3fd9a45a8 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -285,7 +285,7 @@ pub fn add_cg_gcc_cargo_flags(cargo: &mut Cargo, gcc: &GccOutput) {
/// The absolute path to the downloaded GCC artifacts.
#[cfg(not(test))]
fn ci_gcc_root(config: &crate::Config) -> PathBuf {
- config.out.join(config.build).join("ci-gcc")
+ config.out.join(config.host_target).join("ci-gcc")
}
/// Detect whether GCC sources have been modified locally or not.
diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs
index 5419540aa2e08..4434d6658eb24 100644
--- a/src/bootstrap/src/core/build_steps/install.rs
+++ b/src/bootstrap/src/core/build_steps/install.rs
@@ -73,7 +73,7 @@ fn install_sh(
let prefix = default_path(&builder.config.prefix, "/usr/local");
let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
let destdir_env = env::var_os("DESTDIR").map(PathBuf::from);
- let is_cygwin = builder.config.build.is_cygwin();
+ let is_cygwin = builder.config.host_target.is_cygwin();
// Sanity checks on the write access of user.
//
@@ -187,7 +187,7 @@ macro_rules! install {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure($name {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -246,7 +246,7 @@ install!((self, builder, _config),
);
}
};
- LlvmTools, alias = "llvm-tools", _config.llvm_tools_enabled && _config.llvm_enabled(_config.build), only_hosts: true, {
+ LlvmTools, alias = "llvm-tools", _config.llvm_tools_enabled && _config.llvm_enabled(_config.host_target), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::LlvmTools { target: self.target }) {
install_sh(builder, "llvm-tools", self.compiler.stage, Some(self.target), &tarball);
} else {
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 2b7703000cbff..8f2f143c352f0 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -132,14 +132,14 @@ pub fn prebuilt_llvm_config(
let build_llvm_config = if let Some(build_llvm_config) = builder
.config
.target_config
- .get(&builder.config.build)
+ .get(&builder.config.host_target)
.and_then(|config| config.llvm_config.clone())
{
build_llvm_config
} else {
- let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
+ let mut llvm_config_ret_dir = builder.llvm_out(builder.config.host_target);
llvm_config_ret_dir.push("bin");
- llvm_config_ret_dir.join(exe("llvm-config", builder.config.build))
+ llvm_config_ret_dir.join(exe("llvm-config", builder.config.host_target))
};
let llvm_cmake_dir = out_dir.join("lib/cmake/llvm");
@@ -235,8 +235,8 @@ pub(crate) fn is_ci_llvm_available_for_target(config: &Config, asserts: bool) ->
("x86_64-unknown-netbsd", false),
];
- if !supported_platforms.contains(&(&*config.build.triple, asserts))
- && (asserts || !supported_platforms.contains(&(&*config.build.triple, true)))
+ if !supported_platforms.contains(&(&*config.host_target.triple, asserts))
+ && (asserts || !supported_platforms.contains(&(&*config.host_target.triple, true)))
{
return false;
}
@@ -480,7 +480,7 @@ impl Step for Llvm {
// https://llvm.org/docs/HowToCrossCompileLLVM.html
if !builder.config.is_host_target(target) {
let LlvmResult { llvm_config, .. } =
- builder.ensure(Llvm { target: builder.config.build });
+ builder.ensure(Llvm { target: builder.config.host_target });
if !builder.config.dry_run() {
let llvm_bindir =
command(&llvm_config).arg("--bindir").run_capture_stdout(builder).stdout();
@@ -494,7 +494,8 @@ impl Step for Llvm {
}
cfg.define("LLVM_CONFIG_PATH", llvm_config);
if builder.config.llvm_clang {
- let build_bin = builder.llvm_out(builder.config.build).join("build").join("bin");
+ let build_bin =
+ builder.llvm_out(builder.config.host_target).join("build").join("bin");
let clang_tblgen = build_bin.join("clang-tblgen").with_extension(EXE_EXTENSION);
if !builder.config.dry_run() && !clang_tblgen.exists() {
panic!("unable to find {}", clang_tblgen.display());
@@ -628,7 +629,7 @@ fn configure_cmake(
if builder.ninja() {
cfg.generator("Ninja");
}
- cfg.target(&target.triple).host(&builder.config.build.triple);
+ cfg.target(&target.triple).host(&builder.config.host_target.triple);
if !builder.config.is_host_target(target) {
cfg.define("CMAKE_CROSSCOMPILING", "True");
@@ -813,7 +814,7 @@ fn configure_cmake(
ldflags.push_all(flags);
}
- if let Some(flags) = get_var("LDFLAGS", &builder.config.build.triple, &target.triple) {
+ if let Some(flags) = get_var("LDFLAGS", &builder.config.host_target.triple, &target.triple) {
ldflags.push_all(&flags);
}
@@ -1135,7 +1136,8 @@ impl Step for Sanitizers {
return runtimes;
}
- let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build });
+ let LlvmResult { llvm_config, .. } =
+ builder.ensure(Llvm { target: builder.config.host_target });
static STAMP_HASH_MEMO: OnceLock = OnceLock::new();
let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| {
@@ -1345,7 +1347,7 @@ impl Step for CrtBeginEnd {
cfg.cargo_metadata(false)
.out_dir(&out_dir)
.target(&self.target.triple)
- .host(&builder.config.build.triple)
+ .host(&builder.config.host_target.triple)
.warnings(false)
.debug(false)
.opt_level(3)
@@ -1424,7 +1426,7 @@ impl Step for Libunwind {
cfg.archiver(ar);
}
cfg.target(&self.target.triple);
- cfg.host(&builder.config.build.triple);
+ cfg.host(&builder.config.host_target.triple);
cfg.warnings(false);
cfg.debug(false);
// get_compiler() need set opt_level first.
diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs
index 14c7b7cf5e983..c43043b48f4d8 100644
--- a/src/bootstrap/src/core/build_steps/perf.rs
+++ b/src/bootstrap/src/core/build_steps/perf.rs
@@ -136,8 +136,8 @@ impl Display for Scenario {
/// Performs profiling using `rustc-perf` on a built version of the compiler.
pub fn perf(builder: &Builder<'_>, args: &PerfArgs) {
let collector = builder.ensure(RustcPerf {
- compiler: builder.compiler(0, builder.config.build),
- target: builder.config.build,
+ compiler: builder.compiler(0, builder.config.host_target),
+ target: builder.config.host_target,
});
let is_profiling = match &args.cmd {
@@ -151,8 +151,8 @@ pub fn perf(builder: &Builder<'_>, args: &PerfArgs) {
Consider setting `rust.debuginfo-level = 1` in `bootstrap.toml`."#);
}
- let compiler = builder.compiler(builder.top_stage, builder.config.build);
- builder.ensure(Std::new(compiler, builder.config.build));
+ let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
+ builder.ensure(Std::new(compiler, builder.config.host_target));
if let Some(opts) = args.cmd.shared_opts()
&& opts.profiles.contains(&Profile::Doc)
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index 6ef1b13abcde0..b3104ae05e884 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -116,7 +116,7 @@ impl Step for Miri {
}
fn run(self, builder: &Builder<'_>) {
- let host = builder.build.build;
+ let host = builder.build.host_target;
let target = self.target;
// `x run` uses stage 0 by default but miri does not work well with stage 0.
@@ -448,7 +448,7 @@ impl Step for Rustfmt {
}
fn run(self, builder: &Builder<'_>) {
- let host = builder.build.build;
+ let host = builder.build.host_target;
// `x run` uses stage 0 by default but rustfmt does not work well with stage 0.
// Change the stage to 1 if it's not set explicitly.
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index 25adfdf160157..86b7456d7b4e9 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -260,7 +260,7 @@ impl Step for Link {
}
let stage_path =
- ["build", config.build.rustc_target_arg(), "stage1"].join(MAIN_SEPARATOR_STR);
+ ["build", config.host_target.rustc_target_arg(), "stage1"].join(MAIN_SEPARATOR_STR);
if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
attempt_toolchain_link(builder, &stage_path[..]);
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index dddce8fe05d1d..ebb926d81cef4 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -70,7 +70,7 @@ impl Step for CrateBootstrap {
}
fn run(self, builder: &Builder<'_>) {
- let bootstrap_host = builder.config.build;
+ let bootstrap_host = builder.config.host_target;
let compiler = builder.compiler(0, bootstrap_host);
let mut path = self.path.to_str().unwrap();
@@ -128,7 +128,7 @@ You can skip linkcheck with --skip src/tools/linkchecker"
builder.info(&format!("Linkcheck ({host})"));
// Test the linkchecker itself.
- let bootstrap_host = builder.config.build;
+ let bootstrap_host = builder.config.host_target;
let compiler = builder.compiler(0, bootstrap_host);
let cargo = tool::prepare_tool_cargo(
@@ -525,7 +525,7 @@ impl Step for Miri {
/// Runs `cargo test` for miri.
fn run(self, builder: &Builder<'_>) {
- let host = builder.build.build;
+ let host = builder.build.host_target;
let target = self.target;
let stage = builder.top_stage;
if stage == 0 {
@@ -637,7 +637,7 @@ impl Step for CargoMiri {
/// Tests `cargo miri test`.
fn run(self, builder: &Builder<'_>) {
- let host = builder.build.build;
+ let host = builder.build.host_target;
let target = self.target;
let stage = builder.top_stage;
if stage == 0 {
@@ -915,7 +915,7 @@ impl Step for RustdocJSStd {
Kind::Test,
builder.top_stage,
"rustdoc-js-std",
- builder.config.build,
+ builder.config.host_target,
self.target,
);
command.run(builder);
@@ -1607,7 +1607,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
// At stage 0 (stage - 1) we are using the stage0 compiler. Using `self.target` can lead
// finding an incorrect compiler path on cross-targets, as the stage 0 is always equal to
// `build.build` in the configuration.
- let build = builder.build.build;
+ let build = builder.build.host_target;
compiler = builder.compiler(compiler.stage - 1, build);
let test_stage = compiler.stage + 1;
(test_stage, format!("stage{test_stage}-{build}"))
@@ -1729,7 +1729,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
cmd.arg("--mode").arg(mode);
cmd.arg("--target").arg(target.rustc_target_arg());
cmd.arg("--host").arg(&*compiler.host.triple);
- cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build));
+ cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.host_target));
if builder.build.config.llvm_enzyme {
cmd.arg("--has-enzyme");
@@ -1900,7 +1900,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
let mut copts_passed = false;
if builder.config.llvm_enabled(compiler.host) {
let llvm::LlvmResult { llvm_config, .. } =
- builder.ensure(llvm::Llvm { target: builder.config.build });
+ builder.ensure(llvm::Llvm { target: builder.config.host_target });
if !builder.config.dry_run() {
let llvm_version = get_llvm_version(builder, &llvm_config);
let llvm_components =
@@ -1947,7 +1947,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
// If LLD is available, add it to the PATH
if builder.config.lld_enabled {
let lld_install_root =
- builder.ensure(llvm::Lld { target: builder.config.build });
+ builder.ensure(llvm::Lld { target: builder.config.host_target });
let lld_bin_path = lld_install_root.join("bin");
@@ -2202,7 +2202,7 @@ impl BookTest {
let mut lib_paths = vec![];
for dep in self.dependencies {
let mode = Mode::ToolRustc;
- let target = builder.config.build;
+ let target = builder.config.host_target;
let cargo = tool::prepare_tool_cargo(
builder,
compiler,
@@ -2384,7 +2384,7 @@ impl Step for ErrorIndex {
// error_index_generator depends on librustdoc. Use the compiler that
// is normally used to build rustdoc for other tests (like compiletest
// tests in tests/rustdoc) so that it shares the same artifacts.
- let compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.build);
+ let compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.host_target);
run.builder.ensure(ErrorIndex { compiler });
}
@@ -2983,7 +2983,7 @@ impl Step for Distcheck {
.arg("--enable-vendor")
.current_dir(&dir)
.run(builder);
- command(helpers::make(&builder.config.build.triple))
+ command(helpers::make(&builder.config.host_target.triple))
.arg("check")
.current_dir(&dir)
.run(builder);
@@ -3024,7 +3024,7 @@ impl Step for Bootstrap {
/// Tests the build system itself.
fn run(self, builder: &Builder<'_>) {
- let host = builder.config.build;
+ let host = builder.config.host_target;
let compiler = builder.compiler(0, host);
let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host);
@@ -3035,7 +3035,7 @@ impl Step for Bootstrap {
check_bootstrap
.args(["-m", "unittest", "bootstrap_test.py"])
.env("BUILD_DIR", &builder.out)
- .env("BUILD_PLATFORM", builder.build.build.triple)
+ .env("BUILD_PLATFORM", builder.build.host_target.triple)
.env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc)
.env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo)
.current_dir(builder.src.join("src/bootstrap/"));
@@ -3090,8 +3090,11 @@ impl Step for TierCheck {
}
fn make_run(run: RunConfig<'_>) {
- let compiler =
- run.builder.compiler_for(run.builder.top_stage, run.builder.build.build, run.target);
+ let compiler = run.builder.compiler_for(
+ run.builder.top_stage,
+ run.builder.build.host_target,
+ run.target,
+ );
run.builder.ensure(TierCheck { compiler });
}
@@ -3142,7 +3145,7 @@ impl Step for LintDocs {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(LintDocs {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -3168,7 +3171,7 @@ impl Step for RustInstaller {
/// Ensure the version placeholder replacement tool builds
fn run(self, builder: &Builder<'_>) {
- let bootstrap_host = builder.config.build;
+ let bootstrap_host = builder.config.host_target;
let compiler = builder.compiler(0, bootstrap_host);
let cargo = tool::prepare_tool_cargo(
builder,
@@ -3270,7 +3273,7 @@ impl Step for TestHelpers {
cfg.cargo_metadata(false)
.out_dir(&dst)
.target(&target.triple)
- .host(&builder.config.build.triple)
+ .host(&builder.config.host_target.triple)
.opt_level(0)
.warnings(false)
.debug(false)
@@ -3560,7 +3563,7 @@ impl Step for TestFloatParse {
}
fn run(self, builder: &Builder<'_>) {
- let bootstrap_host = builder.config.build;
+ let bootstrap_host = builder.config.host_target;
let compiler = builder.compiler(builder.top_stage, bootstrap_host);
let path = self.path.to_str().unwrap();
let crate_name = self.path.iter().next_back().unwrap().to_str().unwrap();
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 717accb399adc..680718f055299 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -341,14 +341,14 @@ pub(crate) fn get_tool_rustc_compiler(
if builder.download_rustc() && target_compiler.stage == 1 {
// We shouldn't drop to stage0 compiler when using CI rustc.
- return builder.compiler(1, builder.config.build);
+ return builder.compiler(1, builder.config.host_target);
}
// Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
// we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage
// compilers, which isn't what we want. Rustc tools should be linked in the same way as the
// compiler it's paired with, so it must be built with the previous stage compiler.
- builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.build)
+ builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.host_target)
}
/// Links a built tool binary with the given `name` from the build directory to the
@@ -389,8 +389,8 @@ macro_rules! bootstrap_tool {
match tool {
$(Tool::$name =>
self.ensure($name {
- compiler: self.compiler(0, self.config.build),
- target: self.config.build,
+ compiler: self.compiler(0, self.config.host_target),
+ target: self.config.host_target,
}).tool_path,
)+
}
@@ -414,7 +414,7 @@ macro_rules! bootstrap_tool {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure($name {
// snapshot compiler
- compiler: run.builder.compiler(0, run.builder.config.build),
+ compiler: run.builder.compiler(0, run.builder.config.host_target),
target: run.target,
});
}
@@ -531,7 +531,7 @@ impl Step for RustcPerf {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RustcPerf {
- compiler: run.builder.compiler(0, run.builder.config.build),
+ compiler: run.builder.compiler(0, run.builder.config.host_target),
target: run.target,
});
}
@@ -572,7 +572,7 @@ impl ErrorIndex {
pub fn command(builder: &Builder<'_>) -> BootstrapCommand {
// Error-index-generator links with the rustdoc library, so we need to add `rustc_lib_paths`
// for rustc_private and libLLVM.so, and `sysroot_lib` for libstd, etc.
- let host = builder.config.build;
+ let host = builder.config.host_target;
let compiler = builder.compiler_for(builder.top_stage, host, host);
let mut cmd = command(builder.ensure(ErrorIndex { compiler }).tool_path);
let mut dylib_paths = builder.rustc_lib_paths(compiler);
@@ -595,7 +595,7 @@ impl Step for ErrorIndex {
// src/tools/error-index-generator` which almost nobody does.
// Normally, `x.py test` or `x.py doc` will use the
// `ErrorIndex::command` function instead.
- let compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.build);
+ let compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.host_target);
run.builder.ensure(ErrorIndex { compiler });
}
@@ -630,7 +630,7 @@ impl Step for RemoteTestServer {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RemoteTestServer {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -787,7 +787,7 @@ impl Step for Cargo {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Cargo {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -905,7 +905,7 @@ impl Step for RustAnalyzer {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RustAnalyzer {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -950,7 +950,7 @@ impl Step for RustAnalyzerProcMacroSrv {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RustAnalyzerProcMacroSrv {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -1003,7 +1003,7 @@ impl Step for LlvmBitcodeLinker {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(LlvmBitcodeLinker {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
extra_features: Vec::new(),
target: run.target,
});
@@ -1141,7 +1141,7 @@ macro_rules! tool_extended {
fn make_run(run: RunConfig<'_>) {
run.builder.ensure($name {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target),
target: run.target,
});
}
@@ -1283,7 +1283,7 @@ impl Step for TestFloatParse {
}
fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
- let bootstrap_host = builder.config.build;
+ let bootstrap_host = builder.config.host_target;
let compiler = builder.compiler(builder.top_stage, bootstrap_host);
builder.ensure(ToolBuild {
@@ -1306,7 +1306,7 @@ impl Builder<'_> {
/// `host`.
pub fn tool_cmd(&self, tool: Tool) -> BootstrapCommand {
let mut cmd = command(self.tool_exe(tool));
- let compiler = self.compiler(0, self.config.build);
+ let compiler = self.compiler(0, self.config.host_target);
let host = &compiler.host;
// Prepares the `cmd` provided to be able to run the `compiler` provided.
//
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 8b1520de3a854..887db683f7899 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -137,7 +137,7 @@ pub struct RunConfig<'a> {
impl RunConfig<'_> {
pub fn build_triple(&self) -> TargetSelection {
- self.builder.build.build
+ self.builder.build.host_target
}
/// Return a list of crate names selected by `run.paths`.
@@ -1297,10 +1297,10 @@ impl<'a> Builder<'a> {
) -> Compiler {
let mut resolved_compiler = if self.build.force_use_stage2(stage) {
trace!(target: "COMPILER_FOR", ?stage, "force_use_stage2");
- self.compiler(2, self.config.build)
+ self.compiler(2, self.config.host_target)
} else if self.build.force_use_stage1(stage, target) {
trace!(target: "COMPILER_FOR", ?stage, "force_use_stage1");
- self.compiler(1, self.config.build)
+ self.compiler(1, self.config.host_target)
} else {
trace!(target: "COMPILER_FOR", ?stage, ?host, "no force, fallback to `compiler()`");
self.compiler(stage, host)
@@ -1358,7 +1358,7 @@ impl<'a> Builder<'a> {
/// Windows.
pub fn libdir_relative(&self, compiler: Compiler) -> &Path {
if compiler.is_snapshot(self) {
- libdir(self.config.build).as_ref()
+ libdir(self.config.host_target).as_ref()
} else {
match self.config.libdir_relative() {
Some(relative_libdir) if compiler.stage >= 1 => relative_libdir,
@@ -1439,9 +1439,10 @@ impl<'a> Builder<'a> {
return cmd;
}
- let _ = self.ensure(tool::Clippy { compiler: run_compiler, target: self.build.build });
- let cargo_clippy =
- self.ensure(tool::CargoClippy { compiler: run_compiler, target: self.build.build });
+ let _ =
+ self.ensure(tool::Clippy { compiler: run_compiler, target: self.build.host_target });
+ let cargo_clippy = self
+ .ensure(tool::CargoClippy { compiler: run_compiler, target: self.build.host_target });
let mut dylib_path = helpers::dylib_path();
dylib_path.insert(0, self.sysroot(run_compiler).join("lib"));
@@ -1454,9 +1455,10 @@ impl<'a> Builder<'a> {
pub fn cargo_miri_cmd(&self, run_compiler: Compiler) -> BootstrapCommand {
assert!(run_compiler.stage > 0, "miri can not be invoked at stage 0");
// Prepare the tools
- let miri = self.ensure(tool::Miri { compiler: run_compiler, target: self.build.build });
+ let miri =
+ self.ensure(tool::Miri { compiler: run_compiler, target: self.build.host_target });
let cargo_miri =
- self.ensure(tool::CargoMiri { compiler: run_compiler, target: self.build.build });
+ self.ensure(tool::CargoMiri { compiler: run_compiler, target: self.build.host_target });
// Invoke cargo-miri, make sure it can find miri and cargo.
let mut cmd = command(cargo_miri.tool_path);
cmd.env("MIRI", &miri.tool_path);
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index a264d772c5629..a26a96f2815e6 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -46,7 +46,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
.join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
t!(fs::create_dir_all(&dir));
config.out = dir;
- config.build = TargetSelection::from_user(TEST_TRIPLE_1);
+ config.host_target = TargetSelection::from_user(TEST_TRIPLE_1);
config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect();
config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect();
config
@@ -1102,7 +1102,7 @@ fn test_prebuilt_llvm_config_path_resolution() {
let actual = drop_win_disk_prefix_if_present(actual);
assert_eq!(expected, actual);
- let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+ let actual = prebuilt_llvm_config(&builder, builder.config.host_target, false)
.llvm_result()
.llvm_config
.clone();
@@ -1120,15 +1120,15 @@ fn test_prebuilt_llvm_config_path_resolution() {
let build = Build::new(config.clone());
let builder = Builder::new(&build);
- let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+ let actual = prebuilt_llvm_config(&builder, builder.config.host_target, false)
.llvm_result()
.llvm_config
.clone();
let expected = builder
.out
- .join(builder.config.build)
+ .join(builder.config.host_target)
.join("llvm/bin")
- .join(exe("llvm-config", builder.config.build));
+ .join(exe("llvm-config", builder.config.host_target));
assert_eq!(expected, actual);
let config = configure(
@@ -1143,15 +1143,15 @@ fn test_prebuilt_llvm_config_path_resolution() {
let build = Build::new(config.clone());
let builder = Builder::new(&build);
- let actual = prebuilt_llvm_config(&builder, builder.config.build, false)
+ let actual = prebuilt_llvm_config(&builder, builder.config.host_target, false)
.llvm_result()
.llvm_config
.clone();
let expected = builder
.out
- .join(builder.config.build)
+ .join(builder.config.host_target)
.join("ci-llvm/bin")
- .join(exe("llvm-config", builder.config.build));
+ .join(exe("llvm-config", builder.config.host_target));
assert_eq!(expected, actual);
}
}
@@ -1163,7 +1163,7 @@ fn test_is_builder_target() {
for (target1, target2) in [(target1, target2), (target2, target1)] {
let mut config = configure("build", &[], &[]);
- config.build = target1;
+ config.host_target = target1;
let build = Build::new(config);
let builder = Builder::new(&build);
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 860aa120326a3..6aff376bde353 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -221,7 +221,7 @@ pub struct Config {
pub reproducible_artifacts: Vec,
- pub build: TargetSelection,
+ pub host_target: TargetSelection,
pub hosts: Vec,
pub targets: Vec,
pub local_rebuild: bool,
@@ -346,7 +346,7 @@ impl Config {
stderr_is_tty: std::io::stderr().is_terminal(),
// set by build.rs
- build: TargetSelection::from_user(env!("BUILD_TRIPLE")),
+ host_target: TargetSelection::from_user(env!("BUILD_TRIPLE")),
src: {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
@@ -727,7 +727,7 @@ impl Config {
config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0))));
if let Some(file_build) = build {
- config.build = TargetSelection::from_user(&file_build);
+ config.host_target = TargetSelection::from_user(&file_build);
};
set(&mut config.out, flags.build_dir.or_else(|| build_dir.map(PathBuf::from)));
@@ -753,10 +753,10 @@ impl Config {
config.download_beta_toolchain();
config
.out
- .join(config.build)
+ .join(config.host_target)
.join("stage0")
.join("bin")
- .join(exe("rustc", config.build))
+ .join(exe("rustc", config.host_target))
};
config.initial_sysroot = t!(PathBuf::from_str(
@@ -777,7 +777,7 @@ impl Config {
cargo
} else {
config.download_beta_toolchain();
- config.initial_sysroot.join("bin").join(exe("cargo", config.build))
+ config.initial_sysroot.join("bin").join(exe("cargo", config.host_target))
};
// NOTE: it's important this comes *after* we set `initial_rustc` just above.
@@ -792,7 +792,7 @@ impl Config {
} else if let Some(file_host) = host {
file_host.iter().map(|h| TargetSelection::from_user(h)).collect()
} else {
- vec![config.build]
+ vec![config.host_target]
};
config.targets = if let Some(TargetSelectionList(arg_target)) = flags.target {
arg_target
@@ -926,17 +926,19 @@ impl Config {
}
if config.llvm_from_ci {
- let triple = &config.build.triple;
+ let triple = &config.host_target.triple;
let ci_llvm_bin = config.ci_llvm_root().join("bin");
let build_target = config
.target_config
- .entry(config.build)
+ .entry(config.host_target)
.or_insert_with(|| Target::from_triple(triple));
check_ci_llvm!(build_target.llvm_config);
check_ci_llvm!(build_target.llvm_filecheck);
- build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", config.build)));
- build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build)));
+ build_target.llvm_config =
+ Some(ci_llvm_bin.join(exe("llvm-config", config.host_target)));
+ build_target.llvm_filecheck =
+ Some(ci_llvm_bin.join(exe("FileCheck", config.host_target)));
}
config.apply_dist_config(toml.dist);
@@ -953,7 +955,7 @@ impl Config {
);
}
- if config.lld_enabled && config.is_system_llvm(config.build) {
+ if config.lld_enabled && config.is_system_llvm(config.host_target) {
eprintln!(
"Warning: LLD is enabled when using external llvm-config. LLD will not be built and copied to the sysroot."
);
@@ -1147,13 +1149,13 @@ impl Config {
/// The absolute path to the downloaded LLVM artifacts.
pub(crate) fn ci_llvm_root(&self) -> PathBuf {
assert!(self.llvm_from_ci);
- self.out.join(self.build).join("ci-llvm")
+ self.out.join(self.host_target).join("ci-llvm")
}
/// Directory where the extracted `rustc-dev` component is stored.
pub(crate) fn ci_rustc_dir(&self) -> PathBuf {
assert!(self.download_rustc());
- self.out.join(self.build).join("ci-rustc")
+ self.out.join(self.host_target).join("ci-rustc")
}
/// Determine whether llvm should be linked dynamically.
@@ -1237,7 +1239,7 @@ impl Config {
// Check the config compatibility
// FIXME: this doesn't cover `--set` flags yet.
let res = check_incompatible_options_for_ci_rustc(
- self.build,
+ self.host_target,
current_config_toml,
ci_config_toml,
);
@@ -1473,7 +1475,7 @@ impl Config {
debug_assertions_requested: bool,
llvm_assertions: bool,
) -> Option {
- if !is_download_ci_available(&self.build.triple, llvm_assertions) {
+ if !is_download_ci_available(&self.host_target.triple, llvm_assertions) {
return None;
}
@@ -1709,7 +1711,7 @@ impl Config {
/// Checks if the given target is the same as the host target.
pub fn is_host_target(&self, target: TargetSelection) -> bool {
- self.build == target
+ self.host_target == target
}
/// Returns `true` if this is an external version of LLVM not managed by bootstrap.
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index bc4fa73a36266..ea0251e209af0 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -59,7 +59,7 @@ pub struct Flags {
pub build_dir: Option,
#[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "BUILD")]
- /// build target of the stage0 compiler
+ /// host target of the stage0 compiler
pub build: Option,
#[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)]
diff --git a/src/bootstrap/src/core/config/toml/mod.rs b/src/bootstrap/src/core/config/toml/mod.rs
index ac4e249e5802d..01eb243159cea 100644
--- a/src/bootstrap/src/core/config/toml/mod.rs
+++ b/src/bootstrap/src/core/config/toml/mod.rs
@@ -147,7 +147,7 @@ impl Config {
}
let builder_config_path =
- self.out.join(self.build.triple).join(build_name).join(BUILDER_CONFIG_FILENAME);
+ self.out.join(self.host_target.triple).join(build_name).join(BUILDER_CONFIG_FILENAME);
Self::get_toml(&builder_config_path)
}
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index bb18fa802afeb..642f2f2271d8f 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -621,13 +621,13 @@ impl Config {
// thus, disabled
// - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
// when the config sets `rust.lld = false`
- if self.build.triple == "x86_64-unknown-linux-gnu"
- && self.hosts == [self.build]
+ if self.host_target.triple == "x86_64-unknown-linux-gnu"
+ && self.hosts == [self.host_target]
&& (self.channel == "dev" || self.channel == "nightly")
{
let no_llvm_config = self
.target_config
- .get(&self.build)
+ .get(&self.host_target)
.is_some_and(|target_config| target_config.llvm_config.is_none());
let enable_lld = self.llvm_from_ci || no_llvm_config;
// Prefer the config setting in case an explicit opt-out is needed.
diff --git a/src/bootstrap/src/core/config/toml/target.rs b/src/bootstrap/src/core/config/toml/target.rs
index b8fc3e74c354d..b9f6780ca3fe1 100644
--- a/src/bootstrap/src/core/config/toml/target.rs
+++ b/src/bootstrap/src/core/config/toml/target.rs
@@ -101,7 +101,7 @@ impl Config {
let mut target = Target::from_triple(&triple);
if let Some(ref s) = cfg.llvm_config {
- if self.download_rustc_commit.is_some() && triple == *self.build.triple {
+ if self.download_rustc_commit.is_some() && triple == *self.host_target.triple {
panic!(
"setting llvm_config for the host is incompatible with download-rustc"
);
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index f349b9a87edb0..88a58e580e60f 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -256,7 +256,7 @@ impl Config {
}
curl.arg(url);
if !self.check_run(&mut curl) {
- if self.build.contains("windows-msvc") {
+ if self.host_target.contains("windows-msvc") {
eprintln!("Fallback to PowerShell");
for _ in 0..3 {
let powershell = command("PowerShell.exe").allow_failure().args([
@@ -411,7 +411,7 @@ impl Config {
let date = &self.stage0_metadata.compiler.date;
let version = &self.stage0_metadata.compiler.version;
- let host = self.build;
+ let host = self.host_target;
let clippy_stamp =
BuildStamp::new(&self.initial_sysroot).with_prefix("clippy").add_stamp(date);
@@ -449,7 +449,7 @@ impl Config {
let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
let channel = format!("{version}-{date}");
- let host = self.build;
+ let host = self.host_target;
let bin_root = self.out.join(host).join("rustfmt");
let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host));
let rustfmt_stamp = BuildStamp::new(&bin_root).with_prefix("rustfmt").add_stamp(channel);
@@ -557,11 +557,11 @@ impl Config {
extra_components: &[&str],
download_component: fn(&Config, String, &str, &str),
) {
- let host = self.build.triple;
+ let host = self.host_target.triple;
let bin_root = self.out.join(host).join(sysroot);
let rustc_stamp = BuildStamp::new(&bin_root).with_prefix("rustc").add_stamp(stamp_key);
- if !bin_root.join("bin").join(exe("rustc", self.build)).exists()
+ if !bin_root.join("bin").join(exe("rustc", self.host_target)).exists()
|| !rustc_stamp.is_up_to_date()
{
if bin_root.exists() {
@@ -630,7 +630,7 @@ impl Config {
t!(fs::create_dir_all(&cache_dir));
}
- let bin_root = self.out.join(self.build).join(destination);
+ let bin_root = self.out.join(self.host_target).join(destination);
let tarball = cache_dir.join(&filename);
let (base_url, url, should_verify) = match mode {
DownloadSource::CI => {
@@ -759,7 +759,7 @@ download-rustc = false
let now = std::time::SystemTime::now();
let file_times = fs::FileTimes::new().set_accessed(now).set_modified(now);
- let llvm_config = llvm_root.join("bin").join(exe("llvm-config", self.build));
+ let llvm_config = llvm_root.join("bin").join(exe("llvm-config", self.host_target));
t!(crate::utils::helpers::set_file_times(llvm_config, file_times));
if self.should_fix_bins_and_dylibs() {
@@ -814,7 +814,7 @@ download-rustc = false
&self.stage0_metadata.config.artifacts_server
};
let version = self.artifact_version_part(llvm_sha);
- let filename = format!("rust-dev-{}-{}.tar.xz", version, self.build.triple);
+ let filename = format!("rust-dev-{}-{}.tar.xz", version, self.host_target.triple);
let tarball = rustc_cache.join(&filename);
if !tarball.exists() {
let help_on_error = "ERROR: failed to download llvm from ci
@@ -844,7 +844,7 @@ download-rustc = false
}
let base = &self.stage0_metadata.config.artifacts_server;
let version = self.artifact_version_part(gcc_sha);
- let filename = format!("gcc-{version}-{}.tar.xz", self.build.triple);
+ let filename = format!("gcc-{version}-{}.tar.xz", self.host_target.triple);
let tarball = gcc_cache.join(&filename);
if !tarball.exists() {
let help_on_error = "ERROR: failed to download gcc from ci
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index b7bbd294f0e86..ef776e2194365 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -109,9 +109,9 @@ pub fn check(build: &mut Build) {
// Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`.
#[cfg(not(test))]
- if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci {
+ if !build.config.dry_run() && !build.host_target.is_msvc() && build.config.llvm_from_ci {
let builder = Builder::new(build);
- let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build });
+ let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.host_target });
match libcxx_version {
tool::LibcxxVersion::Gnu(version) => {
@@ -237,7 +237,7 @@ than building it.
}
// skip check for cross-targets
- if skip_target_sanity && target != &build.build {
+ if skip_target_sanity && target != &build.host_target {
continue;
}
@@ -308,7 +308,7 @@ than building it.
if build.config.llvm_enabled(*host) {
// Externally configured LLVM requires FileCheck to exist
- let filecheck = build.llvm_filecheck(build.build);
+ let filecheck = build.llvm_filecheck(build.host_target);
if !filecheck.starts_with(&build.out)
&& !filecheck.exists()
&& build.config.codegen_tests
@@ -333,7 +333,7 @@ than building it.
}
// skip check for cross-targets
- if skip_target_sanity && target != &build.build {
+ if skip_target_sanity && target != &build.host_target {
continue;
}
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 88d5d02682061..25e59bfe3a889 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -175,7 +175,7 @@ pub struct Build {
verbosity: usize,
/// Build triple for the pre-compiled snapshot compiler.
- build: TargetSelection,
+ host_target: TargetSelection,
/// Which triples to produce a compiler toolchain for.
hosts: Vec,
/// Which triples to build libraries (core/alloc/std/test/proc_macro) for.
@@ -420,7 +420,7 @@ impl Build {
if bootstrap_out.ends_with("deps") {
bootstrap_out.pop();
}
- if !bootstrap_out.join(exe("rustc", config.build)).exists() && !cfg!(test) {
+ if !bootstrap_out.join(exe("rustc", config.host_target)).exists() && !cfg!(test) {
// this restriction can be lifted whenever https://github.com/rust-lang/rfcs/pull/3028 is implemented
panic!(
"`rustc` not found in {}, run `cargo build --bins` before `cargo run`",
@@ -436,7 +436,9 @@ impl Build {
initial_lld,
initial_relative_libdir,
initial_rustc: config.initial_rustc.clone(),
- initial_rustdoc: config.initial_rustc.with_file_name(exe("rustdoc", config.build)),
+ initial_rustdoc: config
+ .initial_rustc
+ .with_file_name(exe("rustdoc", config.host_target)),
initial_cargo: config.initial_cargo.clone(),
initial_sysroot: config.initial_sysroot.clone(),
local_rebuild: config.local_rebuild,
@@ -444,7 +446,7 @@ impl Build {
doc_tests: config.cmd.doc_tests(),
verbosity: config.verbose,
- build: config.build,
+ host_target: config.host_target,
hosts: config.hosts.clone(),
targets: config.targets.clone(),
@@ -521,7 +523,7 @@ impl Build {
}
// Create symbolic link to use host sysroot from a consistent path (e.g., in the rust-analyzer config file).
- let build_triple = build.out.join(build.build);
+ let build_triple = build.out.join(build.host_target);
t!(fs::create_dir_all(&build_triple));
let host = build.out.join("host");
if host.is_symlink() {
@@ -932,7 +934,7 @@ impl Build {
/// Returns the libdir of the snapshot compiler.
fn rustc_snapshot_libdir(&self) -> PathBuf {
- self.rustc_snapshot_sysroot().join(libdir(self.config.build))
+ self.rustc_snapshot_sysroot().join(libdir(self.config.host_target))
}
/// Returns the sysroot of the snapshot compiler.
@@ -973,7 +975,7 @@ impl Build {
what: impl Display,
target: impl Into