authorbors <bors@rust-lang.org> 2024-09-05 07:41:22 UTC
committerbors <bors@rust-lang.org> 2024-09-05 07:41:22 UTC
logeb33b43bab08223fa6b46abacc1e95e859fe375d
tree836d22aa6b503323c7b3d5247692f17153101af4
parent009e73825af0e59ad4fc603562e038b3dbd6593a
parent3190521a9865a6ffde047df34716ac1a59aaeb99

Auto merge of #129978 - matthiaskrgr:rollup-a7ryoox, r=matthiaskrgr

Rollup of 10 pull requests Successful merges: - #101339 (enable -Zrandomize-layout in debug CI builds ) - #120736 (rustdoc: add header map to the table of contents) - #127021 (Add target support for RTEMS Arm) - #128928 (CI: rfl: add more tools and steps) - #129584 (warn the user if the upstream master branch is old) - #129664 (Arbitrary self types v2: pointers feature gate.) - #129752 (Make supertrait and implied predicates queries defaulted) - #129918 (Update docs of `missing_abi` lint) - #129919 (Stabilize `waker_getters`) - #129925 (remove deprecated option `rust.split-debuginfo`) Failed merges: - #129789 (rustdoc: use strategic boxing to shrink `clean::Item`) r? `@ghost` `@rustbot` modify labels: rollup

110 files changed, 1675 insertions(+), 410 deletions(-)

