diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2020-09-26 15:18:38 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2020-10-03 14:16:24 +0200 |
| commit | 6163d892248a2af02b36a0121bb5bf02a5566d2b (patch) | |
| tree | 1938dcdbef73a5fa14d73c3002987da9e0cf26c2 | |
| parent | 4a3746e67b06bfd3bd11c8cae1c3acab944211bf (diff) | |
| download | rust-6163d892248a2af02b36a0121bb5bf02a5566d2b.tar.gz rust-6163d892248a2af02b36a0121bb5bf02a5566d2b.zip | |
Improve code
| -rw-r--r-- | src/librustdoc/passes/html_tags.rs | 22 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/invalid-html-tags.rs | 19 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/invalid-html-tags.stderr | 30 |
3 files changed, 58 insertions, 13 deletions
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index dfc5373886a..79035ba79ff 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -45,18 +45,20 @@ fn drop_tag( range: Range<usize>, f: &impl Fn(&str, &Range<usize>), ) { - if let Some(pos) = tags.iter().position(|(t, _)| *t == tag_name) { - for _ in pos + 1..tags.len() { - if ALLOWED_UNCLOSED.iter().find(|&at| at == &tags[pos + 1].0).is_some() { + if let Some(pos) = tags.iter().rev().position(|(t, _)| *t == tag_name) { + // Because this is from a `rev` iterator, the position is reversed as well! + let pos = tags.len() - 1 - pos; + for (last_tag_name, last_tag_span) in tags.drain(pos + 1..) { + if ALLOWED_UNCLOSED.iter().any(|&at| at == &last_tag_name) { continue; } // `tags` is used as a queue, meaning that everything after `pos` is included inside it. // So `<h2><h3></h2>` will look like `["h2", "h3"]`. So when closing `h2`, we will still // have `h3`, meaning the tag wasn't closed as it should have. - f(&format!("unclosed HTML tag `{}`", tags[pos + 1].0), &tags[pos + 1].1); - tags.remove(pos + 1); + f(&format!("unclosed HTML tag `{}`", last_tag_name), &last_tag_span); } - tags.remove(pos); + // Remove the `tag_name` that was originally closed + tags.pop(); } else { // It can happen for example in this case: `<h2></script></h2>` (the `h2` tag isn't required // but it helps for the visualization). @@ -84,7 +86,13 @@ fn extract_tag( tag_name.push(*c); } else { if !tag_name.is_empty() { - let r = Range { start: range.start + start_pos, end: range.start + pos }; + let mut r = + Range { start: range.start + start_pos, end: range.start + pos }; + if *c == '>' { + // In case we have a tag without attribute, we can consider the span to + // refer to it fully. + r.end += 1; + } if is_closing { drop_tag(tags, tag_name, r, f); } else { diff --git a/src/test/rustdoc-ui/invalid-html-tags.rs b/src/test/rustdoc-ui/invalid-html-tags.rs index b188e16f605..51bbae2a0b6 100644 --- a/src/test/rustdoc-ui/invalid-html-tags.rs +++ b/src/test/rustdoc-ui/invalid-html-tags.rs @@ -20,3 +20,22 @@ pub fn foo() {} /// </hello> //~^ ERROR unopened HTML tag `hello` pub fn f() {} + +/// <div> +/// <br/> <p> +//~^ ERROR unclosed HTML tag `p` +/// </div> +pub fn a() {} + +/// <div> +/// <p> +/// <div></div> +/// </p> +/// </div> +pub fn b() {} + +/// <div style="hello"> +//~^ ERROR unclosed HTML tag `div` +/// <h3> +//~^ ERROR unclosed HTML tag `h3` +pub fn c() {} diff --git a/src/test/rustdoc-ui/invalid-html-tags.stderr b/src/test/rustdoc-ui/invalid-html-tags.stderr index f8e67732f63..d2e9704a227 100644 --- a/src/test/rustdoc-ui/invalid-html-tags.stderr +++ b/src/test/rustdoc-ui/invalid-html-tags.stderr @@ -2,7 +2,7 @@ error: unclosed HTML tag `unknown` --> $DIR/invalid-html-tags.rs:7:5 | LL | /// <unknown> - | ^^^^^^^^ + | ^^^^^^^^^ | note: the lint level is defined here --> $DIR/invalid-html-tags.rs:1:9 @@ -14,25 +14,43 @@ error: unclosed HTML tag `script` --> $DIR/invalid-html-tags.rs:10:5 | LL | /// <script> - | ^^^^^^^ + | ^^^^^^^^ error: unclosed HTML tag `h2` --> $DIR/invalid-html-tags.rs:15:7 | LL | /// <h2> - | ^^^ + | ^^^^ error: unclosed HTML tag `h3` --> $DIR/invalid-html-tags.rs:17:9 | LL | /// <h3> - | ^^^ + | ^^^^ error: unopened HTML tag `hello` --> $DIR/invalid-html-tags.rs:20:5 | LL | /// </hello> - | ^^^^^^^ + | ^^^^^^^^ + +error: unclosed HTML tag `p` + --> $DIR/invalid-html-tags.rs:25:14 + | +LL | /// <br/> <p> + | ^^^ + +error: unclosed HTML tag `div` + --> $DIR/invalid-html-tags.rs:37:5 + | +LL | /// <div style="hello"> + | ^^^^ + +error: unclosed HTML tag `h3` + --> $DIR/invalid-html-tags.rs:39:7 + | +LL | /// <h3> + | ^^^^ -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors |
