diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index d8ad299c3d38b..f3a3c853caca6 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -94,6 +94,14 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option {
if current_pos == end_pos { None } else { Some(current_pos) }
}
+fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool {
+ // https://spec.commonmark.org/0.30/#raw-html
+ //
+ // > A tag name consists of an ASCII letter followed by zero or more ASCII letters, digits, or
+ // > hyphens (-).
+ c.is_ascii_alphabetic() || !is_empty && (c == '-' || c.is_ascii_digit())
+}
+
fn extract_html_tag(
tags: &mut Vec<(String, Range)>,
text: &str,
@@ -117,7 +125,7 @@ fn extract_html_tag(
// Checking if this is a closing tag (like `` for ``).
if c == '/' && tag_name.is_empty() {
is_closing = true;
- } else if c.is_ascii_alphanumeric() {
+ } else if is_valid_for_html_tag_name(c, tag_name.is_empty()) {
tag_name.push(c);
} else {
if !tag_name.is_empty() {
diff --git a/src/test/rustdoc-ui/invalid-html-tags.rs b/src/test/rustdoc-ui/invalid-html-tags.rs
index cec44b6d2ca62..0f9d2e4b35d05 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.rs
+++ b/src/test/rustdoc-ui/invalid-html-tags.rs
@@ -108,3 +108,9 @@ pub fn j() {}
/// shouldn't warn!
/// ``````
pub fn k() {}
+
+/// Web Components style
+//~^ ERROR unclosed HTML tag `dashed-tags`
+/// Web Components style
+//~^ ERROR unopened HTML tag `unopened-tag`
+pub fn m() {}
diff --git a/src/test/rustdoc-ui/invalid-html-tags.stderr b/src/test/rustdoc-ui/invalid-html-tags.stderr
index 335e100c89d89..24a455576e80a 100644
--- a/src/test/rustdoc-ui/invalid-html-tags.stderr
+++ b/src/test/rustdoc-ui/invalid-html-tags.stderr
@@ -82,5 +82,17 @@ error: Unclosed HTML comment
LL | /// $DIR/invalid-html-tags.rs:114:26
+ |
+LL | /// Web Components style
+ | ^^^^^^^^^^^^^^^
+
+error: unclosed HTML tag `dashed-tags`
+ --> $DIR/invalid-html-tags.rs:112:26
+ |
+LL | /// Web Components style
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 15 previous errors