Cargo.lock+1
......@@ -3569,6 +3569,7 @@ dependencies = [
35693569 "rustc_hir_pretty",
35703570 "rustc_hir_typeck",
35713571 "rustc_incremental",
3572 "rustc_index",
35723573 "rustc_infer",
35733574 "rustc_interface",
35743575 "rustc_lint",
compiler/rustc/Cargo.toml+1
......@@ -30,5 +30,6 @@ features = ['unprefixed_malloc_on_supported_platforms']
3030jemalloc = ['dep:jemalloc-sys']
3131llvm = ['rustc_driver_impl/llvm']
3232max_level_info = ['rustc_driver_impl/max_level_info']
33rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
3334rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']
3435# tidy-alphabetical-end
compiler/rustc_abi/src/layout.rs+7-4
......@@ -968,8 +968,8 @@ fn univariant<
968968 let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
969969 let mut max_repr_align = repr.align;
970970 let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
971 let optimize = !repr.inhibit_struct_field_reordering();
972 if optimize && fields.len() > 1 {
971 let optimize_field_order = !repr.inhibit_struct_field_reordering();
972 if optimize_field_order && fields.len() > 1 {
973973 let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
974974 let optimizing = &mut inverse_memory_index.raw[..end];
975975 let fields_excluding_tail = &fields.raw[..end];
......@@ -1176,7 +1176,7 @@ fn univariant<
11761176 // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
11771177 // Field 5 would be the first element, so memory_index is i:
11781178 // Note: if we didn't optimize, it's already right.
1179 let memory_index = if optimize {
1179 let memory_index = if optimize_field_order {
11801180 inverse_memory_index.invert_bijective_mapping()
11811181 } else {
11821182 debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices()));
......@@ -1189,6 +1189,9 @@ fn univariant<
11891189 }
11901190 let mut layout_of_single_non_zst_field = None;
11911191 let mut abi = Abi::Aggregate { sized };
1192
1193 let optimize_abi = !repr.inhibit_newtype_abi_optimization();
1194
11921195 // Try to make this a Scalar/ScalarPair.
11931196 if sized && size.bytes() > 0 {
11941197 // We skip *all* ZST here and later check if we are good in terms of alignment.
......@@ -1205,7 +1208,7 @@ fn univariant<
12051208 match field.abi {
12061209 // For plain scalars, or vectors of them, we can't unpack
12071210 // newtypes for `#[repr(C)]`, as that affects C ABIs.
1208 Abi::Scalar(_) | Abi::Vector { .. } if optimize => {
1211 Abi::Scalar(_) | Abi::Vector { .. } if optimize_abi => {
12091212 abi = field.abi;
12101213 }
12111214 // But scalar pairs are Rust-specific and get
compiler/rustc_abi/src/lib.rs+11-4
......@@ -43,14 +43,17 @@ bitflags! {
4343 const IS_SIMD = 1 << 1;
4444 const IS_TRANSPARENT = 1 << 2;
4545 // Internal only for now. If true, don't reorder fields.
46 // On its own it does not prevent ABI optimizations.
4647 const IS_LINEAR = 1 << 3;
47 // If true, the type's layout can be randomized using
48 // the seed stored in `ReprOptions.field_shuffle_seed`
48 // If true, the type's crate has opted into layout randomization.
49 // Other flags can still inhibit reordering and thus randomization.
50 // The seed stored in `ReprOptions.field_shuffle_seed`.
4951 const RANDOMIZE_LAYOUT = 1 << 4;
5052 // Any of these flags being set prevent field reordering optimisation.
51 const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits()
53 const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
5254 | ReprFlags::IS_SIMD.bits()
5355 | ReprFlags::IS_LINEAR.bits();
56 const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
5457 }
5558}
5659
......@@ -139,10 +142,14 @@ impl ReprOptions {
139142 self.c() || self.int.is_some()
140143 }
141144
145 pub fn inhibit_newtype_abi_optimization(&self) -> bool {
146 self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE)
147 }
148
142149 /// Returns `true` if this `#[repr()]` guarantees a fixed field order,
143150 /// e.g. `repr(C)` or `repr(<int>)`.
144151 pub fn inhibit_struct_field_reordering(&self) -> bool {
145 self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
152 self.flags.intersects(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE) || self.int.is_some()
146153 }
147154
148155 /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
compiler/rustc_driver_impl/Cargo.toml+5
......@@ -23,6 +23,7 @@ rustc_hir_analysis = { path = "../rustc_hir_analysis" }
2323rustc_hir_pretty = { path = "../rustc_hir_pretty" }
2424rustc_hir_typeck = { path = "../rustc_hir_typeck" }
2525rustc_incremental = { path = "../rustc_incremental" }
26rustc_index = { path = "../rustc_index" }
2627rustc_infer = { path = "../rustc_infer" }
2728rustc_interface = { path = "../rustc_interface" }
2829rustc_lint = { path = "../rustc_lint" }
......@@ -72,6 +73,10 @@ ctrlc = "3.4.4"
7273# tidy-alphabetical-start
7374llvm = ['rustc_interface/llvm']
7475max_level_info = ['rustc_log/max_level_info']
76rustc_randomized_layouts = [
77 'rustc_index/rustc_randomized_layouts',
78 'rustc_middle/rustc_randomized_layouts'
79]
7580rustc_use_parallel_compiler = [
7681 'rustc_data_structures/rustc_use_parallel_compiler',
7782 'rustc_interface/rustc_use_parallel_compiler',
compiler/rustc_feature/src/unstable.rs+3-1
......@@ -349,8 +349,10 @@ declare_features! (
349349 (unstable, adt_const_params, "1.56.0", Some(95174)),
350350 /// Allows defining an `#[alloc_error_handler]`.
351351 (unstable, alloc_error_handler, "1.29.0", Some(51540)),
352 /// Allows trait methods with arbitrary self types.
352 /// Allows inherent and trait methods with arbitrary self types.
353353 (unstable, arbitrary_self_types, "1.23.0", Some(44874)),
354 /// Allows inherent and trait methods with arbitrary self types that are raw pointers.
355 (unstable, arbitrary_self_types_pointers, "CURRENT_RUSTC_VERSION", Some(44874)),
354356 /// Enables experimental inline assembly support for additional architectures.
355357 (unstable, asm_experimental_arch, "1.58.0", Some(93335)),
356358 /// Allows using `label` operands in inline assembly.
compiler/rustc_hir_analysis/src/check/wfcheck.rs+63-19
......@@ -1652,6 +1652,13 @@ fn check_fn_or_method<'tcx>(
16521652 }
16531653}
16541654
1655/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
1656#[derive(Clone, Copy, PartialEq)]
1657enum ArbitrarySelfTypesLevel {
1658 Basic, // just arbitrary_self_types
1659 WithPointers, // both arbitrary_self_types and arbitrary_self_types_pointers
1660}
1661
16551662#[instrument(level = "debug", skip(wfcx))]
16561663fn check_method_receiver<'tcx>(
16571664 wfcx: &WfCheckingCtxt<'_, 'tcx>,
......@@ -1684,14 +1691,27 @@ fn check_method_receiver<'tcx>(
16841691 return Ok(());
16851692 }
16861693
1687 if tcx.features().arbitrary_self_types {
1688 if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
1689 // Report error; `arbitrary_self_types` was enabled.
1690 return Err(tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }));
1691 }
1694 let arbitrary_self_types_level = if tcx.features().arbitrary_self_types_pointers {
1695 Some(ArbitrarySelfTypesLevel::WithPointers)
1696 } else if tcx.features().arbitrary_self_types {
1697 Some(ArbitrarySelfTypesLevel::Basic)
16921698 } else {
1693 if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
1694 return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
1699 None
1700 };
1701
1702 if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) {
1703 return Err(match arbitrary_self_types_level {
1704 // Wherever possible, emit a message advising folks that the features
1705 // `arbitrary_self_types` or `arbitrary_self_types_pointers` might
1706 // have helped.
1707 None if receiver_is_valid(
1708 wfcx,
1709 span,
1710 receiver_ty,
1711 self_ty,
1712 Some(ArbitrarySelfTypesLevel::Basic),
1713 ) =>
1714 {
16951715 // Report error; would have worked with `arbitrary_self_types`.
16961716 feature_err(
16971717 &tcx.sess,
......@@ -1699,25 +1719,49 @@ fn check_method_receiver<'tcx>(
16991719 span,
17001720 format!(
17011721 "`{receiver_ty}` cannot be used as the type of `self` without \
1702 the `arbitrary_self_types` feature",
1722 the `arbitrary_self_types` feature",
17031723 ),
17041724 )
17051725 .with_help(fluent::hir_analysis_invalid_receiver_ty_help)
17061726 .emit()
1707 } else {
1708 // Report error; would not have worked with `arbitrary_self_types`.
1727 }
1728 None | Some(ArbitrarySelfTypesLevel::Basic)
1729 if receiver_is_valid(
1730 wfcx,
1731 span,
1732 receiver_ty,
1733 self_ty,
1734 Some(ArbitrarySelfTypesLevel::WithPointers),
1735 ) =>
1736 {
1737 // Report error; would have worked with `arbitrary_self_types_pointers`.
1738 feature_err(
1739 &tcx.sess,
1740 sym::arbitrary_self_types_pointers,
1741 span,
1742 format!(
1743 "`{receiver_ty}` cannot be used as the type of `self` without \
1744 the `arbitrary_self_types_pointers` feature",
1745 ),
1746 )
1747 .with_help(fluent::hir_analysis_invalid_receiver_ty_help)
1748 .emit()
1749 }
1750 _ =>
1751 // Report error; would not have worked with `arbitrary_self_types[_pointers]`.
1752 {
17091753 tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
1710 });
1711 }
1754 }
1755 });
17121756 }
17131757 Ok(())
17141758}
17151759
17161760/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
17171761/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1718/// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1719/// strict: `receiver_ty` must implement `Receiver` and directly implement
1720/// `Deref<Target = self_ty>`.
1762/// through a `*const/mut T` raw pointer if `arbitrary_self_types_pointers` is also enabled.
1763/// If neither feature is enabled, the requirements are more strict: `receiver_ty` must implement
1764/// `Receiver` and directly implement `Deref<Target = self_ty>`.
17211765///
17221766/// N.B., there are cases this function returns `true` but causes an error to be emitted,
17231767/// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
......@@ -1727,7 +1771,7 @@ fn receiver_is_valid<'tcx>(
17271771 span: Span,
17281772 receiver_ty: Ty<'tcx>,
17291773 self_ty: Ty<'tcx>,
1730 arbitrary_self_types_enabled: bool,
1774 arbitrary_self_types_enabled: Option<ArbitrarySelfTypesLevel>,
17311775) -> bool {
17321776 let infcx = wfcx.infcx;
17331777 let tcx = wfcx.tcx();
......@@ -1745,8 +1789,8 @@ fn receiver_is_valid<'tcx>(
17451789
17461790 let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
17471791
1748 // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1749 if arbitrary_self_types_enabled {
1792 // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
1793 if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) {
17501794 autoderef = autoderef.include_raw_pointers();
17511795 }
17521796
......@@ -1772,7 +1816,7 @@ fn receiver_is_valid<'tcx>(
17721816
17731817 // Without `feature(arbitrary_self_types)`, we require that each step in the
17741818 // deref chain implement `receiver`.
1775 if !arbitrary_self_types_enabled {
1819 if arbitrary_self_types_enabled.is_none() {
17761820 if !receiver_is_implemented(
17771821 wfcx,
17781822 receiver_trait_def_id,
compiler/rustc_hir_typeck/src/method/probe.rs+1-1
......@@ -403,7 +403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403403 mode,
404404 }));
405405 } else if bad_ty.reached_raw_pointer
406 && !self.tcx.features().arbitrary_self_types
406 && !self.tcx.features().arbitrary_self_types_pointers
407407 && !self.tcx.sess.at_least_rust_2018()
408408 {
409409 // this case used to be allowed by the compiler,
compiler/rustc_index/Cargo.toml+1
......@@ -20,4 +20,5 @@ nightly = [
2020 "dep:rustc_macros",
2121 "rustc_index_macros/nightly",
2222]
23rustc_randomized_layouts = []
2324# tidy-alphabetical-end
compiler/rustc_index/src/lib.rs+11
......@@ -33,8 +33,19 @@ pub use vec::IndexVec;
3333///
3434/// </div>
3535#[macro_export]
36#[cfg(not(feature = "rustc_randomized_layouts"))]
3637macro_rules! static_assert_size {
3738 ($ty:ty, $size:expr) => {
3839 const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
3940 };
4041}
42
43#[macro_export]
44#[cfg(feature = "rustc_randomized_layouts")]
45macro_rules! static_assert_size {
46 ($ty:ty, $size:expr) => {
47 // no effect other than using the statements.
48 // struct sizes are not deterministic under randomized layouts
49 const _: (usize, usize) = ($size, ::std::mem::size_of::<$ty>());
50 };
51}
compiler/rustc_lint_defs/src/builtin.rs+7-5
......@@ -3706,7 +3706,7 @@ declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
37063706
37073707declare_lint! {
37083708 /// The `missing_abi` lint detects cases where the ABI is omitted from
3709 /// extern declarations.
3709 /// `extern` declarations.
37103710 ///
37113711 /// ### Example
37123712 ///
......@@ -3720,10 +3720,12 @@ declare_lint! {
37203720 ///
37213721 /// ### Explanation
37223722 ///
3723 /// Historically, Rust implicitly selected C as the ABI for extern
3724 /// declarations. We expect to add new ABIs, like `C-unwind`, in the future,
3725 /// though this has not yet happened, and especially with their addition
3726 /// seeing the ABI easily will make code review easier.
3723 /// For historic reasons, Rust implicitly selects `C` as the default ABI for
3724 /// `extern` declarations. [Other ABIs] like `C-unwind` and `system` have
3725 /// been added since then, and especially with their addition seeing the ABI
3726 /// easily makes code review easier.
3727 ///
3728 /// [Other ABIs]: https://doc.rust-lang.org/reference/items/external-blocks.html#abi
37273729 pub MISSING_ABI,
37283730 Allow,
37293731 "No declared ABI for extern declaration"
compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs+2-2
......@@ -247,8 +247,8 @@ provide! { tcx, def_id, other, cdata,
247247 explicit_predicates_of => { table }
248248 generics_of => { table }
249249 inferred_outlives_of => { table_defaulted_array }
250 explicit_super_predicates_of => { table }
251 explicit_implied_predicates_of => { table }
250 explicit_super_predicates_of => { table_defaulted_array }
251 explicit_implied_predicates_of => { table_defaulted_array }
252252 type_of => { table }
253253 type_alias_is_lazy => { table_direct }
254254 variances_of => { table }
compiler/rustc_metadata/src/rmeta/encoder.rs+4-4
......@@ -1443,9 +1443,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14431443 }
14441444 if let DefKind::Trait = def_kind {
14451445 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
1446 record_array!(self.tables.explicit_super_predicates_of[def_id] <-
1446 record_defaulted_array!(self.tables.explicit_super_predicates_of[def_id] <-
14471447 self.tcx.explicit_super_predicates_of(def_id).skip_binder());
1448 record_array!(self.tables.explicit_implied_predicates_of[def_id] <-
1448 record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
14491449 self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
14501450
14511451 let module_children = self.tcx.module_children_local(local_id);
......@@ -1454,9 +1454,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14541454 }
14551455 if let DefKind::TraitAlias = def_kind {
14561456 record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
1457 record_array!(self.tables.explicit_super_predicates_of[def_id] <-
1457 record_defaulted_array!(self.tables.explicit_super_predicates_of[def_id] <-
14581458 self.tcx.explicit_super_predicates_of(def_id).skip_binder());
1459 record_array!(self.tables.explicit_implied_predicates_of[def_id] <-
1459 record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
14601460 self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
14611461 }
14621462 if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
compiler/rustc_metadata/src/rmeta/mod.rs+2-4
......@@ -390,6 +390,8 @@ define_tables! {
390390 explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
391391 explicit_item_super_predicates: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
392392 inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
393 explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
394 explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
393395 inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
394396 associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
395397 associated_type_for_effects: Table<DefIndex, Option<LazyValue<DefId>>>,
......@@ -419,10 +421,6 @@ define_tables! {
419421 lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
420422 explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
421423 generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
422 explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
423 // As an optimization, we only store this for trait aliases,
424 // since it's identical to explicit_super_predicates_of for traits.
425 explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
426424 type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>,
427425 variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
428426 fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>,
compiler/rustc_middle/Cargo.toml+1
......@@ -40,5 +40,6 @@ tracing = "0.1"
4040
4141[features]
4242# tidy-alphabetical-start
43rustc_randomized_layouts = []
4344rustc_use_parallel_compiler = ["dep:rustc-rayon-core"]
4445# tidy-alphabetical-end
compiler/rustc_middle/src/query/plumbing.rs+1
......@@ -337,6 +337,7 @@ macro_rules! define_callbacks {
337337 // Ensure that values grow no larger than 64 bytes by accident.
338338 // Increase this limit if necessary, but do try to keep the size low if possible
339339 #[cfg(target_pointer_width = "64")]
340 #[cfg(not(feature = "rustc_randomized_layouts"))]
340341 const _: () = {
341342 if mem::size_of::<Value<'static>>() > 64 {
342343 panic!("{}", concat!(
compiler/rustc_middle/src/ty/mod.rs+9-1
......@@ -35,6 +35,7 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
3535use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
3636use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
3737use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
38use rustc_hir::LangItem;
3839use rustc_index::IndexVec;
3940use rustc_macros::{
4041 extension, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable,
......@@ -1570,8 +1571,15 @@ impl<'tcx> TyCtxt<'tcx> {
15701571 flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
15711572 }
15721573
1574 // box is special, on the one hand the compiler assumes an ordered layout, with the pointer
1575 // always at offset zero. On the other hand we want scalar abi optimizations.
1576 let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
1577
15731578 // This is here instead of layout because the choice must make it into metadata.
1574 if !self.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did))) {
1579 if is_box
1580 || !self
1581 .consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did)))
1582 {
15751583 flags.insert(ReprFlags::IS_LINEAR);
15761584 }
15771585
compiler/rustc_span/src/symbol.rs+1
......@@ -407,6 +407,7 @@ symbols! {
407407 append_const_msg,
408408 arbitrary_enum_discriminant,
409409 arbitrary_self_types,
410 arbitrary_self_types_pointers,
410411 args,
411412 arith_offset,
412413 arm,
compiler/rustc_target/src/spec/mod.rs+2
......@@ -1695,6 +1695,8 @@ supported_targets! {
16951695 ("armv7r-none-eabihf", armv7r_none_eabihf),
16961696 ("armv8r-none-eabihf", armv8r_none_eabihf),
16971697
1698 ("armv7-rtems-eabihf", armv7_rtems_eabihf),
1699
16981700 ("x86_64-pc-solaris", x86_64_pc_solaris),
16991701 ("sparcv9-sun-solaris", sparcv9_sun_solaris),
17001702
compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs created+35
......@@ -0,0 +1,35 @@
1use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
2
3pub(crate) fn target() -> Target {
4 Target {
5 llvm_target: "armv7-unknown-none-eabihf".into(),
6 metadata: crate::spec::TargetMetadata {
7 description: Some("Armv7 RTEMS (Requires RTEMS toolchain and kernel".into()),
8 tier: Some(3),
9 host_tools: Some(false),
10 std: Some(true),
11 },
12 pointer_width: 32,
13 data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
14 arch: "arm".into(),
15
16 options: TargetOptions {
17 os: "rtems".into(),
18 families: cvs!["unix"],
19 abi: "eabihf".into(),
20 linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
21 linker: None,
22 relocation_model: RelocModel::Static,
23 panic_strategy: PanicStrategy::Abort,
24 features: "+thumb2,+neon,+vfp3".into(),
25 max_atomic_width: Some(64),
26 emit_debug_gdb_scripts: false,
27 // GCC defaults to 8 for arm-none here.
28 c_enum_min_bits: Some(8),
29 eh_frame_header: false,
30 no_default_libraries: false,
31 env: "newlib".into(),
32 ..Default::default()
33 },
34 }
35}
config.example.toml+3
......@@ -519,6 +519,9 @@
519519# are disabled statically" because `max_level_info` is enabled, set this value to `true`.
520520#debug-logging = rust.debug-assertions (boolean)
521521
522# Whether or not to build rustc, tools and the libraries with randomized type layout
523#randomize-layout = false
524
522525# Whether or not overflow checks are enabled for the compiler and standard
523526# library.
524527#
library/alloc/Cargo.toml+1
......@@ -52,4 +52,5 @@ check-cfg = [
5252 'cfg(no_global_oom_handling)',
5353 'cfg(no_rc)',
5454 'cfg(no_sync)',
55 'cfg(randomized_layouts)',
5556]
library/alloc/src/collections/btree/node/tests.rs+1-1
......@@ -90,7 +90,7 @@ fn test_partial_eq() {
9090
9191#[test]
9292#[cfg(target_arch = "x86_64")]
93#[cfg_attr(miri, ignore)] // We'd like to run Miri with layout randomization
93#[cfg_attr(any(miri, randomized_layouts), ignore)] // We'd like to run Miri with layout randomization
9494fn test_sizes() {
9595 assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16);
9696 assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8);
library/core/Cargo.toml+2
......@@ -43,6 +43,8 @@ check-cfg = [
4343 'cfg(bootstrap)',
4444 'cfg(no_fp_fmt_parse)',
4545 'cfg(stdarch_intel_sde)',
46 # #[cfg(bootstrap)] rtems
47 'cfg(target_os, values("rtems"))',
4648 # core use #[path] imports to portable-simd `core_simd` crate
4749 # and to stdarch `core_arch` crate which messes-up with Cargo list
4850 # of declared features, we therefor expect any feature cfg
library/core/src/ffi/mod.rs+1-1
......@@ -110,7 +110,7 @@ mod c_char_definition {
110110 all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
111111 all(target_os = "l4re", target_arch = "x86_64"),
112112 all(
113 any(target_os = "freebsd", target_os = "openbsd"),
113 any(target_os = "freebsd", target_os = "openbsd", target_os = "rtems"),
114114 any(
115115 target_arch = "aarch64",
116116 target_arch = "arm",
library/core/src/task/wake.rs+79-24
......@@ -60,22 +60,6 @@ impl RawWaker {
6060 RawWaker { data, vtable }
6161 }
6262
63 /// Gets the `data` pointer used to create this `RawWaker`.
64 #[inline]
65 #[must_use]
66 #[unstable(feature = "waker_getters", issue = "96992")]
67 pub fn data(&self) -> *const () {
68 self.data
69 }
70
71 /// Gets the `vtable` pointer used to create this `RawWaker`.
72 #[inline]
73 #[must_use]
74 #[unstable(feature = "waker_getters", issue = "96992")]
75 pub fn vtable(&self) -> &'static RawWakerVTable {
76 self.vtable
77 }
78
7963 #[unstable(feature = "noop_waker", issue = "98286")]
8064 const NOOP: RawWaker = {
8165 const VTABLE: RawWakerVTable = RawWakerVTable::new(
......@@ -509,6 +493,37 @@ impl Waker {
509493 a_data == b_data && ptr::eq(a_vtable, b_vtable)
510494 }
511495
496 /// Creates a new `Waker` from the provided `data` pointer and `vtable`.
497 ///
498 /// The `data` pointer can be used to store arbitrary data as required
499 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
500 /// that is associated with the task.
501 /// The value of this pointer will get passed to all functions that are part
502 /// of the `vtable` as the first parameter.
503 ///
504 /// It is important to consider that the `data` pointer must point to a
505 /// thread safe type such as an `Arc`.
506 ///
507 /// The `vtable` customizes the behavior of a `Waker`. For each operation
508 /// on the `Waker`, the associated function in the `vtable` will be called.
509 ///
510 /// # Safety
511 ///
512 /// The behavior of the returned `Waker` is undefined if the contract defined
513 /// in [`RawWakerVTable`]'s documentation is not upheld.
514 ///
515 /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
516 /// cost of a required heap allocation.)
517 ///
518 /// [`Wake`]: ../../alloc/task/trait.Wake.html
519 #[inline]
520 #[must_use]
521 #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
522 #[rustc_const_stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
523 pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
524 Waker { waker: RawWaker { data, vtable } }
525 }
526
512527 /// Creates a new `Waker` from [`RawWaker`].
513528 ///
514529 /// # Safety
......@@ -565,12 +580,20 @@ impl Waker {
565580 WAKER
566581 }
567582
568 /// Gets a reference to the underlying [`RawWaker`].
583 /// Gets the `data` pointer used to create this `Waker`.
569584 #[inline]
570585 #[must_use]
571 #[unstable(feature = "waker_getters", issue = "96992")]
572 pub fn as_raw(&self) -> &RawWaker {
573 &self.waker
586 #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
587 pub fn data(&self) -> *const () {
588 self.waker.data
589 }
590
591 /// Gets the `vtable` pointer used to create this `Waker`.
592 #[inline]
593 #[must_use]
594 #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")]
595 pub fn vtable(&self) -> &'static RawWakerVTable {
596 self.waker.vtable
574597 }
575598}
576599
......@@ -778,6 +801,30 @@ impl LocalWaker {
778801 a_data == b_data && ptr::eq(a_vtable, b_vtable)
779802 }
780803
804 /// Creates a new `LocalWaker` from the provided `data` pointer and `vtable`.
805 ///
806 /// The `data` pointer can be used to store arbitrary data as required
807 /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
808 /// that is associated with the task.
809 /// The value of this pointer will get passed to all functions that are part
810 /// of the `vtable` as the first parameter.
811 ///
812 /// The `vtable` customizes the behavior of a `LocalWaker`. For each
813 /// operation on the `LocalWaker`, the associated function in the `vtable`
814 /// will be called.
815 ///
816 /// # Safety
817 ///
818 /// The behavior of the returned `Waker` is undefined if the contract defined
819 /// in [`RawWakerVTable`]'s documentation is not upheld.
820 ///
821 #[inline]
822 #[must_use]
823 #[unstable(feature = "local_waker", issue = "118959")]
824 pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self {
825 LocalWaker { waker: RawWaker { data, vtable } }
826 }
827
781828 /// Creates a new `LocalWaker` from [`RawWaker`].
782829 ///
783830 /// The behavior of the returned `LocalWaker` is undefined if the contract defined
......@@ -831,12 +878,20 @@ impl LocalWaker {
831878 WAKER
832879 }
833880
834 /// Gets a reference to the underlying [`RawWaker`].
881 /// Gets the `data` pointer used to create this `LocalWaker`.
835882 #[inline]
836883 #[must_use]
837 #[unstable(feature = "waker_getters", issue = "96992")]
838 pub fn as_raw(&self) -> &RawWaker {
839 &self.waker
884 #[unstable(feature = "local_waker", issue = "118959")]
885 pub fn data(&self) -> *const () {
886 self.waker.data
887 }
888
889 /// Gets the `vtable` pointer used to create this `LocalWaker`.
890 #[inline]
891 #[must_use]
892 #[unstable(feature = "local_waker", issue = "118959")]
893 pub fn vtable(&self) -> &'static RawWakerVTable {
894 self.waker.vtable
840895 }
841896}
842897#[unstable(feature = "local_waker", issue = "118959")]
library/core/tests/lib.rs-1
......@@ -112,7 +112,6 @@
112112#![feature(unsize)]
113113#![feature(unsized_tuple_coercion)]
114114#![feature(unwrap_infallible)]
115#![feature(waker_getters)]
116115// tidy-alphabetical-end
117116#![allow(internal_features)]
118117#![deny(fuzzy_provenance_casts)]
library/core/tests/waker.rs+5-6
......@@ -4,14 +4,13 @@ use std::task::{RawWaker, RawWakerVTable, Waker};
44#[test]
55fn test_waker_getters() {
66 let raw_waker = RawWaker::new(ptr::without_provenance_mut(42usize), &WAKER_VTABLE);
7 assert_eq!(raw_waker.data() as usize, 42);
8 assert!(ptr::eq(raw_waker.vtable(), &WAKER_VTABLE));
9
107 let waker = unsafe { Waker::from_raw(raw_waker) };
8 assert_eq!(waker.data() as usize, 42);
9 assert!(ptr::eq(waker.vtable(), &WAKER_VTABLE));
10
1111 let waker2 = waker.clone();
12 let raw_waker2 = waker2.as_raw();
13 assert_eq!(raw_waker2.data() as usize, 43);
14 assert!(ptr::eq(raw_waker2.vtable(), &WAKER_VTABLE));
12 assert_eq!(waker2.data() as usize, 43);
13 assert!(ptr::eq(waker2.vtable(), &WAKER_VTABLE));
1514}
1615
1716static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
library/panic_unwind/Cargo.toml+7
......@@ -20,3 +20,10 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
2020
2121[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
2222libc = { version = "0.2", default-features = false }
23
24[lints.rust.unexpected_cfgs]
25level = "warn"
26check-cfg = [
27 # #[cfg(bootstrap)] rtems
28 'cfg(target_os, values("rtems"))',
29]
library/panic_unwind/src/lib.rs+1-1
......@@ -48,7 +48,7 @@ cfg_if::cfg_if! {
4848 target_os = "psp",
4949 target_os = "xous",
5050 target_os = "solid_asp3",
51 all(target_family = "unix", not(target_os = "espidf")),
51 all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems"))),
5252 all(target_vendor = "fortanix", target_env = "sgx"),
5353 target_family = "wasm",
5454 ))] {
library/std/Cargo.toml+2
......@@ -146,4 +146,6 @@ check-cfg = [
146146 # and to the `backtrace` crate which messes-up with Cargo list
147147 # of declared features, we therefor expect any feature cfg
148148 'cfg(feature, values(any()))',
149 # #[cfg(bootstrap)] rtems
150 'cfg(target_os, values("rtems"))',
149151]
library/std/build.rs+1
......@@ -53,6 +53,7 @@ fn main() {
5353 || target_os == "uefi"
5454 || target_os == "teeos"
5555 || target_os == "zkvm"
56 || target_os == "rtems"
5657
5758 // See src/bootstrap/src/core/build_steps/synthetic_targets.rs
5859 || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
library/std/src/os/mod.rs+2
......@@ -143,6 +143,8 @@ pub mod nto;
143143pub mod openbsd;
144144#[cfg(target_os = "redox")]
145145pub mod redox;
146#[cfg(target_os = "rtems")]
147pub mod rtems;
146148#[cfg(target_os = "solaris")]
147149pub mod solaris;
148150#[cfg(target_os = "solid_asp3")]
library/std/src/os/rtems/fs.rs created+374
......@@ -0,0 +1,374 @@
1#![stable(feature = "metadata_ext", since = "1.1.0")]
2
3use crate::fs::Metadata;
4use crate::sys_common::AsInner;
5
6/// OS-specific extensions to [`fs::Metadata`].
7///
8/// [`fs::Metadata`]: crate::fs::Metadata
9#[stable(feature = "metadata_ext", since = "1.1.0")]
10pub trait MetadataExt {
11 /// Returns the device ID on which this file resides.
12 ///
13 /// # Examples
14 ///
15 /// ```no_run
16 /// use std::fs;
17 /// use std::io;
18 /// use std::os::rtems::fs::MetadataExt;
19 ///
20 /// fn main() -> io::Result<()> {
21 /// let meta = fs::metadata("some_file")?;
22 /// println!("{}", meta.st_dev());
23 /// Ok(())
24 /// }
25 /// ```
26 #[stable(feature = "metadata_ext2", since = "1.8.0")]
27 fn st_dev(&self) -> u64;
28
29 /// Returns the inode number.
30 ///
31 /// # Examples
32 ///
33 /// ```no_run
34 /// use std::fs;
35 /// use std::io;
36 /// use std::os::rtems::fs::MetadataExt;
37 ///
38 /// fn main() -> io::Result<()> {
39 /// let meta = fs::metadata("some_file")?;
40 /// println!("{}", meta.st_ino());
41 /// Ok(())
42 /// }
43 /// ```
44 #[stable(feature = "metadata_ext2", since = "1.8.0")]
45 fn st_ino(&self) -> u64;
46
47 /// Returns the file type and mode.
48 ///
49 /// # Examples
50 ///
51 /// ```no_run
52 /// use std::fs;
53 /// use std::io;
54 /// use std::os::rtems::fs::MetadataExt;
55 ///
56 /// fn main() -> io::Result<()> {
57 /// let meta = fs::metadata("some_file")?;
58 /// println!("{}", meta.st_mode());
59 /// Ok(())
60 /// }
61 /// ```
62 #[stable(feature = "metadata_ext2", since = "1.8.0")]
63 fn st_mode(&self) -> u32;
64
65 /// Returns the number of hard links to file.
66 ///
67 /// # Examples
68 ///
69 /// ```no_run
70 /// use std::fs;
71 /// use std::io;
72 /// use std::os::rtems::fs::MetadataExt;
73 ///
74 /// fn main() -> io::Result<()> {
75 /// let meta = fs::metadata("some_file")?;
76 /// println!("{}", meta.st_nlink());
77 /// Ok(())
78 /// }
79 /// ```
80 #[stable(feature = "metadata_ext2", since = "1.8.0")]
81 fn st_nlink(&self) -> u64;
82
83 /// Returns the user ID of the file owner.
84 ///
85 /// # Examples
86 ///
87 /// ```no_run
88 /// use std::fs;
89 /// use std::io;
90 /// use std::os::rtems::fs::MetadataExt;
91 ///
92 /// fn main() -> io::Result<()> {
93 /// let meta = fs::metadata("some_file")?;
94 /// println!("{}", meta.st_uid());
95 /// Ok(())
96 /// }
97 /// ```
98 #[stable(feature = "metadata_ext2", since = "1.8.0")]
99 fn st_uid(&self) -> u32;
100
101 /// Returns the group ID of the file owner.
102 ///
103 /// # Examples
104 ///
105 /// ```no_run
106 /// use std::fs;
107 /// use std::io;
108 /// use std::os::rtems::fs::MetadataExt;
109 ///
110 /// fn main() -> io::Result<()> {
111 /// let meta = fs::metadata("some_file")?;
112 /// println!("{}", meta.st_gid());
113 /// Ok(())
114 /// }
115 /// ```
116 #[stable(feature = "metadata_ext2", since = "1.8.0")]
117 fn st_gid(&self) -> u32;
118
119 /// Returns the device ID that this file represents. Only relevant for special file.
120 ///
121 /// # Examples
122 ///
123 /// ```no_run
124 /// use std::fs;
125 /// use std::io;
126 /// use std::os::rtems::fs::MetadataExt;
127 ///
128 /// fn main() -> io::Result<()> {
129 /// let meta = fs::metadata("some_file")?;
130 /// println!("{}", meta.st_rdev());
131 /// Ok(())
132 /// }
133 /// ```
134 #[stable(feature = "metadata_ext2", since = "1.8.0")]
135 fn st_rdev(&self) -> u64;
136
137 /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
138 ///
139 /// The size of a symbolic link is the length of the pathname it contains,
140 /// without a terminating null byte.
141 ///
142 /// # Examples
143 ///
144 /// ```no_run
145 /// use std::fs;
146 /// use std::io;
147 /// use std::os::rtems::fs::MetadataExt;
148 ///
149 /// fn main() -> io::Result<()> {
150 /// let meta = fs::metadata("some_file")?;
151 /// println!("{}", meta.st_size());
152 /// Ok(())
153 /// }
154 /// ```
155 #[stable(feature = "metadata_ext2", since = "1.8.0")]
156 fn st_size(&self) -> u64;
157
158 /// Returns the last access time of the file, in seconds since Unix Epoch.
159 ///
160 /// # Examples
161 ///
162 /// ```no_run
163 /// use std::fs;
164 /// use std::io;
165 /// use std::os::rtems::fs::MetadataExt;
166 ///
167 /// fn main() -> io::Result<()> {
168 /// let meta = fs::metadata("some_file")?;
169 /// println!("{}", meta.st_atime());
170 /// Ok(())
171 /// }
172 /// ```
173 #[stable(feature = "metadata_ext2", since = "1.8.0")]
174 fn st_atime(&self) -> i64;
175
176 /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
177 ///
178 /// [`st_atime`]: Self::st_atime
179 ///
180 /// # Examples
181 ///
182 /// ```no_run
183 /// use std::fs;
184 /// use std::io;
185 /// use std::os::rtems::fs::MetadataExt;
186 ///
187 /// fn main() -> io::Result<()> {
188 /// let meta = fs::metadata("some_file")?;
189 /// println!("{}", meta.st_atime_nsec());
190 /// Ok(())
191 /// }
192 /// ```
193 #[stable(feature = "metadata_ext2", since = "1.8.0")]
194 fn st_atime_nsec(&self) -> i64;
195
196 /// Returns the last modification time of the file, in seconds since Unix Epoch.
197 ///
198 /// # Examples
199 ///
200 /// ```no_run
201 /// use std::fs;
202 /// use std::io;
203 /// use std::os::rtems::fs::MetadataExt;
204 ///
205 /// fn main() -> io::Result<()> {
206 /// let meta = fs::metadata("some_file")?;
207 /// println!("{}", meta.st_mtime());
208 /// Ok(())
209 /// }
210 /// ```
211 #[stable(feature = "metadata_ext2", since = "1.8.0")]
212 fn st_mtime(&self) -> i64;
213
214 /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
215 ///
216 /// [`st_mtime`]: Self::st_mtime
217 ///
218 /// # Examples
219 ///
220 /// ```no_run
221 /// use std::fs;
222 /// use std::io;
223 /// use std::os::rtems::fs::MetadataExt;
224 ///
225 /// fn main() -> io::Result<()> {
226 /// let meta = fs::metadata("some_file")?;
227 /// println!("{}", meta.st_mtime_nsec());
228 /// Ok(())
229 /// }
230 /// ```
231 #[stable(feature = "metadata_ext2", since = "1.8.0")]
232 fn st_mtime_nsec(&self) -> i64;
233
234 /// Returns the last status change time of the file, in seconds since Unix Epoch.
235 ///
236 /// # Examples
237 ///
238 /// ```no_run
239 /// use std::fs;
240 /// use std::io;
241 /// use std::os::rtems::fs::MetadataExt;
242 ///
243 /// fn main() -> io::Result<()> {
244 /// let meta = fs::metadata("some_file")?;
245 /// println!("{}", meta.st_ctime());
246 /// Ok(())
247 /// }
248 /// ```
249 #[stable(feature = "metadata_ext2", since = "1.8.0")]
250 fn st_ctime(&self) -> i64;
251
252 /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
253 ///
254 /// [`st_ctime`]: Self::st_ctime
255 ///
256 /// # Examples
257 ///
258 /// ```no_run
259 /// use std::fs;
260 /// use std::io;
261 /// use std::os::rtems::fs::MetadataExt;
262 ///
263 /// fn main() -> io::Result<()> {
264 /// let meta = fs::metadata("some_file")?;
265 /// println!("{}", meta.st_ctime_nsec());
266 /// Ok(())
267 /// }
268 /// ```
269 #[stable(feature = "metadata_ext2", since = "1.8.0")]
270 fn st_ctime_nsec(&self) -> i64;
271
272 /// Returns the "preferred" block size for efficient filesystem I/O.
273 ///
274 /// # Examples
275 ///
276 /// ```no_run
277 /// use std::fs;
278 /// use std::io;
279 /// use std::os::rtems::fs::MetadataExt;
280 ///
281 /// fn main() -> io::Result<()> {
282 /// let meta = fs::metadata("some_file")?;
283 /// println!("{}", meta.st_blksize());
284 /// Ok(())
285 /// }
286 /// ```
287 #[stable(feature = "metadata_ext2", since = "1.8.0")]
288 fn st_blksize(&self) -> u64;
289
290 /// Returns the number of blocks allocated to the file, 512-byte units.
291 ///
292 /// # Examples
293 ///
294 /// ```no_run
295 /// use std::fs;
296 /// use std::io;
297 /// use std::os::rtems::fs::MetadataExt;
298 ///
299 /// fn main() -> io::Result<()> {
300 /// let meta = fs::metadata("some_file")?;
301 /// println!("{}", meta.st_blocks());
302 /// Ok(())
303 /// }
304 /// ```
305 #[stable(feature = "metadata_ext2", since = "1.8.0")]
306 fn st_blocks(&self) -> u64;
307}
308
309#[stable(feature = "metadata_ext", since = "1.1.0")]
310impl MetadataExt for Metadata {
311 fn st_dev(&self) -> u64 {
312 self.as_inner().as_inner().st_dev as u64
313 }
314
315 fn st_ino(&self) -> u64 {
316 self.as_inner().as_inner().st_ino as u64
317 }
318
319 fn st_mode(&self) -> u32 {
320 self.as_inner().as_inner().st_mode as u32
321 }
322
323 fn st_nlink(&self) -> u64 {
324 self.as_inner().as_inner().st_nlink as u64
325 }
326
327 fn st_uid(&self) -> u32 {
328 self.as_inner().as_inner().st_uid as u32
329 }
330
331 fn st_gid(&self) -> u32 {
332 self.as_inner().as_inner().st_gid as u32
333 }
334
335 fn st_rdev(&self) -> u64 {
336 self.as_inner().as_inner().st_rdev as u64
337 }
338
339 fn st_size(&self) -> u64 {
340 self.as_inner().as_inner().st_size as u64
341 }
342
343 fn st_atime(&self) -> i64 {
344 self.as_inner().as_inner().st_atime as i64
345 }
346
347 fn st_atime_nsec(&self) -> i64 {
348 0
349 }
350
351 fn st_mtime(&self) -> i64 {
352 self.as_inner().as_inner().st_mtime as i64
353 }
354
355 fn st_mtime_nsec(&self) -> i64 {
356 0
357 }
358
359 fn st_ctime(&self) -> i64 {
360 self.as_inner().as_inner().st_ctime as i64
361 }
362
363 fn st_ctime_nsec(&self) -> i64 {
364 0
365 }
366
367 fn st_blksize(&self) -> u64 {
368 self.as_inner().as_inner().st_blksize as u64
369 }
370
371 fn st_blocks(&self) -> u64 {
372 self.as_inner().as_inner().st_blocks as u64
373 }
374}
library/std/src/os/rtems/mod.rs created+4
......@@ -0,0 +1,4 @@
1#![stable(feature = "raw_ext", since = "1.1.0")]
2#![forbid(unsafe_op_in_unsafe_fn)]
3pub mod fs;
4pub(crate) mod raw;
library/std/src/os/rtems/raw.rs created+33
......@@ -0,0 +1,33 @@
1//! rtems raw type definitions
2
3#![stable(feature = "raw_ext", since = "1.1.0")]
4#![deprecated(
5 since = "1.8.0",
6 note = "these type aliases are no longer supported by \
7 the standard library, the `libc` crate on \
8 crates.io should be used instead for the correct \
9 definitions"
10)]
11#![allow(deprecated)]
12
13#[stable(feature = "pthread_t", since = "1.8.0")]
14pub type pthread_t = libc::pthread_t;
15
16#[stable(feature = "raw_ext", since = "1.1.0")]
17pub type blkcnt_t = libc::blkcnt_t;
18
19#[stable(feature = "raw_ext", since = "1.1.0")]
20pub type blksize_t = libc::blksize_t;
21#[stable(feature = "raw_ext", since = "1.1.0")]
22pub type dev_t = libc::dev_t;
23#[stable(feature = "raw_ext", since = "1.1.0")]
24pub type ino_t = libc::ino_t;
25#[stable(feature = "raw_ext", since = "1.1.0")]
26pub type mode_t = libc::mode_t;
27#[stable(feature = "raw_ext", since = "1.1.0")]
28pub type nlink_t = libc::nlink_t;
29#[stable(feature = "raw_ext", since = "1.1.0")]
30pub type off_t = libc::off_t;
31
32#[stable(feature = "raw_ext", since = "1.1.0")]
33pub type time_t = libc::time_t;
library/std/src/os/unix/mod.rs+2
......@@ -73,6 +73,8 @@ mod platform {
7373 pub use crate::os::openbsd::*;
7474 #[cfg(target_os = "redox")]
7575 pub use crate::os::redox::*;
76 #[cfg(target_os = "rtems")]
77 pub use crate::os::rtems::*;
7678 #[cfg(target_os = "solaris")]
7779 pub use crate::os::solaris::*;
7880 #[cfg(target_os = "vita")]
library/std/src/sys/pal/unix/args.rs+1
......@@ -112,6 +112,7 @@ impl DoubleEndedIterator for Args {
112112 target_os = "aix",
113113 target_os = "nto",
114114 target_os = "hurd",
115 target_os = "rtems",
115116))]
116117mod imp {
117118 use crate::ffi::c_char;
library/std/src/sys/pal/unix/env.rs+11
......@@ -240,6 +240,17 @@ pub mod os {
240240 pub const EXE_EXTENSION: &str = "";
241241}
242242
243#[cfg(target_os = "rtems")]
244pub mod os {
245 pub const FAMILY: &str = "unix";
246 pub const OS: &str = "rtems";
247 pub const DLL_PREFIX: &str = "lib";
248 pub const DLL_SUFFIX: &str = ".so";
249 pub const DLL_EXTENSION: &str = "so";
250 pub const EXE_SUFFIX: &str = "";
251 pub const EXE_EXTENSION: &str = "";
252}
253
243254#[cfg(target_os = "vxworks")]
244255pub mod os {
245256 pub const FAMILY: &str = "unix";
library/std/src/sys/pal/unix/fs.rs+16-2
......@@ -478,6 +478,7 @@ impl FileAttr {
478478 target_os = "horizon",
479479 target_os = "vita",
480480 target_os = "hurd",
481 target_os = "rtems",
481482 )))]
482483 pub fn modified(&self) -> io::Result<SystemTime> {
483484 #[cfg(target_pointer_width = "32")]
......@@ -490,7 +491,12 @@ impl FileAttr {
490491 SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtime_nsec as i64)
491492 }
492493
493 #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
494 #[cfg(any(
495 target_os = "vxworks",
496 target_os = "espidf",
497 target_os = "vita",
498 target_os = "rtems",
499 ))]
494500 pub fn modified(&self) -> io::Result<SystemTime> {
495501 SystemTime::new(self.stat.st_mtime as i64, 0)
496502 }
......@@ -506,6 +512,7 @@ impl FileAttr {
506512 target_os = "horizon",
507513 target_os = "vita",
508514 target_os = "hurd",
515 target_os = "rtems",
509516 )))]
510517 pub fn accessed(&self) -> io::Result<SystemTime> {
511518 #[cfg(target_pointer_width = "32")]
......@@ -518,7 +525,12 @@ impl FileAttr {
518525 SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64)
519526 }
520527
521 #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
528 #[cfg(any(
529 target_os = "vxworks",
530 target_os = "espidf",
531 target_os = "vita",
532 target_os = "rtems"
533 ))]
522534 pub fn accessed(&self) -> io::Result<SystemTime> {
523535 SystemTime::new(self.stat.st_atime as i64, 0)
524536 }
......@@ -853,6 +865,7 @@ impl Drop for Dir {
853865 target_os = "fuchsia",
854866 target_os = "horizon",
855867 target_os = "vxworks",
868 target_os = "rtems",
856869 )))]
857870 {
858871 let fd = unsafe { libc::dirfd(self.0) };
......@@ -970,6 +983,7 @@ impl DirEntry {
970983 target_os = "aix",
971984 target_os = "nto",
972985 target_os = "hurd",
986 target_os = "rtems",
973987 target_vendor = "apple",
974988 ))]
975989 pub fn ino(&self) -> u64 {
library/std/src/sys/pal/unix/mod.rs+1
......@@ -79,6 +79,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
7979 target_os = "l4re",
8080 target_os = "horizon",
8181 target_os = "vita",
82 target_os = "rtems",
8283 // The poll on Darwin doesn't set POLLNVAL for closed fds.
8384 target_vendor = "apple",
8485 )))]
library/std/src/sys/pal/unix/os.rs+15-4
......@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
3131}
3232
3333extern "C" {
34 #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
34 #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
3535 #[cfg_attr(
3636 any(
3737 target_os = "linux",
......@@ -61,13 +61,14 @@ extern "C" {
6161}
6262
6363/// Returns the platform-specific value of errno
64#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
64#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
6565pub fn errno() -> i32 {
6666 unsafe { (*errno_location()) as i32 }
6767}
6868
6969/// Sets the platform-specific value of errno
70#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks")))] // needed for readdir and syscall!
70// needed for readdir and syscall!
71#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
7172#[allow(dead_code)] // but not all target cfgs actually end up using it
7273pub fn set_errno(e: i32) {
7374 unsafe { *errno_location() = e as c_int }
......@@ -78,6 +79,16 @@ pub fn errno() -> i32 {
7879 unsafe { libc::errnoGet() }
7980}
8081
82#[cfg(target_os = "rtems")]
83pub fn errno() -> i32 {
84 extern "C" {
85 #[thread_local]
86 static _tls_errno: c_int;
87 }
88
89 unsafe { _tls_errno as i32 }
90}
91
8192#[cfg(target_os = "dragonfly")]
8293pub fn errno() -> i32 {
8394 extern "C" {
......@@ -472,7 +483,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
472483 }
473484}
474485
475#[cfg(target_os = "redox")]
486#[cfg(any(target_os = "redox", target_os = "rtems"))]
476487pub fn current_exe() -> io::Result<PathBuf> {
477488 crate::fs::read_to_string("sys:exe").map(PathBuf::from)
478489}
library/std/src/sys/pal/unix/process/process_unix.rs+3-3
......@@ -1089,13 +1089,13 @@ fn signal_string(signal: i32) -> &'static str {
10891089 libc::SIGURG => " (SIGURG)",
10901090 #[cfg(not(target_os = "l4re"))]
10911091 libc::SIGXCPU => " (SIGXCPU)",
1092 #[cfg(not(target_os = "l4re"))]
1092 #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
10931093 libc::SIGXFSZ => " (SIGXFSZ)",
1094 #[cfg(not(target_os = "l4re"))]
1094 #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
10951095 libc::SIGVTALRM => " (SIGVTALRM)",
10961096 #[cfg(not(target_os = "l4re"))]
10971097 libc::SIGPROF => " (SIGPROF)",
1098 #[cfg(not(target_os = "l4re"))]
1098 #[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
10991099 libc::SIGWINCH => " (SIGWINCH)",
11001100 #[cfg(not(any(target_os = "haiku", target_os = "l4re")))]
11011101 libc::SIGIO => " (SIGIO)",
library/std/src/sys/personality/mod.rs+1-1
......@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
3131 target_os = "psp",
3232 target_os = "xous",
3333 target_os = "solid_asp3",
34 all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re")),
34 all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems")),
3535 all(target_vendor = "fortanix", target_env = "sgx"),
3636 ))] {
3737 mod gcc;
library/unwind/Cargo.toml+7
......@@ -34,3 +34,10 @@ llvm-libunwind = []
3434# If crt-static is enabled, static link to `libunwind.a` provided by system
3535# If crt-static is disabled, dynamic link to `libunwind.so` provided by system
3636system-llvm-libunwind = []
37
38[lints.rust.unexpected_cfgs]
39level = "warn"
40check-cfg = [
41 # #[cfg(bootstrap)] rtems
42 'cfg(target_os, values("rtems"))',
43]
library/unwind/src/lib.rs+1
......@@ -22,6 +22,7 @@ cfg_if::cfg_if! {
2222 target_os = "l4re",
2323 target_os = "none",
2424 target_os = "espidf",
25 target_os = "rtems",
2526 ))] {
2627 // These "unix" family members do not have unwinder.
2728 } else if #[cfg(any(
src/bootstrap/src/core/build_steps/format.rs-1
......@@ -93,7 +93,6 @@ fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, Str
9393 if !verify_rustfmt_version(build) {
9494 return Ok(None);
9595 }
96
9796 get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"])
9897}
9998
src/bootstrap/src/core/build_steps/test.rs+3
......@@ -1810,6 +1810,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
18101810 if builder.config.rust_optimize_tests {
18111811 cmd.arg("--optimize-tests");
18121812 }
1813 if builder.config.rust_randomize_layout {
1814 cmd.arg("--rust-randomized-layout");
1815 }
18131816 if builder.config.cmd.only_modified() {
18141817 cmd.arg("--only-modified");
18151818 }
src/bootstrap/src/core/builder.rs+12
......@@ -1618,6 +1618,15 @@ impl<'a> Builder<'a> {
16181618 rustflags.arg("-Csymbol-mangling-version=legacy");
16191619 }
16201620
1621 // FIXME: the following components don't build with `-Zrandomize-layout` yet:
1622 // - wasm-component-ld, due to the `wast`crate
1623 // - rust-analyzer, due to the rowan crate
1624 // so we exclude entire categories of steps here due to lack of fine-grained control over
1625 // rustflags.
1626 if self.config.rust_randomize_layout && mode != Mode::ToolStd && mode != Mode::ToolRustc {
1627 rustflags.arg("-Zrandomize-layout");
1628 }
1629
16211630 // Enable compile-time checking of `cfg` names, values and Cargo `features`.
16221631 //
16231632 // Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like
......@@ -2193,6 +2202,9 @@ impl<'a> Builder<'a> {
21932202 rustflags.arg("-Zvalidate-mir");
21942203 rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}"));
21952204 }
2205 if self.config.rust_randomize_layout {
2206 rustflags.arg("--cfg=randomized_layouts");
2207 }
21962208 // Always enable inlining MIR when building the standard library.
21972209 // Without this flag, MIR inlining is disabled when incremental compilation is enabled.
21982210 // That causes some mir-opt tests which inline functions from the standard library to
src/bootstrap/src/core/config/config.rs+7-19
......@@ -268,7 +268,6 @@ pub struct Config {
268268 pub rust_debuginfo_level_std: DebuginfoLevel,
269269 pub rust_debuginfo_level_tools: DebuginfoLevel,
270270 pub rust_debuginfo_level_tests: DebuginfoLevel,
271 pub rust_split_debuginfo_for_build_triple: Option<SplitDebuginfo>, // FIXME: Deprecated field. Remove in Q3'24.
272271 pub rust_rpath: bool,
273272 pub rust_strip: bool,
274273 pub rust_frame_pointers: bool,
......@@ -280,6 +279,7 @@ pub struct Config {
280279 pub rust_codegen_backends: Vec<String>,
281280 pub rust_verify_llvm_ir: bool,
282281 pub rust_thin_lto_import_instr_limit: Option<u32>,
282 pub rust_randomize_layout: bool,
283283 pub rust_remap_debuginfo: bool,
284284 pub rust_new_symbol_mangling: Option<bool>,
285285 pub rust_profile_use: Option<String>,
......@@ -1090,6 +1090,7 @@ define_config! {
10901090 codegen_units: Option<u32> = "codegen-units",
10911091 codegen_units_std: Option<u32> = "codegen-units-std",
10921092 debug_assertions: Option<bool> = "debug-assertions",
1093 randomize_layout: Option<bool> = "randomize-layout",
10931094 debug_assertions_std: Option<bool> = "debug-assertions-std",
10941095 overflow_checks: Option<bool> = "overflow-checks",
10951096 overflow_checks_std: Option<bool> = "overflow-checks-std",
......@@ -1099,7 +1100,6 @@ define_config! {
10991100 debuginfo_level_std: Option<DebuginfoLevel> = "debuginfo-level-std",
11001101 debuginfo_level_tools: Option<DebuginfoLevel> = "debuginfo-level-tools",
11011102 debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests",
1102 split_debuginfo: Option<String> = "split-debuginfo",
11031103 backtrace: Option<bool> = "backtrace",
11041104 incremental: Option<bool> = "incremental",
11051105 parallel_compiler: Option<bool> = "parallel-compiler",
......@@ -1181,6 +1181,7 @@ impl Config {
11811181 backtrace: true,
11821182 rust_optimize: RustOptimize::Bool(true),
11831183 rust_optimize_tests: true,
1184 rust_randomize_layout: false,
11841185 submodules: None,
11851186 docs: true,
11861187 docs_minification: true,
......@@ -1636,10 +1637,10 @@ impl Config {
16361637 debuginfo_level_std: debuginfo_level_std_toml,
16371638 debuginfo_level_tools: debuginfo_level_tools_toml,
16381639 debuginfo_level_tests: debuginfo_level_tests_toml,
1639 split_debuginfo,
16401640 backtrace,
16411641 incremental,
16421642 parallel_compiler,
1643 randomize_layout,
16431644 default_linker,
16441645 channel,
16451646 description,
......@@ -1695,18 +1696,6 @@ impl Config {
16951696 debuginfo_level_tests = debuginfo_level_tests_toml;
16961697 lld_enabled = lld_enabled_toml;
16971698
1698 config.rust_split_debuginfo_for_build_triple = split_debuginfo
1699 .as_deref()
1700 .map(SplitDebuginfo::from_str)
1701 .map(|v| v.expect("invalid value for rust.split-debuginfo"));
1702
1703 if config.rust_split_debuginfo_for_build_triple.is_some() {
1704 println!(
1705 "WARNING: specifying `rust.split-debuginfo` is deprecated, use `target.{}.split-debuginfo` instead",
1706 config.build
1707 );
1708 }
1709
17101699 optimize = optimize_toml;
17111700 omit_git_hash = omit_git_hash_toml;
17121701 config.rust_new_symbol_mangling = new_symbol_mangling;
......@@ -1729,6 +1718,7 @@ impl Config {
17291718 set(&mut config.lld_mode, lld_mode);
17301719 set(&mut config.llvm_bitcode_linker_enabled, llvm_bitcode_linker);
17311720
1721 config.rust_randomize_layout = randomize_layout.unwrap_or_default();
17321722 config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
17331723 config.rustc_parallel =
17341724 parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly");
......@@ -2504,9 +2494,6 @@ impl Config {
25042494 self.target_config
25052495 .get(&target)
25062496 .and_then(|t| t.split_debuginfo)
2507 .or_else(|| {
2508 if self.build == target { self.rust_split_debuginfo_for_build_triple } else { None }
2509 })
25102497 .unwrap_or_else(|| SplitDebuginfo::default_for_platform(target))
25112498 }
25122499
......@@ -2900,6 +2887,7 @@ fn check_incompatible_options_for_ci_rustc(
29002887 let Rust {
29012888 // Following options are the CI rustc incompatible ones.
29022889 optimize,
2890 randomize_layout,
29032891 debug_logging,
29042892 debuginfo_level_rustc,
29052893 llvm_tools,
......@@ -2927,7 +2915,6 @@ fn check_incompatible_options_for_ci_rustc(
29272915 debuginfo_level_std: _,
29282916 debuginfo_level_tools: _,
29292917 debuginfo_level_tests: _,
2930 split_debuginfo: _,
29312918 backtrace: _,
29322919 parallel_compiler: _,
29332920 musl_root: _,
......@@ -2964,6 +2951,7 @@ fn check_incompatible_options_for_ci_rustc(
29642951 // otherwise, we just print a warning with `warn` macro.
29652952
29662953 err!(current_rust_config.optimize, optimize);
2954 err!(current_rust_config.randomize_layout, randomize_layout);
29672955 err!(current_rust_config.debug_logging, debug_logging);
29682956 err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc);
29692957 err!(current_rust_config.rpath, rpath);
src/bootstrap/src/core/sanity.rs+13
......@@ -13,6 +13,8 @@ use std::ffi::{OsStr, OsString};
1313use std::path::PathBuf;
1414use std::{env, fs};
1515
16use build_helper::git::warn_old_master_branch;
17
1618#[cfg(not(feature = "bootstrap-self-test"))]
1719use crate::builder::Builder;
1820use crate::builder::Kind;
......@@ -34,6 +36,7 @@ pub struct Finder {
3436// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
3537const STAGE0_MISSING_TARGETS: &[&str] = &[
3638 // just a dummy comment so the list doesn't get onelined
39 "armv7-rtems-eabihf",
3740];
3841
3942/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
......@@ -374,4 +377,14 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
374377 if let Some(ref s) = build.config.ccache {
375378 cmd_finder.must_have(s);
376379 }
380
381 // this warning is useless in CI,
382 // and CI probably won't have the right branches anyway.
383 if !build_helper::ci::CiEnv::is_ci() {
384 if let Err(e) = warn_old_master_branch(&build.config.git_config(), &build.config.src)
385 .map_err(|e| e.to_string())
386 {
387 eprintln!("unable to check if upstream branch is old: {e}");
388 }
389 }
377390}
src/bootstrap/src/lib.rs+3
......@@ -678,6 +678,9 @@ impl Build {
678678 if self.config.rustc_parallel {
679679 features.push("rustc_use_parallel_compiler");
680680 }
681 if self.config.rust_randomize_layout {
682 features.push("rustc_randomized_layouts");
683 }
681684
682685 // If debug logging is on, then we want the default for tracing:
683686 // https://github.com/tokio-rs/tracing/blob/3dd5c03d907afdf2c39444a29931833335171554/tracing/src/level_filters.rs#L26
src/bootstrap/src/utils/change_tracker.rs+5
......@@ -240,4 +240,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
240240 severity: ChangeSeverity::Info,
241241 summary: "New option `build.cargo-clippy` added for supporting the use of custom/external clippy.",
242242 },
243 ChangeInfo {
244 change_id: 129925,
245 severity: ChangeSeverity::Warning,
246 summary: "Removed `rust.split-debuginfo` as it was deprecated long time ago.",
247 },
243248];
src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile+1
......@@ -50,6 +50,7 @@ ENV RUST_CONFIGURE_ARGS \
5050 --build=x86_64-unknown-linux-gnu \
5151 --llvm-root=/usr/lib/llvm-17 \
5252 --enable-llvm-link-shared \
53 --set rust.randomize-layout=true \
5354 --set rust.thin-lto-import-instr-limit=10
5455
5556COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
src/ci/docker/scripts/rfl-build.sh+43-7
......@@ -4,8 +4,8 @@ set -euo pipefail
44
55LINUX_VERSION=4c7864e81d8bbd51036dacf92fb0a400e13aaeee
66
7# Build rustc, rustdoc and cargo
8../x.py build --stage 1 library rustdoc
7# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
8../x.py build --stage 2 library rustdoc clippy rustfmt
99../x.py build --stage 0 cargo
1010
1111# Install rustup so that we can use the built toolchain easily, and also
......@@ -16,7 +16,7 @@ sh rustup.sh -y --default-toolchain none
1616source /cargo/env
1717
1818BUILD_DIR=$(realpath ./build)
19rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage1
19rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2
2020rustup default local
2121
2222mkdir -p rfl
......@@ -62,11 +62,47 @@ make -C linux LLVM=1 -j$(($(nproc) + 1)) \
6262 defconfig \
6363 rfl-for-rust-ci.config
6464
65make -C linux LLVM=1 -j$(($(nproc) + 1)) \
66 samples/rust/rust_minimal.o \
67 samples/rust/rust_print.o \
68 drivers/net/phy/ax88796b_rust.o \
65BUILD_TARGETS="
66 samples/rust/rust_minimal.o
67 samples/rust/rust_print.o
68 drivers/net/phy/ax88796b_rust.o
6969 rust/doctests_kernel_generated.o
70"
71
72# Build a few Rust targets
73#
74# This does not include building the C side of the kernel nor linking,
75# which can find other issues, but it is much faster.
76#
77# This includes transforming `rustdoc` tests into KUnit ones thanks to
78# `CONFIG_RUST_KERNEL_DOCTESTS=y` above (which, for the moment, uses the
79# unstable `--test-builder` and `--no-run`).
80make -C linux LLVM=1 -j$(($(nproc) + 1)) \
81 $BUILD_TARGETS
7082
83# Generate documentation
7184make -C linux LLVM=1 -j$(($(nproc) + 1)) \
7285 rustdoc
86
87# Build macro expanded source (`-Zunpretty=expanded`)
88#
89# This target also formats the macro expanded code, thus it is also
90# intended to catch ICEs with formatting `-Zunpretty=expanded` output
91# like https://github.com/rust-lang/rustfmt/issues/6105.
92make -C linux LLVM=1 -j$(($(nproc) + 1)) \
93 samples/rust/rust_minimal.rsi
94
95# Re-build with Clippy enabled
96#
97# This should not introduce Clippy errors, since `CONFIG_WERROR` is not
98# set (thus no `-Dwarnings`) and the kernel uses `-W` for all Clippy
99# lints, including `clippy::all`. However, it could catch ICEs.
100make -C linux LLVM=1 -j$(($(nproc) + 1)) CLIPPY=1 \
101 $BUILD_TARGETS
102
103# Format the code
104#
105# This returns successfully even if there were changes, i.e. it is not
106# a check.
107make -C linux LLVM=1 -j$(($(nproc) + 1)) \
108 rustfmt
src/doc/not_found.md+1-1
......@@ -2,7 +2,7 @@
22
33<!-- Completely hide the TOC and the section numbers -->
44<style type="text/css">
5#TOC { display: none; }
5#rustdoc-toc { display: none; }
66.header-section-number { display: none; }
77li {list-style-type: none; }
88#search-input {
src/doc/rustc/src/SUMMARY.md+1
......@@ -40,6 +40,7 @@
4040 - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
4141 - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
4242 - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
43 - [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md)
4344 - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
4445 - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
4546 - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
src/doc/rustc/src/platform-support.md+1
......@@ -280,6 +280,7 @@ target | std | host | notes
280280`armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD
281281[`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float
282282[`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain)
283[`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? | | RTEMS OS for ARM BSPs
283284[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
284285[`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat
285286[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat
src/doc/rustc/src/platform-support/armv7-rtems-eabihf.md created+52
......@@ -0,0 +1,52 @@
1# `armv7-rtems-eabihf`
2
3**Tier: 3**
4
5ARM targets for the [RTEMS realtime operating system](https://www.rtems.org) using the RTEMS gcc cross-compiler for linking against the libraries of a specified Board Support Package (BSP).
6
7## Target maintainers
8
9- [@thesummer](https://github.com/thesummer)
10
11## Requirements
12
13The target does not support host tools. Only cross-compilation is possible.
14The cross-compiler toolchain can be obtained by following the installation instructions
15of the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html). Additionally to the cross-compiler also a compiled BSP
16for a board fitting the architecture needs to be available on the host.
17Currently tested has been the BSP `xilinx_zynq_a9_qemu` of RTEMS 6.
18
19`std` support is available, but not yet fully tested. Do NOT use in flight software!
20
21The target follows the EABI calling convention for `extern "C"`.
22
23The resulting binaries are in ELF format.
24
25## Building the target
26
27The target can be built by the standard compiler of Rust.
28
29## Building Rust programs
30
31Rust does not yet ship pre-compiled artifacts for this target. To compile for
32this target, you will either need to build Rust with the target enabled (see
33"Building the target" above), or build your own copy of `core` by using
34`build-std` or similar.
35
36In order to build an RTEMS executable it is also necessary to have a basic RTEMS configuration (in C) compiled to link against as this configures the operating system.
37An example can be found at this [`rtems-sys`](https://github.com/thesummer/rtems-sys) crate which could be added as an dependency to your application.
38
39## Testing
40
41The resulting binaries run fine on an emulated target (possibly also on a real Zedboard or similar).
42For example, on qemu the following command can execute the binary:
43```sh
44qemu-system-arm -no-reboot -serial null -serial mon:stdio -net none -nographic -M xilinx-zynq-a9 -m 512M -kernel <binary file>
45```
46
47While basic execution of the unit test harness seems to work. However, running the Rust testsuite on the (emulated) hardware has not yet been tested.
48
49## Cross-compilation toolchains and C code
50
51Compatible C-code can be built with the RTEMS cross-compiler toolchain `arm-rtems6-gcc`.
52For more information how to build the toolchain, RTEMS itself and RTEMS applications please have a look at the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html).
src/librustdoc/clean/types.rs-6
......@@ -512,9 +512,6 @@ impl Item {
512512 pub(crate) fn is_mod(&self) -> bool {
513513 self.type_() == ItemType::Module
514514 }
515 pub(crate) fn is_trait(&self) -> bool {
516 self.type_() == ItemType::Trait
517 }
518515 pub(crate) fn is_struct(&self) -> bool {
519516 self.type_() == ItemType::Struct
520517 }
......@@ -542,9 +539,6 @@ impl Item {
542539 pub(crate) fn is_ty_method(&self) -> bool {
543540 self.type_() == ItemType::TyMethod
544541 }
545 pub(crate) fn is_type_alias(&self) -> bool {
546 self.type_() == ItemType::TypeAlias
547 }
548542 pub(crate) fn is_primitive(&self) -> bool {
549543 self.type_() == ItemType::Primitive
550544 }
src/librustdoc/html/markdown.rs+62-11
......@@ -51,12 +51,12 @@ use tracing::{debug, trace};
5151use crate::clean::RenderedLink;
5252use crate::doctest;
5353use crate::doctest::GlobalTestOptions;
54use crate::html::escape::Escape;
54use crate::html::escape::{Escape, EscapeBodyText};
5555use crate::html::format::Buffer;
5656use crate::html::highlight;
5757use crate::html::length_limit::HtmlWithLimit;
5858use crate::html::render::small_url_encode;
59use crate::html::toc::TocBuilder;
59use crate::html::toc::{Toc, TocBuilder};
6060
6161#[cfg(test)]
6262mod tests;
......@@ -102,6 +102,7 @@ pub struct Markdown<'a> {
102102/// A struct like `Markdown` that renders the markdown with a table of contents.
103103pub(crate) struct MarkdownWithToc<'a> {
104104 pub(crate) content: &'a str,
105 pub(crate) links: &'a [RenderedLink],
105106 pub(crate) ids: &'a mut IdMap,
106107 pub(crate) error_codes: ErrorCodes,
107108 pub(crate) edition: Edition,
......@@ -533,9 +534,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
533534 let id = self.id_map.derive(id);
534535
535536 if let Some(ref mut builder) = self.toc {
537 let mut text_header = String::new();
538 plain_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()), &mut text_header);
536539 let mut html_header = String::new();
537 html::push_html(&mut html_header, self.buf.iter().map(|(ev, _)| ev.clone()));
538 let sec = builder.push(level as u32, html_header, id.clone());
540 html_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()), &mut html_header);
541 let sec = builder.push(level as u32, text_header, html_header, id.clone());
539542 self.buf.push_front((Event::Html(format!("{sec} ").into()), 0..0));
540543 }
541544
......@@ -1412,10 +1415,23 @@ impl Markdown<'_> {
14121415}
14131416
14141417impl MarkdownWithToc<'_> {
1415 pub(crate) fn into_string(self) -> String {
1416 let MarkdownWithToc { content: md, ids, error_codes: codes, edition, playground } = self;
1418 pub(crate) fn into_parts(self) -> (Toc, String) {
1419 let MarkdownWithToc { content: md, links, ids, error_codes: codes, edition, playground } =
1420 self;
14171421
1418 let p = Parser::new_ext(md, main_body_opts()).into_offset_iter();
1422 // This is actually common enough to special-case
1423 if md.is_empty() {
1424 return (Toc { entries: Vec::new() }, String::new());
1425 }
1426 let mut replacer = |broken_link: BrokenLink<'_>| {
1427 links
1428 .iter()
1429 .find(|link| &*link.original_text == &*broken_link.reference)
1430 .map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
1431 };
1432
1433 let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut replacer));
1434 let p = p.into_offset_iter();
14191435
14201436 let mut s = String::with_capacity(md.len() * 3 / 2);
14211437
......@@ -1429,7 +1445,11 @@ impl MarkdownWithToc<'_> {
14291445 html::push_html(&mut s, p);
14301446 }
14311447
1432 format!("<nav id=\"TOC\">{toc}</nav>{s}", toc = toc.into_toc().print())
1448 (toc.into_toc(), s)
1449 }
1450 pub(crate) fn into_string(self) -> String {
1451 let (toc, s) = self.into_parts();
1452 format!("<nav id=\"rustdoc\">{toc}</nav>{s}", toc = toc.print())
14331453 }
14341454}
14351455
......@@ -1608,7 +1628,16 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16081628
16091629 let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
16101630
1611 for event in p {
1631 plain_text_from_events(p, &mut s);
1632
1633 s
1634}
1635
1636pub(crate) fn plain_text_from_events<'a>(
1637 events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
1638 s: &mut String,
1639) {
1640 for event in events {
16121641 match &event {
16131642 Event::Text(text) => s.push_str(text),
16141643 Event::Code(code) => {
......@@ -1623,8 +1652,29 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16231652 _ => (),
16241653 }
16251654 }
1655}
16261656
1627 s
1657pub(crate) fn html_text_from_events<'a>(
1658 events: impl Iterator<Item = pulldown_cmark::Event<'a>>,
1659 s: &mut String,
1660) {
1661 for event in events {
1662 match &event {
1663 Event::Text(text) => {
1664 write!(s, "{}", EscapeBodyText(text)).expect("string alloc infallible")
1665 }
1666 Event::Code(code) => {
1667 s.push_str("<code>");
1668 write!(s, "{}", EscapeBodyText(code)).expect("string alloc infallible");
1669 s.push_str("</code>");
1670 }
1671 Event::HardBreak | Event::SoftBreak => s.push(' '),
1672 Event::Start(Tag::CodeBlock(..)) => break,
1673 Event::End(TagEnd::Paragraph) => break,
1674 Event::End(TagEnd::Heading(..)) => break,
1675 _ => (),
1676 }
1677 }
16281678}
16291679
16301680#[derive(Debug)]
......@@ -1975,7 +2025,8 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
19752025 map.insert("default-settings".into(), 1);
19762026 map.insert("sidebar-vars".into(), 1);
19772027 map.insert("copy-path".into(), 1);
1978 map.insert("TOC".into(), 1);
2028 map.insert("rustdoc-toc".into(), 1);
2029 map.insert("rustdoc-modnav".into(), 1);
19792030 // This is the list of IDs used by rustdoc sections (but still generated by
19802031 // rustdoc).
19812032 map.insert("fields".into(), 1);
src/librustdoc/html/render/context.rs+4-2
......@@ -15,7 +15,7 @@ use rustc_span::{sym, FileName, Symbol};
1515use tracing::info;
1616
1717use super::print_item::{full_path, item_path, print_item};
18use super::sidebar::{print_sidebar, sidebar_module_like, Sidebar};
18use super::sidebar::{print_sidebar, sidebar_module_like, ModuleLike, Sidebar};
1919use super::write_shared::write_shared;
2020use super::{collect_spans_and_sources, scrape_examples_help, AllTypes, LinkFromSrc, StylePath};
2121use crate::clean::types::ExternalLocation;
......@@ -617,12 +617,14 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
617617 let all = shared.all.replace(AllTypes::new());
618618 let mut sidebar = Buffer::html();
619619
620 let blocks = sidebar_module_like(all.item_sections());
620 // all.html is not customizable, so a blank id map is fine
621 let blocks = sidebar_module_like(all.item_sections(), &mut IdMap::new(), ModuleLike::Crate);
621622 let bar = Sidebar {
622623 title_prefix: "",
623624 title: "",
624625 is_crate: false,
625626 is_mod: false,
627 parent_is_crate: false,
626628 blocks: vec![blocks],
627629 path: String::new(),
628630 };
src/librustdoc/html/render/sidebar.rs+184-98
......@@ -13,7 +13,24 @@ use crate::clean;
1313use crate::formats::item_type::ItemType;
1414use crate::formats::Impl;
1515use crate::html::format::Buffer;
16use crate::html::markdown::IdMap;
16use crate::html::markdown::{IdMap, MarkdownWithToc};
17
18#[derive(Clone, Copy)]
19pub(crate) enum ModuleLike {
20 Module,
21 Crate,
22}
23
24impl ModuleLike {
25 pub(crate) fn is_crate(self) -> bool {
26 matches!(self, ModuleLike::Crate)
27 }
28}
29impl<'a> From<&'a clean::Item> for ModuleLike {
30 fn from(it: &'a clean::Item) -> ModuleLike {
31 if it.is_crate() { ModuleLike::Crate } else { ModuleLike::Module }
32 }
33}
1734
1835#[derive(Template)]
1936#[template(path = "sidebar.html")]
......@@ -21,6 +38,7 @@ pub(super) struct Sidebar<'a> {
2138 pub(super) title_prefix: &'static str,
2239 pub(super) title: &'a str,
2340 pub(super) is_crate: bool,
41 pub(super) parent_is_crate: bool,
2442 pub(super) is_mod: bool,
2543 pub(super) blocks: Vec<LinkBlock<'a>>,
2644 pub(super) path: String,
......@@ -63,15 +81,19 @@ impl<'a> LinkBlock<'a> {
6381/// A link to an item. Content should not be escaped.
6482#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)]
6583pub(crate) struct Link<'a> {
66 /// The content for the anchor tag
84 /// The content for the anchor tag and title attr
6785 name: Cow<'a, str>,
86 /// The content for the anchor tag (if different from name)
87 name_html: Option<Cow<'a, str>>,
6888 /// The id of an anchor within the page (without a `#` prefix)
6989 href: Cow<'a, str>,
90 /// Nested list of links (used only in top-toc)
91 children: Vec<Link<'a>>,
7092}
7193
7294impl<'a> Link<'a> {
7395 pub fn new(href: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>) -> Self {
74 Self { href: href.into(), name: name.into() }
96 Self { href: href.into(), name: name.into(), children: vec![], name_html: None }
7597 }
7698 pub fn empty() -> Link<'static> {
7799 Link::new("", "")
......@@ -95,17 +117,21 @@ pub(crate) mod filters {
95117}
96118
97119pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) {
98 let blocks: Vec<LinkBlock<'_>> = match *it.kind {
99 clean::StructItem(ref s) => sidebar_struct(cx, it, s),
100 clean::TraitItem(ref t) => sidebar_trait(cx, it, t),
101 clean::PrimitiveItem(_) => sidebar_primitive(cx, it),
102 clean::UnionItem(ref u) => sidebar_union(cx, it, u),
103 clean::EnumItem(ref e) => sidebar_enum(cx, it, e),
104 clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t),
105 clean::ModuleItem(ref m) => vec![sidebar_module(&m.items)],
106 clean::ForeignTypeItem => sidebar_foreign_type(cx, it),
107 _ => vec![],
108 };
120 let mut ids = IdMap::new();
121 let mut blocks: Vec<LinkBlock<'_>> = docblock_toc(cx, it, &mut ids).into_iter().collect();
122 match *it.kind {
123 clean::StructItem(ref s) => sidebar_struct(cx, it, s, &mut blocks),
124 clean::TraitItem(ref t) => sidebar_trait(cx, it, t, &mut blocks),
125 clean::PrimitiveItem(_) => sidebar_primitive(cx, it, &mut blocks),
126 clean::UnionItem(ref u) => sidebar_union(cx, it, u, &mut blocks),
127 clean::EnumItem(ref e) => sidebar_enum(cx, it, e, &mut blocks),
128 clean::TypeAliasItem(ref t) => sidebar_type_alias(cx, it, t, &mut blocks),
129 clean::ModuleItem(ref m) => {
130 blocks.push(sidebar_module(&m.items, &mut ids, ModuleLike::from(it)))
131 }
132 clean::ForeignTypeItem => sidebar_foreign_type(cx, it, &mut blocks),
133 _ => {}
134 }
109135 // The sidebar is designed to display sibling functions, modules and
110136 // other miscellaneous information. since there are lots of sibling
111137 // items (and that causes quadratic growth in large modules),
......@@ -113,15 +139,9 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
113139 // still, we don't move everything into JS because we want to preserve
114140 // as much HTML as possible in order to allow non-JS-enabled browsers
115141 // to navigate the documentation (though slightly inefficiently).
116 let (title_prefix, title) = if it.is_struct()
117 || it.is_trait()
118 || it.is_primitive()
119 || it.is_union()
120 || it.is_enum()
121 // crate title is displayed as part of logo lockup
122 || (it.is_mod() && !it.is_crate())
123 || it.is_type_alias()
124 {
142 //
143 // crate title is displayed as part of logo lockup
144 let (title_prefix, title) = if !blocks.is_empty() && !it.is_crate() {
125145 (
126146 match *it.kind {
127147 clean::ModuleItem(..) => "Module ",
......@@ -146,8 +166,15 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
146166 } else {
147167 "".into()
148168 };
149 let sidebar =
150 Sidebar { title_prefix, title, is_mod: it.is_mod(), is_crate: it.is_crate(), blocks, path };
169 let sidebar = Sidebar {
170 title_prefix,
171 title,
172 is_mod: it.is_mod(),
173 is_crate: it.is_crate(),
174 parent_is_crate: sidebar_path.len() == 1,
175 blocks,
176 path,
177 };
151178 sidebar.render_into(buffer).unwrap();
152179}
153180
......@@ -163,30 +190,80 @@ fn get_struct_fields_name<'a>(fields: &'a [clean::Item]) -> Vec<Link<'a>> {
163190 fields
164191}
165192
193fn docblock_toc<'a>(
194 cx: &'a Context<'_>,
195 it: &'a clean::Item,
196 ids: &mut IdMap,
197) -> Option<LinkBlock<'a>> {
198 let (toc, _) = MarkdownWithToc {
199 content: &it.doc_value(),
200 links: &it.links(cx),
201 ids,
202 error_codes: cx.shared.codes,
203 edition: cx.shared.edition(),
204 playground: &cx.shared.playground,
205 }
206 .into_parts();
207 let links: Vec<Link<'_>> = toc
208 .entries
209 .into_iter()
210 .map(|entry| {
211 Link {
212 name_html: if entry.html == entry.name { None } else { Some(entry.html.into()) },
213 name: entry.name.into(),
214 href: entry.id.into(),
215 children: entry
216 .children
217 .entries
218 .into_iter()
219 .map(|entry| Link {
220 name_html: if entry.html == entry.name {
221 None
222 } else {
223 Some(entry.html.into())
224 },
225 name: entry.name.into(),
226 href: entry.id.into(),
227 // Only a single level of nesting is shown here.
228 // Going the full six could break the layout,
229 // so we have to cut it off somewhere.
230 children: vec![],
231 })
232 .collect(),
233 }
234 })
235 .collect();
236 if links.is_empty() {
237 None
238 } else {
239 Some(LinkBlock::new(Link::new("", "Sections"), "top-toc", links))
240 }
241}
242
166243fn sidebar_struct<'a>(
167244 cx: &'a Context<'_>,
168245 it: &'a clean::Item,
169246 s: &'a clean::Struct,
170) -> Vec<LinkBlock<'a>> {
247 items: &mut Vec<LinkBlock<'a>>,
248) {
171249 let fields = get_struct_fields_name(&s.fields);
172250 let field_name = match s.ctor_kind {
173251 Some(CtorKind::Fn) => Some("Tuple Fields"),
174252 None => Some("Fields"),
175253 _ => None,
176254 };
177 let mut items = vec![];
178255 if let Some(name) = field_name {
179256 items.push(LinkBlock::new(Link::new("fields", name), "structfield", fields));
180257 }
181 sidebar_assoc_items(cx, it, &mut items);
182 items
258 sidebar_assoc_items(cx, it, items);
183259}
184260
185261fn sidebar_trait<'a>(
186262 cx: &'a Context<'_>,
187263 it: &'a clean::Item,
188264 t: &'a clean::Trait,
189) -> Vec<LinkBlock<'a>> {
265 blocks: &mut Vec<LinkBlock<'a>>,
266) {
190267 fn filter_items<'a>(
191268 items: &'a [clean::Item],
192269 filt: impl Fn(&clean::Item) -> bool,
......@@ -223,19 +300,20 @@ fn sidebar_trait<'a>(
223300 foreign_impls.sort();
224301 }
225302
226 let mut blocks: Vec<LinkBlock<'_>> = [
227 ("required-associated-types", "Required Associated Types", req_assoc),
228 ("provided-associated-types", "Provided Associated Types", prov_assoc),
229 ("required-associated-consts", "Required Associated Constants", req_assoc_const),
230 ("provided-associated-consts", "Provided Associated Constants", prov_assoc_const),
231 ("required-methods", "Required Methods", req_method),
232 ("provided-methods", "Provided Methods", prov_method),
233 ("foreign-impls", "Implementations on Foreign Types", foreign_impls),
234 ]
235 .into_iter()
236 .map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items))
237 .collect();
238 sidebar_assoc_items(cx, it, &mut blocks);
303 blocks.extend(
304 [
305 ("required-associated-types", "Required Associated Types", req_assoc),
306 ("provided-associated-types", "Provided Associated Types", prov_assoc),
307 ("required-associated-consts", "Required Associated Constants", req_assoc_const),
308 ("provided-associated-consts", "Provided Associated Constants", prov_assoc_const),
309 ("required-methods", "Required Methods", req_method),
310 ("provided-methods", "Provided Methods", prov_method),
311 ("foreign-impls", "Implementations on Foreign Types", foreign_impls),
312 ]
313 .into_iter()
314 .map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items)),
315 );
316 sidebar_assoc_items(cx, it, blocks);
239317
240318 if !t.is_object_safe(cx.tcx()) {
241319 blocks.push(LinkBlock::forced(
......@@ -251,20 +329,17 @@ fn sidebar_trait<'a>(
251329 "impl-auto",
252330 ));
253331 }
254 blocks
255332}
256333
257fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
334fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item, items: &mut Vec<LinkBlock<'a>>) {
258335 if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) {
259 let mut items = vec![];
260 sidebar_assoc_items(cx, it, &mut items);
261 items
336 sidebar_assoc_items(cx, it, items);
262337 } else {
263338 let shared = Rc::clone(&cx.shared);
264339 let (concrete, synthetic, blanket_impl) =
265340 super::get_filtered_impls_for_reference(&shared, it);
266341
267 sidebar_render_assoc_items(cx, &mut IdMap::new(), concrete, synthetic, blanket_impl).into()
342 sidebar_render_assoc_items(cx, &mut IdMap::new(), concrete, synthetic, blanket_impl, items);
268343 }
269344}
270345
......@@ -272,8 +347,8 @@ fn sidebar_type_alias<'a>(
272347 cx: &'a Context<'_>,
273348 it: &'a clean::Item,
274349 t: &'a clean::TypeAlias,
275) -> Vec<LinkBlock<'a>> {
276 let mut items = vec![];
350 items: &mut Vec<LinkBlock<'a>>,
351) {
277352 if let Some(inner_type) = &t.inner_type {
278353 items.push(LinkBlock::forced(Link::new("aliased-type", "Aliased type"), "type"));
279354 match inner_type {
......@@ -295,19 +370,18 @@ fn sidebar_type_alias<'a>(
295370 }
296371 }
297372 }
298 sidebar_assoc_items(cx, it, &mut items);
299 items
373 sidebar_assoc_items(cx, it, items);
300374}
301375
302376fn sidebar_union<'a>(
303377 cx: &'a Context<'_>,
304378 it: &'a clean::Item,
305379 u: &'a clean::Union,
306) -> Vec<LinkBlock<'a>> {
380 items: &mut Vec<LinkBlock<'a>>,
381) {
307382 let fields = get_struct_fields_name(&u.fields);
308 let mut items = vec![LinkBlock::new(Link::new("fields", "Fields"), "structfield", fields)];
309 sidebar_assoc_items(cx, it, &mut items);
310 items
383 items.push(LinkBlock::new(Link::new("fields", "Fields"), "structfield", fields));
384 sidebar_assoc_items(cx, it, items);
311385}
312386
313387/// Adds trait implementations into the blocks of links
......@@ -346,21 +420,22 @@ fn sidebar_assoc_items<'a>(
346420 methods.sort();
347421 }
348422
349 let mut deref_methods = Vec::new();
350 let [concrete, synthetic, blanket] = if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
423 let mut blocks = vec![
424 LinkBlock::new(
425 Link::new("implementations", "Associated Constants"),
426 "associatedconstant",
427 assoc_consts,
428 ),
429 LinkBlock::new(Link::new("implementations", "Methods"), "method", methods),
430 ];
431
432 if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
351433 if let Some(impl_) =
352434 v.iter().find(|i| i.trait_did() == cx.tcx().lang_items().deref_trait())
353435 {
354436 let mut derefs = DefIdSet::default();
355437 derefs.insert(did);
356 sidebar_deref_methods(
357 cx,
358 &mut deref_methods,
359 impl_,
360 v,
361 &mut derefs,
362 &mut used_links,
363 );
438 sidebar_deref_methods(cx, &mut blocks, impl_, v, &mut derefs, &mut used_links);
364439 }
365440
366441 let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
......@@ -368,21 +443,15 @@ fn sidebar_assoc_items<'a>(
368443 let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) =
369444 concrete.into_iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_blanket());
370445
371 sidebar_render_assoc_items(cx, &mut id_map, concrete, synthetic, blanket_impl)
372 } else {
373 std::array::from_fn(|_| LinkBlock::new(Link::empty(), "", vec![]))
374 };
375
376 let mut blocks = vec![
377 LinkBlock::new(
378 Link::new("implementations", "Associated Constants"),
379 "associatedconstant",
380 assoc_consts,
381 ),
382 LinkBlock::new(Link::new("implementations", "Methods"), "method", methods),
383 ];
384 blocks.append(&mut deref_methods);
385 blocks.extend([concrete, synthetic, blanket]);
446 sidebar_render_assoc_items(
447 cx,
448 &mut id_map,
449 concrete,
450 synthetic,
451 blanket_impl,
452 &mut blocks,
453 );
454 }
386455 links.append(&mut blocks);
387456 }
388457}
......@@ -472,7 +541,8 @@ fn sidebar_enum<'a>(
472541 cx: &'a Context<'_>,
473542 it: &'a clean::Item,
474543 e: &'a clean::Enum,
475) -> Vec<LinkBlock<'a>> {
544 items: &mut Vec<LinkBlock<'a>>,
545) {
476546 let mut variants = e
477547 .variants()
478548 .filter_map(|v| v.name)
......@@ -480,24 +550,37 @@ fn sidebar_enum<'a>(
480550 .collect::<Vec<_>>();
481551 variants.sort_unstable();
482552
483 let mut items = vec![LinkBlock::new(Link::new("variants", "Variants"), "variant", variants)];
484 sidebar_assoc_items(cx, it, &mut items);
485 items
553 items.push(LinkBlock::new(Link::new("variants", "Variants"), "variant", variants));
554 sidebar_assoc_items(cx, it, items);
486555}
487556
488557pub(crate) fn sidebar_module_like(
489558 item_sections_in_use: FxHashSet<ItemSection>,
559 ids: &mut IdMap,
560 module_like: ModuleLike,
490561) -> LinkBlock<'static> {
491 let item_sections = ItemSection::ALL
562 let item_sections: Vec<Link<'_>> = ItemSection::ALL
492563 .iter()
493564 .copied()
494565 .filter(|sec| item_sections_in_use.contains(sec))
495 .map(|sec| Link::new(sec.id(), sec.name()))
566 .map(|sec| Link::new(ids.derive(sec.id()), sec.name()))
496567 .collect();
497 LinkBlock::new(Link::empty(), "", item_sections)
568 let header = if let Some(first_section) = item_sections.get(0) {
569 Link::new(
570 first_section.href.to_owned(),
571 if module_like.is_crate() { "Crate Items" } else { "Module Items" },
572 )
573 } else {
574 Link::empty()
575 };
576 LinkBlock::new(header, "", item_sections)
498577}
499578
500fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> {
579fn sidebar_module(
580 items: &[clean::Item],
581 ids: &mut IdMap,
582 module_like: ModuleLike,
583) -> LinkBlock<'static> {
501584 let item_sections_in_use: FxHashSet<_> = items
502585 .iter()
503586 .filter(|it| {
......@@ -518,13 +601,15 @@ fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> {
518601 .map(|it| item_ty_to_section(it.type_()))
519602 .collect();
520603
521 sidebar_module_like(item_sections_in_use)
604 sidebar_module_like(item_sections_in_use, ids, module_like)
522605}
523606
524fn sidebar_foreign_type<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> {
525 let mut items = vec![];
526 sidebar_assoc_items(cx, it, &mut items);
527 items
607fn sidebar_foreign_type<'a>(
608 cx: &'a Context<'_>,
609 it: &'a clean::Item,
610 items: &mut Vec<LinkBlock<'a>>,
611) {
612 sidebar_assoc_items(cx, it, items);
528613}
529614
530615/// Renders the trait implementations for this type
......@@ -534,7 +619,8 @@ fn sidebar_render_assoc_items(
534619 concrete: Vec<&Impl>,
535620 synthetic: Vec<&Impl>,
536621 blanket_impl: Vec<&Impl>,
537) -> [LinkBlock<'static>; 3] {
622 items: &mut Vec<LinkBlock<'_>>,
623) {
538624 let format_impls = |impls: Vec<&Impl>, id_map: &mut IdMap| {
539625 let mut links = FxHashSet::default();
540626
......@@ -559,7 +645,7 @@ fn sidebar_render_assoc_items(
559645 let concrete = format_impls(concrete, id_map);
560646 let synthetic = format_impls(synthetic, id_map);
561647 let blanket = format_impls(blanket_impl, id_map);
562 [
648 items.extend([
563649 LinkBlock::new(
564650 Link::new("trait-implementations", "Trait Implementations"),
565651 "trait-implementation",
......@@ -575,7 +661,7 @@ fn sidebar_render_assoc_items(
575661 "blanket-implementation",
576662 blanket,
577663 ),
578 ]
664 ]);
579665}
580666
581667fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String {
src/librustdoc/html/static/css/rustdoc.css+13-1
......@@ -568,12 +568,16 @@ img {
568568 width: 48px;
569569}
570570
571ul.block, .block li {
571ul.block, .block li, .block ul {
572572 padding: 0;
573573 margin: 0;
574574 list-style: none;
575575}
576576
577.block ul a {
578 padding-left: 1rem;
579}
580
577581.sidebar-elems a,
578582.sidebar > h2 a {
579583 display: block;
......@@ -585,6 +589,14 @@ ul.block, .block li {
585589 background-clip: border-box;
586590}
587591
592.hide-toc #rustdoc-toc, .hide-toc .in-crate {
593 display: none;
594}
595
596.hide-modnav #rustdoc-modnav {
597 display: none;
598}
599
588600.sidebar h2 {
589601 text-wrap: balance;
590602 overflow-wrap: anywhere;
src/librustdoc/html/static/js/main.js+2-2
......@@ -499,7 +499,7 @@ function preLoadCss(cssUrl) {
499499 if (!window.SIDEBAR_ITEMS) {
500500 return;
501501 }
502 const sidebar = document.getElementsByClassName("sidebar-elems")[0];
502 const sidebar = document.getElementById("rustdoc-modnav");
503503
504504 /**
505505 * Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
......@@ -885,7 +885,7 @@ function preLoadCss(cssUrl) {
885885 if (!window.ALL_CRATES) {
886886 return;
887887 }
888 const sidebarElems = document.getElementsByClassName("sidebar-elems")[0];
888 const sidebarElems = document.getElementById("rustdoc-modnav");
889889 if (!sidebarElems) {
890890 return;
891891 }
src/librustdoc/html/static/js/settings.js+29
......@@ -36,6 +36,20 @@
3636 removeClass(document.documentElement, "hide-sidebar");
3737 }
3838 break;
39 case "hide-toc":
40 if (value === true) {
41 addClass(document.documentElement, "hide-toc");
42 } else {
43 removeClass(document.documentElement, "hide-toc");
44 }
45 break;
46 case "hide-modnav":
47 if (value === true) {
48 addClass(document.documentElement, "hide-modnav");
49 } else {
50 removeClass(document.documentElement, "hide-modnav");
51 }
52 break;
3953 }
4054 }
4155
......@@ -102,6 +116,11 @@
102116 let output = "";
103117
104118 for (const setting of settings) {
119 if (setting === "hr") {
120 output += "<hr>";
121 continue;
122 }
123
105124 const js_data_name = setting["js_name"];
106125 const setting_name = setting["name"];
107126
......@@ -198,6 +217,16 @@
198217 "js_name": "hide-sidebar",
199218 "default": false,
200219 },
220 {
221 "name": "Hide table of contents",
222 "js_name": "hide-toc",
223 "default": false,
224 },
225 {
226 "name": "Hide module navigation",
227 "js_name": "hide-modnav",
228 "default": false,
229 },
201230 {
202231 "name": "Disable keyboard shortcuts",
203232 "js_name": "disable-shortcuts",
src/librustdoc/html/static/js/storage.js+9-4
......@@ -196,16 +196,21 @@ updateTheme();
196196// This needs to be done here because this JS is render-blocking,
197197// so that the sidebar doesn't "jump" after appearing on screen.
198198// The user interaction to change this is set up in main.js.
199//
200// At this point in page load, `document.body` is not available yet.
201// Set a class on the `<html>` element instead.
199202if (getSettingValue("source-sidebar-show") === "true") {
200 // At this point in page load, `document.body` is not available yet.
201 // Set a class on the `<html>` element instead.
202203 addClass(document.documentElement, "src-sidebar-expanded");
203204}
204205if (getSettingValue("hide-sidebar") === "true") {
205 // At this point in page load, `document.body` is not available yet.
206 // Set a class on the `<html>` element instead.
207206 addClass(document.documentElement, "hide-sidebar");
208207}
208if (getSettingValue("hide-toc") === "true") {
209 addClass(document.documentElement, "hide-toc");
210}
211if (getSettingValue("hide-modnav") === "true") {
212 addClass(document.documentElement, "hide-modnav");
213}
209214function updateSidebarWidth() {
210215 const desktopSidebarWidth = getSettingValue("desktop-sidebar-width");
211216 if (desktopSidebarWidth && desktopSidebarWidth !== "null") {
src/librustdoc/html/templates/sidebar.html+38-11
......@@ -1,8 +1,3 @@
1{% if !title.is_empty() %}
2 <h2 class="location"> {# #}
3 <a href="#">{{title_prefix}}{{title|wrapped|safe}}</a> {# #}
4 </h2>
5{% endif %}
61<div class="sidebar-elems">
72 {% if is_crate %}
83 <ul class="block"> {# #}
......@@ -11,18 +6,46 @@
116 {% endif %}
127
138 {% if self.should_render_blocks() %}
14 <section>
9 <section id="rustdoc-toc">
10 {% if !title.is_empty() %}
11 <h2 class="location"> {# #}
12 <a href="#">{{title_prefix}}{{title|wrapped|safe}}</a> {# #}
13 </h2>
14 {% endif %}
1515 {% for block in blocks %}
1616 {% if block.should_render() %}
1717 {% if !block.heading.name.is_empty() %}
18 <h3><a href="#{{block.heading.href|safe}}"> {# #}
19 {{block.heading.name|wrapped|safe}} {# #}
20 </a></h3> {# #}
18 <h3> {# #}
19 <a href="#{{block.heading.href|safe}}">{{block.heading.name|wrapped|safe}}</a> {# #}
20 </h3>
2121 {% endif %}
2222 {% if !block.links.is_empty() %}
2323 <ul class="block{% if !block.class.is_empty() +%} {{+block.class}}{% endif %}">
2424 {% for link in block.links %}
25 <li><a href="#{{link.href|safe}}">{{link.name}}</a></li>
25 <li> {# #}
26 <a href="#{{link.href|safe}}" title="{{link.name}}">
27 {% match link.name_html %}
28 {% when Some with (html) %}
29 {{html|safe}}
30 {% else %}
31 {{link.name}}
32 {% endmatch %}
33 </a> {# #}
34 {% if !link.children.is_empty() %}
35 <ul>
36 {% for child in link.children %}
37 <li><a href="#{{child.href|safe}}" title="{{child.name}}">
38 {% match child.name_html %}
39 {% when Some with (html) %}
40 {{html|safe}}
41 {% else %}
42 {{child.name}}
43 {% endmatch %}
44 </a></li>
45 {% endfor %}
46 </ul>
47 {% endif %}
48 </li>
2649 {% endfor %}
2750 </ul>
2851 {% endif %}
......@@ -30,7 +53,11 @@
3053 {% endfor %}
3154 </section>
3255 {% endif %}
56 <div id="rustdoc-modnav">
3357 {% if !path.is_empty() %}
34 <h2><a href="{% if is_mod %}../{% endif %}index.html">In {{+ path|wrapped|safe}}</a></h2>
58 <h2{% if parent_is_crate +%} class="in-crate"{% endif %}> {# #}
59 <a href="{% if is_mod %}../{% endif %}index.html">In {{+ path|wrapped|safe}}</a> {# #}
60 </h2>
3561 {% endif %}
62 </div> {# #}
3663</div>
src/librustdoc/html/toc.rs+17-9
......@@ -1,4 +1,5 @@
11//! Table-of-contents creation.
2use crate::html::escape::Escape;
23
34/// A (recursive) table of contents
45#[derive(Debug, PartialEq)]
......@@ -16,7 +17,7 @@ pub(crate) struct Toc {
1617 /// ### A
1718 /// ## B
1819 /// ```
19 entries: Vec<TocEntry>,
20 pub(crate) entries: Vec<TocEntry>,
2021}
2122
2223impl Toc {
......@@ -27,11 +28,16 @@ impl Toc {
2728
2829#[derive(Debug, PartialEq)]
2930pub(crate) struct TocEntry {
30 level: u32,
31 sec_number: String,
32 name: String,
33 id: String,
34 children: Toc,
31 pub(crate) level: u32,
32 pub(crate) sec_number: String,
33 // name is a plain text header that works in a `title` tag
34 // html includes `<code>` tags
35 // the tooltip is used so that, when a toc is truncated,
36 // you can mouse over it to see the whole thing
37 pub(crate) name: String,
38 pub(crate) html: String,
39 pub(crate) id: String,
40 pub(crate) children: Toc,
3541}
3642
3743/// Progressive construction of a table of contents.
......@@ -115,7 +121,7 @@ impl TocBuilder {
115121 /// Push a level `level` heading into the appropriate place in the
116122 /// hierarchy, returning a string containing the section number in
117123 /// `<num>.<num>.<num>` format.
118 pub(crate) fn push(&mut self, level: u32, name: String, id: String) -> &str {
124 pub(crate) fn push(&mut self, level: u32, name: String, html: String, id: String) -> &str {
119125 assert!(level >= 1);
120126
121127 // collapse all previous sections into their parents until we
......@@ -149,6 +155,7 @@ impl TocBuilder {
149155 self.chain.push(TocEntry {
150156 level,
151157 name,
158 html,
152159 sec_number,
153160 id,
154161 children: Toc { entries: Vec::new() },
......@@ -170,10 +177,11 @@ impl Toc {
170177 // recursively format this table of contents
171178 let _ = write!(
172179 v,
173 "\n<li><a href=\"#{id}\">{num} {name}</a>",
180 "\n<li><a href=\"#{id}\" title=\"{name}\">{num} {html}</a>",
174181 id = entry.id,
175182 num = entry.sec_number,
176 name = entry.name
183 name = Escape(&entry.name),
184 html = &entry.html,
177185 );
178186 entry.children.print_inner(&mut *v);
179187 v.push_str("</li>");
src/librustdoc/html/toc/tests.rs+5-1
......@@ -9,7 +9,10 @@ fn builder_smoke() {
99 // there's been no macro mistake.
1010 macro_rules! push {
1111 ($level: expr, $name: expr) => {
12 assert_eq!(builder.push($level, $name.to_string(), "".to_string()), $name);
12 assert_eq!(
13 builder.push($level, $name.to_string(), $name.to_string(), "".to_string()),
14 $name
15 );
1316 };
1417 }
1518 push!(2, "0.1");
......@@ -48,6 +51,7 @@ fn builder_smoke() {
4851 TocEntry {
4952 level: $level,
5053 name: $name.to_string(),
54 html: $name.to_string(),
5155 sec_number: $name.to_string(),
5256 id: "".to_string(),
5357 children: toc!($($sub),*)
src/librustdoc/markdown.rs+1
......@@ -72,6 +72,7 @@ pub(crate) fn render<P: AsRef<Path>>(
7272 let text = if !options.markdown_no_toc {
7373 MarkdownWithToc {
7474 content: text,
75 links: &[],
7576 ids: &mut ids,
7677 error_codes,
7778 edition,
src/tools/build_helper/src/git.rs+34
......@@ -159,3 +159,37 @@ pub fn get_git_untracked_files(
159159 .collect();
160160 Ok(Some(files))
161161}
162
163/// Print a warning if the branch returned from `updated_master_branch` is old
164///
165/// For certain configurations of git repository, this remote will not be
166/// updated when running `git pull`.
167///
168/// This can result in formatting thousands of files instead of a dozen,
169/// so we should warn the user something is wrong.
170pub fn warn_old_master_branch(
171 config: &GitConfig<'_>,
172 git_dir: &Path,
173) -> Result<(), Box<dyn std::error::Error>> {
174 use std::time::Duration;
175 const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10);
176 let updated_master = updated_master_branch(config, Some(git_dir))?;
177 let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master);
178 match std::fs::metadata(branch_path) {
179 Ok(meta) => {
180 if meta.modified()?.elapsed()? > WARN_AFTER {
181 eprintln!("warning: {updated_master} has not been updated in 10 days");
182 } else {
183 return Ok(());
184 }
185 }
186 Err(err) => {
187 eprintln!("warning: unable to check if {updated_master} is old due to error: {err}")
188 }
189 }
190 eprintln!(
191 "warning: {updated_master} is used to determine if files have been modified\n\
192 warning: if it is not updated, this may cause files to be needlessly reformatted"
193 );
194 Ok(())
195}
src/tools/compiletest/src/command-list.rs+1
......@@ -136,6 +136,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
136136 "min-llvm-version",
137137 "min-system-llvm-version",
138138 "needs-asm-support",
139 "needs-deterministic-layouts",
139140 "needs-dlltool",
140141 "needs-dynamic-linking",
141142 "needs-force-clang-based-tests",
src/tools/compiletest/src/common.rs+3
......@@ -274,6 +274,9 @@ pub struct Config {
274274 /// Flags to pass to the compiler when building for the target
275275 pub target_rustcflags: Vec<String>,
276276
277 /// Whether the compiler and stdlib has been built with randomized struct layouts
278 pub rust_randomized_layout: bool,
279
277280 /// Whether tests should be optimized by default. Individual test-suites and test files may
278281 /// override this setting.
279282 pub optimize_tests: bool,
src/tools/compiletest/src/header/needs.rs+5
......@@ -134,6 +134,11 @@ pub(super) fn handle_needs(
134134 condition: config.target_cfg().relocation_model == "pic",
135135 ignore_reason: "ignored on targets without PIC relocation model",
136136 },
137 Need {
138 name: "needs-deterministic-layouts",
139 condition: !config.rust_randomized_layout,
140 ignore_reason: "ignored when randomizing layouts",
141 },
137142 Need {
138143 name: "needs-wasmtime",
139144 condition: config.runner.as_ref().is_some_and(|r| r.contains("wasmtime")),
src/tools/compiletest/src/lib.rs+6
......@@ -99,6 +99,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
9999 )
100100 .optmulti("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS")
101101 .optmulti("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS")
102 .optflag(
103 "",
104 "rust-randomized-layout",
105 "set this when rustc/stdlib were compiled with randomized layouts",
106 )
102107 .optflag("", "optimize-tests", "run tests with optimizations enabled")
103108 .optflag("", "verbose", "run tests verbosely, showing all output")
104109 .optflag(
......@@ -286,6 +291,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
286291 host_rustcflags: matches.opt_strs("host-rustcflags"),
287292 target_rustcflags: matches.opt_strs("target-rustcflags"),
288293 optimize_tests: matches.opt_present("optimize-tests"),
294 rust_randomized_layout: matches.opt_present("rust-randomized-layout"),
289295 target,
290296 host: opt_str2(matches.opt_str("host")),
291297 cdb,
src/tools/miri/tests/pass/dyn-arbitrary-self.rs+1-1
......@@ -1,6 +1,6 @@
11//@revisions: stack tree
22//@[tree]compile-flags: -Zmiri-tree-borrows
3#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
3#![feature(arbitrary_self_types_pointers, unsize, coerce_unsized, dispatch_from_dyn)]
44#![feature(rustc_attrs)]
55
66fn pin_box_dyn() {
tests/assembly/targets/targets-elf.rs+3
......@@ -129,6 +129,9 @@
129129//@ revisions: armv7_linux_androideabi
130130//@ [armv7_linux_androideabi] compile-flags: --target armv7-linux-androideabi
131131//@ [armv7_linux_androideabi] needs-llvm-components: arm
132//@ revisions: armv7_rtems_eabihf
133//@ [armv7_rtems_eabihf] compile-flags: --target armv7-rtems-eabihf
134//@ [armv7_rtems_eabihf] needs-llvm-components: arm
132135//@ revisions: armv7_sony_vita_newlibeabihf
133136//@ [armv7_sony_vita_newlibeabihf] compile-flags: --target armv7-sony-vita-newlibeabihf
134137//@ [armv7_sony_vita_newlibeabihf] needs-llvm-components: arm
tests/codegen/issues/issue-86106.rs+1
......@@ -1,5 +1,6 @@
11//@ only-64bit llvm appears to use stores instead of memset on 32bit
22//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
3//@ needs-deterministic-layouts
34
45// The below two functions ensure that both `String::new()` and `"".to_string()`
56// produce the identical code.
tests/codegen/mem-replace-big-type.rs+1
......@@ -5,6 +5,7 @@
55
66//@ compile-flags: -C no-prepopulate-passes -Zinline-mir=no
77//@ ignore-debug: precondition checks in ptr::read make them a bad candidate for MIR inlining
8//@ needs-deterministic-layouts
89
910#![crate_type = "lib"]
1011
tests/codegen/slice-iter-nonnull.rs+1
......@@ -1,4 +1,5 @@
11//@ compile-flags: -O
2//@ needs-deterministic-layouts
23#![crate_type = "lib"]
34#![feature(exact_size_is_empty)]
45
tests/codegen/vecdeque-drain.rs+1
......@@ -1,6 +1,7 @@
11// Check that draining at the front or back doesn't copy memory.
22
33//@ compile-flags: -O
4//@ needs-deterministic-layouts
45//@ ignore-debug: FIXME: checks for call detect scoped noalias metadata
56
67#![crate_type = "lib"]
tests/mir-opt/building/receiver_ptr_mutability.rs+1-1
......@@ -1,7 +1,7 @@
11// skip-filecheck
22// EMIT_MIR receiver_ptr_mutability.main.built.after.mir
33
4#![feature(arbitrary_self_types)]
4#![feature(arbitrary_self_types_pointers)]
55
66struct Test {}
77
tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs+1
......@@ -1,3 +1,4 @@
1//@needs-deterministic-layouts
12// Verify that we do not ICE when printing an invalid constant.
23// EMIT_MIR_FOR_EACH_BIT_WIDTH
34// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
tests/rustdoc-gui/sidebar-modnav-position.goml created+44
......@@ -0,0 +1,44 @@
1// Verifies that, when TOC is hidden, modnav is always in exactly the same spot
2// This is driven by a reasonably common use case:
3//
4// - There are three or more items that might meet my needs.
5// - I open the first one, decide it's not what I want, switch to the second one using the sidebar.
6// - The second one also doesn't meet my needs, so I switch to the third.
7// - The third also doesn't meet my needs, so...
8//
9// because the sibling module nav is in exactly the same place every time,
10// it's very easy to find and switch between pages that way.
11
12go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
13show-text: true
14set-local-storage: {"rustdoc-hide-toc": "true"}
15
16define-function: (
17 "check-positions",
18 [url],
19 block {
20 go-to: "file://" + |DOC_PATH| + |url|
21 // Checking results colors.
22 assert-position: ("#rustdoc-modnav > h2", {"x": |h2_x|, "y": |h2_y|})
23 assert-position: (
24 "#rustdoc-modnav > ul:first-of-type > li:first-of-type",
25 {"x": |x|, "y": |y|}
26 )
27 },
28)
29
30// First, at test_docs root
31go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
32store-position: ("#rustdoc-modnav > h2", {"x": h2_x, "y": h2_y})
33store-position: ("#rustdoc-modnav > ul:first-of-type > li:first-of-type", {"x": x, "y": y})
34call-function: ("check-positions", {"url": "/test_docs/enum.WhoLetTheDogOut.html"})
35call-function: ("check-positions", {"url": "/test_docs/struct.StructWithPublicUndocumentedFields.html"})
36call-function: ("check-positions", {"url": "/test_docs/codeblock_sub/index.html"})
37
38// Now in a submodule
39go-to: "file://" + |DOC_PATH| + "/test_docs/fields/struct.Struct.html"
40store-position: ("#rustdoc-modnav > h2", {"x": h2_x, "y": h2_y})
41store-position: ("#rustdoc-modnav > ul:first-of-type > li:first-of-type", {"x": x, "y": y})
42call-function: ("check-positions", {"url": "/test_docs/fields/struct.Struct.html"})
43call-function: ("check-positions", {"url": "/test_docs/fields/union.Union.html"})
44call-function: ("check-positions", {"url": "/test_docs/fields/enum.Enum.html"})
tests/rustdoc-gui/sidebar.goml+39-6
......@@ -118,7 +118,7 @@ assert-false: ".sidebar-elems > .crate"
118118go-to: "./module/index.html"
119119assert-property: (".sidebar", {"clientWidth": "200"})
120120assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
121assert-text: (".sidebar > .location", "Module module")
121assert-text: (".sidebar .location", "Module module")
122122assert-count: (".sidebar .location", 1)
123123assert-text: (".sidebar-elems ul.block > li.current > a", "module")
124124// Module page requires three headings:
......@@ -126,8 +126,8 @@ assert-text: (".sidebar-elems ul.block > li.current > a", "module")
126126// - Module name, followed by TOC for module headings
127127// - "In crate [name]" parent pointer, followed by sibling navigation
128128assert-count: (".sidebar h2", 3)
129assert-text: (".sidebar > .sidebar-elems > h2", "In crate lib2")
130assert-property: (".sidebar > .sidebar-elems > h2 > a", {
129assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In crate lib2")
130assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", {
131131 "href": "/lib2/index.html",
132132}, ENDS_WITH)
133133// We check that we don't have the crate list.
......@@ -136,9 +136,9 @@ assert-false: ".sidebar-elems > .crate"
136136go-to: "./sub_module/sub_sub_module/index.html"
137137assert-property: (".sidebar", {"clientWidth": "200"})
138138assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2")
139assert-text: (".sidebar > .location", "Module sub_sub_module")
140assert-text: (".sidebar > .sidebar-elems > h2", "In lib2::module::sub_module")
141assert-property: (".sidebar > .sidebar-elems > h2 > a", {
139assert-text: (".sidebar .location", "Module sub_sub_module")
140assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In lib2::module::sub_module")
141assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", {
142142 "href": "/module/sub_module/index.html",
143143}, ENDS_WITH)
144144assert-text: (".sidebar-elems ul.block > li.current > a", "sub_sub_module")
......@@ -198,3 +198,36 @@ assert-position-false: (".sidebar-crate > h2 > a", {"x": -3})
198198// when line-wrapped, see that it becomes flush-left again
199199drag-and-drop: ((205, 100), (108, 100))
200200assert-position: (".sidebar-crate > h2 > a", {"x": -3})
201
202// Configuration option to show TOC in sidebar.
203set-local-storage: {"rustdoc-hide-toc": "true"}
204go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
205assert-css: ("#rustdoc-toc", {"display": "none"})
206assert-css: (".sidebar .in-crate", {"display": "none"})
207set-local-storage: {"rustdoc-hide-toc": "false"}
208go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
209assert-css: ("#rustdoc-toc", {"display": "block"})
210assert-css: (".sidebar .in-crate", {"display": "block"})
211
212set-local-storage: {"rustdoc-hide-modnav": "true"}
213go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
214assert-css: ("#rustdoc-modnav", {"display": "none"})
215set-local-storage: {"rustdoc-hide-modnav": "false"}
216go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html"
217assert-css: ("#rustdoc-modnav", {"display": "block"})
218
219set-local-storage: {"rustdoc-hide-toc": "true"}
220go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
221assert-css: ("#rustdoc-toc", {"display": "none"})
222assert-false: ".sidebar .in-crate"
223set-local-storage: {"rustdoc-hide-toc": "false"}
224go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
225assert-css: ("#rustdoc-toc", {"display": "block"})
226assert-false: ".sidebar .in-crate"
227
228set-local-storage: {"rustdoc-hide-modnav": "true"}
229go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
230assert-css: ("#rustdoc-modnav", {"display": "none"})
231set-local-storage: {"rustdoc-hide-modnav": "false"}
232go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
233assert-css: ("#rustdoc-modnav", {"display": "block"})
tests/rustdoc/sidebar-all-page.rs deleted-34
......@@ -1,34 +0,0 @@
1#![crate_name = "foo"]
2#![feature(rustc_attrs)]
3
4//@ has 'foo/all.html'
5//@ has - '//*[@class="sidebar-elems"]//li' 'Structs'
6//@ has - '//*[@class="sidebar-elems"]//li' 'Enums'
7//@ has - '//*[@class="sidebar-elems"]//li' 'Unions'
8//@ has - '//*[@class="sidebar-elems"]//li' 'Functions'
9//@ has - '//*[@class="sidebar-elems"]//li' 'Traits'
10//@ has - '//*[@class="sidebar-elems"]//li' 'Macros'
11//@ has - '//*[@class="sidebar-elems"]//li' 'Type Aliases'
12//@ has - '//*[@class="sidebar-elems"]//li' 'Constants'
13//@ has - '//*[@class="sidebar-elems"]//li' 'Statics'
14//@ has - '//*[@class="sidebar-elems"]//li' 'Primitive Types'
15
16pub struct Foo;
17pub enum Enum {
18 A,
19}
20pub union Bar {
21 a: u8,
22 b: u16,
23}
24pub fn foo() {}
25pub trait Trait {}
26#[macro_export]
27macro_rules! foo {
28 () => {};
29}
30pub type Type = u8;
31pub const FOO: u8 = 0;
32pub static BAR: u8 = 0;
33#[rustc_doc_primitive = "u8"]
34mod u8 {}
tests/rustdoc/sidebar-items.rs deleted-63
......@@ -1,63 +0,0 @@
1#![feature(associated_type_defaults)]
2#![crate_name = "foo"]
3
4//@ has foo/trait.Foo.html
5//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-methods"]' 'Required Methods'
6//@ has - '//*[@class="sidebar-elems"]//section//a' 'bar'
7//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-methods"]' 'Provided Methods'
8//@ has - '//*[@class="sidebar-elems"]//section//a' 'foo'
9//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-associated-consts"]' 'Required Associated Constants'
10//@ has - '//*[@class="sidebar-elems"]//section//a' 'FOO'
11//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-consts"]' 'Provided Associated Constants'
12//@ has - '//*[@class="sidebar-elems"]//section//a' 'BAR'
13//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-associated-types"]' 'Required Associated Types'
14//@ has - '//*[@class="sidebar-elems"]//section//a' 'Output'
15//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
16//@ has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
17//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety'
18pub trait Foo {
19 const FOO: usize;
20 const BAR: u32 = 0;
21 type Extra: Copy = ();
22 type Output: ?Sized;
23
24 fn foo() {}
25 fn bar() -> Self::Output;
26}
27
28//@ has foo/trait.Safe.html
29//@ !has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' ''
30pub trait Safe {
31 fn access(&self);
32}
33
34//@ has foo/struct.Bar.html
35//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
36//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f"]' 'f'
37//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.u"]' 'u'
38//@ !has - '//*[@class="sidebar-elems"]//section//a' 'waza'
39pub struct Bar {
40 pub f: u32,
41 pub u: u32,
42 waza: u32,
43}
44
45//@ has foo/enum.En.html
46//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#variants"]' 'Variants'
47//@ has - '//*[@class="sidebar-elems"]//section//a' 'Foo'
48//@ has - '//*[@class="sidebar-elems"]//section//a' 'Bar'
49pub enum En {
50 Foo,
51 Bar,
52}
53
54//@ has foo/union.MyUnion.html
55//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
56//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f1"]' 'f1'
57//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f2"]' 'f2'
58//@ !has - '//*[@class="sidebar-elems"]//section//a' 'waza'
59pub union MyUnion {
60 pub f1: u32,
61 pub f2: f32,
62 waza: u32,
63}
tests/rustdoc/sidebar-link-generation.rs deleted-13
......@@ -1,13 +0,0 @@
1#![crate_name = "foo"]
2
3//@ has foo/struct.SomeStruct.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.some_fn-1"]' \
4// "some_fn"
5pub struct SomeStruct<T> { _inner: T }
6
7impl SomeStruct<()> {
8 pub fn some_fn(&self) {}
9}
10
11impl SomeStruct<usize> {
12 pub fn some_fn(&self) {}
13}
tests/rustdoc/sidebar-links-to-foreign-impl.rs deleted-16
......@@ -1,16 +0,0 @@
1// issue #56018: "Implementations on Foreign Types" sidebar items should link to specific impls
2
3#![crate_name = "foo"]
4
5//@ has foo/trait.Foo.html
6//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#foreign-impls"]' 'Implementations on Foreign Types'
7//@ has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
8//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo-for-u32"]' 'u32'
9//@ has - '//*[@id="impl-Foo-for-u32"]//h3[@class="code-header"]' 'impl Foo for u32'
10//@ has - "//*[@class=\"sidebar-elems\"]//section//a[@href=\"#impl-Foo-for-%26str\"]" "&'a str"
11//@ has - "//*[@id=\"impl-Foo-for-%26str\"]//h3[@class=\"code-header\"]" "impl<'a> Foo for &'a str"
12pub trait Foo {}
13
14impl Foo for u32 {}
15
16impl<'a> Foo for &'a str {}
tests/rustdoc/sidebar/module.rs created+16
......@@ -0,0 +1,16 @@
1#![crate_name = "foo"]
2
3//@ has 'foo/index.html'
4//@ has - '//section[@id="rustdoc-toc"]/h3' 'Crate Items'
5
6//@ has 'foo/bar/index.html'
7//@ has - '//section[@id="rustdoc-toc"]/h3' 'Module Items'
8pub mod bar {
9 //@ has 'foo/bar/struct.Baz.html'
10 //@ !has - '//section[@id="rustdoc-toc"]/h3' 'Module Items'
11 pub struct Baz;
12}
13
14//@ has 'foo/baz/index.html'
15//@ !has - '//section[@id="rustdoc-toc"]/h3' 'Module Items'
16pub mod baz {}
tests/rustdoc/sidebar/sidebar-all-page.rs created+34
......@@ -0,0 +1,34 @@
1#![crate_name = "foo"]
2#![feature(rustc_attrs)]
3
4//@ has 'foo/all.html'
5//@ has - '//*[@class="sidebar-elems"]//li' 'Structs'
6//@ has - '//*[@class="sidebar-elems"]//li' 'Enums'
7//@ has - '//*[@class="sidebar-elems"]//li' 'Unions'
8//@ has - '//*[@class="sidebar-elems"]//li' 'Functions'
9//@ has - '//*[@class="sidebar-elems"]//li' 'Traits'
10//@ has - '//*[@class="sidebar-elems"]//li' 'Macros'
11//@ has - '//*[@class="sidebar-elems"]//li' 'Type Aliases'
12//@ has - '//*[@class="sidebar-elems"]//li' 'Constants'
13//@ has - '//*[@class="sidebar-elems"]//li' 'Statics'
14//@ has - '//*[@class="sidebar-elems"]//li' 'Primitive Types'
15
16pub struct Foo;
17pub enum Enum {
18 A,
19}
20pub union Bar {
21 a: u8,
22 b: u16,
23}
24pub fn foo() {}
25pub trait Trait {}
26#[macro_export]
27macro_rules! foo {
28 () => {};
29}
30pub type Type = u8;
31pub const FOO: u8 = 0;
32pub static BAR: u8 = 0;
33#[rustc_doc_primitive = "u8"]
34mod u8 {}
tests/rustdoc/sidebar/sidebar-items.rs created+63
......@@ -0,0 +1,63 @@
1#![feature(associated_type_defaults)]
2#![crate_name = "foo"]
3
4//@ has foo/trait.Foo.html
5//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-methods"]' 'Required Methods'
6//@ has - '//*[@class="sidebar-elems"]//section//a' 'bar'
7//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-methods"]' 'Provided Methods'
8//@ has - '//*[@class="sidebar-elems"]//section//a' 'foo'
9//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-associated-consts"]' 'Required Associated Constants'
10//@ has - '//*[@class="sidebar-elems"]//section//a' 'FOO'
11//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-consts"]' 'Provided Associated Constants'
12//@ has - '//*[@class="sidebar-elems"]//section//a' 'BAR'
13//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-associated-types"]' 'Required Associated Types'
14//@ has - '//*[@class="sidebar-elems"]//section//a' 'Output'
15//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
16//@ has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
17//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety'
18pub trait Foo {
19 const FOO: usize;
20 const BAR: u32 = 0;
21 type Extra: Copy = ();
22 type Output: ?Sized;
23
24 fn foo() {}
25 fn bar() -> Self::Output;
26}
27
28//@ has foo/trait.Safe.html
29//@ !has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' ''
30pub trait Safe {
31 fn access(&self);
32}
33
34//@ has foo/struct.Bar.html
35//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
36//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f"]' 'f'
37//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.u"]' 'u'
38//@ !has - '//*[@class="sidebar-elems"]//section//a' 'waza'
39pub struct Bar {
40 pub f: u32,
41 pub u: u32,
42 waza: u32,
43}
44
45//@ has foo/enum.En.html
46//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#variants"]' 'Variants'
47//@ has - '//*[@class="sidebar-elems"]//section//a' 'Foo'
48//@ has - '//*[@class="sidebar-elems"]//section//a' 'Bar'
49pub enum En {
50 Foo,
51 Bar,
52}
53
54//@ has foo/union.MyUnion.html
55//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
56//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f1"]' 'f1'
57//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f2"]' 'f2'
58//@ !has - '//*[@class="sidebar-elems"]//section//a' 'waza'
59pub union MyUnion {
60 pub f1: u32,
61 pub f2: f32,
62 waza: u32,
63}
tests/rustdoc/sidebar/sidebar-link-generation.rs created+13
......@@ -0,0 +1,13 @@
1#![crate_name = "foo"]
2
3//@ has foo/struct.SomeStruct.html '//*[@class="sidebar-elems"]//section//li/a[@href="#method.some_fn-1"]' \
4// "some_fn"
5pub struct SomeStruct<T> { _inner: T }
6
7impl SomeStruct<()> {
8 pub fn some_fn(&self) {}
9}
10
11impl SomeStruct<usize> {
12 pub fn some_fn(&self) {}
13}
tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs created+16
......@@ -0,0 +1,16 @@
1// issue #56018: "Implementations on Foreign Types" sidebar items should link to specific impls
2
3#![crate_name = "foo"]
4
5//@ has foo/trait.Foo.html
6//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#foreign-impls"]' 'Implementations on Foreign Types'
7//@ has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
8//@ has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo-for-u32"]' 'u32'
9//@ has - '//*[@id="impl-Foo-for-u32"]//h3[@class="code-header"]' 'impl Foo for u32'
10//@ has - "//*[@class=\"sidebar-elems\"]//section//a[@href=\"#impl-Foo-for-%26str\"]" "&'a str"
11//@ has - "//*[@id=\"impl-Foo-for-%26str\"]//h3[@class=\"code-header\"]" "impl<'a> Foo for &'a str"
12pub trait Foo {}
13
14impl Foo for u32 {}
15
16impl<'a> Foo for &'a str {}
tests/rustdoc/sidebar/top-toc-html.rs created+23
......@@ -0,0 +1,23 @@
1// ignore-tidy-linelength
2
3#![crate_name = "foo"]
4#![feature(lazy_type_alias)]
5#![allow(incomplete_features)]
6
7//! # Basic [link](https://example.com), *emphasis*, **_very emphasis_** and `code`
8//!
9//! This test case covers TOC entries with rich text inside.
10//! Rustdoc normally supports headers with links, but for the
11//! TOC, that would break the layout.
12//!
13//! For consistency, emphasis is also filtered out.
14
15//@ has foo/index.html
16// User header
17//@ has - '//section[@id="rustdoc-toc"]/h3' 'Sections'
18//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/@title' 'Basic link, emphasis, very emphasis and `code`'
19//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]' 'Basic link, emphasis, very emphasis and code'
20//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/em' 0
21//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/a' 0
22//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/code' 1
23//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#basic-link-emphasis-very-emphasis-and-code"]/code' 'code'
tests/rustdoc/sidebar/top-toc-idmap.rs created+44
......@@ -0,0 +1,44 @@
1#![crate_name = "foo"]
2#![feature(lazy_type_alias)]
3#![allow(incomplete_features)]
4
5//! # Structs
6//!
7//! This header has the same name as a built-in header,
8//! and we need to make sure they're disambiguated with
9//! suffixes.
10//!
11//! Module-like headers get derived from the internal ID map,
12//! so the *internal* one gets a suffix here. To make sure it
13//! works right, the one in the `top-toc` needs to match the one
14//! in the `top-doc`, and the one that's not in the `top-doc`
15//! needs to match the one that isn't in the `top-toc`.
16
17//@ has foo/index.html
18// User header
19//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#structs"]' 'Structs'
20//@ has - '//details[@class="toggle top-doc"]/div[@class="docblock"]/h2[@id="structs"]' 'Structs'
21// Built-in header
22//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block"]/li/a[@href="#structs-1"]' 'Structs'
23//@ has - '//section[@id="main-content"]/h2[@id="structs-1"]' 'Structs'
24
25/// # Fields
26/// ## Fields
27/// ### Fields
28///
29/// The difference between struct-like headers and module-like headers
30/// is strange, but not actually a problem as long as we're consistent.
31
32//@ has foo/struct.MyStruct.html
33// User header
34//@ has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]/li/a[@href="#fields-1"]' 'Fields'
35//@ has - '//details[@class="toggle top-doc"]/div[@class="docblock"]/h2[@id="fields-1"]' 'Fields'
36// Only one level of nesting
37//@ count - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]//a' 2
38// Built-in header
39//@ has - '//section[@id="rustdoc-toc"]/h3/a[@href="#fields"]' 'Fields'
40//@ has - '//section[@id="main-content"]/h2[@id="fields"]' 'Fields'
41
42pub struct MyStruct {
43 pub fields: i32,
44}
tests/rustdoc/sidebar/top-toc-nil.rs created+7
......@@ -0,0 +1,7 @@
1#![crate_name = "foo"]
2
3//! This test case covers missing top TOC entries.
4
5//@ has foo/index.html
6// User header
7//@ !has - '//section[@id="rustdoc-toc"]/ul[@class="block top-toc"]' 'Basic link and emphasis'
tests/rustdoc/strip-enum-variant.no-not-shown.html+1-1
......@@ -1 +1 @@
1<ul class="block variant"><li><a href="#variant.Shown">Shown</a></li></ul>
\ No newline at end of file
1<ul class="block variant"><li><a href="#variant.Shown" title="Shown">Shown</a></li></ul>
\ No newline at end of file
tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs+1-1
......@@ -2,7 +2,7 @@
22//
33// issue: <https://github.com/rust-lang/rust/issues/120217>
44
5#![feature(arbitrary_self_types)]
5#![feature(arbitrary_self_types_pointers)]
66
77trait Static<'a> {
88 fn proof(self: *const Self, s: &'a str) -> &'static str;
tests/ui/check-cfg/well-known-values.stderr+2-2
......@@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
210210LL | target_os = "_UNEXPECTED_VALUE",
211211 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
212212 |
213 = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
213 = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
214214 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
215215
216216warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
......@@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
294294 | |
295295 | help: there is a expected value with a similar name: `"linux"`
296296 |
297 = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
297 = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
298298 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
299299
300300warning: 30 warnings emitted
tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs created+15
......@@ -0,0 +1,15 @@
1trait Foo {
2 fn foo(self: *const Self); //~ ERROR `*const Self` cannot be used as the type of `self`
3}
4
5struct Bar;
6
7impl Foo for Bar {
8 fn foo(self: *const Self) {} //~ ERROR `*const Bar` cannot be used as the type of `self`
9}
10
11impl Bar {
12 fn bar(self: *mut Self) {} //~ ERROR `*mut Bar` cannot be used as the type of `self`
13}
14
15fn main() {}
tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr created+36
......@@ -0,0 +1,36 @@
1error[E0658]: `*const Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
2 --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:8:18
3 |
4LL | fn foo(self: *const Self) {}
5 | ^^^^^^^^^^^
6 |
7 = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
8 = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
9 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10 = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
11
12error[E0658]: `*mut Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
13 --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:12:18
14 |
15LL | fn bar(self: *mut Self) {}
16 | ^^^^^^^^^
17 |
18 = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
19 = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
20 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
21 = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
22
23error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
24 --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:2:18
25 |
26LL | fn foo(self: *const Self);
27 | ^^^^^^^^^^^
28 |
29 = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
30 = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
31 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
32 = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
33
34error: aborting due to 3 previous errors
35
36For more information about this error, try `rustc --explain E0658`.
tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr+6-6
......@@ -1,33 +1,33 @@
1error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types` feature
1error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
22 --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:4:18
33 |
44LL | fn foo(self: *const Self) {}
55 | ^^^^^^^^^^^
66 |
77 = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
8 = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
8 = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
99 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010 = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
1111
12error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature
12error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
1313 --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18
1414 |
1515LL | fn bar(self: *const Self) {}
1616 | ^^^^^^^^^^^
1717 |
1818 = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
19 = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
19 = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
2020 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2121 = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
2222
23error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
23error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
2424 --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18
2525 |
2626LL | fn bar(self: *const Self);
2727 | ^^^^^^^^^^^
2828 |
2929 = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
30 = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
30 = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
3131 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3232 = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
3333
tests/ui/inference/auxiliary/inference_unstable_iterator.rs+1-1
......@@ -1,5 +1,5 @@
11#![feature(staged_api)]
2#![feature(arbitrary_self_types)]
2#![feature(arbitrary_self_types_pointers)]
33
44#![stable(feature = "ipu_iterator", since = "1.0.0")]
55
tests/ui/inference/auxiliary/inference_unstable_itertools.rs+1-1
......@@ -1,4 +1,4 @@
1#![feature(arbitrary_self_types)]
1#![feature(arbitrary_self_types_pointers)]
22
33pub trait IpuItertools {
44 fn ipu_flatten(&self) -> u32 {
tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs+1-1
......@@ -1,5 +1,5 @@
11//@ run-pass
2#![feature(arbitrary_self_types)]
2#![feature(arbitrary_self_types_pointers)]
33
44use std::rc::Rc;
55
tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs+1-1
......@@ -1,5 +1,5 @@
11//@ run-pass
2#![feature(arbitrary_self_types)]
2#![feature(arbitrary_self_types_pointers)]
33
44use std::ptr;
55
tests/ui/stats/hir-stats.rs+3
......@@ -1,12 +1,15 @@
11//@ check-pass
22//@ compile-flags: -Zhir-stats
33//@ only-x86_64
4// layout randomization affects the hir stat output
5//@ needs-deterministic-layouts
46
57// Type layouts sometimes change. When that happens, until the next bootstrap
68// bump occurs, stage1 and stage2 will give different outputs for this test.
79// Add an `ignore-stage1` comment marker to work around that problem during
810// that time.
911
12
1013// The aim here is to include at least one of every different type of top-level
1114// AST/HIR node reported by `-Zhir-stats`.
1215
tests/ui/structs-enums/type-sizes.rs+1
......@@ -1,4 +1,5 @@
11//@ run-pass
2//@ needs-deterministic-layouts
23
34#![allow(non_camel_case_types)]
45#![allow(dead_code)]