| author | bors <bors@rust-lang.org> 2024-09-05 07:41:22 UTC |
| committer | bors <bors@rust-lang.org> 2024-09-05 07:41:22 UTC |
| log | eb33b43bab08223fa6b46abacc1e95e859fe375d |
| tree | 836d22aa6b503323c7b3d5247692f17153101af4 |
| parent | 009e73825af0e59ad4fc603562e038b3dbd6593a |
| parent | 3190521a9865a6ffde047df34716ac1a59aaeb99 |
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: rollup110 files changed, 1675 insertions(+), 410 deletions(-)
Cargo.lock+1| ... | ... | @@ -3569,6 +3569,7 @@ dependencies = [ |
| 3569 | 3569 | "rustc_hir_pretty", |
| 3570 | 3570 | "rustc_hir_typeck", |
| 3571 | 3571 | "rustc_incremental", |
| 3572 | "rustc_index", | |
| 3572 | 3573 | "rustc_infer", |
| 3573 | 3574 | "rustc_interface", |
| 3574 | 3575 | "rustc_lint", |
compiler/rustc/Cargo.toml+1| ... | ... | @@ -30,5 +30,6 @@ features = ['unprefixed_malloc_on_supported_platforms'] |
| 30 | 30 | jemalloc = ['dep:jemalloc-sys'] |
| 31 | 31 | llvm = ['rustc_driver_impl/llvm'] |
| 32 | 32 | max_level_info = ['rustc_driver_impl/max_level_info'] |
| 33 | rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] | |
| 33 | 34 | rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler'] |
| 34 | 35 | # tidy-alphabetical-end |
compiler/rustc_abi/src/layout.rs+7-4| ... | ... | @@ -968,8 +968,8 @@ fn univariant< |
| 968 | 968 | let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; |
| 969 | 969 | let mut max_repr_align = repr.align; |
| 970 | 970 | 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 { | |
| 973 | 973 | let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; |
| 974 | 974 | let optimizing = &mut inverse_memory_index.raw[..end]; |
| 975 | 975 | let fields_excluding_tail = &fields.raw[..end]; |
| ... | ... | @@ -1176,7 +1176,7 @@ fn univariant< |
| 1176 | 1176 | // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0. |
| 1177 | 1177 | // Field 5 would be the first element, so memory_index is i: |
| 1178 | 1178 | // Note: if we didn't optimize, it's already right. |
| 1179 | let memory_index = if optimize { | |
| 1179 | let memory_index = if optimize_field_order { | |
| 1180 | 1180 | inverse_memory_index.invert_bijective_mapping() |
| 1181 | 1181 | } else { |
| 1182 | 1182 | debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices())); |
| ... | ... | @@ -1189,6 +1189,9 @@ fn univariant< |
| 1189 | 1189 | } |
| 1190 | 1190 | let mut layout_of_single_non_zst_field = None; |
| 1191 | 1191 | let mut abi = Abi::Aggregate { sized }; |
| 1192 | ||
| 1193 | let optimize_abi = !repr.inhibit_newtype_abi_optimization(); | |
| 1194 | ||
| 1192 | 1195 | // Try to make this a Scalar/ScalarPair. |
| 1193 | 1196 | if sized && size.bytes() > 0 { |
| 1194 | 1197 | // We skip *all* ZST here and later check if we are good in terms of alignment. |
| ... | ... | @@ -1205,7 +1208,7 @@ fn univariant< |
| 1205 | 1208 | match field.abi { |
| 1206 | 1209 | // For plain scalars, or vectors of them, we can't unpack |
| 1207 | 1210 | // newtypes for `#[repr(C)]`, as that affects C ABIs. |
| 1208 | Abi::Scalar(_) | Abi::Vector { .. } if optimize => { | |
| 1211 | Abi::Scalar(_) | Abi::Vector { .. } if optimize_abi => { | |
| 1209 | 1212 | abi = field.abi; |
| 1210 | 1213 | } |
| 1211 | 1214 | // But scalar pairs are Rust-specific and get |
compiler/rustc_abi/src/lib.rs+11-4| ... | ... | @@ -43,14 +43,17 @@ bitflags! { |
| 43 | 43 | const IS_SIMD = 1 << 1; |
| 44 | 44 | const IS_TRANSPARENT = 1 << 2; |
| 45 | 45 | // Internal only for now. If true, don't reorder fields. |
| 46 | // On its own it does not prevent ABI optimizations. | |
| 46 | 47 | 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`. | |
| 49 | 51 | const RANDOMIZE_LAYOUT = 1 << 4; |
| 50 | 52 | // 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() | |
| 52 | 54 | | ReprFlags::IS_SIMD.bits() |
| 53 | 55 | | ReprFlags::IS_LINEAR.bits(); |
| 56 | const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits(); | |
| 54 | 57 | } |
| 55 | 58 | } |
| 56 | 59 | |
| ... | ... | @@ -139,10 +142,14 @@ impl ReprOptions { |
| 139 | 142 | self.c() || self.int.is_some() |
| 140 | 143 | } |
| 141 | 144 | |
| 145 | pub fn inhibit_newtype_abi_optimization(&self) -> bool { | |
| 146 | self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE) | |
| 147 | } | |
| 148 | ||
| 142 | 149 | /// Returns `true` if this `#[repr()]` guarantees a fixed field order, |
| 143 | 150 | /// e.g. `repr(C)` or `repr(<int>)`. |
| 144 | 151 | 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() | |
| 146 | 153 | } |
| 147 | 154 | |
| 148 | 155 | /// 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" } |
| 23 | 23 | rustc_hir_pretty = { path = "../rustc_hir_pretty" } |
| 24 | 24 | rustc_hir_typeck = { path = "../rustc_hir_typeck" } |
| 25 | 25 | rustc_incremental = { path = "../rustc_incremental" } |
| 26 | rustc_index = { path = "../rustc_index" } | |
| 26 | 27 | rustc_infer = { path = "../rustc_infer" } |
| 27 | 28 | rustc_interface = { path = "../rustc_interface" } |
| 28 | 29 | rustc_lint = { path = "../rustc_lint" } |
| ... | ... | @@ -72,6 +73,10 @@ ctrlc = "3.4.4" |
| 72 | 73 | # tidy-alphabetical-start |
| 73 | 74 | llvm = ['rustc_interface/llvm'] |
| 74 | 75 | max_level_info = ['rustc_log/max_level_info'] |
| 76 | rustc_randomized_layouts = [ | |
| 77 | 'rustc_index/rustc_randomized_layouts', | |
| 78 | 'rustc_middle/rustc_randomized_layouts' | |
| 79 | ] | |
| 75 | 80 | rustc_use_parallel_compiler = [ |
| 76 | 81 | 'rustc_data_structures/rustc_use_parallel_compiler', |
| 77 | 82 | 'rustc_interface/rustc_use_parallel_compiler', |
compiler/rustc_feature/src/unstable.rs+3-1| ... | ... | @@ -349,8 +349,10 @@ declare_features! ( |
| 349 | 349 | (unstable, adt_const_params, "1.56.0", Some(95174)), |
| 350 | 350 | /// Allows defining an `#[alloc_error_handler]`. |
| 351 | 351 | (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. | |
| 353 | 353 | (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)), | |
| 354 | 356 | /// Enables experimental inline assembly support for additional architectures. |
| 355 | 357 | (unstable, asm_experimental_arch, "1.58.0", Some(93335)), |
| 356 | 358 | /// 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>( |
| 1652 | 1652 | } |
| 1653 | 1653 | } |
| 1654 | 1654 | |
| 1655 | /// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`. | |
| 1656 | #[derive(Clone, Copy, PartialEq)] | |
| 1657 | enum ArbitrarySelfTypesLevel { | |
| 1658 | Basic, // just arbitrary_self_types | |
| 1659 | WithPointers, // both arbitrary_self_types and arbitrary_self_types_pointers | |
| 1660 | } | |
| 1661 | ||
| 1655 | 1662 | #[instrument(level = "debug", skip(wfcx))] |
| 1656 | 1663 | fn check_method_receiver<'tcx>( |
| 1657 | 1664 | wfcx: &WfCheckingCtxt<'_, 'tcx>, |
| ... | ... | @@ -1684,14 +1691,27 @@ fn check_method_receiver<'tcx>( |
| 1684 | 1691 | return Ok(()); |
| 1685 | 1692 | } |
| 1686 | 1693 | |
| 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) | |
| 1692 | 1698 | } 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 | { | |
| 1695 | 1715 | // Report error; would have worked with `arbitrary_self_types`. |
| 1696 | 1716 | feature_err( |
| 1697 | 1717 | &tcx.sess, |
| ... | ... | @@ -1699,25 +1719,49 @@ fn check_method_receiver<'tcx>( |
| 1699 | 1719 | span, |
| 1700 | 1720 | format!( |
| 1701 | 1721 | "`{receiver_ty}` cannot be used as the type of `self` without \ |
| 1702 | the `arbitrary_self_types` feature", | |
| 1722 | the `arbitrary_self_types` feature", | |
| 1703 | 1723 | ), |
| 1704 | 1724 | ) |
| 1705 | 1725 | .with_help(fluent::hir_analysis_invalid_receiver_ty_help) |
| 1706 | 1726 | .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 | { | |
| 1709 | 1753 | tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }) |
| 1710 | }); | |
| 1711 | } | |
| 1754 | } | |
| 1755 | }); | |
| 1712 | 1756 | } |
| 1713 | 1757 | Ok(()) |
| 1714 | 1758 | } |
| 1715 | 1759 | |
| 1716 | 1760 | /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If |
| 1717 | 1761 | /// `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>`. | |
| 1721 | 1765 | /// |
| 1722 | 1766 | /// N.B., there are cases this function returns `true` but causes an error to be emitted, |
| 1723 | 1767 | /// 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>( |
| 1727 | 1771 | span: Span, |
| 1728 | 1772 | receiver_ty: Ty<'tcx>, |
| 1729 | 1773 | self_ty: Ty<'tcx>, |
| 1730 | arbitrary_self_types_enabled: bool, | |
| 1774 | arbitrary_self_types_enabled: Option<ArbitrarySelfTypesLevel>, | |
| 1731 | 1775 | ) -> bool { |
| 1732 | 1776 | let infcx = wfcx.infcx; |
| 1733 | 1777 | let tcx = wfcx.tcx(); |
| ... | ... | @@ -1745,8 +1789,8 @@ fn receiver_is_valid<'tcx>( |
| 1745 | 1789 | |
| 1746 | 1790 | let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty); |
| 1747 | 1791 | |
| 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) { | |
| 1750 | 1794 | autoderef = autoderef.include_raw_pointers(); |
| 1751 | 1795 | } |
| 1752 | 1796 | |
| ... | ... | @@ -1772,7 +1816,7 @@ fn receiver_is_valid<'tcx>( |
| 1772 | 1816 | |
| 1773 | 1817 | // Without `feature(arbitrary_self_types)`, we require that each step in the |
| 1774 | 1818 | // deref chain implement `receiver`. |
| 1775 | if !arbitrary_self_types_enabled { | |
| 1819 | if arbitrary_self_types_enabled.is_none() { | |
| 1776 | 1820 | if !receiver_is_implemented( |
| 1777 | 1821 | wfcx, |
| 1778 | 1822 | receiver_trait_def_id, |
compiler/rustc_hir_typeck/src/method/probe.rs+1-1| ... | ... | @@ -403,7 +403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 403 | 403 | mode, |
| 404 | 404 | })); |
| 405 | 405 | } else if bad_ty.reached_raw_pointer |
| 406 | && !self.tcx.features().arbitrary_self_types | |
| 406 | && !self.tcx.features().arbitrary_self_types_pointers | |
| 407 | 407 | && !self.tcx.sess.at_least_rust_2018() |
| 408 | 408 | { |
| 409 | 409 | // this case used to be allowed by the compiler, |
compiler/rustc_index/Cargo.toml+1| ... | ... | @@ -20,4 +20,5 @@ nightly = [ |
| 20 | 20 | "dep:rustc_macros", |
| 21 | 21 | "rustc_index_macros/nightly", |
| 22 | 22 | ] |
| 23 | rustc_randomized_layouts = [] | |
| 23 | 24 | # tidy-alphabetical-end |
compiler/rustc_index/src/lib.rs+11| ... | ... | @@ -33,8 +33,19 @@ pub use vec::IndexVec; |
| 33 | 33 | /// |
| 34 | 34 | /// </div> |
| 35 | 35 | #[macro_export] |
| 36 | #[cfg(not(feature = "rustc_randomized_layouts"))] | |
| 36 | 37 | macro_rules! static_assert_size { |
| 37 | 38 | ($ty:ty, $size:expr) => { |
| 38 | 39 | const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; |
| 39 | 40 | }; |
| 40 | 41 | } |
| 42 | ||
| 43 | #[macro_export] | |
| 44 | #[cfg(feature = "rustc_randomized_layouts")] | |
| 45 | macro_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]); |
| 3706 | 3706 | |
| 3707 | 3707 | declare_lint! { |
| 3708 | 3708 | /// The `missing_abi` lint detects cases where the ABI is omitted from |
| 3709 | /// extern declarations. | |
| 3709 | /// `extern` declarations. | |
| 3710 | 3710 | /// |
| 3711 | 3711 | /// ### Example |
| 3712 | 3712 | /// |
| ... | ... | @@ -3720,10 +3720,12 @@ declare_lint! { |
| 3720 | 3720 | /// |
| 3721 | 3721 | /// ### Explanation |
| 3722 | 3722 | /// |
| 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 | |
| 3727 | 3729 | pub MISSING_ABI, |
| 3728 | 3730 | Allow, |
| 3729 | 3731 | "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, |
| 247 | 247 | explicit_predicates_of => { table } |
| 248 | 248 | generics_of => { table } |
| 249 | 249 | 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 } | |
| 252 | 252 | type_of => { table } |
| 253 | 253 | type_alias_is_lazy => { table_direct } |
| 254 | 254 | variances_of => { table } |
compiler/rustc_metadata/src/rmeta/encoder.rs+4-4| ... | ... | @@ -1443,9 +1443,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { |
| 1443 | 1443 | } |
| 1444 | 1444 | if let DefKind::Trait = def_kind { |
| 1445 | 1445 | 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] <- | |
| 1447 | 1447 | 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] <- | |
| 1449 | 1449 | self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); |
| 1450 | 1450 | |
| 1451 | 1451 | let module_children = self.tcx.module_children_local(local_id); |
| ... | ... | @@ -1454,9 +1454,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { |
| 1454 | 1454 | } |
| 1455 | 1455 | if let DefKind::TraitAlias = def_kind { |
| 1456 | 1456 | 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] <- | |
| 1458 | 1458 | 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] <- | |
| 1460 | 1460 | self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); |
| 1461 | 1461 | } |
| 1462 | 1462 | if let DefKind::Trait | DefKind::Impl { .. } = def_kind { |
compiler/rustc_metadata/src/rmeta/mod.rs+2-4| ... | ... | @@ -390,6 +390,8 @@ define_tables! { |
| 390 | 390 | explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, |
| 391 | 391 | explicit_item_super_predicates: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, |
| 392 | 392 | 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)>>, | |
| 393 | 395 | inherent_impls: Table<DefIndex, LazyArray<DefIndex>>, |
| 394 | 396 | associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>, |
| 395 | 397 | associated_type_for_effects: Table<DefIndex, Option<LazyValue<DefId>>>, |
| ... | ... | @@ -419,10 +421,6 @@ define_tables! { |
| 419 | 421 | lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>, |
| 420 | 422 | explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>, |
| 421 | 423 | 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)>>, | |
| 426 | 424 | type_of: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, Ty<'static>>>>, |
| 427 | 425 | variances_of: Table<DefIndex, LazyArray<ty::Variance>>, |
| 428 | 426 | fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::PolyFnSig<'static>>>>, |
compiler/rustc_middle/Cargo.toml+1| ... | ... | @@ -40,5 +40,6 @@ tracing = "0.1" |
| 40 | 40 | |
| 41 | 41 | [features] |
| 42 | 42 | # tidy-alphabetical-start |
| 43 | rustc_randomized_layouts = [] | |
| 43 | 44 | rustc_use_parallel_compiler = ["dep:rustc-rayon-core"] |
| 44 | 45 | # tidy-alphabetical-end |
compiler/rustc_middle/src/query/plumbing.rs+1| ... | ... | @@ -337,6 +337,7 @@ macro_rules! define_callbacks { |
| 337 | 337 | // Ensure that values grow no larger than 64 bytes by accident. |
| 338 | 338 | // Increase this limit if necessary, but do try to keep the size low if possible |
| 339 | 339 | #[cfg(target_pointer_width = "64")] |
| 340 | #[cfg(not(feature = "rustc_randomized_layouts"))] | |
| 340 | 341 | const _: () = { |
| 341 | 342 | if mem::size_of::<Value<'static>>() > 64 { |
| 342 | 343 | panic!("{}", concat!( |
compiler/rustc_middle/src/ty/mod.rs+9-1| ... | ... | @@ -35,6 +35,7 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr; |
| 35 | 35 | use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; |
| 36 | 36 | use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; |
| 37 | 37 | use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; |
| 38 | use rustc_hir::LangItem; | |
| 38 | 39 | use rustc_index::IndexVec; |
| 39 | 40 | use rustc_macros::{ |
| 40 | 41 | extension, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, |
| ... | ... | @@ -1570,8 +1571,15 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1570 | 1571 | flags.insert(ReprFlags::RANDOMIZE_LAYOUT); |
| 1571 | 1572 | } |
| 1572 | 1573 | |
| 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 | ||
| 1573 | 1578 | // 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 | { | |
| 1575 | 1583 | flags.insert(ReprFlags::IS_LINEAR); |
| 1576 | 1584 | } |
| 1577 | 1585 |
compiler/rustc_span/src/symbol.rs+1| ... | ... | @@ -407,6 +407,7 @@ symbols! { |
| 407 | 407 | append_const_msg, |
| 408 | 408 | arbitrary_enum_discriminant, |
| 409 | 409 | arbitrary_self_types, |
| 410 | arbitrary_self_types_pointers, | |
| 410 | 411 | args, |
| 411 | 412 | arith_offset, |
| 412 | 413 | arm, |
compiler/rustc_target/src/spec/mod.rs+2| ... | ... | @@ -1695,6 +1695,8 @@ supported_targets! { |
| 1695 | 1695 | ("armv7r-none-eabihf", armv7r_none_eabihf), |
| 1696 | 1696 | ("armv8r-none-eabihf", armv8r_none_eabihf), |
| 1697 | 1697 | |
| 1698 | ("armv7-rtems-eabihf", armv7_rtems_eabihf), | |
| 1699 | ||
| 1698 | 1700 | ("x86_64-pc-solaris", x86_64_pc_solaris), |
| 1699 | 1701 | ("sparcv9-sun-solaris", sparcv9_sun_solaris), |
| 1700 | 1702 |
compiler/rustc_target/src/spec/targets/armv7_rtems_eabihf.rs created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; | |
| 2 | ||
| 3 | pub(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 @@ |
| 519 | 519 | # are disabled statically" because `max_level_info` is enabled, set this value to `true`. |
| 520 | 520 | #debug-logging = rust.debug-assertions (boolean) |
| 521 | 521 | |
| 522 | # Whether or not to build rustc, tools and the libraries with randomized type layout | |
| 523 | #randomize-layout = false | |
| 524 | ||
| 522 | 525 | # Whether or not overflow checks are enabled for the compiler and standard |
| 523 | 526 | # library. |
| 524 | 527 | # |
library/alloc/Cargo.toml+1| ... | ... | @@ -52,4 +52,5 @@ check-cfg = [ |
| 52 | 52 | 'cfg(no_global_oom_handling)', |
| 53 | 53 | 'cfg(no_rc)', |
| 54 | 54 | 'cfg(no_sync)', |
| 55 | 'cfg(randomized_layouts)', | |
| 55 | 56 | ] |
library/alloc/src/collections/btree/node/tests.rs+1-1| ... | ... | @@ -90,7 +90,7 @@ fn test_partial_eq() { |
| 90 | 90 | |
| 91 | 91 | #[test] |
| 92 | 92 | #[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 | |
| 94 | 94 | fn test_sizes() { |
| 95 | 95 | assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16); |
| 96 | 96 | assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8); |
library/core/Cargo.toml+2| ... | ... | @@ -43,6 +43,8 @@ check-cfg = [ |
| 43 | 43 | 'cfg(bootstrap)', |
| 44 | 44 | 'cfg(no_fp_fmt_parse)', |
| 45 | 45 | 'cfg(stdarch_intel_sde)', |
| 46 | # #[cfg(bootstrap)] rtems | |
| 47 | 'cfg(target_os, values("rtems"))', | |
| 46 | 48 | # core use #[path] imports to portable-simd `core_simd` crate |
| 47 | 49 | # and to stdarch `core_arch` crate which messes-up with Cargo list |
| 48 | 50 | # 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 { |
| 110 | 110 | all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")), |
| 111 | 111 | all(target_os = "l4re", target_arch = "x86_64"), |
| 112 | 112 | all( |
| 113 | any(target_os = "freebsd", target_os = "openbsd"), | |
| 113 | any(target_os = "freebsd", target_os = "openbsd", target_os = "rtems"), | |
| 114 | 114 | any( |
| 115 | 115 | target_arch = "aarch64", |
| 116 | 116 | target_arch = "arm", |
library/core/src/task/wake.rs+79-24| ... | ... | @@ -60,22 +60,6 @@ impl RawWaker { |
| 60 | 60 | RawWaker { data, vtable } |
| 61 | 61 | } |
| 62 | 62 | |
| 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 | ||
| 79 | 63 | #[unstable(feature = "noop_waker", issue = "98286")] |
| 80 | 64 | const NOOP: RawWaker = { |
| 81 | 65 | const VTABLE: RawWakerVTable = RawWakerVTable::new( |
| ... | ... | @@ -509,6 +493,37 @@ impl Waker { |
| 509 | 493 | a_data == b_data && ptr::eq(a_vtable, b_vtable) |
| 510 | 494 | } |
| 511 | 495 | |
| 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 | ||
| 512 | 527 | /// Creates a new `Waker` from [`RawWaker`]. |
| 513 | 528 | /// |
| 514 | 529 | /// # Safety |
| ... | ... | @@ -565,12 +580,20 @@ impl Waker { |
| 565 | 580 | WAKER |
| 566 | 581 | } |
| 567 | 582 | |
| 568 | /// Gets a reference to the underlying [`RawWaker`]. | |
| 583 | /// Gets the `data` pointer used to create this `Waker`. | |
| 569 | 584 | #[inline] |
| 570 | 585 | #[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 | |
| 574 | 597 | } |
| 575 | 598 | } |
| 576 | 599 | |
| ... | ... | @@ -778,6 +801,30 @@ impl LocalWaker { |
| 778 | 801 | a_data == b_data && ptr::eq(a_vtable, b_vtable) |
| 779 | 802 | } |
| 780 | 803 | |
| 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 | ||
| 781 | 828 | /// Creates a new `LocalWaker` from [`RawWaker`]. |
| 782 | 829 | /// |
| 783 | 830 | /// The behavior of the returned `LocalWaker` is undefined if the contract defined |
| ... | ... | @@ -831,12 +878,20 @@ impl LocalWaker { |
| 831 | 878 | WAKER |
| 832 | 879 | } |
| 833 | 880 | |
| 834 | /// Gets a reference to the underlying [`RawWaker`]. | |
| 881 | /// Gets the `data` pointer used to create this `LocalWaker`. | |
| 835 | 882 | #[inline] |
| 836 | 883 | #[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 | |
| 840 | 895 | } |
| 841 | 896 | } |
| 842 | 897 | #[unstable(feature = "local_waker", issue = "118959")] |
library/core/tests/lib.rs-1| ... | ... | @@ -112,7 +112,6 @@ |
| 112 | 112 | #![feature(unsize)] |
| 113 | 113 | #![feature(unsized_tuple_coercion)] |
| 114 | 114 | #![feature(unwrap_infallible)] |
| 115 | #![feature(waker_getters)] | |
| 116 | 115 | // tidy-alphabetical-end |
| 117 | 116 | #![allow(internal_features)] |
| 118 | 117 | #![deny(fuzzy_provenance_casts)] |
library/core/tests/waker.rs+5-6| ... | ... | @@ -4,14 +4,13 @@ use std::task::{RawWaker, RawWakerVTable, Waker}; |
| 4 | 4 | #[test] |
| 5 | 5 | fn test_waker_getters() { |
| 6 | 6 | 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 | ||
| 10 | 7 | 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 | ||
| 11 | 11 | 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)); | |
| 15 | 14 | } |
| 16 | 15 | |
| 17 | 16 | static 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'] } |
| 20 | 20 | |
| 21 | 21 | [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] |
| 22 | 22 | libc = { version = "0.2", default-features = false } |
| 23 | ||
| 24 | [lints.rust.unexpected_cfgs] | |
| 25 | level = "warn" | |
| 26 | check-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! { |
| 48 | 48 | target_os = "psp", |
| 49 | 49 | target_os = "xous", |
| 50 | 50 | 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"))), | |
| 52 | 52 | all(target_vendor = "fortanix", target_env = "sgx"), |
| 53 | 53 | target_family = "wasm", |
| 54 | 54 | ))] { |
library/std/Cargo.toml+2| ... | ... | @@ -146,4 +146,6 @@ check-cfg = [ |
| 146 | 146 | # and to the `backtrace` crate which messes-up with Cargo list |
| 147 | 147 | # of declared features, we therefor expect any feature cfg |
| 148 | 148 | 'cfg(feature, values(any()))', |
| 149 | # #[cfg(bootstrap)] rtems | |
| 150 | 'cfg(target_os, values("rtems"))', | |
| 149 | 151 | ] |
library/std/build.rs+1| ... | ... | @@ -53,6 +53,7 @@ fn main() { |
| 53 | 53 | || target_os == "uefi" |
| 54 | 54 | || target_os == "teeos" |
| 55 | 55 | || target_os == "zkvm" |
| 56 | || target_os == "rtems" | |
| 56 | 57 | |
| 57 | 58 | // See src/bootstrap/src/core/build_steps/synthetic_targets.rs |
| 58 | 59 | || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok() |
library/std/src/os/mod.rs+2| ... | ... | @@ -143,6 +143,8 @@ pub mod nto; |
| 143 | 143 | pub mod openbsd; |
| 144 | 144 | #[cfg(target_os = "redox")] |
| 145 | 145 | pub mod redox; |
| 146 | #[cfg(target_os = "rtems")] | |
| 147 | pub mod rtems; | |
| 146 | 148 | #[cfg(target_os = "solaris")] |
| 147 | 149 | pub mod solaris; |
| 148 | 150 | #[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 | ||
| 3 | use crate::fs::Metadata; | |
| 4 | use 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")] | |
| 10 | pub 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")] | |
| 310 | impl 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)] | |
| 3 | pub mod fs; | |
| 4 | pub(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")] | |
| 14 | pub type pthread_t = libc::pthread_t; | |
| 15 | ||
| 16 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 17 | pub type blkcnt_t = libc::blkcnt_t; | |
| 18 | ||
| 19 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 20 | pub type blksize_t = libc::blksize_t; | |
| 21 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 22 | pub type dev_t = libc::dev_t; | |
| 23 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 24 | pub type ino_t = libc::ino_t; | |
| 25 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 26 | pub type mode_t = libc::mode_t; | |
| 27 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 28 | pub type nlink_t = libc::nlink_t; | |
| 29 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 30 | pub type off_t = libc::off_t; | |
| 31 | ||
| 32 | #[stable(feature = "raw_ext", since = "1.1.0")] | |
| 33 | pub type time_t = libc::time_t; |
library/std/src/os/unix/mod.rs+2| ... | ... | @@ -73,6 +73,8 @@ mod platform { |
| 73 | 73 | pub use crate::os::openbsd::*; |
| 74 | 74 | #[cfg(target_os = "redox")] |
| 75 | 75 | pub use crate::os::redox::*; |
| 76 | #[cfg(target_os = "rtems")] | |
| 77 | pub use crate::os::rtems::*; | |
| 76 | 78 | #[cfg(target_os = "solaris")] |
| 77 | 79 | pub use crate::os::solaris::*; |
| 78 | 80 | #[cfg(target_os = "vita")] |
library/std/src/sys/pal/unix/args.rs+1| ... | ... | @@ -112,6 +112,7 @@ impl DoubleEndedIterator for Args { |
| 112 | 112 | target_os = "aix", |
| 113 | 113 | target_os = "nto", |
| 114 | 114 | target_os = "hurd", |
| 115 | target_os = "rtems", | |
| 115 | 116 | ))] |
| 116 | 117 | mod imp { |
| 117 | 118 | use crate::ffi::c_char; |
library/std/src/sys/pal/unix/env.rs+11| ... | ... | @@ -240,6 +240,17 @@ pub mod os { |
| 240 | 240 | pub const EXE_EXTENSION: &str = ""; |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | #[cfg(target_os = "rtems")] | |
| 244 | pub 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 | ||
| 243 | 254 | #[cfg(target_os = "vxworks")] |
| 244 | 255 | pub mod os { |
| 245 | 256 | pub const FAMILY: &str = "unix"; |
library/std/src/sys/pal/unix/fs.rs+16-2| ... | ... | @@ -478,6 +478,7 @@ impl FileAttr { |
| 478 | 478 | target_os = "horizon", |
| 479 | 479 | target_os = "vita", |
| 480 | 480 | target_os = "hurd", |
| 481 | target_os = "rtems", | |
| 481 | 482 | )))] |
| 482 | 483 | pub fn modified(&self) -> io::Result<SystemTime> { |
| 483 | 484 | #[cfg(target_pointer_width = "32")] |
| ... | ... | @@ -490,7 +491,12 @@ impl FileAttr { |
| 490 | 491 | SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtime_nsec as i64) |
| 491 | 492 | } |
| 492 | 493 | |
| 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 | ))] | |
| 494 | 500 | pub fn modified(&self) -> io::Result<SystemTime> { |
| 495 | 501 | SystemTime::new(self.stat.st_mtime as i64, 0) |
| 496 | 502 | } |
| ... | ... | @@ -506,6 +512,7 @@ impl FileAttr { |
| 506 | 512 | target_os = "horizon", |
| 507 | 513 | target_os = "vita", |
| 508 | 514 | target_os = "hurd", |
| 515 | target_os = "rtems", | |
| 509 | 516 | )))] |
| 510 | 517 | pub fn accessed(&self) -> io::Result<SystemTime> { |
| 511 | 518 | #[cfg(target_pointer_width = "32")] |
| ... | ... | @@ -518,7 +525,12 @@ impl FileAttr { |
| 518 | 525 | SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64) |
| 519 | 526 | } |
| 520 | 527 | |
| 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 | ))] | |
| 522 | 534 | pub fn accessed(&self) -> io::Result<SystemTime> { |
| 523 | 535 | SystemTime::new(self.stat.st_atime as i64, 0) |
| 524 | 536 | } |
| ... | ... | @@ -853,6 +865,7 @@ impl Drop for Dir { |
| 853 | 865 | target_os = "fuchsia", |
| 854 | 866 | target_os = "horizon", |
| 855 | 867 | target_os = "vxworks", |
| 868 | target_os = "rtems", | |
| 856 | 869 | )))] |
| 857 | 870 | { |
| 858 | 871 | let fd = unsafe { libc::dirfd(self.0) }; |
| ... | ... | @@ -970,6 +983,7 @@ impl DirEntry { |
| 970 | 983 | target_os = "aix", |
| 971 | 984 | target_os = "nto", |
| 972 | 985 | target_os = "hurd", |
| 986 | target_os = "rtems", | |
| 973 | 987 | target_vendor = "apple", |
| 974 | 988 | ))] |
| 975 | 989 | 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) { |
| 79 | 79 | target_os = "l4re", |
| 80 | 80 | target_os = "horizon", |
| 81 | 81 | target_os = "vita", |
| 82 | target_os = "rtems", | |
| 82 | 83 | // The poll on Darwin doesn't set POLLNVAL for closed fds. |
| 83 | 84 | target_vendor = "apple", |
| 84 | 85 | )))] |
library/std/src/sys/pal/unix/os.rs+15-4| ... | ... | @@ -31,7 +31,7 @@ cfg_if::cfg_if! { |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | extern "C" { |
| 34 | #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))] | |
| 34 | #[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))] | |
| 35 | 35 | #[cfg_attr( |
| 36 | 36 | any( |
| 37 | 37 | target_os = "linux", |
| ... | ... | @@ -61,13 +61,14 @@ extern "C" { |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | /// 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")))] | |
| 65 | 65 | pub fn errno() -> i32 { |
| 66 | 66 | unsafe { (*errno_location()) as i32 } |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | /// 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")))] | |
| 71 | 72 | #[allow(dead_code)] // but not all target cfgs actually end up using it |
| 72 | 73 | pub fn set_errno(e: i32) { |
| 73 | 74 | unsafe { *errno_location() = e as c_int } |
| ... | ... | @@ -78,6 +79,16 @@ pub fn errno() -> i32 { |
| 78 | 79 | unsafe { libc::errnoGet() } |
| 79 | 80 | } |
| 80 | 81 | |
| 82 | #[cfg(target_os = "rtems")] | |
| 83 | pub 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 | ||
| 81 | 92 | #[cfg(target_os = "dragonfly")] |
| 82 | 93 | pub fn errno() -> i32 { |
| 83 | 94 | extern "C" { |
| ... | ... | @@ -472,7 +483,7 @@ pub fn current_exe() -> io::Result<PathBuf> { |
| 472 | 483 | } |
| 473 | 484 | } |
| 474 | 485 | |
| 475 | #[cfg(target_os = "redox")] | |
| 486 | #[cfg(any(target_os = "redox", target_os = "rtems"))] | |
| 476 | 487 | pub fn current_exe() -> io::Result<PathBuf> { |
| 477 | 488 | crate::fs::read_to_string("sys:exe").map(PathBuf::from) |
| 478 | 489 | } |
library/std/src/sys/pal/unix/process/process_unix.rs+3-3| ... | ... | @@ -1089,13 +1089,13 @@ fn signal_string(signal: i32) -> &'static str { |
| 1089 | 1089 | libc::SIGURG => " (SIGURG)", |
| 1090 | 1090 | #[cfg(not(target_os = "l4re"))] |
| 1091 | 1091 | libc::SIGXCPU => " (SIGXCPU)", |
| 1092 | #[cfg(not(target_os = "l4re"))] | |
| 1092 | #[cfg(not(any(target_os = "l4re", target_os = "rtems")))] | |
| 1093 | 1093 | libc::SIGXFSZ => " (SIGXFSZ)", |
| 1094 | #[cfg(not(target_os = "l4re"))] | |
| 1094 | #[cfg(not(any(target_os = "l4re", target_os = "rtems")))] | |
| 1095 | 1095 | libc::SIGVTALRM => " (SIGVTALRM)", |
| 1096 | 1096 | #[cfg(not(target_os = "l4re"))] |
| 1097 | 1097 | libc::SIGPROF => " (SIGPROF)", |
| 1098 | #[cfg(not(target_os = "l4re"))] | |
| 1098 | #[cfg(not(any(target_os = "l4re", target_os = "rtems")))] | |
| 1099 | 1099 | libc::SIGWINCH => " (SIGWINCH)", |
| 1100 | 1100 | #[cfg(not(any(target_os = "haiku", target_os = "l4re")))] |
| 1101 | 1101 | libc::SIGIO => " (SIGIO)", |
library/std/src/sys/personality/mod.rs+1-1| ... | ... | @@ -31,7 +31,7 @@ cfg_if::cfg_if! { |
| 31 | 31 | target_os = "psp", |
| 32 | 32 | target_os = "xous", |
| 33 | 33 | 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")), | |
| 35 | 35 | all(target_vendor = "fortanix", target_env = "sgx"), |
| 36 | 36 | ))] { |
| 37 | 37 | mod gcc; |
library/unwind/Cargo.toml+7| ... | ... | @@ -34,3 +34,10 @@ llvm-libunwind = [] |
| 34 | 34 | # If crt-static is enabled, static link to `libunwind.a` provided by system |
| 35 | 35 | # If crt-static is disabled, dynamic link to `libunwind.so` provided by system |
| 36 | 36 | system-llvm-libunwind = [] |
| 37 | ||
| 38 | [lints.rust.unexpected_cfgs] | |
| 39 | level = "warn" | |
| 40 | check-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! { |
| 22 | 22 | target_os = "l4re", |
| 23 | 23 | target_os = "none", |
| 24 | 24 | target_os = "espidf", |
| 25 | target_os = "rtems", | |
| 25 | 26 | ))] { |
| 26 | 27 | // These "unix" family members do not have unwinder. |
| 27 | 28 | } 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 |
| 93 | 93 | if !verify_rustfmt_version(build) { |
| 94 | 94 | return Ok(None); |
| 95 | 95 | } |
| 96 | ||
| 97 | 96 | get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"]) |
| 98 | 97 | } |
| 99 | 98 |
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 |
| 1810 | 1810 | if builder.config.rust_optimize_tests { |
| 1811 | 1811 | cmd.arg("--optimize-tests"); |
| 1812 | 1812 | } |
| 1813 | if builder.config.rust_randomize_layout { | |
| 1814 | cmd.arg("--rust-randomized-layout"); | |
| 1815 | } | |
| 1813 | 1816 | if builder.config.cmd.only_modified() { |
| 1814 | 1817 | cmd.arg("--only-modified"); |
| 1815 | 1818 | } |
src/bootstrap/src/core/builder.rs+12| ... | ... | @@ -1618,6 +1618,15 @@ impl<'a> Builder<'a> { |
| 1618 | 1618 | rustflags.arg("-Csymbol-mangling-version=legacy"); |
| 1619 | 1619 | } |
| 1620 | 1620 | |
| 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 | ||
| 1621 | 1630 | // Enable compile-time checking of `cfg` names, values and Cargo `features`. |
| 1622 | 1631 | // |
| 1623 | 1632 | // Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like |
| ... | ... | @@ -2193,6 +2202,9 @@ impl<'a> Builder<'a> { |
| 2193 | 2202 | rustflags.arg("-Zvalidate-mir"); |
| 2194 | 2203 | rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}")); |
| 2195 | 2204 | } |
| 2205 | if self.config.rust_randomize_layout { | |
| 2206 | rustflags.arg("--cfg=randomized_layouts"); | |
| 2207 | } | |
| 2196 | 2208 | // Always enable inlining MIR when building the standard library. |
| 2197 | 2209 | // Without this flag, MIR inlining is disabled when incremental compilation is enabled. |
| 2198 | 2210 | // 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 { |
| 268 | 268 | pub rust_debuginfo_level_std: DebuginfoLevel, |
| 269 | 269 | pub rust_debuginfo_level_tools: DebuginfoLevel, |
| 270 | 270 | pub rust_debuginfo_level_tests: DebuginfoLevel, |
| 271 | pub rust_split_debuginfo_for_build_triple: Option<SplitDebuginfo>, // FIXME: Deprecated field. Remove in Q3'24. | |
| 272 | 271 | pub rust_rpath: bool, |
| 273 | 272 | pub rust_strip: bool, |
| 274 | 273 | pub rust_frame_pointers: bool, |
| ... | ... | @@ -280,6 +279,7 @@ pub struct Config { |
| 280 | 279 | pub rust_codegen_backends: Vec<String>, |
| 281 | 280 | pub rust_verify_llvm_ir: bool, |
| 282 | 281 | pub rust_thin_lto_import_instr_limit: Option<u32>, |
| 282 | pub rust_randomize_layout: bool, | |
| 283 | 283 | pub rust_remap_debuginfo: bool, |
| 284 | 284 | pub rust_new_symbol_mangling: Option<bool>, |
| 285 | 285 | pub rust_profile_use: Option<String>, |
| ... | ... | @@ -1090,6 +1090,7 @@ define_config! { |
| 1090 | 1090 | codegen_units: Option<u32> = "codegen-units", |
| 1091 | 1091 | codegen_units_std: Option<u32> = "codegen-units-std", |
| 1092 | 1092 | debug_assertions: Option<bool> = "debug-assertions", |
| 1093 | randomize_layout: Option<bool> = "randomize-layout", | |
| 1093 | 1094 | debug_assertions_std: Option<bool> = "debug-assertions-std", |
| 1094 | 1095 | overflow_checks: Option<bool> = "overflow-checks", |
| 1095 | 1096 | overflow_checks_std: Option<bool> = "overflow-checks-std", |
| ... | ... | @@ -1099,7 +1100,6 @@ define_config! { |
| 1099 | 1100 | debuginfo_level_std: Option<DebuginfoLevel> = "debuginfo-level-std", |
| 1100 | 1101 | debuginfo_level_tools: Option<DebuginfoLevel> = "debuginfo-level-tools", |
| 1101 | 1102 | debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests", |
| 1102 | split_debuginfo: Option<String> = "split-debuginfo", | |
| 1103 | 1103 | backtrace: Option<bool> = "backtrace", |
| 1104 | 1104 | incremental: Option<bool> = "incremental", |
| 1105 | 1105 | parallel_compiler: Option<bool> = "parallel-compiler", |
| ... | ... | @@ -1181,6 +1181,7 @@ impl Config { |
| 1181 | 1181 | backtrace: true, |
| 1182 | 1182 | rust_optimize: RustOptimize::Bool(true), |
| 1183 | 1183 | rust_optimize_tests: true, |
| 1184 | rust_randomize_layout: false, | |
| 1184 | 1185 | submodules: None, |
| 1185 | 1186 | docs: true, |
| 1186 | 1187 | docs_minification: true, |
| ... | ... | @@ -1636,10 +1637,10 @@ impl Config { |
| 1636 | 1637 | debuginfo_level_std: debuginfo_level_std_toml, |
| 1637 | 1638 | debuginfo_level_tools: debuginfo_level_tools_toml, |
| 1638 | 1639 | debuginfo_level_tests: debuginfo_level_tests_toml, |
| 1639 | split_debuginfo, | |
| 1640 | 1640 | backtrace, |
| 1641 | 1641 | incremental, |
| 1642 | 1642 | parallel_compiler, |
| 1643 | randomize_layout, | |
| 1643 | 1644 | default_linker, |
| 1644 | 1645 | channel, |
| 1645 | 1646 | description, |
| ... | ... | @@ -1695,18 +1696,6 @@ impl Config { |
| 1695 | 1696 | debuginfo_level_tests = debuginfo_level_tests_toml; |
| 1696 | 1697 | lld_enabled = lld_enabled_toml; |
| 1697 | 1698 | |
| 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 | ||
| 1710 | 1699 | optimize = optimize_toml; |
| 1711 | 1700 | omit_git_hash = omit_git_hash_toml; |
| 1712 | 1701 | config.rust_new_symbol_mangling = new_symbol_mangling; |
| ... | ... | @@ -1729,6 +1718,7 @@ impl Config { |
| 1729 | 1718 | set(&mut config.lld_mode, lld_mode); |
| 1730 | 1719 | set(&mut config.llvm_bitcode_linker_enabled, llvm_bitcode_linker); |
| 1731 | 1720 | |
| 1721 | config.rust_randomize_layout = randomize_layout.unwrap_or_default(); | |
| 1732 | 1722 | config.llvm_tools_enabled = llvm_tools.unwrap_or(true); |
| 1733 | 1723 | config.rustc_parallel = |
| 1734 | 1724 | parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly"); |
| ... | ... | @@ -2504,9 +2494,6 @@ impl Config { |
| 2504 | 2494 | self.target_config |
| 2505 | 2495 | .get(&target) |
| 2506 | 2496 | .and_then(|t| t.split_debuginfo) |
| 2507 | .or_else(|| { | |
| 2508 | if self.build == target { self.rust_split_debuginfo_for_build_triple } else { None } | |
| 2509 | }) | |
| 2510 | 2497 | .unwrap_or_else(|| SplitDebuginfo::default_for_platform(target)) |
| 2511 | 2498 | } |
| 2512 | 2499 | |
| ... | ... | @@ -2900,6 +2887,7 @@ fn check_incompatible_options_for_ci_rustc( |
| 2900 | 2887 | let Rust { |
| 2901 | 2888 | // Following options are the CI rustc incompatible ones. |
| 2902 | 2889 | optimize, |
| 2890 | randomize_layout, | |
| 2903 | 2891 | debug_logging, |
| 2904 | 2892 | debuginfo_level_rustc, |
| 2905 | 2893 | llvm_tools, |
| ... | ... | @@ -2927,7 +2915,6 @@ fn check_incompatible_options_for_ci_rustc( |
| 2927 | 2915 | debuginfo_level_std: _, |
| 2928 | 2916 | debuginfo_level_tools: _, |
| 2929 | 2917 | debuginfo_level_tests: _, |
| 2930 | split_debuginfo: _, | |
| 2931 | 2918 | backtrace: _, |
| 2932 | 2919 | parallel_compiler: _, |
| 2933 | 2920 | musl_root: _, |
| ... | ... | @@ -2964,6 +2951,7 @@ fn check_incompatible_options_for_ci_rustc( |
| 2964 | 2951 | // otherwise, we just print a warning with `warn` macro. |
| 2965 | 2952 | |
| 2966 | 2953 | err!(current_rust_config.optimize, optimize); |
| 2954 | err!(current_rust_config.randomize_layout, randomize_layout); | |
| 2967 | 2955 | err!(current_rust_config.debug_logging, debug_logging); |
| 2968 | 2956 | err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc); |
| 2969 | 2957 | err!(current_rust_config.rpath, rpath); |
src/bootstrap/src/core/sanity.rs+13| ... | ... | @@ -13,6 +13,8 @@ use std::ffi::{OsStr, OsString}; |
| 13 | 13 | use std::path::PathBuf; |
| 14 | 14 | use std::{env, fs}; |
| 15 | 15 | |
| 16 | use build_helper::git::warn_old_master_branch; | |
| 17 | ||
| 16 | 18 | #[cfg(not(feature = "bootstrap-self-test"))] |
| 17 | 19 | use crate::builder::Builder; |
| 18 | 20 | use crate::builder::Kind; |
| ... | ... | @@ -34,6 +36,7 @@ pub struct Finder { |
| 34 | 36 | // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). |
| 35 | 37 | const STAGE0_MISSING_TARGETS: &[&str] = &[ |
| 36 | 38 | // just a dummy comment so the list doesn't get onelined |
| 39 | "armv7-rtems-eabihf", | |
| 37 | 40 | ]; |
| 38 | 41 | |
| 39 | 42 | /// Minimum version threshold for libstdc++ required when using prebuilt LLVM |
| ... | ... | @@ -374,4 +377,14 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake |
| 374 | 377 | if let Some(ref s) = build.config.ccache { |
| 375 | 378 | cmd_finder.must_have(s); |
| 376 | 379 | } |
| 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 | } | |
| 377 | 390 | } |
src/bootstrap/src/lib.rs+3| ... | ... | @@ -678,6 +678,9 @@ impl Build { |
| 678 | 678 | if self.config.rustc_parallel { |
| 679 | 679 | features.push("rustc_use_parallel_compiler"); |
| 680 | 680 | } |
| 681 | if self.config.rust_randomize_layout { | |
| 682 | features.push("rustc_randomized_layouts"); | |
| 683 | } | |
| 681 | 684 | |
| 682 | 685 | // If debug logging is on, then we want the default for tracing: |
| 683 | 686 | // 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] = &[ |
| 240 | 240 | severity: ChangeSeverity::Info, |
| 241 | 241 | summary: "New option `build.cargo-clippy` added for supporting the use of custom/external clippy.", |
| 242 | 242 | }, |
| 243 | ChangeInfo { | |
| 244 | change_id: 129925, | |
| 245 | severity: ChangeSeverity::Warning, | |
| 246 | summary: "Removed `rust.split-debuginfo` as it was deprecated long time ago.", | |
| 247 | }, | |
| 243 | 248 | ]; |
src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile+1| ... | ... | @@ -50,6 +50,7 @@ ENV RUST_CONFIGURE_ARGS \ |
| 50 | 50 | --build=x86_64-unknown-linux-gnu \ |
| 51 | 51 | --llvm-root=/usr/lib/llvm-17 \ |
| 52 | 52 | --enable-llvm-link-shared \ |
| 53 | --set rust.randomize-layout=true \ | |
| 53 | 54 | --set rust.thin-lto-import-instr-limit=10 |
| 54 | 55 | |
| 55 | 56 | COPY 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 |
| 4 | 4 | |
| 5 | 5 | LINUX_VERSION=4c7864e81d8bbd51036dacf92fb0a400e13aaeee |
| 6 | 6 | |
| 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 | |
| 9 | 9 | ../x.py build --stage 0 cargo |
| 10 | 10 | |
| 11 | 11 | # Install rustup so that we can use the built toolchain easily, and also |
| ... | ... | @@ -16,7 +16,7 @@ sh rustup.sh -y --default-toolchain none |
| 16 | 16 | source /cargo/env |
| 17 | 17 | |
| 18 | 18 | BUILD_DIR=$(realpath ./build) |
| 19 | rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage1 | |
| 19 | rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2 | |
| 20 | 20 | rustup default local |
| 21 | 21 | |
| 22 | 22 | mkdir -p rfl |
| ... | ... | @@ -62,11 +62,47 @@ make -C linux LLVM=1 -j$(($(nproc) + 1)) \ |
| 62 | 62 | defconfig \ |
| 63 | 63 | rfl-for-rust-ci.config |
| 64 | 64 | |
| 65 | make -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 \ | |
| 65 | BUILD_TARGETS=" | |
| 66 | samples/rust/rust_minimal.o | |
| 67 | samples/rust/rust_print.o | |
| 68 | drivers/net/phy/ax88796b_rust.o | |
| 69 | 69 | 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`). | |
| 80 | make -C linux LLVM=1 -j$(($(nproc) + 1)) \ | |
| 81 | $BUILD_TARGETS | |
| 70 | 82 | |
| 83 | # Generate documentation | |
| 71 | 84 | make -C linux LLVM=1 -j$(($(nproc) + 1)) \ |
| 72 | 85 | 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. | |
| 92 | make -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. | |
| 100 | make -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. | |
| 107 | make -C linux LLVM=1 -j$(($(nproc) + 1)) \ | |
| 108 | rustfmt |
src/doc/not_found.md+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | <!-- Completely hide the TOC and the section numbers --> |
| 4 | 4 | <style type="text/css"> |
| 5 | #TOC { display: none; } | |
| 5 | #rustdoc-toc { display: none; } | |
| 6 | 6 | .header-section-number { display: none; } |
| 7 | 7 | li {list-style-type: none; } |
| 8 | 8 | #search-input { |
src/doc/rustc/src/SUMMARY.md+1| ... | ... | @@ -40,6 +40,7 @@ |
| 40 | 40 | - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) |
| 41 | 41 | - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) |
| 42 | 42 | - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) |
| 43 | - [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md) | |
| 43 | 44 | - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) |
| 44 | 45 | - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) |
| 45 | 46 | - [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 |
| 280 | 280 | `armv6-unknown-freebsd` | ✓ | ✓ | Armv6 FreeBSD |
| 281 | 281 | [`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv6 NetBSD w/hard-float |
| 282 | 282 | [`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 | |
| 283 | 284 | [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) |
| 284 | 285 | [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat |
| 285 | 286 | [`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 | ||
| 5 | ARM 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 | ||
| 13 | The target does not support host tools. Only cross-compilation is possible. | |
| 14 | The cross-compiler toolchain can be obtained by following the installation instructions | |
| 15 | of the [RTEMS Documentation](https://docs.rtems.org/branches/master/user/index.html). Additionally to the cross-compiler also a compiled BSP | |
| 16 | for a board fitting the architecture needs to be available on the host. | |
| 17 | Currently 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 | ||
| 21 | The target follows the EABI calling convention for `extern "C"`. | |
| 22 | ||
| 23 | The resulting binaries are in ELF format. | |
| 24 | ||
| 25 | ## Building the target | |
| 26 | ||
| 27 | The target can be built by the standard compiler of Rust. | |
| 28 | ||
| 29 | ## Building Rust programs | |
| 30 | ||
| 31 | Rust does not yet ship pre-compiled artifacts for this target. To compile for | |
| 32 | this 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 | ||
| 36 | In 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. | |
| 37 | An 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 | ||
| 41 | The resulting binaries run fine on an emulated target (possibly also on a real Zedboard or similar). | |
| 42 | For example, on qemu the following command can execute the binary: | |
| 43 | ```sh | |
| 44 | qemu-system-arm -no-reboot -serial null -serial mon:stdio -net none -nographic -M xilinx-zynq-a9 -m 512M -kernel <binary file> | |
| 45 | ``` | |
| 46 | ||
| 47 | While 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 | ||
| 51 | Compatible C-code can be built with the RTEMS cross-compiler toolchain `arm-rtems6-gcc`. | |
| 52 | For 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 { |
| 512 | 512 | pub(crate) fn is_mod(&self) -> bool { |
| 513 | 513 | self.type_() == ItemType::Module |
| 514 | 514 | } |
| 515 | pub(crate) fn is_trait(&self) -> bool { | |
| 516 | self.type_() == ItemType::Trait | |
| 517 | } | |
| 518 | 515 | pub(crate) fn is_struct(&self) -> bool { |
| 519 | 516 | self.type_() == ItemType::Struct |
| 520 | 517 | } |
| ... | ... | @@ -542,9 +539,6 @@ impl Item { |
| 542 | 539 | pub(crate) fn is_ty_method(&self) -> bool { |
| 543 | 540 | self.type_() == ItemType::TyMethod |
| 544 | 541 | } |
| 545 | pub(crate) fn is_type_alias(&self) -> bool { | |
| 546 | self.type_() == ItemType::TypeAlias | |
| 547 | } | |
| 548 | 542 | pub(crate) fn is_primitive(&self) -> bool { |
| 549 | 543 | self.type_() == ItemType::Primitive |
| 550 | 544 | } |
src/librustdoc/html/markdown.rs+62-11| ... | ... | @@ -51,12 +51,12 @@ use tracing::{debug, trace}; |
| 51 | 51 | use crate::clean::RenderedLink; |
| 52 | 52 | use crate::doctest; |
| 53 | 53 | use crate::doctest::GlobalTestOptions; |
| 54 | use crate::html::escape::Escape; | |
| 54 | use crate::html::escape::{Escape, EscapeBodyText}; | |
| 55 | 55 | use crate::html::format::Buffer; |
| 56 | 56 | use crate::html::highlight; |
| 57 | 57 | use crate::html::length_limit::HtmlWithLimit; |
| 58 | 58 | use crate::html::render::small_url_encode; |
| 59 | use crate::html::toc::TocBuilder; | |
| 59 | use crate::html::toc::{Toc, TocBuilder}; | |
| 60 | 60 | |
| 61 | 61 | #[cfg(test)] |
| 62 | 62 | mod tests; |
| ... | ... | @@ -102,6 +102,7 @@ pub struct Markdown<'a> { |
| 102 | 102 | /// A struct like `Markdown` that renders the markdown with a table of contents. |
| 103 | 103 | pub(crate) struct MarkdownWithToc<'a> { |
| 104 | 104 | pub(crate) content: &'a str, |
| 105 | pub(crate) links: &'a [RenderedLink], | |
| 105 | 106 | pub(crate) ids: &'a mut IdMap, |
| 106 | 107 | pub(crate) error_codes: ErrorCodes, |
| 107 | 108 | pub(crate) edition: Edition, |
| ... | ... | @@ -533,9 +534,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator |
| 533 | 534 | let id = self.id_map.derive(id); |
| 534 | 535 | |
| 535 | 536 | 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); | |
| 536 | 539 | 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()); | |
| 539 | 542 | self.buf.push_front((Event::Html(format!("{sec} ").into()), 0..0)); |
| 540 | 543 | } |
| 541 | 544 | |
| ... | ... | @@ -1412,10 +1415,23 @@ impl Markdown<'_> { |
| 1412 | 1415 | } |
| 1413 | 1416 | |
| 1414 | 1417 | impl 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; | |
| 1417 | 1421 | |
| 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(); | |
| 1419 | 1435 | |
| 1420 | 1436 | let mut s = String::with_capacity(md.len() * 3 / 2); |
| 1421 | 1437 | |
| ... | ... | @@ -1429,7 +1445,11 @@ impl MarkdownWithToc<'_> { |
| 1429 | 1445 | html::push_html(&mut s, p); |
| 1430 | 1446 | } |
| 1431 | 1447 | |
| 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()) | |
| 1433 | 1453 | } |
| 1434 | 1454 | } |
| 1435 | 1455 | |
| ... | ... | @@ -1608,7 +1628,16 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin |
| 1608 | 1628 | |
| 1609 | 1629 | let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)); |
| 1610 | 1630 | |
| 1611 | for event in p { | |
| 1631 | plain_text_from_events(p, &mut s); | |
| 1632 | ||
| 1633 | s | |
| 1634 | } | |
| 1635 | ||
| 1636 | pub(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 { | |
| 1612 | 1641 | match &event { |
| 1613 | 1642 | Event::Text(text) => s.push_str(text), |
| 1614 | 1643 | Event::Code(code) => { |
| ... | ... | @@ -1623,8 +1652,29 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin |
| 1623 | 1652 | _ => (), |
| 1624 | 1653 | } |
| 1625 | 1654 | } |
| 1655 | } | |
| 1626 | 1656 | |
| 1627 | s | |
| 1657 | pub(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 | } | |
| 1628 | 1678 | } |
| 1629 | 1679 | |
| 1630 | 1680 | #[derive(Debug)] |
| ... | ... | @@ -1975,7 +2025,8 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> { |
| 1975 | 2025 | map.insert("default-settings".into(), 1); |
| 1976 | 2026 | map.insert("sidebar-vars".into(), 1); |
| 1977 | 2027 | 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); | |
| 1979 | 2030 | // This is the list of IDs used by rustdoc sections (but still generated by |
| 1980 | 2031 | // rustdoc). |
| 1981 | 2032 | map.insert("fields".into(), 1); |
src/librustdoc/html/render/context.rs+4-2| ... | ... | @@ -15,7 +15,7 @@ use rustc_span::{sym, FileName, Symbol}; |
| 15 | 15 | use tracing::info; |
| 16 | 16 | |
| 17 | 17 | use super::print_item::{full_path, item_path, print_item}; |
| 18 | use super::sidebar::{print_sidebar, sidebar_module_like, Sidebar}; | |
| 18 | use super::sidebar::{print_sidebar, sidebar_module_like, ModuleLike, Sidebar}; | |
| 19 | 19 | use super::write_shared::write_shared; |
| 20 | 20 | use super::{collect_spans_and_sources, scrape_examples_help, AllTypes, LinkFromSrc, StylePath}; |
| 21 | 21 | use crate::clean::types::ExternalLocation; |
| ... | ... | @@ -617,12 +617,14 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { |
| 617 | 617 | let all = shared.all.replace(AllTypes::new()); |
| 618 | 618 | let mut sidebar = Buffer::html(); |
| 619 | 619 | |
| 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); | |
| 621 | 622 | let bar = Sidebar { |
| 622 | 623 | title_prefix: "", |
| 623 | 624 | title: "", |
| 624 | 625 | is_crate: false, |
| 625 | 626 | is_mod: false, |
| 627 | parent_is_crate: false, | |
| 626 | 628 | blocks: vec![blocks], |
| 627 | 629 | path: String::new(), |
| 628 | 630 | }; |
src/librustdoc/html/render/sidebar.rs+184-98| ... | ... | @@ -13,7 +13,24 @@ use crate::clean; |
| 13 | 13 | use crate::formats::item_type::ItemType; |
| 14 | 14 | use crate::formats::Impl; |
| 15 | 15 | use crate::html::format::Buffer; |
| 16 | use crate::html::markdown::IdMap; | |
| 16 | use crate::html::markdown::{IdMap, MarkdownWithToc}; | |
| 17 | ||
| 18 | #[derive(Clone, Copy)] | |
| 19 | pub(crate) enum ModuleLike { | |
| 20 | Module, | |
| 21 | Crate, | |
| 22 | } | |
| 23 | ||
| 24 | impl ModuleLike { | |
| 25 | pub(crate) fn is_crate(self) -> bool { | |
| 26 | matches!(self, ModuleLike::Crate) | |
| 27 | } | |
| 28 | } | |
| 29 | impl<'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 | } | |
| 17 | 34 | |
| 18 | 35 | #[derive(Template)] |
| 19 | 36 | #[template(path = "sidebar.html")] |
| ... | ... | @@ -21,6 +38,7 @@ pub(super) struct Sidebar<'a> { |
| 21 | 38 | pub(super) title_prefix: &'static str, |
| 22 | 39 | pub(super) title: &'a str, |
| 23 | 40 | pub(super) is_crate: bool, |
| 41 | pub(super) parent_is_crate: bool, | |
| 24 | 42 | pub(super) is_mod: bool, |
| 25 | 43 | pub(super) blocks: Vec<LinkBlock<'a>>, |
| 26 | 44 | pub(super) path: String, |
| ... | ... | @@ -63,15 +81,19 @@ impl<'a> LinkBlock<'a> { |
| 63 | 81 | /// A link to an item. Content should not be escaped. |
| 64 | 82 | #[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)] |
| 65 | 83 | pub(crate) struct Link<'a> { |
| 66 | /// The content for the anchor tag | |
| 84 | /// The content for the anchor tag and title attr | |
| 67 | 85 | name: Cow<'a, str>, |
| 86 | /// The content for the anchor tag (if different from name) | |
| 87 | name_html: Option<Cow<'a, str>>, | |
| 68 | 88 | /// The id of an anchor within the page (without a `#` prefix) |
| 69 | 89 | href: Cow<'a, str>, |
| 90 | /// Nested list of links (used only in top-toc) | |
| 91 | children: Vec<Link<'a>>, | |
| 70 | 92 | } |
| 71 | 93 | |
| 72 | 94 | impl<'a> Link<'a> { |
| 73 | 95 | 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 } | |
| 75 | 97 | } |
| 76 | 98 | pub fn empty() -> Link<'static> { |
| 77 | 99 | Link::new("", "") |
| ... | ... | @@ -95,17 +117,21 @@ pub(crate) mod filters { |
| 95 | 117 | } |
| 96 | 118 | |
| 97 | 119 | pub(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 | } | |
| 109 | 135 | // The sidebar is designed to display sibling functions, modules and |
| 110 | 136 | // other miscellaneous information. since there are lots of sibling |
| 111 | 137 | // 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 |
| 113 | 139 | // still, we don't move everything into JS because we want to preserve |
| 114 | 140 | // as much HTML as possible in order to allow non-JS-enabled browsers |
| 115 | 141 | // 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() { | |
| 125 | 145 | ( |
| 126 | 146 | match *it.kind { |
| 127 | 147 | clean::ModuleItem(..) => "Module ", |
| ... | ... | @@ -146,8 +166,15 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf |
| 146 | 166 | } else { |
| 147 | 167 | "".into() |
| 148 | 168 | }; |
| 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 | }; | |
| 151 | 178 | sidebar.render_into(buffer).unwrap(); |
| 152 | 179 | } |
| 153 | 180 | |
| ... | ... | @@ -163,30 +190,80 @@ fn get_struct_fields_name<'a>(fields: &'a [clean::Item]) -> Vec<Link<'a>> { |
| 163 | 190 | fields |
| 164 | 191 | } |
| 165 | 192 | |
| 193 | fn 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 | ||
| 166 | 243 | fn sidebar_struct<'a>( |
| 167 | 244 | cx: &'a Context<'_>, |
| 168 | 245 | it: &'a clean::Item, |
| 169 | 246 | s: &'a clean::Struct, |
| 170 | ) -> Vec<LinkBlock<'a>> { | |
| 247 | items: &mut Vec<LinkBlock<'a>>, | |
| 248 | ) { | |
| 171 | 249 | let fields = get_struct_fields_name(&s.fields); |
| 172 | 250 | let field_name = match s.ctor_kind { |
| 173 | 251 | Some(CtorKind::Fn) => Some("Tuple Fields"), |
| 174 | 252 | None => Some("Fields"), |
| 175 | 253 | _ => None, |
| 176 | 254 | }; |
| 177 | let mut items = vec![]; | |
| 178 | 255 | if let Some(name) = field_name { |
| 179 | 256 | items.push(LinkBlock::new(Link::new("fields", name), "structfield", fields)); |
| 180 | 257 | } |
| 181 | sidebar_assoc_items(cx, it, &mut items); | |
| 182 | items | |
| 258 | sidebar_assoc_items(cx, it, items); | |
| 183 | 259 | } |
| 184 | 260 | |
| 185 | 261 | fn sidebar_trait<'a>( |
| 186 | 262 | cx: &'a Context<'_>, |
| 187 | 263 | it: &'a clean::Item, |
| 188 | 264 | t: &'a clean::Trait, |
| 189 | ) -> Vec<LinkBlock<'a>> { | |
| 265 | blocks: &mut Vec<LinkBlock<'a>>, | |
| 266 | ) { | |
| 190 | 267 | fn filter_items<'a>( |
| 191 | 268 | items: &'a [clean::Item], |
| 192 | 269 | filt: impl Fn(&clean::Item) -> bool, |
| ... | ... | @@ -223,19 +300,20 @@ fn sidebar_trait<'a>( |
| 223 | 300 | foreign_impls.sort(); |
| 224 | 301 | } |
| 225 | 302 | |
| 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); | |
| 239 | 317 | |
| 240 | 318 | if !t.is_object_safe(cx.tcx()) { |
| 241 | 319 | blocks.push(LinkBlock::forced( |
| ... | ... | @@ -251,20 +329,17 @@ fn sidebar_trait<'a>( |
| 251 | 329 | "impl-auto", |
| 252 | 330 | )); |
| 253 | 331 | } |
| 254 | blocks | |
| 255 | 332 | } |
| 256 | 333 | |
| 257 | fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item) -> Vec<LinkBlock<'a>> { | |
| 334 | fn sidebar_primitive<'a>(cx: &'a Context<'_>, it: &'a clean::Item, items: &mut Vec<LinkBlock<'a>>) { | |
| 258 | 335 | 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); | |
| 262 | 337 | } else { |
| 263 | 338 | let shared = Rc::clone(&cx.shared); |
| 264 | 339 | let (concrete, synthetic, blanket_impl) = |
| 265 | 340 | super::get_filtered_impls_for_reference(&shared, it); |
| 266 | 341 | |
| 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); | |
| 268 | 343 | } |
| 269 | 344 | } |
| 270 | 345 | |
| ... | ... | @@ -272,8 +347,8 @@ fn sidebar_type_alias<'a>( |
| 272 | 347 | cx: &'a Context<'_>, |
| 273 | 348 | it: &'a clean::Item, |
| 274 | 349 | t: &'a clean::TypeAlias, |
| 275 | ) -> Vec<LinkBlock<'a>> { | |
| 276 | let mut items = vec![]; | |
| 350 | items: &mut Vec<LinkBlock<'a>>, | |
| 351 | ) { | |
| 277 | 352 | if let Some(inner_type) = &t.inner_type { |
| 278 | 353 | items.push(LinkBlock::forced(Link::new("aliased-type", "Aliased type"), "type")); |
| 279 | 354 | match inner_type { |
| ... | ... | @@ -295,19 +370,18 @@ fn sidebar_type_alias<'a>( |
| 295 | 370 | } |
| 296 | 371 | } |
| 297 | 372 | } |
| 298 | sidebar_assoc_items(cx, it, &mut items); | |
| 299 | items | |
| 373 | sidebar_assoc_items(cx, it, items); | |
| 300 | 374 | } |
| 301 | 375 | |
| 302 | 376 | fn sidebar_union<'a>( |
| 303 | 377 | cx: &'a Context<'_>, |
| 304 | 378 | it: &'a clean::Item, |
| 305 | 379 | u: &'a clean::Union, |
| 306 | ) -> Vec<LinkBlock<'a>> { | |
| 380 | items: &mut Vec<LinkBlock<'a>>, | |
| 381 | ) { | |
| 307 | 382 | 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); | |
| 311 | 385 | } |
| 312 | 386 | |
| 313 | 387 | /// Adds trait implementations into the blocks of links |
| ... | ... | @@ -346,21 +420,22 @@ fn sidebar_assoc_items<'a>( |
| 346 | 420 | methods.sort(); |
| 347 | 421 | } |
| 348 | 422 | |
| 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()) { | |
| 351 | 433 | if let Some(impl_) = |
| 352 | 434 | v.iter().find(|i| i.trait_did() == cx.tcx().lang_items().deref_trait()) |
| 353 | 435 | { |
| 354 | 436 | let mut derefs = DefIdSet::default(); |
| 355 | 437 | 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); | |
| 364 | 439 | } |
| 365 | 440 | |
| 366 | 441 | let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = |
| ... | ... | @@ -368,21 +443,15 @@ fn sidebar_assoc_items<'a>( |
| 368 | 443 | let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = |
| 369 | 444 | concrete.into_iter().partition::<Vec<_>, _>(|i| i.inner_impl().kind.is_blanket()); |
| 370 | 445 | |
| 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 | } | |
| 386 | 455 | links.append(&mut blocks); |
| 387 | 456 | } |
| 388 | 457 | } |
| ... | ... | @@ -472,7 +541,8 @@ fn sidebar_enum<'a>( |
| 472 | 541 | cx: &'a Context<'_>, |
| 473 | 542 | it: &'a clean::Item, |
| 474 | 543 | e: &'a clean::Enum, |
| 475 | ) -> Vec<LinkBlock<'a>> { | |
| 544 | items: &mut Vec<LinkBlock<'a>>, | |
| 545 | ) { | |
| 476 | 546 | let mut variants = e |
| 477 | 547 | .variants() |
| 478 | 548 | .filter_map(|v| v.name) |
| ... | ... | @@ -480,24 +550,37 @@ fn sidebar_enum<'a>( |
| 480 | 550 | .collect::<Vec<_>>(); |
| 481 | 551 | variants.sort_unstable(); |
| 482 | 552 | |
| 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); | |
| 486 | 555 | } |
| 487 | 556 | |
| 488 | 557 | pub(crate) fn sidebar_module_like( |
| 489 | 558 | item_sections_in_use: FxHashSet<ItemSection>, |
| 559 | ids: &mut IdMap, | |
| 560 | module_like: ModuleLike, | |
| 490 | 561 | ) -> LinkBlock<'static> { |
| 491 | let item_sections = ItemSection::ALL | |
| 562 | let item_sections: Vec<Link<'_>> = ItemSection::ALL | |
| 492 | 563 | .iter() |
| 493 | 564 | .copied() |
| 494 | 565 | .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())) | |
| 496 | 567 | .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) | |
| 498 | 577 | } |
| 499 | 578 | |
| 500 | fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> { | |
| 579 | fn sidebar_module( | |
| 580 | items: &[clean::Item], | |
| 581 | ids: &mut IdMap, | |
| 582 | module_like: ModuleLike, | |
| 583 | ) -> LinkBlock<'static> { | |
| 501 | 584 | let item_sections_in_use: FxHashSet<_> = items |
| 502 | 585 | .iter() |
| 503 | 586 | .filter(|it| { |
| ... | ... | @@ -518,13 +601,15 @@ fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> { |
| 518 | 601 | .map(|it| item_ty_to_section(it.type_())) |
| 519 | 602 | .collect(); |
| 520 | 603 | |
| 521 | sidebar_module_like(item_sections_in_use) | |
| 604 | sidebar_module_like(item_sections_in_use, ids, module_like) | |
| 522 | 605 | } |
| 523 | 606 | |
| 524 | fn 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 | |
| 607 | fn 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); | |
| 528 | 613 | } |
| 529 | 614 | |
| 530 | 615 | /// Renders the trait implementations for this type |
| ... | ... | @@ -534,7 +619,8 @@ fn sidebar_render_assoc_items( |
| 534 | 619 | concrete: Vec<&Impl>, |
| 535 | 620 | synthetic: Vec<&Impl>, |
| 536 | 621 | blanket_impl: Vec<&Impl>, |
| 537 | ) -> [LinkBlock<'static>; 3] { | |
| 622 | items: &mut Vec<LinkBlock<'_>>, | |
| 623 | ) { | |
| 538 | 624 | let format_impls = |impls: Vec<&Impl>, id_map: &mut IdMap| { |
| 539 | 625 | let mut links = FxHashSet::default(); |
| 540 | 626 | |
| ... | ... | @@ -559,7 +645,7 @@ fn sidebar_render_assoc_items( |
| 559 | 645 | let concrete = format_impls(concrete, id_map); |
| 560 | 646 | let synthetic = format_impls(synthetic, id_map); |
| 561 | 647 | let blanket = format_impls(blanket_impl, id_map); |
| 562 | [ | |
| 648 | items.extend([ | |
| 563 | 649 | LinkBlock::new( |
| 564 | 650 | Link::new("trait-implementations", "Trait Implementations"), |
| 565 | 651 | "trait-implementation", |
| ... | ... | @@ -575,7 +661,7 @@ fn sidebar_render_assoc_items( |
| 575 | 661 | "blanket-implementation", |
| 576 | 662 | blanket, |
| 577 | 663 | ), |
| 578 | ] | |
| 664 | ]); | |
| 579 | 665 | } |
| 580 | 666 | |
| 581 | 667 | fn 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 { |
| 568 | 568 | 	width: 48px; |
| 569 | 569 | } |
| 570 | 570 | |
| 571 | ul.block, .block li { | |
| 571 | ul.block, .block li, .block ul { | |
| 572 | 572 | 	padding: 0; |
| 573 | 573 | 	margin: 0; |
| 574 | 574 | 	list-style: none; |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | .block ul a { | |
| 578 | 	padding-left: 1rem; | |
| 579 | } | |
| 580 | ||
| 577 | 581 | .sidebar-elems a, |
| 578 | 582 | .sidebar > h2 a { |
| 579 | 583 | 	display: block; |
| ... | ... | @@ -585,6 +589,14 @@ ul.block, .block li { |
| 585 | 589 | 	background-clip: border-box; |
| 586 | 590 | } |
| 587 | 591 | |
| 592 | .hide-toc #rustdoc-toc, .hide-toc .in-crate { | |
| 593 | 	display: none; | |
| 594 | } | |
| 595 | ||
| 596 | .hide-modnav #rustdoc-modnav { | |
| 597 | 	display: none; | |
| 598 | } | |
| 599 | ||
| 588 | 600 | .sidebar h2 { |
| 589 | 601 | 	text-wrap: balance; |
| 590 | 602 | 	overflow-wrap: anywhere; |
src/librustdoc/html/static/js/main.js+2-2| ... | ... | @@ -499,7 +499,7 @@ function preLoadCss(cssUrl) { |
| 499 | 499 | if (!window.SIDEBAR_ITEMS) { |
| 500 | 500 | return; |
| 501 | 501 | } |
| 502 | const sidebar = document.getElementsByClassName("sidebar-elems")[0]; | |
| 502 | const sidebar = document.getElementById("rustdoc-modnav"); | |
| 503 | 503 | |
| 504 | 504 | /** |
| 505 | 505 | * Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items. |
| ... | ... | @@ -885,7 +885,7 @@ function preLoadCss(cssUrl) { |
| 885 | 885 | if (!window.ALL_CRATES) { |
| 886 | 886 | return; |
| 887 | 887 | } |
| 888 | const sidebarElems = document.getElementsByClassName("sidebar-elems")[0]; | |
| 888 | const sidebarElems = document.getElementById("rustdoc-modnav"); | |
| 889 | 889 | if (!sidebarElems) { |
| 890 | 890 | return; |
| 891 | 891 | } |
src/librustdoc/html/static/js/settings.js+29| ... | ... | @@ -36,6 +36,20 @@ |
| 36 | 36 | removeClass(document.documentElement, "hide-sidebar"); |
| 37 | 37 | } |
| 38 | 38 | 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; | |
| 39 | 53 | } |
| 40 | 54 | } |
| 41 | 55 | |
| ... | ... | @@ -102,6 +116,11 @@ |
| 102 | 116 | let output = ""; |
| 103 | 117 | |
| 104 | 118 | for (const setting of settings) { |
| 119 | if (setting === "hr") { | |
| 120 | output += "<hr>"; | |
| 121 | continue; | |
| 122 | } | |
| 123 | ||
| 105 | 124 | const js_data_name = setting["js_name"]; |
| 106 | 125 | const setting_name = setting["name"]; |
| 107 | 126 | |
| ... | ... | @@ -198,6 +217,16 @@ |
| 198 | 217 | "js_name": "hide-sidebar", |
| 199 | 218 | "default": false, |
| 200 | 219 | }, |
| 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 | }, | |
| 201 | 230 | { |
| 202 | 231 | "name": "Disable keyboard shortcuts", |
| 203 | 232 | "js_name": "disable-shortcuts", |
src/librustdoc/html/static/js/storage.js+9-4| ... | ... | @@ -196,16 +196,21 @@ updateTheme(); |
| 196 | 196 | // This needs to be done here because this JS is render-blocking, |
| 197 | 197 | // so that the sidebar doesn't "jump" after appearing on screen. |
| 198 | 198 | // 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. | |
| 199 | 202 | if (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. | |
| 202 | 203 | addClass(document.documentElement, "src-sidebar-expanded"); |
| 203 | 204 | } |
| 204 | 205 | if (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. | |
| 207 | 206 | addClass(document.documentElement, "hide-sidebar"); |
| 208 | 207 | } |
| 208 | if (getSettingValue("hide-toc") === "true") { | |
| 209 | addClass(document.documentElement, "hide-toc"); | |
| 210 | } | |
| 211 | if (getSettingValue("hide-modnav") === "true") { | |
| 212 | addClass(document.documentElement, "hide-modnav"); | |
| 213 | } | |
| 209 | 214 | function updateSidebarWidth() { |
| 210 | 215 | const desktopSidebarWidth = getSettingValue("desktop-sidebar-width"); |
| 211 | 216 | 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 %} | |
| 6 | 1 | <div class="sidebar-elems"> |
| 7 | 2 | {% if is_crate %} |
| 8 | 3 | <ul class="block"> {# #} |
| ... | ... | @@ -11,18 +6,46 @@ |
| 11 | 6 | {% endif %} |
| 12 | 7 | |
| 13 | 8 | {% 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 %} | |
| 15 | 15 | {% for block in blocks %} |
| 16 | 16 | {% if block.should_render() %} |
| 17 | 17 | {% 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> | |
| 21 | 21 | {% endif %} |
| 22 | 22 | {% if !block.links.is_empty() %} |
| 23 | 23 | <ul class="block{% if !block.class.is_empty() +%} {{+block.class}}{% endif %}"> |
| 24 | 24 | {% 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> | |
| 26 | 49 | {% endfor %} |
| 27 | 50 | </ul> |
| 28 | 51 | {% endif %} |
| ... | ... | @@ -30,7 +53,11 @@ |
| 30 | 53 | {% endfor %} |
| 31 | 54 | </section> |
| 32 | 55 | {% endif %} |
| 56 | <div id="rustdoc-modnav"> | |
| 33 | 57 | {% 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> | |
| 35 | 61 | {% endif %} |
| 62 | </div> {# #} | |
| 36 | 63 | </div> |
src/librustdoc/html/toc.rs+17-9| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | //! Table-of-contents creation. |
| 2 | use crate::html::escape::Escape; | |
| 2 | 3 | |
| 3 | 4 | /// A (recursive) table of contents |
| 4 | 5 | #[derive(Debug, PartialEq)] |
| ... | ... | @@ -16,7 +17,7 @@ pub(crate) struct Toc { |
| 16 | 17 | /// ### A |
| 17 | 18 | /// ## B |
| 18 | 19 | /// ``` |
| 19 | entries: Vec<TocEntry>, | |
| 20 | pub(crate) entries: Vec<TocEntry>, | |
| 20 | 21 | } |
| 21 | 22 | |
| 22 | 23 | impl Toc { |
| ... | ... | @@ -27,11 +28,16 @@ impl Toc { |
| 27 | 28 | |
| 28 | 29 | #[derive(Debug, PartialEq)] |
| 29 | 30 | pub(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, | |
| 35 | 41 | } |
| 36 | 42 | |
| 37 | 43 | /// Progressive construction of a table of contents. |
| ... | ... | @@ -115,7 +121,7 @@ impl TocBuilder { |
| 115 | 121 | /// Push a level `level` heading into the appropriate place in the |
| 116 | 122 | /// hierarchy, returning a string containing the section number in |
| 117 | 123 | /// `<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 { | |
| 119 | 125 | assert!(level >= 1); |
| 120 | 126 | |
| 121 | 127 | // collapse all previous sections into their parents until we |
| ... | ... | @@ -149,6 +155,7 @@ impl TocBuilder { |
| 149 | 155 | self.chain.push(TocEntry { |
| 150 | 156 | level, |
| 151 | 157 | name, |
| 158 | html, | |
| 152 | 159 | sec_number, |
| 153 | 160 | id, |
| 154 | 161 | children: Toc { entries: Vec::new() }, |
| ... | ... | @@ -170,10 +177,11 @@ impl Toc { |
| 170 | 177 | // recursively format this table of contents |
| 171 | 178 | let _ = write!( |
| 172 | 179 | v, |
| 173 | "\n<li><a href=\"#{id}\">{num} {name}</a>", | |
| 180 | "\n<li><a href=\"#{id}\" title=\"{name}\">{num} {html}</a>", | |
| 174 | 181 | id = entry.id, |
| 175 | 182 | num = entry.sec_number, |
| 176 | name = entry.name | |
| 183 | name = Escape(&entry.name), | |
| 184 | html = &entry.html, | |
| 177 | 185 | ); |
| 178 | 186 | entry.children.print_inner(&mut *v); |
| 179 | 187 | v.push_str("</li>"); |
src/librustdoc/html/toc/tests.rs+5-1| ... | ... | @@ -9,7 +9,10 @@ fn builder_smoke() { |
| 9 | 9 | // there's been no macro mistake. |
| 10 | 10 | macro_rules! push { |
| 11 | 11 | ($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 | ); | |
| 13 | 16 | }; |
| 14 | 17 | } |
| 15 | 18 | push!(2, "0.1"); |
| ... | ... | @@ -48,6 +51,7 @@ fn builder_smoke() { |
| 48 | 51 | TocEntry { |
| 49 | 52 | level: $level, |
| 50 | 53 | name: $name.to_string(), |
| 54 | html: $name.to_string(), | |
| 51 | 55 | sec_number: $name.to_string(), |
| 52 | 56 | id: "".to_string(), |
| 53 | 57 | children: toc!($($sub),*) |
src/librustdoc/markdown.rs+1| ... | ... | @@ -72,6 +72,7 @@ pub(crate) fn render<P: AsRef<Path>>( |
| 72 | 72 | let text = if !options.markdown_no_toc { |
| 73 | 73 | MarkdownWithToc { |
| 74 | 74 | content: text, |
| 75 | links: &[], | |
| 75 | 76 | ids: &mut ids, |
| 76 | 77 | error_codes, |
| 77 | 78 | edition, |
src/tools/build_helper/src/git.rs+34| ... | ... | @@ -159,3 +159,37 @@ pub fn get_git_untracked_files( |
| 159 | 159 | .collect(); |
| 160 | 160 | Ok(Some(files)) |
| 161 | 161 | } |
| 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. | |
| 170 | pub 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] = &[ |
| 136 | 136 | "min-llvm-version", |
| 137 | 137 | "min-system-llvm-version", |
| 138 | 138 | "needs-asm-support", |
| 139 | "needs-deterministic-layouts", | |
| 139 | 140 | "needs-dlltool", |
| 140 | 141 | "needs-dynamic-linking", |
| 141 | 142 | "needs-force-clang-based-tests", |
src/tools/compiletest/src/common.rs+3| ... | ... | @@ -274,6 +274,9 @@ pub struct Config { |
| 274 | 274 | /// Flags to pass to the compiler when building for the target |
| 275 | 275 | pub target_rustcflags: Vec<String>, |
| 276 | 276 | |
| 277 | /// Whether the compiler and stdlib has been built with randomized struct layouts | |
| 278 | pub rust_randomized_layout: bool, | |
| 279 | ||
| 277 | 280 | /// Whether tests should be optimized by default. Individual test-suites and test files may |
| 278 | 281 | /// override this setting. |
| 279 | 282 | pub optimize_tests: bool, |
src/tools/compiletest/src/header/needs.rs+5| ... | ... | @@ -134,6 +134,11 @@ pub(super) fn handle_needs( |
| 134 | 134 | condition: config.target_cfg().relocation_model == "pic", |
| 135 | 135 | ignore_reason: "ignored on targets without PIC relocation model", |
| 136 | 136 | }, |
| 137 | Need { | |
| 138 | name: "needs-deterministic-layouts", | |
| 139 | condition: !config.rust_randomized_layout, | |
| 140 | ignore_reason: "ignored when randomizing layouts", | |
| 141 | }, | |
| 137 | 142 | Need { |
| 138 | 143 | name: "needs-wasmtime", |
| 139 | 144 | 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 { |
| 99 | 99 | ) |
| 100 | 100 | .optmulti("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS") |
| 101 | 101 | .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 | ) | |
| 102 | 107 | .optflag("", "optimize-tests", "run tests with optimizations enabled") |
| 103 | 108 | .optflag("", "verbose", "run tests verbosely, showing all output") |
| 104 | 109 | .optflag( |
| ... | ... | @@ -286,6 +291,7 @@ pub fn parse_config(args: Vec<String>) -> Config { |
| 286 | 291 | host_rustcflags: matches.opt_strs("host-rustcflags"), |
| 287 | 292 | target_rustcflags: matches.opt_strs("target-rustcflags"), |
| 288 | 293 | optimize_tests: matches.opt_present("optimize-tests"), |
| 294 | rust_randomized_layout: matches.opt_present("rust-randomized-layout"), | |
| 289 | 295 | target, |
| 290 | 296 | host: opt_str2(matches.opt_str("host")), |
| 291 | 297 | cdb, |
src/tools/miri/tests/pass/dyn-arbitrary-self.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@revisions: stack tree |
| 2 | 2 | //@[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)] | |
| 4 | 4 | #![feature(rustc_attrs)] |
| 5 | 5 | |
| 6 | 6 | fn pin_box_dyn() { |
tests/assembly/targets/targets-elf.rs+3| ... | ... | @@ -129,6 +129,9 @@ |
| 129 | 129 | //@ revisions: armv7_linux_androideabi |
| 130 | 130 | //@ [armv7_linux_androideabi] compile-flags: --target armv7-linux-androideabi |
| 131 | 131 | //@ [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 | |
| 132 | 135 | //@ revisions: armv7_sony_vita_newlibeabihf |
| 133 | 136 | //@ [armv7_sony_vita_newlibeabihf] compile-flags: --target armv7-sony-vita-newlibeabihf |
| 134 | 137 | //@ [armv7_sony_vita_newlibeabihf] needs-llvm-components: arm |
tests/codegen/issues/issue-86106.rs+1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | //@ only-64bit llvm appears to use stores instead of memset on 32bit |
| 2 | 2 | //@ compile-flags: -C opt-level=3 -Z merge-functions=disabled |
| 3 | //@ needs-deterministic-layouts | |
| 3 | 4 | |
| 4 | 5 | // The below two functions ensure that both `String::new()` and `"".to_string()` |
| 5 | 6 | // produce the identical code. |
tests/codegen/mem-replace-big-type.rs+1| ... | ... | @@ -5,6 +5,7 @@ |
| 5 | 5 | |
| 6 | 6 | //@ compile-flags: -C no-prepopulate-passes -Zinline-mir=no |
| 7 | 7 | //@ ignore-debug: precondition checks in ptr::read make them a bad candidate for MIR inlining |
| 8 | //@ needs-deterministic-layouts | |
| 8 | 9 | |
| 9 | 10 | #![crate_type = "lib"] |
| 10 | 11 |
tests/codegen/slice-iter-nonnull.rs+1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | //@ compile-flags: -O |
| 2 | //@ needs-deterministic-layouts | |
| 2 | 3 | #![crate_type = "lib"] |
| 3 | 4 | #![feature(exact_size_is_empty)] |
| 4 | 5 |
tests/codegen/vecdeque-drain.rs+1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | // Check that draining at the front or back doesn't copy memory. |
| 2 | 2 | |
| 3 | 3 | //@ compile-flags: -O |
| 4 | //@ needs-deterministic-layouts | |
| 4 | 5 | //@ ignore-debug: FIXME: checks for call detect scoped noalias metadata |
| 5 | 6 | |
| 6 | 7 | #![crate_type = "lib"] |
tests/mir-opt/building/receiver_ptr_mutability.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // skip-filecheck |
| 2 | 2 | // EMIT_MIR receiver_ptr_mutability.main.built.after.mir |
| 3 | 3 | |
| 4 | #![feature(arbitrary_self_types)] | |
| 4 | #![feature(arbitrary_self_types_pointers)] | |
| 5 | 5 | |
| 6 | 6 | struct Test {} |
| 7 | 7 |
tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.rs+1| ... | ... | @@ -1,3 +1,4 @@ |
| 1 | //@needs-deterministic-layouts | |
| 1 | 2 | // Verify that we do not ICE when printing an invalid constant. |
| 2 | 3 | // EMIT_MIR_FOR_EACH_BIT_WIDTH |
| 3 | 4 | // 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 | ||
| 12 | go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" | |
| 13 | show-text: true | |
| 14 | set-local-storage: {"rustdoc-hide-toc": "true"} | |
| 15 | ||
| 16 | define-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 | |
| 31 | go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" | |
| 32 | store-position: ("#rustdoc-modnav > h2", {"x": h2_x, "y": h2_y}) | |
| 33 | store-position: ("#rustdoc-modnav > ul:first-of-type > li:first-of-type", {"x": x, "y": y}) | |
| 34 | call-function: ("check-positions", {"url": "/test_docs/enum.WhoLetTheDogOut.html"}) | |
| 35 | call-function: ("check-positions", {"url": "/test_docs/struct.StructWithPublicUndocumentedFields.html"}) | |
| 36 | call-function: ("check-positions", {"url": "/test_docs/codeblock_sub/index.html"}) | |
| 37 | ||
| 38 | // Now in a submodule | |
| 39 | go-to: "file://" + |DOC_PATH| + "/test_docs/fields/struct.Struct.html" | |
| 40 | store-position: ("#rustdoc-modnav > h2", {"x": h2_x, "y": h2_y}) | |
| 41 | store-position: ("#rustdoc-modnav > ul:first-of-type > li:first-of-type", {"x": x, "y": y}) | |
| 42 | call-function: ("check-positions", {"url": "/test_docs/fields/struct.Struct.html"}) | |
| 43 | call-function: ("check-positions", {"url": "/test_docs/fields/union.Union.html"}) | |
| 44 | call-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" |
| 118 | 118 | go-to: "./module/index.html" |
| 119 | 119 | assert-property: (".sidebar", {"clientWidth": "200"}) |
| 120 | 120 | assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2") |
| 121 | assert-text: (".sidebar > .location", "Module module") | |
| 121 | assert-text: (".sidebar .location", "Module module") | |
| 122 | 122 | assert-count: (".sidebar .location", 1) |
| 123 | 123 | assert-text: (".sidebar-elems ul.block > li.current > a", "module") |
| 124 | 124 | // Module page requires three headings: |
| ... | ... | @@ -126,8 +126,8 @@ assert-text: (".sidebar-elems ul.block > li.current > a", "module") |
| 126 | 126 | // - Module name, followed by TOC for module headings |
| 127 | 127 | // - "In crate [name]" parent pointer, followed by sibling navigation |
| 128 | 128 | assert-count: (".sidebar h2", 3) |
| 129 | assert-text: (".sidebar > .sidebar-elems > h2", "In crate lib2") | |
| 130 | assert-property: (".sidebar > .sidebar-elems > h2 > a", { | |
| 129 | assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In crate lib2") | |
| 130 | assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", { | |
| 131 | 131 | "href": "/lib2/index.html", |
| 132 | 132 | }, ENDS_WITH) |
| 133 | 133 | // We check that we don't have the crate list. |
| ... | ... | @@ -136,9 +136,9 @@ assert-false: ".sidebar-elems > .crate" |
| 136 | 136 | go-to: "./sub_module/sub_sub_module/index.html" |
| 137 | 137 | assert-property: (".sidebar", {"clientWidth": "200"}) |
| 138 | 138 | assert-text: (".sidebar > .sidebar-crate > h2 > a", "lib2") |
| 139 | assert-text: (".sidebar > .location", "Module sub_sub_module") | |
| 140 | assert-text: (".sidebar > .sidebar-elems > h2", "In lib2::module::sub_module") | |
| 141 | assert-property: (".sidebar > .sidebar-elems > h2 > a", { | |
| 139 | assert-text: (".sidebar .location", "Module sub_sub_module") | |
| 140 | assert-text: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2", "In lib2::module::sub_module") | |
| 141 | assert-property: (".sidebar > .sidebar-elems > #rustdoc-modnav > h2 > a", { | |
| 142 | 142 | "href": "/module/sub_module/index.html", |
| 143 | 143 | }, ENDS_WITH) |
| 144 | 144 | assert-text: (".sidebar-elems ul.block > li.current > a", "sub_sub_module") |
| ... | ... | @@ -198,3 +198,36 @@ assert-position-false: (".sidebar-crate > h2 > a", {"x": -3}) |
| 198 | 198 | // when line-wrapped, see that it becomes flush-left again |
| 199 | 199 | drag-and-drop: ((205, 100), (108, 100)) |
| 200 | 200 | assert-position: (".sidebar-crate > h2 > a", {"x": -3}) |
| 201 | ||
| 202 | // Configuration option to show TOC in sidebar. | |
| 203 | set-local-storage: {"rustdoc-hide-toc": "true"} | |
| 204 | go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" | |
| 205 | assert-css: ("#rustdoc-toc", {"display": "none"}) | |
| 206 | assert-css: (".sidebar .in-crate", {"display": "none"}) | |
| 207 | set-local-storage: {"rustdoc-hide-toc": "false"} | |
| 208 | go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" | |
| 209 | assert-css: ("#rustdoc-toc", {"display": "block"}) | |
| 210 | assert-css: (".sidebar .in-crate", {"display": "block"}) | |
| 211 | ||
| 212 | set-local-storage: {"rustdoc-hide-modnav": "true"} | |
| 213 | go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" | |
| 214 | assert-css: ("#rustdoc-modnav", {"display": "none"}) | |
| 215 | set-local-storage: {"rustdoc-hide-modnav": "false"} | |
| 216 | go-to: "file://" + |DOC_PATH| + "/test_docs/enum.WhoLetTheDogOut.html" | |
| 217 | assert-css: ("#rustdoc-modnav", {"display": "block"}) | |
| 218 | ||
| 219 | set-local-storage: {"rustdoc-hide-toc": "true"} | |
| 220 | go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" | |
| 221 | assert-css: ("#rustdoc-toc", {"display": "none"}) | |
| 222 | assert-false: ".sidebar .in-crate" | |
| 223 | set-local-storage: {"rustdoc-hide-toc": "false"} | |
| 224 | go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" | |
| 225 | assert-css: ("#rustdoc-toc", {"display": "block"}) | |
| 226 | assert-false: ".sidebar .in-crate" | |
| 227 | ||
| 228 | set-local-storage: {"rustdoc-hide-modnav": "true"} | |
| 229 | go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" | |
| 230 | assert-css: ("#rustdoc-modnav", {"display": "none"}) | |
| 231 | set-local-storage: {"rustdoc-hide-modnav": "false"} | |
| 232 | go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" | |
| 233 | assert-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 | ||
| 16 | pub struct Foo; | |
| 17 | pub enum Enum { | |
| 18 | A, | |
| 19 | } | |
| 20 | pub union Bar { | |
| 21 | a: u8, | |
| 22 | b: u16, | |
| 23 | } | |
| 24 | pub fn foo() {} | |
| 25 | pub trait Trait {} | |
| 26 | #[macro_export] | |
| 27 | macro_rules! foo { | |
| 28 | () => {}; | |
| 29 | } | |
| 30 | pub type Type = u8; | |
| 31 | pub const FOO: u8 = 0; | |
| 32 | pub static BAR: u8 = 0; | |
| 33 | #[rustc_doc_primitive = "u8"] | |
| 34 | mod 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' | |
| 18 | pub 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"]' '' | |
| 30 | pub 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' | |
| 39 | pub 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' | |
| 49 | pub 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' | |
| 59 | pub 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" | |
| 5 | pub struct SomeStruct<T> { _inner: T } | |
| 6 | ||
| 7 | impl SomeStruct<()> { | |
| 8 | pub fn some_fn(&self) {} | |
| 9 | } | |
| 10 | ||
| 11 | impl 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" | |
| 12 | pub trait Foo {} | |
| 13 | ||
| 14 | impl Foo for u32 {} | |
| 15 | ||
| 16 | impl<'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' | |
| 8 | pub 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' | |
| 16 | pub 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 | ||
| 16 | pub struct Foo; | |
| 17 | pub enum Enum { | |
| 18 | A, | |
| 19 | } | |
| 20 | pub union Bar { | |
| 21 | a: u8, | |
| 22 | b: u16, | |
| 23 | } | |
| 24 | pub fn foo() {} | |
| 25 | pub trait Trait {} | |
| 26 | #[macro_export] | |
| 27 | macro_rules! foo { | |
| 28 | () => {}; | |
| 29 | } | |
| 30 | pub type Type = u8; | |
| 31 | pub const FOO: u8 = 0; | |
| 32 | pub static BAR: u8 = 0; | |
| 33 | #[rustc_doc_primitive = "u8"] | |
| 34 | mod 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' | |
| 18 | pub 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"]' '' | |
| 30 | pub 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' | |
| 39 | pub 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' | |
| 49 | pub 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' | |
| 59 | pub 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" | |
| 5 | pub struct SomeStruct<T> { _inner: T } | |
| 6 | ||
| 7 | impl SomeStruct<()> { | |
| 8 | pub fn some_fn(&self) {} | |
| 9 | } | |
| 10 | ||
| 11 | impl 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" | |
| 12 | pub trait Foo {} | |
| 13 | ||
| 14 | impl Foo for u32 {} | |
| 15 | ||
| 16 | impl<'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 | ||
| 42 | pub 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 @@ |
| 2 | 2 | // |
| 3 | 3 | // issue: <https://github.com/rust-lang/rust/issues/120217> |
| 4 | 4 | |
| 5 | #![feature(arbitrary_self_types)] | |
| 5 | #![feature(arbitrary_self_types_pointers)] | |
| 6 | 6 | |
| 7 | 7 | trait Static<'a> { |
| 8 | 8 | 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` |
| 210 | 210 | LL | target_os = "_UNEXPECTED_VALUE", |
| 211 | 211 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 212 | 212 | | |
| 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` | |
| 214 | 214 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 215 | 215 | |
| 216 | 216 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| ... | ... | @@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` |
| 294 | 294 | | | |
| 295 | 295 | | help: there is a expected value with a similar name: `"linux"` |
| 296 | 296 | | |
| 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` | |
| 298 | 298 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 299 | 299 | |
| 300 | 300 | warning: 30 warnings emitted |
tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.rs created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | trait Foo { | |
| 2 | fn foo(self: *const Self); //~ ERROR `*const Self` cannot be used as the type of `self` | |
| 3 | } | |
| 4 | ||
| 5 | struct Bar; | |
| 6 | ||
| 7 | impl Foo for Bar { | |
| 8 | fn foo(self: *const Self) {} //~ ERROR `*const Bar` cannot be used as the type of `self` | |
| 9 | } | |
| 10 | ||
| 11 | impl Bar { | |
| 12 | fn bar(self: *mut Self) {} //~ ERROR `*mut Bar` cannot be used as the type of `self` | |
| 13 | } | |
| 14 | ||
| 15 | fn main() {} |
tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | error[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 | | | |
| 4 | LL | 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 | ||
| 12 | error[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 | | | |
| 15 | LL | 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 | ||
| 23 | error[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 | | | |
| 26 | LL | 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 | ||
| 34 | error: aborting due to 3 previous errors | |
| 35 | ||
| 36 | For 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 @@ |
| 1 | error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types` feature | |
| 1 | error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature | |
| 2 | 2 | --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:4:18 |
| 3 | 3 | | |
| 4 | 4 | LL | fn foo(self: *const Self) {} |
| 5 | 5 | | ^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | 7 | = 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 | |
| 9 | 9 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 10 | 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 | 11 | |
| 12 | error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature | |
| 12 | error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature | |
| 13 | 13 | --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18 |
| 14 | 14 | | |
| 15 | 15 | LL | fn bar(self: *const Self) {} |
| 16 | 16 | | ^^^^^^^^^^^ |
| 17 | 17 | | |
| 18 | 18 | = 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 | |
| 20 | 20 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 21 | 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 | 22 | |
| 23 | error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature | |
| 23 | error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature | |
| 24 | 24 | --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18 |
| 25 | 25 | | |
| 26 | 26 | LL | fn bar(self: *const Self); |
| 27 | 27 | | ^^^^^^^^^^^ |
| 28 | 28 | | |
| 29 | 29 | = 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 | |
| 31 | 31 | = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date |
| 32 | 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 | 33 |
tests/ui/inference/auxiliary/inference_unstable_iterator.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | #![feature(staged_api)] |
| 2 | #![feature(arbitrary_self_types)] | |
| 2 | #![feature(arbitrary_self_types_pointers)] | |
| 3 | 3 | |
| 4 | 4 | #![stable(feature = "ipu_iterator", since = "1.0.0")] |
| 5 | 5 |
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)] | |
| 2 | 2 | |
| 3 | 3 | pub trait IpuItertools { |
| 4 | 4 | fn ipu_flatten(&self) -> u32 { |
tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ run-pass |
| 2 | #![feature(arbitrary_self_types)] | |
| 2 | #![feature(arbitrary_self_types_pointers)] | |
| 3 | 3 | |
| 4 | 4 | use std::rc::Rc; |
| 5 | 5 |
tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | //@ run-pass |
| 2 | #![feature(arbitrary_self_types)] | |
| 2 | #![feature(arbitrary_self_types_pointers)] | |
| 3 | 3 | |
| 4 | 4 | use std::ptr; |
| 5 | 5 |
tests/ui/stats/hir-stats.rs+3| ... | ... | @@ -1,12 +1,15 @@ |
| 1 | 1 | //@ check-pass |
| 2 | 2 | //@ compile-flags: -Zhir-stats |
| 3 | 3 | //@ only-x86_64 |
| 4 | // layout randomization affects the hir stat output | |
| 5 | //@ needs-deterministic-layouts | |
| 4 | 6 | |
| 5 | 7 | // Type layouts sometimes change. When that happens, until the next bootstrap |
| 6 | 8 | // bump occurs, stage1 and stage2 will give different outputs for this test. |
| 7 | 9 | // Add an `ignore-stage1` comment marker to work around that problem during |
| 8 | 10 | // that time. |
| 9 | 11 | |
| 12 | ||
| 10 | 13 | // The aim here is to include at least one of every different type of top-level |
| 11 | 14 | // AST/HIR node reported by `-Zhir-stats`. |
| 12 | 15 |
tests/ui/structs-enums/type-sizes.rs+1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | //@ run-pass |
| 2 | //@ needs-deterministic-layouts | |
| 2 | 3 | |
| 3 | 4 | #![allow(non_camel_case_types)] |
| 4 | 5 | #![allow(dead_code)] |