From ec91f26442aaf51ececcb054f5a4b92f7f5c0615 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 7 Mar 2019 18:38:49 -0800 Subject: [PATCH 01/34] Fix SGX implementations of read/write_vectored. --- src/libstd/sys/sgx/net.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index ab8b2681393f8..cea723f6e48e1 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -103,24 +103,22 @@ impl TcpStream { self.inner.inner.read(buf) } - pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result { - let buf = match buf.get_mut(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.read(buf) + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + match bufs.iter_mut().find(|b| !b.is_empty()) { + Some(buf) => self.read(buf), + None => Ok(0), + } } pub fn write(&self, buf: &[u8]) -> io::Result { self.inner.inner.write(buf) } - pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result { - let buf = match buf.get(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.write(buf) + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + match bufs.iter().find(|b| !b.is_empty()) { + Some(buf) => self.write(buf), + None => Ok(0), + } } pub fn peer_addr(&self) -> io::Result { From ab8e1d264e6722169d25d3f52ac2e8de172e205d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 7 Mar 2019 19:31:58 -0800 Subject: [PATCH 02/34] Always call read/write from default vectored io methods --- src/libstd/io/mod.rs | 40 +++++++++++++++++++++++---------- src/libstd/sys/redox/net/tcp.rs | 10 ++------- src/libstd/sys/sgx/net.rs | 10 ++------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e3e2754a7aa09..1a2152a79af5a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -390,6 +390,28 @@ fn read_to_end_with_reservation(r: &mut R, ret } +pub(crate) fn default_read_vectored(read: F, bufs: &mut [IoVecMut<'_>]) -> Result +where + F: FnOnce(&mut [u8]) -> Result +{ + let buf = bufs + .iter_mut() + .find(|b| !b.is_empty()) + .map_or(&mut [][..], |b| &mut **b); + read(buf) +} + +pub(crate) fn default_write_vectored(write: F, bufs: &[IoVec<'_>]) -> Result +where + F: FnOnce(&[u8]) -> Result +{ + let buf = bufs + .iter() + .find(|b| !b.is_empty()) + .map_or(&[][..], |b| &**b); + write(buf) +} + /// The `Read` trait allows for reading bytes from a source. /// /// Implementors of the `Read` trait are called 'readers'. @@ -528,14 +550,11 @@ pub trait Read { /// written to possibly being only partially filled. This method must behave /// as a single call to `read` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `read`. + /// The default implementation calls `read` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + default_read_vectored(|b| self.read(b), bufs) } /// Determines if this `Read`er can work with buffers of uninitialized @@ -1107,14 +1126,11 @@ pub trait Write { /// read from possibly being only partially consumed. This method must /// behave as a call to `write` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `write`. + /// The default implementation calls `write` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + default_write_vectored(|b| self.write(b), bufs) } /// Flush this output stream, ensuring that all intermediately buffered diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs index 5081c3de73c5a..3f2f6166a791a 100644 --- a/src/libstd/sys/redox/net/tcp.rs +++ b/src/libstd/sys/redox/net/tcp.rs @@ -35,10 +35,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> Result { @@ -46,10 +43,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn take_error(&self) -> Result> { diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index cea723f6e48e1..6021020e6f03c 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -104,10 +104,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> io::Result { @@ -115,10 +112,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn peer_addr(&self) -> io::Result { From 9aa89b25232b79b93dc122e86b8071fb14fc4e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 8 Mar 2019 19:08:28 -0800 Subject: [PATCH 03/34] When encountetring `||{}()`, suggest the likely intended `(||{})()` --- src/librustc_typeck/check/callee.rs | 35 ++++++++++++++++++- .../suggest-on-bare-closure-call.rs | 4 +++ .../suggest-on-bare-closure-call.stderr | 15 ++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/suggest-on-bare-closure-call.rs create mode 100644 src/test/ui/suggestions/suggest-on-bare-closure-call.stderr diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 0a4c0eb3aff72..15ae39600f6b4 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -2,7 +2,7 @@ use super::autoderef::Autoderef; use super::method::MethodCallee; use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag}; -use errors::Applicability; +use errors::{Applicability, DiagnosticBuilder}; use hir::def::Def; use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; @@ -232,6 +232,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None } + /// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the + /// likely intention is to call the closure, suggest `(||{})()`. (#55851) + fn identify_bad_closure_def_and_call( + &self, + err: &mut DiagnosticBuilder<'a>, + hir_id: hir::HirId, + callee_node: &hir::ExprKind, + callee_span: Span, + ) { + let hir_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id); + let parent_node = self.tcx.hir().get_by_hir_id(hir_id); + if let ( + hir::Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, _, _, sp, ..), .. }), + hir::ExprKind::Block(..), + ) = (parent_node, callee_node) { + let start = sp.shrink_to_lo(); + let end = self.tcx.sess.source_map().next_point(callee_span); + err.multipart_suggestion( + "if you meant to create this closure and immediately call it, surround the \ + closure with parenthesis", + vec![(start, "(".to_string()), (end, ")".to_string())], + Applicability::MaybeIncorrect, + ); + } + } + fn confirm_builtin_call( &self, call_expr: &hir::Expr, @@ -268,6 +294,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } ); + self.identify_bad_closure_def_and_call( + &mut err, + call_expr.hir_id, + &callee.node, + callee.span, + ); + if let Some(ref path) = unit_variant { err.span_suggestion( call_expr.span, diff --git a/src/test/ui/suggestions/suggest-on-bare-closure-call.rs b/src/test/ui/suggestions/suggest-on-bare-closure-call.rs new file mode 100644 index 0000000000000..355708c08ec2f --- /dev/null +++ b/src/test/ui/suggestions/suggest-on-bare-closure-call.rs @@ -0,0 +1,4 @@ +fn main() { + let _ = ||{}(); + //~^ ERROR expected function, found `()` +} diff --git a/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr b/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr new file mode 100644 index 0000000000000..17001e3974c6d --- /dev/null +++ b/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr @@ -0,0 +1,15 @@ +error[E0618]: expected function, found `()` + --> $DIR/suggest-on-bare-closure-call.rs:2:15 + | +LL | let _ = ||{}(); + | ^^-- + | | + | call expression requires function +help: if you meant to create this closure and immediately call it, surround the closure with parenthesis + | +LL | let _ = (||{})(); + | ^ ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0618`. From 94a6936a692ed5e6f6c6a64d622d21ea4083e051 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 9 Mar 2019 14:28:25 +0800 Subject: [PATCH 04/34] Track embedded-book in the toolstate --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 1 + src/tools/publish_toolstate.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 3343716419ff4..97e6ee25ec7a0 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -78,6 +78,7 @@ status_check() { check_dispatch $1 beta clippy-driver src/tools/clippy # these tools are not required for beta to successfully branch check_dispatch $1 nightly miri src/tools/miri + check_dispatch $1 nightly embedded-book src/doc/embedded-book } # If this PR is intended to update one of these tools, do not let the build pass diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index fb6132a5358ef..430db48954826 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -12,7 +12,7 @@ except ImportError: import urllib.request as urllib2 -# List of people to ping when the status of a tool changed. +# List of people to ping when the status of a tool or a book changed. MAINTAINERS = { 'miri': '@oli-obk @RalfJung @eddyb', 'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch', @@ -22,6 +22,7 @@ 'nomicon': '@frewsxcv @Gankro', 'reference': '@steveklabnik @Havvy @matthewjasper @alercah', 'rust-by-example': '@steveklabnik @marioidival @projektir', + 'embedded-book': '', } REPOS = { @@ -33,6 +34,7 @@ 'nomicon': 'https://github.com/rust-lang-nursery/nomicon', 'reference': 'https://github.com/rust-lang-nursery/reference', 'rust-by-example': 'https://github.com/rust-lang/rust-by-example', + 'embedded-book': 'https://github.com/rust-embedded/book', } @@ -70,7 +72,7 @@ def issue( cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization. - ''').format(relevant_pr_number, tool, REPOS[tool], relevant_pr_user, pr_reviewer), + ''').format(relevant_pr_number, tool, REPOS.get(tool), relevant_pr_user, pr_reviewer), 'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number), 'assignees': assignees, 'labels': ['T-compiler', 'I-nominated'], @@ -137,7 +139,7 @@ def update_latest( if build_failed: try: issue( - tool, MAINTAINERS.get(tool), + tool, MAINTAINERS.get(tool, ''), relevant_pr_number, relevant_pr_user, pr_reviewer, ) except IOError as e: From 967e7f4077247dab223ffd4b2e0c40341f9544a3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 9 Mar 2019 16:15:40 +0300 Subject: [PATCH 05/34] resolve: Account for new importable entities --- src/librustc_resolve/build_reduced_graph.rs | 18 +++++-------- .../uniform-paths/auxiliary/cross-crate.rs | 5 ++++ .../ui/rust-2018/uniform-paths/cross-crate.rs | 11 ++++++++ .../uniform-paths/cross-crate.stderr | 26 +++++++++++++++++++ 4 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/cross-crate.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/cross-crate.stderr diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 29de5308a3cdb..21043a52fda22 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -639,10 +639,9 @@ impl<'a> Resolver<'a> { // but metadata cannot encode gensyms currently, so we create it here. // This is only a guess, two equivalent idents may incorrectly get different gensyms here. let ident = ident.gensym_if_underscore(); - let def_id = def.def_id(); let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene match def { - Def::Mod(..) | Def::Enum(..) => { + Def::Mod(def_id) | Def::Enum(def_id) => { let module = self.new_module(parent, ModuleKind::Def(def, ident.name), def_id, @@ -650,13 +649,14 @@ impl<'a> Resolver<'a> { span); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); } - Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) => { + Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) | Def::Existential(..) | + Def::TraitAlias(..) | Def::PrimTy(..) | Def::ToolMod => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); } Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::VariantCtor(..) => { self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion)); } - Def::StructCtor(..) => { + Def::StructCtor(def_id, ..) => { self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion)); if let Some(struct_def_id) = @@ -665,7 +665,7 @@ impl<'a> Resolver<'a> { self.struct_constructors.insert(struct_def_id, (def, vis)); } } - Def::Trait(..) => { + Def::Trait(def_id) => { let module_kind = ModuleKind::Def(def, ident.name); let module = self.new_module(parent, module_kind, @@ -686,18 +686,14 @@ impl<'a> Resolver<'a> { } module.populated.set(true); } - Def::Existential(..) | - Def::TraitAlias(..) => { - self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); - } - Def::Struct(..) | Def::Union(..) => { + Def::Struct(def_id) | Def::Union(def_id) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); // Record field names for error reporting. let field_names = self.cstore.struct_field_names_untracked(def_id); self.insert_field_names(def_id, field_names); } - Def::Macro(..) => { + Def::Macro(..) | Def::NonMacroAttr(..) => { self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion)); } _ => bug!("unexpected definition: {:?}", def) diff --git a/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs new file mode 100644 index 0000000000000..4aa5d1870000d --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs @@ -0,0 +1,5 @@ +// edition:2018 + +pub use ignore as built_in_attr; +pub use u8 as built_in_type; +pub use rustfmt as tool_mod; diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs new file mode 100644 index 0000000000000..27d6dbf4683e3 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs @@ -0,0 +1,11 @@ +// edition:2018 +// aux-build:cross-crate.rs + +extern crate cross_crate; +use cross_crate::*; + +#[built_in_attr] //~ ERROR cannot use a built-in attribute through an import +#[tool_mod::skip] //~ ERROR cannot use a tool module through an import +fn main() { + let _: built_in_type; // OK +} diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr new file mode 100644 index 0000000000000..ccf66b54c529c --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr @@ -0,0 +1,26 @@ +error: cannot use a built-in attribute through an import + --> $DIR/cross-crate.rs:7:3 + | +LL | #[built_in_attr] //~ ERROR cannot use a built-in attribute through an import + | ^^^^^^^^^^^^^ + | +note: the built-in attribute imported here + --> $DIR/cross-crate.rs:5:5 + | +LL | use cross_crate::*; + | ^^^^^^^^^^^^^^ + +error: cannot use a tool module through an import + --> $DIR/cross-crate.rs:8:3 + | +LL | #[tool_mod::skip] //~ ERROR cannot use a tool module through an import + | ^^^^^^^^ + | +note: the tool module imported here + --> $DIR/cross-crate.rs:5:5 + | +LL | use cross_crate::*; + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From a4ea08420cde12ea0943cafb1505e512c5820f70 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 8 Mar 2019 21:12:12 -0800 Subject: [PATCH 06/34] Avoid some common false positives in intra doc link checking --- src/librustdoc/passes/collect_intra_doc_links.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c346714ab485a..c3d2e63319a95 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -291,6 +291,12 @@ impl<'a, 'tcx, 'rcx> DocFolder for LinkCollector<'a, 'tcx, 'rcx> { if ori_link.contains('/') { continue; } + + // [] is mostly likely not supposed to be a link + if ori_link.is_empty() { + continue; + } + let link = ori_link.replace("`", ""); let (def, fragment) = { let mut kind = PathKind::Unknown; From 3a83cb2c9ba2acca0577a5f4a092d7fc5b243faf Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sat, 9 Mar 2019 03:39:23 +0000 Subject: [PATCH 07/34] Fix ICE in MIR pretty printing A `Def::Variant` should be considered as a function in mir pretty printing. Each variant has a constructor that we must print. Given the following enum definition: ``` pub enum TestMe { X(usize), } ``` We will need to generate a constructor for the variant `X` with a signature that looks something like the following: ``` fn TestMe::X(_1: usize) -> TestMe; ``` --- src/librustc_mir/util/pretty.rs | 4 +++- src/test/mir-opt/unusual-item-types.rs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c3fbee3a2a6e5..af49f61ae86c7 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -1,4 +1,5 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def::CtorKind; use rustc::mir::*; use rustc::mir::visit::Visitor; use rustc::ty::{self, TyCtxt}; @@ -597,7 +598,8 @@ fn write_mir_sig( trace!("write_mir_sig: {:?}", src.instance); let descr = tcx.describe_def(src.def_id()); let is_function = match descr { - Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true, + Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) | + Some(Def::StructCtor(_, CtorKind::Fn)) => true, _ => tcx.is_closure(src.def_id()), }; match (descr, src.promoted) { diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs index fe85baa048e39..ced30381fda68 100644 --- a/src/test/mir-opt/unusual-item-types.rs +++ b/src/test/mir-opt/unusual-item-types.rs @@ -7,11 +7,18 @@ impl A { const ASSOCIATED_CONSTANT: i32 = 2; } +// See #59021 +enum Test { + X(usize), + Y { a: usize }, +} + enum E { V = 5, } fn main() { + let f = Test::X as fn(usize) -> Test; let v = Vec::::new(); } @@ -64,3 +71,14 @@ fn main() { // _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5]; // } // END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir + +// START rustc.Test-X.mir_map.0.mir +// fn Test::X(_1: usize) -> Test { +// let mut _0: Test; +// +// bb0: { +// _0 = Test::X(move _1,); +// return; +// } +// } +// END rustc.Test-X.mir_map.0.mir From 135b686db41f67c4241144e25277a90092b014f4 Mon Sep 17 00:00:00 2001 From: James Munns Date: Sun, 10 Mar 2019 17:38:16 +0800 Subject: [PATCH 08/34] Update src/tools/publish_toolstate.py Co-Authored-By: kennytm --- src/tools/publish_toolstate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 430db48954826..6e06034db599a 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -22,7 +22,7 @@ 'nomicon': '@frewsxcv @Gankro', 'reference': '@steveklabnik @Havvy @matthewjasper @alercah', 'rust-by-example': '@steveklabnik @marioidival @projektir', - 'embedded-book': '', + 'embedded-book': '@adamgreig @andre-richter @jamesmunns @korken89 @ryankurte @thejpster @therealprof', } REPOS = { From d6f51006cd47ca3f1ccacc4e0faa345877653b81 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 10 Mar 2019 18:02:40 +0800 Subject: [PATCH 09/34] Fix tidy --- src/tools/publish_toolstate.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 6e06034db599a..f2a585e627307 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -22,7 +22,10 @@ 'nomicon': '@frewsxcv @Gankro', 'reference': '@steveklabnik @Havvy @matthewjasper @alercah', 'rust-by-example': '@steveklabnik @marioidival @projektir', - 'embedded-book': '@adamgreig @andre-richter @jamesmunns @korken89 @ryankurte @thejpster @therealprof', + 'embedded-book': ( + '@adamgreig @andre-richter @jamesmunns @korken89 ' + '@ryankurte @thejpster @therealprof' + ), } REPOS = { From 8371377d16d12bff9d8a219ae85849c686917125 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 9 Mar 2019 15:48:58 -0800 Subject: [PATCH 10/34] CI: Set job names. This should make it easier to identify what each job is doing when looking at the Travis or Appveyor UI. - Set `name` for each job in Travis. - Move `CI_JOB_NAME` to the front in Appveyor so that it appears first in the UI. --- .travis.yml | 54 ++++++++++++++++++++++++++++++++++++++++++++------ appveyor.yml | 56 ++++++++++++++++++++++++++-------------------------- 2 files changed, 76 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7985b6c0e191f..7a8772d7abd63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,20 +12,27 @@ git: depth: 2 submodules: false +env: + global: + - CI_JOB_NAME=$TRAVIS_JOB_NAME + matrix: fast_finish: true include: # Images used in testing PR and try-build should be run first. - env: IMAGE=x86_64-gnu-llvm-6.0 RUST_BACKTRACE=1 + name: x86_64-gnu-llvm-6.0 if: type = pull_request OR branch = auto - env: IMAGE=dist-x86_64-linux DEPLOY=1 + name: dist-x86_64-linux if: branch = try OR branch = auto # "alternate" deployments, these are "nightlies" but have LLVM assertions # turned on, they're deployed to a different location primarily for # additional testing. - - env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1 CI_JOB_NAME=dist-x86_64-linux-alt + - env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1 + name: dist-x86_64-linux-alt if: branch = try OR branch = auto - env: > @@ -37,9 +44,9 @@ matrix: MACOSX_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 - CI_JOB_NAME=dist-x86_64-apple-alt os: osx osx_image: xcode9.3-moar + name: dist-x86_64-apple-alt if: branch = auto # macOS builders. These are placed near the beginning because they are very @@ -60,9 +67,9 @@ matrix: MACOSX_STD_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 - CI_JOB_NAME=x86_64-apple os: osx osx_image: xcode9.3-moar + name: x86_64-apple if: branch = auto - env: > @@ -74,9 +81,9 @@ matrix: MACOSX_STD_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 - CI_JOB_NAME=i686-apple os: osx osx_image: xcode9.3-moar + name: i686-apple if: branch = auto # OSX builders producing releases. These do not run the full test suite and @@ -95,9 +102,9 @@ matrix: NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 DIST_REQUIRE_ALL_TOOLS=1 - CI_JOB_NAME=dist-i686-apple os: osx osx_image: xcode9.3-moar + name: dist-i686-apple if: branch = auto - env: > @@ -110,81 +117,116 @@ matrix: NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 DIST_REQUIRE_ALL_TOOLS=1 - CI_JOB_NAME=dist-x86_64-apple os: osx osx_image: xcode9.3-moar + name: dist-x86_64-apple if: branch = auto # Linux builders, remaining docker images - env: IMAGE=arm-android + name: arm-android if: branch = auto - env: IMAGE=armhf-gnu + name: armhf-gnu if: branch = auto - env: IMAGE=dist-various-1 DEPLOY=1 + name: dist-various-1 if: branch = auto - env: IMAGE=dist-various-2 DEPLOY=1 + name: dist-various-2 if: branch = auto - env: IMAGE=dist-aarch64-linux DEPLOY=1 + name: dist-aarch64-linux if: branch = auto - env: IMAGE=dist-android DEPLOY=1 + name: dist-android if: branch = auto - env: IMAGE=dist-arm-linux DEPLOY=1 + name: dist-arm-linux if: branch = auto - env: IMAGE=dist-armhf-linux DEPLOY=1 + name: dist-armhf-linux if: branch = auto - env: IMAGE=dist-armv7-linux DEPLOY=1 + name: dist-armv7-linux if: branch = auto - env: IMAGE=dist-i586-gnu-i586-i686-musl DEPLOY=1 + name: dist-i586-gnu-i586-i686-musl if: branch = auto - env: IMAGE=dist-i686-freebsd DEPLOY=1 + name: dist-i686-freebsd if: branch = auto - env: IMAGE=dist-i686-linux DEPLOY=1 + name: dist-i686-linux if: branch = auto - env: IMAGE=dist-mips-linux DEPLOY=1 + name: dist-mips-linux if: branch = auto - env: IMAGE=dist-mips64-linux DEPLOY=1 + name: dist-mips64-linux if: branch = auto - env: IMAGE=dist-mips64el-linux DEPLOY=1 + name: dist-mips64el-linux if: branch = auto - env: IMAGE=dist-mipsel-linux DEPLOY=1 + name: dist-mipsel-linux if: branch = auto - env: IMAGE=dist-powerpc-linux DEPLOY=1 + name: dist-powerpc-linux if: branch = auto - env: IMAGE=dist-powerpc64-linux DEPLOY=1 + name: dist-powerpc64-linux if: branch = auto - env: IMAGE=dist-powerpc64le-linux DEPLOY=1 + name: dist-powerpc64le-linux if: branch = auto - env: IMAGE=dist-s390x-linux DEPLOY=1 + name: dist-s390x-linux if: branch = auto - env: IMAGE=dist-x86_64-freebsd DEPLOY=1 + name: dist-x86_64-freebsd if: branch = auto - env: IMAGE=dist-x86_64-musl DEPLOY=1 + name: dist-x86_64-musl if: branch = auto - env: IMAGE=dist-x86_64-netbsd DEPLOY=1 + name: dist-x86_64-netbsd if: branch = auto - env: IMAGE=asmjs + name: asmjs if: branch = auto - env: IMAGE=i686-gnu + name: i686-gnu if: branch = auto - env: IMAGE=i686-gnu-nopt + name: i686-gnu-nopt if: branch = auto - env: IMAGE=test-various + name: test-various if: branch = auto - env: IMAGE=x86_64-gnu + name: x86_64-gnu if: branch = auto - env: IMAGE=x86_64-gnu-full-bootstrap + name: x86_64-gnu-full-bootstrap if: branch = auto - env: IMAGE=x86_64-gnu-aux + name: x86_64-gnu-aux if: branch = auto - env: IMAGE=x86_64-gnu-tools + name: x86_64-gnu-tools if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/) - env: IMAGE=x86_64-gnu-debug + name: x86_64-gnu-debug if: branch = auto - env: IMAGE=x86_64-gnu-nopt + name: x86_64-gnu-nopt if: branch = auto - env: IMAGE=x86_64-gnu-distcheck + name: x86_64-gnu-distcheck if: branch = auto - env: IMAGE=mingw-check + name: mingw-check if: type = pull_request OR branch = auto - stage: publish toolstate diff --git a/appveyor.yml b/appveyor.yml index d70ad54b1c812..040e21cba9682 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,34 +7,34 @@ environment: matrix: # 32/64 bit MSVC tests - - MSYS_BITS: 64 + - CI_JOB_NAME: x86_64-msvc + MSYS_BITS: 64 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler SCRIPT: python x.py test - CI_JOB_NAME: x86_64-msvc - - MSYS_BITS: 32 + - CI_JOB_NAME: i686-msvc-1 + MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc SCRIPT: make appveyor-subset-1 - CI_JOB_NAME: i686-msvc-1 - - MSYS_BITS: 32 + - CI_JOB_NAME: i686-msvc-2 + MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc SCRIPT: make appveyor-subset-2 - CI_JOB_NAME: i686-msvc-2 # MSVC aux tests - - MSYS_BITS: 64 + - CI_JOB_NAME: x86_64-msvc-aux + MSYS_BITS: 64 RUST_CHECK_TARGET: check-aux EXCLUDE_CARGO=1 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc - CI_JOB_NAME: x86_64-msvc-aux - - MSYS_BITS: 64 + - CI_JOB_NAME: x86_64-msvc-cargo + MSYS_BITS: 64 SCRIPT: python x.py test src/tools/cargotest src/tools/cargo RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc - CI_JOB_NAME: x86_64-msvc-cargo # MSVC tools tests - - MSYS_BITS: 64 + - CI_JOB_NAME: x86_64-msvc-tools + MSYS_BITS: 64 SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri - CI_JOB_NAME: x86_64-msvc-tools # 32/64-bit MinGW builds. # @@ -49,30 +49,31 @@ environment: # bucket, but they cleraly didn't originate there! The downloads originally # came from the mingw-w64 SourceForge download site. Unfortunately # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. - - MSYS_BITS: 32 + - CI_JOB_NAME: i686-mingw-1 + MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make appveyor-subset-1 MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 - CI_JOB_NAME: i686-mingw-1 - - MSYS_BITS: 32 + - CI_JOB_NAME: i686-mingw-2 + MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu SCRIPT: make appveyor-subset-2 MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 - CI_JOB_NAME: i686-mingw-2 - - MSYS_BITS: 64 + - CI_JOB_NAME: x86_64-mingw + MSYS_BITS: 64 SCRIPT: python x.py test RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z MINGW_DIR: mingw64 - CI_JOB_NAME: x86_64-mingw # 32/64 bit MSVC and GNU deployment - - RUST_CONFIGURE_ARGS: > + - CI_JOB_NAME: dist-x86_64-msvc + RUST_CONFIGURE_ARGS: > --build=x86_64-pc-windows-msvc --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc --enable-full-tools @@ -80,9 +81,9 @@ environment: SCRIPT: python x.py dist DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 - CI_JOB_NAME: dist-x86_64-msvc APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview - - RUST_CONFIGURE_ARGS: > + - CI_JOB_NAME: dist-i686-msvc + RUST_CONFIGURE_ARGS: > --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc --enable-full-tools @@ -90,8 +91,8 @@ environment: SCRIPT: python x.py dist DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 - CI_JOB_NAME: dist-i686-msvc - - MSYS_BITS: 32 + - CI_JOB_NAME: dist-i686-mingw + MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools SCRIPT: python x.py dist MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror @@ -99,8 +100,8 @@ environment: MINGW_DIR: mingw32 DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 - CI_JOB_NAME: dist-i686-mingw - - MSYS_BITS: 64 + - CI_JOB_NAME: dist-x86_64-mingw + MSYS_BITS: 64 SCRIPT: python x.py dist RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror @@ -108,14 +109,13 @@ environment: MINGW_DIR: mingw64 DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 - CI_JOB_NAME: dist-x86_64-mingw # "alternate" deployment, see .travis.yml for more info - - MSYS_BITS: 64 + - CI_JOB_NAME: dist-x86_64-msvc-alt + MSYS_BITS: 64 RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist DEPLOY_ALT: 1 - CI_JOB_NAME: dist-x86_64-msvc-alt matrix: fast_finish: true From 4888b1fb99f1bf6a58bebaededdfbf4477383634 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:45:45 +0100 Subject: [PATCH 11/34] we can now skip should_panic tests with the libtest harness --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/btree/map.rs | 5 ----- src/liballoc/tests/slice.rs | 18 ------------------ src/liballoc/tests/str.rs | 11 ----------- src/liballoc/tests/string.rs | 9 --------- src/liballoc/tests/vec.rs | 12 ------------ src/liballoc/tests/vec_deque.rs | 1 - src/libcore/tests/cell.rs | 3 --- src/libcore/tests/iter.rs | 2 -- src/libcore/tests/num/bignum.rs | 14 -------------- src/libcore/tests/option.rs | 3 --- src/libcore/tests/result.rs | 3 --- src/libcore/tests/slice.rs | 7 ------- src/libcore/tests/time.rs | 2 -- 14 files changed, 1 insertion(+), 91 deletions(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 1d4a3edc1ac42..a97a790f5a2d8 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index f14750089c956..844afe870766b 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_equal_excluded() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(2), Excluded(2))); @@ -234,7 +233,6 @@ fn test_range_equal_excluded() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_1() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Included(2))); @@ -242,7 +240,6 @@ fn test_range_backwards_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_2() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Excluded(2))); @@ -250,7 +247,6 @@ fn test_range_backwards_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_3() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Included(2))); @@ -258,7 +254,6 @@ fn test_range_backwards_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_4() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Excluded(2))); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index feba46b0fad78..fb99c95fc6842 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -258,7 +258,6 @@ fn test_swap_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_fail() { let mut v = vec![1]; let _ = v.swap_remove(0); @@ -632,7 +631,6 @@ fn test_insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_insert_oob() { let mut a = vec![1, 2, 3]; a.insert(4, 5); @@ -657,7 +655,6 @@ fn test_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_remove_fail() { let mut a = vec![1]; let _ = a.remove(0); @@ -939,7 +936,6 @@ fn test_windowsator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_windowsator_0() { let v = &[1, 2, 3, 4]; let _it = v.windows(0); @@ -964,7 +960,6 @@ fn test_chunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks(0); @@ -989,7 +984,6 @@ fn test_chunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks_exact(0); @@ -1014,7 +1008,6 @@ fn test_rchunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks(0); @@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks_exact(0); @@ -1092,7 +1084,6 @@ fn test_vec_default() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; v.reserve_exact(!0); @@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; v.reserve_exact(!0); @@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_mut(0); @@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_exact_mut(0); @@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_mut(0); @@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_exact_mut(0); @@ -1411,7 +1397,6 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] -#[cfg(not(miri))] // Miri does not support panics fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1476,7 +1461,6 @@ fn test_copy_from_slice() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_longer() { let src = [0, 1, 2, 3]; let mut dst = [0; 5]; @@ -1485,7 +1469,6 @@ fn test_copy_from_slice_dst_longer() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_shorter() { let src = [0, 1, 2, 3]; let mut dst = [0; 3]; @@ -1605,7 +1588,6 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads -#[cfg(not(miri))] // Miri does not support panics fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..f2dc19a42296a 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -351,7 +351,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of bounds")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!("abc", 0..5, "abc"); } @@ -361,7 +360,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!("abc", 0..2, "abc"); } @@ -409,7 +407,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v: String = $data.into(); let v: &str = &v; @@ -418,7 +415,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v: String = $data.into(); let v: &mut str = &mut v; @@ -514,7 +510,6 @@ mod slice_index { #[test] #[should_panic] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail() { &"中华Việt Nam"[0..2]; } @@ -666,14 +661,12 @@ mod slice_index { // check the panic includes the prefix of the sliced string #[test] #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_1() { &LOREM_PARAGRAPH[..1024]; } // check the truncation in the panic message #[test] #[should_panic(expected="luctus, im`[...]")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_2() { &LOREM_PARAGRAPH[..1024]; } @@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; @@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; @@ -894,7 +885,6 @@ fn test_as_bytes() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_as_bytes_fail() { // Don't double free. (I'm not sure if this exercises the // original problem code path anymore.) @@ -984,7 +974,6 @@ fn test_split_at_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; s.split_at(1); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 7e93d84fe3b97..7e75b8c4f28c8 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -231,7 +231,6 @@ fn test_split_off_empty() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_past_end() { let orig = "Hello, world!"; let mut split = String::from(orig); @@ -240,7 +239,6 @@ fn test_split_off_past_end() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_mid_char() { let mut orig = String::from("山"); orig.split_off(1); @@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_truncate_split_codepoint() { let mut s = String::from("\u{FC}"); // ü s.truncate(1); @@ -324,7 +321,6 @@ fn remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn remove_bad() { "ศ".to_string().remove(1); } @@ -360,13 +356,11 @@ fn insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad1() { "".to_string().insert(1, 't'); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad2() { "ệ".to_string().insert(1, 't'); } @@ -447,7 +441,6 @@ fn test_replace_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_char_boundary() { let mut s = "Hello, 世界!".to_owned(); s.replace_range(..8, ""); @@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..6, "789"); @@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..=5, "789"); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 6e4ca1d90e642..545332bcd6a2f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -368,7 +368,6 @@ fn test_vec_truncate_drop() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_vec_truncate_fail() { struct BadElem(i32); impl Drop for BadElem { @@ -392,7 +391,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let vec = vec![1, 2, 3]; let _ = vec[3]; @@ -400,7 +398,6 @@ fn test_index_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_1() { let x = vec![1, 2, 3, 4, 5]; &x[!0..]; @@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_2() { let x = vec![1, 2, 3, 4, 5]; &x[..6]; @@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_3() { let x = vec![1, 2, 3, 4, 5]; &x[!0..4]; @@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_4() { let x = vec![1, 2, 3, 4, 5]; &x[1..6]; @@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_5() { let x = vec![1, 2, 3, 4, 5]; &x[3..2]; @@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_empty() { let mut vec = Vec::::new(); vec.swap_remove(0); @@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..6); @@ -585,7 +576,6 @@ fn test_drain_max_vec_size() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..=5); @@ -615,7 +605,6 @@ fn test_splice_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; @@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 16ddc1444fcf9..e0fe10a55f55c 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -108,7 +108,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..56f295dff8e43 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn discard_doesnt_unborrow() { let x = RefCell::new(0); let _b = x.borrow(); @@ -350,7 +349,6 @@ fn refcell_ref_coercion() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_swap_borrows() { let x = RefCell::new(0); let _b = x.borrow(); @@ -360,7 +358,6 @@ fn refcell_swap_borrows() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_replace_borrows() { let x = RefCell::new(0); let _b = x.borrow(); diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index d880abb181c20..4652fc329dc02 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_iterator_step_by_zero() { let mut it = (0..).step_by(0); it.next(); @@ -1414,7 +1413,6 @@ fn test_rposition() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rposition_panic() { let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs index 956c22c998219..b873f1dd0652f 100644 --- a/src/libcore/tests/num/bignum.rs +++ b/src/libcore/tests/num/bignum.rs @@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big; #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_from_u64_overflow() { Big::from_u64(0x1000000); } @@ -20,14 +19,12 @@ fn test_add() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_1() { Big::from_small(1).add(&Big::from_u64(0xffffff)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_2() { Big::from_u64(0xffffff).add(&Big::from_small(1)); } @@ -45,7 +42,6 @@ fn test_add_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_small_overflow() { Big::from_u64(0xffffff).add_small(1); } @@ -61,14 +57,12 @@ fn test_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_1() { Big::from_u64(0x10665).sub(&Big::from_u64(0x10666)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_2() { Big::from_small(0).sub(&Big::from_u64(0x123456)); } @@ -82,7 +76,6 @@ fn test_mul_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_small_overflow() { Big::from_u64(0x800000).mul_small(2); } @@ -101,14 +94,12 @@ fn test_mul_pow2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_1() { Big::from_u64(0x1).mul_pow2(24); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_2() { Big::from_u64(0x123).mul_pow2(16); } @@ -127,14 +118,12 @@ fn test_mul_pow5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_1() { Big::from_small(1).mul_pow5(12); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_2() { Big::from_small(230).mul_pow5(8); } @@ -152,14 +141,12 @@ fn test_mul_digits() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_1() { Big::from_u64(0x800000).mul_digits(&[2]); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_2() { Big::from_u64(0x1000).mul_digits(&[0, 0x10]); } @@ -219,7 +206,6 @@ fn test_get_bit() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_get_bit_out_of_range() { Big::from_small(42).get_bit(24); } diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 87ce2720c5918..b059b134868d9 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -69,7 +69,6 @@ fn test_option_dance() { } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_option_too_much_dance() { struct A; let mut y = Some(A); @@ -130,7 +129,6 @@ fn test_unwrap() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic1() { let x: Option = None; x.unwrap(); @@ -138,7 +136,6 @@ fn test_unwrap_panic1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic2() { let x: Option = None; x.unwrap(); diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index bbc8568517667..1fab07526a07f 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -117,7 +117,6 @@ fn test_unwrap_or_else() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { if msg == "I got this." { @@ -139,7 +138,6 @@ pub fn test_expect_ok() { } #[test] #[should_panic(expected="Got expected error: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); @@ -153,7 +151,6 @@ pub fn test_expect_err_err() { } #[test] #[should_panic(expected="Got expected ok: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 31d16e0e32057..ac9c17a0f7c35 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -782,7 +782,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of range")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]); } @@ -792,7 +791,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]); } @@ -842,7 +840,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v = $data; let v: &[_] = &v; @@ -851,7 +848,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v = $data; let v: &mut [_] = &mut v; @@ -1304,7 +1300,6 @@ fn test_copy_within() { #[test] #[should_panic(expected = "src is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so 14 is out of bounds. @@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() { #[test] #[should_panic(expected = "dest is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_dest_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. @@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() { } #[test] #[should_panic(expected = "src end is before src start")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_inverted() { let mut bytes = *b"Hello, World!"; // 2 is greater than 1, so this range is invalid. diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 09aae4583482f..6efd22572dc18 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -107,14 +107,12 @@ fn checked_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad1() { let _ = Duration::new(0, 0) - Duration::new(0, 1); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad2() { let _ = Duration::new(0, 0) - Duration::new(1, 0); } From 52d9fa827d3cf5ef5fc0e2042ca1fc7f6dc391ed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:52:45 +0100 Subject: [PATCH 12/34] enabled too many tests --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/slice.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index a97a790f5a2d8..0930f8dacd494 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support entropy +#[cfg(not(miri))] // Miri does not support panics nor entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index fb99c95fc6842..b54c128a0249a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1397,6 +1397,7 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads nor entropy fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1588,6 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads +#[cfg(not(miri))] // Miri does not support threads nor entropy fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { From 8629fd3e4e5184852352ea1bb18bb1c8465ffac3 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 9 Feb 2019 22:16:58 +0000 Subject: [PATCH 13/34] Improvements to comments in libstd, libcore, liballoc. --- src/libcore/iter/adapters/mod.rs | 4 ++-- src/libcore/mem.rs | 9 ++++++--- src/libcore/num/dec2flt/algorithm.rs | 2 +- src/libcore/num/dec2flt/mod.rs | 6 +++--- src/libcore/num/dec2flt/parse.rs | 2 +- src/libcore/num/flt2dec/decoder.rs | 2 +- src/libcore/num/flt2dec/mod.rs | 14 +++++++------- src/libcore/pin.rs | 2 +- src/libcore/str/mod.rs | 8 ++++---- src/libcore/task/wake.rs | 2 +- src/libstd/collections/hash/map.rs | 2 +- src/libstd/collections/hash/set.rs | 2 +- src/libstd/fs.rs | 2 +- src/libstd/sync/condvar.rs | 12 ++++++------ src/libstd/sys/windows/pipe.rs | 6 +++--- 15 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index d4ad22c16bbfa..cccd51b577930 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1198,7 +1198,7 @@ impl Peekable { } } -/// An iterator that rejects elements while `predicate` is true. +/// An iterator that rejects elements while `predicate` returns `true`. /// /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its /// documentation for more. @@ -1286,7 +1286,7 @@ impl Iterator for SkipWhile impl FusedIterator for SkipWhile where I: FusedIterator, P: FnMut(&I::Item) -> bool {} -/// An iterator that only accepts elements while `predicate` is true. +/// An iterator that only accepts elements while `predicate` returns `true`. /// /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its /// documentation for more. diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 90e84d0b28c3b..3d2fcdc979377 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1111,11 +1111,12 @@ impl DerefMut for ManuallyDrop { /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. +// // FIXME before stabilizing, explain how to initialize a struct field-by-field. #[allow(missing_debug_implementations)] #[unstable(feature = "maybe_uninit", issue = "53491")] #[derive(Copy)] -// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`. +// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`. pub union MaybeUninit { uninit: (), value: ManuallyDrop, @@ -1125,13 +1126,13 @@ pub union MaybeUninit { impl Clone for MaybeUninit { #[inline(always)] fn clone(&self) -> Self { - // Not calling T::clone(), we cannot know if we are initialized enough for that. + // Not calling `T::clone()`, we cannot know if we are initialized enough for that. *self } } impl MaybeUninit { - /// Create a new `MaybeUninit` initialized with the given value. + /// Creates a new `MaybeUninit` initialized with the given value. /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. @@ -1239,6 +1240,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] @@ -1277,6 +1279,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs index 3b57bb7544b35..a83134a6b2ca4 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -326,7 +326,7 @@ pub fn algorithm_m(f: &Big, e: i16) -> T { round_by_remainder(v, rem, q, z) } -/// Skip over most Algorithm M iterations by checking the bit length. +/// Skips over most Algorithm M iterations by checking the bit length. fn quick_start(u: &mut Big, v: &mut Big, k: &mut i16) { // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v). // The estimate is off by at most 1, but always an under-estimate, so the error on log(u) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 47ea5aa5ff000..d62cdae0688be 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -304,8 +304,8 @@ fn simplify(decimal: &mut Decimal) { } } -/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and -/// Algorithm M will compute while working on the given decimal. +/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R +/// and Algorithm M will compute while working on the given decimal. fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { // We don't need to worry too much about overflow here thanks to trivial_cases() and the // parser, which filter out the most extreme inputs for us. @@ -324,7 +324,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { } } -/// Detect obvious overflows and underflows without even looking at the decimal digits. +/// Detects obvious overflows and underflows without even looking at the decimal digits. fn trivial_cases(decimal: &Decimal) -> Option { // There were zeros but they were stripped by simplify() if decimal.integral.is_empty() && decimal.fractional.is_empty() { diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 933f8c1d3f781..f970595452ec9 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -78,7 +78,7 @@ pub fn parse_decimal(s: &str) -> ParseResult { } } -/// Carve off decimal digits up to the first non-digit character. +/// Carves off decimal digits up to the first non-digit character. fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) { let mut i = 0; while i < s.len() && b'0' <= s[i] && s[i] <= b'9' { diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index a3bf783976bbd..a8da31d3e4858 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -10,7 +10,7 @@ use num::dec2flt::rawfp::RawFloat; /// /// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will /// round to the original value. The range is inclusive only when -/// `inclusive` is true. +/// `inclusive` is `true`. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Decoded { /// The scaled mantissa. diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index f9b46a12f7fef..defd4247f4ea4 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -315,15 +315,15 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, } } -/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form -/// with at least given number of significant digits. When `upper` is true, +/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential +/// form with at least the given number of significant digits. When `upper` is `true`, /// the exponent will be prefixed by `E`; otherwise that's `e`. The result is /// stored to the supplied parts array and a slice of written parts is returned. /// /// `min_digits` can be less than the number of actual significant digits in `buf`; /// it will be ignored and full digits will be printed. It is only used to print -/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that -/// it will only print given digits and nothing else. +/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that +/// it will only print the given digits and nothing else. fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool, parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { assert!(!buf.is_empty()); @@ -384,7 +384,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static } } -/// Formats given floating point number into the decimal form with at least +/// Formats the given floating point number into the decimal form with at least /// given number of fractional digits. The result is stored to the supplied parts /// array while utilizing given byte buffer as a scratch. `upper` is currently /// unused but left for the future decision to change the case of non-finite values, @@ -438,7 +438,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Formats given floating point number into the decimal form or +/// Formats the given floating point number into the decimal form or /// the exponential form, depending on the resulting exponent. The result is /// stored to the supplied parts array while utilizing given byte buffer /// as a scratch. `upper` is used to determine the case of non-finite values @@ -497,7 +497,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Returns rather crude approximation (upper bound) for the maximum buffer size +/// Returns a rather crude approximation (upper bound) for the maximum buffer size /// calculated from the given decoded exponent. /// /// The exact limit is: diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index fb78f5e5a2384..cf55b6c379d04 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -1,4 +1,4 @@ -//! Types which pin data to its location in memory +//! Types that pin data to its location in memory. //! //! It is sometimes useful to have objects that are guaranteed to not move, //! in the sense that their placement in memory does not change, and can thus be relied upon. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 53334adadb856..528281d317be3 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2968,7 +2968,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3143,7 +3143,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3326,7 +3326,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3402,7 +3402,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 21f0a8cea4168..12f812d3bed3e 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -108,7 +108,7 @@ impl Waker { unsafe { (self.waker.vtable.wake)(self.waker.data) } } - /// Returns whether or not this `Waker` and other `Waker` have awaken the same task. + /// Returns `true` if this `Waker` and another `Waker` have awoken the same task. /// /// This function works on a best-effort basis, and may return false even /// when the `Waker`s would awaken the same task. However, if this function diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 928de29b297fc..1d45df499d86b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -19,7 +19,7 @@ use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucke use super::table::BucketState::{Empty, Full}; use super::table::Fallibility::{Fallible, Infallible}; -const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two +const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two /// The default behavior of HashMap implements a maximum load factor of 90.9%. #[derive(Clone)] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 8a599c11b2095..1e7d1f1ad58fa 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -8,7 +8,7 @@ use super::Recover; use super::map::{self, HashMap, Keys, RandomState}; // Future Optimization (FIXME!) -// ============================= +// ============================ // // Iteration over zero sized values is a noop. There is no need // for `bucket.val` in the case of HashSet. I suppose we would need HKT diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 25f2dd73504ae..93cee50af13e5 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -211,7 +211,7 @@ pub struct DirBuilder { recursive: bool, } -/// How large a buffer to pre-allocate before reading the entire file. +/// Indicates how large a buffer to pre-allocate before reading the entire file. fn initial_buffer_size(file: &File) -> usize { // Allocate one extra byte so the buffer doesn't need to grow before the // final `read` call at the end of the file. Don't worry about `usize` diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 5ebb61754e1ff..4ad383aa5b613 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is false, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 07f4f5f0e58c4..b38727830f37f 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -37,9 +37,9 @@ pub struct Pipes { /// /// The ours/theirs pipes are *not* specifically readable or writable. Each /// one only supports a read or a write, but which is which depends on the -/// boolean flag given. If `ours_readable` is true then `ours` is readable where -/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is -/// writable where `theirs` is readable. +/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and +/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours` +/// is writable and `theirs` is readable. /// /// Also note that the `ours` pipe is always a handle opened up in overlapped /// mode. This means that technically speaking it should only ever be used From e25df326caf38c1a8559fc6fa633ad60ab401e12 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 17:53:22 +0300 Subject: [PATCH 14/34] consistent naming for duration_float methods and additional f32 methods --- src/libcore/time.rs | 130 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 9 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 91161ca477e39..c8f23fd90bd7a 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -22,6 +22,7 @@ const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; +const MAX_NANOS_F32: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -510,15 +511,34 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.as_float_secs(), 2.7); + /// assert_eq!(dur.as_secs_f64(), 2.7); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub const fn as_float_secs(&self) -> f64 { + pub const fn as_secs_f64(&self) -> f64 { (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64) } - /// Creates a new `Duration` from the specified number of seconds. + /// Returns the number of seconds contained by this `Duration` as `f32`. + /// + /// The returned value does include the fractional (nanosecond) part of the duration. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.as_secs_f32(), 2.7); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub const fn as_secs_f32(&self) -> f32 { + (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32) + } + + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f64`. /// /// # Panics /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. @@ -528,12 +548,12 @@ impl Duration { /// #![feature(duration_float)] /// use std::time::Duration; /// - /// let dur = Duration::from_float_secs(2.7); + /// let dur = Duration::from_secs_f64(2.7); /// assert_eq!(dur, Duration::new(2, 700_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn from_float_secs(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -551,6 +571,40 @@ impl Duration { } } + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f32`. + /// + /// # Panics + /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::from_secs_f32(2.7); + /// assert_eq!(dur, Duration::new(2, 700_000_000)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn from_secs_f32(secs: f32) -> Duration { + let nanos = secs * (NANOS_PER_SEC as f32); + if !nanos.is_finite() { + panic!("got non-finite value when converting float to duration"); + } + if nanos >= MAX_NANOS_F32 { + panic!("overflow when converting float to duration"); + } + if nanos < 0.0 { + panic!("underflow when converting float to duration"); + } + let nanos = nanos as u128; + Duration { + secs: (nanos / (NANOS_PER_SEC as u128)) as u64, + nanos: (nanos % (NANOS_PER_SEC as u128)) as u32, + } + } + /// Multiplies `Duration` by `f64`. /// /// # Panics @@ -568,7 +622,27 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn mul_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(rhs * self.as_float_secs()) + Duration::from_secs_f64(rhs * self.as_secs_f64()) + } + + /// Multiplies `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_000)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn mul_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(rhs * self.as_secs_f32()) } /// Divide `Duration` by `f64`. @@ -589,7 +663,28 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn div_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(self.as_float_secs() / rhs) + Duration::from_secs_f64(self.as_secs_f64() / rhs) + } + + /// Divide `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_611)); + /// // note that truncation is used, not rounding + /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(self.as_secs_f32() / rhs) } /// Divide `Duration` by `Duration` and return `f64`. @@ -605,8 +700,25 @@ impl Duration { /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn div_duration(self, rhs: Duration) -> f64 { - self.as_float_secs() / rhs.as_float_secs() + pub fn div_duration_f64(self, rhs: Duration) -> f64 { + self.as_secs_f64() / rhs.as_secs_f64() + } + + /// Divide `Duration` by `Duration` and return `f32`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur1 = Duration::new(2, 700_000_000); + /// let dur2 = Duration::new(5, 400_000_000); + /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_duration_f32(self, rhs: Duration) -> f32 { + self.as_secs_f32() / rhs.as_secs_f32() } } From 35c19c5b3d1fe8675132ea96e014e37455653ce8 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 18:06:13 +0300 Subject: [PATCH 15/34] move MAX_NANOS_F64/32 to methods --- src/libcore/time.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index c8f23fd90bd7a..d3f80835c0175 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -21,8 +21,6 @@ const NANOS_PER_MILLI: u32 = 1_000_000; const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; -const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; -const MAX_NANOS_F32: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -554,6 +552,8 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn from_secs_f64(secs: f64) -> Duration { + const MAX_NANOS_F64: f64 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -588,6 +588,8 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn from_secs_f32(secs: f32) -> Duration { + const MAX_NANOS_F32: f32 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; let nanos = secs * (NANOS_PER_SEC as f32); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); From d4b2071b1faeaa15ecbad7dc74a94def96200d87 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 11 Mar 2019 15:54:57 +0000 Subject: [PATCH 16/34] Resolved nits raised in review. --- src/libstd/sync/condvar.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 4ad383aa5b613..c383f21dcd752 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is `false`, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } From 02f26e3690ad380223a24078656752d152c4f4f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Mon, 11 Mar 2019 16:07:31 +0000 Subject: [PATCH 17/34] Add peer_addr function to UdpSocket --- src/libstd/net/udp.rs | 17 +++++++++++++++++ src/libstd/sys/cloudabi/shims/net.rs | 4 ++++ src/libstd/sys/redox/net/udp.rs | 5 +++++ src/libstd/sys/sgx/net.rs | 4 ++++ src/libstd/sys_common/net.rs | 6 ++++++ 5 files changed, 36 insertions(+) diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index edc9d665444a0..c7ccf45b953e7 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -180,6 +180,23 @@ impl UdpSocket { } } + /// Returns the socket address of the remote peer this socket was connected to. + /// + /// # Examples + /// + /// ```no_run + /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}; + /// + /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address"); + /// socket.connect("192.168.0.1:41203").expect("couldn't connect to address"); + /// assert_eq!(socket.peer_addr().unwrap(), + /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203))); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn peer_addr(&self) -> io::Result { + self.0.peer_addr() + } + /// Returns the socket address that this socket was created from. /// /// # Examples diff --git a/src/libstd/sys/cloudabi/shims/net.rs b/src/libstd/sys/cloudabi/shims/net.rs index 50d72dc7b240b..1185d7cfb2c4c 100644 --- a/src/libstd/sys/cloudabi/shims/net.rs +++ b/src/libstd/sys/cloudabi/shims/net.rs @@ -159,6 +159,10 @@ impl UdpSocket { unsupported() } + pub fn peer_addr(&self) -> io::Result { + match self.0 {} + } + pub fn socket_addr(&self) -> io::Result { match self.0 {} } diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs index b1a60b1457083..274123dce4b58 100644 --- a/src/libstd/sys/redox/net/udp.rs +++ b/src/libstd/sys/redox/net/udp.rs @@ -72,6 +72,11 @@ impl UdpSocket { Ok(None) } + pub fn peer_addr(&self) -> Result { + let path = self.0.path()?; + Ok(path_to_peer_addr(path.to_str().unwrap_or(""))) + } + pub fn socket_addr(&self) -> Result { let path = self.0.path()?; Ok(path_to_local_addr(path.to_str().unwrap_or(""))) diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index ab8b2681393f8..8e693dc7ac25d 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -257,6 +257,10 @@ impl UdpSocket { unsupported() } + pub fn peer_addr(&self) -> io::Result { + match self.0 {} + } + pub fn socket_addr(&self) -> io::Result { match self.0 {} } diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 36721171b1733..3f88d3e0e4e14 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -472,6 +472,12 @@ impl UdpSocket { pub fn into_socket(self) -> Socket { self.inner } + pub fn peer_addr(&self) -> io::Result { + sockname(|buf, len| unsafe { + c::getpeername(*self.inner.as_inner(), buf, len) + }) + } + pub fn socket_addr(&self) -> io::Result { sockname(|buf, len| unsafe { c::getsockname(*self.inner.as_inner(), buf, len) From 980871af270314d1e4dd42828d9a7c76d6e0c89a Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 19:57:53 +0300 Subject: [PATCH 18/34] fix tests --- src/libcore/time.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index d3f80835c0175..c4d4c4622f3a4 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -638,8 +638,10 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_000)); - /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); + /// // note that due to rounding errors result is slightly different + /// // from 8.478 + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 64_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] @@ -679,7 +681,9 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_611)); + /// // note that due to rounding errors result is slightly + /// // different from 0.859_872_611 + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576)); /// // note that truncation is used, not rounding /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); /// ``` @@ -698,7 +702,7 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] @@ -715,7 +719,7 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] From 197efb05243976a631107f1d6ad88bff65fd43e9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 11 Mar 2019 18:59:41 +0000 Subject: [PATCH 19/34] fix test --- src/libcore/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index c4d4c4622f3a4..f106d06d2ffc1 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -639,9 +639,9 @@ impl Duration { /// /// let dur = Duration::new(2, 700_000_000); /// // note that due to rounding errors result is slightly different - /// // from 8.478 + /// // from 8.478 anf 847800.0 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); - /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 64_000_000)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] From b9d12edd6ce7b364fb1a4de53f7541d536df0940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 11 Mar 2019 15:07:07 -0700 Subject: [PATCH 20/34] Be more discerning on when to attempt suggesting a comma in a macro invocation --- src/libsyntax/tokenstream.rs | 8 +++++--- src/test/ui/macros/missing-comma.rs | 7 +++++++ src/test/ui/macros/missing-comma.stderr | 21 +++++++++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 4ce308d015c00..5caa59a53f92b 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -178,9 +178,11 @@ impl TokenStream { while let Some((pos, ts)) = iter.next() { if let Some((_, next)) = iter.peek() { let sp = match (&ts, &next) { - ((TokenTree::Token(_, token::Token::Comma), NonJoint), _) | - (_, (TokenTree::Token(_, token::Token::Comma), NonJoint)) => continue, - ((TokenTree::Token(sp, _), NonJoint), _) => *sp, + (_, (TokenTree::Token(_, token::Token::Comma), _)) => continue, + ((TokenTree::Token(sp, token_left), NonJoint), + (TokenTree::Token(_, token_right), _)) + if token_left.is_ident() || token_left.is_lit() && + token_right.is_ident() || token_right.is_lit() => *sp, ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), _ => continue, }; diff --git a/src/test/ui/macros/missing-comma.rs b/src/test/ui/macros/missing-comma.rs index 1e146875bcc76..2b411aba8a2ee 100644 --- a/src/test/ui/macros/missing-comma.rs +++ b/src/test/ui/macros/missing-comma.rs @@ -6,6 +6,11 @@ macro_rules! foo { ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); } +macro_rules! bar { + ($lvl:expr, $($arg:tt)+) => {} +} + + fn main() { println!("{}" a); //~^ ERROR expected token: `,` @@ -17,4 +22,6 @@ fn main() { //~^ ERROR no rules expected the token `d` foo!(a, b, c d e); //~^ ERROR no rules expected the token `d` + bar!(Level::Error, ); + //~^ ERROR unexpected end of macro invocation } diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index 5881e0b7b68c6..424fefd00f873 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -1,11 +1,11 @@ error: expected token: `,` - --> $DIR/missing-comma.rs:10:19 + --> $DIR/missing-comma.rs:15:19 | LL | println!("{}" a); | ^ error: no rules expected the token `b` - --> $DIR/missing-comma.rs:12:12 + --> $DIR/missing-comma.rs:17:12 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -16,7 +16,7 @@ LL | foo!(a b); | help: missing comma here error: no rules expected the token `e` - --> $DIR/missing-comma.rs:14:21 + --> $DIR/missing-comma.rs:19:21 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -27,7 +27,7 @@ LL | foo!(a, b, c, d e); | help: missing comma here error: no rules expected the token `d` - --> $DIR/missing-comma.rs:16:18 + --> $DIR/missing-comma.rs:21:18 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -38,7 +38,7 @@ LL | foo!(a, b, c d, e); | help: missing comma here error: no rules expected the token `d` - --> $DIR/missing-comma.rs:18:18 + --> $DIR/missing-comma.rs:23:18 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -46,5 +46,14 @@ LL | macro_rules! foo { LL | foo!(a, b, c d e); | ^ no rules expected this token in macro call -error: aborting due to 5 previous errors +error: unexpected end of macro invocation + --> $DIR/missing-comma.rs:25:23 + | +LL | macro_rules! bar { + | ---------------- when calling this macro +... +LL | bar!(Level::Error, ); + | ^ missing tokens in macro arguments + +error: aborting due to 6 previous errors From 78b248dc4c17581211aaed5c3a449e5b07ebdb52 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 12 Mar 2019 16:42:18 +0300 Subject: [PATCH 21/34] fix typo --- src/libcore/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index f106d06d2ffc1..ae6d8078fd236 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -639,7 +639,7 @@ impl Duration { /// /// let dur = Duration::new(2, 700_000_000); /// // note that due to rounding errors result is slightly different - /// // from 8.478 anf 847800.0 + /// // from 8.478 and 847800.0 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` From df2dce326a979ab178bb2e39a74310e205f0242c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Tue, 12 Mar 2019 10:32:23 +0000 Subject: [PATCH 22/34] Mark UdpSocket peer_addr unstable w/ tracking issue --- src/libstd/net/udp.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index c7ccf45b953e7..164039b303230 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -185,6 +185,7 @@ impl UdpSocket { /// # Examples /// /// ```no_run + /// #![feature(udp_peer_addr)] /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}; /// /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address"); @@ -192,7 +193,7 @@ impl UdpSocket { /// assert_eq!(socket.peer_addr().unwrap(), /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203))); /// ``` - #[stable(feature = "rust1", since = "1.0.0")] + #[unstable(feature = "udp_peer_addr", issue = "59127")] pub fn peer_addr(&self) -> io::Result { self.0.peer_addr() } From 54bf8e02943daa746286ad03b6d745e03f0bf3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Tue, 12 Mar 2019 11:19:33 +0000 Subject: [PATCH 23/34] Document UdpSocket peer_addr NotConnected error --- src/libstd/net/udp.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 164039b303230..79e5ae79e4c01 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -193,6 +193,19 @@ impl UdpSocket { /// assert_eq!(socket.peer_addr().unwrap(), /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203))); /// ``` + /// + /// If the socket isn't connected, it will return a [`NotConnected`] error. + /// + /// [`NotConnected`]: ../../std/io/enum.ErrorKind.html#variant.NotConnected + /// + /// ```no_run + /// #![feature(udp_peer_addr)] + /// use std::net::UdpSocket; + /// + /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address"); + /// assert_eq!(socket.peer_addr().unwrap_err().kind(), + /// ::std::io::ErrorKind::NotConnected); + /// ``` #[unstable(feature = "udp_peer_addr", issue = "59127")] pub fn peer_addr(&self) -> io::Result { self.0.peer_addr() From 507448945612f6b6f80a08a943e88d9a3a14b52f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 12 Mar 2019 17:37:22 +0100 Subject: [PATCH 24/34] Unregress using scalar unions in constants. --- src/librustc_mir/const_eval.rs | 26 +++++++++++++------------- src/test/ui/consts/union_constant.rs | 11 +++++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/consts/union_constant.rs diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 365cb508b0925..d97be0b28725c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( fn mplace_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, mplace: MPlaceTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { +) -> ty::Const<'tcx> { let MemPlace { ptr, align, meta } = *mplace; // extract alloc-offset pair assert!(meta.is_none()); - let ptr = ptr.to_ptr()?; - let alloc = ecx.memory.get(ptr.alloc_id)?; + let ptr = ptr.to_ptr().unwrap(); + let alloc = ecx.memory.get(ptr.alloc_id).unwrap(); assert!(alloc.align >= align); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes()); let mut alloc = alloc.clone(); @@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>( // interned this? I thought that is the entire point of that `FinishStatic` stuff? let alloc = ecx.tcx.intern_const_alloc(alloc); let val = ConstValue::ByRef(ptr, alloc); - Ok(ty::Const { val, ty: mplace.layout.ty }) + ty::Const { val, ty: mplace.layout.ty } } fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { - // We do not normalize just any data. Only scalar layout and slices. +) -> ty::Const<'tcx> { + // We do not normalize just any data. Only non-union scalars and slices. let normalize = match op.layout.abi { - layout::Abi::Scalar(..) => true, + layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()), layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(), _ => false, }; @@ -100,11 +100,11 @@ fn op_to_const<'tcx>( let val = match normalized_op { Ok(mplace) => return mplace_to_const(ecx, mplace), Err(Immediate::Scalar(x)) => - ConstValue::Scalar(x.not_undef()?), + ConstValue::Scalar(x.not_undef().unwrap()), Err(Immediate::ScalarPair(a, b)) => - ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?), + ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()), }; - Ok(ty::Const { val, ty: op.layout.ty }) + ty::Const { val, ty: op.layout.ty } } fn eval_body_and_ecx<'a, 'mir, 'tcx>( @@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>( let field = ecx.operand_field(down, field.index() as u64).unwrap(); // and finally move back to the const world, always normalizing because // this is not called for statics. - op_to_const(&ecx, field).unwrap() + op_to_const(&ecx, field) } // this function uses `unwrap` copiously, because an already validated constant must have valid @@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>( // Now that we validated, turn this into a proper constant. let def_id = cid.instance.def.def_id(); if tcx.is_static(def_id).is_some() || cid.promoted.is_some() { - mplace_to_const(&ecx, mplace) + Ok(mplace_to_const(&ecx, mplace)) } else { - op_to_const(&ecx, mplace.into()) + Ok(op_to_const(&ecx, mplace.into())) } })(); diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs new file mode 100644 index 0000000000000..074014908bad4 --- /dev/null +++ b/src/test/ui/consts/union_constant.rs @@ -0,0 +1,11 @@ +// compile-pass + +union Uninit { + _never_use: *const u8, + uninit: (), +} + +const UNINIT: Uninit = Uninit { uninit: () }; + +fn main() {} + From 79695ea5b51bbee32092966625513c540523b470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Tue, 12 Mar 2019 16:50:00 +0000 Subject: [PATCH 25/34] Add test for UdpSocket peer_addr --- src/libstd/net/udp.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 79e5ae79e4c01..f3f65034f4256 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -903,6 +903,16 @@ mod tests { }) } + #[test] + fn socket_peer_ip4() { + each_ip(&mut |addr1, addr2| { + let server = t!(UdpSocket::bind(&addr1)); + assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected); + t!(server.connect(&addr2)); + assert_eq!(addr2, t!(server.peer_addr())); + }) + } + #[test] fn udp_clone_smoke() { each_ip(&mut |addr1, addr2| { From ca32fe4c0afc8a564a87d700c379adf2d5a2da15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Tue, 12 Mar 2019 17:18:07 +0000 Subject: [PATCH 26/34] Fix test names regarding ip version --- src/libstd/net/udp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index f3f65034f4256..b42a812304269 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -896,7 +896,7 @@ mod tests { } #[test] - fn socket_name_ip4() { + fn socket_name() { each_ip(&mut |addr, _| { let server = t!(UdpSocket::bind(&addr)); assert_eq!(addr, t!(server.local_addr())); @@ -904,7 +904,7 @@ mod tests { } #[test] - fn socket_peer_ip4() { + fn socket_peer() { each_ip(&mut |addr1, addr2| { let server = t!(UdpSocket::bind(&addr1)); assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected); From df05fbf006e90ed4827c385eb9192e4c46de70f4 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 11 Mar 2019 16:39:40 -0700 Subject: [PATCH 27/34] rustc: fix ICE when trait alias has bare Self --- src/librustc/hir/map/mod.rs | 6 ++++-- src/test/ui/issues/issue-59029-1.rs | 8 ++++++++ src/test/ui/issues/issue-59029-1.stderr | 9 +++++++++ src/test/ui/issues/issue-59029-2.rs | 8 ++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issues/issue-59029-1.rs create mode 100644 src/test/ui/issues/issue-59029-1.stderr create mode 100644 src/test/ui/issues/issue-59029-2.rs diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 86b6805cc9b4c..0e83ce009c943 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -541,7 +541,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_owner(&self, id: HirId) -> HirId { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id, + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id, Node::GenericParam(_) => self.get_parent_node_by_hir_id(id), _ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id)) } @@ -549,7 +550,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_name(&self, id: HirId) -> Name { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(), + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(), Node::GenericParam(param) => param.name.ident().name, _ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)), } diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs new file mode 100644 index 0000000000000..e98a4d0e491a3 --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where Self::Res: Svc; +//~^ ERROR associated type `Res` not found for `Self` + +fn main() {} diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr new file mode 100644 index 0000000000000..ed1d98c40d18a --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Res` not found for `Self` + --> $DIR/issue-59029-1.rs:5:46 + | +LL | trait MkSvc = Svc where Self::Res: Svc; + | ^^^^^^^^^ associated type `Res` not found + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/issues/issue-59029-2.rs b/src/test/ui/issues/issue-59029-2.rs new file mode 100644 index 0000000000000..2bdb128d8c4c8 --- /dev/null +++ b/src/test/ui/issues/issue-59029-2.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where >::Res: Svc; + +fn main() {} From 795d307f10ec0fd3851b18a3365755d76b7403e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 14:57:13 -0700 Subject: [PATCH 28/34] Suggest return lifetime when there's only one named lifetime --- src/librustc/middle/resolve_lifetime.rs | 37 +++++++++++++++++-- .../ui/suggestions/return-without-lifetime.rs | 8 ++++ .../return-without-lifetime.stderr | 19 ++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/suggestions/return-without-lifetime.rs create mode 100644 src/test/ui/suggestions/return-without-lifetime.stderr diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f862b690f8806..35bca04d1e623 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2298,6 +2298,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let span = lifetime_refs[0].span; let mut late_depth = 0; let mut scope = self.scope; + let mut lifetime_names = FxHashSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2310,7 +2311,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Elision { ref elide, .. } => { + Scope::Elision { ref elide, ref s, .. } => { let lifetime = match *elide { Elide::FreshLateAnon(ref counter) => { for lifetime_ref in lifetime_refs { @@ -2320,7 +2321,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } Elide::Exact(l) => l.shifted(late_depth), - Elide::Error(ref e) => break Some(e), + Elide::Error(ref e) => { + if let Scope::Binder { ref lifetimes, .. } = s { + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } + } + break Some(e); + } }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); @@ -2343,7 +2353,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } if add_label { - add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len()); + add_missing_lifetime_specifiers_label( + &mut err, + span, + lifetime_refs.len(), + &lifetime_names, + self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), + ); } err.emit(); @@ -2884,10 +2900,23 @@ fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, span: Span, count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); + } else if let (1, Some(name), Some("&")) = ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet, + ) { + err.span_suggestion( + span, + &format!("consider using the named lifetime `{}`", name), + format!("&{} ", name), + Applicability::MaybeIncorrect, + ); } else { err.span_label(span, "expected lifetime parameter"); - }; + } } diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs new file mode 100644 index 0000000000000..5f19e93013acf --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -0,0 +1,8 @@ +struct Thing<'a>(&'a ()); + +fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier +fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr new file mode 100644 index 0000000000000..72f1c142d028f --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -0,0 +1,19 @@ +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:3:34 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime `'a`: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:35 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime `'a`: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. From f9234767e4ff9b682437464efc9a6ff59db4cff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 15:34:16 -0700 Subject: [PATCH 29/34] review comments --- src/librustc/middle/resolve_lifetime.rs | 2 +- src/test/ui/suggestions/return-without-lifetime.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 35bca04d1e623..d03268df5e148 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2912,7 +2912,7 @@ fn add_missing_lifetime_specifiers_label( ) { err.span_suggestion( span, - &format!("consider using the named lifetime `{}`", name), + "consider using the named lifetime", format!("&{} ", name), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 72f1c142d028f..1ffe91bce05a5 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -2,7 +2,7 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:3:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime `'a`: `&'a` + | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from @@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:5:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime `'a`: `&'a` + | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from From adbd0a66457159ffcdd02ee0b553581298968847 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 12 Mar 2019 16:09:20 -0700 Subject: [PATCH 30/34] Make std time tests more robust for platform differences --- src/libstd/time.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 6d7093ac33ea7..4c86f70ad871d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -712,13 +712,6 @@ mod tests { assert_almost_eq!(a - second + second, a); assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - // A difference of 80 and 800 years cannot fit inside a 32-bit time_t - if !(cfg!(unix) && crate::mem::size_of::() <= 4) { - let eighty_years = second * 60 * 60 * 24 * 365 * 80; - assert_almost_eq!(a - eighty_years + eighty_years, a); - assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); - } - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); @@ -747,8 +740,8 @@ mod tests { #[test] fn since_epoch() { let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH).unwrap(); - let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap(); + let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let b = ts.duration_since(UNIX_EPOCH).unwrap(); assert!(b > a); assert_eq!(b - a, Duration::new(1, 0)); From 0ea9b58029bc7c3da3f213eb9e39acdefcf12647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 18:18:24 -0700 Subject: [PATCH 31/34] Suggest adding lifetime to struct field --- src/librustc/middle/resolve_lifetime.rs | 9 ++++++++- src/test/ui/suggestions/return-without-lifetime.rs | 2 ++ .../ui/suggestions/return-without-lifetime.stderr | 12 +++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d03268df5e148..c9ff84ab2f08a 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2306,7 +2306,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => break None, - Scope::Binder { s, .. } => { + Scope::Binder { s, ref lifetimes, .. } => { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } late_depth += 1; scope = s; } @@ -2323,6 +2329,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Elide::Exact(l) => l.shifted(late_depth), Elide::Error(ref e) => { if let Scope::Binder { ref lifetimes, .. } = s { + // collect named lifetimes for suggestions for name in lifetimes.keys() { if let hir::ParamName::Plain(name) = name { lifetime_names.insert(*name); diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs index 5f19e93013acf..9bfce11be9ea3 100644 --- a/src/test/ui/suggestions/return-without-lifetime.rs +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -1,4 +1,6 @@ struct Thing<'a>(&'a ()); +struct Foo<'a>(&usize); +//~^ ERROR missing lifetime specifier fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } //~^ ERROR missing lifetime specifier diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 1ffe91bce05a5..7f5ff95938e30 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -1,5 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/return-without-lifetime.rs:3:34 + --> $DIR/return-without-lifetime.rs:2:16 + | +LL | struct Foo<'a>(&usize); + | ^ help: consider using the named lifetime: `&'a` + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` @@ -7,13 +13,13 @@ LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from error[E0106]: missing lifetime specifier - --> $DIR/return-without-lifetime.rs:5:35 + --> $DIR/return-without-lifetime.rs:7:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0106`. From 27abd52170b2d2769f5fbed665795bdb9a3facef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 13 Mar 2019 00:10:16 -0700 Subject: [PATCH 32/34] Fix operator precedence --- src/libsyntax/tokenstream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 5caa59a53f92b..80a7bde606afa 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -181,8 +181,8 @@ impl TokenStream { (_, (TokenTree::Token(_, token::Token::Comma), _)) => continue, ((TokenTree::Token(sp, token_left), NonJoint), (TokenTree::Token(_, token_right), _)) - if token_left.is_ident() || token_left.is_lit() && - token_right.is_ident() || token_right.is_lit() => *sp, + if (token_left.is_ident() || token_left.is_lit()) && + (token_right.is_ident() || token_right.is_lit()) => *sp, ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), _ => continue, }; From 311025e6a5aad80d028f0771970c43cb4ed025a8 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Thu, 7 Mar 2019 18:30:26 +0100 Subject: [PATCH 33/34] Fix generic argument lookup for Self Rewrite the SelfCtor early and use the replacement Def when calculating the path_segs. Note that this also changes which def is seen by the code that computes user_self_ty and is_alias_variant_ctor; I don't see a immediate issue with that, but I'm not 100% clear on the implications. Fixes #57924 --- src/librustc_typeck/check/mod.rs | 119 ++++++++++++------------ src/test/run-pass/issues/issue-57924.rs | 9 ++ 2 files changed, 69 insertions(+), 59 deletions(-) create mode 100644 src/test/run-pass/issues/issue-57924.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 301d7d3ac5623..7dfe9f40d318f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5302,6 +5302,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(original_span.with_lo(original_span.hi() - BytePos(1))) } + // Rewrite `SelfCtor` to `StructCtor` + pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) { + let tcx = self.tcx; + if let Def::SelfCtor(impl_def_id) = def { + let ty = self.impl_self_ty(span, impl_def_id).ty; + let adt_def = ty.ty_adt_def(); + + match adt_def { + Some(adt_def) if adt_def.has_ctor() => { + let variant = adt_def.non_enum_variant(); + let def = Def::StructCtor(variant.did, variant.ctor_kind); + (def, variant.did, tcx.type_of(variant.did)) + } + _ => { + let mut err = tcx.sess.struct_span_err(span, + "the `Self` constructor can only be used with tuple or unit structs"); + if let Some(adt_def) = adt_def { + match adt_def.adt_kind() { + AdtKind::Enum => { + err.help("did you mean to use one of the enum's variants?"); + }, + AdtKind::Struct | + AdtKind::Union => { + err.span_suggestion( + span, + "use curly brackets", + String::from("Self { /* fields */ }"), + Applicability::HasPlaceholders, + ); + } + } + } + err.emit(); + + (def, impl_def_id, tcx.types.err) + } + } + } else { + let def_id = def.def_id(); + + // The things we are substituting into the type should not contain + // escaping late-bound regions, and nor should the base type scheme. + let ty = tcx.type_of(def_id); + (def, def_id, ty) + } + } + // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_value_path(&self, @@ -5321,6 +5368,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; + match def { + Def::Local(nid) | Def::Upvar(nid, ..) => { + let hid = self.tcx.hir().node_to_hir_id(nid); + let ty = self.local_ty(span, hid).decl_ty; + let ty = self.normalize_associated_types_in(span, &ty); + self.write_ty(hir_id, ty); + return (ty, def); + } + _ => {} + } + + let (def, def_id, ty) = self.rewrite_self_ctor(def, span); let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; @@ -5382,17 +5441,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { user_self_ty = None; } - match def { - Def::Local(nid) | Def::Upvar(nid, ..) => { - let hid = self.tcx.hir().node_to_hir_id(nid); - let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(hir_id, ty); - return (ty, def); - } - _ => {} - } - // Now we have to compare the types that the user *actually* // provided against the types that were *expected*. If the user // did not provide any types, then we want to substitute inference @@ -5425,53 +5473,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.generics_of(*def_id).has_self }).unwrap_or(false); - let mut new_def = def; - let (def_id, ty) = match def { - Def::SelfCtor(impl_def_id) => { - let ty = self.impl_self_ty(span, impl_def_id).ty; - let adt_def = ty.ty_adt_def(); - - match adt_def { - Some(adt_def) if adt_def.has_ctor() => { - let variant = adt_def.non_enum_variant(); - new_def = Def::StructCtor(variant.did, variant.ctor_kind); - (variant.did, tcx.type_of(variant.did)) - } - _ => { - let mut err = tcx.sess.struct_span_err(span, - "the `Self` constructor can only be used with tuple or unit structs"); - if let Some(adt_def) = adt_def { - match adt_def.adt_kind() { - AdtKind::Enum => { - err.help("did you mean to use one of the enum's variants?"); - }, - AdtKind::Struct | - AdtKind::Union => { - err.span_suggestion( - span, - "use curly brackets", - String::from("Self { /* fields */ }"), - Applicability::HasPlaceholders, - ); - } - } - } - err.emit(); - - (impl_def_id, tcx.types.err) - } - } - } - _ => { - let def_id = def.def_id(); - - // The things we are substituting into the type should not contain - // escaping late-bound regions, and nor should the base type scheme. - let ty = tcx.type_of(def_id); - (def_id, ty) - } - }; - let substs = AstConv::create_substs_for_generic_args( tcx, def_id, @@ -5587,7 +5588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_substituted); self.write_substs(hir_id, substs); - (ty_substituted, new_def) + (ty_substituted, def) } fn check_rustc_args_require_const(&self, diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs new file mode 100644 index 0000000000000..232596334b0ed --- /dev/null +++ b/src/test/run-pass/issues/issue-57924.rs @@ -0,0 +1,9 @@ +pub struct Gcm(E); + +impl Gcm { + pub fn crash(e: E) -> Self { + Self::(e) + } +} + +fn main() {} From 856b081eb2ae3264da07434debd55d734fba7eb4 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Mon, 11 Mar 2019 11:03:19 +0100 Subject: [PATCH 34/34] middle: replace NodeId with HirId in AccessLevels --- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/privacy.rs | 4 +- src/librustc/middle/reachable.rs | 5 +-- src/librustc/middle/stability.rs | 2 +- src/librustc_lint/builtin.rs | 12 ++--- src/librustc_privacy/lib.rs | 25 ++++------- src/librustc_save_analysis/dump_visitor.rs | 51 ++++++++++++++-------- src/librustdoc/core.rs | 6 +-- 8 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 94de999c25da8..0de169e652371 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -414,7 +414,7 @@ fn create_and_seed_worklist<'a, 'tcx>( ) -> (Vec, FxHashMap) { let worklist = access_levels.map.iter().filter_map(|(&id, level)| { if level >= &privacy::AccessLevel::Reachable { - Some(tcx.hir().node_to_hir_id(id)) + Some(id) } else { None } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 6ba55f882f8fd..787ff8d48c119 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -2,11 +2,11 @@ //! outside their scopes. This pass will also generate a set of exported items //! which are available for use externally when compiled as a library. +use crate::hir::HirId; use crate::util::nodemap::{DefIdSet, FxHashMap}; use std::hash::Hash; use std::fmt; -use syntax::ast::NodeId; use rustc_macros::HashStable; // Accessibility levels, sorted in ascending order @@ -27,7 +27,7 @@ pub enum AccessLevel { // Accessibility levels for reachable HIR nodes #[derive(Clone)] -pub struct AccessLevels { +pub struct AccessLevels { pub map: FxHashMap } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 72f6d22b696f7..a7294dbf07c00 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -354,8 +354,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, // We need only trait impls here, not inherent impls, and only non-exported ones if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node { - let node_id = self.tcx.hir().hir_to_node_id(item.hir_id); - if !self.access_levels.is_reachable(node_id) { + if !self.access_levels.is_reachable(item.hir_id) { self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id)); let trait_def_id = match trait_ref.path.def { @@ -415,7 +414,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> // use the lang items, so we need to be sure to mark them as // exported. reachable_context.worklist.extend( - access_levels.map.iter().map(|(id, _)| tcx.hir().node_to_hir_id(*id))); + access_levels.map.iter().map(|(id, _)| *id)); for item in tcx.lang_items().items().iter() { if let Some(did) = *item { if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 1677384059e09..b0abe215867b5 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> { let stab = self.tcx.stability().local_stability(hir_id); let is_error = !self.tcx.sess.opts.test && stab.is_none() && - self.access_levels.is_reachable(self.tcx.hir().hir_to_node_id(hir_id)); + self.access_levels.is_reachable(hir_id); if is_error { self.tcx.sess.span_err( span, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7a7c49e460428..ad69493bf79c5 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -380,8 +380,7 @@ impl MissingDoc { // It's an option so the crate root can also use this function (it doesn't // have a NodeId). if let Some(id) = id { - let node_id = cx.tcx.hir().hir_to_node_id(id); - if !cx.access_levels.is_exported(node_id) { + if !cx.access_levels.is_exported(id) { return; } } @@ -557,8 +556,7 @@ impl LintPass for MissingCopyImplementations { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { - let node_id = cx.tcx.hir().hir_to_node_id(item.hir_id); - if !cx.access_levels.is_reachable(node_id) { + if !cx.access_levels.is_reachable(item.hir_id) { return; } let (def, ty) = match item.node { @@ -629,8 +627,7 @@ impl LintPass for MissingDebugImplementations { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { - let node_id = cx.tcx.hir().hir_to_node_id(item.hir_id); - if !cx.access_levels.is_reachable(node_id) { + if !cx.access_levels.is_reachable(item.hir_id) { return; } @@ -1169,9 +1166,8 @@ impl UnreachablePub { fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: hir::HirId, vis: &hir::Visibility, span: Span, exportable: bool) { let mut applicability = Applicability::MachineApplicable; - let node_id = cx.tcx.hir().hir_to_node_id(id); match vis.node { - hir::VisibilityKind::Public if !cx.access_levels.is_reachable(node_id) => { + hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => { if span.ctxt().outer().expn_info().is_some() { applicability = Applicability::MaybeIncorrect; } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 52514a3ca97d6..386a121d5acac 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -379,8 +379,8 @@ impl VisibilityLike for Option { // (which require reaching the `DefId`s in them). const SHALLOW: bool = true; fn new_min<'a, 'tcx>(find: &FindMin<'a, 'tcx, Self>, def_id: DefId) -> Self { - cmp::min(if let Some(node_id) = find.tcx.hir().as_local_node_id(def_id) { - find.access_levels.map.get(&node_id).cloned() + cmp::min(if let Some(hir_id) = find.tcx.hir().as_local_hir_id(def_id) { + find.access_levels.map.get(&hir_id).cloned() } else { Self::MAX }, find.min) @@ -410,8 +410,7 @@ struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> { impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { fn get(&self, id: hir::HirId) -> Option { - let node_id = self.tcx.hir().hir_to_node_id(id); - self.access_levels.map.get(&node_id).cloned() + self.access_levels.map.get(&id).cloned() } // Updates node level and returns the updated level. @@ -419,8 +418,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { let old_level = self.get(id); // Accessibility levels can only grow. if level > old_level { - let node_id = self.tcx.hir().hir_to_node_id(id); - self.access_levels.map.insert(node_id, level.unwrap()); + self.access_levels.map.insert(id, level.unwrap()); self.changed = true; level } else { @@ -1197,8 +1195,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { fn trait_is_public(&self, trait_id: hir::HirId) -> bool { // FIXME: this would preferably be using `exported_items`, but all // traits are exported currently (see `EmbargoVisitor.exported_trait`). - let node_id = self.tcx.hir().hir_to_node_id(trait_id); - self.access_levels.is_public(node_id) + self.access_levels.is_public(trait_id) } fn check_generic_bound(&mut self, bound: &hir::GenericBound) { @@ -1210,8 +1207,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } fn item_is_public(&self, id: &hir::HirId, vis: &hir::Visibility) -> bool { - let node_id = self.tcx.hir().hir_to_node_id(*id); - self.access_levels.is_reachable(node_id) || vis.node.is_pub() + self.access_levels.is_reachable(*id) || vis.node.is_pub() } } @@ -1325,8 +1321,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => { self.access_levels.is_reachable( - self.tcx.hir().hir_to_node_id( - impl_item_ref.id.hir_id)) + impl_item_ref.id.hir_id) } hir::ImplItemKind::Existential(..) | hir::ImplItemKind::Type(_) => false, @@ -1455,8 +1450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) { - let node_id = self.tcx.hir().hir_to_node_id(item.hir_id); - if self.access_levels.is_reachable(node_id) { + if self.access_levels.is_reachable(item.hir_id) { intravisit::walk_foreign_item(self, item) } } @@ -1474,8 +1468,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { v: &'tcx hir::Variant, g: &'tcx hir::Generics, item_id: hir::HirId) { - let node_id = self.tcx.hir().hir_to_node_id(v.node.data.hir_id()); - if self.access_levels.is_reachable(node_id) { + if self.access_levels.is_reachable(v.node.data.hir_id()) { self.in_variant = true; intravisit::walk_variant(self, v, g, item_id); self.in_variant = false; diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index b82aee7c96ad2..8eb2702447dbc 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -58,17 +58,19 @@ macro_rules! down_cast_data { } macro_rules! access_from { - ($save_ctxt:expr, $vis:expr, $id:expr) => { + ($save_ctxt:expr, $item:expr, $id:expr) => { Access { - public: $vis.node.is_pub(), + public: $item.vis.node.is_pub(), reachable: $save_ctxt.access_levels.is_reachable($id), } }; +} - ($save_ctxt:expr, $item:expr) => { +macro_rules! access_from_vis { + ($save_ctxt:expr, $vis:expr, $id:expr) => { Access { - public: $item.vis.node.is_pub(), - reachable: $save_ctxt.access_levels.is_reachable($item.id), + public: $vis.node.is_pub(), + reachable: $save_ctxt.access_levels.is_reachable($id), } }; } @@ -303,7 +305,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { method_data.value = sig_str; method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt); - self.dumper.dump_def(&access_from!(self.save_ctxt, vis, id), method_data); + let hir_id = self.tcx.hir().node_to_hir_id(id); + self.dumper.dump_def(&access_from_vis!(self.save_ctxt, vis, hir_id), method_data); } // walk arg and return types @@ -324,7 +327,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) { let field_data = self.save_ctxt.get_field_data(field, parent_id); if let Some(field_data) = field_data { - self.dumper.dump_def(&access_from!(self.save_ctxt, field), field_data); + let hir_id = self.tcx.hir().node_to_hir_id(field.id); + self.dumper.dump_def(&access_from!(self.save_ctxt, field, hir_id), field_data); } } @@ -389,7 +393,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { |v| v.process_formals(&decl.inputs, &fn_data.qualname), ); self.process_generic_params(ty_params, &fn_data.qualname, item.id); - self.dumper.dump_def(&access_from!(self.save_ctxt, item), fn_data); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); + self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), fn_data); } for arg in &decl.inputs { @@ -409,10 +414,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { typ: &'l ast::Ty, expr: &'l ast::Expr, ) { + let hir_id = self.tcx.hir().node_to_hir_id(item.id); self.nest_tables(item.id, |v| { if let Some(var_data) = v.save_ctxt.get_item_data(item) { down_cast_data!(var_data, DefData, item.span); - v.dumper.dump_def(&access_from!(v.save_ctxt, item), var_data); + v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), var_data); } v.visit_ty(&typ); v.visit_expr(expr); @@ -434,9 +440,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if !self.span.filter_generated(ident.span) { let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt); let span = self.span_from_span(ident.span); + let hir_id = self.tcx.hir().node_to_hir_id(id); self.dumper.dump_def( - &access_from!(self.save_ctxt, vis, id), + &access_from_vis!(self.save_ctxt, vis, hir_id), Def { kind: DefKind::Const, id: id_from_node_id(id, &self.save_ctxt), @@ -510,8 +517,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); self.dumper.dump_def( - &access_from!(self.save_ctxt, item), + &access_from!(self.save_ctxt, item, hir_id), Def { kind, id: id_from_node_id(item.id, &self.save_ctxt), @@ -550,7 +558,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { }; down_cast_data!(enum_data, DefData, item.span); - let access = access_from!(self.save_ctxt, item); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); + let access = access_from!(self.save_ctxt, item, hir_id); for variant in &enum_definition.variants { let name = variant.node.ident.name.to_string(); @@ -698,8 +707,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .iter() .map(|i| id_from_node_id(i.id, &self.save_ctxt)) .collect(); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); self.dumper.dump_def( - &access_from!(self.save_ctxt, item), + &access_from!(self.save_ctxt, item, hir_id), Def { kind: DefKind::Trait, id, @@ -757,7 +767,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_mod(&mut self, item: &ast::Item) { if let Some(mod_data) = self.save_ctxt.get_item_data(item) { down_cast_data!(mod_data, DefData, item.span); - self.dumper.dump_def(&access_from!(self.save_ctxt, item), mod_data); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); + self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), mod_data); } } @@ -1197,7 +1208,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // The access is calculated using the current tree ID, but with the root tree's visibility // (since nested trees don't have their own visibility). - let access = access_from!(self.save_ctxt, root_item.vis, id); + let hir_id = self.tcx.hir().node_to_hir_id(id); + let access = access_from!(self.save_ctxt, root_item, hir_id); // The parent def id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id) @@ -1394,9 +1406,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); let id = id_from_node_id(item.id, &self.save_ctxt); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); self.dumper.dump_def( - &access_from!(self.save_ctxt, item), + &access_from!(self.save_ctxt, item, hir_id), Def { kind: DefKind::Type, id, @@ -1424,9 +1437,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); let id = id_from_node_id(item.id, &self.save_ctxt); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); self.dumper.dump_def( - &access_from!(self.save_ctxt, item), + &access_from!(self.save_ctxt, item, hir_id), Def { kind: DefKind::Type, id, @@ -1624,7 +1638,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) { - let access = access_from!(self.save_ctxt, item); + let hir_id = self.tcx.hir().node_to_hir_id(item.id); + let access = access_from!(self.save_ctxt, item, hir_id); match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 47dbbc20980ba..fe6133dc0830e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -461,11 +461,11 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt sess.abort_if_errors(); let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); - // Convert from a NodeId set to a DefId set since we don't always have easy access - // to the map from defid -> nodeid + // Convert from a HirId set to a DefId set since we don't always have easy access + // to the map from defid -> hirid let access_levels = AccessLevels { map: access_levels.map.iter() - .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) + .map(|(&k, &v)| (tcx.hir().local_def_id_from_hir_id(k), v)) .collect() };