diff --git a/Cargo.lock b/Cargo.lock index 082bb4be93c0a..2882ec0682e2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4504,6 +4504,7 @@ dependencies = [ name = "rustc_smir" version = "0.0.0" dependencies = [ + "rustc_data_structures", "rustc_driver", "rustc_hir", "rustc_interface", diff --git a/RELEASES.md b/RELEASES.md index e261294a032fd..1cc110e6607f9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -229,6 +229,7 @@ Compatibility Notes this should only impact users of other registries, or people who don't publish to a registry. [#12291](https://github.com/rust-lang/cargo/pull/12291) +- [Demoted `mips*-unknown-linux-gnu*` targets from host tier 2 to target tier 3 support.](https://github.com/rust-lang/rust/pull/113274) Version 1.71.1 (2023-08-03) =========================== diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index bf8a7eb293e0d..54274f153564b 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -11,6 +11,8 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(no_crate_inject, attr(deny(warnings))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(new_uninit)] diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index b07ed1d1c741e..ddc7c8ee82583 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -8,6 +8,9 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(deny(warnings))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(const_trait_impl)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index f6186a290f81f..b4728ac2aa67a 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,4 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 1b3f39e69e153..17556c45296ed 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,6 +5,9 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(lazy_cell)] #![feature(decl_macro)] #![feature(panic_update_hook)] diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 665b5d6adec37..63226504d370f 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -3,6 +3,8 @@ //! This module contains the code for creating and emitting diagnostics. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(array_windows)] #![feature(extract_if)] #![feature(if_let_guard)] diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index a01643cd67d2b..191fb787f706d 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -1,4 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 5d86d89581755..9cb279e3efdba 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -273,6 +273,9 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 03963925d3dbd..c7b3648099cc8 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -57,6 +57,9 @@ This API is completely unstable and subject to change. #![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(if_let_guard)] diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 220ea194a6de1..472dfe3dc4ace 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -2,6 +2,9 @@ #![deny(missing_docs)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(never_type)] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index e92ba05aa6739..4a6d1bc682b39 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -13,6 +13,9 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index af2132fb8997a..d7a666aa72ba1 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -27,6 +27,8 @@ #![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(array_windows)] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index eb70961503d1d..518c20c9fa8bf 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -1,6 +1,9 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] // NOTE: This crate only exists to allow linking on mingw targets. diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index fa77b36c4c556..ddeb39669dc7f 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,4 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(decl_macro)] #![feature(extract_if)] #![feature(generators)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index fe4fc3761b377..dee18dc11628c 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -23,6 +23,8 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(allocator_api)] #![feature(array_windows)] #![feature(assert_matches)] diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 90ac436a91f97..7b6153eea09b4 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -9,6 +9,9 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] // We want to be able to build this crate with a stable compiler, so no diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 52fb193f3da6b..fbf3dff756070 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1108,6 +1108,7 @@ impl CheckAttrVisitor<'_> { | sym::html_root_url | sym::html_no_source | sym::test + | sym::rust_logo if !self.check_attr_crate_level(attr, meta, hir_id) => { is_valid = false; @@ -1166,6 +1167,18 @@ impl CheckAttrVisitor<'_> { | sym::plugins | sym::fake_variadic => {} + sym::rust_logo => { + if !self.tcx.features().rustdoc_internals { + feature_err( + &self.tcx.sess.parse_sess, + sym::rustdoc_internals, + meta.span(), + "the `#[doc(rust_logo)]` attribute is used for Rust branding", + ) + .emit(); + } + } + sym::test => { if !self.check_test_attr(meta, hir_id) { is_valid = false; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 51f3c9ad76f16..946a9e68da6e0 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -6,6 +6,9 @@ #![allow(rustc::potential_query_instability)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(map_try_insert)] diff --git a/compiler/rustc_plugin_impl/src/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs index faa7495ef9fd1..0e1c80a1f64aa 100644 --- a/compiler/rustc_plugin_impl/src/lib.rs +++ b/compiler/rustc_plugin_impl/src/lib.rs @@ -7,6 +7,9 @@ //! of the Unstable Book for some examples. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ab85f680fcf9b..21d7bcbed5e40 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,4 +1,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(associated_type_defaults)] #![feature(rustc_private)] #![feature(try_blocks)] diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 30621a135ebc3..a1465dabed697 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -1,6 +1,8 @@ //! Support for serializing the dep-graph and reloading it. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] // this shouldn't be necessary, but the check for `&mut _` is too naive and denies returning a function pointer that takes a mut ref #![feature(const_mut_refs)] #![feature(const_refs_to_cell)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 5f012ec29fe00..0bc45967e3d8a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -7,6 +7,8 @@ //! Type-relative name resolution (methods, fields, associated items) happens in `rustc_hir_analysis`. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(extract_if)] diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 5360aa9ea6a94..cfa54072eb91b 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -5,6 +5,9 @@ html_playground_url = "https://play.rust-lang.org/", test(attr(allow(unused_variables), deny(warnings))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), allow(internal_features))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(allocator_api)] #![feature(associated_type_bounds)] #![feature(const_option)] diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 3e0d6baab6aab..2b77044d6bfc7 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] +rustc_data_structures = { path = "../rustc_data_structures" } rustc_driver = { path = "../rustc_driver" } rustc_hir = { path = "../rustc_hir" } rustc_interface = { path = "../rustc_interface" } diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index d10f46fad9e28..c24b9efe86545 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -10,6 +10,9 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] pub mod rustc_internal; diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 36eb2247253a0..e3c84f06543ed 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,24 +3,27 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use std::ops::{ControlFlow, Index}; - use crate::rustc_internal; use crate::rustc_smir::Tables; +use rustc_data_structures::fx; use rustc_driver::{Callbacks, Compilation, RunCompiler}; use rustc_interface::{interface, Queries}; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Span; +use stable_mir::ty::IndexedVal; use stable_mir::CompilerError; +use std::fmt::Debug; +use std::hash::Hash; +use std::ops::{ControlFlow, Index}; impl<'tcx> Index for Tables<'tcx> { type Output = DefId; #[inline(always)] fn index(&self, index: stable_mir::DefId) -> &Self::Output { - &self.def_ids[index.0] + &self.def_ids[index] } } @@ -29,7 +32,7 @@ impl<'tcx> Index for Tables<'tcx> { #[inline(always)] fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { - &self.spans[index.0] + &self.spans[index] } } @@ -95,36 +98,15 @@ impl<'tcx> Tables<'tcx> { } fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { - // FIXME: this becomes inefficient when we have too many ids - for (i, &d) in self.def_ids.iter().enumerate() { - if d == did { - return stable_mir::DefId(i); - } - } - let id = self.def_ids.len(); - self.def_ids.push(did); - stable_mir::DefId(id) + self.def_ids.create_or_fetch(did) } fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId { - // FIXME: this becomes inefficient when we have too many ids - if let Some(i) = self.alloc_ids.iter().position(|a| *a == aid) { - return stable_mir::AllocId(i); - }; - let id = self.def_ids.len(); - self.alloc_ids.push(aid); - stable_mir::AllocId(id) + self.alloc_ids.create_or_fetch(aid) } pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span { - for (i, &sp) in self.spans.iter().enumerate() { - if sp == span { - return stable_mir::ty::Span(i); - } - } - let id = self.spans.len(); - self.spans.push(span); - stable_mir::ty::Span(id) + self.spans.create_or_fetch(span) } } @@ -134,7 +116,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { stable_mir::run( - Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] }, + Tables { + tcx, + def_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() }, + alloc_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() }, + spans: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() }, + types: vec![], + }, f, ); } @@ -197,3 +185,29 @@ where }) } } + +/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra +/// safety features added. +pub struct IndexMap { + index_map: fx::FxIndexMap, +} + +impl IndexMap { + pub fn create_or_fetch(&mut self, key: K) -> V { + let len = self.index_map.len(); + let v = self.index_map.entry(key).or_insert(V::to_val(len)); + *v + } +} + +impl Index + for IndexMap +{ + type Output = K; + + fn index(&self, index: V) -> &Self::Output { + let (k, v) = self.index_map.get_index(index.to_index()).unwrap(); + assert_eq!(*v, index, "Provided value doesn't match with indexed value"); + k + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 0c474192240d4..2a265fc1f5bc0 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,6 +7,7 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. +use crate::rustc_internal::IndexMap; use crate::rustc_smir::hir::def::DefKind; use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region}; use rustc_hir as hir; @@ -201,9 +202,9 @@ impl PartialEq for MaybeStable { pub struct Tables<'tcx> { pub tcx: TyCtxt<'tcx>, - pub def_ids: Vec, - pub alloc_ids: Vec, - pub spans: Vec, + pub def_ids: IndexMap, + pub alloc_ids: IndexMap, + pub spans: IndexMap, pub types: Vec>>, } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 6fd61e45fcc9c..e62efab5793f2 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -14,6 +14,8 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(array_windows)] #![feature(if_let_guard)] #![feature(negative_impls)] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a62fa246ac41a..ea261923c6541 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1327,6 +1327,7 @@ symbols! { rust_cold_cc, rust_eh_catch_typeinfo, rust_eh_personality, + rust_logo, rustc, rustc_abi, rustc_allocator, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 535a3ea2d7e05..6ade2d777c741 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -88,6 +88,9 @@ //! DefPaths which are much more robust in the face of changes to the code base. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(never_type)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index e838e11131f60..9c5ce88941893 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -8,6 +8,8 @@ //! LLVM. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(assert_matches)] #![feature(associated_type_bounds)] #![feature(exhaustive_patterns)] diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 56d37d58de752..5ba29f878558f 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,6 +11,9 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 147b600f7ba52..1a9de1500415e 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -5,6 +5,9 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] +#![cfg_attr(not(bootstrap), allow(internal_features))] #![feature(assert_matches)] #![feature(iterator_try_collect)] #![feature(let_chains)] diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 79f598b6faac3..f371f46204fe4 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -22,7 +22,8 @@ use std::fmt; use std::fmt::Debug; use self::ty::{ - GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, + GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty, + TyKind, }; #[macro_use] @@ -41,7 +42,7 @@ pub type CrateNum = usize; /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq)] -pub struct DefId(pub usize); +pub struct DefId(usize); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -52,9 +53,28 @@ impl Debug for DefId { } } +impl IndexedVal for DefId { + fn to_val(index: usize) -> Self { + DefId(index) + } + + fn to_index(&self) -> usize { + self.0 + } +} + /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AllocId(pub usize); +pub struct AllocId(usize); + +impl IndexedVal for AllocId { + fn to_val(index: usize) -> Self { + AllocId(index) + } + fn to_index(&self) -> usize { + self.0 + } +} /// A list of crate items. pub type CrateItems = Vec; diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 6029e3c11adef..691af15da8ca8 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -75,7 +75,7 @@ pub struct Placeholder { } #[derive(Clone, Copy, PartialEq, Eq)] -pub struct Span(pub usize); +pub struct Span(usize); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -86,6 +86,15 @@ impl Debug for Span { } } +impl IndexedVal for Span { + fn to_val(index: usize) -> Self { + Span(index) + } + fn to_index(&self) -> usize { + self.0 + } +} + #[derive(Clone, Debug)] pub enum TyKind { RigidTy(RigidTy), @@ -565,3 +574,9 @@ pub enum ImplPolarity { Negative, Reservation, } + +pub trait IndexedVal { + fn to_val(index: usize) -> Self; + + fn to_index(&self) -> usize; +} diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 5481b327d691d..4bdd9639557d4 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -669,7 +669,7 @@ impl BTreeMap { /// map.insert(1, "a"); /// ``` #[unstable(feature = "btreemap_alloc", issue = "32838")] - pub fn new_in(alloc: A) -> BTreeMap { + pub const fn new_in(alloc: A) -> BTreeMap { BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(alloc), _marker: PhantomData } } } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 9da230915b822..0e03551286e8a 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -358,7 +358,7 @@ impl BTreeSet { /// let mut set: BTreeSet = BTreeSet::new_in(Global); /// ``` #[unstable(feature = "btreemap_alloc", issue = "32838")] - pub fn new_in(alloc: A) -> BTreeSet { + pub const fn new_in(alloc: A) -> BTreeSet { BTreeSet { map: BTreeMap::new_in(alloc) } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index cd3648214a48c..d47f9de941cc8 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -78,6 +78,8 @@ not(no_sync), target_has_atomic = "ptr" ))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![no_std] #![needs_allocator] // Lints: diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 7fa7e83a74429..906421327cbc5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -68,6 +68,7 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![doc(cfg_hide( not(test), any(not(feature = "miri-test-libstd"), test, doctest), diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 0a70c488aec91..991fdb1256de3 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -17,6 +17,8 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] // This library is copied into rust-analyzer to allow loading rustc compiled proc macros. // Please avoid unstable features where possible to minimize the amount of changes necessary // to make it compile with rust-analyzer on stable. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 02f4d5bc7ae14..aaf20875129c4 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -227,6 +227,7 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))) )] +#![cfg_attr(not(bootstrap), doc(rust_logo))] #![doc(cfg_hide( not(test), not(any(test, bootstrap)), diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 413f0fba34224..bddf75dffbb62 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -16,6 +16,8 @@ #![unstable(feature = "test", issue = "50297")] #![doc(test(attr(deny(warnings))))] +#![cfg_attr(not(bootstrap), doc(rust_logo))] +#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] #![feature(internal_output_capture)] #![feature(staged_api)] #![feature(process_exitcode_internals)] diff --git a/src/doc/reference b/src/doc/reference index 5262e1c3b43a2..142b2ed77d33f 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 5262e1c3b43a2c489df8f6717683a44c7a2260fd +Subproject commit 142b2ed77d33f37a9973772bd95e6144ed9dce43 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index c954202c1e172..8eb3a01ab74c5 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit c954202c1e1720cba5628f99543cc01188c7d6fc +Subproject commit 8eb3a01ab74c567b7174784892fb807f2c632d6b diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index a13b7c28ed705..b98af7d661e47 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit a13b7c28ed705891c681ce5417b3d1cdb12cecd1 +Subproject commit b98af7d661e4744baab81fb8dc7a049e44a4a998 diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 1fb5e56db5d76..d25fa661c3f3a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -286,6 +286,10 @@ target | std | host | notes `mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl libc `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) +`mips-unknown-linux-gnu` | MIPS Linux (kernel 4.4, glibc 2.23) +`mips64-unknown-linux-gnuabi64` | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23) +`mips64el-unknown-linux-gnuabi64` | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23) +`mipsel-unknown-linux-gnu` | MIPS (LE) Linux (kernel 4.4, glibc 2.23) `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat [`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 7473b09920fba..199b5d69a1c7c 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -207,6 +207,21 @@ To do so, the `#[doc(keyword = "...")]` attribute is used. Example: mod empty_mod {} ``` +### Use the Rust logo as the crate logo + +This is for official Rust project use only. + +Internal Rustdoc pages like settings.html and scrape-examples-help.html show the Rust logo. +This logo is tracked as a static resource. The attribute `#![doc(rust_logo)]` makes this same +built-in resource act as the main logo. + +```rust +#![feature(rustdoc_internals)] +#![allow(internal_features)] +#![doc(rust_logo)] +//! This crate has the Rust(tm) branding on it. +``` + ## Effects of other nightly features These nightly-only features are not primarily related to Rustdoc, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 4c6e7dfb9873b..b916baecc1407 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -223,17 +223,16 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // If the impl is from a masked crate or references something from a // masked crate then remove it completely. - if let clean::ImplItem(ref i) = *item.kind { - if self.cache.masked_crates.contains(&item.item_id.krate()) + if let clean::ImplItem(ref i) = *item.kind && + (self.cache.masked_crates.contains(&item.item_id.krate()) || i.trait_ .as_ref() .map_or(false, |t| self.cache.masked_crates.contains(&t.def_id().krate)) || i.for_ .def_id(self.cache) - .map_or(false, |d| self.cache.masked_crates.contains(&d.krate)) - { - return None; - } + .map_or(false, |d| self.cache.masked_crates.contains(&d.krate))) + { + return None; } // Propagate a trait method's documentation to all implementors of the @@ -334,33 +333,37 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // A crate has a module at its root, containing all items, // which should not be indexed. The crate-item itself is // inserted later on when serializing the search-index. - if item.item_id.as_def_id().map_or(false, |idx| !idx.is_crate_root()) { + if item.item_id.as_def_id().map_or(false, |idx| !idx.is_crate_root()) + && let ty = item.type_() + && (ty != ItemType::StructField + || u16::from_str_radix(s.as_str(), 10).is_err()) + { let desc = short_markdown_summary(&item.doc_value(), &item.link_names(self.cache)); - let ty = item.type_(); - if ty != ItemType::StructField - || u16::from_str_radix(s.as_str(), 10).is_err() - { - // In case this is a field from a tuple struct, we don't add it into - // the search index because its name is something like "0", which is - // not useful for rustdoc search. - self.cache.search_index.push(IndexItem { - ty, - name: s, - path: join_with_double_colon(path), - desc, - parent, - parent_idx: None, - search_type: get_function_type_for_search( - &item, - self.tcx, - clean_impl_generics(self.cache.parent_stack.last()).as_ref(), - self.cache, - ), - aliases: item.attrs.get_doc_aliases(), - deprecation: item.deprecation(self.tcx), - }); - } + // In case this is a field from a tuple struct, we don't add it into + // the search index because its name is something like "0", which is + // not useful for rustdoc search. + self.cache.search_index.push(IndexItem { + ty, + name: s, + path: join_with_double_colon(path), + desc, + parent, + parent_idx: None, + impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) = self.cache.parent_stack.last() { + item_id.as_def_id() + } else { + None + }, + search_type: get_function_type_for_search( + &item, + self.tcx, + clean_impl_generics(self.cache.parent_stack.last()).as_ref(), + self.cache, + ), + aliases: item.attrs.get_doc_aliases(), + deprecation: item.deprecation(self.tcx), + }); } } (Some(parent), None) if is_inherent_impl_item => { @@ -371,6 +374,13 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { parent, item: item.clone(), impl_generics, + impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) = + self.cache.parent_stack.last() + { + item_id.as_def_id() + } else { + None + }, }); } _ => {} @@ -541,6 +551,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { pub(crate) struct OrphanImplItem { pub(crate) parent: DefId, + pub(crate) impl_id: Option, pub(crate) item: clean::Item, pub(crate) impl_generics: Option<(clean::Type, clean::Generics)>, } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 8c5871d912647..d4b4db0f3fda6 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -17,6 +17,7 @@ pub(crate) struct Layout { pub(crate) external_html: ExternalHtml, pub(crate) default_settings: FxHashMap, pub(crate) krate: String, + pub(crate) krate_version: String, /// The given user css file which allow to customize the generated /// documentation theme. pub(crate) css_file_extension: Option, @@ -31,6 +32,7 @@ pub(crate) struct Page<'a> { pub(crate) static_root_path: Option<&'a str>, pub(crate) description: &'a str, pub(crate) resource_suffix: &'a str, + pub(crate) rust_logo: bool, } impl<'a> Page<'a> { @@ -54,9 +56,19 @@ struct PageLayout<'a> { themes: Vec, sidebar: String, content: String, - krate_with_trailing_slash: String, rust_channel: &'static str, pub(crate) rustdoc_version: &'a str, + // same as layout.krate, except on top-level pages like + // Settings, Help, All Crates, and About Scraped Examples, + // where these things instead give Rustdoc name and version. + // + // These are separate from the variables used for the search + // engine, because "Rustdoc" isn't necessarily a crate in + // the current workspace. + display_krate: &'a str, + display_krate_with_trailing_slash: String, + display_krate_version_number: &'a str, + display_krate_version_extra: &'a str, } pub(crate) fn render( @@ -66,12 +78,26 @@ pub(crate) fn render( t: T, style_files: &[StylePath], ) -> String { + let rustdoc_version = rustc_interface::util::version_str!().unwrap_or("unknown version"); + + let (display_krate, display_krate_version, display_krate_with_trailing_slash) = + if page.root_path == "./" { + // top level pages use Rust branding + ("Rustdoc", rustdoc_version, String::new()) + } else { + let display_krate_with_trailing_slash = + ensure_trailing_slash(&layout.krate).to_string(); + (&layout.krate[..], &layout.krate_version[..], display_krate_with_trailing_slash) + }; let static_root_path = page.get_static_root_path(); - let krate_with_trailing_slash = ensure_trailing_slash(&layout.krate).to_string(); + + // bootstrap passes in parts of the version separated by tabs, but other stuff might use spaces + let (display_krate_version_number, display_krate_version_extra) = + display_krate_version.split_once([' ', '\t']).unwrap_or((display_krate_version, "")); + let mut themes: Vec = style_files.iter().map(|s| s.basename().unwrap()).collect(); themes.sort(); - let rustdoc_version = rustc_interface::util::version_str!().unwrap_or("unknown version"); let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar. let sidebar = Buffer::html().to_display(sidebar); PageLayout { @@ -82,7 +108,10 @@ pub(crate) fn render( themes, sidebar, content, - krate_with_trailing_slash, + display_krate, + display_krate_with_trailing_slash, + display_krate_version_number, + display_krate_version_extra, rust_channel: *crate::clean::utils::DOC_CHANNEL, rustdoc_version, } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 97714afaa4587..bf8d1a80337e8 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -24,6 +24,7 @@ use super::{ sidebar::{sidebar_module_like, Sidebar}, AllTypes, LinkFromSrc, StylePath, }; +use crate::clean::utils::has_doc_flag; use crate::clean::{self, types::ExternalLocation, ExternalCrate, TypeAliasItem}; use crate::config::{ModuleSorting, RenderOptions}; use crate::docfs::{DocFS, PathError}; @@ -277,6 +278,7 @@ impl<'tcx> Context<'tcx> { title: &title, description: &desc, resource_suffix: &clone_shared.resource_suffix, + rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), }; let mut page_buffer = Buffer::html(); print_item(self, it, &mut page_buffer, &page); @@ -528,12 +530,14 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { if let Some(url) = playground_url { playground = Some(markdown::Playground { crate_name: Some(krate.name(tcx)), url }); } + let krate_version = cache.crate_version.as_deref().unwrap_or_default(); let mut layout = layout::Layout { logo: String::new(), favicon: String::new(), external_html, default_settings, krate: krate.name(tcx).to_string(), + krate_version: krate_version.to_string(), css_file_extension: extension_css, scrape_examples_extension: !call_locations.is_empty(), }; @@ -658,21 +662,22 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { let shared = Rc::clone(&self.shared); let mut page = layout::Page { title: "List of all items in this crate", - css_class: "mod", + css_class: "mod sys", root_path: "../", static_root_path: shared.static_root_path.as_deref(), description: "List of all items in this crate", resource_suffix: &shared.resource_suffix, + rust_logo: has_doc_flag(self.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), }; let all = shared.all.replace(AllTypes::new()); let mut sidebar = Buffer::html(); let blocks = sidebar_module_like(all.item_sections()); let bar = Sidebar { - title_prefix: "Crate ", - title: crate_name.as_str(), + title_prefix: "", + title: "", is_crate: false, - version: "", + is_mod: false, blocks: vec![blocks], path: String::new(), }; @@ -689,9 +694,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared.fs.write(final_file, v)?; // Generating settings page. - page.title = "Rustdoc settings"; + page.title = "Settings"; page.description = "Settings of Rustdoc"; page.root_path = "./"; + page.rust_logo = true; let sidebar = "

Settings

"; let v = layout::render( @@ -739,9 +745,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { shared.fs.write(settings_file, v)?; // Generating help page. - page.title = "Rustdoc help"; + page.title = "Help"; page.description = "Documentation for Rustdoc"; page.root_path = "./"; + page.rust_logo = true; let sidebar = "

Help

"; let v = layout::render( diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 3e671a64b54f7..49817f5eb6457 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -54,7 +54,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::Mutability; use rustc_middle::middle::stability; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{ symbol::{sym, Symbol}, BytePos, FileName, RealFileName, @@ -102,6 +102,7 @@ pub(crate) struct IndexItem { pub(crate) desc: String, pub(crate) parent: Option, pub(crate) parent_idx: Option, + pub(crate) impl_id: Option, pub(crate) search_type: Option, pub(crate) aliases: Box<[Symbol]>, pub(crate) deprecation: Option, @@ -1877,7 +1878,7 @@ pub(crate) fn render_impl_summary( aliases: &[String], ) { let inner_impl = i.inner_impl(); - let id = cx.derive_id(get_id_for_impl(&inner_impl.for_, inner_impl.trait_.as_ref(), cx)); + let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); let aliases = if aliases.is_empty() { String::new() } else { @@ -1994,21 +1995,35 @@ pub(crate) fn small_url_encode(s: String) -> String { } } -fn get_id_for_impl(for_: &clean::Type, trait_: Option<&clean::Path>, cx: &Context<'_>) -> String { - match trait_ { - Some(t) => small_url_encode(format!("impl-{:#}-for-{:#}", t.print(cx), for_.print(cx))), - None => small_url_encode(format!("impl-{:#}", for_.print(cx))), - } +fn get_id_for_impl<'tcx>(tcx: TyCtxt<'tcx>, impl_id: ItemId) -> String { + use rustc_middle::ty::print::with_forced_trimmed_paths; + let (type_, trait_) = match impl_id { + ItemId::Auto { trait_, for_ } => { + let ty = tcx.type_of(for_).skip_binder(); + (ty, Some(ty::TraitRef::new(tcx, trait_, [ty]))) + } + ItemId::Blanket { impl_id, .. } | ItemId::DefId(impl_id) => { + match tcx.impl_subject(impl_id).skip_binder() { + ty::ImplSubject::Trait(trait_ref) => { + (trait_ref.args[0].expect_ty(), Some(trait_ref)) + } + ty::ImplSubject::Inherent(ty) => (ty, None), + } + } + }; + with_forced_trimmed_paths!(small_url_encode(if let Some(trait_) = trait_ { + format!("impl-{trait_}-for-{type_}", trait_ = trait_.print_only_trait_path()) + } else { + format!("impl-{type_}") + })) } fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> { match *item.kind { - clean::ItemKind::ImplItem(ref i) => { - i.trait_.as_ref().map(|trait_| { - // Alternative format produces no URLs, - // so this parameter does nothing. - (format!("{:#}", i.for_.print(cx)), get_id_for_impl(&i.for_, Some(trait_), cx)) - }) + clean::ItemKind::ImplItem(ref i) if i.trait_.is_some() => { + // Alternative format produces no URLs, + // so this parameter does nothing. + Some((format!("{:#}", i.for_.print(cx)), get_id_for_impl(cx.tcx(), item.item_id))) } _ => None, } @@ -2079,6 +2094,7 @@ impl ItemSection { const ALL: &'static [Self] = { use ItemSection::*; // NOTE: The order here affects the order in the UI. + // Keep this synchronized with addSidebarItems in main.js &[ Reexports, PrimitiveTypes, diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 78c443b2257d0..af1dab5949613 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -12,7 +12,7 @@ use crate::formats::cache::{Cache, OrphanImplItem}; use crate::formats::item_type::ItemType; use crate::html::format::join_with_double_colon; use crate::html::markdown::short_markdown_summary; -use crate::html::render::{IndexItem, IndexItemFunctionType, RenderType, RenderTypeId}; +use crate::html::render::{self, IndexItem, IndexItemFunctionType, RenderType, RenderTypeId}; /// Builds the search index from the collected metadata pub(crate) fn build_index<'tcx>( @@ -26,7 +26,8 @@ pub(crate) fn build_index<'tcx>( // Attach all orphan items to the type's definition if the type // has since been learned. - for &OrphanImplItem { parent, ref item, ref impl_generics } in &cache.orphan_impl_items { + for &OrphanImplItem { impl_id, parent, ref item, ref impl_generics } in &cache.orphan_impl_items + { if let Some((fqp, _)) = cache.paths.get(&parent) { let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache)); cache.search_index.push(IndexItem { @@ -36,6 +37,7 @@ pub(crate) fn build_index<'tcx>( desc, parent: Some(parent), parent_idx: None, + impl_id, search_type: get_function_type_for_search(item, tcx, impl_generics.as_ref(), cache), aliases: item.attrs.get_doc_aliases(), deprecation: item.deprecation(tcx), @@ -222,6 +224,29 @@ pub(crate) fn build_index<'tcx>( }) .collect(); + // Find associated items that need disambiguators + let mut associated_item_duplicates = FxHashMap::<(isize, ItemType, Symbol), usize>::default(); + + for &item in &crate_items { + if item.impl_id.is_some() && let Some(parent_idx) = item.parent_idx { + let count = associated_item_duplicates + .entry((parent_idx, item.ty, item.name)) + .or_insert(0); + *count += 1; + } + } + + let associated_item_disambiguators = crate_items + .iter() + .enumerate() + .filter_map(|(index, item)| { + let impl_id = ItemId::DefId(item.impl_id?); + let parent_idx = item.parent_idx?; + let count = *associated_item_duplicates.get(&(parent_idx, item.ty, item.name))?; + if count > 1 { Some((index, render::get_id_for_impl(tcx, impl_id))) } else { None } + }) + .collect::>(); + struct CrateData<'a> { doc: String, items: Vec<&'a IndexItem>, @@ -230,6 +255,8 @@ pub(crate) fn build_index<'tcx>( // // To be noted: the `usize` elements are indexes to `items`. aliases: &'a BTreeMap>, + // Used when a type has more than one impl with an associated item with the same name. + associated_item_disambiguators: &'a Vec<(usize, String)>, } struct Paths { @@ -382,6 +409,7 @@ pub(crate) fn build_index<'tcx>( crate_data.serialize_field("f", &functions)?; crate_data.serialize_field("c", &deprecated)?; crate_data.serialize_field("p", &paths)?; + crate_data.serialize_field("b", &self.associated_item_disambiguators)?; if has_aliases { crate_data.serialize_field("a", &self.aliases)?; } @@ -398,6 +426,7 @@ pub(crate) fn build_index<'tcx>( items: crate_items, paths: crate_paths, aliases: &aliases, + associated_item_disambiguators: &associated_item_disambiguators, }) .expect("failed serde conversion") // All these `replace` calls are because we have to go through JS string for JSON content. diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 76f63c6f63e36..fb429f237e3db 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -19,7 +19,7 @@ pub(super) struct Sidebar<'a> { pub(super) title_prefix: &'static str, pub(super) title: &'a str, pub(super) is_crate: bool, - pub(super) version: &'a str, + pub(super) is_mod: bool, pub(super) blocks: Vec>, pub(super) path: String, } @@ -99,12 +99,12 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf || it.is_primitive() || it.is_union() || it.is_enum() - || it.is_mod() + // crate title is displayed as part of logo lockup + || (it.is_mod() && !it.is_crate()) || it.is_type_alias() { ( match *it.kind { - clean::ModuleItem(..) if it.is_crate() => "Crate ", clean::ModuleItem(..) => "Module ", _ => "", }, @@ -113,14 +113,22 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf } else { ("", "") }; - let version = - if it.is_crate() { cx.cache().crate_version.as_deref().unwrap_or_default() } else { "" }; - let path: String = if !it.is_mod() { - cx.current.iter().map(|s| s.as_str()).intersperse("::").collect() + // need to show parent path header if: + // - it's a child module, instead of the crate root + // - there's a sidebar section for the item itself + // + // otherwise, the parent path header is redundant with the big crate + // branding area at the top of the sidebar + let sidebar_path = + if it.is_mod() { &cx.current[..cx.current.len() - 1] } else { &cx.current[..] }; + let path: String = if sidebar_path.len() > 1 || !title.is_empty() { + let path = sidebar_path.iter().map(|s| s.as_str()).intersperse("::").collect(); + if sidebar_path.len() == 1 { format!("crate {path}") } else { path } } else { "".into() }; - let sidebar = Sidebar { title_prefix, title, is_crate: it.is_crate(), version, blocks, path }; + let sidebar = + Sidebar { title_prefix, title, is_mod: it.is_mod(), is_crate: it.is_crate(), blocks, path }; sidebar.render_into(buffer).unwrap(); } @@ -503,8 +511,7 @@ fn sidebar_render_assoc_items( .iter() .filter_map(|it| { let trait_ = it.inner_impl().trait_.as_ref()?; - let encoded = - id_map.derive(super::get_id_for_impl(&it.inner_impl().for_, Some(trait_), cx)); + let encoded = id_map.derive(super::get_id_for_impl(cx.tcx(), it.impl_item.item_id)); let prefix = match it.inner_impl().polarity { ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index e824651e727df..e68d5ab2fbdb5 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -336,11 +336,12 @@ if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; let dst = cx.dst.join("index.html"); let page = layout::Page { title: "Index of crates", - css_class: "mod", + css_class: "mod sys", root_path: "./", static_root_path: shared.static_root_path.as_deref(), description: "List of crates", resource_suffix: &shared.resource_suffix, + rust_logo: true, }; let content = format!( diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 1d6eafe51b95d..4a218b9b37cb1 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -1,4 +1,5 @@ use crate::clean; +use crate::clean::utils::has_doc_flag; use crate::docfs::PathError; use crate::error::Error; use crate::html::format; @@ -13,6 +14,7 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::source_map::FileName; +use rustc_span::sym; use std::cell::RefCell; use std::ffi::OsStr; @@ -231,6 +233,7 @@ impl SourceCollector<'_, '_> { static_root_path: shared.static_root_path.as_deref(), description: &desc, resource_suffix: &shared.resource_suffix, + rust_logo: has_doc_flag(self.cx.tcx(), LOCAL_CRATE.as_def_id(), sym::rust_logo), }; let v = layout::render( &shared.layout, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 47f9e65028118..e2b4cc50dd580 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -461,19 +461,9 @@ img { display: none !important; } -.sidebar .logo-container { - margin-top: 10px; - margin-bottom: 10px; - text-align: center; -} - -.version { - overflow-wrap: break-word; -} - .logo-container > img { - height: 100px; - width: 100px; + height: 48px; + width: 48px; } ul.block, .block li { @@ -502,6 +492,7 @@ ul.block, .block li { } .sidebar-elems, +.sidebar > .version, .sidebar > h2 { padding-left: 24px; } @@ -510,6 +501,8 @@ ul.block, .block li { color: var(--sidebar-link-color); } .sidebar .current, +.sidebar .current a, +.sidebar-crate a.logo-container:hover + h2 a, .sidebar a:hover:not(.logo-container) { background-color: var(--sidebar-current-link-background-color); } @@ -524,6 +517,75 @@ ul.block, .block li { overflow: hidden; } +.sidebar-crate { + display: flex; + align-items: center; + justify-content: center; + /* there's a 10px padding at the top of
, and a 4px margin at the + top of the search form. To line them up, add them. */ + margin: 14px 32px 1rem; + row-gap: 10px; + column-gap: 32px; + flex-wrap: wrap; +} + +.sidebar-crate h2 { + flex-grow: 1; + /* This setup with the margins and row-gap is designed to make flex-wrap + work the way we want. If they're in the side-by-side lockup, there + should be a 16px margin to the left of the logo (visually the same as + the 24px one on everything else, which are not giant circles) and 8px + between it and the crate's name and version. When they're line wrapped, + the logo needs to have the same margin on both sides of itself (to + center properly) and the crate name and version need 24px on their + left margin. */ + margin: 0 -8px; + /* To align this with the search bar, it should not be centered, even when + the logo is. */ + align-self: start; +} + +.sidebar-crate .logo-container { + /* The logo is expected to have 8px "slop" along its edges, so we can optically + center it. */ + margin: 0 -16px 0 -16px; + text-align: center; +} + +.sidebar-crate h2 a { + display: block; + margin: 0 calc(-24px + 0.25rem) 0 -0.5rem; + /* Align the sidebar crate link with the search bar, which have different + font sizes. + + | | font-size | line-height | total line-height | padding-y | total | + |:-------|----------:|------------:|------------------:|----------:|-------------:| + | crate | 1.375rem | 1.25 | 1.72rem | x | 2x+1.72rem | + | search | 1rem | 1.15 | 1.15rem | 8px | 1.15rem+16px | + + 2x + 1.72rem = 1.15rem + 16px + 2x = 1.15rem + 16px - 1.72rem + 2x = 16px - 0.57rem + x = ( 16px - 0.57rem ) / 2 + */ + padding: calc( ( 16px - 0.57rem ) / 2 ) 0.25rem; + padding-left: 0.5rem; +} + +.sidebar-crate h2 .version { + display: block; + font-weight: normal; + font-size: 1rem; + overflow-wrap: break-word; + /* opposite of the link padding, cut in half again */ + margin-top: calc( ( -16px + 0.57rem ) / 2 ); +} + +.sidebar-crate + .version { + margin-top: -1rem; + margin-bottom: 1rem; +} + .mobile-topbar { display: none; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index eb256455b0878..2e9897ef82ba2 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -51,9 +51,14 @@ function setMobileTopbar() { // but with the current code it's hard to get the right information in the right place. const mobileTopbar = document.querySelector(".mobile-topbar"); const locationTitle = document.querySelector(".sidebar h2.location"); - if (mobileTopbar && locationTitle) { + if (mobileTopbar) { const mobileTitle = document.createElement("h2"); - mobileTitle.innerHTML = locationTitle.innerHTML; + mobileTitle.className = "location"; + if (hasClass(document.body, "crate")) { + mobileTitle.innerText = `Crate ${window.currentCrate}`; + } else if (locationTitle) { + mobileTitle.innerHTML = locationTitle.innerHTML; + } mobileTopbar.appendChild(mobileTitle); } } @@ -354,6 +359,34 @@ function preLoadCss(cssUrl) { expandSection(pageId); } } + if (savedHash.startsWith("impl-")) { + // impl-disambiguated links, used by the search engine + // format: impl-X[-for-Y]/method.WHATEVER + // turn this into method.WHATEVER[-NUMBER] + const splitAt = savedHash.indexOf("/"); + if (splitAt !== -1) { + const implId = savedHash.slice(0, splitAt); + const assocId = savedHash.slice(splitAt + 1); + const implElem = document.getElementById(implId); + if (implElem && implElem.parentElement.tagName === "SUMMARY" && + implElem.parentElement.parentElement.tagName === "DETAILS") { + onEachLazy(implElem.parentElement.parentElement.querySelectorAll( + `[id^="${assocId}"]`), + item => { + const numbered = /([^-]+)-([0-9]+)/.exec(item.id); + if (item.id === assocId || (numbered && numbered[1] === assocId)) { + openParentDetails(item); + item.scrollIntoView(); + // Let the section expand itself before trying to highlight + setTimeout(() => { + window.location.replace("#" + item.id); + }, 0); + } + } + ); + } + } + } } function onHashChange(ev) { @@ -452,22 +485,27 @@ function preLoadCss(cssUrl) { return; } + const modpath = hasClass(document.body, "mod") ? "../" : ""; + const h3 = document.createElement("h3"); - h3.innerHTML = `${longty}`; + h3.innerHTML = `${longty}`; const ul = document.createElement("ul"); ul.className = "block " + shortty; for (const name of filtered) { let path; if (shortty === "mod") { - path = name + "/index.html"; + path = `${modpath}${name}/index.html`; } else { - path = shortty + "." + name + ".html"; + path = `${modpath}${shortty}.${name}.html`; + } + let current_page = document.location.href.toString(); + if (current_page.endsWith("/")) { + current_page += "index.html"; } - const current_page = document.location.href.split("/").pop(); const link = document.createElement("a"); link.href = path; - if (path === current_page) { + if (link.href === current_page) { link.className = "current"; } link.textContent = name; @@ -480,19 +518,33 @@ function preLoadCss(cssUrl) { } if (sidebar) { + // keep this synchronized with ItemSection::ALL in html/render/mod.rs + // Re-exports aren't shown here, because they don't have child pages + //block("reexport", "reexports", "Re-exports"); block("primitive", "primitives", "Primitive Types"); block("mod", "modules", "Modules"); block("macro", "macros", "Macros"); block("struct", "structs", "Structs"); block("enum", "enums", "Enums"); - block("union", "unions", "Unions"); block("constant", "constants", "Constants"); block("static", "static", "Statics"); block("trait", "traits", "Traits"); block("fn", "functions", "Functions"); block("type", "types", "Type Aliases"); + block("union", "unions", "Unions"); + // No point, because these items don't appear in modules + //block("impl", "impls", "Implementations"); + //block("tymethod", "tymethods", "Type Methods"); + //block("method", "methods", "Methods"); + //block("structfield", "fields", "Fields"); + //block("variant", "variants", "Variants"); + //block("associatedtype", "associated-types", "Associated Types"); + //block("associatedconstant", "associated-consts", "Associated Constants"); block("foreigntype", "foreign-types", "Foreign Types"); block("keyword", "keywords", "Keywords"); + block("opaque", "opaque-types", "Opaque Types"); + block("attr", "attributes", "Attribute Macros"); + block("derive", "derives", "Derive Macros"); block("traitalias", "trait-aliases", "Trait Aliases"); } } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 7a282a99e9ce9..48c9a53a28310 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1752,6 +1752,7 @@ function initSearch(rawSearchIndex) { type: item.type, is_alias: true, deprecated: item.deprecated, + implDisambiguator: item.implDisambiguator, }; } @@ -2218,7 +2219,7 @@ function initSearch(rawSearchIndex) { href = ROOT_PATH + name + "/index.html"; } else if (item.parent !== undefined) { const myparent = item.parent; - let anchor = "#" + type + "." + name; + let anchor = type + "." + name; const parentType = itemTypes[myparent.ty]; let pageType = parentType; let pageName = myparent.name; @@ -2232,16 +2233,19 @@ function initSearch(rawSearchIndex) { const enumName = item.path.substr(enumNameIdx + 2); path = item.path.substr(0, enumNameIdx); displayPath = path + "::" + enumName + "::" + myparent.name + "::"; - anchor = "#variant." + myparent.name + ".field." + name; + anchor = "variant." + myparent.name + ".field." + name; pageType = "enum"; pageName = enumName; } else { displayPath = path + "::" + myparent.name + "::"; } + if (item.implDisambiguator !== null) { + anchor = item.implDisambiguator + "/" + anchor; + } href = ROOT_PATH + path.replace(/::/g, "/") + "/" + pageType + "." + pageName + - ".html" + anchor; + ".html#" + anchor; } else { displayPath = item.path + "::"; href = ROOT_PATH + item.path.replace(/::/g, "/") + @@ -2727,6 +2731,10 @@ ${item.displayPath}${name}\ * Types are also represented as arrays; the first item is an index into the `p` * array, while the second is a list of types representing any generic parameters. * + * b[i] contains an item's impl disambiguator. This is only present if an item + * is defined in an impl block and, the impl block's type has more than one associated + * item with the same name. + * * `a` defines aliases with an Array of pairs: [name, offset], where `offset` * points into the n/t/d/q/i/f arrays. * @@ -2746,6 +2754,7 @@ ${item.displayPath}${name}\ * i: Array, * f: Array, * p: Array, + * b: Array<[Number, String]>, * c: Array * }} */ @@ -2766,6 +2775,7 @@ ${item.displayPath}${name}\ id: id, normalizedName: crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, ""), deprecated: null, + implDisambiguator: null, }; id += 1; searchIndex.push(crateRow); @@ -2789,6 +2799,8 @@ ${item.displayPath}${name}\ const itemFunctionSearchTypes = crateCorpus.f; // an array of (Number) indices for the deprecated items const deprecatedItems = new Set(crateCorpus.c); + // an array of (Number) indices for the deprecated items + const implDisambiguator = new Map(crateCorpus.b); // an array of [(Number) item type, // (String) name] const paths = crateCorpus.p; @@ -2849,6 +2861,7 @@ ${item.displayPath}${name}\ id: id, normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), deprecated: deprecatedItems.has(i), + implDisambiguator: implDisambiguator.has(i) ? implDisambiguator.get(i) : null, }; id += 1; searchIndex.push(row); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 579c782be0975..ebf817673bfef 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -42,6 +42,8 @@ {# #} {% else if !page.css_class.contains("mod") %} {# #} + {% else if !page.css_class.contains("sys") %} + {# #} {% endif %} {# #} {% if layout.scrape_examples_extension %} @@ -77,36 +79,51 @@ {% if page.css_class != "src" %} {% endif %} {# #}
{# #} {% if page.css_class != "src" %}
{% endif %}