diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 502e3de8c637d..98b5fcd3ee4f0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4515,7 +4515,7 @@ macro_rules! rev { )*} } -/// intra-sign conversions +// intra-sign conversions try_from_upper_bounded!(u16, u8); try_from_upper_bounded!(u32, u16, u8); try_from_upper_bounded!(u64, u32, u16, u8); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index b9db4523ce1d1..4fb8b7168b89d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -122,15 +122,15 @@ impl fmt::Display for HirId { // hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module mod item_local_id_inner { use rustc_data_structures::indexed_vec::Idx; - /// An `ItemLocalId` uniquely identifies something within a given "item-like", - /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no - /// guarantee that the numerical value of a given `ItemLocalId` corresponds to - /// the node's position within the owning item in any way, but there is a - /// guarantee that the `LocalItemId`s within an owner occupy a dense range of - /// integers starting at zero, so a mapping that maps all or most nodes within - /// an "item-like" to something else can be implement by a `Vec` instead of a - /// tree or hash map. newtype_index! { + /// An `ItemLocalId` uniquely identifies something within a given "item-like", + /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no + /// guarantee that the numerical value of a given `ItemLocalId` corresponds to + /// the node's position within the owning item in any way, but there is a + /// guarantee that the `LocalItemId`s within an owner occupy a dense range of + /// integers starting at zero, so a mapping that maps all or most nodes within + /// an "item-like" to something else can be implement by a `Vec` instead of a + /// tree or hash map. pub struct ItemLocalId { .. } } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 062742bca7608..93030c98f3559 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -132,25 +132,24 @@ pub enum ScopeData { Remainder(FirstStatementIndex) } -/// Represents a subscope of `block` for a binding that is introduced -/// by `block.stmts[first_statement_index]`. Such subscopes represent -/// a suffix of the block. Note that each subscope does not include -/// the initializer expression, if any, for the statement indexed by -/// `first_statement_index`. -/// -/// For example, given `{ let (a, b) = EXPR_1; let c = EXPR_2; ... }`: -/// -/// * The subscope with `first_statement_index == 0` is scope of both -/// `a` and `b`; it does not include EXPR_1, but does include -/// everything after that first `let`. (If you want a scope that -/// includes EXPR_1 as well, then do not use `Scope::Remainder`, -/// but instead another `Scope` that encompasses the whole block, -/// e.g., `Scope::Node`. -/// -/// * The subscope with `first_statement_index == 1` is scope of `c`, -/// and thus does not include EXPR_2, but covers the `...`. - newtype_index! { + /// Represents a subscope of `block` for a binding that is introduced + /// by `block.stmts[first_statement_index]`. Such subscopes represent + /// a suffix of the block. Note that each subscope does not include + /// the initializer expression, if any, for the statement indexed by + /// `first_statement_index`. + /// + /// For example, given `{ let (a, b) = EXPR_1; let c = EXPR_2; ... }`: + /// + /// * The subscope with `first_statement_index == 0` is scope of both + /// `a` and `b`; it does not include EXPR_1, but does include + /// everything after that first `let`. (If you want a scope that + /// includes EXPR_1 as well, then do not use `Scope::Remainder`, + /// but instead another `Scope` that encompasses the whole block, + /// e.g., `Scope::Node`. + /// + /// * The subscope with `first_statement_index == 1` is scope of `c`, + /// and thus does not include EXPR_2, but covers the `...`. pub struct FirstStatementIndex { .. } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 2a3a9d1f5f43b..274721b45cba0 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1892,9 +1892,11 @@ pub mod tls { rayon_core::tlv::get() } - /// A thread local variable which stores a pointer to the current ImplicitCtxt #[cfg(not(parallel_compiler))] - thread_local!(static TLV: Cell = Cell::new(0)); + thread_local! { + /// A thread local variable which stores a pointer to the current ImplicitCtxt. + static TLV: Cell = Cell::new(0); + } /// Sets TLV to `value` during the call to `f`. /// It is restored to its previous value after. @@ -2011,10 +2013,11 @@ pub mod tls { }) } - /// Stores a pointer to the GlobalCtxt if one is available. - /// This is used to access the GlobalCtxt in the deadlock handler - /// given to Rayon. - scoped_thread_local!(pub static GCX_PTR: Lock); + scoped_thread_local! { + /// Stores a pointer to the GlobalCtxt if one is available. + /// This is used to access the GlobalCtxt in the deadlock handler given to Rayon. + pub static GCX_PTR: Lock + } /// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local. /// This is used in the deadlock handler. diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 356f9c32f03df..1629f1dc6302a 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1512,42 +1512,42 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } } -/// "Universes" are used during type- and trait-checking in the -/// presence of `for<..>` binders to control what sets of names are -/// visible. Universes are arranged into a tree: the root universe -/// contains names that are always visible. Each child then adds a new -/// set of names that are visible, in addition to those of its parent. -/// We say that the child universe "extends" the parent universe with -/// new names. -/// -/// To make this more concrete, consider this program: -/// -/// ``` -/// struct Foo { } -/// fn bar(x: T) { -/// let y: for<'a> fn(&'a u8, Foo) = ...; -/// } -/// ``` -/// -/// The struct name `Foo` is in the root universe U0. But the type -/// parameter `T`, introduced on `bar`, is in an extended universe U1 -/// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside -/// of `bar`, we cannot name `T`. Then, within the type of `y`, the -/// region `'a` is in a universe U2 that extends U1, because we can -/// name it inside the fn type but not outside. -/// -/// Universes are used to do type- and trait-checking around these -/// "forall" binders (also called **universal quantification**). The -/// idea is that when, in the body of `bar`, we refer to `T` as a -/// type, we aren't referring to any type in particular, but rather a -/// kind of "fresh" type that is distinct from all other types we have -/// actually declared. This is called a **placeholder** type, and we -/// use universes to talk about this. In other words, a type name in -/// universe 0 always corresponds to some "ground" type that the user -/// declared, but a type name in a non-zero universe is a placeholder -/// type -- an idealized representative of "types in general" that we -/// use for checking generic functions. newtype_index! { + /// "Universes" are used during type- and trait-checking in the + /// presence of `for<..>` binders to control what sets of names are + /// visible. Universes are arranged into a tree: the root universe + /// contains names that are always visible. Each child then adds a new + /// set of names that are visible, in addition to those of its parent. + /// We say that the child universe "extends" the parent universe with + /// new names. + /// + /// To make this more concrete, consider this program: + /// + /// ``` + /// struct Foo { } + /// fn bar(x: T) { + /// let y: for<'a> fn(&'a u8, Foo) = ...; + /// } + /// ``` + /// + /// The struct name `Foo` is in the root universe U0. But the type + /// parameter `T`, introduced on `bar`, is in an extended universe U1 + /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside + /// of `bar`, we cannot name `T`. Then, within the type of `y`, the + /// region `'a` is in a universe U2 that extends U1, because we can + /// name it inside the fn type but not outside. + /// + /// Universes are used to do type- and trait-checking around these + /// "forall" binders (also called **universal quantification**). The + /// idea is that when, in the body of `bar`, we refer to `T` as a + /// type, we aren't referring to any type in particular, but rather a + /// kind of "fresh" type that is distinct from all other types we have + /// actually declared. This is called a **placeholder** type, and we + /// use universes to talk about this. In other words, a type name in + /// universe 0 always corresponds to some "ground" type that the user + /// declared, but a type name in a non-zero universe is a placeholder + /// type -- an idealized representative of "types in general" that we + /// use for checking generic functions. pub struct UniverseIndex { DEBUG_FORMAT = "U{}", } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 1aa4ca7ff97ab..95148834e01cc 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1082,46 +1082,46 @@ impl<'a, 'gcx, 'tcx> ParamConst { } } -/// A [De Bruijn index][dbi] is a standard means of representing -/// regions (and perhaps later types) in a higher-ranked setting. In -/// particular, imagine a type like this: -/// -/// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char) -/// ^ ^ | | | -/// | | | | | -/// | +------------+ 0 | | -/// | | | -/// +--------------------------------+ 1 | -/// | | -/// +------------------------------------------+ 0 -/// -/// In this type, there are two binders (the outer fn and the inner -/// fn). We need to be able to determine, for any given region, which -/// fn type it is bound by, the inner or the outer one. There are -/// various ways you can do this, but a De Bruijn index is one of the -/// more convenient and has some nice properties. The basic idea is to -/// count the number of binders, inside out. Some examples should help -/// clarify what I mean. -/// -/// Let's start with the reference type `&'b isize` that is the first -/// argument to the inner function. This region `'b` is assigned a De -/// Bruijn index of 0, meaning "the innermost binder" (in this case, a -/// fn). The region `'a` that appears in the second argument type (`&'a -/// isize`) would then be assigned a De Bruijn index of 1, meaning "the -/// second-innermost binder". (These indices are written on the arrays -/// in the diagram). -/// -/// What is interesting is that De Bruijn index attached to a particular -/// variable will vary depending on where it appears. For example, -/// the final type `&'a char` also refers to the region `'a` declared on -/// the outermost fn. But this time, this reference is not nested within -/// any other binders (i.e., it is not an argument to the inner fn, but -/// rather the outer one). Therefore, in this case, it is assigned a -/// De Bruijn index of 0, because the innermost binder in that location -/// is the outer fn. -/// -/// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index newtype_index! { + /// A [De Bruijn index][dbi] is a standard means of representing + /// regions (and perhaps later types) in a higher-ranked setting. In + /// particular, imagine a type like this: + /// + /// for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char) + /// ^ ^ | | | + /// | | | | | + /// | +------------+ 0 | | + /// | | | + /// +--------------------------------+ 1 | + /// | | + /// +------------------------------------------+ 0 + /// + /// In this type, there are two binders (the outer fn and the inner + /// fn). We need to be able to determine, for any given region, which + /// fn type it is bound by, the inner or the outer one. There are + /// various ways you can do this, but a De Bruijn index is one of the + /// more convenient and has some nice properties. The basic idea is to + /// count the number of binders, inside out. Some examples should help + /// clarify what I mean. + /// + /// Let's start with the reference type `&'b isize` that is the first + /// argument to the inner function. This region `'b` is assigned a De + /// Bruijn index of 0, meaning "the innermost binder" (in this case, a + /// fn). The region `'a` that appears in the second argument type (`&'a + /// isize`) would then be assigned a De Bruijn index of 1, meaning "the + /// second-innermost binder". (These indices are written on the arrays + /// in the diagram). + /// + /// What is interesting is that De Bruijn index attached to a particular + /// variable will vary depending on where it appears. For example, + /// the final type `&'a char` also refers to the region `'a` declared on + /// the outermost fn. But this time, this reference is not nested within + /// any other binders (i.e., it is not an argument to the inner fn, but + /// rather the outer one). Therefore, in this case, it is assigned a + /// De Bruijn index of 0, because the innermost binder in that location + /// is the outer fn. + /// + /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index pub struct DebruijnIndex { DEBUG_FORMAT = "DebruijnIndex({})", const INNERMOST = 0, diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 09aec50e4bb11..1153c3e79bfd5 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -58,9 +58,10 @@ macro_rules! newtype_index { // ---- public rules ---- // Use default constants - ($v:vis struct $name:ident { .. }) => ( + ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( newtype_index!( // Leave out derives marker so we can use its absence to ensure it comes first + @attrs [$(#[$attrs])*] @type [$name] // shave off 256 indices at the end to allow space for packing these indices into enums @max [0xFFFF_FF00] @@ -69,9 +70,10 @@ macro_rules! newtype_index { ); // Define any constants - ($v:vis struct $name:ident { $($tokens:tt)+ }) => ( + ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( newtype_index!( // Leave out derives marker so we can use its absence to ensure it comes first + @attrs [$(#[$attrs])*] @type [$name] // shave off 256 indices at the end to allow space for packing these indices into enums @max [0xFFFF_FF00] @@ -84,10 +86,12 @@ macro_rules! newtype_index { // Base case, user-defined constants (if any) have already been defined (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] @type [$type:ident] @max [$max:expr] @vis [$v:vis] @debug_format [$debug_format:tt]) => ( + $(#[$attrs])* #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] #[rustc_layout_scalar_valid_range_end($max)] $v struct $type { @@ -317,7 +321,8 @@ macro_rules! newtype_index { // By not including the @derives marker in this list nor in the default args, we can force it // to come first if it exists. When encodable isn't custom, add serialization traits by default. - (@type [$type:ident] + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] @max [$max:expr] @vis [$v:vis] @debug_format [$debug_format:tt] @@ -325,6 +330,7 @@ macro_rules! newtype_index { $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)+ RustcEncodable,] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -335,7 +341,8 @@ macro_rules! newtype_index { // The case where no derives are added, but encodable is overridden. Don't // derive serialization traits - (@type [$type:ident] + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] @max [$max:expr] @vis [$v:vis] @debug_format [$debug_format:tt] @@ -343,6 +350,7 @@ macro_rules! newtype_index { $($tokens:tt)*) => ( newtype_index!( @derives [] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -351,13 +359,15 @@ macro_rules! newtype_index { ); // The case where no derives are added, add serialization derives by default - (@type [$type:ident] + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] @max [$max:expr] @vis [$v:vis] @debug_format [$debug_format:tt] $($tokens:tt)*) => ( newtype_index!( @derives [RustcEncodable,] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -384,6 +394,7 @@ macro_rules! newtype_index { // Rewrite final without comma to one that includes comma (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] @type [$type:ident] @max [$max:expr] @vis [$v:vis] @@ -391,6 +402,7 @@ macro_rules! newtype_index { $name:ident = $constant:expr) => ( newtype_index!( @derives [$($derives,)*] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -400,6 +412,7 @@ macro_rules! newtype_index { // Rewrite final const without comma to one that includes comma (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] @type [$type:ident] @max [$_max:expr] @vis [$v:vis] @@ -408,6 +421,7 @@ macro_rules! newtype_index { const $name:ident = $constant:expr) => ( newtype_index!( @derives [$($derives,)*] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -417,6 +431,7 @@ macro_rules! newtype_index { // Replace existing default for max (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] @type [$type:ident] @max [$_max:expr] @vis [$v:vis] @@ -425,6 +440,7 @@ macro_rules! newtype_index { $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)*] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -434,6 +450,7 @@ macro_rules! newtype_index { // Replace existing default for debug_format (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] @type [$type:ident] @max [$max:expr] @vis [$v:vis] @@ -442,6 +459,7 @@ macro_rules! newtype_index { $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)*] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] @@ -451,6 +469,7 @@ macro_rules! newtype_index { // Assign a user-defined constant (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] @type [$type:ident] @max [$max:expr] @vis [$v:vis] @@ -462,6 +481,7 @@ macro_rules! newtype_index { pub const $name: $type = $type::from_u32_const($constant); newtype_index!( @derives [$($derives,)*] + @attrs [$(#[$attrs])*] @type [$type] @max [$max] @vis [$v] diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index aafae28b49ea5..7a7c49e460428 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -36,7 +36,7 @@ use syntax::tokenstream::{TokenTree, TokenStream}; use syntax::ast; use syntax::ptr::P; use syntax::ast::Expr; -use syntax::attr; +use syntax::attr::{self, HasAttrs}; use syntax::source_map::Spanned; use syntax::edition::Edition; use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType}; @@ -802,27 +802,81 @@ impl LintPass for UnusedDocComment { } impl UnusedDocComment { - fn warn_if_doc<'a, 'tcx, - I: Iterator, - C: LintContext<'tcx>>(&self, mut attrs: I, cx: &C) { - if let Some(attr) = attrs.find(|a| a.is_value_str() && a.check_name("doc")) { - cx.struct_span_lint(UNUSED_DOC_COMMENTS, attr.span, "doc comment not used by rustdoc") - .emit(); + fn warn_if_doc( + &self, + cx: &EarlyContext<'_>, + node_span: Span, + node_kind: &str, + is_macro_expansion: bool, + attrs: &[ast::Attribute] + ) { + let mut attrs = attrs.into_iter().peekable(); + + // Accumulate a single span for sugared doc comments. + let mut sugared_span: Option = None; + + while let Some(attr) = attrs.next() { + if attr.is_sugared_doc { + sugared_span = Some( + sugared_span.map_or_else( + || attr.span, + |span| span.with_hi(attr.span.hi()), + ), + ); + } + + if attrs.peek().map(|next_attr| next_attr.is_sugared_doc).unwrap_or_default() { + continue; + } + + let span = sugared_span.take().unwrap_or_else(|| attr.span); + + if attr.name() == "doc" { + let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment"); + + err.span_label( + node_span, + format!("rustdoc does not generate documentation for {}", node_kind) + ); + + if is_macro_expansion { + err.help("to document an item produced by a macro, \ + the macro must produce the documentation as part of its expansion"); + } + + err.emit(); + } } } } impl EarlyLintPass for UnusedDocComment { - fn check_local(&mut self, cx: &EarlyContext<'_>, decl: &ast::Local) { - self.warn_if_doc(decl.attrs.iter(), cx); + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { + if let ast::ItemKind::Mac(..) = item.node { + self.warn_if_doc(cx, item.span, "macro expansions", true, &item.attrs); + } + } + + fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &ast::Stmt) { + let (kind, is_macro_expansion) = match stmt.node { + ast::StmtKind::Local(..) => ("statements", false), + ast::StmtKind::Item(..) => ("inner items", false), + ast::StmtKind::Mac(..) => ("macro expansions", true), + // expressions will be reported by `check_expr`. + ast::StmtKind::Semi(..) | + ast::StmtKind::Expr(..) => return, + }; + + self.warn_if_doc(cx, stmt.span, kind, is_macro_expansion, stmt.node.attrs()); } fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) { - self.warn_if_doc(arm.attrs.iter(), cx); + let arm_span = arm.pats[0].span.with_hi(arm.body.span.hi()); + self.warn_if_doc(cx, arm_span, "match arms", false, &arm.attrs); } fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) { - self.warn_if_doc(expr.attrs.iter(), cx); + self.warn_if_doc(cx, expr.span, "expressions", false, &expr.attrs); } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5c243e1389073..5e375dcaa0681 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -66,6 +66,7 @@ macro_rules! pre_expansion_lint_passes { ($macro:path, $args:tt) => ( $macro!($args, [ KeywordIdents: KeywordIdents, + UnusedDocComment: UnusedDocComment, ]); ) } @@ -77,7 +78,6 @@ macro_rules! early_lint_passes { UnusedImportBraces: UnusedImportBraces, UnsafeCode: UnsafeCode, AnonymousParameters: AnonymousParameters, - UnusedDocComment: UnusedDocComment, EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns, NonCamelCaseTypes: NonCamelCaseTypes, DeprecatedAttr: DeprecatedAttr::new(), diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index c4491778162f4..2101447965a15 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -116,14 +116,14 @@ impl RegionValueElements { } } -/// A single integer representing a `Location` in the MIR control-flow -/// graph. Constructed efficiently from `RegionValueElements`. newtype_index! { + /// A single integer representing a `Location` in the MIR control-flow + /// graph. Constructed efficiently from `RegionValueElements`. pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" } } -/// A single integer representing a `ty::Placeholder`. newtype_index! { + /// A single integer representing a `ty::Placeholder`. pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" } } diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 0c29ea8ab4afa..97f84675f94bf 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -23,7 +23,7 @@ pub(crate) mod indexes { use rustc_data_structures::indexed_vec::Idx; macro_rules! new_index { - ($Index:ident, $debug_name:expr) => { + ($(#[$attrs:meta])* $Index:ident, $debug_name:expr) => { #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct $Index(NonZeroUsize); @@ -44,17 +44,29 @@ pub(crate) mod indexes { } } - /// Index into MovePathData.move_paths - new_index!(MovePathIndex, "mp"); - - /// Index into MoveData.moves. - new_index!(MoveOutIndex, "mo"); - - /// Index into MoveData.inits. - new_index!(InitIndex, "in"); - - /// Index into Borrows.locations - new_index!(BorrowIndex, "bw"); + new_index!( + /// Index into MovePathData.move_paths + MovePathIndex, + "mp" + ); + + new_index!( + /// Index into MoveData.moves. + MoveOutIndex, + "mo" + ); + + new_index!( + /// Index into MoveData.inits. + InitIndex, + "in" + ); + + new_index!( + /// Index into Borrows.locations + BorrowIndex, + "bw" + ); } pub use self::indexes::MovePathIndex; diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 589fb455a191c..d53a294fa6a9e 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -11,15 +11,15 @@ use crate::sys::stdio; use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; use crate::thread::LocalKey; -/// Stdout used by print! and println! macros thread_local! { + /// Stdout used by print! and println! macros static LOCAL_STDOUT: RefCell>> = { RefCell::new(None) } } -/// Stderr used by eprint! and eprintln! macros, and panics thread_local! { + /// Stderr used by eprint! and eprintln! macros, and panics static LOCAL_STDERR: RefCell>> = { RefCell::new(None) } diff --git a/src/test/ui/useless_comment.rs b/src/test/ui/useless_comment.rs index 531eec007fc48..7d2e5ab6f2b7f 100644 --- a/src/test/ui/useless_comment.rs +++ b/src/test/ui/useless_comment.rs @@ -1,18 +1,43 @@ +#![feature(stmt_expr_attributes)] + #![deny(unused_doc_comments)] +macro_rules! mac { + () => {} +} + +/// foo //~ ERROR unused doc comment +mac!(); + fn foo() { - /// a //~ ERROR doc comment not used by rustdoc + /// a //~ ERROR unused doc comment let x = 12; - /// b //~ doc comment not used by rustdoc + /// multi-line //~ unused doc comment + /// doc comment + /// that is unused match x { - /// c //~ ERROR doc comment not used by rustdoc + /// c //~ ERROR unused doc comment 1 => {}, _ => {} } - /// foo //~ ERROR doc comment not used by rustdoc + /// foo //~ ERROR unused doc comment unsafe {} + + #[doc = "foo"] //~ ERROR unused doc comment + #[doc = "bar"] //~ ERROR unused doc comment + 3; + + /// bar //~ ERROR unused doc comment + mac!(); + + let x = /** comment */ 47; //~ ERROR unused doc comment + + /// dox //~ ERROR unused doc comment + { + + } } fn main() { diff --git a/src/test/ui/useless_comment.stderr b/src/test/ui/useless_comment.stderr index cc818f6ce7c39..0742a844b7f40 100644 --- a/src/test/ui/useless_comment.stderr +++ b/src/test/ui/useless_comment.stderr @@ -1,32 +1,98 @@ -error: doc comment not used by rustdoc - --> $DIR/useless_comment.rs:4:5 +error: unused doc comment + --> $DIR/useless_comment.rs:9:1 | -LL | /// a //~ ERROR doc comment not used by rustdoc - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// foo //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | mac!(); + | ------- rustdoc does not generate documentation for macro expansions | note: lint level defined here - --> $DIR/useless_comment.rs:1:9 + --> $DIR/useless_comment.rs:3:9 | LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion -error: doc comment not used by rustdoc - --> $DIR/useless_comment.rs:7:5 +error: unused doc comment + --> $DIR/useless_comment.rs:13:5 | -LL | /// b //~ doc comment not used by rustdoc - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// a //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let x = 12; + | ----------- rustdoc does not generate documentation for statements -error: doc comment not used by rustdoc - --> $DIR/useless_comment.rs:9:9 +error: unused doc comment + --> $DIR/useless_comment.rs:16:5 | -LL | /// c //~ ERROR doc comment not used by rustdoc - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / /// multi-line //~ unused doc comment +LL | | /// doc comment +LL | | /// that is unused + | |______________________^ +LL | / match x { +LL | | /// c //~ ERROR unused doc comment +LL | | 1 => {}, +LL | | _ => {} +LL | | } + | |_____- rustdoc does not generate documentation for expressions -error: doc comment not used by rustdoc - --> $DIR/useless_comment.rs:14:5 +error: unused doc comment + --> $DIR/useless_comment.rs:20:9 | -LL | /// foo //~ ERROR doc comment not used by rustdoc - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// c //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | 1 => {}, + | ------- rustdoc does not generate documentation for match arms -error: aborting due to 4 previous errors +error: unused doc comment + --> $DIR/useless_comment.rs:25:5 + | +LL | /// foo //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe {} + | --------- rustdoc does not generate documentation for expressions + +error: unused doc comment + --> $DIR/useless_comment.rs:28:5 + | +LL | #[doc = "foo"] //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^ +LL | #[doc = "bar"] //~ ERROR unused doc comment +LL | 3; + | - rustdoc does not generate documentation for expressions + +error: unused doc comment + --> $DIR/useless_comment.rs:29:5 + | +LL | #[doc = "bar"] //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^ +LL | 3; + | - rustdoc does not generate documentation for expressions + +error: unused doc comment + --> $DIR/useless_comment.rs:32:5 + | +LL | /// bar //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | mac!(); + | ------- rustdoc does not generate documentation for macro expansions + | + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion + +error: unused doc comment + --> $DIR/useless_comment.rs:35:13 + | +LL | let x = /** comment */ 47; //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions + +error: unused doc comment + --> $DIR/useless_comment.rs:37:5 + | +LL | /// dox //~ ERROR unused doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / { +LL | | +LL | | } + | |_____- rustdoc does not generate documentation for expressions + +error: aborting due to 10 previous errors