From 2ea0410f090ae06d18f5535e62e888e49a4f21a7 Mon Sep 17 00:00:00 2001 From: Soveu Date: Fri, 30 Apr 2021 16:13:00 +0200 Subject: [PATCH 1/5] str::is_char_boundary - slight optimization --- library/core/src/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 95dd54976b2c0..e7970bf5c8f13 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -195,11 +195,11 @@ impl str { // 0 and len are always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. - if index == 0 || index == self.len() { + if index == 0 { return true; } match self.as_bytes().get(index) { - None => false, + None => index == self.len(), // This is bit magic equivalent to: b < 128 || b >= 192 Some(&b) => (b as i8) >= -0x40, } From 7bd9d9f1e995272494854c78dd60fcd8e06487f8 Mon Sep 17 00:00:00 2001 From: Soveu Date: Fri, 30 Apr 2021 20:51:30 +0200 Subject: [PATCH 2/5] str::is_char_boundary - few comments --- library/core/src/str/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index e7970bf5c8f13..065acd3f38bb2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -192,14 +192,26 @@ impl str { #[stable(feature = "is_char_boundary", since = "1.9.0")] #[inline] pub fn is_char_boundary(&self, index: usize) -> bool { - // 0 and len are always ok. + // 0 is always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. + // Note that optimizing `self.get(..index)` relies on this. if index == 0 { return true; } + match self.as_bytes().get(index) { + // For `None` we have two options: + // + // - index == self.len() + // Empty strings are valid, so return true + // - index > self.len() + // In this case return false + // + // The check is placed exactly here, because it improves generated + // code on higher opt-levels. See PR #84751 for more details. None => index == self.len(), + // This is bit magic equivalent to: b < 128 || b >= 192 Some(&b) => (b as i8) >= -0x40, } From 46d55d65491ab57e6373d6424f432295eb2eb672 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sat, 15 May 2021 12:58:23 +0200 Subject: [PATCH 3/5] Warn about unused pub fields in non-pub structs --- compiler/rustc_passes/src/dead.rs | 49 +++++++++++-------- src/test/ui/cast/issue-84213.fixed | 1 + src/test/ui/cast/issue-84213.rs | 1 + src/test/ui/cast/issue-84213.stderr | 4 +- src/test/ui/lint/dead-code/issue-85255.rs | 22 +++++++++ src/test/ui/lint/dead-code/issue-85255.stderr | 32 ++++++++++++ 6 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/lint/dead-code/issue-85255.rs create mode 100644 src/test/ui/lint/dead-code/issue-85255.stderr diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d32180525bf70..bd142677cf9ed 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -44,6 +44,7 @@ struct MarkSymbolVisitor<'tcx> { repr_has_repr_c: bool, in_pat: bool, inherited_pub_visibility: bool, + pub_visibility: bool, ignore_variant_stack: Vec, // maps from tuple struct constructors to tuple struct items struct_constructors: FxHashMap, @@ -188,27 +189,33 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn visit_node(&mut self, node: Node<'tcx>) { let had_repr_c = self.repr_has_repr_c; - self.repr_has_repr_c = false; let had_inherited_pub_visibility = self.inherited_pub_visibility; + let had_pub_visibility = self.pub_visibility; + self.repr_has_repr_c = false; self.inherited_pub_visibility = false; + self.pub_visibility = false; match node { - Node::Item(item) => match item.kind { - hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { - let def = self.tcx.adt_def(item.def_id); - self.repr_has_repr_c = def.repr.c(); + Node::Item(item) => { + self.pub_visibility = item.vis.node.is_pub(); - intravisit::walk_item(self, &item); - } - hir::ItemKind::Enum(..) => { - self.inherited_pub_visibility = item.vis.node.is_pub(); + match item.kind { + hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { + let def = self.tcx.adt_def(item.def_id); + self.repr_has_repr_c = def.repr.c(); - intravisit::walk_item(self, &item); - } - hir::ItemKind::ForeignMod { .. } => {} - _ => { - intravisit::walk_item(self, &item); + intravisit::walk_item(self, &item); + } + hir::ItemKind::Enum(..) => { + self.inherited_pub_visibility = self.pub_visibility; + + intravisit::walk_item(self, &item); + } + hir::ItemKind::ForeignMod { .. } => {} + _ => { + intravisit::walk_item(self, &item); + } } - }, + } Node::TraitItem(trait_item) => { intravisit::walk_trait_item(self, trait_item); } @@ -220,8 +227,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } _ => {} } - self.repr_has_repr_c = had_repr_c; + self.pub_visibility = had_pub_visibility; self.inherited_pub_visibility = had_inherited_pub_visibility; + self.repr_has_repr_c = had_repr_c; } fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &[hir::ExprField<'_>]) { @@ -259,10 +267,10 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { ) { let has_repr_c = self.repr_has_repr_c; let inherited_pub_visibility = self.inherited_pub_visibility; - let live_fields = def - .fields() - .iter() - .filter(|f| has_repr_c || inherited_pub_visibility || f.vis.node.is_pub()); + let pub_visibility = self.pub_visibility; + let live_fields = def.fields().iter().filter(|f| { + has_repr_c || (pub_visibility && (inherited_pub_visibility || f.vis.node.is_pub())) + }); self.live_symbols.extend(live_fields.map(|f| f.hir_id)); intravisit::walk_struct_def(self, def); @@ -500,6 +508,7 @@ fn find_live<'tcx>( repr_has_repr_c: false, in_pat: false, inherited_pub_visibility: false, + pub_visibility: false, ignore_variant_stack: vec![], struct_constructors, }; diff --git a/src/test/ui/cast/issue-84213.fixed b/src/test/ui/cast/issue-84213.fixed index e1a60557a20c7..b5c4a77529664 100644 --- a/src/test/ui/cast/issue-84213.fixed +++ b/src/test/ui/cast/issue-84213.fixed @@ -6,6 +6,7 @@ struct Something { fn main() { let mut something = Something { field: 1337 }; + let _ = something.field; let _pointer_to_something = &something as *const Something; //~^ ERROR: non-primitive cast diff --git a/src/test/ui/cast/issue-84213.rs b/src/test/ui/cast/issue-84213.rs index 3df264bdffb6a..6eb81291abc7f 100644 --- a/src/test/ui/cast/issue-84213.rs +++ b/src/test/ui/cast/issue-84213.rs @@ -6,6 +6,7 @@ struct Something { fn main() { let mut something = Something { field: 1337 }; + let _ = something.field; let _pointer_to_something = something as *const Something; //~^ ERROR: non-primitive cast diff --git a/src/test/ui/cast/issue-84213.stderr b/src/test/ui/cast/issue-84213.stderr index a76aac580131e..1b71d4db511b5 100644 --- a/src/test/ui/cast/issue-84213.stderr +++ b/src/test/ui/cast/issue-84213.stderr @@ -1,5 +1,5 @@ error[E0605]: non-primitive cast: `Something` as `*const Something` - --> $DIR/issue-84213.rs:10:33 + --> $DIR/issue-84213.rs:11:33 | LL | let _pointer_to_something = something as *const Something; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast @@ -10,7 +10,7 @@ LL | let _pointer_to_something = &something as *const Something; | ^ error[E0605]: non-primitive cast: `Something` as `*mut Something` - --> $DIR/issue-84213.rs:13:37 + --> $DIR/issue-84213.rs:14:37 | LL | let _mut_pointer_to_something = something as *mut Something; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast diff --git a/src/test/ui/lint/dead-code/issue-85255.rs b/src/test/ui/lint/dead-code/issue-85255.rs new file mode 100644 index 0000000000000..9a4d9fbad35ba --- /dev/null +++ b/src/test/ui/lint/dead-code/issue-85255.rs @@ -0,0 +1,22 @@ +// Unused `pub` fields in non-`pub` structs should also trigger dead code warnings. +// check-pass + +#![warn(dead_code)] + +struct Foo { + a: i32, //~ WARNING: field is never read + pub b: i32, //~ WARNING: field is never read +} + +struct Bar; + +impl Bar { + fn a(&self) -> i32 { 5 } //~ WARNING: associated function is never used + pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function is never used +} + + +fn main() { + let _ = Foo { a: 1, b: 2 }; + let _ = Bar; +} diff --git a/src/test/ui/lint/dead-code/issue-85255.stderr b/src/test/ui/lint/dead-code/issue-85255.stderr new file mode 100644 index 0000000000000..7364643929533 --- /dev/null +++ b/src/test/ui/lint/dead-code/issue-85255.stderr @@ -0,0 +1,32 @@ +warning: field is never read: `a` + --> $DIR/issue-85255.rs:7:5 + | +LL | a: i32, + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-85255.rs:4:9 + | +LL | #![warn(dead_code)] + | ^^^^^^^^^ + +warning: field is never read: `b` + --> $DIR/issue-85255.rs:8:5 + | +LL | pub b: i32, + | ^^^^^^^^^^ + +warning: associated function is never used: `a` + --> $DIR/issue-85255.rs:14:8 + | +LL | fn a(&self) -> i32 { 5 } + | ^ + +warning: associated function is never used: `b` + --> $DIR/issue-85255.rs:15:12 + | +LL | pub fn b(&self) -> i32 { 6 } + | ^ + +warning: 4 warnings emitted + From c96d531a927d2f9fa927513a28135fc875b3d647 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 15 May 2021 14:22:29 +0200 Subject: [PATCH 4/5] fix version_str comment --- compiler/rustc_interface/src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index fd29053433e55..7b1660b501bf8 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -922,7 +922,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { } } -/// Returns a version string such as "rustc 1.46.0 (04488afe3 2020-08-24)" +/// Returns a version string such as "1.46.0 (04488afe3 2020-08-24)" pub fn version_str() -> Option<&'static str> { option_env!("CFG_VERSION") } From b9b67b7d5b3e50e319ad6ae3f38c4890570cc8a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 May 2021 15:51:25 +0200 Subject: [PATCH 5/5] Don't generate more docs than necessary --- src/bootstrap/doc.rs | 31 +++++++++++++------ .../docker/host-x86_64/mingw-check/Dockerfile | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index a32b92ef1af83..c4cfefb1ce8fa 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -451,6 +451,22 @@ impl Step for Std { builder.run(&mut cargo.into()); }; + + let paths = builder + .paths + .iter() + .map(components_simplified) + .filter_map(|path| { + if path.get(0) == Some(&"library") { + Some(path[1].to_owned()) + } else if !path.is_empty() { + Some(path[0].to_owned()) + } else { + None + } + }) + .collect::>(); + // Only build the following crates. While we could just iterate over the // folder structure, that would also build internal crates that we do // not want to show in documentation. These crates will later be visited @@ -464,20 +480,17 @@ impl Step for Std { let krates = ["core", "alloc", "std", "proc_macro", "test"]; for krate in &krates { run_cargo_rustdoc_for(krate); + if paths.iter().any(|p| p == krate) { + // No need to document more of the libraries if we have the one we want. + break; + } } builder.cp_r(&out_dir, &out); // Look for library/std, library/core etc in the `x.py doc` arguments and // open the corresponding rendered docs. - for path in builder.paths.iter().map(components_simplified) { - let requested_crate = if path.get(0) == Some(&"library") { - &path[1] - } else if !path.is_empty() { - &path[0] - } else { - continue; - }; - if krates.contains(&requested_crate) { + for requested_crate in paths { + if krates.iter().any(|k| *k == requested_crate.as_str()) { let index = out.join(requested_crate).join("index.html"); open(builder, &index); } diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index a9398649cf056..fd6dc563a0ec8 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -34,7 +34,7 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 2 src/tools/tidy && \ - python3 ../x.py doc --stage 0 library/std && \ + python3 ../x.py doc --stage 0 library/test && \ /scripts/validate-toolstate.sh && \ # Runs checks to ensure that there are no ES5 issues in our JS code. es-check es5 ../src/librustdoc/html/static/*.js