diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index be764cfe83bc3..39faed0bf365c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2412,9 +2412,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { #[derive(Debug)] enum SubOrigin<'hir> { GAT(&'hir hir::Generics<'hir>), - Impl(&'hir hir::Generics<'hir>), - Trait(&'hir hir::Generics<'hir>), - Fn(&'hir hir::Generics<'hir>), + Impl, + Trait, + Fn, Unknown, } let sub_origin = 'origin: { @@ -2429,34 +2429,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { kind: hir::ImplItemKind::TyAlias(..), generics, .. - }) => SubOrigin::GAT(generics), - Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(..), - generics, - .. - }) => SubOrigin::Fn(generics), - Node::TraitItem(hir::TraitItem { + }) + | Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), generics, .. }) => SubOrigin::GAT(generics), - Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(..), - generics, + Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(..), .. - }) => SubOrigin::Fn(generics), - Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, generics, _, _), + }) + | Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(..), .. - }) => SubOrigin::Trait(generics), + }) + | Node::Item(hir::Item { + kind: hir::ItemKind::Fn(..), .. + }) => SubOrigin::Fn, Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), + kind: hir::ItemKind::Trait(..), .. - }) => SubOrigin::Impl(generics), + }) => SubOrigin::Trait, Node::Item(hir::Item { - kind: hir::ItemKind::Fn(_, generics, _), - .. - }) => SubOrigin::Fn(generics), + kind: hir::ItemKind::Impl(..), .. + }) => SubOrigin::Impl, _ => continue, }; } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 6631470f2191b..e955a1798b735 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -524,7 +524,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let crate_root = self.r.resolve_crate_root(source.ident); let crate_name = match crate_root.kind { ModuleKind::Def(.., name) => name, - ModuleKind::Block(..) => unreachable!(), + ModuleKind::Block => unreachable!(), }; // HACK(eddyb) unclear how good this is, but keeping `$crate` // in `source` breaks `src/test/ui/imports/import-crate-var.rs`, @@ -936,7 +936,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { if self.block_needs_anonymous_module(block) { let module = self.r.new_module( Some(parent), - ModuleKind::Block(block.id), + ModuleKind::Block, expansion.to_expn_id(), block.span, parent.no_implicit_prelude, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 8a655cbf3845a..0343e8d9b8ec3 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -163,7 +163,7 @@ impl<'a> Resolver<'a> { let container = match parent.kind { ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()), - ModuleKind::Block(..) => "block", + ModuleKind::Block => "block", }; let old_noun = match old_binding.is_import() { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 0cc6d05d1d086..6e6782881427b 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -218,7 +218,7 @@ impl<'a> Resolver<'a> { return Some((self.expn_def_scope(ctxt.remove_mark()), None)); } - if let ModuleKind::Block(..) = module.kind { + if let ModuleKind::Block = module.kind { return Some((module.parent.unwrap().nearest_item_scope(), None)); } @@ -333,7 +333,7 @@ impl<'a> Resolver<'a> { }; match module.kind { - ModuleKind::Block(..) => {} // We can see through blocks + ModuleKind::Block => {} // We can see through blocks _ => break, } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index f979403e09735..6b49c6b1ac63e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1444,7 +1444,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { // Items from this module self.r.add_module_candidates(module, &mut names, &filter_fn); - if let ModuleKind::Block(..) = module.kind { + if let ModuleKind::Block = module.kind { // We can see through blocks } else { // Items from the prelude diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6945306a69189..31d10008efbfb 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -437,7 +437,7 @@ enum ModuleKind { /// f(); // Resolves to (1) /// } /// ``` - Block(NodeId), + Block, /// Any module with a name. /// /// This could be: @@ -454,7 +454,7 @@ impl ModuleKind { /// Get name of the module. pub fn name(&self) -> Option { match self { - ModuleKind::Block(..) => None, + ModuleKind::Block => None, ModuleKind::Def(.., name) => Some(*name), } } @@ -530,7 +530,7 @@ impl<'a> ModuleData<'a> { ) -> Self { let is_foreign = match kind { ModuleKind::Def(_, def_id, _) => !def_id.is_local(), - ModuleKind::Block(_) => false, + ModuleKind::Block => false, }; ModuleData { parent, diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 6dc8563c421fc..234fa213da89f 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1000,7 +1000,7 @@ pub fn copy(x: &T) -> T { /// /// This function will unsafely assume the pointer `src` is valid for [`size_of::`][size_of] /// bytes by transmuting `&T` to `&U` and then reading the `&U` (except that this is done in a way -/// that is correct even when `&U` makes stricter alignment requirements than `&T`). It will also +/// that is correct even when `&U` has stricter alignment requirements than `&T`). It will also /// unsafely create a copy of the contained value instead of moving out of `src`. /// /// It is not a compile-time error if `T` and `U` have different sizes, but it diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 18f7f6a35e98f..96addbd1a0558 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -898,7 +898,7 @@ pub trait Read { /// use std::fs::File; /// /// fn main() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; + /// let f = File::open("foo.txt")?; /// /// for byte in f.bytes() { /// println!("{}", byte.unwrap()); @@ -932,8 +932,8 @@ pub trait Read { /// use std::fs::File; /// /// fn main() -> io::Result<()> { - /// let mut f1 = File::open("foo.txt")?; - /// let mut f2 = File::open("bar.txt")?; + /// let f1 = File::open("foo.txt")?; + /// let f2 = File::open("bar.txt")?; /// /// let mut handle = f1.chain(f2); /// let mut buffer = String::new(); @@ -973,7 +973,7 @@ pub trait Read { /// use std::fs::File; /// /// fn main() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; + /// let f = File::open("foo.txt")?; /// let mut buffer = [0; 5]; /// /// // read at most five bytes diff --git a/src/doc/rustdoc/src/deprecated-features.md b/src/doc/rustdoc/src/deprecated-features.md index 2bc6e8fc8ae4d..9438948af544a 100644 --- a/src/doc/rustdoc/src/deprecated-features.md +++ b/src/doc/rustdoc/src/deprecated-features.md @@ -10,4 +10,4 @@ change in any release. In the past the most common use case for customizing passes was to omit the `strip-private` pass. You can do this more easily, and without risk of the pass being changed, by passing -[`--document-private-items`](./unstable-features.md#--document-private-items). +[`--document-private-items`](command-line-arguments.md#--document-private-items-show-items-that-are-not-public). diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 30b3d6defb4b8..32b350074903e 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -466,7 +466,7 @@ Note that the third item is the crate root, which in this case is undocumented. and is also accepted on stable toolchains. It can also be used with `--show-coverage`. Take a look at its -[documentation](#--show-coverage-get-statistics-about-code-documentation-coverage) for more +[documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more information. ### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c9ef4748a4845..07237438a0d32 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1993,6 +1993,7 @@ fn clean_maybe_renamed_item<'tcx>( ItemKind::Trait(_, _, generics, bounds, item_ids) => { let items = item_ids.iter().map(|ti| cx.tcx.hir().trait_item(ti.id).clean(cx)).collect(); + TraitItem(Trait { def_id, items, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 81cc12c9d5596..dcd2eaac7ea60 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1,9 +1,5 @@ use clean::AttributesExt; -use std::cmp::Ordering; -use std::fmt; -use std::rc::Rc; - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::CtorKind; @@ -15,6 +11,9 @@ use rustc_middle::ty::{Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants}; +use std::cmp::Ordering; +use std::fmt; +use std::rc::Rc; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_section, @@ -37,6 +36,7 @@ use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; use crate::html::url_parts_builder::UrlPartsBuilder; use askama::Template; +use itertools::Itertools; const ITEM_TABLE_OPEN: &str = "
"; const ITEM_TABLE_CLOSE: &str = "
"; @@ -539,6 +539,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: let count_types = required_types.len() + provided_types.len(); let count_consts = required_consts.len() + provided_consts.len(); let count_methods = required_methods.len() + provided_methods.len(); + let must_implement_one_of_functions = + cx.tcx().trait_def(t.def_id).must_implement_one_of.clone(); // Output the trait definition wrap_into_docblock(w, |w| { @@ -784,13 +786,22 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: } // Output the documentation for each function individually - if !required_methods.is_empty() { + if !required_methods.is_empty() || must_implement_one_of_functions.is_some() { write_small_section_header( w, "required-methods", "Required Methods", "
", ); + + if let Some(list) = must_implement_one_of_functions.as_deref() { + write!( + w, + "
At least one of the `{}` methods is required.
", + list.iter().join("`, `") + ); + } + for m in required_methods { trait_item(w, cx, m, it); } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 7ff8063904ace..c42cac59bd6fa 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -205,11 +205,13 @@ details.rustdoc-toggle > summary::before { /* Created this empty rule to satisfy the theme checks. */ .stab.empty-impl {} +.stab.must_implement {} .stab.unstable, .stab.deprecated, .stab.portability, -.stab.empty-impl { +.stab.empty-impl, +.stab.must_implement { color: #c5c5c5; background: #314559 !important; border-style: none !important; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 8e753f5768206..62d9eaa02e6a7 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -180,6 +180,7 @@ details.rustdoc-toggle > summary::before { .stab.empty-impl { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } .stab.unstable { background: #FFF5D6; border-color: #FFC600; color: #2f2f2f; } .stab.deprecated { background: #ffc4c4; border-color: #db7b7b; color: #2f2f2f; } +.stab.must_implement { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; } .stab.portability { background: #F3DFFF; border-color: #b07bdb; color: #2f2f2f; } .stab.portability > code { background: none; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 40d965c39c390..b751acff152cb 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -163,6 +163,7 @@ details.rustdoc-toggle > summary::before { .stab.empty-impl { background: #FFF5D6; border-color: #FFC600; } .stab.unstable { background: #FFF5D6; border-color: #FFC600; } .stab.deprecated { background: #ffc4c4; border-color: #db7b7b; } +.stab.must_implement { background: #F3DFFF; border-color: #b07bdb; } .stab.portability { background: #F3DFFF; border-color: #b07bdb; } .stab.portability > code { background: none; } diff --git a/src/test/rustdoc/must_implement_one_of.rs b/src/test/rustdoc/must_implement_one_of.rs new file mode 100644 index 0000000000000..1f1dd5d5796ee --- /dev/null +++ b/src/test/rustdoc/must_implement_one_of.rs @@ -0,0 +1,10 @@ +#![crate_name = "c"] +#![feature(rustc_attrs)] + +#[rustc_must_implement_one_of(a, b)] +// @matches c/trait.Trait.html '//*[@class="stab must_implement"]' \ +// 'At least one of the `a`, `b` methods is required.$' +pub trait Trait { + fn a() {} + fn b() {} +} diff --git a/src/test/ui/issues/issue-30371.rs b/src/test/ui/issues/issue-30371.rs index 58521b95cf637..a1ae9a36bc1d7 100644 --- a/src/test/ui/issues/issue-30371.rs +++ b/src/test/ui/issues/issue-30371.rs @@ -1,6 +1,5 @@ // run-pass #![allow(unreachable_code)] -#![allow(unused_mut)] // rust-lang/rust#54586 #![deny(unused_variables)] fn main() { diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index c9b1649200d9c..a7c78d80ccd76 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -348,11 +348,6 @@ impl Checker { return; } - // These appear to be broken in mdbook right now? - if fragment.starts_with('-') { - return; - } - parse_ids(&mut target_ids.borrow_mut(), &pretty_path, target_source, report); if target_ids.borrow().contains(*fragment) {