Skip to content

Rollup of 10 pull requests #80078

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7cb74ed
Remove memoization leftovers
Dec 8, 2020
de1cd4b
Extra assertions in eval_body_using_ecx to disallow queries for
Dec 9, 2020
c6f2d49
fix issue #78496
wecing Dec 10, 2020
78c0680
update comments
wecing Dec 10, 2020
3812f70
fix test case issue ref
wecing Dec 10, 2020
b6f7eef
Remove unnecessary check and fix local_def_id parameter
Dec 10, 2020
a03feaa
add missing constraints
Dec 11, 2020
ed80815
Move binder for dyn to each list item
jackh726 Dec 11, 2020
0f30b7d
fix panic if converting ZST Vec to VecDeque
Stupremee Dec 13, 2020
d75618e
replace assert! with assert_eq!
Stupremee Dec 13, 2020
94fd1d3
BTreeMap: more expressive local variables in merge
ssomers Nov 23, 2020
09d528e
fix typo
Stupremee Dec 13, 2020
6c7835e
BTreeSet: simplify implementation of pop_first/pop_last
ssomers Nov 20, 2020
357565d
expand-yaml-anchors: Make the output directory separator-insensitive
JohnTitor Dec 14, 2020
01c2520
Add explanation for skip_binder in relate
jackh726 Dec 14, 2020
777ca99
Optimization for bool's PartialOrd impl
ChayimFriedman2 Dec 14, 2020
0e0ae47
Add a new lint to rustdoc for invalid codeblocks
poliorcetics Dec 15, 2020
cfc38d2
Take into account negative impls in "trait item not found" suggestions
LeSeulArtichaut Dec 7, 2020
8ad950f
Rollup merge of #79790 - LeSeulArtichaut:issue-79683, r=lcnr
Dylan-DPC Dec 16, 2020
34cec89
Rollup merge of #79816 - poliorcetics:rustdoc-fail-on-deny, r=jyn514
Dylan-DPC Dec 16, 2020
3039e70
Rollup merge of #79840 - dvtkrlbs:issue-79667, r=oli-obk
Dylan-DPC Dec 16, 2020
c382492
Rollup merge of #79882 - wecing:master, r=oli-obk
Dylan-DPC Dec 16, 2020
72006a8
Rollup merge of #79945 - jackh726:existential_trait_ref, r=nikomatsakis
Dylan-DPC Dec 16, 2020
4659002
Rollup merge of #80003 - Stupremee:fix-zst-vecdeque-conversion-panic,…
Dylan-DPC Dec 16, 2020
dd694f2
Rollup merge of #80006 - ssomers:btree_cleanup_6, r=Mark-Simulacrum
Dylan-DPC Dec 16, 2020
51007f5
Rollup merge of #80022 - ssomers:btree_cleanup_8, r=Mark-Simulacrum
Dylan-DPC Dec 16, 2020
34bd7c2
Rollup merge of #80026 - JohnTitor:separator-insensitive, r=Mark-Simu…
Dylan-DPC Dec 16, 2020
7c61d6a
Rollup merge of #80035 - ChayimFriedman2:patch-1, r=nagisa
Dylan-DPC Dec 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::{
BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS,
EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS,
MISSING_DOC_CODE_EXAMPLES, NON_AUTOLINKS, PRIVATE_DOC_TESTS,
INVALID_RUST_CODEBLOCK, MISSING_DOC_CODE_EXAMPLES, NON_AUTOLINKS, PRIVATE_DOC_TESTS,
};
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::Span;
Expand Down Expand Up @@ -320,6 +320,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
BROKEN_INTRA_DOC_LINKS,
PRIVATE_INTRA_DOC_LINKS,
INVALID_CODEBLOCK_ATTRIBUTES,
INVALID_RUST_CODEBLOCK,
MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS,
INVALID_HTML_TAGS
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1847,6 +1847,18 @@ declare_lint! {
"codeblock attribute looks a lot like a known one"
}

declare_lint! {
/// The `invalid_rust_codeblock` lint detects Rust code blocks in
/// documentation examples that are invalid (e.g. empty, not parsable as
/// Rust code). This is a `rustdoc` only lint, see the documentation in the
/// [rustdoc book].
///
/// [rustdoc book]: ../../../rustdoc/lints.html#invalid_rust_codeblock
pub INVALID_RUST_CODEBLOCK,
Warn,
"codeblock could not be parsed as valid Rust or is empty"
}

