diff --git a/src/doc/book b/src/doc/book index 6247be15a7f75..e8a4714a9d8a6 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 6247be15a7f7509559f7981ee2209b9e0cc121df +Subproject commit e8a4714a9d8a6136a59b8e63544e149683876e36 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 49270740c7a4b..0a8ab50468297 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 49270740c7a4bff2763e6bc730b191d45b7d5167 +Subproject commit 0a8ab5046829733eb03df0738c4fafaa9b36b348 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 366c50a03bed9..5555a97f04ad7 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 366c50a03bed928589771eba8a6f18e0c0c01d23 +Subproject commit 5555a97f04ad7974ac6fb8fb47c267c4274adf4a diff --git a/src/doc/reference b/src/doc/reference index 892b928b565e3..becdca9477c9e 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 892b928b565e35d25b6f9c47faee03b94bc41489 +Subproject commit becdca9477c9eafa96a4eea5156fe7a2730d9dd2 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index ab072b14393cb..7aa82129aa23e 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit ab072b14393cbd9e8a1d1d75879bf51e27217bbb +Subproject commit 7aa82129aa23e7e181efbeb8da03a2a897ef6afc diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index b791d313fc4f4..ee27342541c93 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -276,6 +276,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { UNUSED_ALLOCATION, UNUSED_DOC_COMMENTS, UNUSED_EXTERN_CRATES, + UNUSED_CRATE_DEPENDENCIES, UNUSED_FEATURES, UNUSED_LABELS, UNUSED_PARENS, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index b0220ddd3c38e..db29e9538999a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -5,6 +5,7 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind}; use rustc_ast::{ast, attr}; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; use rustc_errors::struct_span_err; @@ -18,6 +19,7 @@ use rustc_middle::middle::cstore::{ }; use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType}; +use rustc_session::lint; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; use rustc_session::{CrateDisambiguator, Session}; @@ -49,6 +51,7 @@ pub struct CrateLoader<'a> { local_crate_name: Symbol, // Mutable output. cstore: CStore, + used_extern_options: FxHashSet, } pub enum LoadedMacro { @@ -205,6 +208,7 @@ impl<'a> CrateLoader<'a> { allocator_kind: None, has_global_allocator: false, }, + used_extern_options: Default::default(), } } @@ -445,6 +449,9 @@ impl<'a> CrateLoader<'a> { dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> CrateNum { + if dep.is_none() { + self.used_extern_options.insert(name); + } self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report()) } @@ -839,6 +846,26 @@ impl<'a> CrateLoader<'a> { }); } + fn report_unused_deps(&mut self, krate: &ast::Crate) { + // Make a point span rather than covering the whole file + let span = krate.span.shrink_to_lo(); + // Complain about anything left over + for (name, _) in self.sess.opts.externs.iter() { + if !self.used_extern_options.contains(&Symbol::intern(name)) { + self.sess.parse_sess.buffer_lint( + lint::builtin::UNUSED_CRATE_DEPENDENCIES, + span, + ast::CRATE_NODE_ID, + &format!( + "external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`", + name, + self.local_crate_name, + name), + ); + } + } + } + pub fn postprocess(&mut self, krate: &ast::Crate) { self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -847,6 +874,8 @@ impl<'a> CrateLoader<'a> { if log_enabled!(log::Level::Info) { dump_crates(&self.cstore); } + + self.report_unused_deps(krate); } pub fn process_extern_crate( diff --git a/src/librustc_mir/transform/check_packed_ref.rs b/src/librustc_mir/transform/check_packed_ref.rs new file mode 100644 index 0000000000000..faad1a72327f4 --- /dev/null +++ b/src/librustc_mir/transform/check_packed_ref.rs @@ -0,0 +1,66 @@ +use rustc_middle::mir::visit::{PlaceContext, Visitor}; +use rustc_middle::mir::*; +use rustc_middle::ty::{self, TyCtxt}; +use rustc_session::lint::builtin::UNALIGNED_REFERENCES; + +use crate::transform::{MirPass, MirSource}; +use crate::util; + +pub struct CheckPackedRef; + +impl<'tcx> MirPass<'tcx> for CheckPackedRef { + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { + let param_env = tcx.param_env(src.instance.def_id()); + let source_info = SourceInfo::outermost(body.span); + let mut checker = PackedRefChecker { body, tcx, param_env, source_info }; + checker.visit_body(&body); + } +} + +struct PackedRefChecker<'a, 'tcx> { + body: &'a Body<'tcx>, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + source_info: SourceInfo, +} + +impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> { + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { + // Make sure we know where in the MIR we are. + self.source_info = terminator.source_info; + self.super_terminator(terminator, location); + } + + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + // Make sure we know where in the MIR we are. + self.source_info = statement.source_info; + self.super_statement(statement, location); + } + + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { + if context.is_borrow() { + if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { + let source_info = self.source_info; + let lint_root = self.body.source_scopes[source_info.scope] + .local_data + .as_ref() + .assert_crate_local() + .lint_root; + self.tcx.struct_span_lint_hir( + UNALIGNED_REFERENCES, + lint_root, + source_info.span, + |lint| { + lint.build(&format!("reference to packed field is unaligned",)) + .note( + "fields of packed structs are not properly aligned, and creating \ + a misaligned reference is undefined behavior (even if that \ + reference is never dereferenced)", + ) + .emit() + }, + ); + } + } + } +} diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 9bcb45f6493d1..a335fa2de411b 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -14,7 +14,7 @@ use rustc_span::symbol::{sym, Symbol}; use std::ops::Bound; -use crate::const_eval::{is_const_fn, is_min_const_fn}; +use crate::const_eval::is_min_const_fn; use crate::util; pub struct UnsafetyChecker<'a, 'tcx> { @@ -527,7 +527,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: LocalDefId) -> UnsafetyCheckRe let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) { hir::BodyOwnerKind::Closure => (false, false), hir::BodyOwnerKind::Fn => { - (is_const_fn(tcx, def_id.to_def_id()), is_min_const_fn(tcx, def_id.to_def_id())) + (tcx.is_const_fn_raw(def_id.to_def_id()), is_min_const_fn(tcx, def_id.to_def_id())) } hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false), }; diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index af9436d404180..26725a2ac02d5 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -17,6 +17,7 @@ pub mod add_call_guards; pub mod add_moves_for_packed_drops; pub mod add_retag; pub mod check_consts; +pub mod check_packed_ref; pub mod check_unsafety; pub mod cleanup_post_borrowck; pub mod const_prop; @@ -228,10 +229,11 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { validator.qualifs_in_return_place() } +/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts! fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal> { let def_id = def_id.expect_local(); - // Unsafety check uses the raw mir, so make sure it is run + // Unsafety check uses the raw mir, so make sure it is run. let _ = tcx.unsafety_check_result(def_id); let mut body = tcx.mir_built(def_id).steal(); @@ -247,6 +249,8 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> Steal> { None, MirPhase::Const, &[&[ + // MIR-level lints. + &check_packed_ref::CheckPackedRef, // What we need to do constant evaluation. &simplify::SimplifyCfg::new("initial"), &rustc_peek::SanityCheck, diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 09b3d44020d81..767a6909d31d4 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -9,6 +9,7 @@ use rustc_middle::hir::map::Map; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::Session; +use rustc_span::hygiene::DesugaringKind; use rustc_span::Span; #[derive(Clone, Copy, Debug, PartialEq)] @@ -203,7 +204,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { label: &Destination, cf_type: &str, ) -> bool { - if self.cx == LabeledBlock { + if !span.is_desugaring(DesugaringKind::QuestionMark) && self.cx == LabeledBlock { if label.label.is_none() { struct_span_err!( self.sess, diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 3d03e46683ed5..e55ddc26a9441 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -71,6 +71,12 @@ declare_lint! { "extern crates that are never used" } +declare_lint! { + pub UNUSED_CRATE_DEPENDENCIES, + Allow, + "crate dependencies that are never used" +} + declare_lint! { pub UNUSED_QUALIFICATIONS, Allow, @@ -216,10 +222,16 @@ declare_lint! { "lints that have been renamed or removed" } +declare_lint! { + pub UNALIGNED_REFERENCES, + Allow, + "detects unaligned references to fields of packed structs", +} + declare_lint! { pub SAFE_PACKED_BORROWS, Warn, - "safe borrows of fields of packed structs were was erroneously allowed", + "safe borrows of fields of packed structs were erroneously allowed", @future_incompatible = FutureIncompatibleInfo { reference: "issue #46043 ", edition: None, @@ -523,6 +535,7 @@ declare_lint_pass! { UNCONDITIONAL_PANIC, UNUSED_IMPORTS, UNUSED_EXTERN_CRATES, + UNUSED_CRATE_DEPENDENCIES, UNUSED_QUALIFICATIONS, UNKNOWN_LINTS, UNUSED_VARIABLES, @@ -545,6 +558,7 @@ declare_lint_pass! { INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, RENAMED_AND_REMOVED_LINTS, + UNALIGNED_REFERENCES, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, MISSING_FRAGMENT_SPECIFIER, diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 9869c50fbb0cf..22c9426db2036 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -3,7 +3,7 @@ // Local js definitions: /* global addClass, getCurrentValue, hasClass */ -/* global onEach, removeClass, updateLocalStorage */ +/* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { @@ -47,6 +47,16 @@ function getSearchElement() { return document.getElementById("search"); } +// Sets the focus on the search bar at the top of the page +function focusSearchBar() { + getSearchInput().focus(); +} + +// Removes the focus from the search bar +function defocusSearchBar() { + getSearchInput().blur(); +} + (function() { "use strict"; @@ -181,6 +191,7 @@ function getSearchElement() { var savedHash = ""; function handleHashes(ev) { + var elem; var search = getSearchElement(); if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) { // This block occurs when clicking on an element in the navbar while @@ -190,7 +201,7 @@ function getSearchElement() { if (browserSupportsHistoryApi()) { history.replaceState(hash, "", "?search=#" + hash); } - var elem = document.getElementById(hash); + elem = document.getElementById(hash); if (elem) { elem.scrollIntoView(); } @@ -201,7 +212,7 @@ function getSearchElement() { if (savedHash.length === 0) { return; } - var elem = document.getElementById(savedHash.slice(1)); // we remove the '#' + elem = document.getElementById(savedHash.slice(1)); // we remove the '#' if (!elem || !isHidden(elem)) { return; } @@ -324,7 +335,7 @@ function getSearchElement() { } function displayHelp(display, ev, help) { - var help = help ? help : getHelpElement(); + help = help ? help : getHelpElement(); if (display === true) { if (hasClass(help, "hidden")) { ev.preventDefault(); @@ -438,8 +449,8 @@ function getSearchElement() { set_fragment(cur_line_id); } - } - })(); + }; + }()); document.addEventListener("click", function(ev) { if (hasClass(ev.target, "collapse-toggle")) { @@ -465,27 +476,30 @@ function getSearchElement() { } }); - var x = document.getElementsByClassName("version-selector"); - if (x.length > 0) { - x[0].onchange = function() { - var i, match, - url = document.location.href, - stripped = "", - len = rootPath.match(/\.\.\//g).length + 1; + (function() { + var x = document.getElementsByClassName("version-selector"); + if (x.length > 0) { + x[0].onchange = function() { + var i, match, + url = document.location.href, + stripped = "", + len = rootPath.match(/\.\.\//g).length + 1; - for (i = 0; i < len; ++i) { - match = url.match(/\/[^\/]*$/); - if (i < len - 1) { - stripped = match[0] + stripped; + for (i = 0; i < len; ++i) { + match = url.match(/\/[^\/]*$/); + if (i < len - 1) { + stripped = match[0] + stripped; + } + url = url.substring(0, url.length - match[0].length); } - url = url.substring(0, url.length - match[0].length); - } - url += "/" + document.getElementsByClassName("version-selector")[0].value + stripped; + var selectedVersion = document.getElementsByClassName("version-selector")[0].value; + url += "/" + selectedVersion + stripped; - document.location.href = url; - }; - } + document.location.href = url; + }; + } + }()); /** * A function to compute the Levenshtein distance between two strings @@ -522,7 +536,7 @@ function getSearchElement() { return s1_len + s2_len; } - function initSearch(rawSearchIndex) { + window.initSearch = function(rawSearchIndex) { var MAX_LEV_DISTANCE = 3; var MAX_RESULTS = 200; var GENERICS_DATA = 1; @@ -602,7 +616,7 @@ function getSearchElement() { function sortResults(results, isType) { var ar = []; for (var entry in results) { - if (results.hasOwnProperty(entry)) { + if (hasOwnProperty(results, entry)) { ar.push(results[entry]); } } @@ -1100,8 +1114,6 @@ function getSearchElement() { } fullId = generateId(ty); - // allow searching for void (no output) functions as well - var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : ""; returned = checkReturned(ty, output, true, NO_TYPE_FILTER); if (output.name === "*" || returned === true) { in_args = false; @@ -1164,7 +1176,6 @@ function getSearchElement() { var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1); var lev; - var lev_distance; for (j = 0; j < nSearchWords; ++j) { ty = searchIndex[j]; if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) { @@ -1661,7 +1672,7 @@ function getSearchElement() { function getFilterCrates() { var elem = document.getElementById("crate-search"); - if (elem && elem.value !== "All crates" && rawSearchIndex.hasOwnProperty(elem.value)) { + if (elem && elem.value !== "All crates" && hasOwnProperty(rawSearchIndex, elem.value)) { return elem.value; } return undefined; @@ -1709,7 +1720,7 @@ function getSearchElement() { var currentIndex = 0; for (var crate in rawSearchIndex) { - if (!rawSearchIndex.hasOwnProperty(crate)) { continue; } + if (!hasOwnProperty(rawSearchIndex, crate)) { continue; } var crateSize = 0; @@ -1893,7 +1904,7 @@ function getSearchElement() { var crates = []; for (var crate in rawSearchIndex) { - if (!rawSearchIndex.hasOwnProperty(crate)) { + if (!hasOwnProperty(rawSearchIndex, crate)) { continue; } crates.push(crate); @@ -1917,12 +1928,11 @@ function getSearchElement() { sidebar.appendChild(div); } } - } + }; - window.initSearch = initSearch; // delayed sidebar rendering. - function initSidebarItems(items) { + window.initSidebarItems = function(items) { var sidebar = document.getElementsByClassName("sidebar-elems")[0]; var current = window.sidebarCurrent; @@ -1984,9 +1994,7 @@ function getSearchElement() { block("foreigntype", "Foreign Types"); block("keyword", "Keywords"); block("traitalias", "Trait Aliases"); - } - - window.initSidebarItems = initSidebarItems; + }; window.register_implementors = function(imp) { var implementors = document.getElementById("implementors-list"); @@ -2163,19 +2171,13 @@ function getSearchElement() { } } var ns = n.nextElementSibling; - while (true) { - if (ns && ( - hasClass(ns, "docblock") || - hasClass(ns, "stability"))) { - if (addOrRemove) { - addClass(ns, "hidden-by-impl-hider"); - } else { - removeClass(ns, "hidden-by-impl-hider"); - } - ns = ns.nextElementSibling; - continue; + while (ns && (hasClass(ns, "docblock") || hasClass(ns, "stability"))) { + if (addOrRemove) { + addClass(ns, "hidden-by-impl-hider"); + } else { + removeClass(ns, "hidden-by-impl-hider"); } - break; + ns = ns.nextElementSibling; } } }; @@ -2248,7 +2250,7 @@ function getSearchElement() { } } - function collapser(e, collapse) { + function collapser(pageId, e, collapse) { // inherent impl ids are like "impl" or impl-'. // they will never be hidden by default. var n = e.parentElement; @@ -2268,7 +2270,7 @@ function getSearchElement() { if (impl_list !== null) { onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) { - collapser(e, collapse); + collapser(pageId, e, collapse); }); } @@ -2276,7 +2278,7 @@ function getSearchElement() { if (blanket_list !== null) { onEachLazy(blanket_list.getElementsByClassName("collapse-toggle"), function(e) { - collapser(e, collapse); + collapser(pageId, e, collapse); }); } } @@ -2300,103 +2302,7 @@ function getSearchElement() { return toggle; } - var toggle = createSimpleToggle(false); - var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true"; - var pageId = getPageId(); - - var func = function(e) { - var next = e.nextElementSibling; - if (!next) { - return; - } - if (hasClass(next, "docblock") === true || - (hasClass(next, "stability") === true && - hasClass(next.nextElementSibling, "docblock") === true)) { - var newToggle = toggle.cloneNode(true); - insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); - if (hideMethodDocs === true && hasClass(e, "method") === true) { - collapseDocs(newToggle, "hide", pageId); - } - } - }; - - var funcImpl = function(e) { - var next = e.nextElementSibling; - if (next && hasClass(next, "docblock")) { - next = next.nextElementSibling; - } - if (!next) { - return; - } - if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) { - insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); - } - }; - - onEachLazy(document.getElementsByClassName("method"), func); - onEachLazy(document.getElementsByClassName("associatedconstant"), func); - onEachLazy(document.getElementsByClassName("impl"), funcImpl); - var impl_call = function() {}; - if (hideMethodDocs === true) { - impl_call = function(e, newToggle, pageId) { - if (e.id.match(/^impl(?:-\d+)?$/) === null) { - // Automatically minimize all non-inherent impls - if (hasClass(e, "impl") === true) { - collapseDocs(newToggle, "hide", pageId); - } - } - }; - } - var newToggle = document.createElement("a"); - newToggle.href = "javascript:void(0)"; - newToggle.className = "collapse-toggle hidden-default collapsed"; - newToggle.innerHTML = "[" + labelForToggleButton(true) + - "] Show hidden undocumented items"; - function toggleClicked() { - if (hasClass(this, "collapsed")) { - removeClass(this, "collapsed"); - onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) { - if (hasClass(x, "content") === false) { - removeClass(x, "hidden"); - addClass(x, "x"); - } - }, true); - this.innerHTML = "[" + labelForToggleButton(false) + - "] Hide undocumented items"; - } else { - addClass(this, "collapsed"); - onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) { - if (hasClass(x, "content") === false) { - addClass(x, "hidden"); - removeClass(x, "x"); - } - }, true); - this.innerHTML = "[" + labelForToggleButton(true) + - "] Show hidden undocumented items"; - } - } - onEachLazy(document.getElementsByClassName("impl-items"), function(e) { - onEachLazy(e.getElementsByClassName("associatedconstant"), func); - var hiddenElems = e.getElementsByClassName("hidden"); - var needToggle = false; - - var hlength = hiddenElems.length; - for (var i = 0; i < hlength; ++i) { - if (hasClass(hiddenElems[i], "content") === false && - hasClass(hiddenElems[i], "docblock") === false) { - needToggle = true; - break; - } - } - if (needToggle === true) { - var inner_toggle = newToggle.cloneNode(true); - inner_toggle.onclick = toggleClicked; - e.insertBefore(inner_toggle, e.firstChild); - impl_call(e.previousSibling, inner_toggle, pageId); - } - }); - - function createToggle(otherMessage, fontSize, extraClass, show) { + function createToggle(toggle, otherMessage, fontSize, extraClass, show) { var span = document.createElement("span"); span.className = "toggle-label"; if (show) { @@ -2431,97 +2337,197 @@ function getSearchElement() { return wrapper; } - var currentType = document.getElementsByClassName("type-decl")[0]; - var className = null; - if (currentType) { - currentType = currentType.getElementsByClassName("rust")[0]; - if (currentType) { - currentType.classList.forEach(function(item) { - if (item !== "main") { - className = item; - return true; + (function() { + var toggle = createSimpleToggle(false); + var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true"; + var pageId = getPageId(); + + var func = function(e) { + var next = e.nextElementSibling; + if (!next) { + return; + } + if (hasClass(next, "docblock") === true || + (hasClass(next, "stability") === true && + hasClass(next.nextElementSibling, "docblock") === true)) { + var newToggle = toggle.cloneNode(true); + insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); + if (hideMethodDocs === true && hasClass(e, "method") === true) { + collapseDocs(newToggle, "hide", pageId); } - }); + } + }; + + var funcImpl = function(e) { + var next = e.nextElementSibling; + if (next && hasClass(next, "docblock")) { + next = next.nextElementSibling; + } + if (!next) { + return; + } + if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) { + insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); + } + }; + + onEachLazy(document.getElementsByClassName("method"), func); + onEachLazy(document.getElementsByClassName("associatedconstant"), func); + onEachLazy(document.getElementsByClassName("impl"), funcImpl); + var impl_call = function() {}; + if (hideMethodDocs === true) { + impl_call = function(e, newToggle) { + if (e.id.match(/^impl(?:-\d+)?$/) === null) { + // Automatically minimize all non-inherent impls + if (hasClass(e, "impl") === true) { + collapseDocs(newToggle, "hide", pageId); + } + } + }; } - } - var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className); - if (showItemDeclarations === null) { - if (className === "enum" || className === "macro") { - showItemDeclarations = "false"; - } else if (className === "struct" || className === "union" || className === "trait") { - showItemDeclarations = "true"; - } else { - // In case we found an unknown type, we just use the "parent" value. - showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations"); + var newToggle = document.createElement("a"); + newToggle.href = "javascript:void(0)"; + newToggle.className = "collapse-toggle hidden-default collapsed"; + newToggle.innerHTML = "[" + labelForToggleButton(true) + + "] Show hidden undocumented items"; + function toggleClicked() { + if (hasClass(this, "collapsed")) { + removeClass(this, "collapsed"); + onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) { + if (hasClass(x, "content") === false) { + removeClass(x, "hidden"); + addClass(x, "x"); + } + }, true); + this.innerHTML = "[" + labelForToggleButton(false) + + "] Hide undocumented items"; + } else { + addClass(this, "collapsed"); + onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) { + if (hasClass(x, "content") === false) { + addClass(x, "hidden"); + removeClass(x, "x"); + } + }, true); + this.innerHTML = "[" + labelForToggleButton(true) + + "] Show hidden undocumented items"; + } } - } - showItemDeclarations = showItemDeclarations === "false"; - function buildToggleWrapper(e) { - if (hasClass(e, "autohide")) { - var wrap = e.previousElementSibling; - if (wrap && hasClass(wrap, "toggle-wrapper")) { - var inner_toggle = wrap.childNodes[0]; - var extra = e.childNodes[0].tagName === "H3"; - - e.style.display = "none"; - addClass(wrap, "collapsed"); - onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) { - e.innerHTML = labelForToggleButton(true); - }); - onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) { - e.style.display = "inline-block"; - if (extra === true) { - i_e.innerHTML = " Show " + e.childNodes[0].innerHTML; + onEachLazy(document.getElementsByClassName("impl-items"), function(e) { + onEachLazy(e.getElementsByClassName("associatedconstant"), func); + var hiddenElems = e.getElementsByClassName("hidden"); + var needToggle = false; + + var hlength = hiddenElems.length; + for (var i = 0; i < hlength; ++i) { + if (hasClass(hiddenElems[i], "content") === false && + hasClass(hiddenElems[i], "docblock") === false) { + needToggle = true; + break; + } + } + if (needToggle === true) { + var inner_toggle = newToggle.cloneNode(true); + inner_toggle.onclick = toggleClicked; + e.insertBefore(inner_toggle, e.firstChild); + impl_call(e.previousSibling, inner_toggle); + } + }); + + var currentType = document.getElementsByClassName("type-decl")[0]; + var className = null; + if (currentType) { + currentType = currentType.getElementsByClassName("rust")[0]; + if (currentType) { + currentType.classList.forEach(function(item) { + if (item !== "main") { + className = item; + return true; } }); } } - if (e.parentNode.id === "main") { - var otherMessage = ""; - var fontSize; - var extraClass; - - if (hasClass(e, "type-decl")) { - fontSize = "20px"; - otherMessage = " Show declaration"; - if (showItemDeclarations === false) { - extraClass = "collapsed"; - } - } else if (hasClass(e, "sub-variant")) { - otherMessage = " Show fields"; - } else if (hasClass(e, "non-exhaustive")) { - otherMessage = " This "; - if (hasClass(e, "non-exhaustive-struct")) { - otherMessage += "struct"; - } else if (hasClass(e, "non-exhaustive-enum")) { - otherMessage += "enum"; - } else if (hasClass(e, "non-exhaustive-variant")) { - otherMessage += "enum variant"; - } else if (hasClass(e, "non-exhaustive-type")) { - otherMessage += "type"; - } - otherMessage += " is marked as non-exhaustive"; - } else if (hasClass(e.childNodes[0], "impl-items")) { - extraClass = "marg-left"; - } - - e.parentNode.insertBefore( - createToggle(otherMessage, - fontSize, - extraClass, - hasClass(e, "type-decl") === false || showItemDeclarations === true), - e); - if (hasClass(e, "type-decl") === true && showItemDeclarations === true) { - collapseDocs(e.previousSibling.childNodes[0], "toggle"); - } - if (hasClass(e, "non-exhaustive") === true) { - collapseDocs(e.previousSibling.childNodes[0], "toggle"); + var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className); + if (showItemDeclarations === null) { + if (className === "enum" || className === "macro") { + showItemDeclarations = "false"; + } else if (className === "struct" || className === "union" || className === "trait") { + showItemDeclarations = "true"; + } else { + // In case we found an unknown type, we just use the "parent" value. + showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations"); + } + } + showItemDeclarations = showItemDeclarations === "false"; + function buildToggleWrapper(e) { + if (hasClass(e, "autohide")) { + var wrap = e.previousElementSibling; + if (wrap && hasClass(wrap, "toggle-wrapper")) { + var inner_toggle = wrap.childNodes[0]; + var extra = e.childNodes[0].tagName === "H3"; + + e.style.display = "none"; + addClass(wrap, "collapsed"); + onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) { + e.innerHTML = labelForToggleButton(true); + }); + onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) { + e.style.display = "inline-block"; + if (extra === true) { + e.innerHTML = " Show " + e.childNodes[0].innerHTML; + } + }); + } + } + if (e.parentNode.id === "main") { + var otherMessage = ""; + var fontSize; + var extraClass; + + if (hasClass(e, "type-decl")) { + fontSize = "20px"; + otherMessage = " Show declaration"; + if (showItemDeclarations === false) { + extraClass = "collapsed"; + } + } else if (hasClass(e, "sub-variant")) { + otherMessage = " Show fields"; + } else if (hasClass(e, "non-exhaustive")) { + otherMessage = " This "; + if (hasClass(e, "non-exhaustive-struct")) { + otherMessage += "struct"; + } else if (hasClass(e, "non-exhaustive-enum")) { + otherMessage += "enum"; + } else if (hasClass(e, "non-exhaustive-variant")) { + otherMessage += "enum variant"; + } else if (hasClass(e, "non-exhaustive-type")) { + otherMessage += "type"; + } + otherMessage += " is marked as non-exhaustive"; + } else if (hasClass(e.childNodes[0], "impl-items")) { + extraClass = "marg-left"; + } + + e.parentNode.insertBefore( + createToggle( + toggle, + otherMessage, + fontSize, + extraClass, + hasClass(e, "type-decl") === false || showItemDeclarations === true), + e); + if (hasClass(e, "type-decl") === true && showItemDeclarations === true) { + collapseDocs(e.previousSibling.childNodes[0], "toggle"); + } + if (hasClass(e, "non-exhaustive") === true) { + collapseDocs(e.previousSibling.childNodes[0], "toggle"); + } } } - } - onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); - onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); + onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); + onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); + }()); function createToggleWrapper(tog) { var span = document.createElement("span"); @@ -2536,56 +2542,60 @@ function getSearchElement() { return wrapper; } - // To avoid checking on "rustdoc-item-attributes" value on every loop... - var itemAttributesFunc = function() {}; - if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") { - itemAttributesFunc = function(x) { - collapseDocs(x.previousSibling.childNodes[0], "toggle"); - }; - } - var attributesToggle = createToggleWrapper(createSimpleToggle(false)); - onEachLazy(main.getElementsByClassName("attributes"), function(i_e) { - var attr_tog = attributesToggle.cloneNode(true); - if (hasClass(i_e, "top-attr") === true) { - addClass(attr_tog, "top-attr"); - } - i_e.parentNode.insertBefore(attr_tog, i_e); - itemAttributesFunc(i_e); - }); - - // To avoid checking on "rustdoc-line-numbers" value on every loop... - var lineNumbersFunc = function() {}; - if (getCurrentValue("rustdoc-line-numbers") === "true") { - lineNumbersFunc = function(x) { - var count = x.textContent.split("\n").length; - var elems = []; - for (var i = 0; i < count; ++i) { - elems.push(i + 1); - } - var node = document.createElement("pre"); - addClass(node, "line-number"); - node.innerHTML = elems.join("\n"); - x.parentNode.insertBefore(node, x); - }; - } - onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) { - if (hasClass(e, "compile_fail")) { - e.addEventListener("mouseover", function(event) { - this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00"; - }); - e.addEventListener("mouseout", function(event) { - this.parentElement.previousElementSibling.childNodes[0].style.color = ""; - }); - } else if (hasClass(e, "ignore")) { - e.addEventListener("mouseover", function(event) { - this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200"; - }); - e.addEventListener("mouseout", function(event) { - this.parentElement.previousElementSibling.childNodes[0].style.color = ""; - }); + (function() { + // To avoid checking on "rustdoc-item-attributes" value on every loop... + var itemAttributesFunc = function() {}; + if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") { + itemAttributesFunc = function(x) { + collapseDocs(x.previousSibling.childNodes[0], "toggle"); + }; } - lineNumbersFunc(e); - }); + var attributesToggle = createToggleWrapper(createSimpleToggle(false)); + onEachLazy(main.getElementsByClassName("attributes"), function(i_e) { + var attr_tog = attributesToggle.cloneNode(true); + if (hasClass(i_e, "top-attr") === true) { + addClass(attr_tog, "top-attr"); + } + i_e.parentNode.insertBefore(attr_tog, i_e); + itemAttributesFunc(i_e); + }); + }()); + + (function() { + // To avoid checking on "rustdoc-line-numbers" value on every loop... + var lineNumbersFunc = function() {}; + if (getCurrentValue("rustdoc-line-numbers") === "true") { + lineNumbersFunc = function(x) { + var count = x.textContent.split("\n").length; + var elems = []; + for (var i = 0; i < count; ++i) { + elems.push(i + 1); + } + var node = document.createElement("pre"); + addClass(node, "line-number"); + node.innerHTML = elems.join("\n"); + x.parentNode.insertBefore(node, x); + }; + } + onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) { + if (hasClass(e, "compile_fail")) { + e.addEventListener("mouseover", function() { + this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00"; + }); + e.addEventListener("mouseout", function() { + this.parentElement.previousElementSibling.childNodes[0].style.color = ""; + }); + } else if (hasClass(e, "ignore")) { + e.addEventListener("mouseover", function() { + this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200"; + }); + e.addEventListener("mouseout", function() { + this.parentElement.previousElementSibling.childNodes[0].style.color = ""; + }); + } + lineNumbersFunc(e); + }); + }()); // In the search display, allows to switch between tabs. function printTab(nb) { @@ -2678,7 +2688,7 @@ function getSearchElement() { }); } - function addSearchOptions(crates) { + window.addSearchOptions = function(crates) { var elem = document.getElementById("crate-search"); if (!elem) { @@ -2687,7 +2697,7 @@ function getSearchElement() { var crates_text = []; if (Object.keys(crates).length > 1) { for (var crate in crates) { - if (crates.hasOwnProperty(crate)) { + if (hasOwnProperty(crates, crate)) { crates_text.push(crate); } } @@ -2722,10 +2732,8 @@ function getSearchElement() { if (search_input) { search_input.removeAttribute('disabled'); - }; - } - - window.addSearchOptions = addSearchOptions; + } + }; function buildHelperPopup() { var popup = document.createElement("aside"); @@ -2778,16 +2786,6 @@ function getSearchElement() { buildHelperPopup(); }()); -// Sets the focus on the search bar at the top of the page -function focusSearchBar() { - getSearchInput().focus(); -} - -// Removes the focus from the search bar -function defocusSearchBar() { - getSearchInput().blur(); -} - // This is required in firefox. Explanations: when going back in the history, firefox doesn't re-run // the JS, therefore preventing rustdoc from setting a few things required to be able to reload the // previous search results (if you navigated to a search result with the keyboard, pressed enter on diff --git a/src/librustdoc/html/static/settings.js b/src/librustdoc/html/static/settings.js index c21db7371f3c3..427a74c0c87fa 100644 --- a/src/librustdoc/html/static/settings.js +++ b/src/librustdoc/html/static/settings.js @@ -1,3 +1,6 @@ +// Local js definitions: +/* global getCurrentValue, updateLocalStorage */ + (function () { function changeSetting(settingName, isEnabled) { updateLocalStorage('rustdoc-' + settingName, isEnabled); diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js index 567022b4139ad..cfbfe6675f52b 100644 --- a/src/librustdoc/html/static/source-script.js +++ b/src/librustdoc/html/static/source-script.js @@ -1,5 +1,5 @@ // From rust: -/* global sourcesIndex */ +/* global search, sourcesIndex */ // Local js definitions: /* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */ diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index d142d99ac704d..0a2fae274fa87 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -27,14 +27,15 @@ function removeClass(elem, className) { function onEach(arr, func, reversed) { if (arr && arr.length > 0 && func) { var length = arr.length; + var i; if (reversed !== true) { - for (var i = 0; i < length; ++i) { + for (i = 0; i < length; ++i) { if (func(arr[i]) === true) { return true; } } } else { - for (var i = length - 1; i >= 0; --i) { + for (i = length - 1; i >= 0; --i) { if (func(arr[i]) === true) { return true; } @@ -51,6 +52,10 @@ function onEachLazy(lazyArray, func, reversed) { reversed); } +function hasOwnProperty(obj, property) { + return Object.prototype.hasOwnProperty.call(obj, property); +} + function usableLocalStorage() { // Check if the browser supports localStorage at all: if (typeof Storage === "undefined") { diff --git a/src/test/ui/issues/issue-27060-rpass.rs b/src/test/ui/issues/issue-27060-rpass.rs index b6ffc3ecb5133..b20d614b3036b 100644 --- a/src/test/ui/issues/issue-27060-rpass.rs +++ b/src/test/ui/issues/issue-27060-rpass.rs @@ -7,19 +7,10 @@ pub struct Good { aligned: [u8; 32], } -#[repr(packed)] -pub struct JustArray { - array: [u32] -} - // kill this test when that turns to a hard error #[allow(safe_packed_borrows)] fn main() { - let good = Good { - data: &0, - data2: [&0, &0], - aligned: [0; 32] - }; + let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] }; unsafe { let _ = &good.data; // ok diff --git a/src/test/ui/issues/issue-27060.rs b/src/test/ui/issues/issue-27060.rs index 4caad03a36151..78f2022ed38df 100644 --- a/src/test/ui/issues/issue-27060.rs +++ b/src/test/ui/issues/issue-27060.rs @@ -5,11 +5,6 @@ pub struct Good { aligned: [u8; 32], } -#[repr(packed)] -pub struct JustArray { - array: [u32] -} - #[deny(safe_packed_borrows)] fn main() { let good = Good { diff --git a/src/test/ui/issues/issue-27060.stderr b/src/test/ui/issues/issue-27060.stderr index 6bf6348631a70..d14ae4d41d5c5 100644 --- a/src/test/ui/issues/issue-27060.stderr +++ b/src/test/ui/issues/issue-27060.stderr @@ -1,11 +1,11 @@ error: borrow of packed field is unsafe and requires unsafe function or block (error E0133) - --> $DIR/issue-27060.rs:26:13 + --> $DIR/issue-27060.rs:21:13 | LL | let _ = &good.data; | ^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/issue-27060.rs:13:8 + --> $DIR/issue-27060.rs:8:8 | LL | #[deny(safe_packed_borrows)] | ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | #[deny(safe_packed_borrows)] = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior error: borrow of packed field is unsafe and requires unsafe function or block (error E0133) - --> $DIR/issue-27060.rs:28:13 + --> $DIR/issue-27060.rs:23:13 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/label/label_break_value_desugared_break.rs b/src/test/ui/label/label_break_value_desugared_break.rs new file mode 100644 index 0000000000000..de883b61111ce --- /dev/null +++ b/src/test/ui/label/label_break_value_desugared_break.rs @@ -0,0 +1,12 @@ +// compile-flags: --edition 2018 +#![feature(label_break_value, try_blocks)] + +// run-pass +fn main() { + let _: Result<(), ()> = try { + 'foo: { + Err(())?; + break 'foo; + } + }; +} diff --git a/src/test/ui/lint/unaligned_references.rs b/src/test/ui/lint/unaligned_references.rs new file mode 100644 index 0000000000000..1d9f4c3db2eb5 --- /dev/null +++ b/src/test/ui/lint/unaligned_references.rs @@ -0,0 +1,22 @@ +#![deny(unaligned_references)] + +#[repr(packed)] +pub struct Good { + data: &'static u32, + data2: [&'static u32; 2], + aligned: [u8; 32], +} + +fn main() { + unsafe { + let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] }; + + let _ = &good.data; //~ ERROR reference to packed field + let _ = &good.data as *const _; //~ ERROR reference to packed field + let _: *const _ = &good.data; //~ ERROR reference to packed field + let _ = &good.data2[0]; //~ ERROR reference to packed field + let _ = &*good.data; // ok, behind a pointer + let _ = &good.aligned; // ok, has align 1 + let _ = &good.aligned[2]; // ok, has align 1 + } +} diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr new file mode 100644 index 0000000000000..0c594cdb30a3c --- /dev/null +++ b/src/test/ui/lint/unaligned_references.stderr @@ -0,0 +1,39 @@ +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:14:17 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:15:17 + | +LL | let _ = &good.data as *const _; + | ^^^^^^^^^^ + | + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:16:27 + | +LL | let _: *const _ = &good.data; + | ^^^^^^^^^^ + | + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:17:17 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.rs b/src/test/ui/unsafe/unsafe-unstable-const-fn.rs new file mode 100644 index 0000000000000..d9d85ee913266 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.rs @@ -0,0 +1,13 @@ +#![stable(feature = "foo", since = "1.33.0")] +#![feature(staged_api)] +#![feature(const_compare_raw_pointers)] +#![feature(const_fn)] + +#[stable(feature = "foo", since = "1.33.0")] +#[rustc_const_unstable(feature = "const_foo", issue = "none")] +const fn unstable(a: *const i32, b: *const i32) -> bool { + a == b + //~^ pointer operation is unsafe +} + +fn main() {} diff --git a/src/test/ui/unsafe/unsafe-unstable-const-fn.stderr b/src/test/ui/unsafe/unsafe-unstable-const-fn.stderr new file mode 100644 index 0000000000000..d8f3737c8f541 --- /dev/null +++ b/src/test/ui/unsafe/unsafe-unstable-const-fn.stderr @@ -0,0 +1,11 @@ +error[E0133]: pointer operation is unsafe and requires unsafe function or block + --> $DIR/unsafe-unstable-const-fn.rs:9:5 + | +LL | a == b + | ^^^^^^ pointer operation + | + = note: operations on pointers in constants + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unused-crate-deps/auxiliary/bar.rs b/src/test/ui/unused-crate-deps/auxiliary/bar.rs new file mode 100644 index 0000000000000..1d3824e7a44f6 --- /dev/null +++ b/src/test/ui/unused-crate-deps/auxiliary/bar.rs @@ -0,0 +1 @@ +pub const BAR: &str = "bar"; diff --git a/src/test/ui/unused-crate-deps/auxiliary/foo.rs b/src/test/ui/unused-crate-deps/auxiliary/foo.rs new file mode 100644 index 0000000000000..0ef03eb9edf0f --- /dev/null +++ b/src/test/ui/unused-crate-deps/auxiliary/foo.rs @@ -0,0 +1,5 @@ +// edition:2018 +// aux-crate:bar=bar.rs + +pub const FOO: &str = "foo"; +pub use bar::BAR; diff --git a/src/test/ui/unused-crate-deps/libfib.rs b/src/test/ui/unused-crate-deps/libfib.rs new file mode 100644 index 0000000000000..c1545dca99f57 --- /dev/null +++ b/src/test/ui/unused-crate-deps/libfib.rs @@ -0,0 +1,21 @@ +// Test warnings for a library crate + +// check-pass +// aux-crate:bar=bar.rs +// compile-flags:--crate-type lib -Wunused-crate-dependencies + +pub fn fib(n: u32) -> Vec { +//~^ WARNING external crate `bar` unused in +let mut prev = 0; + let mut cur = 1; + let mut v = vec![]; + + for _ in 0..n { + v.push(prev); + let n = prev + cur; + prev = cur; + cur = n; + } + + v +} diff --git a/src/test/ui/unused-crate-deps/libfib.stderr b/src/test/ui/unused-crate-deps/libfib.stderr new file mode 100644 index 0000000000000..15833126bd620 --- /dev/null +++ b/src/test/ui/unused-crate-deps/libfib.stderr @@ -0,0 +1,10 @@ +warning: external crate `bar` unused in `libfib`: remove the dependency or add `use bar as _;` + --> $DIR/libfib.rs:7:1 + | +LL | pub fn fib(n: u32) -> Vec { + | ^ + | + = note: requested on the command line with `-W unused-crate-dependencies` + +warning: 1 warning emitted + diff --git a/src/test/ui/unused-crate-deps/suppress.rs b/src/test/ui/unused-crate-deps/suppress.rs new file mode 100644 index 0000000000000..8904d04bc14f7 --- /dev/null +++ b/src/test/ui/unused-crate-deps/suppress.rs @@ -0,0 +1,11 @@ +// Suppress by using crate + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs + +#![warn(unused_crate_dependencies)] + +use bar as _; + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/unused-aliases.rs b/src/test/ui/unused-crate-deps/unused-aliases.rs new file mode 100644 index 0000000000000..1b7cb9b970e49 --- /dev/null +++ b/src/test/ui/unused-crate-deps/unused-aliases.rs @@ -0,0 +1,13 @@ +// Warn about unused aliased for the crate + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs +// aux-crate:barbar=bar.rs + +#![warn(unused_crate_dependencies)] +//~^ WARNING external crate `barbar` unused in + +use bar as _; + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/unused-aliases.stderr b/src/test/ui/unused-crate-deps/unused-aliases.stderr new file mode 100644 index 0000000000000..c8c6c4507b0c5 --- /dev/null +++ b/src/test/ui/unused-crate-deps/unused-aliases.stderr @@ -0,0 +1,14 @@ +warning: external crate `barbar` unused in `unused_aliases`: remove the dependency or add `use barbar as _;` + --> $DIR/unused-aliases.rs:8:1 + | +LL | #![warn(unused_crate_dependencies)] + | ^ + | +note: the lint level is defined here + --> $DIR/unused-aliases.rs:8:9 + | +LL | #![warn(unused_crate_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/src/test/ui/unused-crate-deps/use_extern_crate_2015.rs b/src/test/ui/unused-crate-deps/use_extern_crate_2015.rs new file mode 100644 index 0000000000000..f15c87fa0b249 --- /dev/null +++ b/src/test/ui/unused-crate-deps/use_extern_crate_2015.rs @@ -0,0 +1,13 @@ +// Suppress by using crate + +// edition:2015 +// check-pass +// aux-crate:bar=bar.rs + +#![warn(unused_crate_dependencies)] + +extern crate bar; + +fn main() { + println!("bar {}", bar::BAR); +} diff --git a/src/test/ui/unused-crate-deps/warn-attr.rs b/src/test/ui/unused-crate-deps/warn-attr.rs new file mode 100644 index 0000000000000..1acb307ab21b3 --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-attr.rs @@ -0,0 +1,10 @@ +// Check for unused crate dep, no path + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs + +#![warn(unused_crate_dependencies)] +//~^ WARNING external crate `bar` unused in + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/warn-attr.stderr b/src/test/ui/unused-crate-deps/warn-attr.stderr new file mode 100644 index 0000000000000..0d38315704b11 --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-attr.stderr @@ -0,0 +1,14 @@ +warning: external crate `bar` unused in `warn_attr`: remove the dependency or add `use bar as _;` + --> $DIR/warn-attr.rs:7:1 + | +LL | #![warn(unused_crate_dependencies)] + | ^ + | +note: the lint level is defined here + --> $DIR/warn-attr.rs:7:9 + | +LL | #![warn(unused_crate_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-static.rs b/src/test/ui/unused-crate-deps/warn-cmdline-static.rs new file mode 100644 index 0000000000000..c609529a6c6fb --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-cmdline-static.rs @@ -0,0 +1,10 @@ +// Check for unused crate dep, no path + +// edition:2018 +// check-pass +// compile-flags: -Wunused-crate-dependencies +// aux-crate:bar=bar.rs +// no-prefer-dynamic + +fn main() {} +//~^ WARNING external crate `bar` unused in diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr new file mode 100644 index 0000000000000..65956461d6439 --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr @@ -0,0 +1,10 @@ +warning: external crate `bar` unused in `warn_cmdline_static`: remove the dependency or add `use bar as _;` + --> $DIR/warn-cmdline-static.rs:9:1 + | +LL | fn main() {} + | ^ + | + = note: requested on the command line with `-W unused-crate-dependencies` + +warning: 1 warning emitted + diff --git a/src/test/ui/unused-crate-deps/warn-cmdline.rs b/src/test/ui/unused-crate-deps/warn-cmdline.rs new file mode 100644 index 0000000000000..3bae61c3ea2cc --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-cmdline.rs @@ -0,0 +1,9 @@ +// Check for unused crate dep, no path + +// edition:2018 +// check-pass +// compile-flags: -Wunused-crate-dependencies +// aux-crate:bar=bar.rs + +fn main() {} +//~^ WARNING external crate `bar` unused in diff --git a/src/test/ui/unused-crate-deps/warn-cmdline.stderr b/src/test/ui/unused-crate-deps/warn-cmdline.stderr new file mode 100644 index 0000000000000..ea675ba9a1eb1 --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-cmdline.stderr @@ -0,0 +1,10 @@ +warning: external crate `bar` unused in `warn_cmdline`: remove the dependency or add `use bar as _;` + --> $DIR/warn-cmdline.rs:8:1 + | +LL | fn main() {} + | ^ + | + = note: requested on the command line with `-W unused-crate-dependencies` + +warning: 1 warning emitted + diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 1fa46ce99f5e6..163571bc5b988 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -241,7 +241,7 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) { ALIASES = {}; finalJS += 'window = { "currentCrate": "' + crate + '" };\n'; finalJS += 'var rootPath = "../";\n'; - finalJS += loadThings(["onEach"], 'function', extractFunction, storageJs); + finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs); finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);