diff options
| author | bors <bors@rust-lang.org> | 2023-03-10 08:09:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-03-10 08:09:25 +0000 |
| commit | 104f4300cfddbd956e32820ef202a732f06ec848 (patch) | |
| tree | 556e5ecc43e89550c7d8b8f3d82454197f391d79 /src | |
| parent | f37f8549940386a9d066ba199983affff47afbb4 (diff) | |
| parent | 5b3f84d8af3668944f25b542d2f71f88f253ecc0 (diff) | |
| download | rust-104f4300cfddbd956e32820ef202a732f06ec848.tar.gz rust-104f4300cfddbd956e32820ef202a732f06ec848.zip | |
Auto merge of #108934 - matthiaskrgr:rollup-vm414p5, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #106915 (Only load one CSS theme by default) - #108294 (Place binder correctly for arbitrary trait bound suggestion) - #108778 (x fmt: Don't print all modified files if there's more than 10) - #108854 (feat/refactor: improve errors in case of ident with number at start) - #108870 (Fix invalid inlining of reexport of reexport of private item) - #108917 (Consider target_family as pal) - #108922 (Add auto notification for changes to stable mir) - #108929 (Fix typo in span_map.rs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'src')
| -rw-r--r-- | src/bootstrap/format.rs | 8 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 108 | ||||
| -rw-r--r-- | src/librustdoc/html/render/context.rs | 28 | ||||
| -rw-r--r-- | src/librustdoc/html/render/span_map.rs | 6 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/main.js | 39 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/storage.js | 47 | ||||
| -rw-r--r-- | src/librustdoc/html/templates/page.html | 39 | ||||
| -rw-r--r-- | src/librustdoc/visit_ast.rs | 20 | ||||
| -rw-r--r-- | src/tools/tidy/src/pal.rs | 3 |
9 files changed, 198 insertions, 100 deletions
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 5cb94c2f1d6..b79969663ca 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -165,8 +165,14 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { if !CiEnv::is_ci() && paths.is_empty() { match get_modified_rs_files(build) { Ok(Some(files)) => { + if files.len() <= 10 { + for file in &files { + println!("formatting modified file {file}"); + } + } else { + println!("formatting {} modified files", files.len()); + } for file in files { - println!("formatting modified file {file}"); ignore_fmt.add(&format!("/{file}")).expect(&file); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bbd9f18973a..29c3afe0d95 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2065,23 +2065,81 @@ fn clean_bare_fn_ty<'tcx>( BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params } } -/// This visitor is used to go through only the "top level" of a item and not enter any sub -/// item while looking for a given `Ident` which is stored into `item` if found. -struct OneLevelVisitor<'hir> { +/// Get DefId of of an item's user-visible parent. +/// +/// "User-visible" should account for re-exporting and inlining, which is why this function isn't +/// just `tcx.parent(def_id)`. If the provided `path` has more than one path element, the `DefId` +/// of the second-to-last will be given. +/// +/// ```text +/// use crate::foo::Bar; +/// ^^^ DefId of this item will be returned +/// ``` +/// +/// If the provided path has only one item, `tcx.parent(def_id)` will be returned instead. +fn get_path_parent_def_id( + tcx: TyCtxt<'_>, + def_id: DefId, + path: &hir::UsePath<'_>, +) -> Option<DefId> { + if let [.., parent_segment, _] = &path.segments { + match parent_segment.res { + hir::def::Res::Def(_, parent_def_id) => Some(parent_def_id), + _ if parent_segment.ident.name == kw::Crate => { + // In case the "parent" is the crate, it'll give `Res::Err` so we need to + // circumvent it this way. + Some(tcx.parent(def_id)) + } + _ => None, + } + } else { + // If the path doesn't have a parent, then the parent is the current module. + Some(tcx.parent(def_id)) + } +} + +/// This visitor is used to find an HIR Item based on its `use` path. This doesn't use the ordinary +/// name resolver because it does not walk all the way through a chain of re-exports. +pub(crate) struct OneLevelVisitor<'hir> { map: rustc_middle::hir::map::Map<'hir>, - item: Option<&'hir hir::Item<'hir>>, + pub(crate) item: Option<&'hir hir::Item<'hir>>, looking_for: Ident, target_def_id: LocalDefId, } impl<'hir> OneLevelVisitor<'hir> { - fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self { + pub(crate) fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self { Self { map, item: None, looking_for: Ident::empty(), target_def_id } } - fn reset(&mut self, looking_for: Ident) { - self.looking_for = looking_for; + pub(crate) fn find_target( + &mut self, + tcx: TyCtxt<'_>, + def_id: DefId, + path: &hir::UsePath<'_>, + ) -> Option<&'hir hir::Item<'hir>> { + let parent_def_id = get_path_parent_def_id(tcx, def_id, path)?; + let parent = self.map.get_if_local(parent_def_id)?; + + // We get the `Ident` we will be looking for into `item`. + self.looking_for = path.segments[path.segments.len() - 1].ident; + // We reset the `item`. self.item = None; + + match parent { + hir::Node::Item(parent_item) => { + hir::intravisit::walk_item(self, parent_item); + } + hir::Node::Crate(m) => { + hir::intravisit::walk_mod( + self, + m, + tcx.local_def_id_to_hir_id(parent_def_id.as_local().unwrap()), + ); + } + _ => return None, + } + self.item } } @@ -2129,41 +2187,7 @@ fn get_all_import_attributes<'hir>( add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); } - let def_id = if let [.., parent_segment, _] = &path.segments { - match parent_segment.res { - hir::def::Res::Def(_, def_id) => def_id, - _ if parent_segment.ident.name == kw::Crate => { - // In case the "parent" is the crate, it'll give `Res::Err` so we need to - // circumvent it this way. - tcx.parent(item.owner_id.def_id.to_def_id()) - } - _ => break, - } - } else { - // If the path doesn't have a parent, then the parent is the current module. - tcx.parent(item.owner_id.def_id.to_def_id()) - }; - - let Some(parent) = hir_map.get_if_local(def_id) else { break }; - - // We get the `Ident` we will be looking for into `item`. - let looking_for = path.segments[path.segments.len() - 1].ident; - visitor.reset(looking_for); - - match parent { - hir::Node::Item(parent_item) => { - hir::intravisit::walk_item(&mut visitor, parent_item); - } - hir::Node::Crate(m) => { - hir::intravisit::walk_mod( - &mut visitor, - m, - tcx.local_def_id_to_hir_id(def_id.as_local().unwrap()), - ); - } - _ => break, - } - if let Some(i) = visitor.item { + if let Some(i) = visitor.find_target(tcx, item.owner_id.def_id.to_def_id(), path) { item = i; } else { break; diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 1030fe74747..ed1eb66b97c 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -647,11 +647,35 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { </noscript>\ <link rel=\"stylesheet\" \ href=\"{static_root_path}{settings_css}\">\ - <script defer src=\"{static_root_path}{settings_js}\"></script>", + <script defer src=\"{static_root_path}{settings_js}\"></script>\ + <link rel=\"preload\" href=\"{static_root_path}{theme_light_css}\" \ + as=\"style\">\ + <link rel=\"preload\" href=\"{static_root_path}{theme_dark_css}\" \ + as=\"style\">\ + <link rel=\"preload\" href=\"{static_root_path}{theme_ayu_css}\" \ + as=\"style\">", static_root_path = page.get_static_root_path(), settings_css = static_files::STATIC_FILES.settings_css, settings_js = static_files::STATIC_FILES.settings_js, - ) + theme_light_css = static_files::STATIC_FILES.theme_light_css, + theme_dark_css = static_files::STATIC_FILES.theme_dark_css, + theme_ayu_css = static_files::STATIC_FILES.theme_ayu_css, + ); + // Pre-load all theme CSS files, so that switching feels seamless. + // + // When loading settings.html as a popover, the equivalent HTML is + // generated in main.js. + for file in &shared.style_files { + if let Ok(theme) = file.basename() { + write!( + buf, + "<link rel=\"preload\" href=\"{root_path}{theme}{suffix}.css\" \ + as=\"style\">", + root_path = page.static_root_path.unwrap_or(""), + suffix = page.resource_suffix, + ); + } + } }, &shared.style_files, ); diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 4514894cabe..eb9262f472b 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -29,12 +29,12 @@ pub(crate) enum LinkFromSrc { /// This function will do at most two things: /// -/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`. +/// 1. Generate a `span` correspondence map which links an item `span` to its definition `span`. /// 2. Collect the source code files. /// -/// It returns the `krate`, the source code files and the `span` correspondance map. +/// It returns the `krate`, the source code files and the `span` correspondence map. /// -/// Note about the `span` correspondance map: the keys are actually `(lo, hi)` of `span`s. We don't +/// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't /// need the `span` context later on, only their position, so instead of keep a whole `Span`, we /// only keep the `lo` and `hi`. pub(crate) fn collect_spans_and_sources( diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 5e8c0e8d10c..403b5004d65 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,20 +1,9 @@ // Local js definitions: /* global addClass, getSettingValue, hasClass, searchState */ -/* global onEach, onEachLazy, removeClass */ +/* global onEach, onEachLazy, removeClass, getVar */ "use strict"; -// Get a value from the rustdoc-vars div, which is used to convey data from -// Rust to the JS. If there is no such element, return null. -function getVar(name) { - const el = document.getElementById("rustdoc-vars"); - if (el) { - return el.attributes["data-" + name].value; - } else { - return null; - } -} - // Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL // for a resource under the root-path, with the resource-suffix. function resourcePath(basename, extension) { @@ -187,6 +176,15 @@ function loadCss(cssUrl) { document.getElementsByTagName("head")[0].appendChild(link); } +function preLoadCss(cssUrl) { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload + const link = document.createElement("link"); + link.href = cssUrl; + link.rel = "preload"; + link.as = "style"; + document.getElementsByTagName("head")[0].appendChild(link); +} + (function() { const isHelpPage = window.location.pathname.endsWith("/help.html"); @@ -207,6 +205,23 @@ function loadCss(cssUrl) { // hopefully be loaded when the JS will generate the settings content. loadCss(getVar("static-root-path") + getVar("settings-css")); loadScript(getVar("static-root-path") + getVar("settings-js")); + preLoadCss(getVar("static-root-path") + getVar("theme-light-css")); + preLoadCss(getVar("static-root-path") + getVar("theme-dark-css")); + preLoadCss(getVar("static-root-path") + getVar("theme-ayu-css")); + // Pre-load all theme CSS files, so that switching feels seamless. + // + // When loading settings.html as a standalone page, the equivalent HTML is + // generated in context.rs. + setTimeout(() => { + const themes = getVar("themes").split(","); + for (const theme of themes) { + // if there are no themes, do nothing + // "".split(",") == [""] + if (theme !== "") { + preLoadCss(getVar("root-path") + theme + ".css"); + } + } + }, 0); }; window.searchState = { diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index c72ac254fc0..c3fed9a72d4 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -7,7 +7,6 @@ const darkThemes = ["dark", "ayu"]; window.currentTheme = document.getElementById("themeStyle"); -window.mainTheme = document.getElementById("mainThemeStyle"); // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY // If you update this line, then you also need to update the media query with the same @@ -44,8 +43,6 @@ function getSettingValue(settingName) { const localStoredTheme = getSettingValue("theme"); -const savedHref = []; - // eslint-disable-next-line no-unused-vars function hasClass(elem, className) { return elem && elem.classList && elem.classList.contains(className); @@ -102,6 +99,7 @@ function onEach(arr, func, reversed) { * @param {function(?)} func - The callback * @param {boolean} [reversed] - Whether to iterate in reverse */ +// eslint-disable-next-line no-unused-vars function onEachLazy(lazyArray, func, reversed) { return onEach( Array.prototype.slice.call(lazyArray), @@ -125,30 +123,37 @@ function getCurrentValue(name) { } } -function switchTheme(styleElem, mainStyleElem, newThemeName, saveTheme) { +// Get a value from the rustdoc-vars div, which is used to convey data from +// Rust to the JS. If there is no such element, return null. +const getVar = (function getVar(name) { + const el = document.getElementById("rustdoc-vars"); + if (el) { + return el.attributes["data-" + name].value; + } else { + return null; + } +}); + +function switchTheme(newThemeName, saveTheme) { // If this new value comes from a system setting or from the previously // saved theme, no need to save it. if (saveTheme) { updateLocalStorage("theme", newThemeName); } - if (savedHref.length === 0) { - onEachLazy(document.getElementsByTagName("link"), el => { - savedHref.push(el.href); - }); + let newHref; + + if (newThemeName === "light" || newThemeName === "dark" || newThemeName === "ayu") { + newHref = getVar("static-root-path") + getVar("theme-" + newThemeName + "-css"); + } else { + newHref = getVar("root-path") + newThemeName + getVar("resource-suffix") + ".css"; } - const newHref = savedHref.find(url => { - const m = url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/); - if (m && m[1] === newThemeName) { - return true; - } - const m2 = url.match(/\/([^/]*)\.css$/); - if (m2 && m2[1].startsWith(newThemeName)) { - return true; - } - }); - if (newHref && newHref !== styleElem.href) { - styleElem.href = newHref; + + if (!window.currentTheme) { + document.write(`<link rel="stylesheet" id="themeStyle" href="${newHref}">`); + window.currentTheme = document.getElementById("themeStyle"); + } else if (newHref !== window.currentTheme.href) { + window.currentTheme.href = newHref; } } @@ -164,7 +169,7 @@ const updateTheme = (function() { */ function updateTheme() { const use = (theme, saveTheme) => { - switchTheme(window.currentTheme, window.mainTheme, theme, saveTheme); + switchTheme(theme, saveTheme); }; // maybe the user has disabled the setting in the meantime! diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index e896850fab6..532660e3d33 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -17,12 +17,6 @@ <link rel="stylesheet" {#+ #} href="{{static_root_path|safe}}{{files.rustdoc_css}}" {#+ #} id="mainThemeStyle"> {# #} - <link rel="stylesheet" id="themeStyle" href="{{static_root_path|safe}}{{files.theme_light_css}}"> {# #} - <link rel="stylesheet" disabled href="{{static_root_path|safe}}{{files.theme_dark_css}}"> {# #} - <link rel="stylesheet" disabled href="{{static_root_path|safe}}{{files.theme_ayu_css}}"> {# #} - {% for theme in themes %} - <link rel="stylesheet" disabled href="{{page.root_path|safe}}{{theme}}{{page.resource_suffix}}.css"> {# #} - {% endfor %} {% if !layout.default_settings.is_empty() %} <script id="default-settings" {#+ #} {%~ for (k, v) in layout.default_settings ~%} @@ -30,6 +24,21 @@ {% endfor %} ></script> {# #} {% endif %} + <div id="rustdoc-vars" {#+ #} + data-root-path="{{page.root_path|safe}}" {#+ #} + data-static-root-path="{{static_root_path|safe}}" {#+ #} + data-current-crate="{{layout.krate}}" {#+ #} + data-themes="{{themes|join(",") }}" {#+ #} + data-resource-suffix="{{page.resource_suffix}}" {#+ #} + data-rustdoc-version="{{rustdoc_version}}" {#+ #} + data-search-js="{{files.search_js}}" {#+ #} + data-settings-js="{{files.settings_js}}" {#+ #} + data-settings-css="{{files.settings_css}}" {#+ #} + data-theme-light-css="{{files.theme_light_css}}" {#+ #} + data-theme-dark-css="{{files.theme_dark_css}}" {#+ #} + data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #} + > {# #} + </div> {# #} <script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #} {% if page.css_class.contains("crate") %} <script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #} @@ -45,6 +54,12 @@ {% endif %} <noscript> {# #} <link rel="stylesheet" {#+ #} + media="(prefers-color-scheme:light)" {#+ #} + href="{{static_root_path|safe}}{{files.theme_light_css}}"> {# #} + <link rel="stylesheet" {#+ #} + media="(prefers-color-scheme:dark)" {#+ #} + href="{{static_root_path|safe}}{{files.theme_dark_css}}"> {# #} + <link rel="stylesheet" {#+ #} href="{{static_root_path|safe}}{{files.noscript_css}}"> {# #} </noscript> {# #} {% if layout.css_file_extension.is_some() %} @@ -132,17 +147,5 @@ {% if page.css_class != "source" %}</div>{% endif %} </main> {# #} {{ layout.external_html.after_content|safe }} - <div id="rustdoc-vars" {#+ #} - data-root-path="{{page.root_path|safe}}" {#+ #} - data-static-root-path="{{static_root_path|safe}}" {#+ #} - data-current-crate="{{layout.krate}}" {#+ #} - data-themes="{{themes|join(",") }}" {#+ #} - data-resource-suffix="{{page.resource_suffix}}" {#+ #} - data-rustdoc-version="{{rustdoc_version}}" {#+ #} - data-search-js="{{files.search_js}}" {#+ #} - data-settings-js="{{files.settings_js}}" {#+ #} - data-settings-css="{{files.settings_css}}" {#+ #} - > {# #} - </div> {# #} </body> {# #} </html> {# #} diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 5bbbff175cf..44e9b49f82a 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -15,7 +15,7 @@ use rustc_span::Span; use std::mem; -use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt}; +use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt, OneLevelVisitor}; use crate::core; /// This module is used to store stuff from Rust's AST in a more convenient @@ -220,6 +220,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { renamed: Option<Symbol>, glob: bool, please_inline: bool, + path: &hir::UsePath<'_>, ) -> bool { debug!("maybe_inline_local res: {:?}", res); @@ -263,6 +264,22 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } + if !please_inline && + let mut visitor = OneLevelVisitor::new(self.cx.tcx.hir(), res_did) && + let Some(item) = visitor.find_target(self.cx.tcx, def_id.to_def_id(), path) && + let item_def_id = item.owner_id.def_id && + item_def_id != def_id && + self + .cx + .cache + .effective_visibilities + .is_directly_public(self.cx.tcx, item_def_id.to_def_id()) && + !inherits_doc_hidden(self.cx.tcx, item_def_id) + { + // The imported item is public and not `doc(hidden)` so no need to inline it. + return false; + } + let ret = match tcx.hir().get_by_def_id(res_did) { Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => { let prev = mem::replace(&mut self.inlining, true); @@ -361,6 +378,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { ident, is_glob, please_inline, + path, ) { continue; } diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 33938ac9a0a..6d6d3c89a3c 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -62,6 +62,8 @@ const EXCEPTION_PATHS: &[&str] = &[ "library/std/src/panic.rs", // fuchsia-specific panic backtrace handling "library/std/src/personality.rs", "library/std/src/personality/", + "library/std/src/thread/mod.rs", + "library/std/src/thread/local.rs", ]; pub fn check(path: &Path, bad: &mut bool) { @@ -128,6 +130,7 @@ fn check_cfgs( || cfg.contains("target_env") || cfg.contains("target_abi") || cfg.contains("target_vendor") + || cfg.contains("target_family") || cfg.contains("unix") || cfg.contains("windows"); |