declare_lint! {
/// The `missing_crate_level_docs` lint detects if documentation is
/// missing at the crate root. This is a `rustdoc` only lint, see the
Expand Down Expand Up @@ -2847,6 +2859,7 @@ declare_lint_pass! {
BROKEN_INTRA_DOC_LINKS,
PRIVATE_INTRA_DOC_LINKS,
INVALID_CODEBLOCK_ATTRIBUTES,
INVALID_RUST_CODEBLOCK,
MISSING_CRATE_LEVEL_DOCS,
MISSING_DOC_CODE_EXAMPLES,
INVALID_HTML_TAGS,
Expand Down
35 changes: 35 additions & 0 deletions src/doc/rustdoc/src/lints.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,41 @@ warning: unclosed HTML tag `h1`

warning: 2 warnings emitted
```

## invalid_rust_codeblock

This lint **warns by default**. It detects Rust code blocks in documentation
examples that are invalid (e.g. empty, not parsable as Rust). For example:

```rust
/// Empty code block, with and without Rust:
///
/// ```rust
/// ```
///
/// Unclosed code block:
///
/// ```rust
fn main() {}
```

Which will give:

```text
warning: Rust code block is empty
--> src/lib.rs:3:5
|
3 | /// ```rust
| _____^
4 | | /// ```
| |_______^

warning: Rust code block is empty
--> src/lib.rs:8:5
|
8 | /// ```rust
| ^^^^^^^
```

## non_autolinks

Expand Down
2 changes: 2 additions & 0 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ crate fn run_core(
let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name;
let no_crate_level_docs = rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS.name;
let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
let invalid_rust_codeblock = rustc_lint::builtin::INVALID_RUST_CODEBLOCK.name;
let invalid_html_tags = rustc_lint::builtin::INVALID_HTML_TAGS.name;
let renamed_and_removed_lints = rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name;
let non_autolinks = rustc_lint::builtin::NON_AUTOLINKS.name;
Expand All @@ -337,6 +338,7 @@ crate fn run_core(
private_doc_tests.to_owned(),
no_crate_level_docs.to_owned(),
invalid_codeblock_attributes_name.to_owned(),
invalid_rust_codeblock.to_owned(),
invalid_html_tags.to_owned(),
renamed_and_removed_lints.to_owned(),
unknown_lints.to_owned(),
Expand Down
71 changes: 49 additions & 22 deletions src/librustdoc/passes/check_code_block_syntax.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler};
use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_parse::parse_stream_from_source_str;
use rustc_session::lint;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::{FilePathMapping, SourceMap};
use rustc_span::{FileName, InnerSpan};
Expand Down Expand Up @@ -47,51 +49,76 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
.unwrap_or(false);
let buffer = buffer.borrow();

if buffer.has_errors || is_empty {
let mut diag = if let Some(sp) =
super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
{
let warning_message = if buffer.has_errors {
if !(buffer.has_errors || is_empty) {
// No errors in a non-empty program.
return;
}

let local_id = match item.def_id.as_local() {
Some(id) => id,
// We don't need to check the syntax for other crates so returning
// without doing anything should not be a problem.
None => return,
};

let hir_id = self.cx.tcx.hir().local_def_id_to_hir_id(local_id);
let mark_with_text = code_block.syntax.is_none() && code_block.is_fenced;

// The span and whether it is precise or not.
let (sp, precise_span) = match super::source_span_for_markdown_range(
self.cx,
&dox,
&code_block.range,
&item.attrs,
) {
Some(sp) => (sp, true),
None => (super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()), false),
};

// lambda that will use the lint to start a new diagnostic and add
// a suggestion to it when needed.
let diag_builder = |lint: LintDiagnosticBuilder<'_>| {
let mut diag = if precise_span {
let msg = if buffer.has_errors {
"could not parse code block as Rust code"
} else {
"Rust code block is empty"
};

let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);

if code_block.syntax.is_none() && code_block.is_fenced {
let sp = sp.from_inner(InnerSpan::new(0, 3));
let mut diag = lint.build(msg);
if mark_with_text {
diag.span_suggestion(
sp,
sp.from_inner(InnerSpan::new(0, 3)),
"mark blocks that do not contain Rust code as text",
String::from("```text"),
Applicability::MachineApplicable,
);
}

diag
} else {
// We couldn't calculate the span of the markdown block that had the error, so our
// diagnostics are going to be a bit lacking.
let mut diag = self.cx.sess().struct_span_warn(
super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
"doc comment contains an invalid Rust code block",
);

if code_block.syntax.is_none() && code_block.is_fenced {
let mut diag = lint.build("doc comment contains an invalid Rust code block");
if mark_with_text {
diag.help("mark blocks that do not contain Rust code as text: ```text");
}

diag
};

// FIXME(#67563): Provide more context for these errors by displaying the spans inline.
for message in buffer.messages.iter() {
diag.note(&message);
}

diag.emit();
}
};

// Finally build and emit the completed diagnostic.
// All points of divergence have been handled earlier so this can be
// done the same way whether the span is precise or not.
self.cx.tcx.struct_span_lint_hir(
lint::builtin::INVALID_RUST_CODEBLOCK,
hir_id,
sp,
diag_builder,
);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/test/rustdoc-ui/invalid-syntax.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ LL | | /// \__________pkt->size___________/ \_result->size_/ \__pkt->si
LL | | /// ```
| |_______^
|
= note: `#[warn(invalid_rust_codeblock)]` on by default
= note: error from rustc: unknown start of token: \
= note: error from rustc: unknown start of token: \
= note: error from rustc: unknown start of token: \
Expand Down