Remove bad merge
This commit is contained in:
parent
50ef8006eb
commit
09f0741449
@ -655,205 +655,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||||||
headers
|
headers
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD:src/tools/clippy/clippy_lints/src/doc/mod.rs
|
|
||||||
=======
|
|
||||||
fn check_link_quotes(cx: &LateContext<'_>, trimmed_text: &str, range: Range<usize>, fragments: Fragments<'_>) {
|
|
||||||
if trimmed_text.starts_with('\'')
|
|
||||||
&& trimmed_text.ends_with('\'')
|
|
||||||
&& let Some(span) = fragments.span(cx, range)
|
|
||||||
{
|
|
||||||
span_lint(
|
|
||||||
cx,
|
|
||||||
DOC_LINK_WITH_QUOTES,
|
|
||||||
span,
|
|
||||||
"possible intra-doc link using quotes instead of backticks",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, range: Range<usize>, fragments: Fragments<'_>) {
|
|
||||||
fn has_needless_main(code: String, edition: Edition) -> bool {
|
|
||||||
rustc_driver::catch_fatal_errors(|| {
|
|
||||||
rustc_span::create_session_globals_then(edition, || {
|
|
||||||
let filename = FileName::anon_source_code(&code);
|
|
||||||
|
|
||||||
let fallback_bundle =
|
|
||||||
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
|
|
||||||
let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle);
|
|
||||||
let handler = Handler::with_emitter(Box::new(emitter)).disable_warnings();
|
|
||||||
#[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_span_handler
|
|
||||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
|
||||||
let sess = ParseSess::with_span_handler(handler, sm);
|
|
||||||
|
|
||||||
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(errs) => {
|
|
||||||
drop(errs);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut relevant_main_found = false;
|
|
||||||
loop {
|
|
||||||
match parser.parse_item(ForceCollect::No) {
|
|
||||||
Ok(Some(item)) => match &item.kind {
|
|
||||||
ItemKind::Fn(box Fn {
|
|
||||||
sig, body: Some(block), ..
|
|
||||||
}) if item.ident.name == sym::main => {
|
|
||||||
let is_async = sig.header.coro_kind.map_or(false, |coro| coro.is_async());
|
|
||||||
let returns_nothing = match &sig.decl.output {
|
|
||||||
FnRetTy::Default(..) => true,
|
|
||||||
FnRetTy::Ty(ty) if ty.kind.is_unit() => true,
|
|
||||||
FnRetTy::Ty(_) => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if returns_nothing && !is_async && !block.stmts.is_empty() {
|
|
||||||
// This main function should be linted, but only if there are no other functions
|
|
||||||
relevant_main_found = true;
|
|
||||||
} else {
|
|
||||||
// This main function should not be linted, we're done
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Tests with one of these items are ignored
|
|
||||||
ItemKind::Static(..)
|
|
||||||
| ItemKind::Const(..)
|
|
||||||
| ItemKind::ExternCrate(..)
|
|
||||||
| ItemKind::ForeignMod(..)
|
|
||||||
// Another function was found; this case is ignored
|
|
||||||
| ItemKind::Fn(..) => return false,
|
|
||||||
_ => {},
|
|
||||||
},
|
|
||||||
Ok(None) => break,
|
|
||||||
Err(e) => {
|
|
||||||
e.cancel();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
relevant_main_found
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
let trailing_whitespace = text.len() - text.trim_end().len();
|
|
||||||
|
|
||||||
// Because of the global session, we need to create a new session in a different thread with
|
|
||||||
// the edition we need.
|
|
||||||
let text = text.to_owned();
|
|
||||||
if thread::spawn(move || has_needless_main(text, edition))
|
|
||||||
.join()
|
|
||||||
.expect("thread::spawn failed")
|
|
||||||
&& let Some(span) = fragments.span(cx, range.start..range.end - trailing_whitespace)
|
|
||||||
{
|
|
||||||
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_text(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
|
|
||||||
for word in text.split(|c: char| c.is_whitespace() || c == '\'') {
|
|
||||||
// Trim punctuation as in `some comment (see foo::bar).`
|
|
||||||
// ^^
|
|
||||||
// Or even as in `_foo bar_` which is emphasized. Also preserve `::` as a prefix/suffix.
|
|
||||||
let mut word = word.trim_matches(|c: char| !c.is_alphanumeric() && c != ':');
|
|
||||||
|
|
||||||
// Remove leading or trailing single `:` which may be part of a sentence.
|
|
||||||
if word.starts_with(':') && !word.starts_with("::") {
|
|
||||||
word = word.trim_start_matches(':');
|
|
||||||
}
|
|
||||||
if word.ends_with(':') && !word.ends_with("::") {
|
|
||||||
word = word.trim_end_matches(':');
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid_idents.contains(word) || word.chars().all(|c| c == ':') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust for the current word
|
|
||||||
let offset = word.as_ptr() as usize - text.as_ptr() as usize;
|
|
||||||
let span = Span::new(
|
|
||||||
span.lo() + BytePos::from_usize(offset),
|
|
||||||
span.lo() + BytePos::from_usize(offset + word.len()),
|
|
||||||
span.ctxt(),
|
|
||||||
span.parent(),
|
|
||||||
);
|
|
||||||
|
|
||||||
check_word(cx, word, span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
|
|
||||||
/// Checks if a string is upper-camel-case, i.e., starts with an uppercase and
|
|
||||||
/// contains at least two uppercase letters (`Clippy` is ok) and one lower-case
|
|
||||||
/// letter (`NASA` is ok).
|
|
||||||
/// Plurals are also excluded (`IDs` is ok).
|
|
||||||
fn is_camel_case(s: &str) -> bool {
|
|
||||||
if s.starts_with(|c: char| c.is_ascii_digit() | c.is_ascii_lowercase()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let s = s.strip_suffix('s').unwrap_or(s);
|
|
||||||
|
|
||||||
s.chars().all(char::is_alphanumeric)
|
|
||||||
&& s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1
|
|
||||||
&& s.chars().filter(|&c| c.is_lowercase()).take(1).count() > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_underscore(s: &str) -> bool {
|
|
||||||
s != "_" && !s.contains("\\_") && s.contains('_')
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_hyphen(s: &str) -> bool {
|
|
||||||
s != "-" && s.contains('-')
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(url) = Url::parse(word) {
|
|
||||||
// try to get around the fact that `foo::bar` parses as a valid URL
|
|
||||||
if !url.cannot_be_a_base() {
|
|
||||||
span_lint(
|
|
||||||
cx,
|
|
||||||
DOC_MARKDOWN,
|
|
||||||
span,
|
|
||||||
"you should put bare URLs between `<`/`>` or make a proper Markdown link",
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)
|
|
||||||
if has_underscore(word) && has_hyphen(word) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
|
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
|
||||||
|
|
||||||
span_lint_and_then(
|
|
||||||
cx,
|
|
||||||
DOC_MARKDOWN,
|
|
||||||
span,
|
|
||||||
"item in documentation is missing backticks",
|
|
||||||
|diag| {
|
|
||||||
let snippet = snippet_with_applicability(cx, span, "..", &mut applicability);
|
|
||||||
diag.span_suggestion_with_style(
|
|
||||||
span,
|
|
||||||
"try",
|
|
||||||
format!("`{snippet}`"),
|
|
||||||
applicability,
|
|
||||||
// always show the suggestion in a separate line, since the
|
|
||||||
// inline presentation adds another pair of backticks
|
|
||||||
SuggestionStyle::ShowAlways,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
>>>>>>> d116f1718f1 (Merge Async and Gen into CoroutineKind):src/tools/clippy/clippy_lints/src/doc.rs
|
|
||||||
struct FindPanicUnwrap<'a, 'tcx> {
|
struct FindPanicUnwrap<'a, 'tcx> {
|
||||||
cx: &'a LateContext<'tcx>,
|
cx: &'a LateContext<'tcx>,
|
||||||
panic_span: Option<Span>,
|
panic_span: Option<Span>,
|
||||||
|
Loading…
Reference in New Issue
Block a user