From 4d04b0b0fe16dbf2227b308907bc2652be4c7c95 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 2 Jan 2020 04:02:48 +0100 Subject: [PATCH 01/18] Remove wrong advice about spin locks from `spin_loop_hint` docs Using a pure spin lock for a critical section in a preemptable thread is always wrong, however short the critical section may be. The thread might be preempted, which will cause all other threads to hammer busily at the core for the whole quant. Moreover, if threads have different priorities, this might lead to a priority inversion problem and a deadlock. More generally, a spinlock is not more efficient than a well-written mutex, which typically does several spin iterations at the start anyway. The advise about UP vs SMP is also irrelevant in the context of preemptive threads. --- src/libcore/sync/atomic.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index a2352c08e7316..ba41cd2b7a08e 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -134,16 +134,8 @@ use crate::hint::spin_loop; /// This function is different from [`std::thread::yield_now`] which directly yields to the /// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system. /// -/// Spin locks can be very efficient for short lock durations because they do not involve context -/// switches or interaction with the operating system. For long lock durations they become wasteful -/// however because they use CPU cycles for the entire lock duration, and using a -/// [`std::sync::Mutex`] is likely the better approach. If actively spinning for a long time is -/// required, e.g. because code polls a non-blocking API, calling [`std::thread::yield_now`] -/// or [`std::thread::sleep`] may be the best option. -/// -/// **Note**: Spin locks are based on the underlying assumption that another thread will release -/// the lock 'soon'. In order for this to work, that other thread must run on a different CPU or -/// core (at least potentially). Spin locks do not work efficiently on single CPU / core platforms. +/// If actively spinning for a long time is required, e.g. because code polls a non-blocking API, +/// calling [`std::thread::yield_now`] or [`std::thread::sleep`] may be the best option. /// /// **Note**: On platforms that do not support receiving spin-loop hints this function does not /// do anything at all. From 91334e0a799c35d6adf0a226a2f0aee0d70896e3 Mon Sep 17 00:00:00 2001 From: cjkenn Date: Fri, 3 Jan 2020 15:53:03 -0800 Subject: [PATCH 02/18] add a check for variable names that might match by word --- src/libsyntax/util/lev_distance.rs | 33 ++++++++++++++++++++---- src/libsyntax/util/lev_distance/tests.rs | 6 +++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs index f55b58d7d137a..8ddda1720b8d7 100644 --- a/src/libsyntax/util/lev_distance.rs +++ b/src/libsyntax/util/lev_distance.rs @@ -52,14 +52,15 @@ where T: Iterator, { let max_dist = dist.map_or_else(|| cmp::max(lookup.len(), 3) / 3, |d| d); + let name_vec: Vec<&Symbol> = iter_names.collect(); - let (case_insensitive_match, levenstein_match) = iter_names + let (case_insensitive_match, levenshtein_match) = name_vec.iter() .filter_map(|&name| { let dist = lev_distance(lookup, &name.as_str()); if dist <= max_dist { Some((name, dist)) } else { None } }) // Here we are collecting the next structure: - // (case_insensitive_match, (levenstein_match, levenstein_distance)) + // (case_insensitive_match, (levenshtein_match, levenshtein_distance)) .fold((None, None), |result, (candidate, dist)| { ( if candidate.as_str().to_uppercase() == lookup.to_uppercase() { @@ -73,10 +74,32 @@ where }, ) }); - + + // Priority of matches: + // 1. Exact case insensitive match + // 2. Levenshtein distance match + // 3. Sorted word match if let Some(candidate) = case_insensitive_match { - Some(candidate) // exact case insensitive match has a higher priority + Some(*candidate) + } else if levenshtein_match.is_some() { + levenshtein_match.map(|(candidate, _)| *candidate) } else { - levenstein_match.map(|(candidate, _)| candidate) + find_match_by_sorted_words(name_vec, lookup) } } + +fn find_match_by_sorted_words<'a>(iter_names: Vec<&'a Symbol>, lookup: &str) -> Option { + iter_names.iter().fold(None, |result, candidate| { + if sort_by_words(&candidate.as_str()) == sort_by_words(lookup) { + Some(**candidate) + } else { + result + } + }) +} + +fn sort_by_words(name: &str) -> String { + let mut split_words: Vec<&str> = name.split('_').collect(); + split_words.sort(); + split_words.join("_") +} diff --git a/src/libsyntax/util/lev_distance/tests.rs b/src/libsyntax/util/lev_distance/tests.rs index f65f9275d0341..222661687c1c2 100644 --- a/src/libsyntax/util/lev_distance/tests.rs +++ b/src/libsyntax/util/lev_distance/tests.rs @@ -46,5 +46,11 @@ fn test_find_best_match_for_name() { find_best_match_for_name(input.iter(), "aaaa", Some(4)), Some(Symbol::intern("AAAA")) ); + + let input = vec![Symbol::intern("a_longer_variable_name")]; + assert_eq!( + find_best_match_for_name(input.iter(), "a_variable_longer_name", None), + Some(Symbol::intern("a_longer_variable_name")) + ); }) } From 27ea4c855e2adeeea9e5e58622715d45fd9c7801 Mon Sep 17 00:00:00 2001 From: cjkenn Date: Fri, 3 Jan 2020 17:01:16 -0800 Subject: [PATCH 03/18] missed tidy check --- src/libsyntax/util/lev_distance.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs index 8ddda1720b8d7..afbf91c00554e 100644 --- a/src/libsyntax/util/lev_distance.rs +++ b/src/libsyntax/util/lev_distance.rs @@ -54,7 +54,8 @@ where let max_dist = dist.map_or_else(|| cmp::max(lookup.len(), 3) / 3, |d| d); let name_vec: Vec<&Symbol> = iter_names.collect(); - let (case_insensitive_match, levenshtein_match) = name_vec.iter() + let (case_insensitive_match, levenshtein_match) = name_vec + .iter() .filter_map(|&name| { let dist = lev_distance(lookup, &name.as_str()); if dist <= max_dist { Some((name, dist)) } else { None } @@ -74,7 +75,6 @@ where }, ) }); - // Priority of matches: // 1. Exact case insensitive match // 2. Levenshtein distance match From e01e8b9256587a074968b440aa30d43b31642cb5 Mon Sep 17 00:00:00 2001 From: cjkenn Date: Sat, 4 Jan 2020 10:58:04 -0800 Subject: [PATCH 04/18] add ui test --- .../ui/suggestions/issue-66968-suggest-sorted-words.rs | 4 ++++ .../suggestions/issue-66968-suggest-sorted-words.stderr | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/ui/suggestions/issue-66968-suggest-sorted-words.rs create mode 100644 src/test/ui/suggestions/issue-66968-suggest-sorted-words.stderr diff --git a/src/test/ui/suggestions/issue-66968-suggest-sorted-words.rs b/src/test/ui/suggestions/issue-66968-suggest-sorted-words.rs new file mode 100644 index 0000000000000..440bb653a83c3 --- /dev/null +++ b/src/test/ui/suggestions/issue-66968-suggest-sorted-words.rs @@ -0,0 +1,4 @@ +fn main() { + let a_longer_variable_name = 1; + println!("{}", a_variable_longer_name); //~ ERROR E0425 +} diff --git a/src/test/ui/suggestions/issue-66968-suggest-sorted-words.stderr b/src/test/ui/suggestions/issue-66968-suggest-sorted-words.stderr new file mode 100644 index 0000000000000..d7b33ea41f79a --- /dev/null +++ b/src/test/ui/suggestions/issue-66968-suggest-sorted-words.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `a_variable_longer_name` in this scope + --> $DIR/issue-66968-suggest-sorted-words.rs:3:20 + | +LL | println!("{}", a_variable_longer_name); + | ^^^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `a_longer_variable_name` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From 90adafbc9e6583fa2edae0f320e7fe51407e7f3b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 4 Jan 2020 10:58:32 -0800 Subject: [PATCH 05/18] Distinguish between private items and hidden items in rustdoc I believe rustdoc should not be conflating private items (visibility lower than `pub`) and hidden items (attribute `doc(hidden)`). This matters now that Cargo is passing --document-private-items by default for bin crates. In bin crates that rely on macros, intentionally hidden implementation details of the macros can overwhelm the actual useful internal API that one would want to document. This PR restores the strip-hidden pass when documenting private items, and introduces a separate unstable --document-hidden-items option to skip the strip-hidden pass. The two options are orthogonal to one another. --- src/librustdoc/config.rs | 43 +++++---- src/librustdoc/core.rs | 26 ++++-- src/librustdoc/lib.rs | 3 + .../passes/calculate_doc_coverage.rs | 2 +- .../passes/check_code_block_syntax.rs | 2 +- src/librustdoc/passes/collapse_docs.rs | 2 +- .../passes/collect_intra_doc_links.rs | 2 +- src/librustdoc/passes/collect_trait_impls.rs | 2 +- src/librustdoc/passes/mod.rs | 87 +++++++++++-------- .../passes/private_items_doc_tests.rs | 2 +- src/librustdoc/passes/propagate_doc_cfg.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 2 +- src/librustdoc/passes/strip_priv_imports.rs | 2 +- src/librustdoc/passes/strip_private.rs | 2 +- src/librustdoc/passes/unindent_comments.rs | 2 +- src/test/rustdoc/issue-46380.rs | 5 -- src/test/rustdoc/issue-67851-both.rs | 8 ++ src/test/rustdoc/issue-67851-hidden.rs | 8 ++ src/test/rustdoc/issue-67851-neither.rs | 6 ++ src/test/rustdoc/issue-67851-private.rs | 8 ++ 20 files changed, 138 insertions(+), 78 deletions(-) delete mode 100644 src/test/rustdoc/issue-46380.rs create mode 100644 src/test/rustdoc/issue-67851-both.rs create mode 100644 src/test/rustdoc/issue-67851-hidden.rs create mode 100644 src/test/rustdoc/issue-67851-neither.rs create mode 100644 src/test/rustdoc/issue-67851-private.rs diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 4a65a9f431a44..dbb67345ba041 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -24,7 +24,7 @@ use crate::html; use crate::html::markdown::IdMap; use crate::html::static_files; use crate::opts; -use crate::passes::{self, DefaultPassOption}; +use crate::passes::{self, Condition, DefaultPassOption}; use crate::theme; /// Configuration options for rustdoc. @@ -98,6 +98,10 @@ pub struct Options { /// /// Be aware: This option can come both from the CLI and from crate attributes! pub default_passes: DefaultPassOption, + /// Document items that have lower than `pub` visibility. + pub document_private: bool, + /// Document items that have `doc(hidden)`. + pub document_hidden: bool, /// Any passes manually selected by the user. /// /// Be aware: This option can come both from the CLI and from crate attributes! @@ -146,6 +150,8 @@ impl fmt::Debug for Options { .field("test_args", &self.test_args) .field("persist_doctests", &self.persist_doctests) .field("default_passes", &self.default_passes) + .field("document_private", &self.document_private) + .field("document_hidden", &self.document_hidden) .field("manual_passes", &self.manual_passes) .field("display_warnings", &self.display_warnings) .field("show_coverage", &self.show_coverage) @@ -240,22 +246,26 @@ impl Options { println!("{:>20} - {}", pass.name, pass.description); } println!("\nDefault passes for rustdoc:"); - for pass in passes::DEFAULT_PASSES { - println!("{:>20}", pass.name); - } - println!("\nPasses run with `--document-private-items`:"); - for pass in passes::DEFAULT_PRIVATE_PASSES { - println!("{:>20}", pass.name); + for p in passes::DEFAULT_PASSES { + print!("{:>20}", p.pass.name); + println_condition(p.condition); } if nightly_options::is_nightly_build() { println!("\nPasses run with `--show-coverage`:"); - for pass in passes::DEFAULT_COVERAGE_PASSES { - println!("{:>20}", pass.name); + for p in passes::COVERAGE_PASSES { + print!("{:>20}", p.pass.name); + println_condition(p.condition); } - println!("\nPasses run with `--show-coverage --document-private-items`:"); - for pass in passes::PRIVATE_COVERAGE_PASSES { - println!("{:>20}", pass.name); + } + + fn println_condition(condition: Condition) { + use Condition::*; + match condition { + Always => println!(), + WhenDocumentPrivate => println!(" (when --document-private-items)"), + WhenNotDocumentPrivate => println!(" (when not --document-private-items)"), + WhenNotDocumentHidden => println!(" (when not --document-hidden-items)"), } } @@ -449,16 +459,11 @@ impl Options { }); let show_coverage = matches.opt_present("show-coverage"); - let document_private = matches.opt_present("document-private-items"); let default_passes = if matches.opt_present("no-defaults") { passes::DefaultPassOption::None - } else if show_coverage && document_private { - passes::DefaultPassOption::PrivateCoverage } else if show_coverage { passes::DefaultPassOption::Coverage - } else if document_private { - passes::DefaultPassOption::Private } else { passes::DefaultPassOption::Default }; @@ -497,6 +502,8 @@ impl Options { let runtool = matches.opt_str("runtool"); let runtool_args = matches.opt_strs("runtool-arg"); let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores"); + let document_private = matches.opt_present("document-private-items"); + let document_hidden = matches.opt_present("document-hidden-items"); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -523,6 +530,8 @@ impl Options { should_test, test_args, default_passes, + document_private, + document_hidden, manual_passes, display_warnings, show_coverage, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index cb22039327e07..64c2a28de8371 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -33,7 +33,7 @@ use crate::clean::{AttributesExt, MAX_DEF_ID}; use crate::config::{Options as RustdocOptions, RenderOptions}; use crate::html::render::RenderInfo; -use crate::passes; +use crate::passes::{self, Condition::*, ConditionalPass}; pub use rustc::session::config::{CodegenOptions, Input, Options}; pub use rustc::session::search_paths::SearchPath; @@ -234,6 +234,8 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt describe_lints, lint_cap, mut default_passes, + mut document_private, + document_hidden, mut manual_passes, display_warnings, render_options, @@ -470,16 +472,14 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt } if attr.is_word() && name == sym::document_private_items { - if default_passes == passes::DefaultPassOption::Default { - default_passes = passes::DefaultPassOption::Private; - } + document_private = true; } } - let passes = passes::defaults(default_passes).iter().chain( + let passes = passes::defaults(default_passes).iter().copied().chain( manual_passes.into_iter().flat_map(|name| { if let Some(pass) = passes::find_pass(&name) { - Some(pass) + Some(ConditionalPass::always(pass)) } else { error!("unknown pass {}, skipping", name); None @@ -489,9 +489,17 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt info!("Executing passes"); - for pass in passes { - debug!("running pass {}", pass.name); - krate = (pass.pass)(krate, &ctxt); + for p in passes { + let run = match p.condition { + Always => true, + WhenDocumentPrivate => document_private, + WhenNotDocumentPrivate => !document_private, + WhenNotDocumentHidden => !document_hidden, + }; + if run { + debug!("running pass {}", p.pass.name); + krate = (p.pass.run)(krate, &ctxt); + } } ctxt.sess().abort_if_errors(); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 998b28b8807d3..281e78a692a99 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -173,6 +173,9 @@ fn opts() -> Vec { stable("document-private-items", |o| { o.optflag("", "document-private-items", "document private items") }), + unstable("document-hidden-items", |o| { + o.optflag("", "document-hidden-items", "document items that have doc(hidden)") + }), stable("test", |o| o.optflag("", "test", "run code examples as tests")), stable("test-args", |o| { o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS") diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 803bcc2cfdf86..7ed531c9206af 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -12,7 +12,7 @@ use std::ops; pub const CALCULATE_DOC_COVERAGE: Pass = Pass { name: "calculate-doc-coverage", - pass: calculate_doc_coverage, + run: calculate_doc_coverage, description: "counts the number of items with and without documentation", }; diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index b568d034d8934..476c4a0a9c00d 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -13,7 +13,7 @@ use crate::passes::Pass; pub const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass { name: "check-code-block-syntax", - pass: check_code_block_syntax, + run: check_code_block_syntax, description: "validates syntax inside Rust code blocks", }; diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index c6b22883e9723..c2185592d1483 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -8,7 +8,7 @@ use std::mem::take; pub const COLLAPSE_DOCS: Pass = Pass { name: "collapse-docs", - pass: collapse_docs, + run: collapse_docs, description: "concatenates all document attributes into one document attribute", }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a8bb40a06b989..26d49cf348514 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -28,7 +28,7 @@ use super::span_of_attrs; pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass { name: "collect-intra-doc-links", - pass: collect_intra_doc_links, + run: collect_intra_doc_links, description: "reads a crate's documentation to resolve intra-doc-links", }; diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 63ad9a66a482d..473e683df0181 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -9,7 +9,7 @@ use rustc_span::symbol::sym; pub const COLLECT_TRAIT_IMPLS: Pass = Pass { name: "collect-trait-impls", - pass: collect_trait_impls, + run: collect_trait_impls, description: "retrieves trait impls for items in the crate", }; diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 7ac3009d8271d..6fa226433fcac 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -9,6 +9,7 @@ use rustc_span::{InnerSpan, Span, DUMMY_SP}; use std::mem; use std::ops::Range; +use self::Condition::*; use crate::clean::{self, GetDefId, Item}; use crate::core::DocContext; use crate::fold::{DocFolder, StripItem}; @@ -53,10 +54,29 @@ pub use self::calculate_doc_coverage::CALCULATE_DOC_COVERAGE; #[derive(Copy, Clone)] pub struct Pass { pub name: &'static str, - pub pass: fn(clean::Crate, &DocContext<'_>) -> clean::Crate, + pub run: fn(clean::Crate, &DocContext<'_>) -> clean::Crate, pub description: &'static str, } +/// In a list of passes, a pass that may or may not need to be run depending on options. +#[derive(Copy, Clone)] +pub struct ConditionalPass { + pub pass: Pass, + pub condition: Condition, +} + +/// How to decide whether to run a conditional pass. +#[derive(Copy, Clone)] +pub enum Condition { + Always, + /// When `--document-private-items` is passed. + WhenDocumentPrivate, + /// When `--document-private-items` is not passed. + WhenNotDocumentPrivate, + /// When `--document-hidden-items` is not passed. + WhenNotDocumentHidden, +} + /// The full list of passes. pub const PASSES: &[Pass] = &[ CHECK_PRIVATE_ITEMS_DOC_TESTS, @@ -73,63 +93,58 @@ pub const PASSES: &[Pass] = &[ ]; /// The list of passes run by default. -pub const DEFAULT_PASSES: &[Pass] = &[ - COLLECT_TRAIT_IMPLS, - COLLAPSE_DOCS, - UNINDENT_COMMENTS, - CHECK_PRIVATE_ITEMS_DOC_TESTS, - STRIP_HIDDEN, - STRIP_PRIVATE, - COLLECT_INTRA_DOC_LINKS, - CHECK_CODE_BLOCK_SYNTAX, - PROPAGATE_DOC_CFG, +pub const DEFAULT_PASSES: &[ConditionalPass] = &[ + ConditionalPass::always(COLLECT_TRAIT_IMPLS), + ConditionalPass::always(COLLAPSE_DOCS), + ConditionalPass::always(UNINDENT_COMMENTS), + ConditionalPass::always(CHECK_PRIVATE_ITEMS_DOC_TESTS), + ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), + ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), + ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate), + ConditionalPass::always(COLLECT_INTRA_DOC_LINKS), + ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX), + ConditionalPass::always(PROPAGATE_DOC_CFG), ]; -/// The list of default passes run with `--document-private-items` is passed to rustdoc. -pub const DEFAULT_PRIVATE_PASSES: &[Pass] = &[ - COLLECT_TRAIT_IMPLS, - COLLAPSE_DOCS, - UNINDENT_COMMENTS, - CHECK_PRIVATE_ITEMS_DOC_TESTS, - STRIP_PRIV_IMPORTS, - COLLECT_INTRA_DOC_LINKS, - CHECK_CODE_BLOCK_SYNTAX, - PROPAGATE_DOC_CFG, +/// The list of default passes run when `--doc-coverage` is passed to rustdoc. +pub const COVERAGE_PASSES: &[ConditionalPass] = &[ + ConditionalPass::always(COLLECT_TRAIT_IMPLS), + ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), + ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), + ConditionalPass::always(CALCULATE_DOC_COVERAGE), ]; -/// The list of default passes run when `--doc-coverage` is passed to rustdoc. -pub const DEFAULT_COVERAGE_PASSES: &[Pass] = - &[COLLECT_TRAIT_IMPLS, STRIP_HIDDEN, STRIP_PRIVATE, CALCULATE_DOC_COVERAGE]; +impl ConditionalPass { + pub const fn always(pass: Pass) -> Self { + Self::new(pass, Always) + } -/// The list of default passes run when `--doc-coverage --document-private-items` is passed to -/// rustdoc. -pub const PRIVATE_COVERAGE_PASSES: &[Pass] = &[COLLECT_TRAIT_IMPLS, CALCULATE_DOC_COVERAGE]; + pub const fn new(pass: Pass, condition: Condition) -> Self { + ConditionalPass { pass, condition } + } +} /// A shorthand way to refer to which set of passes to use, based on the presence of -/// `--no-defaults` or `--document-private-items`. +/// `--no-defaults` and `--show-coverage`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum DefaultPassOption { Default, - Private, Coverage, - PrivateCoverage, None, } /// Returns the given default set of passes. -pub fn defaults(default_set: DefaultPassOption) -> &'static [Pass] { +pub fn defaults(default_set: DefaultPassOption) -> &'static [ConditionalPass] { match default_set { DefaultPassOption::Default => DEFAULT_PASSES, - DefaultPassOption::Private => DEFAULT_PRIVATE_PASSES, - DefaultPassOption::Coverage => DEFAULT_COVERAGE_PASSES, - DefaultPassOption::PrivateCoverage => PRIVATE_COVERAGE_PASSES, + DefaultPassOption::Coverage => COVERAGE_PASSES, DefaultPassOption::None => &[], } } /// If the given name matches a known pass, returns its information. -pub fn find_pass(pass_name: &str) -> Option<&'static Pass> { - PASSES.iter().find(|p| p.name == pass_name) +pub fn find_pass(pass_name: &str) -> Option { + PASSES.iter().find(|p| p.name == pass_name).copied() } struct Stripper<'a> { diff --git a/src/librustdoc/passes/private_items_doc_tests.rs b/src/librustdoc/passes/private_items_doc_tests.rs index 23e272709705d..aec5a6bd4e221 100644 --- a/src/librustdoc/passes/private_items_doc_tests.rs +++ b/src/librustdoc/passes/private_items_doc_tests.rs @@ -5,7 +5,7 @@ use crate::passes::{look_for_tests, Pass}; pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass { name: "check-private-items-doc-tests", - pass: check_private_items_doc_tests, + run: check_private_items_doc_tests, description: "check private items doc tests", }; diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index a296e73e3b5fd..64b0c45ba65d3 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -8,7 +8,7 @@ use crate::passes::Pass; pub const PROPAGATE_DOC_CFG: Pass = Pass { name: "propagate-doc-cfg", - pass: propagate_doc_cfg, + run: propagate_doc_cfg, description: "propagates `#[doc(cfg(...))]` to child items", }; diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 9698ad1d2312d..47f43958ed554 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -10,7 +10,7 @@ use crate::passes::{ImplStripper, Pass}; pub const STRIP_HIDDEN: Pass = Pass { name: "strip-hidden", - pass: strip_hidden, + run: strip_hidden, description: "strips all doc(hidden) items from the output", }; diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index af34842ad0f89..35b26fb8ab0be 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -5,7 +5,7 @@ use crate::passes::{ImportStripper, Pass}; pub const STRIP_PRIV_IMPORTS: Pass = Pass { name: "strip-priv-imports", - pass: strip_priv_imports, + run: strip_priv_imports, description: "strips all private import statements (`use`, `extern crate`) from a crate", }; diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 5113afa48402c..e0379d7ffe2c5 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -7,7 +7,7 @@ use crate::passes::{ImplStripper, ImportStripper, Pass, Stripper}; pub const STRIP_PRIVATE: Pass = Pass { name: "strip-private", - pass: strip_private, + run: strip_private, description: "strips all private items from a crate which cannot be seen externally, \ implies strip-priv-imports", }; diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index 3212af055efc5..d4e09ce47a3c1 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -12,7 +12,7 @@ mod tests; pub const UNINDENT_COMMENTS: Pass = Pass { name: "unindent-comments", - pass: unindent_comments, + run: unindent_comments, description: "removes excess indentation on comments in order for markdown to like it", }; diff --git a/src/test/rustdoc/issue-46380.rs b/src/test/rustdoc/issue-46380.rs deleted file mode 100644 index 8837a6b463e88..0000000000000 --- a/src/test/rustdoc/issue-46380.rs +++ /dev/null @@ -1,5 +0,0 @@ -// compile-flags: --document-private-items - -// @has issue_46380/struct.Hidden.html -#[doc(hidden)] -pub struct Hidden; diff --git a/src/test/rustdoc/issue-67851-both.rs b/src/test/rustdoc/issue-67851-both.rs new file mode 100644 index 0000000000000..d69b943173412 --- /dev/null +++ b/src/test/rustdoc/issue-67851-both.rs @@ -0,0 +1,8 @@ +// compile-flags: -Zunstable-options --document-private-items --document-hidden-items + +// @has issue_67851_both/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @has issue_67851_both/struct.Private.html +struct Private; diff --git a/src/test/rustdoc/issue-67851-hidden.rs b/src/test/rustdoc/issue-67851-hidden.rs new file mode 100644 index 0000000000000..8a3cafe4c3dc7 --- /dev/null +++ b/src/test/rustdoc/issue-67851-hidden.rs @@ -0,0 +1,8 @@ +// compile-flags: -Zunstable-options --document-hidden-items + +// @has issue_67851_hidden/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @!has issue_67851_hidden/struct.Private.html +struct Private; diff --git a/src/test/rustdoc/issue-67851-neither.rs b/src/test/rustdoc/issue-67851-neither.rs new file mode 100644 index 0000000000000..4e3cd83285388 --- /dev/null +++ b/src/test/rustdoc/issue-67851-neither.rs @@ -0,0 +1,6 @@ +// @!has issue_67851_neither/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @!has issue_67851_neither/struct.Private.html +struct Private; diff --git a/src/test/rustdoc/issue-67851-private.rs b/src/test/rustdoc/issue-67851-private.rs new file mode 100644 index 0000000000000..8addc7f3e4b53 --- /dev/null +++ b/src/test/rustdoc/issue-67851-private.rs @@ -0,0 +1,8 @@ +// compile-flags: --document-private-items + +// @!has issue_67851_private/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @has issue_67851_private/struct.Private.html +struct Private; From 2e9d573d3f6bc9808e01cef914084fac15f42cc2 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 4 Jan 2020 19:30:44 -0800 Subject: [PATCH 06/18] Option's panics are all #[track_caller]. Also includes a simple test with a custom panic hook to ensure we don't regress. --- src/libcore/option.rs | 6 ++++ .../std-panic-locations.rs | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/test/ui/rfc-2091-track-caller/std-panic-locations.rs diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 2066a484dac80..fb534586fc615 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -341,6 +341,7 @@ impl Option { /// x.expect("the world is ending"); // panics with `the world is ending` /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn expect(self, msg: &str) -> T { match self { @@ -374,6 +375,7 @@ impl Option { /// assert_eq!(x.unwrap(), "air"); // fails /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap(self) -> T { match self { @@ -1015,6 +1017,7 @@ impl Option { /// } /// ``` #[inline] + #[track_caller] #[unstable(feature = "option_expect_none", reason = "newly added", issue = "62633")] pub fn expect_none(self, msg: &str) { if let Some(val) = self { @@ -1057,6 +1060,7 @@ impl Option { /// } /// ``` #[inline] + #[track_caller] #[unstable(feature = "option_unwrap_none", reason = "newly added", issue = "62633")] pub fn unwrap_none(self) { if let Some(val) = self { @@ -1184,6 +1188,7 @@ impl Option> { // This is a separate function to reduce the code size of .expect() itself. #[inline(never)] #[cold] +#[track_caller] fn expect_failed(msg: &str) -> ! { panic!("{}", msg) } @@ -1191,6 +1196,7 @@ fn expect_failed(msg: &str) -> ! { // This is a separate function to reduce the code size of .expect_none() itself. #[inline(never)] #[cold] +#[track_caller] fn expect_none_failed(msg: &str, value: &dyn fmt::Debug) -> ! { panic!("{}: {:?}", msg, value) } diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs new file mode 100644 index 0000000000000..96620d6440fb6 --- /dev/null +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -0,0 +1,29 @@ +// run-pass + +#![feature(option_expect_none, option_unwrap_none)] + +//! Test that panic locations for `#[track_caller]` functions in std have the correct +//! location reported. + +fn main() { + // inspect the `PanicInfo` we receive to ensure the right file is the source + std::panic::set_hook(Box::new(|info| { + let actual = info.location().unwrap(); + if actual.file() != file!(){ + eprintln!("expected a location in the test file, found {:?}", actual); + panic!(); + } + })); + + fn assert_panicked(f: impl FnOnce() + std::panic::UnwindSafe) { + std::panic::catch_unwind(f).unwrap_err(); + } + + let nope: Option<()> = None; + assert_panicked(|| nope.unwrap()); + assert_panicked(|| nope.expect("")); + + let yep: Option<()> = Some(()); + assert_panicked(|| yep.unwrap_none()); + assert_panicked(|| yep.expect_none("")); +} From 7a6af7eb0ef685c2dfd907f7e76a876174c9f665 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 4 Jan 2020 19:42:21 -0800 Subject: [PATCH 07/18] Result's panics have `#[track_caller]`. --- src/libcore/result.rs | 5 +++++ src/test/ui/rfc-2091-track-caller/std-panic-locations.rs | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 5cfc81097dd44..b39abf917850d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -957,6 +957,7 @@ impl Result { /// x.unwrap(); // panics with `emergency failure` /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap(self) -> T { match self { @@ -984,6 +985,7 @@ impl Result { /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` /// ``` #[inline] + #[track_caller] #[stable(feature = "result_expect", since = "1.4.0")] pub fn expect(self, msg: &str) -> T { match self { @@ -1017,6 +1019,7 @@ impl Result { /// assert_eq!(x.unwrap_err(), "emergency failure"); /// ``` #[inline] + #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] pub fn unwrap_err(self) -> E { match self { @@ -1044,6 +1047,7 @@ impl Result { /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10` /// ``` #[inline] + #[track_caller] #[stable(feature = "result_expect_err", since = "1.17.0")] pub fn expect_err(self, msg: &str) -> E { match self { @@ -1188,6 +1192,7 @@ impl Result, E> { // This is a separate function to reduce the code size of the methods #[inline(never)] #[cold] +#[track_caller] fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! { panic!("{}: {:?}", msg, error) } diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index 96620d6440fb6..c65027d9cac73 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -26,4 +26,12 @@ fn main() { let yep: Option<()> = Some(()); assert_panicked(|| yep.unwrap_none()); assert_panicked(|| yep.expect_none("")); + + let oops: Result<(), ()> = Err(()); + assert_panicked(|| oops.unwrap()); + assert_panicked(|| oops.expect("")); + + let fine: Result<(), ()> = Ok(()); + assert_panicked(|| fine.unwrap_err()); + assert_panicked(|| fine.expect_err("")); } From b97ee0f07aca5a05bea8074d0cd1ecd73e54d1b7 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Sat, 4 Jan 2020 22:54:09 -0800 Subject: [PATCH 08/18] Fix typo Co-Authored-By: lzutao --- src/test/ui/rfc-2091-track-caller/std-panic-locations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index c65027d9cac73..0e622af815c3e 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -9,7 +9,7 @@ fn main() { // inspect the `PanicInfo` we receive to ensure the right file is the source std::panic::set_hook(Box::new(|info| { let actual = info.location().unwrap(); - if actual.file() != file!(){ + if actual.file() != file!() { eprintln!("expected a location in the test file, found {:?}", actual); panic!(); } From b25eeef88d55a412c0e0bec7c0989d5a7969f195 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 5 Jan 2020 20:06:52 +0100 Subject: [PATCH 09/18] Add more nuanced advice about spin_loop_hint --- src/libcore/sync/atomic.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index ba41cd2b7a08e..fae95ca5cdb36 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -134,8 +134,10 @@ use crate::hint::spin_loop; /// This function is different from [`std::thread::yield_now`] which directly yields to the /// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system. /// -/// If actively spinning for a long time is required, e.g. because code polls a non-blocking API, -/// calling [`std::thread::yield_now`] or [`std::thread::sleep`] may be the best option. +/// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS +/// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly +/// recommended that the spin loop is terminated after a finite amount of iterations and an +/// appropriate blocking syscall is made. /// /// **Note**: On platforms that do not support receiving spin-loop hints this function does not /// do anything at all. From 012127b3fe7bf192530cb620297510539fb8159d Mon Sep 17 00:00:00 2001 From: Umesh Kalappa Date: Mon, 9 Dec 2019 06:37:29 -0800 Subject: [PATCH 10/18] Remove weak.rs for VxWorks --- src/libstd/sys/vxworks/weak.rs | 56 ---------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 src/libstd/sys/vxworks/weak.rs diff --git a/src/libstd/sys/vxworks/weak.rs b/src/libstd/sys/vxworks/weak.rs deleted file mode 100644 index 4c6fddefd3f84..0000000000000 --- a/src/libstd/sys/vxworks/weak.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! Support for "weak linkage" to symbols on Unix -//! -//! Some I/O operations we do in libstd require newer versions of OSes but we -//! need to maintain binary compatibility with older releases for now. In order -//! to use the new functionality when available we use this module for -//! detection. -//! -//! One option to use here is weak linkage, but that is unfortunately only -//! really workable on Linux. Hence, use dlsym to get the symbol value at -//! runtime. This is also done for compatibility with older versions of glibc, -//! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that -//! we've been dynamically linked to the library the symbol comes from, but that -//! is currently always the case for things like libpthread/libc. -//! -//! A long time ago this used weak linkage for the __pthread_get_minstack -//! symbol, but that caused Debian to detect an unnecessarily strict versioned -//! dependency on libc6 (#23628). - -use crate::ffi::CStr; -use crate::marker; -use crate::mem; -use crate::sync::atomic::{AtomicUsize, Ordering}; - -pub struct Weak { - name: &'static str, - addr: AtomicUsize, - _marker: marker::PhantomData, -} - -impl Weak { - pub const fn new(name: &'static str) -> Weak { - Weak { name, addr: AtomicUsize::new(1), _marker: marker::PhantomData } - } - - pub fn get(&self) -> Option { - assert_eq!(mem::size_of::(), mem::size_of::()); - unsafe { - if self.addr.load(Ordering::SeqCst) == 1 { - self.addr.store(fetch(self.name), Ordering::SeqCst); - } - match self.addr.load(Ordering::SeqCst) { - 0 => None, - addr => Some(mem::transmute_copy::(&addr)), - } - } - } -} - -unsafe fn fetch(name: &str) -> usize { - let name = match CStr::from_bytes_with_nul(name.as_bytes()) { - Ok(cstr) => cstr, - Err(..) => return 0, - }; - assert!(false, "FIXME: fetch"); - libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize -} From 86b9d49cbe9fe4b97bbe120d3902f82af9f7993a Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 6 Jan 2020 23:57:02 +0000 Subject: [PATCH 11/18] rustdoc: Remove more `#[doc(cfg(..))]` duplicates --- src/librustdoc/clean/cfg.rs | 54 ++++++++++++++++++++++--------- src/librustdoc/clean/cfg/tests.rs | 52 +++++++++++++++++++++++++++++ src/test/rustdoc/duplicate-cfg.rs | 33 +++++++++++++++++-- 3 files changed, 120 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 13df1892a5f17..84e6ff648a38f 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -202,23 +202,34 @@ impl ops::Not for Cfg { impl ops::BitAndAssign for Cfg { fn bitand_assign(&mut self, other: Cfg) { - if *self == other { - return; - } match (self, other) { (&mut Cfg::False, _) | (_, Cfg::True) => {} (s, Cfg::False) => *s = Cfg::False, (s @ &mut Cfg::True, b) => *s = b, - (&mut Cfg::All(ref mut a), Cfg::All(ref mut b)) => a.append(b), - (&mut Cfg::All(ref mut a), ref mut b) => a.push(mem::replace(b, Cfg::True)), + (&mut Cfg::All(ref mut a), Cfg::All(ref mut b)) => { + for c in b.drain(..) { + if !a.contains(&c) { + a.push(c); + } + } + } + (&mut Cfg::All(ref mut a), ref mut b) => { + if !a.contains(b) { + a.push(mem::replace(b, Cfg::True)); + } + } (s, Cfg::All(mut a)) => { let b = mem::replace(s, Cfg::True); - a.push(b); + if !a.contains(&b) { + a.push(b); + } *s = Cfg::All(a); } (s, b) => { - let a = mem::replace(s, Cfg::True); - *s = Cfg::All(vec![a, b]); + if *s != b { + let a = mem::replace(s, Cfg::True); + *s = Cfg::All(vec![a, b]); + } } } } @@ -234,23 +245,34 @@ impl ops::BitAnd for Cfg { impl ops::BitOrAssign for Cfg { fn bitor_assign(&mut self, other: Cfg) { - if *self == other { - return; - } match (self, other) { (&mut Cfg::True, _) | (_, Cfg::False) => {} (s, Cfg::True) => *s = Cfg::True, (s @ &mut Cfg::False, b) => *s = b, - (&mut Cfg::Any(ref mut a), Cfg::Any(ref mut b)) => a.append(b), - (&mut Cfg::Any(ref mut a), ref mut b) => a.push(mem::replace(b, Cfg::True)), + (&mut Cfg::Any(ref mut a), Cfg::Any(ref mut b)) => { + for c in b.drain(..) { + if !a.contains(&c) { + a.push(c); + } + } + } + (&mut Cfg::Any(ref mut a), ref mut b) => { + if !a.contains(b) { + a.push(mem::replace(b, Cfg::True)); + } + } (s, Cfg::Any(mut a)) => { let b = mem::replace(s, Cfg::True); - a.push(b); + if !a.contains(&b) { + a.push(b); + } *s = Cfg::Any(a); } (s, b) => { - let a = mem::replace(s, Cfg::True); - *s = Cfg::Any(vec![a, b]); + if *s != b { + let a = mem::replace(s, Cfg::True); + *s = Cfg::Any(vec![a, b]); + } } } } diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 309f72040615d..d090bf325038f 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -87,6 +87,12 @@ fn test_cfg_and() { x &= word_cfg("test3"); assert_eq!(x, word_cfg("test3")); + x &= word_cfg("test3"); + assert_eq!(x, word_cfg("test3")); + + x &= word_cfg("test4"); + assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); + x &= word_cfg("test4"); assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); @@ -105,6 +111,18 @@ fn test_cfg_and() { ]) ); + x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); + assert_eq!( + x, + Cfg::All(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + ]) + ); + let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]); y &= x; assert_eq!( @@ -119,6 +137,14 @@ fn test_cfg_and() { ]) ); + let mut z = word_cfg("test8"); + z &= Cfg::All(vec![word_cfg("test9"), word_cfg("test10")]); + assert_eq!(z, Cfg::All(vec![word_cfg("test9"), word_cfg("test10"), word_cfg("test8")])); + + let mut z = word_cfg("test11"); + z &= Cfg::All(vec![word_cfg("test11"), word_cfg("test12")]); + assert_eq!(z, Cfg::All(vec![word_cfg("test11"), word_cfg("test12")])); + assert_eq!( word_cfg("a") & word_cfg("b") & word_cfg("c"), Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) @@ -145,6 +171,12 @@ fn test_cfg_or() { x |= word_cfg("test3"); assert_eq!(x, word_cfg("test3")); + x |= word_cfg("test3"); + assert_eq!(x, word_cfg("test3")); + + x |= word_cfg("test4"); + assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); + x |= word_cfg("test4"); assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); @@ -163,6 +195,18 @@ fn test_cfg_or() { ]) ); + x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); + assert_eq!( + x, + Cfg::Any(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + ]) + ); + let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]); y |= x; assert_eq!( @@ -177,6 +221,14 @@ fn test_cfg_or() { ]) ); + let mut z = word_cfg("test8"); + z |= Cfg::Any(vec![word_cfg("test9"), word_cfg("test10")]); + assert_eq!(z, Cfg::Any(vec![word_cfg("test9"), word_cfg("test10"), word_cfg("test8")])); + + let mut z = word_cfg("test11"); + z |= Cfg::Any(vec![word_cfg("test11"), word_cfg("test12")]); + assert_eq!(z, Cfg::Any(vec![word_cfg("test11"), word_cfg("test12")])); + assert_eq!( word_cfg("a") | word_cfg("b") | word_cfg("c"), Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs index 505d6ee769ab3..9ccc5d7882eb8 100644 --- a/src/test/rustdoc/duplicate-cfg.rs +++ b/src/test/rustdoc/duplicate-cfg.rs @@ -1,15 +1,42 @@ +// ignore-tidy-linelength + #![crate_name = "foo"] #![feature(doc_cfg)] -// @has 'foo/index.html' -// @!has '-' '//*[@class="stab portability"]' 'feature="sync" and' -// @has '-' '//*[@class="stab portability"]' 'feature="sync"' +// @has 'foo/struct.Foo.html' +// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" only.' #[doc(cfg(feature = "sync"))] #[doc(cfg(feature = "sync"))] pub struct Foo; +// @has 'foo/bar/struct.Bar.html' +// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" only.' #[doc(cfg(feature = "sync"))] pub mod bar { #[doc(cfg(feature = "sync"))] pub struct Bar; } + +// @has 'foo/baz/struct.Baz.html' +// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" and feature="send" only.' +#[doc(cfg(all(feature = "sync", feature = "send")))] +pub mod baz { + #[doc(cfg(feature = "sync"))] + pub struct Baz; +} + +// @has 'foo/qux/struct.Qux.html' +// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" and feature="send" only.' +#[doc(cfg(feature = "sync"))] +pub mod qux { + #[doc(cfg(all(feature = "sync", feature = "send")))] + pub struct Qux; +} + +// @has 'foo/quux/struct.Quux.html' +// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" and feature="send" and foo and bar only.' +#[doc(cfg(all(feature = "sync", feature = "send", foo)))] +pub mod quux { + #[doc(cfg(all(feature = "send", feature = "sync", bar)))] + pub struct Quux; +} From cec957e1542c062e97f664aab5b23ebd532f5c85 Mon Sep 17 00:00:00 2001 From: BaoshanPang Date: Fri, 20 Dec 2019 13:59:52 -0800 Subject: [PATCH 12/18] ignore signal SIGPIPE --- src/libstd/sys/vxworks/mod.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs index f102e4d6adf59..12bbfa1d4e1a6 100644 --- a/src/libstd/sys/vxworks/mod.rs +++ b/src/libstd/sys/vxworks/mod.rs @@ -36,18 +36,10 @@ pub use crate::sys_common::os_str_bytes as os_str; #[cfg(not(test))] pub fn init() { - // By default, some platforms will send a *signal* when an EPIPE error - // would otherwise be delivered. This runtime doesn't install a SIGPIPE - // handler, causing it to kill the program, which isn't exactly what we - // want! - // - // Hence, we set SIGPIPE to ignore when the program starts up in order - // to prevent this problem. + // ignore SIGPIPE unsafe { - reset_sigpipe(); + assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR); } - - unsafe fn reset_sigpipe() {} } pub use libc::signal; From 3acd34659453a92fe28308105a7b95230215e380 Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Tue, 7 Jan 2020 07:22:49 -0800 Subject: [PATCH 13/18] Skip caller location test in wasm32. --- src/test/ui/rfc-2091-track-caller/std-panic-locations.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs index 0e622af815c3e..be13076b8af52 100644 --- a/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs +++ b/src/test/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -1,4 +1,5 @@ // run-pass +// ignore-wasm32-bare compiled with panic=abort by default #![feature(option_expect_none, option_unwrap_none)] From 48add5453b8757ac8757cfc2c8ad1197d4d258b1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 7 Jan 2020 12:01:39 -0800 Subject: [PATCH 14/18] Remove insignificant notes from CStr documentation These notes are about a distinction that is not going to be observable in the API. Whether or not the UTF-8 check knows the string length ahead of time, these methods require linear time. --- src/libstd/ffi/c_str.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index d2ee65f0a74eb..700e015b08edc 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -1187,11 +1187,6 @@ impl CStr { /// function will return the corresponding [`&str`] slice. Otherwise, /// it will return an error with details of where UTF-8 validation failed. /// - /// > **Note**: This method is currently implemented to check for validity - /// > after a constant-time cast, but it is planned to alter its definition - /// > in the future to perform the length calculation in addition to the - /// > UTF-8 check whenever this method is called. - /// /// [`&str`]: ../primitive.str.html /// /// # Examples @@ -1220,11 +1215,6 @@ impl CStr { /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a /// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result. /// - /// > **Note**: This method is currently implemented to check for validity - /// > after a constant-time cast, but it is planned to alter its definition - /// > in the future to perform the length calculation in addition to the - /// > UTF-8 check whenever this method is called. - /// /// [`Cow`]: ../borrow/enum.Cow.html /// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed /// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned From f5baa03af0da7aa565190ae563291cd268998c83 Mon Sep 17 00:00:00 2001 From: oxalica Date: Wed, 8 Jan 2020 14:18:42 +0800 Subject: [PATCH 15/18] Try statx for all linux-gnu targets --- src/libstd/sys/unix/fs.rs | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 4fa9095c89983..ab2a871b92df4 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -51,24 +51,14 @@ pub use crate::sys_common::fs::remove_dir_all; pub struct File(FileDesc); -// FIXME: This should be available on Linux with all `target_arch` and `target_env`. -// https://github.com/rust-lang/libc/issues/1545 +// FIXME: This should be available on Linux with all `target_env`. +// But currently only glibc exposes `statx` fn and structs. +// We don't want to import unverified raw C structs here directly. +// https://github.com/rust-lang/rust/pull/67774 macro_rules! cfg_has_statx { ({ $($then_tt:tt)* } else { $($else_tt:tt)* }) => { cfg_if::cfg_if! { - if #[cfg(all(target_os = "linux", target_env = "gnu", any( - target_arch = "x86", - target_arch = "arm", - // target_arch = "mips", - target_arch = "powerpc", - target_arch = "x86_64", - // target_arch = "aarch64", - target_arch = "powerpc64", - // target_arch = "mips64", - // target_arch = "s390x", - target_arch = "sparc64", - target_arch = "riscv64", - )))] { + if #[cfg(all(target_os = "linux", target_env = "gnu"))] { $($then_tt)* } else { $($else_tt)* @@ -76,19 +66,7 @@ macro_rules! cfg_has_statx { } }; ($($block_inner:tt)*) => { - #[cfg(all(target_os = "linux", target_env = "gnu", any( - target_arch = "x86", - target_arch = "arm", - // target_arch = "mips", - target_arch = "powerpc", - target_arch = "x86_64", - // target_arch = "aarch64", - target_arch = "powerpc64", - // target_arch = "mips64", - // target_arch = "s390x", - target_arch = "sparc64", - target_arch = "riscv64", - )))] + #[cfg(all(target_os = "linux", target_env = "gnu"))] { $($block_inner)* } From 588296adfe72260a109c5962c1ca2784505e77f9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 17:40:05 +0100 Subject: [PATCH 16/18] Move constness.rs to librustc_mir. --- .../ty/constness.rs => librustc_mir/const_eval/fn_queries.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/ty/constness.rs => librustc_mir/const_eval/fn_queries.rs} (100%) diff --git a/src/librustc/ty/constness.rs b/src/librustc_mir/const_eval/fn_queries.rs similarity index 100% rename from src/librustc/ty/constness.rs rename to src/librustc_mir/const_eval/fn_queries.rs From c1c09bee29732c3e47939a7253c7d0e56ffbc280 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 18:06:00 +0100 Subject: [PATCH 17/18] Move `is_min_const_fn` query to librustc_mir. The only two uses of the associated methods are in librustc_mir and librustdoc. Please tell me if there is a better choice. --- src/librustc/ty/mod.rs | 2 - src/librustc_mir/const_eval.rs | 2 + src/librustc_mir/const_eval/fn_queries.rs | 139 +++++++++--------- src/librustc_mir/lib.rs | 1 + .../transform/check_consts/validation.rs | 7 +- src/librustc_mir/transform/check_unsafety.rs | 3 +- src/librustc_mir/transform/promote_consts.rs | 5 +- .../transform/qualify_min_const_fn.rs | 2 +- src/librustdoc/clean/inline.rs | 3 +- src/librustdoc/clean/mod.rs | 5 +- src/librustdoc/lib.rs | 1 + 11 files changed, 86 insertions(+), 84 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7cca12308e65f..747e6e8da99af 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -97,7 +97,6 @@ pub mod cast; #[macro_use] pub mod codec; pub mod _match; -mod constness; mod erase_regions; pub mod error; pub mod fast_reject; @@ -3318,7 +3317,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); erase_regions::provide(providers); layout::provide(providers); - constness::provide(providers); *providers = ty::query::Providers { asyncness, associated_item, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index ac04ae285884b..7b2ce7f9ac7be 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -9,10 +9,12 @@ use crate::interpret::{intern_const_alloc_recursive, ConstValue, InterpCx}; mod error; mod eval_queries; +mod fn_queries; mod machine; pub use error::*; pub use eval_queries::*; +pub use fn_queries::*; pub use machine::*; /// Extracts a field of a (variant of a) const. diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/src/librustc_mir/const_eval/fn_queries.rs index cc5131cb21795..2443e1e91d378 100644 --- a/src/librustc_mir/const_eval/fn_queries.rs +++ b/src/librustc_mir/const_eval/fn_queries.rs @@ -1,89 +1,84 @@ -use crate::hir::map::blocks::FnLikeNode; -use crate::ty::query::Providers; -use crate::ty::TyCtxt; +use rustc::hir::map::blocks::FnLikeNode; +use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; use syntax::attr; -impl<'tcx> TyCtxt<'tcx> { - /// Whether the `def_id` counts as const fn in your current crate, considering all active - /// feature gates - pub fn is_const_fn(self, def_id: DefId) -> bool { - self.is_const_fn_raw(def_id) - && match self.is_unstable_const_fn(def_id) { - Some(feature_name) => { - // has a `rustc_const_unstable` attribute, check whether the user enabled the - // corresponding feature gate. - self.features() - .declared_lib_features - .iter() - .any(|&(sym, _)| sym == feature_name) - } - // functions without const stability are either stable user written - // const fn or the user is using feature gates and we thus don't - // care what they do - None => true, +/// Whether the `def_id` counts as const fn in your current crate, considering all active +/// feature gates +pub fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + tcx.is_const_fn_raw(def_id) + && match is_unstable_const_fn(tcx, def_id) { + Some(feature_name) => { + // has a `rustc_const_unstable` attribute, check whether the user enabled the + // corresponding feature gate. + tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_name) } - } - - /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it - pub fn is_unstable_const_fn(self, def_id: DefId) -> Option { - if self.is_const_fn_raw(def_id) { - let const_stab = self.lookup_const_stability(def_id)?; - if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None } - } else { - None + // functions without const stability are either stable user written + // const fn or the user is using feature gates and we thus don't + // care what they do + None => true, } +} + +/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it +pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + if tcx.is_const_fn_raw(def_id) { + let const_stab = tcx.lookup_const_stability(def_id)?; + if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None } + } else { + None } +} - /// Returns `true` if this function must conform to `min_const_fn` - pub fn is_min_const_fn(self, def_id: DefId) -> bool { - // Bail out if the signature doesn't contain `const` - if !self.is_const_fn_raw(def_id) { - return false; - } +/// Returns `true` if this function must conform to `min_const_fn` +pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + // Bail out if the signature doesn't contain `const` + if !tcx.is_const_fn_raw(def_id) { + return false; + } - if self.features().staged_api { - // In order for a libstd function to be considered min_const_fn - // it needs to be stable and have no `rustc_const_unstable` attribute. - match self.lookup_const_stability(def_id) { - // `rustc_const_unstable` functions don't need to conform. - Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false, - None => { - if let Some(stab) = self.lookup_stability(def_id) { - if stab.level.is_stable() { - self.sess.span_err( - self.def_span(def_id), - "stable const functions must have either `rustc_const_stable` or \ - `rustc_const_unstable` attribute", - ); - // While we errored above, because we don't know if we need to conform, we - // err on the "safe" side and require min_const_fn. - true - } else { - // Unstable functions need not conform to min_const_fn. - false - } - } else { - // Internal functions are forced to conform to min_const_fn. - // Annotate the internal function with a const stability attribute if - // you need to use unstable features. - // Note: this is an arbitrary choice that does not affect stability or const - // safety or anything, it just changes whether we need to annotate some - // internal functions with `rustc_const_stable` or with `rustc_const_unstable` + if tcx.features().staged_api { + // In order for a libstd function to be considered min_const_fn + // it needs to be stable and have no `rustc_const_unstable` attribute. + match tcx.lookup_const_stability(def_id) { + // `rustc_const_unstable` functions don't need to conform. + Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false, + None => { + if let Some(stab) = tcx.lookup_stability(def_id) { + if stab.level.is_stable() { + tcx.sess.span_err( + tcx.def_span(def_id), + "stable const functions must have either `rustc_const_stable` or \ + `rustc_const_unstable` attribute", + ); + // While we errored above, because we don't know if we need to conform, we + // err on the "safe" side and require min_const_fn. true + } else { + // Unstable functions need not conform to min_const_fn. + false } + } else { + // Internal functions are forced to conform to min_const_fn. + // Annotate the internal function with a const stability attribute if + // you need to use unstable features. + // Note: this is an arbitrary choice that does not affect stability or const + // safety or anything, it just changes whether we need to annotate some + // internal functions with `rustc_const_stable` or with `rustc_const_unstable` + true } - // Everything else needs to conform, because it would be callable from - // other `min_const_fn` functions. - _ => true, } - } else { - // users enabling the `const_fn` feature gate can do what they want - !self.features().const_fn + // Everything else needs to conform, because it would be callable from + // other `min_const_fn` functions. + _ => true, } + } else { + // users enabling the `const_fn` feature gate can do what they want + !tcx.features().const_fn } } @@ -121,7 +116,7 @@ pub fn provide(providers: &mut Providers<'_>) { } fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - tcx.is_const_fn(def_id) + is_const_fn(tcx, def_id) && match tcx.lookup_const_stability(def_id) { Some(stab) => { if cfg!(debug_assertions) && stab.promotable { @@ -140,7 +135,7 @@ pub fn provide(providers: &mut Providers<'_>) { } fn const_fn_is_allowed_fn_ptr(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - tcx.is_const_fn(def_id) + is_const_fn(tcx, def_id) && tcx .lookup_const_stability(def_id) .map(|stab| stab.allow_const_fn_ptr) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 32b35c4139dad..b384d19905167 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -54,6 +54,7 @@ use rustc::ty::query::Providers; pub fn provide(providers: &mut Providers<'_>) { borrow_check::provide(providers); + const_eval::provide(providers); shim::provide(providers); transform::provide(providers); monomorphize::partitioning::provide(providers); diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 3c52a2e0dd270..83fd07f31d4d6 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -20,6 +20,7 @@ use super::ops::{self, NonConstOp}; use super::qualifs::{self, HasMutInterior, NeedsDrop}; use super::resolver::FlowSensitiveAnalysis; use super::{is_lang_panic_fn, ConstKind, Item, Qualif}; +use crate::const_eval::{is_const_fn, is_unstable_const_fn}; use crate::dataflow::{self as old_dataflow, generic as dataflow}; pub type IndirectlyMutableResults<'mir, 'tcx> = @@ -172,7 +173,7 @@ impl Validator<'a, 'mir, 'tcx> { let Item { tcx, body, def_id, const_kind, .. } = *self.item; let use_min_const_fn_checks = (const_kind == Some(ConstKind::ConstFn) - && tcx.is_min_const_fn(def_id)) + && crate::const_eval::is_min_const_fn(tcx, def_id)) && !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you; if use_min_const_fn_checks { @@ -559,13 +560,13 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { }; // At this point, we are calling a function whose `DefId` is known... - if self.tcx.is_const_fn(def_id) { + if is_const_fn(self.tcx, def_id) { return; } if is_lang_panic_fn(self.tcx, def_id) { self.check_op(ops::Panic); - } else if let Some(feature) = self.tcx.is_unstable_const_fn(def_id) { + } else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) { // Exempt unstable const fns inside of macros with // `#[allow_internal_unstable]`. if !self.span.allows_unstable(feature) { diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index b333bc681f6bb..5dc93e7c06288 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -13,6 +13,7 @@ use rustc_span::symbol::{sym, Symbol}; use std::ops::Bound; +use crate::const_eval::{is_const_fn, is_min_const_fn}; use crate::util; use rustc_error_codes::*; @@ -522,7 +523,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult let id = tcx.hir().as_local_hir_id(def_id).unwrap(); let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) { hir::BodyOwnerKind::Closure => (false, false), - hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)), + hir::BodyOwnerKind::Fn => (is_const_fn(tcx, def_id), is_min_const_fn(tcx, def_id)), hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false), }; let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env); diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index b6656e720c5c3..00a39905c0232 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -29,6 +29,7 @@ use rustc_target::spec::abi::Abi; use std::cell::Cell; use std::{iter, mem, usize}; +use crate::const_eval::{is_const_fn, is_unstable_const_fn}; use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item}; use crate::transform::{MirPass, MirSource}; @@ -702,8 +703,8 @@ impl<'tcx> Validator<'_, 'tcx> { let is_const_fn = match fn_ty.kind { ty::FnDef(def_id, _) => { - self.tcx.is_const_fn(def_id) - || self.tcx.is_unstable_const_fn(def_id).is_some() + is_const_fn(self.tcx, def_id) + || is_unstable_const_fn(self.tcx, def_id).is_some() || is_lang_panic_fn(self.tcx, self.def_id) } _ => false, diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 9dea44e020010..fcdabb29cd0e2 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -327,7 +327,7 @@ fn check_terminator( TerminatorKind::Call { func, args, from_hir_call: _, destination: _, cleanup: _ } => { let fn_ty = func.ty(body, tcx); if let ty::FnDef(def_id, _) = fn_ty.kind { - if !tcx.is_min_const_fn(def_id) { + if !crate::const_eval::is_min_const_fn(tcx, def_id) { return Err(( span, format!( diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 2400dded66668..c7e0f1e9e704b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -9,6 +9,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::Mutability; use rustc_metadata::creader::LoadedMacro; +use rustc_mir::const_eval::is_min_const_fn; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::sym; use rustc_span::Span; @@ -212,7 +213,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function { let sig = cx.tcx.fn_sig(did); let constness = - if cx.tcx.is_min_const_fn(did) { hir::Constness::Const } else { hir::Constness::NotConst }; + if is_min_const_fn(cx.tcx, did) { hir::Constness::Const } else { hir::Constness::NotConst }; let asyncness = cx.tcx.asyncness(did); let predicates = cx.tcx.predicates_of(did); let (generics, decl) = clean::enter_impl_trait(cx, || { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bb46a15258e0f..be9654612f504 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -21,6 +21,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_index::vec::{Idx, IndexVec}; +use rustc_mir::const_eval::is_min_const_fn; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym}; use rustc_span::{self, Pos}; @@ -895,7 +896,7 @@ impl Clean for doctree::Function<'_> { enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx))); let did = cx.tcx.hir().local_def_id(self.id); - let constness = if cx.tcx.is_min_const_fn(did) { + let constness = if is_min_const_fn(cx.tcx, did) { hir::Constness::Const } else { hir::Constness::NotConst @@ -1187,7 +1188,7 @@ impl Clean for ty::AssocItem { }; let (all_types, ret_types) = get_all_types(&generics, &decl, cx); if provided { - let constness = if cx.tcx.is_min_const_fn(self.def_id) { + let constness = if is_min_const_fn(cx.tcx, self.def_id) { hir::Constness::Const } else { hir::Constness::NotConst diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index eeaac1d8c7431..32c93ee3b164d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,6 +32,7 @@ extern crate rustc_interface; extern crate rustc_lexer; extern crate rustc_lint; extern crate rustc_metadata; +extern crate rustc_mir; extern crate rustc_parse; extern crate rustc_resolve; extern crate rustc_span as rustc_span; From aabc73631e94ad2ced73cebbae3086f98c83cafa Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 8 Jan 2020 12:24:01 +0100 Subject: [PATCH 18/18] ci: fix wrong shared.sh import for publish_toolstate --- src/ci/publish_toolstate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/publish_toolstate.sh b/src/ci/publish_toolstate.sh index fb828477f98b7..7c43d034d8b7f 100755 --- a/src/ci/publish_toolstate.sh +++ b/src/ci/publish_toolstate.sh @@ -3,7 +3,7 @@ set -euo pipefail IFS=$'\n\t' -source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" +source "$(cd "$(dirname "$0")" && pwd)/shared.sh" # The following lines are also found in src/bootstrap/toolstate.rs, # so if updating here, please also update that file.