From bc1885703cb46a462a4be1eea7c4e0f9abbe7a95 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 29 Oct 2018 14:44:15 -0400 Subject: [PATCH 01/24] Return &T / &mut T in ManuallyDrop Deref(Mut) impl Without this change the generated documentation looks like this: fn deref(&self) -> & as Deref>::Target Returning the actual type directly makes the generated docs more clear: fn deref(&self) -> &T --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 22016e8cf4174..1f1df51919c45 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1018,7 +1018,7 @@ impl ManuallyDrop { impl Deref for ManuallyDrop { type Target = T; #[inline] - fn deref(&self) -> &Self::Target { + fn deref(&self) -> &T { &self.value } } @@ -1026,7 +1026,7 @@ impl Deref for ManuallyDrop { #[stable(feature = "manually_drop", since = "1.20.0")] impl DerefMut for ManuallyDrop { #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { + fn deref_mut(&mut self) -> &mut T { &mut self.value } } From b937be87cb89f08235a57e07e9c73b4489dc50a1 Mon Sep 17 00:00:00 2001 From: Meltinglava Date: Thu, 8 Nov 2018 15:33:10 +0100 Subject: [PATCH 02/24] Clarifying documentation for collections::hash_map::Entry::or_insert Previous version does not show that or_insert does not insert the passed value, as the passed value was the same value as what was already in the map. --- src/libstd/collections/hash/map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 8de415e8aed5c..f84e03ae765fc 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2030,7 +2030,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 12); /// - /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 12).1 += 10; + /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 += 10; /// assert_eq!(map["poneyland"], 22); /// ``` #[unstable(feature = "hash_raw_entry", issue = "54043")] @@ -2652,7 +2652,7 @@ impl<'a, K, V> Entry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 12); /// - /// *map.entry("poneyland").or_insert(12) += 10; + /// *map.entry("poneyland").or_insert(10) += 10; /// assert_eq!(map["poneyland"], 22); /// ``` pub fn or_insert(self, default: V) -> &'a mut V { From 8b750a77fc73290635499494779f77848a8e2b09 Mon Sep 17 00:00:00 2001 From: Meltinglava Date: Tue, 13 Nov 2018 12:20:23 +0100 Subject: [PATCH 03/24] The example values are now easyer to differenciate --- src/libstd/collections/hash/map.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f84e03ae765fc..8ebf9b2fdf566 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2026,12 +2026,12 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 12); /// - /// assert_eq!(map["poneyland"], 12); + /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3); + /// assert_eq!(map["poneyland"], 3); /// - /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 += 10; - /// assert_eq!(map["poneyland"], 22); + /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; + /// assert_eq!(map["poneyland"], 6); /// ``` #[unstable(feature = "hash_raw_entry", issue = "54043")] pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) @@ -2648,12 +2648,12 @@ impl<'a, K, V> Entry<'a, K, V> { /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// map.entry("poneyland").or_insert(12); /// - /// assert_eq!(map["poneyland"], 12); + /// map.entry("poneyland").or_insert(3); + /// assert_eq!(map["poneyland"], 3); /// - /// *map.entry("poneyland").or_insert(10) += 10; - /// assert_eq!(map["poneyland"], 22); + /// *map.entry("poneyland").or_insert(10) *= 2; + /// assert_eq!(map["poneyland"], 6); /// ``` pub fn or_insert(self, default: V) -> &'a mut V { match self { From a9a48ed3da1134364052322d628fd9d9418998f4 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 14 Nov 2018 16:22:14 -0700 Subject: [PATCH 04/24] Fix VecDeque pretty-printer This fixes the VecDeque pretty-printer to handle cases where head < tail. Closes #55944 --- src/etc/gdb_rust_pretty_printing.py | 14 +++++++++++--- src/test/debuginfo/pretty-std-collections.rs | 11 +++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index e6d5ef1a23ff7..27275ba37957e 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -293,15 +293,23 @@ def display_hint(): def to_string(self): (tail, head, data_ptr, cap) = \ rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + if head >= tail: + size = head - tail + else: + size = cap + head - tail return (self.__val.type.get_unqualified_type_name() + - ("(len: %i, cap: %i)" % (head - tail, cap))) + ("(len: %i, cap: %i)" % (size, cap))) def children(self): (tail, head, data_ptr, cap) = \ rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) gdb_ptr = data_ptr.get_wrapped_value() - for index in xrange(tail, head): - yield (str(index), (gdb_ptr + index).dereference()) + if head >= tail: + size = head - tail + else: + size = cap + head - tail + for index in xrange(0, size): + yield (str(index), (gdb_ptr + ((tail + index) % cap)).dereference()) class RustStdBTreeSetPrinter(object): diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index 8e37a884b34bb..0d3f4b90f23ed 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -28,6 +28,9 @@ // gdb-command: print vec_deque // gdb-check:$3 = VecDeque(len: 3, cap: 8) = {5, 3, 7} +// gdb-command: print vec_deque2 +// gdb-check:$4 = VecDeque(len: 7, cap: 8) = {2, 3, 4, 5, 6, 7, 8} + #![allow(unused_variables)] use std::collections::BTreeSet; use std::collections::BTreeMap; @@ -54,6 +57,14 @@ fn main() { vec_deque.push_back(3); vec_deque.push_back(7); + // VecDeque where an element was popped. + let mut vec_deque2 = VecDeque::new(); + for i in 1..8 { + vec_deque2.push_back(i) + } + vec_deque2.pop_front(); + vec_deque2.push_back(8); + zzz(); // #break } From 052bdff8fbaef9b3c32eec842fc9c03877651cf5 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 15 Nov 2018 16:35:23 +0800 Subject: [PATCH 05/24] lint based on closure pipe span --- src/librustc/traits/error_reporting.rs | 16 +++++++++++++++- .../ui/mismatched_types/closure-arg-count.rs | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 2761a954cea88..d08a4b47b31bf 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1092,13 +1092,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(found_span) = found_span { err.span_label(found_span, format!("takes {}", found_str)); + // move |_| { ... } + // ^^^^^^^^-- def_span + // + // move |_| { ... } + // ^^^^^-- prefix + let prefix_span = self.tcx.sess.source_map().span_until_char(found_span, '|'); + // move |_| { ... } + // ^^^-- pipe_span + let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { + span + } else { + found_span + }; + // Suggest to take and ignore the arguments with expected_args_length `_`s if // found arguments is empty (assume the user just wants to ignore args in this case). // For example, if `expected_args_length` is 2, suggest `|_, _|`. if found_args.is_empty() && is_closure { let underscores = vec!["_"; expected_args.len()].join(", "); err.span_suggestion_with_applicability( - found_span, + pipe_span, &format!( "consider changing the closure to take and ignore the expected argument{}", if expected_args.len() < 2 { diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 9eb11148a8bce..ed9162d234892 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -22,6 +22,8 @@ fn main() { //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take + f(move || panic!()); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); //~^ ERROR closure is expected to take From dbd9abd74d1ca8329f483c30ba04526d8c45a5ac Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 15 Nov 2018 22:17:49 +0800 Subject: [PATCH 06/24] update closure arg suggesstion ui test --- .../mismatched_types/closure-arg-count.stderr | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 057cf6efa1dea..89977aadf88f0 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -60,8 +60,26 @@ help: consider changing the closure to take and ignore the expected argument LL | f(|_| panic!()); | ^^^ +error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments + --> $DIR/closure-arg-count.rs:25:5 + | +LL | f(move || panic!()); + | ^ ------- takes 0 arguments + | | + | expected closure that takes 1 argument + | +note: required by `f` + --> $DIR/closure-arg-count.rs:13:1 + | +LL | fn f>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider changing the closure to take and ignore the expected argument + | +LL | f(move|_| panic!()); + | ^^^ + error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 + --> $DIR/closure-arg-count.rs:28:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); | ^^^ ------ takes 2 distinct arguments @@ -73,7 +91,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 + --> $DIR/closure-arg-count.rs:30:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); | ^^^ ------------- takes 2 distinct arguments @@ -85,7 +103,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:32:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments @@ -93,7 +111,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:32:53 + --> $DIR/closure-arg-count.rs:34:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument @@ -102,7 +120,7 @@ LL | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:35:53 + --> $DIR/closure-arg-count.rs:37:53 | LL | let bar = |i, x, y| i; | --------- takes 3 distinct arguments @@ -110,7 +128,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:37:53 + --> $DIR/closure-arg-count.rs:39:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); | ^^^ expected function that takes a single 2-tuple as argument @@ -119,13 +137,13 @@ LL | fn qux(x: usize, y: usize) {} | -------------------------- takes 2 distinct arguments error[E0593]: function is expected to take 1 argument, but it takes 2 arguments - --> $DIR/closure-arg-count.rs:40:41 + --> $DIR/closure-arg-count.rs:42:41 | LL | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); | ^^^ expected function that takes 1 argument error[E0593]: function is expected to take 0 arguments, but it takes 1 argument - --> $DIR/closure-arg-count.rs:43:5 + --> $DIR/closure-arg-count.rs:45:5 | LL | call(Foo); | ^^^^ expected function that takes 0 arguments @@ -134,11 +152,11 @@ LL | struct Foo(u8); | --------------- takes 1 argument | note: required by `call` - --> $DIR/closure-arg-count.rs:50:1 + --> $DIR/closure-arg-count.rs:52:1 | LL | fn call(_: F) where F: FnOnce() -> R {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0593`. From 7cb068e52368e374f1f2c41e98f4b802d3869d14 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 13:08:58 +0100 Subject: [PATCH 07/24] add ui test --- src/test/ui/bare-function-self.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/bare-function-self.rs diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs new file mode 100644 index 0000000000000..5cd33da923c30 --- /dev/null +++ b/src/test/ui/bare-function-self.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +fn a(&self) { } +//~^ ERROR `self` argument in bare function + +fn main() { } \ No newline at end of file From 80c2101b2042ba9ba3e4c7b2351ec45867965338 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 13:54:09 +0100 Subject: [PATCH 08/24] change expected error message --- src/test/ui/bare-function-self.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs index 5cd33da923c30..01189ae321b50 100644 --- a/src/test/ui/bare-function-self.rs +++ b/src/test/ui/bare-function-self.rs @@ -10,6 +10,6 @@ fn a(&self) { } -//~^ ERROR `self` argument in bare function +//~^ ERROR unexpected `self` argument in bare function -fn main() { } \ No newline at end of file +fn main() { } From 218e35efa1500be4ebc1ee5d84a4e6971352c500 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 13:54:49 +0100 Subject: [PATCH 09/24] eat CloseDelim --- src/libsyntax/parse/parser.rs | 11 +++++++++-- src/test/ui/bare-function-self.stderr | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/bare-function-self.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d90ec4ea081b2..dd1864ce1244c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5385,11 +5385,16 @@ impl<'a> Parser<'a> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { + self.expect(&token::OpenDelim(token::Paren))?; + + if let Ok(Some(_)) = self.parse_self_arg() { + return Err(self.fatal("unexpected `self` argument in bare function")) + } + let sp = self.span; let mut variadic = false; let args: Vec> = - self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), + self.parse_seq_to_before_end( &token::CloseDelim(token::Paren), SeqSep::trailing_allowed(token::Comma), |p| { @@ -5436,6 +5441,8 @@ impl<'a> Parser<'a> { } )?; + self.eat(&token::CloseDelim(token::Paren)); + let args: Vec<_> = args.into_iter().filter_map(|x| x).collect(); if variadic && args.is_empty() { diff --git a/src/test/ui/bare-function-self.stderr b/src/test/ui/bare-function-self.stderr new file mode 100644 index 0000000000000..51db0ddd70d76 --- /dev/null +++ b/src/test/ui/bare-function-self.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in bare function + --> $DIR/bare-function-self.rs:12:11 + | +LL | fn a(&self) { } + | ^ + +error: aborting due to previous error + From 675319e5586817143fef60243d319395ae858ad1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Oct 2018 00:55:12 +0200 Subject: [PATCH 10/24] lint if a private item has doctests --- src/librustc/lint/builtin.rs | 7 +++ src/librustdoc/core.rs | 4 +- .../passes/collect_intra_doc_links.rs | 45 ++------------ src/librustdoc/passes/mod.rs | 60 ++++++++++++++++++- .../passes/private_items_doc_tests.rs | 49 +++++++++++++++ src/test/rustdoc-ui/private-item-doc-test.rs | 20 +++++++ .../rustdoc-ui/private-item-doc-test.stderr | 16 +++++ 7 files changed, 158 insertions(+), 43 deletions(-) create mode 100644 src/librustdoc/passes/private_items_doc_tests.rs create mode 100644 src/test/rustdoc-ui/private-item-doc-test.rs create mode 100644 src/test/rustdoc-ui/private-item-doc-test.stderr diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 01d87bdbf6337..22f2023eefbd8 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -318,6 +318,12 @@ declare_lint! { "warn about missing code example in an item's documentation" } +declare_lint! { + pub PRIVATE_DOC_TESTS, + Allow, + "warn about doc test in private item" +} + declare_lint! { pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, @@ -415,6 +421,7 @@ impl LintPass for HardwiredLints { DUPLICATE_MACRO_EXPORTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, + PRIVATE_DOC_TESTS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 0bd6f6bf8a2f4..aac0f9f94e329 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -351,13 +351,15 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let warnings_lint_name = lint::builtin::WARNINGS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; + let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; // In addition to those specific lints, we also need to whitelist those given through // command line, otherwise they'll get ignored and we don't want that. let mut whitelisted_lints = vec![warnings_lint_name.to_owned(), intra_link_resolution_failure_name.to_owned(), missing_docs.to_owned(), - missing_doc_example.to_owned()]; + missing_doc_example.to_owned(), + private_doc_tests.to_owned()]; whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 471ba6345e248..675e3e9be1e62 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -24,9 +24,9 @@ use std::ops::Range; use core::DocContext; use fold::DocFolder; -use html::markdown::{find_testable_code, markdown_links, ErrorCodes, LangString}; +use html::markdown::markdown_links; -use passes::Pass; +use passes::{look_for_tests, Pass}; pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass::early("collect-intra-doc-links", collect_intra_doc_links, @@ -214,43 +214,6 @@ impl<'a, 'tcx, 'rcx, 'cstore> LinkCollector<'a, 'tcx, 'rcx, 'cstore> { } } -fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>( - cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, - dox: &str, - item: &Item, -) { - if (item.is_mod() && cx.tcx.hir.as_local_node_id(item.def_id).is_none()) || - cx.as_local_node_id(item.def_id).is_none() { - // If non-local, no need to check anything. - return; - } - - struct Tests { - found_tests: usize, - } - - impl ::test::Tester for Tests { - fn add_test(&mut self, _: String, _: LangString, _: usize) { - self.found_tests += 1; - } - } - - let mut tests = Tests { - found_tests: 0, - }; - - if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() { - if tests.found_tests == 0 { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::MISSING_DOC_CODE_EXAMPLES, - NodeId::from_u32(0), - span_of_attrs(&item.attrs), - "Missing code example in this documentation"); - diag.emit(); - } - } -} - impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstore> { fn fold_item(&mut self, mut item: Item) -> Option { let item_node_id = if item.is_mod() { @@ -313,7 +276,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor let cx = self.cx; let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); - look_for_tests(&cx, &dox, &item); + look_for_tests(&cx, &dox, &item, true); if !self.is_nightly_build { return None; @@ -488,7 +451,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { None } -fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { +pub fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { if attrs.doc_strings.is_empty() { return DUMMY_SP; } diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index d00eb3257d43c..eee7278e4f0a9 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -12,16 +12,22 @@ //! process. use rustc::hir::def_id::DefId; +use rustc::lint as lint; use rustc::middle::privacy::AccessLevels; use rustc::util::nodemap::DefIdSet; use std::mem; use std::fmt; +use syntax::ast::NodeId; use clean::{self, GetDefId, Item}; -use core::DocContext; +use core::{DocContext, DocAccessLevels}; use fold; use fold::StripItem; +use html::markdown::{find_testable_code, ErrorCodes, LangString}; + +use self::collect_intra_doc_links::span_of_attrs; + mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -43,6 +49,9 @@ pub use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; mod collect_intra_doc_links; pub use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; +mod private_items_doc_tests; +pub use self::private_items_doc_tests::CHECK_PRIVATE_ITEMS_DOC_TESTS; + mod collect_trait_impls; pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; @@ -128,6 +137,7 @@ impl Pass { /// The full list of passes. pub const PASSES: &'static [Pass] = &[ + CHECK_PRIVATE_ITEMS_DOC_TESTS, STRIP_HIDDEN, UNINDENT_COMMENTS, COLLAPSE_DOCS, @@ -141,6 +151,7 @@ pub const PASSES: &'static [Pass] = &[ /// The list of passes run by default. pub const DEFAULT_PASSES: &'static [&'static str] = &[ "collect-trait-impls", + "check-private-items-doc-tests", "strip-hidden", "strip-private", "collect-intra-doc-links", @@ -152,6 +163,7 @@ pub const DEFAULT_PASSES: &'static [&'static str] = &[ /// The list of default passes run with `--document-private-items` is passed to rustdoc. pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ "collect-trait-impls", + "check-private-items-doc-tests", "strip-priv-imports", "collect-intra-doc-links", "collapse-docs", @@ -348,3 +360,49 @@ impl fold::DocFolder for ImportStripper { } } } + +pub fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>( + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, + dox: &str, + item: &Item, + check_missing_code: bool, +) { + if cx.as_local_node_id(item.def_id).is_none() { + // If non-local, no need to check anything. + return; + } + + struct Tests { + found_tests: usize, + } + + impl ::test::Tester for Tests { + fn add_test(&mut self, _: String, _: LangString, _: usize) { + self.found_tests += 1; + } + } + + let mut tests = Tests { + found_tests: 0, + }; + + if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() { + if check_missing_code == true && tests.found_tests == 0 { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::MISSING_DOC_CODE_EXAMPLES, + NodeId::from_u32(0), + span_of_attrs(&item.attrs), + "Missing code example in this documentation"); + diag.emit(); + } else if check_missing_code == false && + tests.found_tests > 0 && + !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::PRIVATE_DOC_TESTS, + NodeId::from_u32(0), + span_of_attrs(&item.attrs), + "Documentation test in private item"); + diag.emit(); + } + } +} diff --git a/src/librustdoc/passes/private_items_doc_tests.rs b/src/librustdoc/passes/private_items_doc_tests.rs new file mode 100644 index 0000000000000..7c5ce8894b106 --- /dev/null +++ b/src/librustdoc/passes/private_items_doc_tests.rs @@ -0,0 +1,49 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clean::*; + +use core::DocContext; +use fold::DocFolder; + +use passes::{look_for_tests, Pass}; + +pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = + Pass::early("check-private-items-doc-tests", check_private_items_doc_tests, + "check private items doc tests"); + +struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, +} + +impl<'a, 'tcx, 'rcx, 'cstore> PrivateItemDocTestLinter<'a, 'tcx, 'rcx, 'cstore> { + fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self { + PrivateItemDocTestLinter { + cx, + } + } +} + +pub fn check_private_items_doc_tests(krate: Crate, cx: &DocContext) -> Crate { + let mut coll = PrivateItemDocTestLinter::new(cx); + + coll.fold_crate(krate) +} + +impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for PrivateItemDocTestLinter<'a, 'tcx, 'rcx, 'cstore> { + fn fold_item(&mut self, item: Item) -> Option { + let cx = self.cx; + let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); + + look_for_tests(&cx, &dox, &item, false); + + self.fold_item_recur(item) + } +} diff --git a/src/test/rustdoc-ui/private-item-doc-test.rs b/src/test/rustdoc-ui/private-item-doc-test.rs new file mode 100644 index 0000000000000..5a13fe359f527 --- /dev/null +++ b/src/test/rustdoc-ui/private-item-doc-test.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(private_doc_tests)] + +mod foo { + /// private doc test + /// + /// ``` + /// assert!(false); + /// ``` + fn bar() {} +} diff --git a/src/test/rustdoc-ui/private-item-doc-test.stderr b/src/test/rustdoc-ui/private-item-doc-test.stderr new file mode 100644 index 0000000000000..b43add7ea505f --- /dev/null +++ b/src/test/rustdoc-ui/private-item-doc-test.stderr @@ -0,0 +1,16 @@ +error: Documentation test in private item + --> $DIR/private-item-doc-test.rs:14:5 + | +LL | / /// private doc test +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); +LL | | /// ``` + | |___________^ + | +note: lint level defined here + --> $DIR/private-item-doc-test.rs:11:9 + | +LL | #![deny(private_doc_tests)] + | ^^^^^^^^^^^^^^^^^ + From 4c4aff9b3d1734a1dfb127ce8732728edc5b39ed Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 18:28:23 +0100 Subject: [PATCH 11/24] remove license --- src/test/ui/bare-function-self.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs index 01189ae321b50..0a430aee97379 100644 --- a/src/test/ui/bare-function-self.rs +++ b/src/test/ui/bare-function-self.rs @@ -1,14 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - fn a(&self) { } //~^ ERROR unexpected `self` argument in bare function From 646d68f585e6cbabba5b7a67665af9a1f83ea6ea Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 18:43:06 +0100 Subject: [PATCH 12/24] add a note to the error message --- src/libsyntax/parse/parser.rs | 5 ++++- src/test/ui/bare-function-self.rs | 1 + src/test/ui/bare-function-self.stderr | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dd1864ce1244c..7ddb4099e0e90 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5388,7 +5388,10 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Paren))?; if let Ok(Some(_)) = self.parse_self_arg() { - return Err(self.fatal("unexpected `self` argument in bare function")) + let mut err = self.struct_span_err(self.prev_span + , "unexpected `self` argument in bare function"); + err.span_label(self.prev_span, "invalid argument in bare function"); + return Err(err); } let sp = self.span; diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs index 0a430aee97379..f906b176d9240 100644 --- a/src/test/ui/bare-function-self.rs +++ b/src/test/ui/bare-function-self.rs @@ -1,4 +1,5 @@ fn a(&self) { } //~^ ERROR unexpected `self` argument in bare function +//~| NOTE invalid argument in bare function fn main() { } diff --git a/src/test/ui/bare-function-self.stderr b/src/test/ui/bare-function-self.stderr index 51db0ddd70d76..002d71b1103e1 100644 --- a/src/test/ui/bare-function-self.stderr +++ b/src/test/ui/bare-function-self.stderr @@ -1,8 +1,8 @@ error: unexpected `self` argument in bare function - --> $DIR/bare-function-self.rs:12:11 + --> $DIR/bare-function-self.rs:1:7 | LL | fn a(&self) { } - | ^ + | ^^^^ invalid argument in bare function error: aborting due to previous error From fe23ffbda01d2033c98ec6cec7f51cb08f625ec9 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 19:27:27 +0100 Subject: [PATCH 13/24] improve error when self is used as not the first argument --- src/libsyntax/parse/parser.rs | 17 +++++++++-------- src/test/ui/bare-function-self.rs | 5 ----- .../ui/invalid-self-argument/bare-fn-start.rs | 5 +++++ src/test/ui/invalid-self-argument/bare-fn.rs | 5 +++++ src/test/ui/invalid-self-argument/trait-fn.rs | 11 +++++++++++ 5 files changed, 30 insertions(+), 13 deletions(-) delete mode 100644 src/test/ui/bare-function-self.rs create mode 100644 src/test/ui/invalid-self-argument/bare-fn-start.rs create mode 100644 src/test/ui/invalid-self-argument/bare-fn.rs create mode 100644 src/test/ui/invalid-self-argument/trait-fn.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7ddb4099e0e90..a4b01f485d38b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1824,6 +1824,14 @@ impl<'a> Parser<'a> { fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { maybe_whole!(self, NtArg, |x| x); + if let Ok(Some(_)) = self.parse_self_arg() { + let mut err = self.struct_span_err(self.prev_span, + "unexpected `self` argument in function"); + err.span_label(self.prev_span, + "`self` is only valid as the first argument of a trait function"); + return Err(err); + } + let (pat, ty) = if require_name || self.is_named_argument() { debug!("parse_arg_general parse_pat (require_name:{})", require_name); @@ -5386,14 +5394,7 @@ impl<'a> Parser<'a> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { self.expect(&token::OpenDelim(token::Paren))?; - - if let Ok(Some(_)) = self.parse_self_arg() { - let mut err = self.struct_span_err(self.prev_span - , "unexpected `self` argument in bare function"); - err.span_label(self.prev_span, "invalid argument in bare function"); - return Err(err); - } - + let sp = self.span; let mut variadic = false; let args: Vec> = diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs deleted file mode 100644 index f906b176d9240..0000000000000 --- a/src/test/ui/bare-function-self.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn a(&self) { } -//~^ ERROR unexpected `self` argument in bare function -//~| NOTE invalid argument in bare function - -fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs new file mode 100644 index 0000000000000..a84fe55502dc1 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -0,0 +1,5 @@ +fn a(&self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of a trait function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs new file mode 100644 index 0000000000000..27e56a537139f --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -0,0 +1,5 @@ +fn b(foo: u32, &mut self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of a trait function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs new file mode 100644 index 0000000000000..e2107e4d8676d --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -0,0 +1,11 @@ +struct Foo {} + +impl Foo { + fn c(foo: u32, self) {} + //~^ ERROR unexpected `self` argument in function + //~| NOTE `self` is only valid as the first argument of a trait function + + fn good(&mut self, foo: u32) {} +} + +fn main() { } From 2be930bd03d3c9b9230ae3b9cc8fc30b83378900 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 19:35:13 +0100 Subject: [PATCH 14/24] fix tidy (remove whitespace) --- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn-start.stderr | 8 ++++++++ src/test/ui/invalid-self-argument/bare-fn.stderr | 8 ++++++++ src/test/ui/invalid-self-argument/trait-fn.stderr | 8 ++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/invalid-self-argument/bare-fn-start.stderr create mode 100644 src/test/ui/invalid-self-argument/bare-fn.stderr create mode 100644 src/test/ui/invalid-self-argument/trait-fn.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a4b01f485d38b..18929af4718fe 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5394,7 +5394,7 @@ impl<'a> Parser<'a> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { self.expect(&token::OpenDelim(token::Paren))?; - + let sp = self.span; let mut variadic = false; let args: Vec> = diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr new file mode 100644 index 0000000000000..d0eca1a9e5ce1 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn-start.rs:1:7 + | +LL | fn a(&self) { } + | ^^^^ `self` is only valid as the first argument of a trait function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr new file mode 100644 index 0000000000000..bd6c598c88a0b --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn.rs:1:21 + | +LL | fn b(foo: u32, &mut self) { } + | ^^^^ `self` is only valid as the first argument of a trait function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr new file mode 100644 index 0000000000000..d056e53b95c72 --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/trait-fn.rs:4:20 + | +LL | fn c(foo: u32, self) {} + | ^^^^ `self` is only valid as the first argument of a trait function + +error: aborting due to previous error + From 5bfdcc1ab1c94baa4865093b6c36fb15416e6a4d Mon Sep 17 00:00:00 2001 From: Axary Date: Sat, 17 Nov 2018 09:36:56 +0100 Subject: [PATCH 15/24] remove stray file with UI testing output --- src/test/ui/bare-function-self.stderr | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/test/ui/bare-function-self.stderr diff --git a/src/test/ui/bare-function-self.stderr b/src/test/ui/bare-function-self.stderr deleted file mode 100644 index 002d71b1103e1..0000000000000 --- a/src/test/ui/bare-function-self.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: unexpected `self` argument in bare function - --> $DIR/bare-function-self.rs:1:7 - | -LL | fn a(&self) { } - | ^^^^ invalid argument in bare function - -error: aborting due to previous error - From d93e5b04f4817718480d17eafa0ee5e7bbe1f019 Mon Sep 17 00:00:00 2001 From: csmoe Date: Sat, 17 Nov 2018 17:57:17 +0800 Subject: [PATCH 16/24] reserve whitespaces between prefix and pipe --- src/librustc/traits/error_reporting.rs | 2 +- src/test/ui/mismatched_types/closure-arg-count.rs | 2 +- src/test/ui/mismatched_types/closure-arg-count.stderr | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d08a4b47b31bf..48b2b25d6adf9 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1097,7 +1097,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // // move |_| { ... } // ^^^^^-- prefix - let prefix_span = self.tcx.sess.source_map().span_until_char(found_span, '|'); + let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span); // move |_| { ... } // ^^^-- pipe_span let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index ed9162d234892..2dcc7a25c8401 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -22,7 +22,7 @@ fn main() { //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take - f(move || panic!()); + f( move || panic!()); //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 89977aadf88f0..eeadf07262c3e 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -63,8 +63,8 @@ LL | f(|_| panic!()); error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:25:5 | -LL | f(move || panic!()); - | ^ ------- takes 0 arguments +LL | f( move || panic!()); + | ^ ---------- takes 0 arguments | | | expected closure that takes 1 argument | @@ -75,8 +75,8 @@ LL | fn f>(_: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the closure to take and ignore the expected argument | -LL | f(move|_| panic!()); - | ^^^ +LL | f( move |_| panic!()); + | ^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments --> $DIR/closure-arg-count.rs:28:53 From 7c9bcc52668a8865f5ed71f1bc3dcead1367e148 Mon Sep 17 00:00:00 2001 From: 0xrgb <0xrgb@users.noreply.github.com> Date: Mon, 19 Nov 2018 15:59:21 +0900 Subject: [PATCH 17/24] Update any.rs documentation using keyword dyn --- src/libcore/any.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 6b26093439e4f..c2113dfd2a067 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -39,7 +39,7 @@ //! //! // Logger function for any type that implements Debug. //! fn log(value: &T) { -//! let value_any = value as &Any; +//! let value_any = value as &dyn Any; //! //! // try to convert our value to a String. If successful, we want to //! // output the String's length as well as its value. If not, it's a @@ -95,7 +95,7 @@ pub trait Any: 'static { /// /// use std::any::{Any, TypeId}; /// - /// fn is_string(s: &Any) -> bool { + /// fn is_string(s: &dyn Any) -> bool { /// TypeId::of::() == s.get_type_id() /// } /// @@ -151,7 +151,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &Any) { + /// fn is_string(s: &dyn Any) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -185,7 +185,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &Any) { + /// fn print_if_string(s: &dyn Any) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -218,7 +218,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut Any) { + /// fn modify_if_u32(s: &mut dyn Any) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } @@ -256,7 +256,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &(Any + Send)) { + /// fn is_string(s: &(dyn Any + Send)) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -282,7 +282,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &(Any + Send)) { + /// fn print_if_string(s: &(dyn Any + Send)) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -308,7 +308,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut (Any + Send)) { + /// fn modify_if_u32(s: &mut (dyn Any + Send)) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } @@ -340,7 +340,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &(Any + Send + Sync)) { + /// fn is_string(s: &(dyn Any + Send + Sync)) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -366,7 +366,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &(Any + Send + Sync)) { + /// fn print_if_string(s: &(dyn Any + Send + Sync)) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -392,7 +392,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut (Any + Send + Sync)) { + /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } From a44e446551a7251a06c23caa97aebcfbb98c79b2 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 19 Nov 2018 15:04:28 +0530 Subject: [PATCH 18/24] Add `override_export_symbols` option to Rust target specification --- src/librustc_codegen_ssa/back/linker.rs | 4 ++++ src/librustc_target/spec/mod.rs | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index da9cfbb94d1c5..ec5ca5801049e 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -1050,6 +1050,10 @@ impl<'a> Linker for WasmLd<'a> { } fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { + if let Some(ref exports) = tcx.sess.target.target.options.override_export_symbols { + return exports.clone() + } + let mut symbols = Vec::new(); let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 16dc2a91030f1..57bbf6b026089 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -683,6 +683,10 @@ pub struct TargetOptions { /// target features. This is `true` by default, and `false` for targets like /// wasm32 where the whole program either has simd or not. pub simd_types_indirect: bool, + + /// If set, have the linker export exactly these symbols, instead of using + /// the usual logic to figure this out from the crate itself. + pub override_export_symbols: Option> } impl Default for TargetOptions { @@ -763,6 +767,7 @@ impl Default for TargetOptions { emit_debug_gdb_scripts: true, requires_uwtable: false, simd_types_indirect: true, + override_export_symbols: None, } } } @@ -898,6 +903,14 @@ impl Target { ) ); } ); + ($key_name:ident, opt_list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).map(|o| o.as_array() + .map(|v| base.options.$key_name = Some(v.iter() + .map(|a| a.as_string().unwrap().to_string()).collect()) + ) + ); + } ); ($key_name:ident, optional) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(o) = obj.find(&name[..]) { @@ -1044,6 +1057,7 @@ impl Target { key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); key!(simd_types_indirect, bool); + key!(override_export_symbols, opt_list); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1253,6 +1267,7 @@ impl ToJson for Target { target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); target_option_val!(simd_types_indirect); + target_option_val!(override_export_symbols); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() From b8da7190243faca8dc0a5173496034b772ff4449 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 19 Nov 2018 13:29:35 -0800 Subject: [PATCH 19/24] Fix error message for `-C panic=xxx`. --- src/librustc/session/config.rs | 2 +- src/test/ui/panic-runtime/bad-panic-flag1.rs | 2 +- src/test/ui/panic-runtime/bad-panic-flag1.stderr | 2 +- src/test/ui/panic-runtime/bad-panic-flag2.rs | 2 +- src/test/ui/panic-runtime/bad-panic-flag2.stderr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index ee6d970750adf..c620e092f36ca 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -802,7 +802,7 @@ macro_rules! options { pub const parse_opt_uint: Option<&'static str> = Some("a number"); pub const parse_panic_strategy: Option<&'static str> = - Some("either `panic` or `abort`"); + Some("either `unwind` or `abort`"); pub const parse_relro_level: Option<&'static str> = Some("one of: `full`, `partial`, or `off`"); pub const parse_sanitizer: Option<&'static str> = diff --git a/src/test/ui/panic-runtime/bad-panic-flag1.rs b/src/test/ui/panic-runtime/bad-panic-flag1.rs index f067b6b8349b6..4e553c4df2fd4 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag1.rs +++ b/src/test/ui/panic-runtime/bad-panic-flag1.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags:-C panic=foo -// error-pattern:either `panic` or `abort` was expected +// error-pattern:either `unwind` or `abort` was expected fn main() {} diff --git a/src/test/ui/panic-runtime/bad-panic-flag1.stderr b/src/test/ui/panic-runtime/bad-panic-flag1.stderr index 3a65419c98fb7..013373c6f9313 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag1.stderr +++ b/src/test/ui/panic-runtime/bad-panic-flag1.stderr @@ -1,2 +1,2 @@ -error: incorrect value `foo` for codegen option `panic` - either `panic` or `abort` was expected +error: incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected diff --git a/src/test/ui/panic-runtime/bad-panic-flag2.rs b/src/test/ui/panic-runtime/bad-panic-flag2.rs index 0ecf65f080fa9..f560e7f4eb2de 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag2.rs +++ b/src/test/ui/panic-runtime/bad-panic-flag2.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags:-C panic -// error-pattern:requires either `panic` or `abort` +// error-pattern:requires either `unwind` or `abort` fn main() {} diff --git a/src/test/ui/panic-runtime/bad-panic-flag2.stderr b/src/test/ui/panic-runtime/bad-panic-flag2.stderr index 8d919e55c9068..6ab94ea704d30 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag2.stderr +++ b/src/test/ui/panic-runtime/bad-panic-flag2.stderr @@ -1,2 +1,2 @@ -error: codegen option `panic` requires either `panic` or `abort` (C panic=) +error: codegen option `panic` requires either `unwind` or `abort` (C panic=) From 88d60941da317d8e9deee34d2ed5e8dbb54f928c Mon Sep 17 00:00:00 2001 From: Axary Date: Tue, 20 Nov 2018 14:43:16 +0100 Subject: [PATCH 20/24] improve error note --- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn-start.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn-start.stderr | 2 +- src/test/ui/invalid-self-argument/bare-fn.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn.stderr | 2 +- src/test/ui/invalid-self-argument/trait-fn.rs | 2 +- src/test/ui/invalid-self-argument/trait-fn.stderr | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 18929af4718fe..e4a4c1f5a7ccb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1828,7 +1828,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(self.prev_span, "unexpected `self` argument in function"); err.span_label(self.prev_span, - "`self` is only valid as the first argument of a trait function"); + "`self` is only valid as the first argument of an associated function"); return Err(err); } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs index a84fe55502dc1..741ba5f41ce16 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.rs +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -1,5 +1,5 @@ fn a(&self) { } //~^ ERROR unexpected `self` argument in function -//~| NOTE `self` is only valid as the first argument of a trait function +//~| NOTE `self` is only valid as the first argument of an associated function fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr index d0eca1a9e5ce1..6a878b619d813 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -2,7 +2,7 @@ error: unexpected `self` argument in function --> $DIR/bare-fn-start.rs:1:7 | LL | fn a(&self) { } - | ^^^^ `self` is only valid as the first argument of a trait function + | ^^^^ `self` is only valid as the first argument of an associated function error: aborting due to previous error diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs index 27e56a537139f..704fa996ca631 100644 --- a/src/test/ui/invalid-self-argument/bare-fn.rs +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -1,5 +1,5 @@ fn b(foo: u32, &mut self) { } //~^ ERROR unexpected `self` argument in function -//~| NOTE `self` is only valid as the first argument of a trait function +//~| NOTE `self` is only valid as the first argument of an associated function fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr index bd6c598c88a0b..b13f746a4ec58 100644 --- a/src/test/ui/invalid-self-argument/bare-fn.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -2,7 +2,7 @@ error: unexpected `self` argument in function --> $DIR/bare-fn.rs:1:21 | LL | fn b(foo: u32, &mut self) { } - | ^^^^ `self` is only valid as the first argument of a trait function + | ^^^^ `self` is only valid as the first argument of an associated function error: aborting due to previous error diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs index e2107e4d8676d..31e867bc7641f 100644 --- a/src/test/ui/invalid-self-argument/trait-fn.rs +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -3,7 +3,7 @@ struct Foo {} impl Foo { fn c(foo: u32, self) {} //~^ ERROR unexpected `self` argument in function - //~| NOTE `self` is only valid as the first argument of a trait function + //~| NOTE `self` is only valid as the first argument of an associated function fn good(&mut self, foo: u32) {} } diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr index d056e53b95c72..b3c2cc5b5ebe0 100644 --- a/src/test/ui/invalid-self-argument/trait-fn.stderr +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -2,7 +2,7 @@ error: unexpected `self` argument in function --> $DIR/trait-fn.rs:4:20 | LL | fn c(foo: u32, self) {} - | ^^^^ `self` is only valid as the first argument of a trait function + | ^^^^ `self` is only valid as the first argument of an associated function error: aborting due to previous error From 8a0909df79d30c2d893dc6b6bfc2ec5667dc28cc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 20 Nov 2018 17:30:29 +0100 Subject: [PATCH 21/24] Remove incorrect doc comment --- src/librustc_codegen_ssa/mono_item.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 53acb3e376c77..8fe8979196904 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - use base; use rustc::hir; use rustc::hir::def::Def; From 9ce7b11e7c6ac970c4a507f27ea340d4dd4e8960 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 20 Nov 2018 17:32:46 +0100 Subject: [PATCH 22/24] Remove incorrect doc comment in rustc_mir::monomorphize::item --- src/librustc_mir/monomorphize/item.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 9d69a5669b1c0..9c90e5ffd3c78 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - use monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::DefId; From 9e2e57511f13569c8e9de910c04540ad1b93a321 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 19 Nov 2018 15:05:28 +0530 Subject: [PATCH 23/24] Add x86_64-fortanix-unknown-sgx target to the compiler --- src/librustc_target/spec/mod.rs | 2 + .../spec/x86_64_fortanix_unknown_sgx.rs | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 57bbf6b026089..986607e9ca765 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -412,6 +412,8 @@ supported_targets! { ("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf), ("aarch64-unknown-none", aarch64_unknown_none), + + ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx), } /// Everything `rustc` knows about how to compile for a specific target. diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs new file mode 100644 index 0000000000000..07383b3d64862 --- /dev/null +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -0,0 +1,72 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::iter; + +use super::{LinkerFlavor, Target, TargetOptions, PanicStrategy}; + +pub fn target() -> Result { + const PRE_LINK_ARGS: &[&str] = &[ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64", + "-fuse-ld=gold", + "-nostdlib", + "-shared", + "-Wl,-e,sgx_entry", + "-Wl,-Bstatic", + "-Wl,--gc-sections", + "-Wl,-z,text", + "-Wl,-z,norelro", + "-Wl,--rosegment", + "-Wl,--no-undefined", + "-Wl,--error-unresolved-symbols", + "-Wl,--no-undefined-version", + "-Wl,-Bsymbolic", + "-Wl,--export-dynamic", + ]; + const EXPORT_SYMBOLS: &[&str] = &[ + "sgx_entry", + "HEAP_BASE", + "HEAP_SIZE", + "RELA", + "RELACOUNT", + "ENCLAVE_SIZE", + "CFGDATA_BASE", + "DEBUG", + ]; + let opts = TargetOptions { + dynamic_linking: false, + executables: true, + linker_is_gnu: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + cpu: "x86-64".into(), + position_independent_executables: true, + pre_link_args: iter::once( + (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect()) + ).collect(), + override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()), + ..Default::default() + }; + Ok(Target { + llvm_target: "x86_64-unknown-linux-gnu".into(), + target_endian: "little".into(), + target_pointer_width: "64".into(), + target_c_int_width: "32".into(), + target_os: "unknown".into(), + target_env: "sgx".into(), + target_vendor: "fortanix".into(), + data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + linker_flavor: LinkerFlavor::Gcc, + options: opts, + }) +} From e538a4a7debaff6627c11f4a5d2cb29beea0b336 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 13 Nov 2018 13:54:51 +0100 Subject: [PATCH 24/24] core/benches/num: Add `from_str/from_str_radix()` benchmarks --- src/libcore/benches/num/mod.rs | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/libcore/benches/num/mod.rs b/src/libcore/benches/num/mod.rs index 55f0bdb57ec82..b57e167b05d9e 100644 --- a/src/libcore/benches/num/mod.rs +++ b/src/libcore/benches/num/mod.rs @@ -10,3 +10,108 @@ mod flt2dec; mod dec2flt; + +use test::Bencher; +use std::str::FromStr; + +const ASCII_NUMBERS: [&str; 19] = [ + "0", + "1", + "2", + "43", + "765", + "76567", + "987245987", + "-4aa32", + "1786235", + "8723095", + "f##5s", + "83638730", + "-2345", + "562aa43", + "-1", + "-0", + "abc", + "xyz", + "c0ffee", +]; + +macro_rules! from_str_bench { + ($mac:ident, $t:ty) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str(s).ok()) + .max() + }) + } + ) +} + +macro_rules! from_str_radix_bench { + ($mac:ident, $t:ty, $radix:expr) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str_radix(s, $radix).ok()) + .max() + }) + } + ) +} + +from_str_bench!(bench_u8_from_str, u8); +from_str_radix_bench!(bench_u8_from_str_radix_2, u8, 2); +from_str_radix_bench!(bench_u8_from_str_radix_10, u8, 10); +from_str_radix_bench!(bench_u8_from_str_radix_16, u8, 16); +from_str_radix_bench!(bench_u8_from_str_radix_36, u8, 36); + +from_str_bench!(bench_u16_from_str, u16); +from_str_radix_bench!(bench_u16_from_str_radix_2, u16, 2); +from_str_radix_bench!(bench_u16_from_str_radix_10, u16, 10); +from_str_radix_bench!(bench_u16_from_str_radix_16, u16, 16); +from_str_radix_bench!(bench_u16_from_str_radix_36, u16, 36); + +from_str_bench!(bench_u32_from_str, u32); +from_str_radix_bench!(bench_u32_from_str_radix_2, u32, 2); +from_str_radix_bench!(bench_u32_from_str_radix_10, u32, 10); +from_str_radix_bench!(bench_u32_from_str_radix_16, u32, 16); +from_str_radix_bench!(bench_u32_from_str_radix_36, u32, 36); + +from_str_bench!(bench_u64_from_str, u64); +from_str_radix_bench!(bench_u64_from_str_radix_2, u64, 2); +from_str_radix_bench!(bench_u64_from_str_radix_10, u64, 10); +from_str_radix_bench!(bench_u64_from_str_radix_16, u64, 16); +from_str_radix_bench!(bench_u64_from_str_radix_36, u64, 36); + +from_str_bench!(bench_i8_from_str, i8); +from_str_radix_bench!(bench_i8_from_str_radix_2, i8, 2); +from_str_radix_bench!(bench_i8_from_str_radix_10, i8, 10); +from_str_radix_bench!(bench_i8_from_str_radix_16, i8, 16); +from_str_radix_bench!(bench_i8_from_str_radix_36, i8, 36); + +from_str_bench!(bench_i16_from_str, i16); +from_str_radix_bench!(bench_i16_from_str_radix_2, i16, 2); +from_str_radix_bench!(bench_i16_from_str_radix_10, i16, 10); +from_str_radix_bench!(bench_i16_from_str_radix_16, i16, 16); +from_str_radix_bench!(bench_i16_from_str_radix_36, i16, 36); + +from_str_bench!(bench_i32_from_str, i32); +from_str_radix_bench!(bench_i32_from_str_radix_2, i32, 2); +from_str_radix_bench!(bench_i32_from_str_radix_10, i32, 10); +from_str_radix_bench!(bench_i32_from_str_radix_16, i32, 16); +from_str_radix_bench!(bench_i32_from_str_radix_36, i32, 36); + +from_str_bench!(bench_i64_from_str, i64); +from_str_radix_bench!(bench_i64_from_str_radix_2, i64, 2); +from_str_radix_bench!(bench_i64_from_str_radix_10, i64, 10); +from_str_radix_bench!(bench_i64_from_str_radix_16, i64, 16); +from_str_radix_bench!(bench_i64_from_str_radix_36, i64, 36);