diff --git a/RELEASES.md b/RELEASES.md
index 29c872eb44896..1b9bc62ba3a2d 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -100,6 +100,9 @@ Compatibility Notes
The reason is that these types have different roles: `std::panic::PanicHookInfo` is the argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in std context (where panics can have an arbitrary payload), while `core::panic::PanicInfo` is the argument to the [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) in no_std context (where panics always carry a formatted *message*). Separating these types allows us to add more useful methods to these types, such as `std::panic::PanicHookInfo::payload_as_str()` and `core::panic::PanicInfo::message()`.
* The new sort implementations may panic if a type's implementation of [`Ord`](https://doc.rust-lang.org/std/cmp/trait.Ord.html) (or the given comparison function) does not implement a [total order](https://en.wikipedia.org/wiki/Total_order) as the trait requires. `Ord`'s supertraits (`PartialOrd`, `Eq`, and `PartialEq`) must also be consistent. The previous implementations would not "notice" any problem, but the new implementations have a good chance of detecting inconsistencies, throwing a panic rather than returning knowingly unsorted data.
+* [In very rare cases, a change in the internal evaluation order of the trait
+ solver may result in new fatal overflow errors.](https://github.com/rust-lang/rust/pull/126128)
+
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 618602ed70f44..d55220ba5c3a4 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -353,9 +353,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec {
None
}
})
- .filter(|feature| {
- RUSTC_SPECIAL_FEATURES.contains(feature) || features.contains(&Symbol::intern(feature))
- })
+ .filter(|feature| features.contains(&Symbol::intern(feature)))
.map(|feature| Symbol::intern(feature))
.collect()
}
diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs
index 0f2c0eee27d2f..aaa95f6b7f19e 100644
--- a/compiler/rustc_data_structures/src/steal.rs
+++ b/compiler/rustc_data_structures/src/steal.rs
@@ -57,6 +57,7 @@ impl Steal {
///
/// This should not be used within rustc as it leaks information not tracked
/// by the query system, breaking incremental compilation.
+ #[cfg_attr(not(bootstrap), rustc_lint_untracked_query_information)]
pub fn is_stolen(&self) -> bool {
self.value.borrow().is_none()
}
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index e2491922b8df6..e86421f2150db 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -793,6 +793,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_lint_query_instability, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
),
+ // Used by the `rustc::untracked_query_information` lint to warn methods which
+ // might not be stable during incremental compilation.
+ rustc_attr!(
+ rustc_lint_untracked_query_information, Normal, template!(Word),
+ WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
+ ),
// Used by the `rustc::diagnostic_outside_of_impl` lints to assist in changes to diagnostic
// APIs. Any function with this attribute will be checked by that lint.
rustc_attr!(
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 353345958337c..759320b9eb65f 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -699,6 +699,9 @@ lint_ptr_null_checks_ref = references are not nullable, so checking them for nul
lint_query_instability = using `{$query}` can result in unstable query results
.note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+lint_query_untracked = `{$method}` accesses information that is not tracked by the query system
+ .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
lint_range_use_inclusive_range = use an inclusive range instead
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 2e8116b8ba892..9d637c1eb7f84 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -17,8 +17,8 @@ use tracing::debug;
use crate::lints::{
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
- NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
- TykindKind, TypeIrInherentUsage, UntranslatableDiag,
+ NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag, TyQualified,
+ TykindDiag, TykindKind, TypeIrInherentUsage, UntranslatableDiag,
};
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
@@ -88,7 +88,18 @@ declare_tool_lint! {
report_in_external_macro: true
}
-declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]);
+declare_tool_lint! {
+ /// The `untracked_query_information` lint detects use of methods which leak information not
+ /// tracked by the query system, such as whether a `Steal` value has already been stolen. In
+ /// order not to break incremental compilation, such methods must be used very carefully or not
+ /// at all.
+ pub rustc::UNTRACKED_QUERY_INFORMATION,
+ Allow,
+ "require explicit opt-in when accessing information not tracked by the query system",
+ report_in_external_macro: true
+}
+
+declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUERY_INFORMATION]);
impl LateLintPass<'_> for QueryStability {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
@@ -102,6 +113,13 @@ impl LateLintPass<'_> for QueryStability {
QueryInstability { query: cx.tcx.item_name(def_id) },
);
}
+ if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) {
+ cx.emit_span_lint(
+ UNTRACKED_QUERY_INFORMATION,
+ span,
+ QueryUntracked { method: cx.tcx.item_name(def_id) },
+ );
+ }
}
}
}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index c5a5c5b30afef..105a90de03407 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -609,6 +609,7 @@ fn register_internals(store: &mut LintStore) {
vec![
LintId::of(DEFAULT_HASH_TYPES),
LintId::of(POTENTIAL_QUERY_INSTABILITY),
+ LintId::of(UNTRACKED_QUERY_INFORMATION),
LintId::of(USAGE_OF_TY_TYKIND),
LintId::of(PASS_BY_VALUE),
LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 7ca282b7c8541..9050f36acba7b 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -894,6 +894,13 @@ pub(crate) struct QueryInstability {
pub query: Symbol,
}
+#[derive(LintDiagnostic)]
+#[diag(lint_query_untracked)]
+#[note]
+pub(crate) struct QueryUntracked {
+ pub method: Symbol,
+}
+
#[derive(LintDiagnostic)]
#[diag(lint_span_use_eq_ctxt)]
pub(crate) struct SpanUseEqCtxtDiag;
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 748ca047754a9..22a4b688c517c 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1307,6 +1307,9 @@ pub enum Rvalue<'tcx> {
/// If the type of the place is an array, this is the array length. For slices (`[T]`, not
/// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
/// ill-formed for places of other types.
+ ///
+ /// This cannot be a `UnOp(PtrMetadata, _)` because that expects a value, and we only
+ /// have a place, and `UnOp(PtrMetadata, RawPtr(place))` is not a thing.
Len(Place<'tcx>),
/// Performs essentially all of the casts that can be performed via `as`.
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 21478a44b0e14..e41f89a3c9da9 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -125,7 +125,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
[sym::coverage, ..] => self.check_coverage(attr, span, target),
[sym::optimize, ..] => self.check_optimize(hir_id, attr, target),
- [sym::no_sanitize, ..] => self.check_no_sanitize(hir_id, attr, span, target),
+ [sym::no_sanitize, ..] => {
+ self.check_applied_to_fn_or_method(hir_id, attr, span, target)
+ }
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
[sym::target_feature, ..] => {
@@ -166,10 +168,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)
}
[sym::rustc_lint_query_instability, ..] => {
- self.check_rustc_lint_query_instability(hir_id, attr, span, target)
+ self.check_applied_to_fn_or_method(hir_id, attr, span, target)
+ }
+ [sym::rustc_lint_untracked_query_information, ..] => {
+ self.check_applied_to_fn_or_method(hir_id, attr, span, target)
}
[sym::rustc_lint_diagnostics, ..] => {
- self.check_rustc_lint_diagnostics(hir_id, attr, span, target)
+ self.check_applied_to_fn_or_method(hir_id, attr, span, target)
}
[sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target),
[sym::rustc_lint_opt_deny_field_access, ..] => {
@@ -452,11 +457,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
- /// Checks that `#[no_sanitize(..)]` is applied to a function or method.
- fn check_no_sanitize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
- self.check_applied_to_fn_or_method(hir_id, attr, span, target)
- }
-
fn check_generic_attr(
&self,
hir_id: HirId,
@@ -1635,30 +1635,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
- /// Checks that the `#[rustc_lint_query_instability]` attribute is only applied to a function
- /// or method.
- fn check_rustc_lint_query_instability(
- &self,
- hir_id: HirId,
- attr: &Attribute,
- span: Span,
- target: Target,
- ) {
- self.check_applied_to_fn_or_method(hir_id, attr, span, target)
- }
-
- /// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or
- /// method.
- fn check_rustc_lint_diagnostics(
- &self,
- hir_id: HirId,
- attr: &Attribute,
- span: Span,
- target: Target,
- ) {
- self.check_applied_to_fn_or_method(hir_id, attr, span, target)
- }
-
/// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct.
fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) {
match target {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 3476520960585..cc63769d51df6 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1653,6 +1653,7 @@ symbols! {
rustc_lint_opt_deny_field_access,
rustc_lint_opt_ty,
rustc_lint_query_instability,
+ rustc_lint_untracked_query_information,
rustc_macro_transparency,
rustc_main,
rustc_mir,
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d7ed4edcc0041..08d06cad55d06 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -2277,6 +2277,14 @@ impl fmt::Debug for F {
/// `addr_of!(expr)` is equivalent to `&raw const expr`. The macro is *soft-deprecated*;
/// use `&raw const` instead.
///
+/// It is still an open question under which conditions writing through an `addr_of!`-created
+/// pointer is permitted. If the place `expr` evaluates to is based on a raw pointer, then the
+/// result of `addr_of!` inherits all permissions from that raw pointer. However, if the place is
+/// based on a reference, local variable, or `static`, then until all details are decided, the same
+/// rules as for shared references apply: it is UB to write through a pointer created with this
+/// operation, except for bytes located inside an `UnsafeCell`. Use `&raw mut` (or [`addr_of_mut`])
+/// to create a raw pointer that definitely permits mutation.
+///
/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
/// and points to initialized data. For cases where those requirements do not hold,
/// raw pointers should be used instead. However, `&expr as *const _` creates a reference
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 0390bb59a8984..c19eeedb35426 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -250,7 +250,7 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::from_millis(2569);
+ /// let duration = Duration::from_millis(2_569);
///
/// assert_eq!(2, duration.as_secs());
/// assert_eq!(569_000_000, duration.subsec_nanos());
@@ -279,7 +279,7 @@ impl Duration {
/// let duration = Duration::from_micros(1_000_002);
///
/// assert_eq!(1, duration.as_secs());
- /// assert_eq!(2000, duration.subsec_nanos());
+ /// assert_eq!(2_000, duration.subsec_nanos());
/// ```
#[stable(feature = "duration_from_micros", since = "1.27.0")]
#[must_use]
@@ -472,7 +472,7 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::new(5, 730023852);
+ /// let duration = Duration::new(5, 730_023_852);
/// assert_eq!(duration.as_secs(), 5);
/// ```
///
@@ -501,7 +501,7 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::from_millis(5432);
+ /// let duration = Duration::from_millis(5_432);
/// assert_eq!(duration.as_secs(), 5);
/// assert_eq!(duration.subsec_millis(), 432);
/// ```
@@ -547,7 +547,7 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::from_millis(5010);
+ /// let duration = Duration::from_millis(5_010);
/// assert_eq!(duration.as_secs(), 5);
/// assert_eq!(duration.subsec_nanos(), 10_000_000);
/// ```
@@ -566,8 +566,8 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::new(5, 730023852);
- /// assert_eq!(duration.as_millis(), 5730);
+ /// let duration = Duration::new(5, 730_023_852);
+ /// assert_eq!(duration.as_millis(), 5_730);
/// ```
#[stable(feature = "duration_as_u128", since = "1.33.0")]
#[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
@@ -584,8 +584,8 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::new(5, 730023852);
- /// assert_eq!(duration.as_micros(), 5730023);
+ /// let duration = Duration::new(5, 730_023_852);
+ /// assert_eq!(duration.as_micros(), 5_730_023);
/// ```
#[stable(feature = "duration_as_u128", since = "1.33.0")]
#[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
@@ -602,8 +602,8 @@ impl Duration {
/// ```
/// use std::time::Duration;
///
- /// let duration = Duration::new(5, 730023852);
- /// assert_eq!(duration.as_nanos(), 5730023852);
+ /// let duration = Duration::new(5, 730_023_852);
+ /// assert_eq!(duration.as_nanos(), 5_730_023_852);
/// ```
#[stable(feature = "duration_as_u128", since = "1.33.0")]
#[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
@@ -879,7 +879,7 @@ impl Duration {
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 345_678_000);
- /// assert_eq!(dur.as_millis_f64(), 2345.678);
+ /// assert_eq!(dur.as_millis_f64(), 2_345.678);
/// ```
#[unstable(feature = "duration_millis_float", issue = "122451")]
#[must_use]
@@ -900,7 +900,7 @@ impl Duration {
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 345_678_000);
- /// assert_eq!(dur.as_millis_f32(), 2345.678);
+ /// assert_eq!(dur.as_millis_f32(), 2_345.678);
/// ```
#[unstable(feature = "duration_millis_float", issue = "122451")]
#[must_use]
@@ -1017,7 +1017,7 @@ impl Duration {
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641));
- /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847800, 0));
+ /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0));
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[must_use = "this returns the result of the operation, \
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index 7f7faf077d047..066f913568c54 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -91,8 +91,8 @@ impl Step for Std {
// We skip populating the sysroot in non-zero stage because that'll lead
// to rlib/rmeta conflicts if std gets built during this session.
if compiler.stage == 0 {
- let libdir = builder.sysroot_libdir(compiler, target);
- let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+ let libdir = builder.sysroot_target_libdir(compiler, target);
+ let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
}
drop(_guard);
@@ -257,8 +257,8 @@ impl Step for Rustc {
false,
);
- let libdir = builder.sysroot_libdir(compiler, target);
- let hostdir = builder.sysroot_libdir(compiler, compiler.host);
+ let libdir = builder.sysroot_target_libdir(compiler, target);
+ let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
add_to_sysroot(builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
}
}
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index eef548033f1c6..0d505e404608e 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -240,7 +240,7 @@ impl Step for Std {
.join("bin");
if src_sysroot_bin.exists() {
let target_sysroot_bin =
- builder.sysroot_libdir(compiler, target).parent().unwrap().join("bin");
+ builder.sysroot_target_libdir(compiler, target).parent().unwrap().join("bin");
t!(fs::create_dir_all(&target_sysroot_bin));
builder.cp_link_r(&src_sysroot_bin, &target_sysroot_bin);
}
@@ -354,7 +354,7 @@ fn copy_third_party_objects(
&& (target.contains("linux") || target.contains("fuchsia"))
{
let libunwind_path =
- copy_llvm_libunwind(builder, target, &builder.sysroot_libdir(*compiler, target));
+ copy_llvm_libunwind(builder, target, &builder.sysroot_target_libdir(*compiler, target));
target_deps.push((libunwind_path, DependencyType::Target));
}
@@ -367,7 +367,8 @@ fn copy_self_contained_objects(
compiler: &Compiler,
target: TargetSelection,
) -> Vec<(PathBuf, DependencyType)> {
- let libdir_self_contained = builder.sysroot_libdir(*compiler, target).join("self-contained");
+ let libdir_self_contained =
+ builder.sysroot_target_libdir(*compiler, target).join("self-contained");
t!(fs::create_dir_all(&libdir_self_contained));
let mut target_deps = vec![];
@@ -675,8 +676,8 @@ impl Step for StdLink {
let hostdir = sysroot.join(lib).join("rustlib").join(compiler.host).join("lib");
(libdir, hostdir)
} else {
- let libdir = builder.sysroot_libdir(target_compiler, target);
- let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
+ let libdir = builder.sysroot_target_libdir(target_compiler, target);
+ let hostdir = builder.sysroot_target_libdir(target_compiler, compiler.host);
(libdir, hostdir)
};
@@ -743,7 +744,7 @@ fn copy_sanitizers(
}
let mut target_deps = Vec::new();
- let libdir = builder.sysroot_libdir(*compiler, target);
+ let libdir = builder.sysroot_target_libdir(*compiler, target);
for runtime in &runtimes {
let dst = libdir.join(&runtime.name);
@@ -821,7 +822,7 @@ impl Step for StartupObjects {
let src_dir = &builder.src.join("library").join("rtstartup");
let dst_dir = &builder.native_dir(target).join("rtstartup");
- let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
+ let sysroot_dir = &builder.sysroot_target_libdir(for_compiler, target);
t!(fs::create_dir_all(dst_dir));
for file in &["rsbegin", "rsend"] {
@@ -931,7 +932,12 @@ impl Step for Rustc {
// NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler,
// so its artifacts can't be reused.
if builder.download_rustc() && compiler.stage != 0 {
- builder.ensure(Sysroot { compiler, force_recompile: false });
+ let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
+ cp_rustc_component_to_ci_sysroot(
+ builder,
+ &sysroot,
+ builder.config.ci_rustc_dev_contents(),
+ );
return compiler.stage;
}
@@ -1273,10 +1279,17 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect
}
}
+/// `RustcLink` copies all of the rlibs from the rustc build into the previous stage's sysroot.
+/// This is necessary for tools using `rustc_private`, where the previous compiler will build
+/// a tool against the next compiler.
+/// To build a tool against a compiler, the rlibs of that compiler that it links against
+/// must be in the sysroot of the compiler that's doing the compiling.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct RustcLink {
+ /// The compiler whose rlibs we are copying around.
pub compiler: Compiler,
- pub target_compiler: Compiler,
+ /// This is the compiler into whose sysroot we want to copy the rlibs into.
+ pub previous_stage_compiler: Compiler,
pub target: TargetSelection,
/// Not actually used; only present to make sure the cache invalidation is correct.
crates: Vec,
@@ -1286,7 +1299,7 @@ impl RustcLink {
fn from_rustc(rustc: Rustc, host_compiler: Compiler) -> Self {
Self {
compiler: host_compiler,
- target_compiler: rustc.compiler,
+ previous_stage_compiler: rustc.compiler,
target: rustc.target,
crates: rustc.crates,
}
@@ -1303,12 +1316,12 @@ impl Step for RustcLink {
/// Same as `std_link`, only for librustc
fn run(self, builder: &Builder<'_>) {
let compiler = self.compiler;
- let target_compiler = self.target_compiler;
+ let previous_stage_compiler = self.previous_stage_compiler;
let target = self.target;
add_to_sysroot(
builder,
- &builder.sysroot_libdir(target_compiler, target),
- &builder.sysroot_libdir(target_compiler, compiler.host),
+ &builder.sysroot_target_libdir(previous_stage_compiler, target),
+ &builder.sysroot_target_libdir(previous_stage_compiler, compiler.host),
&librustc_stamp(builder, compiler, target),
);
}
@@ -1845,7 +1858,7 @@ impl Step for Assemble {
let sysroot = builder.sysroot(target_compiler);
let rustc_libdir = builder.rustc_libdir(target_compiler);
t!(fs::create_dir_all(&rustc_libdir));
- let src_libdir = builder.sysroot_libdir(build_compiler, host);
+ let src_libdir = builder.sysroot_target_libdir(build_compiler, host);
for f in builder.read_dir(&src_libdir) {
let filename = f.file_name().into_string().unwrap();
if (is_dylib(&filename) || is_debug_info(&filename)) && !proc_macros.contains(&filename)
@@ -1858,7 +1871,7 @@ impl Step for Assemble {
// We prepend this bin directory to the user PATH when linking Rust binaries. To
// avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
- let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
+ let libdir = builder.sysroot_target_libdir(target_compiler, target_compiler.host);
let libdir_bin = libdir.parent().unwrap().join("bin");
t!(fs::create_dir_all(&libdir_bin));
if let Some(lld_install) = lld_install {
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 4957de2e1b791..9684ec946a09f 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -459,7 +459,8 @@ impl Step for Rustc {
// Copy over lld if it's there
if builder.config.lld_enabled {
- let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin");
+ let src_dir =
+ builder.sysroot_target_libdir(compiler, host).parent().unwrap().join("bin");
let rust_lld = exe("rust-lld", compiler.host);
builder.copy_link(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld));
let self_contained_lld_src_dir = src_dir.join("gcc-ld");
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index ffb617c642baf..ac68bbf805092 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -1186,6 +1186,9 @@ impl Step for RustcBook {
cmd.arg("--rustc");
cmd.arg(&rustc);
cmd.arg("--rustc-target").arg(self.target.rustc_target_arg());
+ if let Some(target_linker) = builder.linker(self.target) {
+ cmd.arg("--rustc-linker").arg(target_linker);
+ }
if builder.is_verbose() {
cmd.arg("--verbose");
}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 84a6b26a491ed..437d4327e3ef8 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -800,7 +800,7 @@ impl Step for RustdocTheme {
.arg(builder.src.join("src/librustdoc/html/static/css/rustdoc.css").to_str().unwrap())
.env("RUSTC_STAGE", self.compiler.stage.to_string())
.env("RUSTC_SYSROOT", builder.sysroot(self.compiler))
- .env("RUSTDOC_LIBDIR", builder.sysroot_libdir(self.compiler, self.compiler.host))
+ .env("RUSTDOC_LIBDIR", builder.sysroot_target_libdir(self.compiler, self.compiler.host))
.env("CFG_RELEASE_CHANNEL", &builder.config.channel)
.env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
.env("RUSTC_BOOTSTRAP", "1");
@@ -1728,7 +1728,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
// of them!
cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler));
- cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target));
+ cmd.arg("--run-lib-path").arg(builder.sysroot_target_libdir(compiler, target));
cmd.arg("--rustc-path").arg(builder.rustc(compiler));
let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js");
@@ -2553,7 +2553,7 @@ fn prepare_cargo_test(
// by `Cargo::new` and that actually makes things go wrong.
if builder.kind != Kind::Miri {
let mut dylib_path = dylib_path();
- dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
+ dylib_path.insert(0, PathBuf::from(&*builder.sysroot_target_libdir(compiler, target)));
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
}
@@ -2788,7 +2788,7 @@ impl Step for CrateRustdoc {
let libdir = if builder.download_rustc() {
builder.rustc_libdir(compiler)
} else {
- builder.sysroot_libdir(compiler, target).to_path_buf()
+ builder.sysroot_target_libdir(compiler, target).to_path_buf()
};
let mut dylib_path = dylib_path();
dylib_path.insert(0, PathBuf::from(&*libdir));
@@ -2913,7 +2913,7 @@ impl Step for RemoteCopyLibs {
cmd.run(builder);
// Push all our dylibs to the emulator
- for f in t!(builder.sysroot_libdir(compiler, target).read_dir()) {
+ for f in t!(builder.sysroot_target_libdir(compiler, target).read_dir()) {
let f = t!(f);
let name = f.file_name().into_string().unwrap();
if helpers::is_dylib(&name) {
@@ -3526,11 +3526,13 @@ impl Step for TestFloatParse {
fn run(self, builder: &Builder<'_>) {
let bootstrap_host = builder.config.build;
- let compiler = builder.compiler(0, bootstrap_host);
+ let compiler = builder.compiler(builder.top_stage, bootstrap_host);
let path = self.path.to_str().unwrap();
let crate_name = self.path.components().last().unwrap().as_os_str().to_str().unwrap();
- builder.ensure(compile::Std::new(compiler, self.host));
+ if !builder.download_rustc() {
+ builder.ensure(compile::Std::new(compiler, self.host));
+ }
// Run any unit tests in the crate
let cargo_test = tool::prepare_tool_cargo(
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 3a1eb43b801f5..d50b78f5c425e 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -448,7 +448,7 @@ impl ErrorIndex {
let compiler = builder.compiler_for(builder.top_stage, host, host);
let mut cmd = command(builder.ensure(ErrorIndex { compiler }));
let mut dylib_paths = builder.rustc_lib_paths(compiler);
- dylib_paths.push(PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host)));
+ dylib_paths.push(PathBuf::from(&builder.sysroot_target_libdir(compiler, compiler.host)));
add_dylib_path(dylib_paths, &mut cmd);
cmd
}
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index d7398b76cc91e..bc43c3c2b45d0 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1152,7 +1152,7 @@ impl<'a> Builder<'a> {
/// Returns the libdir where the standard library and other artifacts are
/// found for a compiler's sysroot.
- pub fn sysroot_libdir(&self, compiler: Compiler, target: TargetSelection) -> PathBuf {
+ pub fn sysroot_target_libdir(&self, compiler: Compiler, target: TargetSelection) -> PathBuf {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
struct Libdir {
compiler: Compiler,
@@ -1200,7 +1200,7 @@ impl<'a> Builder<'a> {
}
pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf {
- self.sysroot_libdir(compiler, compiler.host).with_file_name("codegen-backends")
+ self.sysroot_target_libdir(compiler, compiler.host).with_file_name("codegen-backends")
}
/// Returns the compiler's libdir where it stores the dynamic libraries that
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 82b640f54234d..c81ec710f2dc2 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -332,14 +332,20 @@ impl Build {
.trim()
.to_string();
- let initial_libdir = initial_target_dir
- .parent()
- .unwrap()
- .parent()
- .unwrap()
- .strip_prefix(&initial_sysroot)
- .unwrap()
- .to_path_buf();
+ // FIXME(Zalathar): Determining this path occasionally fails locally for
+ // unknown reasons, so we print some extra context to help track down why.
+ let find_initial_libdir = || {
+ let initial_libdir =
+ initial_target_dir.parent()?.parent()?.strip_prefix(&initial_sysroot).ok()?;
+ Some(initial_libdir.to_path_buf())
+ };
+ let Some(initial_libdir) = find_initial_libdir() else {
+ panic!(
+ "couldn't determine `initial_libdir` \
+ from target dir {initial_target_dir:?} \
+ and sysroot {initial_sysroot:?}"
+ )
+ };
let version = std::fs::read_to_string(src.join("src").join("version"))
.expect("failed to read src/version");
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index dc34c7844bfdd..095bfe158ff19 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1794,13 +1794,64 @@ fn render_impl(
let mut default_impl_items = Buffer::empty_from(w);
let impl_ = i.inner_impl();
+ // Impl items are grouped by kinds:
+ //
+ // 1. Constants
+ // 2. Types
+ // 3. Functions
+ //
+ // This order is because you can have associated constants used in associated types (like array
+ // length), and both in associcated functions. So with this order, when reading from top to
+ // bottom, you should see items definitions before they're actually used most of the time.
+ let mut assoc_types = Vec::new();
+ let mut methods = Vec::new();
+
if !impl_.is_negative_trait_impl() {
for trait_item in &impl_.items {
+ match *trait_item.kind {
+ clean::MethodItem(..) | clean::TyMethodItem(_) => methods.push(trait_item),
+ clean::TyAssocTypeItem(..) | clean::AssocTypeItem(..) => {
+ assoc_types.push(trait_item)
+ }
+ clean::TyAssocConstItem(..) | clean::AssocConstItem(_) => {
+ // We render it directly since they're supposed to come first.
+ doc_impl_item(
+ &mut default_impl_items,
+ &mut impl_items,
+ cx,
+ trait_item,
+ if trait_.is_some() { &i.impl_item } else { parent },
+ link,
+ render_mode,
+ false,
+ trait_,
+ rendering_params,
+ );
+ }
+ _ => {}
+ }
+ }
+
+ for assoc_type in assoc_types {
doc_impl_item(
&mut default_impl_items,
&mut impl_items,
cx,
- trait_item,
+ assoc_type,
+ if trait_.is_some() { &i.impl_item } else { parent },
+ link,
+ render_mode,
+ false,
+ trait_,
+ rendering_params,
+ );
+ }
+ for method in methods {
+ doc_impl_item(
+ &mut default_impl_items,
+ &mut impl_items,
+ cx,
+ method,
if trait_.is_some() { &i.impl_item } else { parent },
link,
render_mode,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index a0a72d59d123f..cda5409a460ee 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -843,55 +843,55 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
}
}
- if !required_types.is_empty() {
+ if !required_consts.is_empty() {
write_section_heading(
w,
- "Required Associated Types",
- "required-associated-types",
+ "Required Associated Constants",
+ "required-associated-consts",
None,
"
",
);
- for t in required_types {
+ for t in required_consts {
trait_item(w, cx, t, it);
}
w.write_str("