diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e385ac44113a6..90ec4d07ff9c0 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1283,12 +1283,10 @@ impl<'a> Parser<'a> { /// Parses an enum declaration. fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> { if self.token.is_keyword(kw::Struct) { - let mut err = self.struct_span_err( - self.prev_token.span.to(self.token.span), - "`enum` and `struct` are mutually exclusive", - ); + let span = self.prev_token.span.to(self.token.span); + let mut err = self.struct_span_err(span, "`enum` and `struct` are mutually exclusive"); err.span_suggestion( - self.prev_token.span.to(self.token.span), + span, "replace `enum struct` with", "enum", Applicability::MachineApplicable, @@ -1307,7 +1305,8 @@ impl<'a> Parser<'a> { let (variants, _) = self .parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()) - .map_err(|e| { + .map_err(|mut e| { + e.span_label(id.span, "while parsing this enum"); self.recover_stmt(); e })?; @@ -1332,7 +1331,8 @@ impl<'a> Parser<'a> { let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) { // Parse a struct variant. - let (fields, recovered) = this.parse_record_struct_body("struct", false)?; + let (fields, recovered) = + this.parse_record_struct_body("struct", ident.span, false)?; VariantData::Struct(fields, recovered) } else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) { VariantData::Tuple(this.parse_tuple_struct_body()?, DUMMY_NODE_ID) @@ -1386,8 +1386,11 @@ impl<'a> Parser<'a> { VariantData::Unit(DUMMY_NODE_ID) } else { // If we see: `struct Foo where T: Copy { ... }` - let (fields, recovered) = - self.parse_record_struct_body("struct", generics.where_clause.has_where_token)?; + let (fields, recovered) = self.parse_record_struct_body( + "struct", + class_name.span, + generics.where_clause.has_where_token, + )?; VariantData::Struct(fields, recovered) } // No `where` so: `struct Foo;` @@ -1395,8 +1398,11 @@ impl<'a> Parser<'a> { VariantData::Unit(DUMMY_NODE_ID) // Record-style struct definition } else if self.token == token::OpenDelim(Delimiter::Brace) { - let (fields, recovered) = - self.parse_record_struct_body("struct", generics.where_clause.has_where_token)?; + let (fields, recovered) = self.parse_record_struct_body( + "struct", + class_name.span, + generics.where_clause.has_where_token, + )?; VariantData::Struct(fields, recovered) // Tuple-style struct definition with optional where-clause. } else if self.token == token::OpenDelim(Delimiter::Parenthesis) { @@ -1425,12 +1431,18 @@ impl<'a> Parser<'a> { let vdata = if self.token.is_keyword(kw::Where) { generics.where_clause = self.parse_where_clause()?; - let (fields, recovered) = - self.parse_record_struct_body("union", generics.where_clause.has_where_token)?; + let (fields, recovered) = self.parse_record_struct_body( + "union", + class_name.span, + generics.where_clause.has_where_token, + )?; VariantData::Struct(fields, recovered) } else if self.token == token::OpenDelim(Delimiter::Brace) { - let (fields, recovered) = - self.parse_record_struct_body("union", generics.where_clause.has_where_token)?; + let (fields, recovered) = self.parse_record_struct_body( + "union", + class_name.span, + generics.where_clause.has_where_token, + )?; VariantData::Struct(fields, recovered) } else { let token_str = super::token_descr(&self.token); @@ -1446,6 +1458,7 @@ impl<'a> Parser<'a> { fn parse_record_struct_body( &mut self, adt_ty: &str, + ident_span: Span, parsed_where: bool, ) -> PResult<'a, (Vec, /* recovered */ bool)> { let mut fields = Vec::new(); @@ -1460,6 +1473,7 @@ impl<'a> Parser<'a> { match field { Ok(field) => fields.push(field), Err(mut err) => { + err.span_label(ident_span, format!("while parsing this {adt_ty}")); err.emit(); break; } diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 905212eb372b1..372439f14ec83 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -709,12 +709,19 @@ pub use macros::Debug; /// Format trait for an empty format, `{}`. /// +/// Implementing this trait for a type will automatically implement the +/// [`ToString`][tostring] trait for the type, allowing the usage +/// of the [`.to_string()`][tostring_function] method. Prefer implementing +/// the `Display` trait for a type, rather than [`ToString`][tostring]. +/// /// `Display` is similar to [`Debug`], but `Display` is for user-facing /// output, and so cannot be derived. /// /// For more information on formatters, see [the module-level documentation][module]. /// /// [module]: ../../std/fmt/index.html +/// [tostring]: ../../std/string/trait.ToString.html +/// [tostring_function]: ../../std/string/trait.ToString.html#tymethod.to_string /// /// # Examples /// diff --git a/library/core/src/option.rs b/library/core/src/option.rs index ed7703befcfa3..4a93df4591b7a 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -834,20 +834,12 @@ impl Option { /// /// # Examples /// - /// Converts a string to an integer, turning poorly-formed strings - /// into 0 (the default value for integers). [`parse`] converts - /// a string to any other type that implements [`FromStr`], returning - /// [`None`] on error. - /// /// ``` - /// let good_year_from_input = "1909"; - /// let bad_year_from_input = "190blarg"; - /// // Result::ok() converts a Result to an Option - /// let good_year = good_year_from_input.parse().ok().unwrap_or_default(); - /// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default(); + /// let x: Option = None; + /// let y: Option = Some(12); /// - /// assert_eq!(1909, good_year); - /// assert_eq!(0, bad_year); + /// assert_eq!(x.unwrap_or_default(), 0); + /// assert_eq!(y.unwrap_or_default(), 12); /// ``` /// /// [default value]: Default::default diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index cd04fa0044241..aed8fbf092ed3 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2076,7 +2076,7 @@ impl [T] { SplitN::new(self.split(pred), n) } - /// Returns an iterator over subslices separated by elements that match + /// Returns an iterator over mutable subslices separated by elements that match /// `pred`, limited to returning at most `n` items. The matched element is /// not contained in the subslices. /// diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 2e2bee78b95f9..7ab65bff3469f 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -274,7 +274,7 @@ pub(crate) fn print_src( ) { let lines = s.lines().count(); let mut line_numbers = Buffer::empty_from(buf); - line_numbers.write_str("
");
+    line_numbers.write_str("
");
     match source_context {
         SourceContext::Standalone => {
             for line in 1..=lines {
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 28dc4bf30108e..e7a05b80c127f 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -299,15 +299,6 @@ summary {
 
 /* Fix some style changes due to normalize.css 8 */
 
-td,
-th {
-	padding: 0;
-}
-
-table {
-	border-collapse: collapse;
-}
-
 button,
 input,
 optgroup,
@@ -578,7 +569,7 @@ h2.location a {
 	position: relative;
 }
 
-.example-wrap > pre.line-number {
+pre.example-line-numbers {
 	overflow: initial;
 	border: 1px solid;
 	padding: 13px 8px;
@@ -591,15 +582,15 @@ h2.location a {
 	text-decoration: underline;
 }
 
-.line-numbers {
+.src-line-numbers {
 	text-align: right;
 }
-.rustdoc:not(.source) .example-wrap > pre:not(.line-number) {
+.rustdoc:not(.source) .example-wrap > pre:not(.example-line-numbers) {
 	width: 100%;
 	overflow-x: auto;
 }
 
-.rustdoc:not(.source) .example-wrap > pre.line-numbers {
+.rustdoc:not(.source) .example-wrap > pre.src-line-numbers {
 	width: auto;
 	overflow-x: visible;
 }
@@ -612,14 +603,14 @@ h2.location a {
 	text-align: center;
 }
 
-.content > .example-wrap pre.line-numbers {
+.content > .example-wrap pre.src-line-numbers {
 	position: relative;
 	-webkit-user-select: none;
 	-moz-user-select: none;
 	-ms-user-select: none;
 	user-select: none;
 }
-.line-numbers span {
+.src-line-numbers span {
 	cursor: pointer;
 }
 
@@ -695,6 +686,7 @@ pre, .rustdoc.source .example-wrap {
 	width: calc(100% - 2px);
 	overflow-x: auto;
 	display: block;
+	border-collapse: collapse;
 }
 
 .docblock table td {
@@ -2067,7 +2059,7 @@ in storage.js plus the media query with (min-width: 701px)
 	padding-bottom: 0;
 }
 
-.scraped-example:not(.expanded) .code-wrapper pre.line-numbers {
+.scraped-example:not(.expanded) .code-wrapper pre.src-line-numbers {
 	overflow-x: hidden;
 }
 
@@ -2113,12 +2105,12 @@ in storage.js plus the media query with (min-width: 701px)
 	bottom: 0;
 }
 
-.scraped-example .code-wrapper .line-numbers {
+.scraped-example .code-wrapper .src-line-numbers {
 	margin: 0;
 	padding: 14px 0;
 }
 
-.scraped-example .code-wrapper .line-numbers span {
+.scraped-example .code-wrapper .src-line-numbers span {
 	padding: 0 14px;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index e7a898e9fa62c..44238ca573dcd 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -93,8 +93,8 @@ pre, .rustdoc.source .example-wrap {
 	color: #ff7733;
 }
 
-.line-numbers span { color: #5c6773; }
-.line-numbers .line-highlighted {
+.src-line-numbers span { color: #5c6773; }
+.src-line-numbers .line-highlighted {
 	color: #708090;
 	background-color: rgba(255, 236, 164, 0.06);
 	padding-right: 4px;
@@ -171,7 +171,7 @@ details.rustdoc-toggle > summary::before {
 	color: #788797;
 }
 
-.line-numbers :target { background-color: transparent; }
+.src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
 pre.rust .number, pre.rust .string { color: #b8cc52; }
@@ -190,7 +190,7 @@ pre.rust .attribute {
 	color: #e6e1cf;
 }
 
-.example-wrap > pre.line-number {
+pre.example-line-numbers {
 	color: #5c67736e;
 	border: none;
 }
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 07a1ed8b7db74..858d836c03d5e 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -54,8 +54,8 @@ input:focus + .slider {
 	background: #444;
 }
 
-.line-numbers span { color: #3B91E2; }
-.line-numbers .line-highlighted {
+.src-line-numbers span { color: #3B91E2; }
+.src-line-numbers .line-highlighted {
 	background-color: #0a042f !important;
 }
 
@@ -141,7 +141,7 @@ details.rustdoc-toggle > summary::before {
 	background: none;
 }
 
-.line-numbers :target { background-color: transparent; }
+.src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
 pre.rust .kw { color: #ab8ac1; }
@@ -155,7 +155,7 @@ pre.rust .question-mark {
 	color: #ff9011;
 }
 
-.example-wrap > pre.line-number {
+pre.example-line-numbers {
 	border-color: #4a4949;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 64335f6292801..6fbea6f6c7a5d 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -53,8 +53,8 @@ input:focus + .slider {
 	background-color: #fff;
 }
 
-.line-numbers span { color: #c67e2d; }
-.line-numbers .line-highlighted {
+.src-line-numbers span { color: #c67e2d; }
+.src-line-numbers .line-highlighted {
 	background-color: #FDFFD3 !important;
 }
 
@@ -125,7 +125,7 @@ body.source .example-wrap pre.rust a {
 .stab { background: #FFF5D6; border-color: #FFC600; }
 .stab.portability > code { background: none; }
 
-.line-numbers :target { background-color: transparent; }
+.src-line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
 pre.rust .kw { color: #8959A8; }
@@ -141,7 +141,7 @@ pre.rust .question-mark {
 	color: #ff9011;
 }
 
-.example-wrap > pre.line-number {
+pre.example-line-numbers {
 	border-color: #c7c7c7;
 }
 
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index c9674f11a5ecf..bbaf6d3b50797 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -699,7 +699,7 @@ function loadCss(cssFileName) {
     window.rustdoc_add_line_numbers_to_examples = () => {
         onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => {
             const parent = x.parentNode;
-            const line_numbers = parent.querySelectorAll(".line-number");
+            const line_numbers = parent.querySelectorAll(".example-line-numbers");
             if (line_numbers.length > 0) {
                 return;
             }
@@ -709,7 +709,7 @@ function loadCss(cssFileName) {
                 elems.push(i + 1);
             }
             const node = document.createElement("pre");
-            addClass(node, "line-number");
+            addClass(node, "example-line-numbers");
             node.innerHTML = elems.join("\n");
             parent.insertBefore(node, x);
         });
@@ -718,7 +718,7 @@ function loadCss(cssFileName) {
     window.rustdoc_remove_line_numbers_from_examples = () => {
         onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => {
             const parent = x.parentNode;
-            const line_numbers = parent.querySelectorAll(".line-number");
+            const line_numbers = parent.querySelectorAll(".example-line-numbers");
             for (const node of line_numbers) {
                 parent.removeChild(node);
             }
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index fd7a1449763eb..d0fd115fd15c6 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -8,7 +8,7 @@
 
     // Scroll code block to the given code location
     function scrollToLoc(elt, loc) {
-        const lines = elt.querySelector(".line-numbers");
+        const lines = elt.querySelector(".src-line-numbers");
         let scrollOffset;
 
         // If the block is greater than the size of the viewer,
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index 06d15d9e5ffea..8286e9201e649 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -183,7 +183,7 @@ function highlightSourceLines(match) {
     if (x) {
         x.scrollIntoView();
     }
-    onEachLazy(document.getElementsByClassName("line-numbers"), e => {
+    onEachLazy(document.getElementsByClassName("src-line-numbers"), e => {
         onEachLazy(e.getElementsByTagName("span"), i_e => {
             removeClass(i_e, "line-highlighted");
         });
@@ -245,7 +245,7 @@ window.addEventListener("hashchange", () => {
     }
 });
 
-onEachLazy(document.getElementsByClassName("line-numbers"), el => {
+onEachLazy(document.getElementsByClassName("src-line-numbers"), el => {
     el.addEventListener("click", handleSourceHighlight);
 });
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 49a31f5f1da1f..4170412caef87 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -272,7 +272,12 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
         ConstantItem(c) => ItemEnum::Constant(c.into_tcx(tcx)),
         MacroItem(m) => ItemEnum::Macro(m.source),
         ProcMacroItem(m) => ItemEnum::ProcMacro(m.into_tcx(tcx)),
-        PrimitiveItem(p) => ItemEnum::PrimitiveType(p.as_sym().to_string()),
+        PrimitiveItem(p) => {
+            ItemEnum::Primitive(Primitive {
+                name: p.as_sym().to_string(),
+                impls: Vec::new(), // Added in JsonRenderer::item
+            })
+        }
         TyAssocConstItem(ty) => ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: None },
         AssocConstItem(ty, default) => {
             ItemEnum::AssocConst { type_: ty.into_tcx(tcx), default: Some(default.expr(tcx)) }
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 5e8f5f6fe3eb9..8d6450838c1d0 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -219,12 +219,15 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                     u.impls = self.get_impls(item_id.expect_def_id());
                     false
                 }
+                types::ItemEnum::Primitive(ref mut p) => {
+                    p.impls = self.get_impls(item_id.expect_def_id());
+                    false
+                }
 
                 types::ItemEnum::Method(_)
                 | types::ItemEnum::Module(_)
                 | types::ItemEnum::AssocConst { .. }
-                | types::ItemEnum::AssocType { .. }
-                | types::ItemEnum::PrimitiveType(_) => true,
+                | types::ItemEnum::AssocType { .. } => true,
                 types::ItemEnum::ExternCrate { .. }
                 | types::ItemEnum::Import(_)
                 | types::ItemEnum::StructField(_)
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index fb183042670e8..7379b04ad1677 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -9,7 +9,7 @@ use std::path::PathBuf;
 use serde::{Deserialize, Serialize};
 
 /// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 21;
+pub const FORMAT_VERSION: u32 = 22;
 
 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
 /// about the language items in the local crate, as well as info about external items to allow
@@ -254,7 +254,7 @@ pub enum ItemEnum {
     Macro(String),
     ProcMacro(ProcMacro),
 
-    PrimitiveType(String),
+    Primitive(Primitive),
 
     AssocConst {
         #[serde(rename = "type")]
@@ -709,5 +709,11 @@ pub struct Static {
     pub expr: String,
 }
 
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct Primitive {
+    pub name: String,
+    pub impls: Vec,
+}
+
 #[cfg(test)]
 mod tests;
diff --git a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs
index bac3970a4d37f..d8658a0f25577 100644
--- a/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs
+++ b/src/test/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs
@@ -1,8 +1,8 @@
 // Scraped example should only include line numbers for items b and c in ex.rs
-// @!has foobar/fn.f.html '//*[@class="line-numbers"]' '14'
-// @has foobar/fn.f.html '//*[@class="line-numbers"]' '15'
-// @has foobar/fn.f.html '//*[@class="line-numbers"]' '21'
-// @!has foobar/fn.f.html '//*[@class="line-numbers"]' '22'
+// @!has foobar/fn.f.html '//*[@class="src-line-numbers"]' '14'
+// @has foobar/fn.f.html '//*[@class="src-line-numbers"]' '15'
+// @has foobar/fn.f.html '//*[@class="src-line-numbers"]' '21'
+// @!has foobar/fn.f.html '//*[@class="src-line-numbers"]' '22'
 
 pub fn f() {}
 
diff --git a/src/test/rustdoc-gui/basic-code.goml b/src/test/rustdoc-gui/basic-code.goml
index 27deb2c989c8b..79090b499c832 100644
--- a/src/test/rustdoc-gui/basic-code.goml
+++ b/src/test/rustdoc-gui/basic-code.goml
@@ -1,3 +1,3 @@
 goto: file://|DOC_PATH|/test_docs/index.html
 click: ".srclink"
-assert-count: (".line-numbers", 1)
+assert-count: (".src-line-numbers", 1)
diff --git a/src/test/rustdoc-gui/docblock-code-block-line-number.goml b/src/test/rustdoc-gui/docblock-code-block-line-number.goml
index ebfffbce71561..4e1e83c0fbd73 100644
--- a/src/test/rustdoc-gui/docblock-code-block-line-number.goml
+++ b/src/test/rustdoc-gui/docblock-code-block-line-number.goml
@@ -2,7 +2,7 @@
 goto: file://|DOC_PATH|/test_docs/fn.foo.html
 
 // We check that without this setting, there is no line number displayed.
-assert-false: "pre.line-number"
+assert-false: "pre.example-line-numbers"
 
 // We now set the setting to show the line numbers on code examples.
 local-storage: {"rustdoc-line-numbers": "true" }
@@ -10,16 +10,16 @@ local-storage: {"rustdoc-line-numbers": "true" }
 reload:
 
 // We wait for them to be added into the DOM by the JS...
-wait-for: "pre.line-number"
+wait-for: "pre.example-line-numbers"
 // If the test didn't fail, it means that it was found!
 // Let's now check some CSS properties...
-assert-css: ("pre.line-number", {
+assert-css: ("pre.example-line-numbers", {
     "margin": "0px",
     "padding": "13px 8px",
     "text-align": "right",
 })
 // The first code block has two lines so let's check its `
` elements lists both of them.
-assert-text: ("pre.line-number", "1\n2")
+assert-text: ("pre.example-line-numbers", "1\n2")
 
 // Now, try changing the setting dynamically. We'll turn it off, using the settings menu,
 // and make sure it goes away.
@@ -32,8 +32,8 @@ assert-css: ("#settings", {"display": "block"})
 // Then, click the toggle button.
 click: "input#line-numbers + .slider"
 wait-for: 100 // wait-for-false does not exist
-assert-false: "pre.line-number"
+assert-false: "pre.example-line-numbers"
 
 // Finally, turn it on again.
 click: "input#line-numbers + .slider"
-wait-for: "pre.line-number"
+wait-for: "pre.example-line-numbers"
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index 581f826a3d94d..5f0bb7f19c050 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -1,22 +1,22 @@
 // Checks that the interactions with the source code pages are working as expected.
 goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
 // Check that we can click on the line number.
-click: ".line-numbers > span:nth-child(4)" // This is the span for line 4.
+click: ".src-line-numbers > span:nth-child(4)" // This is the span for line 4.
 // Ensure that the page URL was updated.
 assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH)
 assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"})
 // We now check that the good spans are highlighted
 goto: file://|DOC_PATH|/src/test_docs/lib.rs.html#4-6
-assert-attribute-false: (".line-numbers > span:nth-child(3)", {"class": "line-highlighted"})
-assert-attribute: (".line-numbers > span:nth-child(4)", {"class": "line-highlighted"})
-assert-attribute: (".line-numbers > span:nth-child(5)", {"class": "line-highlighted"})
-assert-attribute: (".line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
-assert-attribute-false: (".line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
+assert-attribute-false: (".src-line-numbers > span:nth-child(3)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > span:nth-child(4)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > span:nth-child(5)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
+assert-attribute-false: (".src-line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
 // This is to ensure that the content is correctly align with the line numbers.
 compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
 
 // Assert that the line numbers text is aligned to the right.
-assert-css: (".line-numbers", {"text-align": "right"})
+assert-css: (".src-line-numbers", {"text-align": "right"})
 
 // Now let's check that clicking on something else than the line number doesn't
 // do anything (and certainly not add a `#NaN` to the URL!).
@@ -24,7 +24,7 @@ show-text: true
 goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
 // We use this assert-position to know where we will click.
 assert-position: ("//*[@id='1']", {"x": 104, "y": 103})
-// We click on the left of the "1" span but still in the "line-number" `
`.
+// We click on the left of the "1" span but still in the "src-line-number" `
`.
 click: (103, 103)
 assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
 
diff --git a/src/test/rustdoc-json/primitives/primitive_impls.rs b/src/test/rustdoc-json/primitives/primitive_impls.rs
new file mode 100644
index 0000000000000..1fc9374065f66
--- /dev/null
+++ b/src/test/rustdoc-json/primitives/primitive_impls.rs
@@ -0,0 +1,34 @@
+#![feature(no_core)]
+#![feature(rustc_attrs)]
+#![feature(rustdoc_internals)]
+#![no_core]
+#![rustc_coherence_is_core]
+
+// @set impl_i32 = "$.index[*][?(@.docs=='Only core can do this')].id"
+
+/// Only core can do this
+impl i32 {
+    // @set identity = "$.index[*][?(@.docs=='Do Nothing')].id"
+
+    /// Do Nothing
+    pub fn identity(self) -> Self {
+        self
+    }
+
+    // @is "$.index[*][?(@.docs=='Only core can do this')].inner.items[*]" $identity
+}
+
+// @set Trait = "$.index[*][?(@.name=='Trait')].id"
+pub trait Trait {}
+// @set impl_trait_for_i32 = "$.index[*][?(@.docs=='impl Trait for i32')].id"
+/// impl Trait for i32
+impl Trait for i32 {}
+
+/// i32
+#[doc(primitive = "i32")]
+mod prim_i32 {}
+
+// @set i32 = "$.index[*][?(@.docs=='i32')].id"
+// @is "$.index[*][?(@.docs=='i32')].name" '"i32"'
+// @is "$.index[*][?(@.docs=='i32')].inner.name" '"i32"'
+// @ismany "$.index[*][?(@.docs=='i32')].inner.impls[*]" $impl_i32 $impl_trait_for_i32
diff --git a/src/test/rustdoc-json/primitive_overloading.rs b/src/test/rustdoc-json/primitives/primitive_overloading.rs
similarity index 100%
rename from src/test/rustdoc-json/primitive_overloading.rs
rename to src/test/rustdoc-json/primitives/primitive_overloading.rs
diff --git a/src/test/rustdoc-json/primitives.rs b/src/test/rustdoc-json/primitives/primitive_type.rs
similarity index 100%
rename from src/test/rustdoc-json/primitives.rs
rename to src/test/rustdoc-json/primitives/primitive_type.rs
diff --git a/src/test/rustdoc-json/primitive.rs b/src/test/rustdoc-json/primitives/use_primitive.rs
similarity index 88%
rename from src/test/rustdoc-json/primitive.rs
rename to src/test/rustdoc-json/primitives/use_primitive.rs
index 6454dd7f51fab..e22927374621f 100644
--- a/src/test/rustdoc-json/primitive.rs
+++ b/src/test/rustdoc-json/primitives/use_primitive.rs
@@ -5,7 +5,7 @@
 #[doc(primitive = "usize")]
 mod usize {}
 
-// @set local_crate_id = "$.index[*][?(@.name=='primitive')].crate_id"
+// @set local_crate_id = "$.index[*][?(@.name=='use_primitive')].crate_id"
 
 // @has "$.index[*][?(@.name=='ilog10')]"
 // @!is "$.index[*][?(@.name=='ilog10')].crate_id" $local_crate_id
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
index ccbaa1f2af0d8..6bd8f671d7393 100644
--- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
+++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
@@ -46,7 +46,9 @@ error: expected identifier, found keyword `await`
   --> $DIR/2018-edition-error-in-non-macro-position.rs:13:14
    |
 LL | struct Foo { await: () }
-   |              ^^^^^ expected identifier, found keyword
+   |        ---   ^^^^^ expected identifier, found keyword
+   |        |
+   |        while parsing this struct
    |
 help: escape `await` to use it as an identifier
    |
diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
index 19f90677398ea..92b5133b74dd6 100644
--- a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
+++ b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr
@@ -1,6 +1,9 @@
 error[E0585]: found a documentation comment that doesn't document anything
   --> $DIR/doc-before-struct-rbrace-1.rs:3:5
    |
+LL | struct X {
+   |        - while parsing this struct
+LL |     a: u8,
 LL |     /// document
    |     ^^^^^^^^^^^^
    |
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.stderr b/src/test/ui/parser/fn-field-parse-error-ice.stderr
index d582f61cc97a9..e9583f55b8efb 100644
--- a/src/test/ui/parser/fn-field-parse-error-ice.stderr
+++ b/src/test/ui/parser/fn-field-parse-error-ice.stderr
@@ -7,6 +7,8 @@ LL |     inner : dyn fn ()
 error: functions are not allowed in struct definitions
   --> $DIR/fn-field-parse-error-ice.rs:4:17
    |
+LL | struct Baz {
+   |        --- while parsing this struct
 LL |     inner : dyn fn ()
    |                 ^^
    |
diff --git a/src/test/ui/parser/issues/issue-101540.stderr b/src/test/ui/parser/issues/issue-101540.stderr
index 53c7c9590e6ca..8af887050023c 100644
--- a/src/test/ui/parser/issues/issue-101540.stderr
+++ b/src/test/ui/parser/issues/issue-101540.stderr
@@ -1,6 +1,8 @@
 error: structs are not allowed in struct definitions
   --> $DIR/issue-101540.rs:2:5
    |
+LL | struct S1 {
+   |        -- while parsing this struct
 LL |     struct S2 {
    |     ^^^^^^^^^
    |
diff --git a/src/test/ui/parser/issues/issue-48636.stderr b/src/test/ui/parser/issues/issue-48636.stderr
index 462723d1d931e..1a6e4cfd2b203 100644
--- a/src/test/ui/parser/issues/issue-48636.stderr
+++ b/src/test/ui/parser/issues/issue-48636.stderr
@@ -1,6 +1,8 @@
 error[E0585]: found a documentation comment that doesn't document anything
   --> $DIR/issue-48636.rs:7:5
    |
+LL | struct S {
+   |        - while parsing this struct
 LL |     x: u8
    |          - help: missing comma here: `,`
 LL |     /// The ID of the parent core
diff --git a/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr
index ef365a616437b..adabb68593c09 100644
--- a/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr
+++ b/src/test/ui/parser/issues/issue-68000-unicode-ident-after-missing-comma.stderr
@@ -7,6 +7,8 @@ LL |     pub bar: Vecö
 error: expected `:`, found `}`
   --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1
    |
+LL | pub struct Foo {
+   |            --- while parsing this struct
 LL |     pub bar: Vecö
    |                       - expected `:`
 LL |
diff --git a/src/test/ui/parser/macro/issue-37113.stderr b/src/test/ui/parser/macro/issue-37113.stderr
index 0912858ddc4a6..b1f8674fbdf38 100644
--- a/src/test/ui/parser/macro/issue-37113.stderr
+++ b/src/test/ui/parser/macro/issue-37113.stderr
@@ -1,6 +1,8 @@
 error: expected identifier, found `String`
   --> $DIR/issue-37113.rs:4:16
    |
+LL |         enum SomeEnum {
+   |              -------- while parsing this enum
 LL |             $( $t, )*
    |                ^^ expected identifier
 ...
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
index a47d5506ef0b8..ad1e90e43ec4e 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-struct.stderr
@@ -10,6 +10,9 @@ LL | fn main() {}
 error: expected identifier, found keyword `trait`
   --> $DIR/missing-close-brace-in-struct.rs:4:1
    |
+LL | pub(crate) struct Bar {
+   |                   --- while parsing this struct
+...
 LL | trait T {
    | ^^^^^ expected identifier, found keyword
 
diff --git a/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr
index 46ca1f06be67b..6d8b0c3fccde3 100644
--- a/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr
+++ b/src/test/ui/parser/missing-closing-angle-bracket-struct-field-ty.stderr
@@ -1,6 +1,9 @@
 error: expected one of `>`, a const expression, lifetime, or type, found `}`
   --> $DIR/missing-closing-angle-bracket-struct-field-ty.rs:9:1
    |
+LL | pub struct Foo {
+   |            --- while parsing this struct
+...
 LL |     c: Arc>,
    |                          - expected one of `>`, a const expression, lifetime, or type
 LL | }
diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr
index ee29f06638f11..7634bca921c86 100644
--- a/src/test/ui/parser/recover-enum2.stderr
+++ b/src/test/ui/parser/recover-enum2.stderr
@@ -1,6 +1,8 @@
 error: expected type, found `{`
   --> $DIR/recover-enum2.rs:6:18
    |
+LL |         Var3 {
+   |         ---- while parsing this struct
 LL |             abc: {},
    |                  ^ expected type
 
diff --git a/src/test/ui/parser/recover-field-semi.stderr b/src/test/ui/parser/recover-field-semi.stderr
index 657366db9b4b7..3cf4847488c05 100644
--- a/src/test/ui/parser/recover-field-semi.stderr
+++ b/src/test/ui/parser/recover-field-semi.stderr
@@ -1,12 +1,16 @@
 error: struct fields are separated by `,`
   --> $DIR/recover-field-semi.rs:2:13
    |
+LL | struct Foo {
+   |        --- while parsing this struct
 LL |     foo: i32;
    |             ^ help: replace `;` with `,`
 
 error: union fields are separated by `,`
   --> $DIR/recover-field-semi.rs:7:13
    |
+LL | union Bar {
+   |       --- while parsing this union
 LL |     foo: i32;
    |             ^ help: replace `;` with `,`
 
@@ -14,7 +18,9 @@ error: struct fields are separated by `,`
   --> $DIR/recover-field-semi.rs:12:19
    |
 LL |     Qux { foo: i32; }
-   |                   ^ help: replace `;` with `,`
+   |     ---           ^ help: replace `;` with `,`
+   |     |
+   |     while parsing this struct
 
 error: unions cannot have zero fields
   --> $DIR/recover-field-semi.rs:6:1
diff --git a/src/test/ui/parser/recover-struct.stderr b/src/test/ui/parser/recover-struct.stderr
index 1b72184b0c886..9f6fb06caa34d 100644
--- a/src/test/ui/parser/recover-struct.stderr
+++ b/src/test/ui/parser/recover-struct.stderr
@@ -1,6 +1,8 @@
 error: expected `:`, found `Bad`
   --> $DIR/recover-struct.rs:4:9
    |
+LL |     struct Test {
+   |            ---- while parsing this struct
 LL |         Very
    |             - expected `:`
 LL |         Bad
diff --git a/src/test/ui/parser/recovered-struct-variant.stderr b/src/test/ui/parser/recovered-struct-variant.stderr
index 51aaf8bb3cfbe..78c67866fb0f1 100644
--- a/src/test/ui/parser/recovered-struct-variant.stderr
+++ b/src/test/ui/parser/recovered-struct-variant.stderr
@@ -2,7 +2,9 @@ error: expected `:`, found `,`
   --> $DIR/recovered-struct-variant.rs:2:10
    |
 LL |     A { a, b: usize }
-   |          ^ expected `:`
+   |     -    ^ expected `:`
+   |     |
+   |     while parsing this struct
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-enum-newtype.stderr b/src/test/ui/parser/removed-syntax-enum-newtype.stderr
index 2daa6249b4ce0..8f7ca356798e2 100644
--- a/src/test/ui/parser/removed-syntax-enum-newtype.stderr
+++ b/src/test/ui/parser/removed-syntax-enum-newtype.stderr
@@ -2,7 +2,9 @@ error: expected one of `<`, `where`, or `{`, found `=`
   --> $DIR/removed-syntax-enum-newtype.rs:1:8
    |
 LL | enum e = isize;
-   |        ^ expected one of `<`, `where`, or `{`
+   |      - ^ expected one of `<`, `where`, or `{`
+   |      |
+   |      while parsing this enum
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr
index 10be2e045b2b8..ab3d2056581b6 100644
--- a/src/test/ui/parser/removed-syntax-field-let.stderr
+++ b/src/test/ui/parser/removed-syntax-field-let.stderr
@@ -1,6 +1,8 @@
 error: expected identifier, found keyword `let`
   --> $DIR/removed-syntax-field-let.rs:2:5
    |
+LL | struct S {
+   |        - while parsing this struct
 LL |     let foo: (),
    |     ^^^ expected identifier, found keyword
 
diff --git a/src/test/ui/parser/removed-syntax-field-semicolon.stderr b/src/test/ui/parser/removed-syntax-field-semicolon.stderr
index e4f75f672063c..532d4fb2b61f0 100644
--- a/src/test/ui/parser/removed-syntax-field-semicolon.stderr
+++ b/src/test/ui/parser/removed-syntax-field-semicolon.stderr
@@ -1,6 +1,8 @@
 error: struct fields are separated by `,`
   --> $DIR/removed-syntax-field-semicolon.rs:2:12
    |
+LL | struct S {
+   |        - while parsing this struct
 LL |     bar: ();
    |            ^ help: replace `;` with `,`
 
diff --git a/src/test/ui/pattern/issue-66270-pat-struct-parser-recovery.stderr b/src/test/ui/pattern/issue-66270-pat-struct-parser-recovery.stderr
index fef0f3c0e06ef..f40642f300cdf 100644
--- a/src/test/ui/pattern/issue-66270-pat-struct-parser-recovery.stderr
+++ b/src/test/ui/pattern/issue-66270-pat-struct-parser-recovery.stderr
@@ -1,6 +1,8 @@
 error: expected type, found `0`
   --> $DIR/issue-66270-pat-struct-parser-recovery.rs:4:22
    |
+LL | struct Bug {
+   |        --- while parsing this struct
 LL |     incorrect_field: 0,
    |                      ^ expected type
 
diff --git a/src/test/ui/proc-macro/derive-bad.stderr b/src/test/ui/proc-macro/derive-bad.stderr
index ae48141fb3133..241f99b28c24b 100644
--- a/src/test/ui/proc-macro/derive-bad.stderr
+++ b/src/test/ui/proc-macro/derive-bad.stderr
@@ -2,7 +2,10 @@ error: expected `:`, found `}`
   --> $DIR/derive-bad.rs:6:10
    |
 LL | #[derive(A)]
-   |          ^ expected `:`
+   |          ^
+   |          |
+   |          expected `:`
+   |          while parsing this struct
    |
    = note: this error originates in the derive macro `A` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/pub/pub-restricted-error.stderr b/src/test/ui/pub/pub-restricted-error.stderr
index 95bf498c7f746..b47328f34e6eb 100644
--- a/src/test/ui/pub/pub-restricted-error.stderr
+++ b/src/test/ui/pub/pub-restricted-error.stderr
@@ -1,6 +1,8 @@
 error: expected identifier, found `(`
   --> $DIR/pub-restricted-error.rs:4:16
    |
+LL | struct Foo {
+   |        --- while parsing this struct
 LL |     pub(crate) () foo: usize,
    |                ^ expected identifier
 
diff --git a/src/test/ui/structs/struct-fn-in-definition.stderr b/src/test/ui/structs/struct-fn-in-definition.stderr
index 1d7cd52729586..472365c6ed739 100644
--- a/src/test/ui/structs/struct-fn-in-definition.stderr
+++ b/src/test/ui/structs/struct-fn-in-definition.stderr
@@ -1,6 +1,9 @@
 error: functions are not allowed in struct definitions
   --> $DIR/struct-fn-in-definition.rs:9:5
    |
+LL | struct S {
+   |        - while parsing this struct
+...
 LL |     fn foo() {}
    |     ^^^^^^^^^^^
    |
@@ -10,6 +13,9 @@ LL |     fn foo() {}
 error: functions are not allowed in union definitions
   --> $DIR/struct-fn-in-definition.rs:18:5
    |
+LL | union U {
+   |       - while parsing this union
+...
 LL |     fn foo() {}
    |     ^^^^^^^^^^^
    |
@@ -19,6 +25,9 @@ LL |     fn foo() {}
 error: functions are not allowed in enum definitions
   --> $DIR/struct-fn-in-definition.rs:27:5
    |
+LL | enum E {
+   |      - while parsing this enum
+...
 LL |     fn foo() {}
    |     ^^^^^^^^^^^
    |
diff --git a/src/test/ui/suggestions/struct-field-type-including-single-colon.stderr b/src/test/ui/suggestions/struct-field-type-including-single-colon.stderr
index 189759d64fc4e..4dd514480da40 100644
--- a/src/test/ui/suggestions/struct-field-type-including-single-colon.stderr
+++ b/src/test/ui/suggestions/struct-field-type-including-single-colon.stderr
@@ -12,6 +12,8 @@ LL |     a: foo::A,
 error: expected `,`, or `}`, found `:`
   --> $DIR/struct-field-type-including-single-colon.rs:9:11
    |
+LL | struct Foo {
+   |        --- while parsing this struct
 LL |     a: foo:A,
    |           ^
 
@@ -29,6 +31,8 @@ LL |     b: foo::bar::B,
 error: expected `,`, or `}`, found `:`
   --> $DIR/struct-field-type-including-single-colon.rs:15:16
    |
+LL | struct Bar {
+   |        --- while parsing this struct
 LL |     b: foo::bar:B,
    |                ^
 
diff --git a/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr
index 6bc9c8498c9d1..fc7c23a225240 100644
--- a/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr
+++ b/src/test/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.stderr
@@ -2,7 +2,9 @@ error: expected identifier, found `0`
   --> $DIR/issue-69378-ice-on-invalid-type-node-after-recovery.rs:3:14
    |
 LL | struct Foo { 0: u8 }
-   |              ^ expected identifier
+   |        ---   ^ expected identifier
+   |        |
+   |        while parsing this struct
 
 error: aborting due to previous error
 
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index ad8e96a0bd81d..6d986e57501a3 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -142,8 +142,7 @@ impl Kind {
             ItemEnum::Static(_) => Static,
             ItemEnum::Macro(_) => Macro,
             ItemEnum::ProcMacro(_) => ProcMacro,
-            // https://github.com/rust-lang/rust/issues/100961
-            ItemEnum::PrimitiveType(_) => Primitive,
+            ItemEnum::Primitive(_) => Primitive,
             ItemEnum::ForeignType => ForeignType,
             ItemEnum::ExternCrate { .. } => ExternCrate,
             ItemEnum::AssocConst { .. } => AssocConst,
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index a0e77127dc2ca..94af4c5e9e16d 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -4,8 +4,8 @@ use std::hash::Hash;
 use rustdoc_json_types::{
     Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs,
     GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, Method, Module, OpaqueTy,
-    Path, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding,
-    TypeBindingKind, Typedef, Union, Variant, WherePredicate,
+    Path, Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type,
+    TypeBinding, TypeBindingKind, Typedef, Union, Variant, WherePredicate,
 };
 
 use crate::{item_kind::Kind, Error, ErrorKind};
@@ -76,7 +76,7 @@ impl<'a> Validator<'a> {
                 ItemEnum::ForeignType => {} // nop
                 ItemEnum::Macro(x) => self.check_macro(x),
                 ItemEnum::ProcMacro(x) => self.check_proc_macro(x),
-                ItemEnum::PrimitiveType(x) => self.check_primitive_type(x),
+                ItemEnum::Primitive(x) => self.check_primitive_type(x),
                 ItemEnum::Module(x) => self.check_module(x),
                 // FIXME: Why don't these have their own structs?
                 ItemEnum::ExternCrate { .. } => {}
@@ -219,8 +219,8 @@ impl<'a> Validator<'a> {
         // nop
     }
 
-    fn check_primitive_type(&mut self, _: &'a str) {
-        // nop
+    fn check_primitive_type(&mut self, x: &'a Primitive) {
+        x.impls.iter().for_each(|i| self.add_impl_id(i));
     }
 
     fn check_generics(&mut self, x: &'a Generics) {