From 119efbcbfb42115adf04db98cf3fad20e13d25d9 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 20 May 2020 13:58:41 -0700 Subject: [PATCH 01/15] Use `is_const_fn_raw` when unsafety checking --- src/librustc_mir/transform/check_unsafety.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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), }; From 09619bc4592418aa66a77bf90c6c2efbd648d103 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 20 May 2020 14:55:38 -0700 Subject: [PATCH 02/15] Add regression test for #72394 --- src/test/ui/unsafe/unsafe-unstable-const-fn.rs | 13 +++++++++++++ src/test/ui/unsafe/unsafe-unstable-const-fn.stderr | 11 +++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/test/ui/unsafe/unsafe-unstable-const-fn.rs create mode 100644 src/test/ui/unsafe/unsafe-unstable-const-fn.stderr 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`. From b27e649537770ba6631f3347974e3ae7e082adfe Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 May 2020 16:17:07 +0200 Subject: [PATCH 03/15] add a lint against references to packed fields --- .../transform/check_packed_ref.rs | 66 +++++++++++++++++++ src/librustc_mir/transform/mod.rs | 6 +- src/librustc_session/lint/builtin.rs | 9 ++- src/test/ui/lint/packed_reference.rs | 25 +++++++ src/test/ui/lint/packed_reference.stderr | 23 +++++++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 src/librustc_mir/transform/check_packed_ref.rs create mode 100644 src/test/ui/lint/packed_reference.rs create mode 100644 src/test/ui/lint/packed_reference.stderr 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..9e07a4599f686 --- /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::PACKED_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( + PACKED_REFERENCES, + lint_root, + source_info.span, + |lint| { + lint.build(&format!("reference to packed field is not allowed",)) + .note( + "fields of packed structs might be misaligned, and creating \ + a misaligned reference is undefined behavior (even if that \ + reference is never dereferenced)", + ) + .emit() + }, + ); + } + } + } +} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 0551ed5a15ddb..7d2f890362480 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; @@ -211,10 +212,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(); @@ -230,6 +232,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_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 3d03e46683ed5..0753e9e4b7325 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -216,10 +216,16 @@ declare_lint! { "lints that have been renamed or removed" } +declare_lint! { + pub PACKED_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, @@ -545,6 +551,7 @@ declare_lint_pass! { INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, RENAMED_AND_REMOVED_LINTS, + PACKED_REFERENCES, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, MISSING_FRAGMENT_SPECIFIER, diff --git a/src/test/ui/lint/packed_reference.rs b/src/test/ui/lint/packed_reference.rs new file mode 100644 index 0000000000000..d588ffd212006 --- /dev/null +++ b/src/test/ui/lint/packed_reference.rs @@ -0,0 +1,25 @@ +#![deny(packed_references)] + +#[repr(packed)] +pub struct Good { + data: &'static u32, + data2: [&'static u32; 2], + aligned: [u8; 32], +} + +#[repr(packed)] +pub struct JustArray { + array: [u32], +} + +fn main() { + unsafe { + let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] }; + + let _ = &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/packed_reference.stderr b/src/test/ui/lint/packed_reference.stderr new file mode 100644 index 0000000000000..094fb4f34d329 --- /dev/null +++ b/src/test/ui/lint/packed_reference.stderr @@ -0,0 +1,23 @@ +error: reference to packed field is not allowed + --> $DIR/packed_reference.rs:19:17 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/packed_reference.rs:1:9 + | +LL | #![deny(packed_references)] + | ^^^^^^^^^^^^^^^^^ + = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is not allowed + --> $DIR/packed_reference.rs:20:17 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | + = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: aborting due to 2 previous errors + From c79535eab9500b87ab62f9e077db3953aa06b486 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 May 2020 16:29:27 +0200 Subject: [PATCH 04/15] remove some unused types from the tests --- src/test/ui/issues/issue-27060-rpass.rs | 11 +---------- src/test/ui/issues/issue-27060.rs | 5 ----- src/test/ui/issues/issue-27060.stderr | 6 +++--- src/test/ui/lint/packed_reference.rs | 5 ----- src/test/ui/lint/packed_reference.stderr | 4 ++-- 5 files changed, 6 insertions(+), 25 deletions(-) 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/lint/packed_reference.rs b/src/test/ui/lint/packed_reference.rs index d588ffd212006..c684fd62ee345 100644 --- a/src/test/ui/lint/packed_reference.rs +++ b/src/test/ui/lint/packed_reference.rs @@ -7,11 +7,6 @@ pub struct Good { aligned: [u8; 32], } -#[repr(packed)] -pub struct JustArray { - array: [u32], -} - fn main() { unsafe { let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] }; diff --git a/src/test/ui/lint/packed_reference.stderr b/src/test/ui/lint/packed_reference.stderr index 094fb4f34d329..428f4b66944ec 100644 --- a/src/test/ui/lint/packed_reference.stderr +++ b/src/test/ui/lint/packed_reference.stderr @@ -1,5 +1,5 @@ error: reference to packed field is not allowed - --> $DIR/packed_reference.rs:19:17 + --> $DIR/packed_reference.rs:14:17 | LL | let _ = &good.data; | ^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(packed_references)] = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) error: reference to packed field is not allowed - --> $DIR/packed_reference.rs:20:17 + --> $DIR/packed_reference.rs:15:17 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ From 061773fd2b7fd40ba7c368de50878539d30f7bb1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 25 May 2020 11:15:38 +0200 Subject: [PATCH 05/15] more test ref-to-packed tests --- src/test/ui/lint/packed_reference.rs | 2 ++ src/test/ui/lint/packed_reference.stderr | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/test/ui/lint/packed_reference.rs b/src/test/ui/lint/packed_reference.rs index c684fd62ee345..349421084682b 100644 --- a/src/test/ui/lint/packed_reference.rs +++ b/src/test/ui/lint/packed_reference.rs @@ -12,6 +12,8 @@ fn main() { 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 diff --git a/src/test/ui/lint/packed_reference.stderr b/src/test/ui/lint/packed_reference.stderr index 428f4b66944ec..51158a84175dc 100644 --- a/src/test/ui/lint/packed_reference.stderr +++ b/src/test/ui/lint/packed_reference.stderr @@ -14,10 +14,26 @@ LL | #![deny(packed_references)] error: reference to packed field is not allowed --> $DIR/packed_reference.rs:15:17 | +LL | let _ = &good.data as *const _; + | ^^^^^^^^^^ + | + = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is not allowed + --> $DIR/packed_reference.rs:16:27 + | +LL | let _: *const _ = &good.data; + | ^^^^^^^^^^ + | + = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + +error: reference to packed field is not allowed + --> $DIR/packed_reference.rs:17:17 + | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors From d959a8f91d9945302f58a8f79613e75060c6b77d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 25 May 2020 15:32:46 +0200 Subject: [PATCH 06/15] rename lint --- .../transform/check_packed_ref.rs | 8 ++-- src/librustc_session/lint/builtin.rs | 4 +- src/test/ui/lint/packed_reference.stderr | 39 ------------------- ...d_reference.rs => unaligned_references.rs} | 2 +- src/test/ui/lint/unaligned_references.stderr | 39 +++++++++++++++++++ 5 files changed, 46 insertions(+), 46 deletions(-) delete mode 100644 src/test/ui/lint/packed_reference.stderr rename src/test/ui/lint/{packed_reference.rs => unaligned_references.rs} (95%) create mode 100644 src/test/ui/lint/unaligned_references.stderr diff --git a/src/librustc_mir/transform/check_packed_ref.rs b/src/librustc_mir/transform/check_packed_ref.rs index 9e07a4599f686..faad1a72327f4 100644 --- a/src/librustc_mir/transform/check_packed_ref.rs +++ b/src/librustc_mir/transform/check_packed_ref.rs @@ -1,7 +1,7 @@ use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::lint::builtin::PACKED_REFERENCES; +use rustc_session::lint::builtin::UNALIGNED_REFERENCES; use crate::transform::{MirPass, MirSource}; use crate::util; @@ -47,13 +47,13 @@ impl<'a, 'tcx> Visitor<'tcx> for PackedRefChecker<'a, 'tcx> { .assert_crate_local() .lint_root; self.tcx.struct_span_lint_hir( - PACKED_REFERENCES, + UNALIGNED_REFERENCES, lint_root, source_info.span, |lint| { - lint.build(&format!("reference to packed field is not allowed",)) + lint.build(&format!("reference to packed field is unaligned",)) .note( - "fields of packed structs might be misaligned, and creating \ + "fields of packed structs are not properly aligned, and creating \ a misaligned reference is undefined behavior (even if that \ reference is never dereferenced)", ) diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 0753e9e4b7325..4035417204867 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -217,7 +217,7 @@ declare_lint! { } declare_lint! { - pub PACKED_REFERENCES, + pub UNALIGNED_REFERENCES, Allow, "detects unaligned references to fields of packed structs", } @@ -551,7 +551,7 @@ declare_lint_pass! { INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, RENAMED_AND_REMOVED_LINTS, - PACKED_REFERENCES, + UNALIGNED_REFERENCES, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, MISSING_FRAGMENT_SPECIFIER, diff --git a/src/test/ui/lint/packed_reference.stderr b/src/test/ui/lint/packed_reference.stderr deleted file mode 100644 index 51158a84175dc..0000000000000 --- a/src/test/ui/lint/packed_reference.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error: reference to packed field is not allowed - --> $DIR/packed_reference.rs:14:17 - | -LL | let _ = &good.data; - | ^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/packed_reference.rs:1:9 - | -LL | #![deny(packed_references)] - | ^^^^^^^^^^^^^^^^^ - = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - -error: reference to packed field is not allowed - --> $DIR/packed_reference.rs:15:17 - | -LL | let _ = &good.data as *const _; - | ^^^^^^^^^^ - | - = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - -error: reference to packed field is not allowed - --> $DIR/packed_reference.rs:16:27 - | -LL | let _: *const _ = &good.data; - | ^^^^^^^^^^ - | - = note: fields of packed structs might be misaligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - -error: reference to packed field is not allowed - --> $DIR/packed_reference.rs:17:17 - | -LL | let _ = &good.data2[0]; - | ^^^^^^^^^^^^^^ - | - = note: fields of packed structs might be misaligned, 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/lint/packed_reference.rs b/src/test/ui/lint/unaligned_references.rs similarity index 95% rename from src/test/ui/lint/packed_reference.rs rename to src/test/ui/lint/unaligned_references.rs index 349421084682b..1d9f4c3db2eb5 100644 --- a/src/test/ui/lint/packed_reference.rs +++ b/src/test/ui/lint/unaligned_references.rs @@ -1,4 +1,4 @@ -#![deny(packed_references)] +#![deny(unaligned_references)] #[repr(packed)] pub struct Good { 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 + From 91dcbbbf50baa02d0757085bb5a9bd69bae5a5a4 Mon Sep 17 00:00:00 2001 From: Samrat Man Singh Date: Mon, 25 May 2020 20:45:26 +0530 Subject: [PATCH 07/15] Allow unlabeled breaks from desugared `?` in labeled blocks --- src/librustc_passes/loops.rs | 3 ++- .../ui/label/label_break_value_desugared_break.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/label/label_break_value_desugared_break.rs 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/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; + } + }; +} From 0fdbfd3f05cdca7cdbde839c34cdcdf040009e9e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 25 May 2020 17:17:27 -0700 Subject: [PATCH 08/15] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/embedded-book | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) 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 From ffa493ab57fbb44f16efae2515abdde6876cc5c9 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 17 May 2020 01:48:01 -0700 Subject: [PATCH 09/15] Implement warning for unused dependencies. This will print a diagnostic for crates which are mentioned as `--extern` arguments on the command line, but are never referenced from the source. This diagnostic is controlled by `-Wunused-crate-dependencies` or `#![warn(unused_crate_dependencies)]` and is "allow" by default. There are cases where certain crates need to be linked in but are not directly referenced - for example if they are providing symbols for C linkage. In this case the warning can be suppressed with `use needed_crate as _;`. Thanks to @petrochenkov for simplified core. Resolves issue #57274 --- src/librustc_lint/lib.rs | 1 + src/librustc_metadata/creader.rs | 29 +++++++++++++++++++ src/librustc_session/lint/builtin.rs | 7 +++++ .../ui/unused-crate-deps/auxiliary/bar.rs | 1 + .../ui/unused-crate-deps/auxiliary/foo.rs | 5 ++++ src/test/ui/unused-crate-deps/libfib.rs | 21 ++++++++++++++ src/test/ui/unused-crate-deps/libfib.stderr | 10 +++++++ src/test/ui/unused-crate-deps/suppress.rs | 11 +++++++ .../ui/unused-crate-deps/unused-aliases.rs | 13 +++++++++ .../unused-crate-deps/unused-aliases.stderr | 14 +++++++++ .../use_extern_crate_2015.rs | 13 +++++++++ src/test/ui/unused-crate-deps/warn-attr.rs | 10 +++++++ .../ui/unused-crate-deps/warn-attr.stderr | 14 +++++++++ .../unused-crate-deps/warn-cmdline-static.rs | 10 +++++++ .../warn-cmdline-static.stderr | 10 +++++++ src/test/ui/unused-crate-deps/warn-cmdline.rs | 9 ++++++ .../ui/unused-crate-deps/warn-cmdline.stderr | 10 +++++++ 17 files changed, 188 insertions(+) create mode 100644 src/test/ui/unused-crate-deps/auxiliary/bar.rs create mode 100644 src/test/ui/unused-crate-deps/auxiliary/foo.rs create mode 100644 src/test/ui/unused-crate-deps/libfib.rs create mode 100644 src/test/ui/unused-crate-deps/libfib.stderr create mode 100644 src/test/ui/unused-crate-deps/suppress.rs create mode 100644 src/test/ui/unused-crate-deps/unused-aliases.rs create mode 100644 src/test/ui/unused-crate-deps/unused-aliases.stderr create mode 100644 src/test/ui/unused-crate-deps/use_extern_crate_2015.rs create mode 100644 src/test/ui/unused-crate-deps/warn-attr.rs create mode 100644 src/test/ui/unused-crate-deps/warn-attr.stderr create mode 100644 src/test/ui/unused-crate-deps/warn-cmdline-static.rs create mode 100644 src/test/ui/unused-crate-deps/warn-cmdline-static.stderr create mode 100644 src/test/ui/unused-crate-deps/warn-cmdline.rs create mode 100644 src/test/ui/unused-crate-deps/warn-cmdline.stderr 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_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index 3d03e46683ed5..66d8908799181 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, @@ -523,6 +529,7 @@ declare_lint_pass! { UNCONDITIONAL_PANIC, UNUSED_IMPORTS, UNUSED_EXTERN_CRATES, + UNUSED_CRATE_DEPENDENCIES, UNUSED_QUALIFICATIONS, UNKNOWN_LINTS, UNUSED_VARIABLES, 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 + From 0fa4762a807a8e637aeaa805bc705c52a1c70d13 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 17 May 2020 14:06:21 +0200 Subject: [PATCH 10/15] Move focusSearchBar and defocusSearchBar functions to the top of the file with other functions --- src/librustdoc/html/static/main.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 9869c50fbb0cf..94d74bf793e7c 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -47,6 +47,17 @@ 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"; @@ -2778,16 +2789,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 From deaf5e200e79a75ac57d3f0952f6758a38168e52 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 17 May 2020 14:49:04 +0200 Subject: [PATCH 11/15] Move "global" code into anonymous functions --- src/librustdoc/html/static/main.js | 506 +++++++++++++++-------------- 1 file changed, 258 insertions(+), 248 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 94d74bf793e7c..28003084f5700 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -450,7 +450,7 @@ function defocusSearchBar() { set_fragment(cur_line_id); } } - })(); + }()); document.addEventListener("click", function(ev) { if (hasClass(ev.target, "collapse-toggle")) { @@ -476,27 +476,29 @@ function defocusSearchBar() { } }); - 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; + url += "/" + document.getElementsByClassName("version-selector")[0].value + stripped; - document.location.href = url; - }; - } + document.location.href = url; + }; + } + }()); /** * A function to compute the Levenshtein distance between two strings @@ -2259,7 +2261,7 @@ function defocusSearchBar() { } } - 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; @@ -2279,7 +2281,7 @@ function defocusSearchBar() { if (impl_list !== null) { onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) { - collapser(e, collapse); + collapser(pageId, e, collapse); }); } @@ -2287,7 +2289,7 @@ function defocusSearchBar() { if (blanket_list !== null) { onEachLazy(blanket_list.getElementsByClassName("collapse-toggle"), function(e) { - collapser(e, collapse); + collapser(pageId, e, collapse); }); } } @@ -2311,103 +2313,7 @@ function defocusSearchBar() { 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) { @@ -2442,97 +2348,197 @@ function defocusSearchBar() { 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) { + i_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"); @@ -2547,56 +2553,60 @@ function defocusSearchBar() { 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(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 = ""; + }); + } + lineNumbersFunc(e); + }); + }()); // In the search display, allows to switch between tabs. function printTab(nb) { From 872ddf243e4a019d7d2ad5c803b21bffc34ea9cb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 17 May 2020 14:57:19 +0200 Subject: [PATCH 12/15] Reexported functions are now declared directly as "windows" field --- src/librustdoc/html/static/main.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 28003084f5700..ba308c97f30e8 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -535,7 +535,7 @@ function defocusSearchBar() { 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; @@ -1930,12 +1930,11 @@ function defocusSearchBar() { 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; @@ -1997,9 +1996,7 @@ function defocusSearchBar() { 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"); @@ -2699,7 +2696,7 @@ function defocusSearchBar() { }); } - function addSearchOptions(crates) { + window.addSearchOptions = function(crates) { var elem = document.getElementById("crate-search"); if (!elem) { @@ -2744,9 +2741,7 @@ function defocusSearchBar() { if (search_input) { search_input.removeAttribute('disabled'); }; - } - - window.addSearchOptions = addSearchOptions; + }; function buildHelperPopup() { var popup = document.createElement("aside"); From f41d284ea0b87187e84d6edab4f9a71542cfd1b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 17 May 2020 15:34:59 +0200 Subject: [PATCH 13/15] Fix eslint lints --- src/librustdoc/html/static/main.js | 54 +++++++++------------ src/librustdoc/html/static/settings.js | 3 ++ src/librustdoc/html/static/source-script.js | 2 +- src/librustdoc/html/static/storage.js | 9 +++- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ba308c97f30e8..8413f9397067f 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) { @@ -192,6 +192,7 @@ function defocusSearchBar() { 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 @@ -201,7 +202,7 @@ function defocusSearchBar() { if (browserSupportsHistoryApi()) { history.replaceState(hash, "", "?search=#" + hash); } - var elem = document.getElementById(hash); + elem = document.getElementById(hash); if (elem) { elem.scrollIntoView(); } @@ -212,7 +213,7 @@ function defocusSearchBar() { 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; } @@ -335,7 +336,7 @@ function defocusSearchBar() { } function displayHelp(display, ev, help) { - var help = help ? help : getHelpElement(); + help = help ? help : getHelpElement(); if (display === true) { if (hasClass(help, "hidden")) { ev.preventDefault(); @@ -449,7 +450,7 @@ function defocusSearchBar() { set_fragment(cur_line_id); } - } + }; }()); document.addEventListener("click", function(ev) { @@ -615,7 +616,7 @@ function defocusSearchBar() { function sortResults(results, isType) { var ar = []; for (var entry in results) { - if (results.hasOwnProperty(entry)) { + if (hasOwnProperty(results, entry)) { ar.push(results[entry]); } } @@ -1113,8 +1114,6 @@ function defocusSearchBar() { } 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; @@ -1177,7 +1176,6 @@ function defocusSearchBar() { 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)) { @@ -1674,7 +1672,7 @@ function defocusSearchBar() { 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; @@ -1722,7 +1720,7 @@ function defocusSearchBar() { var currentIndex = 0; for (var crate in rawSearchIndex) { - if (!rawSearchIndex.hasOwnProperty(crate)) { continue; } + if (!hasOwnProperty(rawSearchIndex, crate)) { continue; } var crateSize = 0; @@ -1906,7 +1904,7 @@ function defocusSearchBar() { var crates = []; for (var crate in rawSearchIndex) { - if (!rawSearchIndex.hasOwnProperty(crate)) { + if (!hasOwnProperty(rawSearchIndex, crate)) { continue; } crates.push(crate); @@ -2173,19 +2171,13 @@ function defocusSearchBar() { } } 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; } } }; @@ -2482,7 +2474,7 @@ function defocusSearchBar() { onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) { e.style.display = "inline-block"; if (extra === true) { - i_e.innerHTML = " Show " + e.childNodes[0].innerHTML; + e.innerHTML = " Show " + e.childNodes[0].innerHTML; } }); } @@ -2587,17 +2579,17 @@ function defocusSearchBar() { } onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) { if (hasClass(e, "compile_fail")) { - e.addEventListener("mouseover", function(event) { + e.addEventListener("mouseover", function() { this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00"; }); - e.addEventListener("mouseout", function(event) { + e.addEventListener("mouseout", function() { this.parentElement.previousElementSibling.childNodes[0].style.color = ""; }); } else if (hasClass(e, "ignore")) { - e.addEventListener("mouseover", function(event) { + e.addEventListener("mouseover", function() { this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200"; }); - e.addEventListener("mouseout", function(event) { + e.addEventListener("mouseout", function() { this.parentElement.previousElementSibling.childNodes[0].style.color = ""; }); } @@ -2705,7 +2697,7 @@ function defocusSearchBar() { 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); } } @@ -2740,7 +2732,7 @@ function defocusSearchBar() { if (search_input) { search_input.removeAttribute('disabled'); - }; + } }; function buildHelperPopup() { 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") { From a423d2d4b0812339e10fd5101fddb31780061903 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 26 May 2020 11:48:59 +0200 Subject: [PATCH 14/15] Improve formatting --- src/librustdoc/html/static/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 8413f9397067f..22c9426db2036 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -57,7 +57,6 @@ function defocusSearchBar() { getSearchInput().blur(); } - (function() { "use strict"; @@ -494,7 +493,8 @@ function defocusSearchBar() { 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; }; From 398511a1352ab5b6d5fd8f2c9e80b357f6b84441 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 26 May 2020 15:11:36 +0200 Subject: [PATCH 15/15] Import missing functions from storage.js --- src/tools/rustdoc-js/tester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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);