diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 927d7c6aaf6a4..fa918ff1bce1b 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -580,3 +580,12 @@ impl NestedMetaItem { MetaItem::from_tokens(tokens).map(NestedMetaItem::MetaItem) } } + +/// Return true if the attributes contain `#[doc(hidden)]` +pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool { + attrs + .iter() + .filter(|attr| attr.has_name(sym::doc)) + .filter_map(ast::Attribute::meta_item_list) + .any(|l| list_contains_name(&l, sym::hidden)) +} diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index d87aa5ed0d552..673fd3fc0b940 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -346,9 +346,11 @@ where } } -impl HashStable for SmallVec<[A; 1]> +impl HashStable for SmallVec<[T; N]> where - A: HashStable, + T: HashStable, + [T; N]: smallvec::Array, + <[T; N] as smallvec::Array>::Item: HashStable, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4e5d21049a0d9..b82970721de66 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -133,8 +133,8 @@ provide! { <'tcx> tcx, def_id, other, cdata, generator_kind => { cdata.generator_kind(def_id.index) } opt_def_kind => { Some(cdata.def_kind(def_id.index)) } def_span => { cdata.get_span(def_id.index, &tcx.sess) } - def_ident_span => { - cdata.try_item_ident(def_id.index, &tcx.sess).ok().map(|ident| ident.span) + def_ident => { + cdata.try_item_ident(def_id.index, &tcx.sess).ok() } lookup_stability => { cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s)) @@ -290,15 +290,11 @@ pub fn provide(providers: &mut Providers) { // external item that is visible from at least one local module) to a // sufficiently visible parent (considering modules that re-export the // external item to be parents). - visible_parent_map: |tcx, ()| { - use std::collections::hash_map::Entry; - use std::collections::vec_deque::VecDeque; + visible_parents_map: |tcx, ()| { + use rustc_data_structures::fx::FxHashSet; + use std::collections::VecDeque; - let mut visible_parent_map: DefIdMap = Default::default(); - // This is a secondary visible_parent_map, storing the DefId of parents that re-export - // the child as `_`. Since we prefer parents that don't do this, merge this map at the - // end, only if we're missing any keys from the former. - let mut fallback_map: DefIdMap = Default::default(); + let mut visible_parents_map: DefIdMap> = DefIdMap::default(); // Issue 46112: We want the map to prefer the shortest // paths when reporting the path to an item. Therefore we @@ -310,59 +306,81 @@ pub fn provide(providers: &mut Providers) { // only get paths that are locally minimal with respect to // whatever crate we happened to encounter first in this // traversal, but not globally minimal across all crates. - let bfs_queue = &mut VecDeque::new(); - - for &cnum in tcx.crates(()) { - // Ignore crates without a corresponding local `extern crate` item. - if tcx.missing_extern_crate_item(cnum) { - continue; + let mut bfs_queue = VecDeque::default(); + + bfs_queue.extend( + tcx.crates(()) + .into_iter() + // Ignore crates without a corresponding local `extern crate` item. + .filter(|cnum| !tcx.missing_extern_crate_item(**cnum)) + .map(|cnum| DefId { krate: *cnum, index: CRATE_DEF_INDEX }), + ); + + // Iterate over graph using BFS. + // Filter out any non-public items. + while let Some(parent) = bfs_queue.pop_front() { + for child in tcx + .item_children(parent) + .iter() + .filter(|child| child.vis.is_public()) + .filter_map(|child| child.res.opt_def_id()) + { + visible_parents_map + .entry(child) + .or_insert_with(|| { + // If we encounter node the first time + // add it to queue for next iterations + bfs_queue.push_back(child); + Default::default() + }) + .push(parent); } + } - bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX }); + // Iterate over parents vector to remove duplicate elements + // while preserving order + let mut dedup_set = FxHashSet::default(); + for (_, parents) in &mut visible_parents_map { + parents.retain(|parent| dedup_set.insert(*parent)); + + // Reuse hashset allocation. + dedup_set.clear(); } - let mut add_child = |bfs_queue: &mut VecDeque<_>, export: &Export, parent: DefId| { - if !export.vis.is_public() { - return; - } + visible_parents_map + }, + best_visible_parent: |tcx, child| { + // Use `min_by_key` because it returns + // first match in case keys are equal + tcx.visible_parents_map(()) + .get(&child)? + .into_iter() + .min_by_key(|parent| { + // If this is just regular export in another module, assign it a neutral score. + let mut score = 0; + + // If child and parent are local, we prefer them + if child.is_local() && parent.is_local() { + score += 1; + } - if let Some(child) = export.res.opt_def_id() { - if export.ident.name == kw::Underscore { - fallback_map.insert(child, parent); - return; + // Even if child and parent are local, if parent is `#[doc(hidden)]` + // We reduce their score to avoid showing items not popping in documentation. + if ast::attr::is_doc_hidden(tcx.item_attrs(**parent)) { + score -= 2; } - match visible_parent_map.entry(child) { - Entry::Occupied(mut entry) => { - // If `child` is defined in crate `cnum`, ensure - // that it is mapped to a parent in `cnum`. - if child.is_local() && entry.get().is_local() { - entry.insert(parent); - } - } - Entry::Vacant(entry) => { - entry.insert(parent); - bfs_queue.push_back(child); + // If parent identifier is _ we prefer it only as last resort if other items are not available + if let Some(ident) = tcx.def_ident(**parent) { + if ident.name == kw::Underscore { + score -= 3; } } - } - }; - - while let Some(def) = bfs_queue.pop_front() { - for child in tcx.item_children(def).iter() { - add_child(bfs_queue, child, def); - } - } - // Fill in any missing entries with the (less preferable) path ending in `::_`. - // We still use this path in a diagnostic that suggests importing `::*`. - for (child, parent) in fallback_map { - visible_parent_map.entry(child).or_insert(parent); - } - - visible_parent_map + -score + }) + .map(ToOwned::to_owned) }, - dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)), has_global_allocator: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ad3f61d07843a..fd1e5c182ea97 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -977,8 +977,8 @@ rustc_queries! { } /// Gets the span for the identifier of the definition. - query def_ident_span(def_id: DefId) -> Option { - desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } + query def_ident(def_id: DefId) -> Option { + desc { |tcx| "looking up ident for `{}`'s identifier", tcx.def_path_str(def_id) } separate_provide_extern } @@ -1552,10 +1552,14 @@ rustc_queries! { desc { "calculating the missing lang items in a crate" } separate_provide_extern } - query visible_parent_map(_: ()) -> DefIdMap { + + query visible_parents_map(_: ()) -> DefIdMap> { storage(ArenaCacheSelector<'tcx>) desc { "calculating the visible parent map" } } + query best_visible_parent(child: DefId) -> Option { + desc { "calculating best visible parent" } + } query trimmed_def_paths(_: ()) -> FxHashMap { storage(ArenaCacheSelector<'tcx>) desc { "calculating trimmed def paths" } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 47a9234419c2d..b4fe26b0a0379 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -387,8 +387,6 @@ pub trait PrettyPrinter<'tcx>: return Ok((self, false)); } - let visible_parent_map = self.tcx().visible_parent_map(()); - let mut cur_def_key = self.tcx().def_key(def_id); debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); @@ -404,7 +402,7 @@ pub trait PrettyPrinter<'tcx>: cur_def_key = self.tcx().def_key(parent); } - let visible_parent = match visible_parent_map.get(&def_id).cloned() { + let visible_parent = match self.tcx().best_visible_parent(def_id) { Some(parent) => parent, None => return Ok((self, false)), }; @@ -431,7 +429,7 @@ pub trait PrettyPrinter<'tcx>: // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is // private so the "true" path to `CommandExt` isn't accessible. // - // In this case, the `visible_parent_map` will look something like this: + // In this case, the `visible_parents_map` will look something like this: // // (child) -> (parent) // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process` @@ -451,7 +449,7 @@ pub trait PrettyPrinter<'tcx>: // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with // the visible parent (`std::os`). If these do not match, then we iterate over // the children of the visible parent (as was done when computing - // `visible_parent_map`), looking for the specific child we currently have and then + // `visible_parents_map`), looking for the specific child we currently have and then // have access to the re-exported name. DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => { // Item might be re-exported several times, but filter for the one diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 2f91503afdfaf..c119d34a3d8fe 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -30,7 +30,7 @@ use crate::traits::specialization_graph; use crate::traits::{self, ImplSource}; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; -use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; +use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, Ident, ParamEnvAnd, Ty, TyCtxt}; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::steal::Steal; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 6c2657bd64bdb..df73de4fcd02e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; -use rustc_span::{sym, Span}; +use rustc_span::{sym, symbol::Ident}; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -216,19 +216,16 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems<'_> { ty::AssocItems::new(items) } -fn def_ident_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - tcx.hir() - .get_if_local(def_id) - .and_then(|node| match node { - // A `Ctor` doesn't have an identifier itself, but its parent - // struct/variant does. Compare with `hir::Map::opt_span`. - hir::Node::Ctor(ctor) => ctor - .ctor_hir_id() - .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id))) - .and_then(|parent| parent.ident()), - _ => node.ident(), - }) - .map(|ident| ident.span) +fn def_ident(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + tcx.hir().get_if_local(def_id).and_then(|node| match node { + // A `Ctor` doesn't have an identifier itself, but its parent + // struct/variant does. Compare with `hir::Map::opt_span`. + hir::Node::Ctor(ctor) => ctor + .ctor_hir_id() + .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id))) + .and_then(|parent| parent.ident()), + _ => node.ident(), + }) } /// If the given `DefId` describes an item belonging to a trait, @@ -624,7 +621,7 @@ pub fn provide(providers: &mut ty::query::Providers) { associated_item_def_ids, associated_items, adt_sized_constraint, - def_ident_span, + def_ident, param_env, param_env_reveal_all_normalized, trait_of_item, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 11b63a99043b7..e4f4d368481c9 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -197,8 +197,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if let Some(def_id) = def_id { - if let Some(def_span) = tcx.def_ident_span(def_id) { - let mut spans: MultiSpan = def_span.into(); + if let Some(def_ident) = tcx.def_ident(def_id) { + let mut spans: MultiSpan = def_ident.span.into(); let params = tcx .hir() diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index d5a4de86d4d1e..3a5ee76f44953 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -12,7 +12,7 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::{simplify_type, SimplifyParams, StripReferences}; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_span::lev_distance; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{source_map, FileName, MultiSpan, Span, Symbol}; @@ -1310,17 +1310,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mut msg: String, candidates: Vec, ) { - let parent_map = self.tcx.visible_parent_map(()); - // Separate out candidates that must be imported with a glob, because they are named `_` // and cannot be referred with their identifier. let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| { - if let Some(parent_did) = parent_map.get(trait_did) { + if let Some(parent_did) = self.tcx.best_visible_parent(*trait_did) { // If the item is re-exported as `_`, we should suggest a glob-import instead. - if Some(*parent_did) != self.tcx.parent(*trait_did) + if Some(parent_did) != self.tcx.best_visible_parent(*trait_did) && self .tcx - .item_children(*parent_did) + .item_children(parent_did) .iter() .filter(|child| child.res.opt_def_id() == Some(*trait_did)) .all(|child| child.ident.name == kw::Underscore) @@ -1347,14 +1345,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let glob_path_strings = globs.iter().map(|trait_did| { - let parent_did = parent_map.get(trait_did).unwrap(); - // Produce an additional newline to separate the new use statement // from the directly following item. let additional_newline = if found_use { "" } else { "\n" }; format!( "use {}::*; // trait {}\n{}", - with_crate_prefix(|| self.tcx.def_path_str(*parent_did)), + with_crate_prefix(|| self + .tcx + .def_path_str(self.tcx.best_visible_parent(*trait_did).unwrap())), self.tcx.item_name(*trait_did), additional_newline ) @@ -1385,19 +1383,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (i, trait_did) in globs.iter().take(limit.saturating_sub(candidates.len())).enumerate() { - let parent_did = parent_map.get(trait_did).unwrap(); + let parent_did = self.tcx.best_visible_parent(*trait_did).unwrap(); if candidates.len() + globs.len() > 1 { msg.push_str(&format!( "\ncandidate #{}: `use {}::*; // trait {}`", candidates.len() + i + 1, - with_crate_prefix(|| self.tcx.def_path_str(*parent_did)), + with_crate_prefix(|| self.tcx.def_path_str(parent_did)), self.tcx.item_name(*trait_did), )); } else { msg.push_str(&format!( "\n`use {}::*; // trait {}`", - with_crate_prefix(|| self.tcx.def_path_str(*parent_did)), + with_crate_prefix(|| self.tcx.def_path_str(parent_did)), self.tcx.item_name(*trait_did), )); } diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index ec06e0b11264d..694417389a837 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1025,7 +1025,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let last_subpat_span = *subpat_spans.last().unwrap(); let res_span = self.tcx.def_span(res.def_id()); - let def_ident_span = self.tcx.def_ident_span(res.def_id()).unwrap_or(res_span); + let def_ident_span = + self.tcx.def_ident(res.def_id()).map(|ident| ident.span).unwrap_or(res_span); let field_def_spans = if fields.is_empty() { vec![res_span] } else { diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index a1c2945770920..733764c13ba35 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -730,9 +730,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { /// Builds the `type defined here` message. fn show_definition(&self, err: &mut DiagnosticBuilder<'_>) { - let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) { - if self.tcx.sess.source_map().span_to_snippet(def_span).is_ok() { - def_span.into() + let mut spans: MultiSpan = if let Some(def_ident) = self.tcx.def_ident(self.def_id) { + if self.tcx.sess.source_map().span_to_snippet(def_ident.span).is_ok() { + def_ident.span.into() } else { return; } diff --git a/src/test/ui/proc-macro/issue-37788.rs b/src/test/ui/proc-macro/issue-37788.rs index 73b1f0d58c837..7adc7a55e4f7a 100644 --- a/src/test/ui/proc-macro/issue-37788.rs +++ b/src/test/ui/proc-macro/issue-37788.rs @@ -4,6 +4,6 @@ extern crate test_macros; fn main() { - // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. + // Test that constructing the `visible_parents_map` (in `cstore_impl.rs`) does not ICE. std::cell::Cell::new(0) //~ ERROR mismatched types } diff --git a/src/test/ui/proc-macro/issue-37788.stderr b/src/test/ui/proc-macro/issue-37788.stderr index 345520d4852ae..899752893172b 100644 --- a/src/test/ui/proc-macro/issue-37788.stderr +++ b/src/test/ui/proc-macro/issue-37788.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | fn main() { | - expected `()` because of default return type -LL | // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. +LL | // Test that constructing the `visible_parents_map` (in `cstore_impl.rs`) does not ICE. LL | std::cell::Cell::new(0) | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` | | diff --git a/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/auxiliary/other_crate.rs b/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/auxiliary/other_crate.rs index 13bf9a7a28928..5a5079d8204ac 100644 --- a/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/auxiliary/other_crate.rs +++ b/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/auxiliary/other_crate.rs @@ -4,5 +4,5 @@ extern crate core; #[doc(hidden)] pub mod __private { - pub use core::option::Option::{self, None, Some}; + pub use core::option::Option::{self, None, Some}; } diff --git a/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/dont-suggest-doc-hidden-variant-for-enum.stderr b/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/dont-suggest-doc-hidden-variant-for-enum.stderr index 709dec3ec3132..e9dcee0659af3 100644 --- a/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/dont-suggest-doc-hidden-variant-for-enum.stderr +++ b/src/test/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/dont-suggest-doc-hidden-variant-for-enum.stderr @@ -2,14 +2,16 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-doc-hidden-variant-for-enum.rs:6:26 | LL | let x: Option = 1i32; - | ----------- ^^^^ - | | | - | | expected enum `Option`, found `i32` - | | help: try using a variant of the expected enum: `Some(1i32)` + | ----------- ^^^^ expected enum `Option`, found `i32` + | | | expected due to this | = note: expected enum `Option` found type `i32` +help: try wrapping the expression in `Some` + | +LL | let x: Option = Some(1i32); + | +++++ + error: aborting due to previous error diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 3650e4f91a001..0e7ace0b400b0 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -1,4 +1,3 @@ -use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_then}; use clippy_utils::source::{first_line_of_span, snippet_with_applicability}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; @@ -7,6 +6,7 @@ use if_chain::if_chain; use itertools::Itertools; use rustc_ast::ast::{Async, AttrKind, Attribute, Fn, FnRetTy, ItemKind}; use rustc_ast::token::CommentKind; +use rustc_ast::attr::is_doc_hidden; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::EmitterWriter; diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 63a72d4fddeb0..4144ca4bfad65 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -1,9 +1,9 @@ -use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; use clippy_utils::{meets_msrv, msrvs}; use if_chain::if_chain; use rustc_ast::ast::{FieldDef, Item, ItemKind, Variant, VariantData, VisibilityKind}; +use rustc_ast::attr::is_doc_hidden; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_semver::RustcVersion; diff --git a/src/tools/clippy/clippy_lints/src/matches.rs b/src/tools/clippy/clippy_lints/src/matches.rs index 22970507f964c..b9a721186f6f2 100644 --- a/src/tools/clippy/clippy_lints/src/matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches.rs @@ -15,7 +15,7 @@ use clippy_utils::{ use clippy_utils::{paths, search_same, SpanlessEq, SpanlessHash}; use core::iter::{once, ExactSizeIterator}; use if_chain::if_chain; -use rustc_ast::ast::{Attribute, LitKind}; +use rustc_ast::{ast::{LitKind, Attribute}, attr::is_doc_hidden}; use rustc_errors::Applicability; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::LangItem::{OptionNone, OptionSome}; @@ -1021,7 +1021,8 @@ impl CommonPrefixSearcher<'a> { fn is_hidden(cx: &LateContext<'_>, variant_def: &VariantDef) -> bool { let attrs = cx.tcx.get_attrs(variant_def.def_id); - clippy_utils::attrs::is_doc_hidden(attrs) || clippy_utils::attrs::is_unstable(attrs) + + is_doc_hidden(attrs) || clippy_utils::attrs::is_unstable(attrs) } #[allow(clippy::too_many_lines)] diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index fc0483a929a7a..cacdaf2dd0950 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -5,9 +5,8 @@ // [`missing_doc`]: https://github.com/rust-lang/rust/blob/cf9cf7c923eb01146971429044f216a3ca905e06/compiler/rustc_lint/src/builtin.rs#L415 // -use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint; -use rustc_ast::ast; +use rustc_ast::{ast, attr::is_doc_hidden}; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty; diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 25a84d1665089..23c6d69ff1770 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -1,4 +1,4 @@ -use rustc_ast::{ast, attr}; +use rustc_ast::ast; use rustc_errors::Applicability; use rustc_session::Session; use rustc_span::sym; @@ -148,15 +148,6 @@ pub fn is_proc_macro(sess: &Session, attrs: &[ast::Attribute]) -> bool { attrs.iter().any(|attr| sess.is_proc_macro_attr(attr)) } -/// Return true if the attributes contain `#[doc(hidden)]` -pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool { - attrs - .iter() - .filter(|attr| attr.has_name(sym::doc)) - .filter_map(ast::Attribute::meta_item_list) - .any(|l| attr::list_contains_name(&l, sym::hidden)) -} - /// Return true if the attributes contain `#[unstable]` pub fn is_unstable(attrs: &[ast::Attribute]) -> bool { attrs.iter().any(|attr| attr.has_name(sym::unstable))