From fba747a06e661c663626ae4d7db3fdaf9f9f13f9 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 2 Feb 2021 12:16:35 -0600 Subject: [PATCH 01/10] Refactor out PrimitiveTypeTable --- compiler/rustc_hir/src/hir.rs | 49 +++++++++++++++++++ compiler/rustc_resolve/src/diagnostics.rs | 6 +-- compiler/rustc_resolve/src/late.rs | 12 ++--- .../rustc_resolve/src/late/diagnostics.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 47 ++---------------- compiler/rustc_resolve/src/macros.rs | 11 ++--- 6 files changed, 67 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1c16dc026670b..58bcd37478a73 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2057,6 +2057,28 @@ pub enum PrimTy { } impl PrimTy { + /// All of the primitive types + pub const ALL: [Self; 17] = [ + // any changes here should also be reflected in `PrimTy::from_name` + Self::Int(IntTy::I8), + Self::Int(IntTy::I16), + Self::Int(IntTy::I32), + Self::Int(IntTy::I64), + Self::Int(IntTy::I128), + Self::Int(IntTy::Isize), + Self::Uint(UintTy::U8), + Self::Uint(UintTy::U16), + Self::Uint(UintTy::U32), + Self::Uint(UintTy::U64), + Self::Uint(UintTy::U128), + Self::Uint(UintTy::Usize), + Self::Float(FloatTy::F32), + Self::Float(FloatTy::F64), + Self::Bool, + Self::Char, + Self::Str, + ]; + pub fn name_str(self) -> &'static str { match self { PrimTy::Int(i) => i.name_str(), @@ -2078,6 +2100,33 @@ impl PrimTy { PrimTy::Char => sym::char, } } + + /// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32". + /// Returns `None` if no matching type is found. + pub fn from_name(name: Symbol) -> Option { + let ty = match name { + // any changes here should also be reflected in `PrimTy::ALL` + sym::i8 => Self::Int(IntTy::I8), + sym::i16 => Self::Int(IntTy::I16), + sym::i32 => Self::Int(IntTy::I32), + sym::i64 => Self::Int(IntTy::I64), + sym::i128 => Self::Int(IntTy::I128), + sym::isize => Self::Int(IntTy::Isize), + sym::u8 => Self::Uint(UintTy::U8), + sym::u16 => Self::Uint(UintTy::U16), + sym::u32 => Self::Uint(UintTy::U32), + sym::u64 => Self::Uint(UintTy::U64), + sym::u128 => Self::Uint(UintTy::U128), + sym::usize => Self::Uint(UintTy::Usize), + sym::f32 => Self::Float(FloatTy::F32), + sym::f64 => Self::Float(FloatTy::F64), + sym::bool => Self::Bool, + sym::char => Self::Char, + sym::str => Self::Str, + _ => return None, + }; + Some(ty) + } } #[derive(Debug, HashStable_Generic)] diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9d55bafd2868e..0714d76f7448a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -9,6 +9,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::PrimTy; use rustc_middle::bug; use rustc_middle::ty::{self, DefIdTree}; use rustc_session::Session; @@ -718,10 +719,9 @@ impl<'a> Resolver<'a> { } } Scope::BuiltinTypes => { - let primitive_types = &this.primitive_type_table.primitive_types; - suggestions.extend(primitive_types.iter().flat_map(|(name, prim_ty)| { + suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| { let res = Res::PrimTy(*prim_ty); - filter_fn(res).then_some(TypoSuggestion::from_res(*name, res)) + filter_fn(res).then_some(TypoSuggestion::from_res(prim_ty.name(), res)) })) } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index eaeb28388d4f0..b7e4efc707844 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -20,7 +20,7 @@ use rustc_errors::DiagnosticId; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; -use rustc_hir::TraitCandidate; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1921,7 +1921,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.r.trait_map.insert(id, traits); } - if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) { + if PrimTy::from_name(path[0].ident.name).is_some() { let mut std_path = Vec::with_capacity(1 + path.len()); std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std))); @@ -2115,13 +2115,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // The same fallback is used when `a` resolves to nothing. PathResult::Module(ModuleOrUniformRoot::Module(_)) | PathResult::Failed { .. } if (ns == TypeNS || path.len() > 1) - && self - .r - .primitive_type_table - .primitive_types - .contains_key(&path[0].ident.name) => + && PrimTy::from_name(path[0].ident.name).is_some() => { - let prim = self.r.primitive_type_table.primitive_types[&path[0].ident.name]; + let prim = PrimTy::from_name(path[0].ident.name).unwrap(); PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1) } PathResult::Module(ModuleOrUniformRoot::Module(module)) => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9c90388d24aaa..52c7f1357effc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1210,8 +1210,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { // Add primitive types to the mix if filter_fn(Res::PrimTy(PrimTy::Bool)) { names.extend( - self.r.primitive_type_table.primitive_types.iter().map(|(name, prim_ty)| { - TypoSuggestion::from_res(*name, Res::PrimTy(*prim_ty)) + PrimTy::ALL.iter().map(|prim_ty| { + TypoSuggestion::from_res(prim_ty.name(), Res::PrimTy(*prim_ty)) }), ) } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2b4a1d9e3fa0a..8f62a91691e80 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -24,7 +24,7 @@ use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::unwrap_or; use rustc_ast::visit::{self, Visitor}; -use rustc_ast::{self as ast, FloatTy, IntTy, NodeId, UintTy}; +use rustc_ast::{self as ast, NodeId}; use rustc_ast::{Crate, CRATE_NODE_ID}; use rustc_ast::{ItemKind, Path}; use rustc_ast_lowering::ResolverAstLowering; @@ -38,8 +38,7 @@ use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; -use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; -use rustc_hir::TraitCandidate; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::vec::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::hir::exports::ExportMap; @@ -833,39 +832,6 @@ impl<'a> NameBinding<'a> { } } -/// Interns the names of the primitive types. -/// -/// All other types are defined somewhere and possibly imported, but the primitive ones need -/// special handling, since they have no place of origin. -struct PrimitiveTypeTable { - primitive_types: FxHashMap, -} - -impl PrimitiveTypeTable { - fn new() -> PrimitiveTypeTable { - let mut table = FxHashMap::default(); - - table.insert(sym::bool, Bool); - table.insert(sym::char, Char); - table.insert(sym::f32, Float(FloatTy::F32)); - table.insert(sym::f64, Float(FloatTy::F64)); - table.insert(sym::isize, Int(IntTy::Isize)); - table.insert(sym::i8, Int(IntTy::I8)); - table.insert(sym::i16, Int(IntTy::I16)); - table.insert(sym::i32, Int(IntTy::I32)); - table.insert(sym::i64, Int(IntTy::I64)); - table.insert(sym::i128, Int(IntTy::I128)); - table.insert(sym::str, Str); - table.insert(sym::usize, Uint(UintTy::Usize)); - table.insert(sym::u8, Uint(UintTy::U8)); - table.insert(sym::u16, Uint(UintTy::U16)); - table.insert(sym::u32, Uint(UintTy::U32)); - table.insert(sym::u64, Uint(UintTy::U64)); - table.insert(sym::u128, Uint(UintTy::U128)); - Self { primitive_types: table } - } -} - #[derive(Debug, Default, Clone)] pub struct ExternPreludeEntry<'a> { extern_crate_item: Option<&'a NameBinding<'a>>, @@ -911,9 +877,6 @@ pub struct Resolver<'a> { /// "self-confirming" import resolutions during import validation. unusable_binding: Option<&'a NameBinding<'a>>, - /// The idents for the primitive types. - primitive_type_table: PrimitiveTypeTable, - /// Resolutions for nodes that have a single resolution. partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. @@ -1283,8 +1246,6 @@ impl<'a> Resolver<'a> { last_import_segment: false, unusable_binding: None, - primitive_type_table: PrimitiveTypeTable::new(), - partial_res_map: Default::default(), import_res_map: Default::default(), label_res_map: Default::default(), @@ -1993,9 +1954,9 @@ impl<'a> Resolver<'a> { } if ns == TypeNS { - if let Some(prim_ty) = self.primitive_type_table.primitive_types.get(&ident.name) { + if let Some(prim_ty) = PrimTy::from_name(ident.name) { let binding = - (Res::PrimTy(*prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root()) + (Res::PrimTy(prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root()) .to_name_binding(self.arenas); return Some(LexicalScopeBinding::Item(binding)); } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index d0adee2429d9a..d76db7c645abc 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -21,6 +21,7 @@ use rustc_expand::expand::{AstFragment, Invocation, InvocationKind}; use rustc_feature::is_builtin_attr_name; use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; use rustc_hir::def_id; +use rustc_hir::PrimTy; use rustc_middle::middle::stability; use rustc_middle::ty; use rustc_session::lint::builtin::{SOFT_UNSTABLE, UNUSED_MACROS}; @@ -796,12 +797,10 @@ impl<'a> Resolver<'a> { } result } - Scope::BuiltinTypes => { - match this.primitive_type_table.primitive_types.get(&ident.name).cloned() { - Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas), - None => Err(Determinacy::Determined), - } - } + Scope::BuiltinTypes => match PrimTy::from_name(ident.name) { + Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas), + None => Err(Determinacy::Determined), + }, }; match result { From f66115dc10d53976daba4bad7ec522a151c4c5a4 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 2 Feb 2021 12:28:58 -0600 Subject: [PATCH 02/10] Use PrimTy in builtin type shadow lint --- src/tools/clippy/clippy_lints/src/misc_early.rs | 8 ++++---- .../clippy/clippy_lints/src/utils/constants.rs | 13 ------------- src/tools/clippy/clippy_lints/src/utils/mod.rs | 1 - 3 files changed, 4 insertions(+), 18 deletions(-) delete mode 100644 src/tools/clippy/clippy_lints/src/utils/constants.rs diff --git a/src/tools/clippy/clippy_lints/src/misc_early.rs b/src/tools/clippy/clippy_lints/src/misc_early.rs index 5bc45c87874b4..84a0df92f5b43 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early.rs @@ -1,4 +1,4 @@ -use crate::utils::{constants, snippet_opt, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; +use crate::utils::{snippet_opt, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; use rustc_ast::ast::{ BindingMode, Expr, ExprKind, GenericParamKind, Generics, Lit, LitFloatType, LitIntType, LitKind, Mutability, NodeId, Pat, PatKind, UnOp, @@ -6,6 +6,7 @@ use rustc_ast::ast::{ use rustc_ast::visit::FnKind; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; +use rustc_hir::PrimTy; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -264,13 +265,12 @@ impl EarlyLintPass for MiscEarlyLints { fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) { for param in &gen.params { if let GenericParamKind::Type { .. } = param.kind { - let name = param.ident.as_str(); - if constants::BUILTIN_TYPES.contains(&&*name) { + if let Some(prim_ty) = PrimTy::from_name(param.ident.name) { span_lint( cx, BUILTIN_TYPE_SHADOW, param.ident.span, - &format!("this generic shadows the built-in type `{}`", name), + &format!("this generic shadows the built-in type `{}`", prim_ty.name()), ); } } diff --git a/src/tools/clippy/clippy_lints/src/utils/constants.rs b/src/tools/clippy/clippy_lints/src/utils/constants.rs deleted file mode 100644 index 522932f054d89..0000000000000 --- a/src/tools/clippy/clippy_lints/src/utils/constants.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! This module contains some useful constants. - -#![deny(clippy::missing_docs_in_private_items)] - -/// List of the built-in types names. -/// -/// See also [the reference][reference-types] for a list of such types. -/// -/// [reference-types]: https://doc.rust-lang.org/reference/types.html -pub const BUILTIN_TYPES: &[&str] = &[ - "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "i128", "u128", "isize", "usize", "f32", "f64", "bool", - "str", "char", -]; diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index d0db3a67533bc..e639d33ed4715 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -8,7 +8,6 @@ pub mod author; pub mod camel_case; pub mod comparisons; pub mod conf; -pub mod constants; mod diagnostics; pub mod eager_or_lazy; pub mod higher; From 253a970c3dd35bf92040e819b7a60a5136728e59 Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 3 Feb 2021 21:41:18 -0800 Subject: [PATCH 03/10] Miscellaneous small diagnostics cleanup --- .../rustc_trait_selection/src/traits/const_evaluatable.rs | 2 +- .../src/traits/error_reporting/mod.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- compiler/rustc_typeck/src/check/mod.rs | 2 +- .../cross_crate_predicate.stderr | 8 ++++---- .../const_evaluatable_checked/different-fn.stderr | 2 +- src/test/ui/const_evaluatable/needs_where_clause.stderr | 2 +- src/test/ui/const_evaluatable/no_where_clause.stderr | 2 +- src/test/ui/issues/issue-18919.stderr | 2 +- src/test/ui/issues/issue-23281.stderr | 2 +- .../adt-param-with-implicit-sized-bound.stderr | 4 ++-- src/test/ui/unsized/unsized-enum.stderr | 2 +- .../ui/unsized/unsized-inherent-impl-self-type.stderr | 2 +- src/test/ui/unsized/unsized-struct.stderr | 2 +- src/test/ui/unsized/unsized-trait-impl-self-type.stderr | 2 +- src/test/ui/wf/wf-fn-where-clause.stderr | 2 +- 16 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 89820bb1417eb..b1ac02d9fed5a 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -117,7 +117,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( { err.span_help( tcx.def_span(def.did), - &format!("try adding a `where` bound using this expression: where [u8; {}]: Sized", snippet), + &format!("try adding a `where` bound using this expression: `where [u8; {}]: Sized`", snippet), ); } else { err.span_help( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index d3b3403ac3e73..756281450d723 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1780,7 +1780,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { multispan.push_span_label( sp, format!( - "...if indirection was used here: `Box<{}>`", + "...if indirection were used here: `Box<{}>`", param.name.ident(), ), ); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 218280061643c..34bd332951c06 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1103,7 +1103,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // This is currently not possible to trigger because E0038 takes precedence, but // leave it in for completeness in case anything changes in an earlier stage. err.note(&format!( - "if trait `{}` was object safe, you could return a trait object", + "if trait `{}` were object-safe, you could return a trait object", trait_obj, )); } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index dc3e3b4e73839..229127e95d93c 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -838,7 +838,7 @@ fn missing_items_err( // Obtain the level of indentation ending in `sugg_sp`. let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0); // Make the whitespace that will make the suggestion have the right indentation. - let padding: String = (0..indentation).map(|_| " ").collect(); + let padding: String = std::iter::repeat(" ").take(indentation).collect(); for trait_item in missing_items { let snippet = suggestion_signature(&trait_item, tcx); diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr index 92547ca4796a4..1beb5315d1055 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr @@ -4,7 +4,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized +help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::() - 1]: Sized, @@ -16,7 +16,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized +help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] @@ -28,7 +28,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized +help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::() - 1]: Sized, @@ -40,7 +40,7 @@ error: unconstrained generic constant LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; std::mem::size_of::() - 1]: Sized +help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] diff --git a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr index 00efb61000401..8cdc9b57750ee 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr @@ -4,7 +4,7 @@ error: unconstrained generic constant LL | [0; size_of::>()] | ^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; size_of::>()]: Sized +help: try adding a `where` bound using this expression: `where [u8; size_of::>()]: Sized` --> $DIR/different-fn.rs:10:9 | LL | [0; size_of::>()] diff --git a/src/test/ui/const_evaluatable/needs_where_clause.stderr b/src/test/ui/const_evaluatable/needs_where_clause.stderr index e991c508c03f3..945105d1a2dc6 100644 --- a/src/test/ui/const_evaluatable/needs_where_clause.stderr +++ b/src/test/ui/const_evaluatable/needs_where_clause.stderr @@ -4,7 +4,7 @@ error: unconstrained generic constant LL | b: [f32; complex_maths::(N)], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; complex_maths::(N)]: Sized +help: try adding a `where` bound using this expression: `where [u8; complex_maths::(N)]: Sized` --> $DIR/needs_where_clause.rs:11:12 | LL | b: [f32; complex_maths::(N)], diff --git a/src/test/ui/const_evaluatable/no_where_clause.stderr b/src/test/ui/const_evaluatable/no_where_clause.stderr index 65100909e53d5..84a65f0d1d29b 100644 --- a/src/test/ui/const_evaluatable/no_where_clause.stderr +++ b/src/test/ui/const_evaluatable/no_where_clause.stderr @@ -4,7 +4,7 @@ error: unconstrained generic constant LL | b: [f32; complex_maths(N)], | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: where [u8; complex_maths(N)]: Sized +help: try adding a `where` bound using this expression: `where [u8; complex_maths(N)]: Sized` --> $DIR/no_where_clause.rs:10:12 | LL | b: [f32; complex_maths(N)], diff --git a/src/test/ui/issues/issue-18919.stderr b/src/test/ui/issues/issue-18919.stderr index ece714c949c19..d4b93eb074cfe 100644 --- a/src/test/ui/issues/issue-18919.stderr +++ b/src/test/ui/issues/issue-18919.stderr @@ -14,7 +14,7 @@ help: you could relax the implicit `Sized` bound on `T` if it were used through LL | enum Option { | ^ this could be changed to `T: ?Sized`... LL | Some(T), - | - ...if indirection was used here: `Box` + | - ...if indirection were used here: `Box` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23281.stderr b/src/test/ui/issues/issue-23281.stderr index d8046497b9875..a3d2583292551 100644 --- a/src/test/ui/issues/issue-23281.stderr +++ b/src/test/ui/issues/issue-23281.stderr @@ -14,7 +14,7 @@ help: you could relax the implicit `Sized` bound on `T` if it were used through LL | struct Vec { | ^ this could be changed to `T: ?Sized`... LL | t: T, - | - ...if indirection was used here: `Box` + | - ...if indirection were used here: `Box` error: aborting due to previous error diff --git a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr index 9450612332caa..9437fbe61cc7e 100644 --- a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr +++ b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr @@ -13,7 +13,7 @@ help: you could relax the implicit `Sized` bound on `T` if it were used through --> $DIR/adt-param-with-implicit-sized-bound.rs:18:10 | LL | struct X(T); - | ^ - ...if indirection was used here: `Box` + | ^ - ...if indirection were used here: `Box` | | | this could be changed to `T: ?Sized`... @@ -68,7 +68,7 @@ help: you could relax the implicit `Sized` bound on `T` if it were used through LL | struct Struct3{ | ^ this could be changed to `T: ?Sized`... LL | _t: T, - | - ...if indirection was used here: `Box` + | - ...if indirection were used here: `Box` help: consider further restricting `Self` | LL | fn func3() -> Struct3 where Self: Sized; diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr index 795c7beab0ac6..3057d4789bd81 100644 --- a/src/test/ui/unsized/unsized-enum.stderr +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -13,7 +13,7 @@ help: you could relax the implicit `Sized` bound on `U` if it were used through --> $DIR/unsized-enum.rs:4:10 | LL | enum Foo { FooSome(U), FooNone } - | ^ - ...if indirection was used here: `Box` + | ^ - ...if indirection were used here: `Box` | | | this could be changed to `U: ?Sized`... diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr index 9efebe3aeff70..9d8a1c67734a4 100644 --- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -13,7 +13,7 @@ help: you could relax the implicit `Sized` bound on `Y` if it were used through --> $DIR/unsized-inherent-impl-self-type.rs:5:11 | LL | struct S5(Y); - | ^ - ...if indirection was used here: `Box` + | ^ - ...if indirection were used here: `Box` | | | this could be changed to `Y: ?Sized`... diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index e013b8fc69ece..6661cf358b3ab 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -13,7 +13,7 @@ help: you could relax the implicit `Sized` bound on `T` if it were used through --> $DIR/unsized-struct.rs:4:12 | LL | struct Foo { data: T } - | ^ - ...if indirection was used here: `Box` + | ^ - ...if indirection were used here: `Box` | | | this could be changed to `T: ?Sized`... diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr index 516c750cb342e..d1b590d813307 100644 --- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -13,7 +13,7 @@ help: you could relax the implicit `Sized` bound on `Y` if it were used through --> $DIR/unsized-trait-impl-self-type.rs:8:11 | LL | struct S5(Y); - | ^ - ...if indirection was used here: `Box` + | ^ - ...if indirection were used here: `Box` | | | this could be changed to `Y: ?Sized`... diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index 988cb2fa5480c..22598e58bd744 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -28,7 +28,7 @@ help: you could relax the implicit `Sized` bound on `T` if it were used through LL | struct Vec { | ^ this could be changed to `T: ?Sized`... LL | t: T, - | - ...if indirection was used here: `Box` + | - ...if indirection were used here: `Box` error[E0038]: the trait `Copy` cannot be made into an object --> $DIR/wf-fn-where-clause.rs:12:16 From bb22eaf39e6e0a904a8f19a2a659620c12f03a24 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 25 Jan 2021 16:19:57 -0800 Subject: [PATCH 04/10] tidy: Run tidy style against markdown files. --- .../infer/lexical_region_resolve/README.md | 1 - src/doc/rustc/src/exploit-mitigations.md | 2 +- src/doc/rustc/src/lints/levels.md | 4 +- src/doc/rustc/src/lints/listing/index.md | 2 +- src/doc/rustc/src/what-is-rustc.md | 4 +- src/doc/rustdoc/src/advanced-features.md | 5 +- src/doc/rustdoc/src/documentation-tests.md | 20 ++++-- .../rustdoc/src/how-to-write-documentation.md | 34 +++++----- src/doc/rustdoc/src/lints.md | 3 +- src/doc/rustdoc/src/passes.md | 8 ++- src/doc/rustdoc/src/references.md | 6 +- src/doc/rustdoc/src/the-doc-attribute.md | 38 ++++++----- src/doc/rustdoc/src/what-is-rustdoc.md | 12 ++-- src/doc/rustdoc/src/what-to-include.md | 24 +++---- .../src/compiler-flags/codegen-backend.md | 2 +- .../src/compiler-flags/control-flow-guard.md | 4 +- .../src/compiler-flags/profile.md | 4 +- .../src/compiler-flags/report-time.md | 2 +- .../src/compiler-flags/tls-model.md | 2 +- .../src/language-features/auto-traits.md | 13 ++-- .../custom-test-frameworks.md | 1 - .../infer-static-outlives-requirements.md | 1 - .../src/language-features/intrinsics.md | 1 - .../src/language-features/lang-items.md | 12 ++-- .../src/language-features/non-ascii-idents.md | 8 +-- .../src/language-features/or-patterns.md | 2 +- .../src/language-features/plugin.md | 4 +- .../src/language-features/rustc-attrs.md | 2 +- .../src/language-features/unboxed-closures.md | 2 +- .../src/language-features/unsized-locals.md | 4 +- .../unsized-tuple-coercion.md | 2 +- .../unstable-book/src/library-features/asm.md | 2 +- .../src/library-features/concat-idents.md | 2 +- .../src/library-features/global-asm.md | 6 +- .../src/library-features/llvm-asm.md | 2 +- .../src/library-features/test.md | 4 +- .../src/library-features/try-trait.md | 2 +- src/tools/tidy/src/style.rs | 67 +++++++++++++------ 38 files changed, 176 insertions(+), 138 deletions(-) diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md index e0b2c0bffeeb3..0a7da8c80639c 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md @@ -1,4 +1,3 @@ - Lexical Region Resolution was removed in https://github.com/rust-lang/rust/pull/64790. Rust now uses Non-lexical lifetimes. For more info, please see the [borrowck diff --git a/src/doc/rustc/src/exploit-mitigations.md b/src/doc/rustc/src/exploit-mitigations.md index 44d5d9564f267..70df5170b21c1 100644 --- a/src/doc/rustc/src/exploit-mitigations.md +++ b/src/doc/rustc/src/exploit-mitigations.md @@ -378,7 +378,7 @@ C library default allocator5 since version 1.32.0 (2019-01-17)[39]. -```ignore +```rust,no_run fn main() { let mut x = Box::new([0; 1024]); diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 64cbbbb003585..3e616f226ed76 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -62,7 +62,7 @@ warning: unused variable: `x` A 'deny' lint produces an error if you violate it. For example, this code runs into the `exceeding_bitshifts` lint. -```rust,ignore +```rust,no_run fn main() { 100u8 << 10; } @@ -232,7 +232,7 @@ pub fn foo() {} This is the maximum level for all lints. So for example, if we take our code sample from the "deny" lint level above: -```rust,ignore +```rust,no_run fn main() { 100u8 << 10; } diff --git a/src/doc/rustc/src/lints/listing/index.md b/src/doc/rustc/src/lints/listing/index.md index 18cd2fe32a3cc..97aa2caf91508 100644 --- a/src/doc/rustc/src/lints/listing/index.md +++ b/src/doc/rustc/src/lints/listing/index.md @@ -2,4 +2,4 @@ This section lists out all of the lints, grouped by their default lint levels. -You can also see this list by running `rustc -W help`. \ No newline at end of file +You can also see this list by running `rustc -W help`. diff --git a/src/doc/rustc/src/what-is-rustc.md b/src/doc/rustc/src/what-is-rustc.md index 9dcc9f7daa9ff..39a05cfe20534 100644 --- a/src/doc/rustc/src/what-is-rustc.md +++ b/src/doc/rustc/src/what-is-rustc.md @@ -39,7 +39,7 @@ $ .\hello.exe # on Windows Note that we only ever pass `rustc` the *crate root*, not every file we wish to compile. For example, if we had a `main.rs` that looked like this: -```rust,ignore +```rust,ignore (needs-multiple-files) mod foo; fn main() { @@ -49,7 +49,7 @@ fn main() { And a `foo.rs` that had this: -```rust,ignore +```rust,no_run pub fn hello() { println!("Hello, world!"); } diff --git a/src/doc/rustdoc/src/advanced-features.md b/src/doc/rustdoc/src/advanced-features.md index 5128ff13b7a79..990a6b00d18d0 100644 --- a/src/doc/rustdoc/src/advanced-features.md +++ b/src/doc/rustdoc/src/advanced-features.md @@ -47,8 +47,7 @@ all type errors and name resolution errors with function bodies. Note that this work for anything outside a function body: since Rustdoc documents your types, it has to know what those types are! For example, this code will work regardless of the platform: - -```ignore +```rust,ignore (platform-specific) pub fn f() { use std::os::windows::ffi::OsStrExt; } @@ -56,7 +55,7 @@ pub fn f() { but this will not, because the unknown type is part of the function signature: -```ignore +```rust,ignore (platform-specific) pub fn f() -> std::os::windows::ffi::EncodeWide<'static> { unimplemented!() } diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index 387d86189b08f..8e3c622818954 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -5,12 +5,13 @@ that examples within your documentation are up to date and working. The basic idea is this: -```ignore +```rust,no_run /// # Examples /// /// ``` /// let x = 5; /// ``` +# fn f() {} ``` The triple backticks start and end code blocks. If this were in a file named `foo.rs`, @@ -78,12 +79,13 @@ Sometimes, you need some setup code, or other things that would distract from your example, but are important to make the tests work. Consider an example block that looks like this: -```ignore +```rust,no_run /// ``` /// /// Some documentation. /// # fn foo() {} // this function will be hidden /// println!("Hello, World!"); /// ``` +# fn f() {} ``` It will render like this: @@ -196,12 +198,13 @@ When writing an example, it is rarely useful to include a complete error handling, as it would add significant amounts of boilerplate code. Instead, you may want the following: -```ignore +```rust,no_run /// ``` /// use std::io; /// let mut input = String::new(); /// io::stdin().read_line(&mut input)?; /// ``` +# fn f() {} ``` The problem is that `?` returns a `Result` and test functions don't @@ -210,7 +213,7 @@ return anything, so this will give a mismatched types error. You can get around this limitation by manually adding a `main` that returns `Result`, because `Result` implements the `Termination` trait: -```ignore +```rust,no_run /// A doc test using ? /// /// ``` @@ -222,12 +225,13 @@ You can get around this limitation by manually adding a `main` that returns /// Ok(()) /// } /// ``` +# fn f() {} ``` Together with the `# ` from the section above, you arrive at a solution that appears to the reader as the initial idea but works with doc tests: -```ignore +```rust,no_run /// ``` /// use std::io; /// # fn main() -> io::Result<()> { @@ -236,18 +240,20 @@ appears to the reader as the initial idea but works with doc tests: /// # Ok(()) /// # } /// ``` +# fn f() {} ``` As of version 1.34.0, one can also omit the `fn main()`, but you will have to disambiguate the error type: -```ignore +```rust,no_run /// ``` /// use std::io; /// let mut input = String::new(); /// io::stdin().read_line(&mut input)?; /// # Ok::<(), io::Error>(()) /// ``` +# fn f() {} ``` This is an unfortunate consequence of the `?` operator adding an implicit @@ -417,7 +423,7 @@ Another possible use of `#[cfg(doctest)]` is to test doctests that are included without including it in your main documentation. For example, you could write this into your `lib.rs` to test your README as part of your doctests: -```rust,ignore +```rust,no_run #![feature(external_doc)] #[doc(include = "../README.md")] diff --git a/src/doc/rustdoc/src/how-to-write-documentation.md b/src/doc/rustdoc/src/how-to-write-documentation.md index 41736e5ee3a7e..0a7dedb25a124 100644 --- a/src/doc/rustdoc/src/how-to-write-documentation.md +++ b/src/doc/rustdoc/src/how-to-write-documentation.md @@ -7,7 +7,7 @@ implementation detail, or leaves readers with unanswered questions. There are a few tenets to Rust documentation that can help guide anyone through the process of documenting libraries so that everyone has an ample opportunity -to use the code. +to use the code. This chapter covers not only how to write documentation but specifically how to write **good** documentation. It is important to be as clear @@ -19,31 +19,31 @@ then it should be documented. Documenting a crate should begin with front-page documentation. As an example, the [`hashbrown`] crate level documentation summarizes the role of -the crate, provides links to explain technical details, and explains why you -would want to use the crate. +the crate, provides links to explain technical details, and explains why you +would want to use the crate. -After introducing the crate, it is important that the front-page gives +After introducing the crate, it is important that the front-page gives an example of how to use the crate in a real world setting. Stick to the library's role in the example, but do so without shortcuts to benefit users who -may copy and paste the example to get started. +may copy and paste the example to get started. [`futures`] uses inline comments to explain line by line -the complexities of using a [`Future`], because a person's first exposure to +the complexities of using a [`Future`], because a person's first exposure to rust's [`Future`] may be this example. -The [`backtrace`] documentation walks through the whole process, explaining +The [`backtrace`] documentation walks through the whole process, explaining changes made to the `Cargo.toml` file, passing command line arguments to the -compiler, and shows a quick example of backtrace in the wild. +compiler, and shows a quick example of backtrace in the wild. Finally, the front-page can eventually become a comprehensive reference how to use a crate, like [`regex`]. In this front page, all -requirements are outlined, the edge cases shown, and practical examples +requirements are outlined, the edge cases shown, and practical examples provided. The front page goes on to show how to use regular expressions then concludes with crate features. Don't worry about comparing your crate, which is just beginning, to other more developed crates. To get the documentation to something more polished, start -incrementally and put in an introduction, example, and features. Rome was not +incrementally and put in an introduction, example, and features. Rome was not built in a day! The first lines within the `lib.rs` will compose the front-page, and they @@ -51,7 +51,7 @@ use a different convention than the rest of the rustdocs. Lines should start with `//!` which indicate module-level or crate-level documentation. Here's a quick example of the difference: -```rust,ignore +```rust,no_run //! Fast and easy queue abstraction. //! //! Provides an abstraction over a queue. When the abstraction is used @@ -64,13 +64,13 @@ Here's a quick example of the difference: /// This module makes it easy. pub mod easy { - /// Use the abstract function to do this specific thing. - pub fn abstract() {} + /// Use the abstraction function to do this specific thing. + pub fn abstraction() {} } ``` -Ideally, this first line of documentation is a sentence without highly +Ideally, this first line of documentation is a sentence without highly technical details, but with a good description of where this crate fits within the rust ecosystem. Users should know whether this crate meets their use case after reading this line. @@ -95,7 +95,7 @@ It is recommended that each item's documentation follows this basic structure: This basic structure should be straightforward to follow when writing your documentation; while you might think that a code example is trivial, -the examples are really important because they can help users understand +the examples are really important because they can help users understand what an item is, how it is used, and for what purpose it exists. Let's see an example coming from the [standard library] by taking a look at the @@ -133,7 +133,7 @@ for argument in env::args() { [`args_os`]: ./fn.args_os.html `````` -Everything before the first empty line will be reused to describe the component +Everything before the first empty line will be reused to describe the component in searches and module overviews. For example, the function `std::env::args()` above will be shown on the [`std::env`] module documentation. It is good practice to keep the summary to one line: concise writing is a goal of good @@ -225,7 +225,7 @@ details on the exact syntax supported. [commonmark markdown specification]: https://commonmark.org/ [commonmark quick reference]: https://commonmark.org/help/ [env::args]: https://doc.rust-lang.org/stable/std/env/fn.args.html -[`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html +[`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html [`futures`]: https://docs.rs/futures/0.3.5/futures/ [`hashbrown`]: https://docs.rs/hashbrown/0.8.2/hashbrown/ [`regex`]: https://docs.rs/regex/1.3.9/regex/ diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index 41292b3d83841..cce3623dc8f49 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -3,10 +3,11 @@ `rustdoc` provides lints to help you writing and testing your documentation. You can use them like any other lints by doing this: -```rust,ignore +```rust #![allow(missing_docs)] // allows the lint, no diagnostics will be reported #![warn(missing_docs)] // warn if there are missing docs #![deny(missing_docs)] // error if there are missing docs +# //! Crate docs. ``` Here is the list of the lints provided by `rustdoc`: diff --git a/src/doc/rustdoc/src/passes.md b/src/doc/rustdoc/src/passes.md index 081e477de8010..140b832f19a54 100644 --- a/src/doc/rustdoc/src/passes.md +++ b/src/doc/rustdoc/src/passes.md @@ -32,8 +32,9 @@ Without this pass, these items will remain in the output. When you write a doc comment like this: -```rust,ignore +```rust,no_run /// This is a documentation comment. +# fn f() {} ``` There's a space between the `///` and that `T`. That spacing isn't intended @@ -52,9 +53,10 @@ documentation string. For example: -```rust,ignore +```rust,no_run #[doc = "This is the first line."] #[doc = "This is the second line."] +# fn f() {} ``` Gets collapsed into a single doc string of @@ -68,7 +70,7 @@ This is the second line. This removes documentation for any non-public items, so for example: -```rust,ignore +```rust,no_run /// These are private docs. struct Private; diff --git a/src/doc/rustdoc/src/references.md b/src/doc/rustdoc/src/references.md index 1e050e321d2e3..b0e2437392c95 100644 --- a/src/doc/rustdoc/src/references.md +++ b/src/doc/rustdoc/src/references.md @@ -3,7 +3,7 @@ There are many great `rustdoc` references out there. If you know of other great resources, please submit a pull request! -## Official +## Official - [Learn Rust] - [Rust By Example] @@ -11,7 +11,7 @@ If you know of other great resources, please submit a pull request! - [RFC 1574: More API Documentation Conventions] - [RFC 1946: Intra Rustdoc Links] -## Community +## Community - [API Guidelines] - [Github tagged RFCs] - [Github tagged issues] @@ -28,4 +28,4 @@ If you know of other great resources, please submit a pull request! [RFC 1946: Intra Rustdoc Links]: https://rust-lang.github.io/rfcs/1946-intra-rustdoc-links.html [RFC (stalled) front page styleguide]: https://github.com/rust-lang/rfcs/pull/1687 [Rust By Example]: https://doc.rust-lang.org/stable/rust-by-example/meta/doc.html -[Rust Reference]: https://doc.rust-lang.org/stable/reference/comments.html#doc-comments \ No newline at end of file +[Rust Reference]: https://doc.rust-lang.org/stable/reference/comments.html#doc-comments diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index ef143c8727ee9..52f2a3728fabb 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -7,9 +7,10 @@ The most basic function of `#[doc]` is to handle the actual documentation text. That is, `///` is syntax sugar for `#[doc]`. This means that these two are the same: -```rust,ignore +```rust,no_run /// This is a doc comment. #[doc = " This is a doc comment."] +# fn f() {} ``` (Note the leading space in the attribute version.) @@ -18,16 +19,18 @@ In most cases, `///` is easier to use than `#[doc]`. One case where the latter i when generating documentation in macros; the `collapse-docs` pass will combine multiple `#[doc]` attributes into a single doc comment, letting you generate code like this: -```rust,ignore +```rust,no_run #[doc = "This is"] #[doc = " a "] #[doc = "doc comment"] +# fn f() {} ``` Which can feel more flexible. Note that this would generate this: -```rust,ignore +```rust,no_run #[doc = "This is\n a \ndoc comment"] +# fn f() {} ``` but given that docs are rendered via Markdown, it will remove these newlines. @@ -45,7 +48,7 @@ These options control how the docs look at a crate level. This form of the `doc` attribute lets you control the favicon of your docs. -```rust,ignore +```rust,no_run #![doc(html_favicon_url = "https://example.com/favicon.ico")] ``` @@ -59,7 +62,7 @@ If you don't use this attribute, there will be no favicon. This form of the `doc` attribute lets you control the logo in the upper left hand side of the docs. -```rust,ignore +```rust,no_run #![doc(html_logo_url = "https://example.com/logo.jpg")] ``` @@ -73,7 +76,7 @@ If you don't use this attribute, there will be no logo. This form of the `doc` attribute lets you control where the "run" buttons on your documentation examples make requests to. -```rust,ignore +```rust,no_run #![doc(html_playground_url = "https://playground.example.com/")] ``` @@ -88,7 +91,7 @@ When a feature is unstable, an issue number for tracking the feature must be given. `rustdoc` uses this number, plus the base URL given here, to link to the tracking issue. -```rust,ignore +```rust,no_run #![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] ``` @@ -103,7 +106,7 @@ available. If that is not available, then it will use the `html_root_url` value in the extern crate if it is available. If that is not available, then the extern items will not be linked. -```rust,ignore +```rust,no_run #![doc(html_root_url = "https://docs.rs/serde/1.0")] ``` @@ -112,7 +115,7 @@ the extern items will not be linked. By default, `rustdoc` will include the source code of your program, with links to it in the docs. But if you include this: -```rust,ignore +```rust,no_run #![doc(html_no_source)] ``` @@ -123,7 +126,7 @@ it will not. By default, `rustdoc` will automatically add a line with `extern crate my_crate;` into each doctest. But if you include this: -```rust,ignore +```rust,no_run #![doc(test(no_crate_inject))] ``` @@ -134,7 +137,7 @@ it will not. This form of the `doc` attribute allows you to add arbitrary attributes to all your doctests. For example, if you want your doctests to fail if they produce any warnings, you could add this: -```rust,ignore +```rust,no_run #![doc(test(attr(deny(warnings))))] ``` @@ -148,7 +151,7 @@ they are documented. These attributes are used on `use` statements, and control where the documentation shows up. For example, consider this Rust code: -```rust,ignore +```rust,no_run pub use bar::Bar; /// bar docs @@ -156,6 +159,7 @@ pub mod bar { /// the docs for Bar pub struct Bar; } +# fn main() {} ``` The documentation will generate a "Re-exports" section, and say `pub use bar::Bar;`, where @@ -163,9 +167,11 @@ The documentation will generate a "Re-exports" section, and say `pub use bar::Ba If we change the `use` line like this: -```rust,ignore +```rust,no_run #[doc(inline)] pub use bar::Bar; +# pub mod bar { pub struct Bar; } +# fn main() {} ``` Instead, `Bar` will appear in a `Structs` section, just like `Bar` was defined at the @@ -173,7 +179,7 @@ top level, rather than `pub use`'d. Let's change our original example, by making `bar` private: -```rust,ignore +```rust,no_run pub use bar::Bar; /// bar docs @@ -181,6 +187,7 @@ mod bar { /// the docs for Bar pub struct Bar; } +# fn main() {} ``` Here, because `bar` is not public, `Bar` wouldn't have its own page, so there's nowhere @@ -188,7 +195,7 @@ to link to. `rustdoc` will inline these definitions, and so we end up in the sam as the `#[doc(inline)]` above; `Bar` is in a `Structs` section, as if it were defined at the top level. If we add the `no_inline` form of the attribute: -```rust,ignore +```rust,no_run #[doc(no_inline)] pub use bar::Bar; @@ -197,6 +204,7 @@ mod bar { /// the docs for Bar pub struct Bar; } +# fn main() {} ``` Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere. diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md index 32dc1e02bb3db..7a444d77c09d1 100644 --- a/src/doc/rustdoc/src/what-is-rustdoc.md +++ b/src/doc/rustdoc/src/what-is-rustdoc.md @@ -32,7 +32,7 @@ $ rustdoc src/lib.rs This will create a new directory, `doc`, with a website inside! In our case, the main page is located in `doc/lib/index.html`. If you open that up in a web browser, you will see a page with a search bar, and "Crate lib" at the -top, with no contents. +top, with no contents. ## Configuring rustdoc @@ -89,18 +89,18 @@ dependency=/docs/target/debug/deps You can see this with `cargo doc --verbose`. It generates the correct `--crate-name` for us, as well as pointing to -`src/lib.rs`. But what about those other arguments? - - `-o` controls the *o*utput of our docs. Instead of a top-level - `doc` directory, notice that Cargo puts generated documentation under +`src/lib.rs`. But what about those other arguments? + - `-o` controls the *o*utput of our docs. Instead of a top-level + `doc` directory, notice that Cargo puts generated documentation under `target`. That is the idiomatic place for generated files in Cargo projects. - - `-L` flag helps rustdoc find the dependencies your code relies on. + - `-L` flag helps rustdoc find the dependencies your code relies on. If our project used dependencies, we would get documentation for them as well! ## Outer and inner documentation The `///` syntax is used to document the item present after it. That's why it is called an outer documentation. -There is another syntax: `//!`, which is used to document the +There is another syntax: `//!`, which is used to document the item it is present inside. It is called an inner documentation. It is often used when documenting the entire crate, because nothing comes before it: it is the root of the crate. diff --git a/src/doc/rustdoc/src/what-to-include.md b/src/doc/rustdoc/src/what-to-include.md index 878c75baae727..9683f519be121 100644 --- a/src/doc/rustdoc/src/what-to-include.md +++ b/src/doc/rustdoc/src/what-to-include.md @@ -38,10 +38,10 @@ warning: 1 warning emitted As a library author, adding the lint `#![deny(missing_docs)]` is a great way to ensure the project does not drift away from being documented well, and -`#![warn(missing_docs)]` is a good way to move towards comprehensive +`#![warn(missing_docs)]` is a good way to move towards comprehensive documentation. In addition to docs, `#![deny(missing_doc_code_examples)]` ensures each function contains a usage example. In our example above, the -warning is resolved by adding crate level documentation. +warning is resolved by adding crate level documentation. There are more lints in the upcoming chapter [Lints][rustdoc-lints]. @@ -58,7 +58,7 @@ users to figure out how to put the `async` code into their own runtime. It is preferred that `unwrap()` not be used inside an example, and some of the error handling components be hidden if they make the example too difficult to -follow. +follow. ``````text /// Example @@ -66,9 +66,9 @@ follow. /// let fourtytwo = "42".parse::()?; /// println!("{} + 10 = {}", fourtytwo, fourtytwo+10); /// ``` -`````` +`````` -When rustdoc wraps that in a main function, it will fail to compile because the +When rustdoc wraps that in a main function, it will fail to compile because the `ParseIntError` trait is not implemented. In order to help both your audience and your test suite, this example needs some additional code: @@ -81,17 +81,17 @@ and your test suite, this example needs some additional code: /// # Ok(()) /// # } /// ``` -`````` +`````` The example is the same on the doc page, but has that extra information -available to anyone trying to use your crate. More about tests in the -upcoming [Documentation tests] chapter. +available to anyone trying to use your crate. More about tests in the +upcoming [Documentation tests] chapter. ## What to Exclude Certain parts of your public interface may be included by default in the output of rustdoc. The attribute `#[doc(hidden)]` can hide implementation details -to encourage idiomatic use of the crate. +to encourage idiomatic use of the crate. For example, an internal `macro!` that makes the crate easier to implement can become a footgun for users when it appears in the public documentation. An @@ -101,11 +101,11 @@ detailed in the [API Guidelines]. ## Customizing the output It is possible to pass a custom css file to `rustdoc` and style the -documentation. +documentation. ```bash rustdoc --extend-css custom.css src/lib.rs -``` +``` A good example of using this feature to create a dark theme is documented [on this blog]. Just remember, dark theme is already included in the rustdoc output @@ -122,4 +122,4 @@ Here is an example of a new theme, [Ayu]. [API Guidelines]: https://rust-lang.github.io/api-guidelines/documentation.html#rustdoc-does-not-show-unhelpful-implementation-details-c-hidden [Documentation tests]: documentation-tests.md [on this blog]: https://blog.guillaume-gomez.fr/articles/2016-09-16+Generating+doc+with+rustdoc+and+a+custom+theme -[rustdoc-lints]: lints.md \ No newline at end of file +[rustdoc-lints]: lints.md diff --git a/src/doc/unstable-book/src/compiler-flags/codegen-backend.md b/src/doc/unstable-book/src/compiler-flags/codegen-backend.md index 878c894a6ca70..3c0cd32fae172 100644 --- a/src/doc/unstable-book/src/compiler-flags/codegen-backend.md +++ b/src/doc/unstable-book/src/compiler-flags/codegen-backend.md @@ -15,7 +15,7 @@ named `__rustc_codegen_backend` with a signature of `fn() -> Box(_t: T) { } fn main() { // works must_be_valid( MaybeValid(True) ); - + // compiler error - trait bound not satisfied // must_be_valid( MaybeValid(False) ); } @@ -80,7 +80,7 @@ where Explicit impls may be either positive or negative. They take the form: -```rust,ignore +```rust,ignore (partial-example) impl<...> AutoTrait for StructName<..> { } impl<...> !AutoTrait for StructName<..> { } ``` @@ -104,4 +104,3 @@ Auto traits cannot have any trait items, such as methods or associated types. Th ## Supertraits Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile. - diff --git a/src/doc/unstable-book/src/language-features/custom-test-frameworks.md b/src/doc/unstable-book/src/language-features/custom-test-frameworks.md index 3990b6ad2f080..53ecac9314d79 100644 --- a/src/doc/unstable-book/src/language-features/custom-test-frameworks.md +++ b/src/doc/unstable-book/src/language-features/custom-test-frameworks.md @@ -30,4 +30,3 @@ const WILL_PASS: i32 = 0; #[test_case] const WILL_FAIL: i32 = 4; ``` - diff --git a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md index 53e01091f754e..5f3f1b4dd8a31 100644 --- a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md +++ b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md @@ -42,4 +42,3 @@ struct Bar { x: T, } ``` - diff --git a/src/doc/unstable-book/src/language-features/intrinsics.md b/src/doc/unstable-book/src/language-features/intrinsics.md index bc35c2a030533..a0fb4e743d3f2 100644 --- a/src/doc/unstable-book/src/language-features/intrinsics.md +++ b/src/doc/unstable-book/src/language-features/intrinsics.md @@ -27,4 +27,3 @@ extern "rust-intrinsic" { ``` As with any other FFI functions, these are always `unsafe` to call. - diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index 20c7d7dcec8d6..d44c841d48c66 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -15,8 +15,8 @@ For example, `Box` pointers require two lang items, one for allocation and one for deallocation. A freestanding program that uses the `Box` sugar for dynamic allocations via `malloc` and `free`: -```rust,ignore -#![feature(lang_items, box_syntax, start, libc, core_intrinsics)] +```rust,ignore (libc-is-finicky) +#![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)] #![no_std] use core::intrinsics; use core::panic::PanicInfo; @@ -105,8 +105,8 @@ or overriding the default shim for the C `main` function with your own. The function marked `#[start]` is passed the command line parameters in the same format as C: -```rust,ignore -#![feature(lang_items, core_intrinsics)] +```rust,ignore (libc-is-finicky) +#![feature(lang_items, core_intrinsics, rustc_private)] #![feature(start)] #![no_std] use core::intrinsics; @@ -141,8 +141,8 @@ with `#![no_main]` and then create the appropriate symbol with the correct ABI and the correct name, which requires overriding the compiler's name mangling too: -```rust,ignore -#![feature(lang_items, core_intrinsics)] +```rust,ignore (libc-is-finicky) +#![feature(lang_items, core_intrinsics, rustc_private)] #![feature(start)] #![no_std] #![no_main] diff --git a/src/doc/unstable-book/src/language-features/non-ascii-idents.md b/src/doc/unstable-book/src/language-features/non-ascii-idents.md index 22dae0c89a6ff..847f25ecab132 100644 --- a/src/doc/unstable-book/src/language-features/non-ascii-idents.md +++ b/src/doc/unstable-book/src/language-features/non-ascii-idents.md @@ -19,10 +19,10 @@ const Π: f64 = 3.14f64; ## Changes to the language reference -> **Lexer:** -> IDENTIFIER : ->       XID_start XID_continue\* ->    | `_` XID_continue+ +> **Lexer:**\ +> IDENTIFIER :\ +>       XID_start XID_continue\*\ +>    | `_` XID_continue+ An identifier is any nonempty Unicode string of the following form: diff --git a/src/doc/unstable-book/src/language-features/or-patterns.md b/src/doc/unstable-book/src/language-features/or-patterns.md index 8ebacb44d37cc..55c31add26d77 100644 --- a/src/doc/unstable-book/src/language-features/or-patterns.md +++ b/src/doc/unstable-book/src/language-features/or-patterns.md @@ -11,7 +11,7 @@ a pattern, for example, `Some(A(0) | B(1 | 2))` becomes a valid pattern. ## Examples -```rust,ignore +```rust,no_run #![feature(or_patterns)] pub enum Foo { diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 3835113152762..44308bdfba6c3 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -38,7 +38,7 @@ additional checks for code style, safety, etc. Now let's write a plugin [`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs) that warns about any item named `lintme`. -```rust,ignore +```rust,ignore (requires-stage-2) #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] @@ -77,7 +77,7 @@ pub fn plugin_registrar(reg: &mut Registry) { Then code like -```rust,ignore +```rust,ignore (requires-plugin) #![feature(plugin)] #![plugin(lint_plugin_test)] diff --git a/src/doc/unstable-book/src/language-features/rustc-attrs.md b/src/doc/unstable-book/src/language-features/rustc-attrs.md index 1d9409ee9e438..c67b806f06af4 100644 --- a/src/doc/unstable-book/src/language-features/rustc-attrs.md +++ b/src/doc/unstable-book/src/language-features/rustc-attrs.md @@ -18,7 +18,7 @@ Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`, ## Examples -```rust,ignore +```rust,compile_fail #![feature(rustc_attrs)] #[rustc_layout(abi, size)] diff --git a/src/doc/unstable-book/src/language-features/unboxed-closures.md b/src/doc/unstable-book/src/language-features/unboxed-closures.md index 71003fba00ba2..e4113d72d0914 100644 --- a/src/doc/unstable-book/src/language-features/unboxed-closures.md +++ b/src/doc/unstable-book/src/language-features/unboxed-closures.md @@ -9,7 +9,7 @@ See Also: [`fn_traits`](../library-features/fn-traits.md) ---- The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI, -required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have +required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have exactly one (non self) argument, a tuple representing the argument list. [`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md index d716b1d51dcf7..d5b01a3d6168e 100644 --- a/src/doc/unstable-book/src/language-features/unsized-locals.md +++ b/src/doc/unstable-book/src/language-features/unsized-locals.md @@ -30,7 +30,7 @@ fn foo(_: dyn Any) {} The RFC still forbids the following unsized expressions: -```rust,ignore +```rust,compile_fail #![feature(unsized_locals)] use std::any::Any; @@ -124,7 +124,7 @@ One of the objectives of this feature is to allow `Box`. The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`. -```rust,ignore +```rust,ignore (not-yet-implemented) #![feature(unsized_locals)] fn mergesort(a: &mut [T]) { diff --git a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md b/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md index 731d2acbfdd5a..310c8d962948a 100644 --- a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md +++ b/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md @@ -8,7 +8,7 @@ The tracking issue for this feature is: [#42877] This is a part of [RFC0401]. According to the RFC, there should be an implementation like this: -```rust,ignore +```rust,ignore (partial-example) impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized {} ``` diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index ccdd862869961..c0e23b834d150 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -405,7 +405,7 @@ When required, options are specified as the final argument. The following ABNF specifies the general syntax: -```ignore +```text dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout" reg_spec := / "" operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_" diff --git a/src/doc/unstable-book/src/library-features/concat-idents.md b/src/doc/unstable-book/src/library-features/concat-idents.md index ecfd34a22e5cc..73f6cfa21787e 100644 --- a/src/doc/unstable-book/src/library-features/concat-idents.md +++ b/src/doc/unstable-book/src/library-features/concat-idents.md @@ -19,4 +19,4 @@ fn main() { let f = concat_idents!(foo, bar); assert_eq!(f(), 23); } -``` \ No newline at end of file +``` diff --git a/src/doc/unstable-book/src/library-features/global-asm.md b/src/doc/unstable-book/src/library-features/global-asm.md index bc55fe80fa64c..c5ff68ec7d39a 100644 --- a/src/doc/unstable-book/src/library-features/global-asm.md +++ b/src/doc/unstable-book/src/library-features/global-asm.md @@ -24,15 +24,15 @@ conventions of the assembler in your toolchain. A simple usage looks like this: -```rust,ignore +```rust,ignore (requires-external-file) # #![feature(global_asm)] -# you also need relevant target_arch cfgs +# // you also need relevant target_arch cfgs global_asm!(include_str!("something_neato.s")); ``` And a more complicated usage looks like this: -```rust,ignore +```rust,no_run # #![feature(global_asm)] # #![cfg(any(target_arch = "x86", target_arch = "x86_64"))] diff --git a/src/doc/unstable-book/src/library-features/llvm-asm.md b/src/doc/unstable-book/src/library-features/llvm-asm.md index a2f029db29165..07fc16261d820 100644 --- a/src/doc/unstable-book/src/library-features/llvm-asm.md +++ b/src/doc/unstable-book/src/library-features/llvm-asm.md @@ -10,7 +10,7 @@ For extremely low-level manipulations and performance reasons, one might wish to control the CPU directly. Rust supports using inline assembly to do this via the `llvm_asm!` macro. -```rust,ignore +```rust,ignore (pseudo-code) llvm_asm!(assembly template : output operands : input operands diff --git a/src/doc/unstable-book/src/library-features/test.md b/src/doc/unstable-book/src/library-features/test.md index 6b4a3a677db61..c99584e5fb397 100644 --- a/src/doc/unstable-book/src/library-features/test.md +++ b/src/doc/unstable-book/src/library-features/test.md @@ -9,7 +9,7 @@ most widely used part of the `test` crate are benchmark tests, which can test the performance of your code. Let's make our `src/lib.rs` look like this (comments elided): -```rust,ignore +```rust,no_run #![feature(test)] extern crate test; @@ -83,7 +83,7 @@ the benchmark is no longer benchmarking what one expects. For example, the compiler might recognize that some calculation has no external effects and remove it entirely. -```rust,ignore +```rust,no_run #![feature(test)] extern crate test; diff --git a/src/doc/unstable-book/src/library-features/try-trait.md b/src/doc/unstable-book/src/library-features/try-trait.md index 0c07329025bca..022640067bd11 100644 --- a/src/doc/unstable-book/src/library-features/try-trait.md +++ b/src/doc/unstable-book/src/library-features/try-trait.md @@ -16,7 +16,7 @@ macro on `Poll`, among other things. Here's an example implementation of the trait: -```rust,ignore +```rust,ignore (cannot-reimpl-Try) /// A distinct type to represent the `None` value of an `Option`. /// /// This enables using the `?` operator on `Option`; it's rarely useful alone. diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 6697fbd1be2de..9f68c55ec975c 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -18,6 +18,8 @@ use std::path::Path; +/// Error code markdown is restricted to 80 columns because they can be +/// displayed on the console with --example. const ERROR_CODE_COLS: usize = 80; const COLS: usize = 100; @@ -55,9 +57,9 @@ enum LIUState { /// Lines of this form are allowed to be overlength, because Markdown /// offers no way to split a line in the middle of a URL, and the lengths /// of URLs to external references are beyond our control. -fn line_is_url(columns: usize, line: &str) -> bool { - // more basic check for error_codes.rs, to avoid complexity in implementing two state machines - if columns == ERROR_CODE_COLS { +fn line_is_url(is_error_code: bool, columns: usize, line: &str) -> bool { + // more basic check for markdown, to avoid complexity in implementing two state machines + if is_error_code { return line.starts_with('[') && line.contains("]:") && line.contains("http"); } @@ -93,8 +95,13 @@ fn line_is_url(columns: usize, line: &str) -> bool { /// Returns `true` if `line` is allowed to be longer than the normal limit. /// Currently there is only one exception, for long URLs, but more /// may be added in the future. -fn long_line_is_ok(max_columns: usize, line: &str) -> bool { - if line_is_url(max_columns, line) { +fn long_line_is_ok(extension: &str, is_error_code: bool, max_columns: usize, line: &str) -> bool { + if extension != "md" || is_error_code { + if line_is_url(is_error_code, max_columns, line) { + return true; + } + } else if extension == "md" { + // non-error code markdown is allowed to be any length return true; } @@ -158,8 +165,36 @@ pub fn is_in(full_path: &Path, parent_folder_to_find: &str, folder_to_find: &str } } +fn skip_markdown_path(path: &Path) -> bool { + // These aren't ready for tidy. + const SKIP_MD: &[&str] = &[ + "src/doc/edition-guide", + "src/doc/embedded-book", + "src/doc/nomicon", + "src/doc/reference", + "src/doc/rust-by-example", + "src/doc/rustc-dev-guide", + ]; + SKIP_MD.iter().any(|p| path.ends_with(p)) +} + +fn is_unexplained_ignore(extension: &str, line: &str) -> bool { + if !line.ends_with("```ignore") && !line.ends_with("```rust,ignore") { + return false; + } + if extension == "md" && line.trim().starts_with("//") { + // Markdown examples may include doc comments with ignore inside a + // code block. + return false; + } + true +} + pub fn check(path: &Path, bad: &mut bool) { - super::walk(path, &mut super::filter_dirs, &mut |entry, contents| { + fn skip(path: &Path) -> bool { + super::filter_dirs(path) || skip_markdown_path(path) + } + super::walk(path, &mut skip, &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css"]; @@ -176,13 +211,6 @@ pub fn check(path: &Path, bad: &mut bool) { a.ends_with("src/doc/book") }); - if filename.ends_with(".md") - && file.parent().unwrap().file_name().unwrap().to_string_lossy() != "error_codes" - { - // We don't want to check all ".md" files (almost of of them aren't compliant - // currently), just the long error code explanation ones. - return; - } if is_style_file && !is_in(file, "src", "librustdoc") { // We only check CSS files in rustdoc. return; @@ -192,11 +220,10 @@ pub fn check(path: &Path, bad: &mut bool) { tidy_error!(bad, "{}: empty file", file.display()); } - let max_columns = if filename == "error_codes.rs" || filename.ends_with(".md") { - ERROR_CODE_COLS - } else { - COLS - }; + let extension = file.extension().unwrap().to_string_lossy(); + let is_error_code = extension == "md" && is_in(file, "src", "error_codes"); + + let max_columns = if is_error_code { ERROR_CODE_COLS } else { COLS }; let can_contain = contents.contains("// ignore-tidy-") || contents.contains("# ignore-tidy-") @@ -227,7 +254,7 @@ pub fn check(path: &Path, bad: &mut bool) { }; if !under_rustfmt && line.chars().count() > max_columns - && !long_line_is_ok(max_columns, line) + && !long_line_is_ok(&extension, is_error_code, max_columns, line) { suppressible_tidy_err!( err, @@ -280,7 +307,7 @@ pub fn check(path: &Path, bad: &mut bool) { "copyright notices attributed to the Rust Project Developers are deprecated" ); } - if line.ends_with("```ignore") || line.ends_with("```rust,ignore") { + if is_unexplained_ignore(&extension, line) { err(UNEXPLAINED_IGNORE_DOCTEST_INFO); } if filename.ends_with(".cpp") && line.contains("llvm_unreachable") { From dc7746f3343429924531daa6d692eba94b414e55 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 25 Jan 2021 18:15:34 -0800 Subject: [PATCH 05/10] Elaborate on rustdoc example reason for being ignored. --- src/doc/rustdoc/src/advanced-features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustdoc/src/advanced-features.md b/src/doc/rustdoc/src/advanced-features.md index 990a6b00d18d0..abdc2e4025d0e 100644 --- a/src/doc/rustdoc/src/advanced-features.md +++ b/src/doc/rustdoc/src/advanced-features.md @@ -47,7 +47,7 @@ all type errors and name resolution errors with function bodies. Note that this work for anything outside a function body: since Rustdoc documents your types, it has to know what those types are! For example, this code will work regardless of the platform: -```rust,ignore (platform-specific) +```rust,ignore (platform-specific,rustdoc-specific-behavior) pub fn f() { use std::os::windows::ffi::OsStrExt; } @@ -55,7 +55,7 @@ pub fn f() { but this will not, because the unknown type is part of the function signature: -```rust,ignore (platform-specific) +```rust,ignore (platform-specific,rustdoc-specific-behavior) pub fn f() -> std::os::windows::ffi::EncodeWide<'static> { unimplemented!() } From 900648cfd68c246ab7774bee1126b770955e3e6b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 4 Feb 2021 09:41:15 -0800 Subject: [PATCH 06/10] Adjust global_asm doc test to work on all platforms. The cfg isn't actually necessary, since `--emit=metadata` does not actually do enough validation for it to fail on any platform. However, I feel a little more comfortable leaving it in. Unhide the feature flag, since I think that is important to display. --- src/doc/unstable-book/src/library-features/global-asm.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/global-asm.md b/src/doc/unstable-book/src/library-features/global-asm.md index c5ff68ec7d39a..ce1155a977cd0 100644 --- a/src/doc/unstable-book/src/library-features/global-asm.md +++ b/src/doc/unstable-book/src/library-features/global-asm.md @@ -25,7 +25,7 @@ conventions of the assembler in your toolchain. A simple usage looks like this: ```rust,ignore (requires-external-file) -# #![feature(global_asm)] +#![feature(global_asm)] # // you also need relevant target_arch cfgs global_asm!(include_str!("something_neato.s")); ``` @@ -33,8 +33,9 @@ global_asm!(include_str!("something_neato.s")); And a more complicated usage looks like this: ```rust,no_run -# #![feature(global_asm)] -# #![cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#![feature(global_asm)] +# #[cfg(any(target_arch="x86", target_arch="x86_64"))] +# mod x86 { pub mod sally { global_asm!(r#" @@ -64,6 +65,7 @@ pub mod harry { #[no_mangle] pub unsafe extern "C" fn quux() {} } +# } ``` You may use `global_asm!` multiple times, anywhere in your crate, in From ed6232927b5d2f198ec33f77f0eb597a9eb68aa8 Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 3 Feb 2021 21:29:00 -0800 Subject: [PATCH 07/10] typeck: Emit structured suggestions for tuple struct syntax And tuple variant syntax, but that didn't fit in the subject :) Now the fact that these are suggestions is exposed both to the layout engine and to IDEs and rustfix for automatic application. --- compiler/rustc_typeck/src/check/expr.rs | 23 ++++++++++++++--------- src/test/ui/issues/issue-4736.stderr | 2 +- src/test/ui/issues/issue-80607.stderr | 2 +- src/test/ui/numeric/numeric-fields.stderr | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 33b1c0bb2c97c..1a11aad1441ee 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1460,28 +1460,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); err.span_label(field.ident.span, "field does not exist"); - err.span_label( + err.span_suggestion( ty_span, + &format!( + "`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax", + adt = ty, + variant = variant.ident, + ), format!( - "`{adt}::{variant}` is a tuple {kind_name}, \ - use the appropriate syntax: `{adt}::{variant}(/* fields */)`", + "{adt}::{variant}(/* fields */)", adt = ty, variant = variant.ident, - kind_name = kind_name ), + Applicability::HasPlaceholders, ); } _ => { err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty)); err.span_label(field.ident.span, "field does not exist"); - err.span_label( + err.span_suggestion( ty_span, - format!( - "`{adt}` is a tuple {kind_name}, \ - use the appropriate syntax: `{adt}(/* fields */)`", + &format!( + "`{adt}` is a tuple {kind_name}, use the appropriate syntax", adt = ty, - kind_name = kind_name + kind_name = kind_name, ), + format!("{adt}(/* fields */)", adt = ty), + Applicability::HasPlaceholders, ); } }, diff --git a/src/test/ui/issues/issue-4736.stderr b/src/test/ui/issues/issue-4736.stderr index 257ec914a61ca..9be4eb1c7fddb 100644 --- a/src/test/ui/issues/issue-4736.stderr +++ b/src/test/ui/issues/issue-4736.stderr @@ -7,7 +7,7 @@ LL | struct NonCopyable(()); LL | let z = NonCopyable{ p: () }; | ----------- ^ field does not exist | | - | `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)` + | help: `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-80607.stderr b/src/test/ui/issues/issue-80607.stderr index 5375478942b18..22a660b4167d3 100644 --- a/src/test/ui/issues/issue-80607.stderr +++ b/src/test/ui/issues/issue-80607.stderr @@ -7,7 +7,7 @@ LL | V1(i32), LL | Enum::V1 { x } | -------- ^ field does not exist | | - | `Enum::V1` is a tuple variant, use the appropriate syntax: `Enum::V1(/* fields */)` + | help: `Enum::V1` is a tuple variant, use the appropriate syntax: `Enum::V1(/* fields */)` error: aborting due to previous error diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index 5202393f559c9..13b6cfae4ec47 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -7,7 +7,7 @@ LL | struct S(u8, u16); LL | let s = S{0b1: 10, 0: 11}; | - ^^^ field does not exist | | - | `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)` + | help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)` error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:7:17 From f0b8166870bd73a872642f090ae6b88e2bef922a Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Wed, 27 Jan 2021 13:21:02 +0100 Subject: [PATCH 08/10] BTreeMap: fix documentation of unstable public members --- library/alloc/src/collections/btree/map.rs | 32 ++++++++++++---------- library/alloc/src/collections/btree/set.rs | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 5554a448b5c59..003fd590e072b 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1117,21 +1117,23 @@ impl BTreeMap { right } - /// Creates an iterator which uses a closure to determine if an element should be removed. - /// - /// If the closure returns true, the element is removed from the map and yielded. - /// If the closure returns false, or panics, the element remains in the map and will not be - /// yielded. - /// - /// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of - /// whether you choose to keep or remove it. - /// - /// If the iterator is only partially consumed or not consumed at all, each of the remaining - /// elements will still be subjected to the closure and removed and dropped if it returns true. - /// - /// It is unspecified how many more elements will be subjected to the closure - /// if a panic occurs in the closure, or a panic occurs while dropping an element, - /// or if the `DrainFilter` value is leaked. + /// Creates an iterator that visits all elements (key-value pairs) in + /// ascending key order and uses a closure to determine if an element should + /// be removed. If the closure returns `true`, the element is removed from + /// the map and yielded. If the closure returns `false`, or panics, the + /// element remains in the map and will not be yielded. + /// + /// The iterator also lets you mutate the value of each element in the + /// closure, regardless of whether you choose to keep or remove it. + /// + /// If the iterator is only partially consumed or not consumed at all, each + /// of the remaining elements is still subjected to the closure, which may + /// change its value and, by returning `true`, have the element removed and + /// dropped. + /// + /// It is unspecified how many more elements will be subjected to the + /// closure if a panic occurs in the closure, or a panic occurs while + /// dropping an element, or if the `DrainFilter` value is leaked. /// /// # Examples /// diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index d39eb1fd4f955..e60e82c7875ef 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -652,7 +652,7 @@ impl BTreeSet { /// use std::collections::BTreeSet; /// /// let mut map = BTreeSet::new(); - /// assert_eq!(map.first(), None); + /// assert_eq!(map.last(), None); /// map.insert(1); /// assert_eq!(map.last(), Some(&1)); /// map.insert(2); From 9653b601b2c5ac554e6adedf98d2ac173eb61985 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 4 Feb 2021 18:10:33 -0500 Subject: [PATCH 09/10] Enable 'task list' markdown extension - Add documentation about task lists --- .../rustdoc/src/how-to-write-documentation.md | 20 +++++++++++++++++++ src/librustdoc/html/markdown.rs | 5 ++++- src/test/rustdoc/task-lists.rs | 13 ++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc/task-lists.rs diff --git a/src/doc/rustdoc/src/how-to-write-documentation.md b/src/doc/rustdoc/src/how-to-write-documentation.md index 41736e5ee3a7e..b3664cb9940a0 100644 --- a/src/doc/rustdoc/src/how-to-write-documentation.md +++ b/src/doc/rustdoc/src/how-to-write-documentation.md @@ -221,6 +221,25 @@ This example will render similarly to this: See the specification for the [GitHub Tables extension][tables] for more details on the exact syntax supported. +### Task lists + +Task lists can be used as a checklist of items that have been completed. +Example: + +```md +- [x] Complete task +- [ ] IncComplete task +``` + +This will render as + +
    +
  • +
  • +
+ +See the specification for the [task list extension] for more details. + [`backtrace`]: https://docs.rs/backtrace/0.3.50/backtrace/ [commonmark markdown specification]: https://commonmark.org/ [commonmark quick reference]: https://commonmark.org/help/ @@ -234,3 +253,4 @@ details on the exact syntax supported. [`std::env`]: https://doc.rust-lang.org/stable/std/env/index.html#functions [strikethrough]: https://github.github.com/gfm/#strikethrough-extension- [tables]: https://github.github.com/gfm/#tables-extension- +[task list extension]: https://github.github.com/gfm/#task-list-items-extension- diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index bdb92844f07ad..a81fd55f6f192 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -48,7 +48,10 @@ mod tests; /// Options for rendering Markdown in the main body of documentation. pub(crate) fn opts() -> Options { - Options::ENABLE_TABLES | Options::ENABLE_FOOTNOTES | Options::ENABLE_STRIKETHROUGH + Options::ENABLE_TABLES + | Options::ENABLE_FOOTNOTES + | Options::ENABLE_STRIKETHROUGH + | Options::ENABLE_TASKLISTS } /// A subset of [`opts()`] used for rendering summaries. diff --git a/src/test/rustdoc/task-lists.rs b/src/test/rustdoc/task-lists.rs new file mode 100644 index 0000000000000..c2e7dd60f225e --- /dev/null +++ b/src/test/rustdoc/task-lists.rs @@ -0,0 +1,13 @@ +// ignore-tidy-linelength +// FIXME: this doesn't test as much as I'd like; ideally it would have these query too: + // has task_lists/index.html '//li/input[@type="checkbox" and disabled]/following-sibling::text()' 'a' + // has task_lists/index.html '//li/input[@type="checkbox"]/following-sibling::text()' 'b' +// Unfortunately that requires LXML, because the built-in xml module doesn't support all of xpath. + +// @has task_lists/index.html '//ul/li/input[@type="checkbox"]' '' +// @has task_lists/index.html '//ul/li/input[@disabled]' '' +// @has task_lists/index.html '//ul/li' 'a' +// @has task_lists/index.html '//ul/li' 'b' +//! This tests 'task list' support, a common markdown extension. +//! - [ ] a +//! - [x] b From 243755a13e78ebe7a3bb5ba797dd3e2fd04dd2dd Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 6 Feb 2021 02:26:35 +0200 Subject: [PATCH 10/10] Add a test for escaping LLVMisms in inline asm We escape certain LLVM-specific features when passing the inline assembly string to the LLVM. Until now, however, there was no test making sure this behaviour stays intact. This commit adds such a test! --- src/test/codegen/asm-sanitize-llvm.rs | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/codegen/asm-sanitize-llvm.rs diff --git a/src/test/codegen/asm-sanitize-llvm.rs b/src/test/codegen/asm-sanitize-llvm.rs new file mode 100644 index 0000000000000..fe09caa697309 --- /dev/null +++ b/src/test/codegen/asm-sanitize-llvm.rs @@ -0,0 +1,32 @@ +// FIXME(nagisa): remove the flags here once all targets support `asm!`. +// compile-flags: --target x86_64-unknown-linux-gnu + +// Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't +// inadvertently rely on the LLVM-specific syntax and features. +#![no_core] +#![feature(no_core, lang_items, rustc_attrs)] +#![crate_type = "rlib"] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +pub unsafe fn we_escape_dollar_signs() { + // CHECK: call void asm sideeffect alignstack inteldialect "banana$$:" + asm!( + r"banana$:", + ) +} + +pub unsafe fn we_escape_escapes_too() { + // CHECK: call void asm sideeffect alignstack inteldialect "banana\{{(\\|5C)}}36:" + asm!( + r"banana\36:", + ) +}