Move lint machinery into a separate file
This commit is contained in:
parent
cc62018e61
commit
37e4cfe512
@ -12,8 +12,6 @@ use rustc_hir::{
|
||||
Path,
|
||||
};
|
||||
use rustc_interface::{interface, Queries};
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_lint_defs::{declare_tool_lint, Lint, LintId};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::middle::privacy::AccessLevels;
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
||||
@ -28,7 +26,6 @@ use rustc_span::DUMMY_SP;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::lazy::SyncLazy as Lazy;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -232,164 +229,6 @@ crate fn new_handler(
|
||||
)
|
||||
}
|
||||
|
||||
/// This function is used to setup the lint initialization. By default, in rustdoc, everything
|
||||
/// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
|
||||
/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTES" lint is activated in both
|
||||
/// modes.
|
||||
///
|
||||
/// A little detail easy to forget is that there is a way to set the lint level for all lints
|
||||
/// through the "WARNINGS" lint. To prevent this to happen, we set it back to its "normal" level
|
||||
/// inside this function.
|
||||
///
|
||||
/// It returns a tuple containing:
|
||||
/// * Vector of tuples of lints' name and their associated "max" level
|
||||
/// * HashMap of lint id with their associated "max" level
|
||||
pub(crate) fn init_lints<F>(
|
||||
mut allowed_lints: Vec<String>,
|
||||
lint_opts: Vec<(String, lint::Level)>,
|
||||
filter_call: F,
|
||||
) -> (Vec<(String, lint::Level)>, FxHashMap<lint::LintId, lint::Level>)
|
||||
where
|
||||
F: Fn(&lint::Lint) -> Option<(String, lint::Level)>,
|
||||
{
|
||||
let warnings_lint_name = lint::builtin::WARNINGS.name;
|
||||
|
||||
allowed_lints.push(warnings_lint_name.to_owned());
|
||||
allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
|
||||
|
||||
let lints = || {
|
||||
lint::builtin::HardwiredLints::get_lints()
|
||||
.into_iter()
|
||||
.chain(rustc_lint::SoftLints::get_lints().into_iter())
|
||||
};
|
||||
|
||||
let lint_opts = lints()
|
||||
.filter_map(|lint| {
|
||||
// Permit feature-gated lints to avoid feature errors when trying to
|
||||
// allow all lints.
|
||||
if lint.feature_gate.is_some() || allowed_lints.iter().any(|l| lint.name == l) {
|
||||
None
|
||||
} else {
|
||||
filter_call(lint)
|
||||
}
|
||||
})
|
||||
.chain(lint_opts.into_iter())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let lint_caps = lints()
|
||||
.filter_map(|lint| {
|
||||
// We don't want to allow *all* lints so let's ignore
|
||||
// those ones.
|
||||
if allowed_lints.iter().any(|l| lint.name == l) {
|
||||
None
|
||||
} else {
|
||||
Some((lint::LintId::of(lint), lint::Allow))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
(lint_opts, lint_caps)
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `broken_intra_doc_links` lint detects failures in resolving
|
||||
/// intra-doc link targets. This is a `rustdoc` only lint, see the
|
||||
/// documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#broken_intra_doc_links
|
||||
pub rustdoc::BROKEN_INTRA_DOC_LINKS,
|
||||
Warn,
|
||||
"failures in resolving intra-doc link targets"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// This is a subset of `broken_intra_doc_links` that warns when linking from
|
||||
/// a public item to a private one. This is a `rustdoc` only lint, see the
|
||||
/// documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#private_intra_doc_links
|
||||
pub rustdoc::PRIVATE_INTRA_DOC_LINKS,
|
||||
Warn,
|
||||
"linking from a public item to a private one"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `invalid_codeblock_attributes` lint detects code block attributes
|
||||
/// in documentation examples that have potentially mis-typed values. This
|
||||
/// is a `rustdoc` only lint, see the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#invalid_codeblock_attributes
|
||||
pub rustdoc::INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
Warn,
|
||||
"codeblock attribute looks a lot like a known one"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `missing_doc_code_examples` lint detects publicly-exported items
|
||||
/// without code samples in their documentation. This is a `rustdoc` only
|
||||
/// lint, see the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples
|
||||
pub rustdoc::MISSING_DOC_CODE_EXAMPLES,
|
||||
Allow,
|
||||
"detects publicly-exported items without code samples in their documentation"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `private_doc_tests` lint detects code samples in docs of private
|
||||
/// items not documented by `rustdoc`. This is a `rustdoc` only lint, see
|
||||
/// the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#private_doc_tests
|
||||
pub rustdoc::PRIVATE_DOC_TESTS,
|
||||
Allow,
|
||||
"detects code samples in docs of private items not documented by rustdoc"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `invalid_html_tags` lint detects invalid HTML tags. This is a
|
||||
/// `rustdoc` only lint, see the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#invalid_html_tags
|
||||
pub rustdoc::INVALID_HTML_TAGS,
|
||||
Allow,
|
||||
"detects invalid HTML tags in doc comments"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `non_autolinks` lint detects when a URL could be written using
|
||||
/// only angle brackets. This is a `rustdoc` only lint, see the
|
||||
/// documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#non_autolinks
|
||||
pub rustdoc::NON_AUTOLINKS,
|
||||
Warn,
|
||||
"detects URLs that could be written using only angle brackets"
|
||||
}
|
||||
|
||||
static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
|
||||
vec![
|
||||
BROKEN_INTRA_DOC_LINKS,
|
||||
PRIVATE_INTRA_DOC_LINKS,
|
||||
MISSING_DOC_CODE_EXAMPLES,
|
||||
PRIVATE_DOC_TESTS,
|
||||
INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
INVALID_HTML_TAGS,
|
||||
NON_AUTOLINKS,
|
||||
]
|
||||
});
|
||||
|
||||
crate fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
|
||||
lint_store.register_lints(&**RUSTDOC_LINTS);
|
||||
lint_store.register_group(
|
||||
true,
|
||||
"rustdoc",
|
||||
None,
|
||||
RUSTDOC_LINTS.iter().map(|&lint| LintId::of(lint)).collect(),
|
||||
);
|
||||
lint_store
|
||||
.register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links");
|
||||
}
|
||||
|
||||
/// Parse, resolve, and typecheck the given crate.
|
||||
crate fn create_config(
|
||||
RustdocOptions {
|
||||
@ -418,8 +257,8 @@ crate fn create_config(
|
||||
let cpath = Some(input.clone());
|
||||
let input = Input::File(input);
|
||||
|
||||
// In addition to those specific lints, we also need to allow those given through
|
||||
// command line, otherwise they'll get ignored and we don't want that.
|
||||
// By default, rustdoc ignores all lints.
|
||||
// Specifically unblock lints relevant to documentation or the lint machinery itself.
|
||||
let mut lints_to_show = vec![
|
||||
// it's unclear whether these should be part of rustdoc directly
|
||||
rustc_lint::builtin::MISSING_DOCS.name.to_string(),
|
||||
@ -428,12 +267,12 @@ crate fn create_config(
|
||||
rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name.to_string(),
|
||||
rustc_lint::builtin::UNKNOWN_LINTS.name.to_string(),
|
||||
];
|
||||
lints_to_show.extend(RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string()));
|
||||
lints_to_show.extend(crate::lint::RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string()));
|
||||
|
||||
let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| {
|
||||
let (lint_opts, lint_caps) = crate::lint::init_lints(lints_to_show, lint_opts, |lint| {
|
||||
// FIXME: why is this necessary?
|
||||
if lint.name == BROKEN_INTRA_DOC_LINKS.name
|
||||
|| lint.name == INVALID_CODEBLOCK_ATTRIBUTES.name
|
||||
if lint.name == crate::lint::BROKEN_INTRA_DOC_LINKS.name
|
||||
|| lint.name == crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name
|
||||
{
|
||||
None
|
||||
} else {
|
||||
@ -474,7 +313,7 @@ crate fn create_config(
|
||||
diagnostic_output: DiagnosticOutput::Default,
|
||||
stderr: None,
|
||||
lint_caps,
|
||||
register_lints: Some(box register_lints),
|
||||
register_lints: Some(box crate::lint::register_lints),
|
||||
override_queries: Some(|_sess, providers, _external_providers| {
|
||||
// Most lints will require typechecking, so just don't run them.
|
||||
providers.lint_mod = |_, _| {};
|
||||
|
@ -26,8 +26,8 @@ use std::str;
|
||||
|
||||
use crate::clean::Attributes;
|
||||
use crate::config::Options;
|
||||
use crate::core::init_lints;
|
||||
use crate::html::markdown::{self, ErrorCodes, Ignore, LangString};
|
||||
use crate::lint::init_lints;
|
||||
use crate::passes::span_of_attrs;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@ -44,10 +44,9 @@ crate struct TestOptions {
|
||||
crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
let input = config::Input::File(options.input.clone());
|
||||
|
||||
let invalid_codeblock_attributes_name = crate::core::INVALID_CODEBLOCK_ATTRIBUTES.name;
|
||||
let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;
|
||||
|
||||
// In addition to those specific lints, we also need to allow those given through
|
||||
// command line, otherwise they'll get ignored and we don't want that.
|
||||
// See core::create_config for what's going on here.
|
||||
let allowed_lints = vec![
|
||||
invalid_codeblock_attributes_name.to_owned(),
|
||||
lint::builtin::UNKNOWN_LINTS.name.to_owned(),
|
||||
@ -96,7 +95,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
diagnostic_output: DiagnosticOutput::Default,
|
||||
stderr: None,
|
||||
lint_caps,
|
||||
register_lints: Some(box crate::core::register_lints),
|
||||
register_lints: Some(box crate::lint::register_lints),
|
||||
override_queries: None,
|
||||
make_codegen_backend: None,
|
||||
registry: rustc_driver::diagnostics_registry(),
|
||||
|
@ -720,7 +720,7 @@ impl<'tcx> ExtraInfo<'tcx> {
|
||||
(None, None) => return,
|
||||
};
|
||||
self.tcx.struct_span_lint_hir(
|
||||
crate::core::INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
crate::lint::INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
hir_id,
|
||||
self.sp,
|
||||
|lint| {
|
||||
|
@ -86,6 +86,7 @@ mod formats;
|
||||
// used by the error-index generator, so it needs to be public
|
||||
pub mod html;
|
||||
mod json;
|
||||
crate mod lint;
|
||||
mod markdown;
|
||||
mod passes;
|
||||
mod theme;
|
||||
|
164
src/librustdoc/lint.rs
Normal file
164
src/librustdoc/lint.rs
Normal file
@ -0,0 +1,164 @@
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_lint_defs::{declare_tool_lint, Lint, LintId};
|
||||
use rustc_session::{lint, Session};
|
||||
|
||||
use std::lazy::SyncLazy as Lazy;
|
||||
|
||||
/// This function is used to setup the lint initialization. By default, in rustdoc, everything
|
||||
/// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
|
||||
/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTES" lint is activated in both
|
||||
/// modes.
|
||||
///
|
||||
/// A little detail easy to forget is that there is a way to set the lint level for all lints
|
||||
/// through the "WARNINGS" lint. To prevent this to happen, we set it back to its "normal" level
|
||||
/// inside this function.
|
||||
///
|
||||
/// It returns a tuple containing:
|
||||
/// * Vector of tuples of lints' name and their associated "max" level
|
||||
/// * HashMap of lint id with their associated "max" level
|
||||
pub(crate) fn init_lints<F>(
|
||||
mut allowed_lints: Vec<String>,
|
||||
lint_opts: Vec<(String, lint::Level)>,
|
||||
filter_call: F,
|
||||
) -> (Vec<(String, lint::Level)>, FxHashMap<lint::LintId, lint::Level>)
|
||||
where
|
||||
F: Fn(&lint::Lint) -> Option<(String, lint::Level)>,
|
||||
{
|
||||
let warnings_lint_name = lint::builtin::WARNINGS.name;
|
||||
|
||||
allowed_lints.push(warnings_lint_name.to_owned());
|
||||
allowed_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned());
|
||||
|
||||
let lints = || {
|
||||
lint::builtin::HardwiredLints::get_lints()
|
||||
.into_iter()
|
||||
.chain(rustc_lint::SoftLints::get_lints().into_iter())
|
||||
};
|
||||
|
||||
let lint_opts = lints()
|
||||
.filter_map(|lint| {
|
||||
// Permit feature-gated lints to avoid feature errors when trying to
|
||||
// allow all lints.
|
||||
if lint.feature_gate.is_some() || allowed_lints.iter().any(|l| lint.name == l) {
|
||||
None
|
||||
} else {
|
||||
filter_call(lint)
|
||||
}
|
||||
})
|
||||
.chain(lint_opts.into_iter())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let lint_caps = lints()
|
||||
.filter_map(|lint| {
|
||||
// We don't want to allow *all* lints so let's ignore
|
||||
// those ones.
|
||||
if allowed_lints.iter().any(|l| lint.name == l) {
|
||||
None
|
||||
} else {
|
||||
Some((lint::LintId::of(lint), lint::Allow))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
(lint_opts, lint_caps)
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `broken_intra_doc_links` lint detects failures in resolving
|
||||
/// intra-doc link targets. This is a `rustdoc` only lint, see the
|
||||
/// documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#broken_intra_doc_links
|
||||
pub rustdoc::BROKEN_INTRA_DOC_LINKS,
|
||||
Warn,
|
||||
"failures in resolving intra-doc link targets"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// This is a subset of `broken_intra_doc_links` that warns when linking from
|
||||
/// a public item to a private one. This is a `rustdoc` only lint, see the
|
||||
/// documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#private_intra_doc_links
|
||||
pub rustdoc::PRIVATE_INTRA_DOC_LINKS,
|
||||
Warn,
|
||||
"linking from a public item to a private one"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `invalid_codeblock_attributes` lint detects code block attributes
|
||||
/// in documentation examples that have potentially mis-typed values. This
|
||||
/// is a `rustdoc` only lint, see the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#invalid_codeblock_attributes
|
||||
pub rustdoc::INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
Warn,
|
||||
"codeblock attribute looks a lot like a known one"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `missing_doc_code_examples` lint detects publicly-exported items
|
||||
/// without code samples in their documentation. This is a `rustdoc` only
|
||||
/// lint, see the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#missing_doc_code_examples
|
||||
pub rustdoc::MISSING_DOC_CODE_EXAMPLES,
|
||||
Allow,
|
||||
"detects publicly-exported items without code samples in their documentation"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `private_doc_tests` lint detects code samples in docs of private
|
||||
/// items not documented by `rustdoc`. This is a `rustdoc` only lint, see
|
||||
/// the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#private_doc_tests
|
||||
pub rustdoc::PRIVATE_DOC_TESTS,
|
||||
Allow,
|
||||
"detects code samples in docs of private items not documented by rustdoc"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `invalid_html_tags` lint detects invalid HTML tags. This is a
|
||||
/// `rustdoc` only lint, see the documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#invalid_html_tags
|
||||
pub rustdoc::INVALID_HTML_TAGS,
|
||||
Allow,
|
||||
"detects invalid HTML tags in doc comments"
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `non_autolinks` lint detects when a URL could be written using
|
||||
/// only angle brackets. This is a `rustdoc` only lint, see the
|
||||
/// documentation in the [rustdoc book].
|
||||
///
|
||||
/// [rustdoc book]: ../../../rustdoc/lints.html#non_autolinks
|
||||
pub rustdoc::NON_AUTOLINKS,
|
||||
Warn,
|
||||
"detects URLs that could be written using only angle brackets"
|
||||
}
|
||||
|
||||
crate static RUSTDOC_LINTS: Lazy<Vec<&'static Lint>> = Lazy::new(|| {
|
||||
vec![
|
||||
BROKEN_INTRA_DOC_LINKS,
|
||||
PRIVATE_INTRA_DOC_LINKS,
|
||||
MISSING_DOC_CODE_EXAMPLES,
|
||||
PRIVATE_DOC_TESTS,
|
||||
INVALID_CODEBLOCK_ATTRIBUTES,
|
||||
INVALID_HTML_TAGS,
|
||||
NON_AUTOLINKS,
|
||||
]
|
||||
});
|
||||
|
||||
crate fn register_lints(_sess: &Session, lint_store: &mut LintStore) {
|
||||
lint_store.register_lints(&**RUSTDOC_LINTS);
|
||||
lint_store.register_group(
|
||||
true,
|
||||
"rustdoc",
|
||||
None,
|
||||
RUSTDOC_LINTS.iter().map(|&lint| LintId::of(lint)).collect(),
|
||||
);
|
||||
lint_store
|
||||
.register_renamed("intra_doc_link_resolution_failure", "rustdoc::broken_intra_doc_links");
|
||||
}
|
@ -32,9 +32,9 @@ use std::ops::Range;
|
||||
|
||||
use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLink, PrimitiveType};
|
||||
use crate::core::DocContext;
|
||||
use crate::core::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
|
||||
use crate::fold::DocFolder;
|
||||
use crate::html::markdown::{markdown_links, MarkdownLink};
|
||||
use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
|
||||
use crate::passes::Pass;
|
||||
|
||||
use super::span_of_attrs;
|
||||
|
@ -68,7 +68,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo
|
||||
return false;
|
||||
}
|
||||
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_local());
|
||||
let (level, source) = cx.tcx.lint_level_at_node(crate::core::MISSING_DOC_CODE_EXAMPLES, hir_id);
|
||||
let (level, source) = cx.tcx.lint_level_at_node(crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id);
|
||||
level != lint::Level::Allow || matches!(source, LintLevelSource::Default)
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
|
||||
debug!("reporting error for {:?} (hir_id={:?})", item, hir_id);
|
||||
let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
|
||||
cx.tcx.struct_span_lint_hir(
|
||||
crate::core::MISSING_DOC_CODE_EXAMPLES,
|
||||
crate::lint::MISSING_DOC_CODE_EXAMPLES,
|
||||
hir_id,
|
||||
sp,
|
||||
|lint| lint.build("missing code example in this documentation").emit(),
|
||||
@ -98,7 +98,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
|
||||
}
|
||||
} else if tests.found_tests > 0 && !cx.renderinfo.access_levels.is_public(item.def_id) {
|
||||
cx.tcx.struct_span_lint_hir(
|
||||
crate::core::PRIVATE_DOC_TESTS,
|
||||
crate::lint::PRIVATE_DOC_TESTS,
|
||||
hir_id,
|
||||
span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
|
||||
|lint| lint.build("documentation test in private item").emit(),
|
||||
|
@ -182,7 +182,7 @@ impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> {
|
||||
Some(sp) => sp,
|
||||
None => span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
|
||||
};
|
||||
cx.tcx.struct_span_lint_hir(crate::core::INVALID_HTML_TAGS, hir_id, sp, |lint| {
|
||||
cx.tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
|
||||
lint.build(msg).emit()
|
||||
});
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ impl<'a, 'tcx> DocFolder for NonAutolinksLinter<'a, 'tcx> {
|
||||
let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs)
|
||||
.or_else(|| span_of_attrs(&item.attrs))
|
||||
.unwrap_or(item.source.span());
|
||||
cx.tcx.struct_span_lint_hir(crate::core::NON_AUTOLINKS, hir_id, sp, |lint| {
|
||||
cx.tcx.struct_span_lint_hir(crate::lint::NON_AUTOLINKS, hir_id, sp, |lint| {
|
||||
lint.build(msg)
|
||||
.span_suggestion(
|
||||
sp,
|
||||
|
Loading…
x
Reference in New Issue
Block a user