expand unused doc comment diagnostic
Report the diagnostic on macro expansions, and add a label indicating why the comment is unused.
This commit is contained in:
parent
018d4d265f
commit
daf80f721b
14 changed files with 303 additions and 167 deletions
|
@ -4515,7 +4515,7 @@ macro_rules! rev {
|
||||||
)*}
|
)*}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// intra-sign conversions
|
// intra-sign conversions
|
||||||
try_from_upper_bounded!(u16, u8);
|
try_from_upper_bounded!(u16, u8);
|
||||||
try_from_upper_bounded!(u32, u16, u8);
|
try_from_upper_bounded!(u32, u16, u8);
|
||||||
try_from_upper_bounded!(u64, u32, u16, u8);
|
try_from_upper_bounded!(u64, u32, u16, u8);
|
||||||
|
|
|
@ -122,6 +122,7 @@ impl fmt::Display for HirId {
|
||||||
// hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module
|
// hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module
|
||||||
mod item_local_id_inner {
|
mod item_local_id_inner {
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
newtype_index! {
|
||||||
/// An `ItemLocalId` uniquely identifies something within a given "item-like",
|
/// An `ItemLocalId` uniquely identifies something within a given "item-like",
|
||||||
/// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
|
/// 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
|
/// guarantee that the numerical value of a given `ItemLocalId` corresponds to
|
||||||
|
@ -130,7 +131,6 @@ mod item_local_id_inner {
|
||||||
/// integers starting at zero, so a mapping that maps all or most nodes within
|
/// 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
|
/// an "item-like" to something else can be implement by a `Vec` instead of a
|
||||||
/// tree or hash map.
|
/// tree or hash map.
|
||||||
newtype_index! {
|
|
||||||
pub struct ItemLocalId { .. }
|
pub struct ItemLocalId { .. }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,25 +132,24 @@ pub enum ScopeData {
|
||||||
Remainder(FirstStatementIndex)
|
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! {
|
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 { .. }
|
pub struct FirstStatementIndex { .. }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1892,9 +1892,11 @@ pub mod tls {
|
||||||
rayon_core::tlv::get()
|
rayon_core::tlv::get()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A thread local variable which stores a pointer to the current ImplicitCtxt
|
|
||||||
#[cfg(not(parallel_compiler))]
|
#[cfg(not(parallel_compiler))]
|
||||||
thread_local!(static TLV: Cell<usize> = Cell::new(0));
|
thread_local! {
|
||||||
|
/// A thread local variable which stores a pointer to the current ImplicitCtxt.
|
||||||
|
static TLV: Cell<usize> = Cell::new(0);
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets TLV to `value` during the call to `f`.
|
/// Sets TLV to `value` during the call to `f`.
|
||||||
/// It is restored to its previous value after.
|
/// It is restored to its previous value after.
|
||||||
|
@ -2011,10 +2013,11 @@ pub mod tls {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoped_thread_local! {
|
||||||
/// Stores a pointer to the GlobalCtxt if one is available.
|
/// Stores a pointer to the GlobalCtxt if one is available.
|
||||||
/// This is used to access the GlobalCtxt in the deadlock handler
|
/// This is used to access the GlobalCtxt in the deadlock handler given to Rayon.
|
||||||
/// given to Rayon.
|
pub static GCX_PTR: Lock<usize>
|
||||||
scoped_thread_local!(pub static GCX_PTR: Lock<usize>);
|
}
|
||||||
|
|
||||||
/// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local.
|
/// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local.
|
||||||
/// This is used in the deadlock handler.
|
/// This is used in the deadlock handler.
|
||||||
|
|
|
@ -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<T>(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! {
|
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<T>(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 {
|
pub struct UniverseIndex {
|
||||||
DEBUG_FORMAT = "U{}",
|
DEBUG_FORMAT = "U{}",
|
||||||
}
|
}
|
||||||
|
|
|
@ -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! {
|
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 {
|
pub struct DebruijnIndex {
|
||||||
DEBUG_FORMAT = "DebruijnIndex({})",
|
DEBUG_FORMAT = "DebruijnIndex({})",
|
||||||
const INNERMOST = 0,
|
const INNERMOST = 0,
|
||||||
|
|
|
@ -58,9 +58,10 @@ macro_rules! newtype_index {
|
||||||
// ---- public rules ----
|
// ---- public rules ----
|
||||||
|
|
||||||
// Use default constants
|
// Use default constants
|
||||||
($v:vis struct $name:ident { .. }) => (
|
($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
// Leave out derives marker so we can use its absence to ensure it comes first
|
// Leave out derives marker so we can use its absence to ensure it comes first
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$name]
|
@type [$name]
|
||||||
// shave off 256 indices at the end to allow space for packing these indices into enums
|
// shave off 256 indices at the end to allow space for packing these indices into enums
|
||||||
@max [0xFFFF_FF00]
|
@max [0xFFFF_FF00]
|
||||||
|
@ -69,9 +70,10 @@ macro_rules! newtype_index {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Define any constants
|
// Define any constants
|
||||||
($v:vis struct $name:ident { $($tokens:tt)+ }) => (
|
($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
// Leave out derives marker so we can use its absence to ensure it comes first
|
// Leave out derives marker so we can use its absence to ensure it comes first
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$name]
|
@type [$name]
|
||||||
// shave off 256 indices at the end to allow space for packing these indices into enums
|
// shave off 256 indices at the end to allow space for packing these indices into enums
|
||||||
@max [0xFFFF_FF00]
|
@max [0xFFFF_FF00]
|
||||||
|
@ -84,10 +86,12 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// Base case, user-defined constants (if any) have already been defined
|
// Base case, user-defined constants (if any) have already been defined
|
||||||
(@derives [$($derives:ident,)*]
|
(@derives [$($derives:ident,)*]
|
||||||
|
@attrs [$(#[$attrs:meta])*]
|
||||||
@type [$type:ident]
|
@type [$type:ident]
|
||||||
@max [$max:expr]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
@debug_format [$debug_format:tt]) => (
|
@debug_format [$debug_format:tt]) => (
|
||||||
|
$(#[$attrs])*
|
||||||
#[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)]
|
#[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)]
|
||||||
#[rustc_layout_scalar_valid_range_end($max)]
|
#[rustc_layout_scalar_valid_range_end($max)]
|
||||||
$v struct $type {
|
$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
|
// 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.
|
// 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]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
@debug_format [$debug_format:tt]
|
@debug_format [$debug_format:tt]
|
||||||
|
@ -325,6 +330,7 @@ macro_rules! newtype_index {
|
||||||
$($tokens:tt)*) => (
|
$($tokens:tt)*) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [$($derives,)+ RustcEncodable,]
|
@derives [$($derives,)+ RustcEncodable,]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -335,7 +341,8 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// The case where no derives are added, but encodable is overridden. Don't
|
// The case where no derives are added, but encodable is overridden. Don't
|
||||||
// derive serialization traits
|
// derive serialization traits
|
||||||
(@type [$type:ident]
|
(@attrs [$(#[$attrs:meta])*]
|
||||||
|
@type [$type:ident]
|
||||||
@max [$max:expr]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
@debug_format [$debug_format:tt]
|
@debug_format [$debug_format:tt]
|
||||||
|
@ -343,6 +350,7 @@ macro_rules! newtype_index {
|
||||||
$($tokens:tt)*) => (
|
$($tokens:tt)*) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives []
|
@derives []
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -351,13 +359,15 @@ macro_rules! newtype_index {
|
||||||
);
|
);
|
||||||
|
|
||||||
// The case where no derives are added, add serialization derives by default
|
// The case where no derives are added, add serialization derives by default
|
||||||
(@type [$type:ident]
|
(@attrs [$(#[$attrs:meta])*]
|
||||||
|
@type [$type:ident]
|
||||||
@max [$max:expr]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
@debug_format [$debug_format:tt]
|
@debug_format [$debug_format:tt]
|
||||||
$($tokens:tt)*) => (
|
$($tokens:tt)*) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [RustcEncodable,]
|
@derives [RustcEncodable,]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -384,6 +394,7 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// Rewrite final without comma to one that includes comma
|
// Rewrite final without comma to one that includes comma
|
||||||
(@derives [$($derives:ident,)*]
|
(@derives [$($derives:ident,)*]
|
||||||
|
@attrs [$(#[$attrs:meta])*]
|
||||||
@type [$type:ident]
|
@type [$type:ident]
|
||||||
@max [$max:expr]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
|
@ -391,6 +402,7 @@ macro_rules! newtype_index {
|
||||||
$name:ident = $constant:expr) => (
|
$name:ident = $constant:expr) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [$($derives,)*]
|
@derives [$($derives,)*]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -400,6 +412,7 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// Rewrite final const without comma to one that includes comma
|
// Rewrite final const without comma to one that includes comma
|
||||||
(@derives [$($derives:ident,)*]
|
(@derives [$($derives:ident,)*]
|
||||||
|
@attrs [$(#[$attrs:meta])*]
|
||||||
@type [$type:ident]
|
@type [$type:ident]
|
||||||
@max [$_max:expr]
|
@max [$_max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
|
@ -408,6 +421,7 @@ macro_rules! newtype_index {
|
||||||
const $name:ident = $constant:expr) => (
|
const $name:ident = $constant:expr) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [$($derives,)*]
|
@derives [$($derives,)*]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -417,6 +431,7 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// Replace existing default for max
|
// Replace existing default for max
|
||||||
(@derives [$($derives:ident,)*]
|
(@derives [$($derives:ident,)*]
|
||||||
|
@attrs [$(#[$attrs:meta])*]
|
||||||
@type [$type:ident]
|
@type [$type:ident]
|
||||||
@max [$_max:expr]
|
@max [$_max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
|
@ -425,6 +440,7 @@ macro_rules! newtype_index {
|
||||||
$($tokens:tt)*) => (
|
$($tokens:tt)*) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [$($derives,)*]
|
@derives [$($derives,)*]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -434,6 +450,7 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// Replace existing default for debug_format
|
// Replace existing default for debug_format
|
||||||
(@derives [$($derives:ident,)*]
|
(@derives [$($derives:ident,)*]
|
||||||
|
@attrs [$(#[$attrs:meta])*]
|
||||||
@type [$type:ident]
|
@type [$type:ident]
|
||||||
@max [$max:expr]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
|
@ -442,6 +459,7 @@ macro_rules! newtype_index {
|
||||||
$($tokens:tt)*) => (
|
$($tokens:tt)*) => (
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [$($derives,)*]
|
@derives [$($derives,)*]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
@ -451,6 +469,7 @@ macro_rules! newtype_index {
|
||||||
|
|
||||||
// Assign a user-defined constant
|
// Assign a user-defined constant
|
||||||
(@derives [$($derives:ident,)*]
|
(@derives [$($derives:ident,)*]
|
||||||
|
@attrs [$(#[$attrs:meta])*]
|
||||||
@type [$type:ident]
|
@type [$type:ident]
|
||||||
@max [$max:expr]
|
@max [$max:expr]
|
||||||
@vis [$v:vis]
|
@vis [$v:vis]
|
||||||
|
@ -462,6 +481,7 @@ macro_rules! newtype_index {
|
||||||
pub const $name: $type = $type::from_u32_const($constant);
|
pub const $name: $type = $type::from_u32_const($constant);
|
||||||
newtype_index!(
|
newtype_index!(
|
||||||
@derives [$($derives,)*]
|
@derives [$($derives,)*]
|
||||||
|
@attrs [$(#[$attrs])*]
|
||||||
@type [$type]
|
@type [$type]
|
||||||
@max [$max]
|
@max [$max]
|
||||||
@vis [$v]
|
@vis [$v]
|
||||||
|
|
|
@ -36,7 +36,7 @@ use syntax::tokenstream::{TokenTree, TokenStream};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::ast::Expr;
|
use syntax::ast::Expr;
|
||||||
use syntax::attr;
|
use syntax::attr::{self, HasAttrs};
|
||||||
use syntax::source_map::Spanned;
|
use syntax::source_map::Spanned;
|
||||||
use syntax::edition::Edition;
|
use syntax::edition::Edition;
|
||||||
use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
|
use syntax::feature_gate::{AttributeGate, AttributeTemplate, AttributeType};
|
||||||
|
@ -802,7 +802,14 @@ impl LintPass for UnusedDocComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnusedDocComment {
|
impl UnusedDocComment {
|
||||||
fn warn_if_doc(&self, cx: &EarlyContext, attrs: &[ast::Attribute]) {
|
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();
|
let mut attrs = attrs.into_iter().peekable();
|
||||||
|
|
||||||
// Accumulate a single span for sugared doc comments.
|
// Accumulate a single span for sugared doc comments.
|
||||||
|
@ -825,27 +832,51 @@ impl UnusedDocComment {
|
||||||
let span = sugared_span.take().unwrap_or_else(|| attr.span);
|
let span = sugared_span.take().unwrap_or_else(|| attr.span);
|
||||||
|
|
||||||
if attr.name() == "doc" {
|
if attr.name() == "doc" {
|
||||||
cx.struct_span_lint(
|
let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");
|
||||||
UNUSED_DOC_COMMENTS,
|
|
||||||
span,
|
err.span_label(
|
||||||
"doc comment not used by rustdoc",
|
node_span,
|
||||||
).emit();
|
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 {
|
impl EarlyLintPass for UnusedDocComment {
|
||||||
fn check_local(&mut self, cx: &EarlyContext<'_>, decl: &ast::Local) {
|
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
|
||||||
self.warn_if_doc(cx, &decl.attrs);
|
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) {
|
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
|
||||||
self.warn_if_doc(cx, &arm.attrs);
|
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) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
|
||||||
self.warn_if_doc(cx, &expr.attrs);
|
self.warn_if_doc(cx, expr.span, "expressions", false, &expr.attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ macro_rules! pre_expansion_lint_passes {
|
||||||
($macro:path, $args:tt) => (
|
($macro:path, $args:tt) => (
|
||||||
$macro!($args, [
|
$macro!($args, [
|
||||||
KeywordIdents: KeywordIdents,
|
KeywordIdents: KeywordIdents,
|
||||||
|
UnusedDocComment: UnusedDocComment,
|
||||||
]);
|
]);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,6 @@ macro_rules! early_lint_passes {
|
||||||
UnusedImportBraces: UnusedImportBraces,
|
UnusedImportBraces: UnusedImportBraces,
|
||||||
UnsafeCode: UnsafeCode,
|
UnsafeCode: UnsafeCode,
|
||||||
AnonymousParameters: AnonymousParameters,
|
AnonymousParameters: AnonymousParameters,
|
||||||
UnusedDocComment: UnusedDocComment,
|
|
||||||
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns,
|
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns,
|
||||||
NonCamelCaseTypes: NonCamelCaseTypes,
|
NonCamelCaseTypes: NonCamelCaseTypes,
|
||||||
DeprecatedAttr: DeprecatedAttr::new(),
|
DeprecatedAttr: DeprecatedAttr::new(),
|
||||||
|
|
|
@ -116,14 +116,14 @@ impl RegionValueElements {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single integer representing a `Location` in the MIR control-flow
|
|
||||||
/// graph. Constructed efficiently from `RegionValueElements`.
|
|
||||||
newtype_index! {
|
newtype_index! {
|
||||||
|
/// A single integer representing a `Location` in the MIR control-flow
|
||||||
|
/// graph. Constructed efficiently from `RegionValueElements`.
|
||||||
pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" }
|
pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single integer representing a `ty::Placeholder`.
|
|
||||||
newtype_index! {
|
newtype_index! {
|
||||||
|
/// A single integer representing a `ty::Placeholder`.
|
||||||
pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" }
|
pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub(crate) mod indexes {
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
|
||||||
macro_rules! new_index {
|
macro_rules! new_index {
|
||||||
($Index:ident, $debug_name:expr) => {
|
($(#[$attrs:meta])* $Index:ident, $debug_name:expr) => {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct $Index(NonZeroUsize);
|
pub struct $Index(NonZeroUsize);
|
||||||
|
|
||||||
|
@ -44,17 +44,29 @@ pub(crate) mod indexes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_index!(
|
||||||
/// Index into MovePathData.move_paths
|
/// Index into MovePathData.move_paths
|
||||||
new_index!(MovePathIndex, "mp");
|
MovePathIndex,
|
||||||
|
"mp"
|
||||||
|
);
|
||||||
|
|
||||||
|
new_index!(
|
||||||
/// Index into MoveData.moves.
|
/// Index into MoveData.moves.
|
||||||
new_index!(MoveOutIndex, "mo");
|
MoveOutIndex,
|
||||||
|
"mo"
|
||||||
|
);
|
||||||
|
|
||||||
|
new_index!(
|
||||||
/// Index into MoveData.inits.
|
/// Index into MoveData.inits.
|
||||||
new_index!(InitIndex, "in");
|
InitIndex,
|
||||||
|
"in"
|
||||||
|
);
|
||||||
|
|
||||||
|
new_index!(
|
||||||
/// Index into Borrows.locations
|
/// Index into Borrows.locations
|
||||||
new_index!(BorrowIndex, "bw");
|
BorrowIndex,
|
||||||
|
"bw"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::indexes::MovePathIndex;
|
pub use self::indexes::MovePathIndex;
|
||||||
|
|
|
@ -11,15 +11,15 @@ use crate::sys::stdio;
|
||||||
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
||||||
use crate::thread::LocalKey;
|
use crate::thread::LocalKey;
|
||||||
|
|
||||||
/// Stdout used by print! and println! macros
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
/// Stdout used by print! and println! macros
|
||||||
static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
|
static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
|
||||||
RefCell::new(None)
|
RefCell::new(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stderr used by eprint! and eprintln! macros, and panics
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
|
/// Stderr used by eprint! and eprintln! macros, and panics
|
||||||
static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
|
static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
|
||||||
RefCell::new(None)
|
RefCell::new(None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,43 @@
|
||||||
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
||||||
#![deny(unused_doc_comments)]
|
#![deny(unused_doc_comments)]
|
||||||
|
|
||||||
|
macro_rules! mac {
|
||||||
|
() => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// foo //~ ERROR unused doc comment
|
||||||
|
mac!();
|
||||||
|
|
||||||
fn foo() {
|
fn foo() {
|
||||||
/// a //~ ERROR doc comment not used by rustdoc
|
/// a //~ ERROR unused doc comment
|
||||||
let x = 12;
|
let x = 12;
|
||||||
|
|
||||||
/// multi-line //~ doc comment not used by rustdoc
|
/// multi-line //~ unused doc comment
|
||||||
/// doc comment
|
/// doc comment
|
||||||
/// that is unused
|
/// that is unused
|
||||||
match x {
|
match x {
|
||||||
/// c //~ ERROR doc comment not used by rustdoc
|
/// c //~ ERROR unused doc comment
|
||||||
1 => {},
|
1 => {},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// foo //~ ERROR doc comment not used by rustdoc
|
/// foo //~ ERROR unused doc comment
|
||||||
unsafe {}
|
unsafe {}
|
||||||
|
|
||||||
#[doc = "foo"] //~ ERROR doc comment not used by rustdoc
|
#[doc = "foo"] //~ ERROR unused doc comment
|
||||||
#[doc = "bar"] //~ ERROR doc comment not used by rustdoc
|
#[doc = "bar"] //~ ERROR unused doc comment
|
||||||
3;
|
3;
|
||||||
|
|
||||||
|
/// bar //~ ERROR unused doc comment
|
||||||
|
mac!();
|
||||||
|
|
||||||
|
let x = /** comment */ 47; //~ ERROR unused doc comment
|
||||||
|
|
||||||
|
/// dox //~ ERROR unused doc comment
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,46 +1,98 @@
|
||||||
error: doc comment not used by rustdoc
|
error: unused doc comment
|
||||||
--> $DIR/useless_comment.rs:4:5
|
--> $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
|
note: lint level defined here
|
||||||
--> $DIR/useless_comment.rs:1:9
|
--> $DIR/useless_comment.rs:3:9
|
||||||
|
|
|
|
||||||
LL | #![deny(unused_doc_comments)]
|
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
|
error: unused doc comment
|
||||||
--> $DIR/useless_comment.rs:7:5
|
--> $DIR/useless_comment.rs:13:5
|
||||||
|
|
|
|
||||||
LL | / /// multi-line //~ doc comment not used by rustdoc
|
LL | /// a //~ ERROR unused doc comment
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | let x = 12;
|
||||||
|
| ----------- rustdoc does not generate documentation for statements
|
||||||
|
|
||||||
|
error: unused doc comment
|
||||||
|
--> $DIR/useless_comment.rs:16:5
|
||||||
|
|
|
||||||
|
LL | / /// multi-line //~ unused doc comment
|
||||||
LL | | /// doc comment
|
LL | | /// doc comment
|
||||||
LL | | /// that is unused
|
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
|
error: unused doc comment
|
||||||
--> $DIR/useless_comment.rs:11:9
|
--> $DIR/useless_comment.rs:20:9
|
||||||
|
|
|
|
||||||
LL | /// c //~ ERROR doc comment not used by rustdoc
|
LL | /// c //~ ERROR unused doc comment
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | 1 => {},
|
||||||
|
| ------- rustdoc does not generate documentation for match arms
|
||||||
|
|
||||||
error: doc comment not used by rustdoc
|
error: unused doc comment
|
||||||
--> $DIR/useless_comment.rs:16:5
|
--> $DIR/useless_comment.rs:25:5
|
||||||
|
|
|
|
||||||
LL | /// foo //~ ERROR doc comment not used by rustdoc
|
LL | /// foo //~ ERROR unused doc comment
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL | unsafe {}
|
||||||
|
| --------- rustdoc does not generate documentation for expressions
|
||||||
|
|
||||||
error: doc comment not used by rustdoc
|
error: unused doc comment
|
||||||
--> $DIR/useless_comment.rs:19:5
|
--> $DIR/useless_comment.rs:28:5
|
||||||
|
|
|
|
||||||
LL | #[doc = "foo"] //~ ERROR doc comment not used by rustdoc
|
LL | #[doc = "foo"] //~ ERROR unused doc comment
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
LL | #[doc = "bar"] //~ ERROR unused doc comment
|
||||||
|
LL | 3;
|
||||||
|
| - rustdoc does not generate documentation for expressions
|
||||||
|
|
||||||
error: doc comment not used by rustdoc
|
error: unused doc comment
|
||||||
--> $DIR/useless_comment.rs:20:5
|
--> $DIR/useless_comment.rs:29:5
|
||||||
|
|
|
|
||||||
LL | #[doc = "bar"] //~ ERROR doc comment not used by rustdoc
|
LL | #[doc = "bar"] //~ ERROR unused doc comment
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
LL | 3;
|
||||||
|
| - rustdoc does not generate documentation for expressions
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue