diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ci/channel | 2 | ||||
| -rw-r--r-- | src/librustdoc/clean/auto_trait.rs | 28 | ||||
| -rw-r--r-- | src/librustdoc/clean/inline.rs | 37 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 27 | ||||
| -rw-r--r-- | src/test/rustdoc/auxiliary/issue-100204-aux.rs | 13 | ||||
| -rw-r--r-- | src/test/rustdoc/fn-bound.rs | 21 | ||||
| -rw-r--r-- | src/test/rustdoc/issue-100204-inline-impl-through-glob-import.rs | 14 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/lib.register_all.rs | 1 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/lib.register_nursery.rs | 1 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs | 1 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/matches/mod.rs | 2 |
11 files changed, 112 insertions, 35 deletions
diff --git a/src/ci/channel b/src/ci/channel index 65b2df87f7d..2bf5ad0447d 100644 --- a/src/ci/channel +++ b/src/ci/channel @@ -1 +1 @@ -beta +stable diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fb178cbd95e..5e9f3346af9 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -345,15 +345,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { fn make_final_bounds( &self, ty_to_bounds: FxHashMap<Type, FxHashSet<GenericBound>>, - ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)>, + ty_to_fn: FxHashMap<Type, (PolyTrait, Option<Type>)>, lifetime_to_bounds: FxHashMap<Lifetime, FxHashSet<GenericBound>>, ) -> Vec<WherePredicate> { ty_to_bounds .into_iter() .flat_map(|(ty, mut bounds)| { - if let Some(data) = ty_to_fn.get(&ty) { - let (poly_trait, output) = - (data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new)); + if let Some((ref poly_trait, ref output)) = ty_to_fn.get(&ty) { let mut new_path = poly_trait.trait_.clone(); let last_segment = new_path.segments.pop().expect("segments were empty"); @@ -371,8 +369,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { GenericArgs::Parenthesized { inputs, output } => (inputs, output), }; + let output = output.as_ref().cloned().map(Box::new); if old_output.is_some() && old_output != output { - panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, data.1); + panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, output); } let new_params = GenericArgs::Parenthesized { inputs: old_input, output }; @@ -382,7 +381,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .push(PathSegment { name: last_segment.name, args: new_params }); bounds.insert(GenericBound::TraitBound( - PolyTrait { trait_: new_path, generic_params: poly_trait.generic_params }, + PolyTrait { + trait_: new_path, + generic_params: poly_trait.generic_params.clone(), + }, hir::TraitBoundModifier::None, )); } @@ -468,7 +470,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { let mut lifetime_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default(); let mut ty_to_traits: FxHashMap<Type, FxHashSet<Path>> = Default::default(); - let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = Default::default(); + let mut ty_to_fn: FxHashMap<Type, (PolyTrait, Option<Type>)> = Default::default(); for p in clean_where_predicates { let (orig_p, p) = (p, p.clean(self.cx)); @@ -532,8 +534,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { if is_fn { ty_to_fn .entry(ty.clone()) - .and_modify(|e| *e = (Some(poly_trait.clone()), e.1.clone())) - .or_insert(((Some(poly_trait.clone())), None)); + .and_modify(|e| *e = (poly_trait.clone(), e.1.clone())) + .or_insert(((poly_trait.clone()), None)); ty_to_bounds.entry(ty.clone()).or_default(); } else { @@ -556,7 +558,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .and_modify(|e| { *e = (e.0.clone(), Some(rhs.ty().unwrap().clone())) }) - .or_insert((None, Some(rhs.ty().unwrap().clone()))); + .or_insert(( + PolyTrait { + trait_: trait_.clone(), + generic_params: Vec::new(), + }, + Some(rhs.ty().unwrap().clone()), + )); continue; } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d4c38f34b5b..5a3a8086f12 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -138,6 +138,7 @@ pub(crate) fn try_inline_glob( cx: &mut DocContext<'_>, res: Res, visited: &mut FxHashSet<DefId>, + inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Option<Vec<clean::Item>> { let did = res.opt_def_id()?; if did.is_local() { @@ -146,8 +147,17 @@ pub(crate) fn try_inline_glob( match res { Res::Def(DefKind::Mod, did) => { - let m = build_module(cx, did, visited); - Some(m.items) + let mut items = build_module_items(cx, did, visited, inlined_names); + items.drain_filter(|item| { + if let Some(name) = item.name { + // If an item with the same type and name already exists, + // it takes priority over the inlined stuff. + !inlined_names.insert((item.type_(), name)) + } else { + false + } + }); + Some(items) } // glob imports on things like enums aren't inlined even for local exports, so just bail _ => None, @@ -517,6 +527,18 @@ fn build_module( did: DefId, visited: &mut FxHashSet<DefId>, ) -> clean::Module { + let items = build_module_items(cx, did, visited, &mut FxHashSet::default()); + + let span = clean::Span::new(cx.tcx.def_span(did)); + clean::Module { items, span } +} + +fn build_module_items( + cx: &mut DocContext<'_>, + did: DefId, + visited: &mut FxHashSet<DefId>, + inlined_names: &mut FxHashSet<(ItemType, Symbol)>, +) -> Vec<clean::Item> { let mut items = Vec::new(); // If we're re-exporting a re-export it may actually re-export something in @@ -526,7 +548,13 @@ fn build_module( if item.vis.is_public() { let res = item.res.expect_non_local(); if let Some(def_id) = res.mod_def_id() { - if did == def_id || !visited.insert(def_id) { + // If we're inlining a glob import, it's possible to have + // two distinct modules with the same name. We don't want to + // inline it, or mark any of its contents as visited. + if did == def_id + || inlined_names.contains(&(ItemType::Module, item.ident.name)) + || !visited.insert(def_id) + { continue; } } @@ -563,8 +591,7 @@ fn build_module( } } - let span = clean::Span::new(cx.tcx.def_span(did)); - clean::Module { items, span } + items } pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index af9ea315ac3..4fd05c7babd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -71,7 +71,7 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> { // priority to the not-imported one, so we should, too. items.extend(self.items.iter().flat_map(|(item, renamed)| { // First, lower everything other than imports. - if matches!(item.kind, hir::ItemKind::Use(..)) { + if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { return Vec::new(); } let v = clean_maybe_renamed_item(cx, item, *renamed); @@ -84,20 +84,13 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> { })); items.extend(self.items.iter().flat_map(|(item, renamed)| { // Now we actually lower the imports, skipping everything else. - if !matches!(item.kind, hir::ItemKind::Use(..)) { - return Vec::new(); + if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { + let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) + } else { + // skip everything else + Vec::new() } - let mut v = clean_maybe_renamed_item(cx, item, *renamed); - v.drain_filter(|item| { - if let Some(name) = item.name { - // If an item with the same type and name already exists, - // it takes priority over the inlined stuff. - !inserted.insert((item.type_(), name)) - } else { - false - } - }); - v })); // determine if we should display the inner contents or @@ -1992,7 +1985,7 @@ fn clean_maybe_renamed_item<'tcx>( return clean_extern_crate(item, name, orig_name, cx); } ItemKind::Use(path, kind) => { - return clean_use_statement(item, name, path, kind, cx); + return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default()); } _ => unreachable!("not yet converted"), }; @@ -2113,6 +2106,7 @@ fn clean_use_statement<'tcx>( path: &hir::Path<'tcx>, kind: hir::UseKind, cx: &mut DocContext<'tcx>, + inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Vec<Item> { // We need this comparison because some imports (for std types for example) // are "inserted" as well but directly by the compiler and they should not be @@ -2177,7 +2171,8 @@ fn clean_use_statement<'tcx>( let inner = if kind == hir::UseKind::Glob { if !denied { let mut visited = FxHashSet::default(); - if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) { + if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited, inlined_names) + { return items; } } diff --git a/src/test/rustdoc/auxiliary/issue-100204-aux.rs b/src/test/rustdoc/auxiliary/issue-100204-aux.rs new file mode 100644 index 00000000000..df1b59069be --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-100204-aux.rs @@ -0,0 +1,13 @@ +#![crate_name="first"] + +pub mod prelude { + pub use crate::Bot; +} + +pub struct Bot; + +impl Bot { + pub fn new() -> Bot { + Bot + } +} diff --git a/src/test/rustdoc/fn-bound.rs b/src/test/rustdoc/fn-bound.rs new file mode 100644 index 00000000000..4c4ffddc8a6 --- /dev/null +++ b/src/test/rustdoc/fn-bound.rs @@ -0,0 +1,21 @@ +// Regression test for #100143 + +use std::iter::Peekable; + +pub struct Span<F: Fn(&i32)> { + inner: Peekable<ConditionalIterator<F>>, +} + +pub struct ConditionalIterator<F> { + f: F, +} + + +// @has 'fn_bound/struct.ConditionalIterator.html' '//h3[@class="code-header in-band"]' 'impl<F: Fn(&i32)> Iterator for ConditionalIterator<F>' +impl<F: Fn(&i32)> Iterator for ConditionalIterator<F> { + type Item = (); + + fn next(&mut self) -> Option<Self::Item> { + todo!() + } +} diff --git a/src/test/rustdoc/issue-100204-inline-impl-through-glob-import.rs b/src/test/rustdoc/issue-100204-inline-impl-through-glob-import.rs new file mode 100644 index 00000000000..3e20c5c0741 --- /dev/null +++ b/src/test/rustdoc/issue-100204-inline-impl-through-glob-import.rs @@ -0,0 +1,14 @@ +// aux-build:issue-100204-aux.rs +// build-aux-docs +// ignore-cross-compile + +#![crate_name="second"] + +extern crate first; + +pub mod prelude {} + +// @has first/struct.Bot.html '//h4[@class="code-header"]' 'pub fn new() -> Bot' +// @has second/struct.Bot.html '//h4[@class="code-header"]' 'pub fn new() -> Bot' +#[doc(inline)] +pub use first::*; diff --git a/src/tools/clippy/clippy_lints/src/lib.register_all.rs b/src/tools/clippy/clippy_lints/src/lib.register_all.rs index 8a2cfbff953..a69f77f220f 100644 --- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs +++ b/src/tools/clippy/clippy_lints/src/lib.register_all.rs @@ -151,7 +151,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![ LintId::of(matches::MATCH_STR_CASE_MISMATCH), LintId::of(matches::NEEDLESS_MATCH), LintId::of(matches::REDUNDANT_PATTERN_MATCHING), - LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE), LintId::of(matches::SINGLE_MATCH), LintId::of(matches::WILDCARD_IN_OR_PATTERNS), LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE), diff --git a/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs b/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs index 642d629971d..91210b23afe 100644 --- a/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs +++ b/src/tools/clippy/clippy_lints/src/lib.register_nursery.rs @@ -13,6 +13,7 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![ LintId::of(future_not_send::FUTURE_NOT_SEND), LintId::of(index_refutable_slice::INDEX_REFUTABLE_SLICE), LintId::of(let_if_seq::USELESS_LET_IF_SEQ), + LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE), LintId::of(methods::ITER_WITH_DRAIN), LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN), LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL), diff --git a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs index 7b13713c36e..6dc7ad33488 100644 --- a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs +++ b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs @@ -24,7 +24,6 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec! LintId::of(loops::EMPTY_LOOP), LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES), LintId::of(loops::MUT_RANGE_BOUND), - LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE), LintId::of(methods::NO_EFFECT_REPLACE), LintId::of(methods::SUSPICIOUS_MAP), LintId::of(mut_key::MUTABLE_KEY_TYPE), diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs index 3e765173fb9..03cb1dc36b1 100644 --- a/src/tools/clippy/clippy_lints/src/matches/mod.rs +++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs @@ -845,7 +845,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.60.0"] pub SIGNIFICANT_DROP_IN_SCRUTINEE, - suspicious, + nursery, "warns when a temporary of a type with a drop with a significant side-effect might have a surprising lifetime" } |
