use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, layout::LayoutError, Ty, TyCtxt};
+use rustc_session::lint::FutureIncompatibilityReason;
use rustc_session::Session;
use rustc_span::edition::Edition;
use rustc_span::source_map::Spanned;
self.check_missing_docs_attrs(cx, hir::CRATE_HIR_ID, krate.item.inner, "the", "crate");
for macro_def in krate.exported_macros {
+ // Non exported macros should be skipped, since `missing_docs` only
+ // applies to externally visible items.
+ if !cx.access_levels.is_exported(macro_def.hir_id()) {
+ continue;
+ }
+
let attrs = cx.tcx.hir().attrs(macro_def.hir_id());
let has_doc = attrs.iter().any(|a| has_doc(cx.sess(), a));
if !has_doc {
"detects anonymous parameters",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
- edition: Some(Edition::Edition2018),
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
};
}
}
fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &[ast::Attribute]) {
+ use rustc_ast::token::CommentKind;
+
let mut attrs = attrs.iter().peekable();
// Accumulate a single span for sugared doc comments.
let mut sugared_span: Option<Span> = None;
while let Some(attr) = attrs.next() {
- if attr.is_doc_comment() {
+ let is_doc_comment = attr.is_doc_comment();
+ if is_doc_comment {
sugared_span =
Some(sugared_span.map_or(attr.span, |span| span.with_hi(attr.span.hi())));
}
let span = sugared_span.take().unwrap_or(attr.span);
- if attr.is_doc_comment() || cx.sess().check_name(attr, sym::doc) {
+ if is_doc_comment || cx.sess().check_name(attr, sym::doc) {
cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| {
let mut err = lint.build("unused doc comment");
err.span_label(
node_span,
format!("rustdoc does not generate documentation for {}", node_kind),
);
+ match attr.kind {
+ AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => {
+ err.help("use `//` for a plain comment");
+ }
+ AttrKind::DocComment(CommentKind::Block, _) => {
+ err.help("use `/* */` for a plain comment");
+ }
+ }
err.emit();
});
}
///
/// ### Explanation
///
- /// An function with generics must have its symbol mangled to accommodate
+ /// A function with generics must have its symbol mangled to accommodate
/// the generic parameter. The [`no_mangle` attribute] has no effect in
/// this situation, and should be removed.
///
"`...` range patterns are deprecated",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #80165 <https://github.com/rust-lang/rust/issues/80165>",
- edition: Some(Edition::Edition2021),
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
};
}
"detects edition keywords being used as an identifier",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #49716 <https://github.com/rust-lang/rust/issues/49716>",
- edition: Some(Edition::Edition2018),
+ reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
};
}
/// ### Example
///
/// ```rust
- /// #![feature(generic_associated_types)]
+ /// #![feature(const_generics)]
/// ```
///
/// {{produces}}
.iter()
.map(|(name, span, _)| (name, span))
.chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
- .filter(|(name, _)| rustc_feature::INCOMPLETE_FEATURES.iter().any(|f| name == &f))
+ .filter(|(&name, _)| features.incomplete(name))
.for_each(|(&name, &span)| {
cx.struct_span_lint(INCOMPLETE_FEATURES, span, |lint| {
let mut builder = lint.build(&format!(