From ccd550ee565436b4c9b7f987c19bd3a9111714f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 16 Aug 2021 23:19:00 +0200 Subject: [PATCH] [rustdoc] Wrap code blocks in tag --- src/librustdoc/html/highlight.rs | 7 +- src/librustdoc/html/markdown.rs | 2 +- src/librustdoc/html/render/print_item.rs | 556 +++++++++++---------- src/librustdoc/html/static/css/rustdoc.css | 1 - src/test/rustdoc-gui/code-tags.goml | 20 + src/test/rustdoc-gui/source-code-page.goml | 2 +- 6 files changed, 318 insertions(+), 270 deletions(-) create mode 100644 src/test/rustdoc-gui/code-tags.goml diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 3cdb1352bef..f8fc9243e14 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -65,10 +65,11 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option", class); + write!(out, "
", class);
     } else {
-        writeln!(out, "
");
+        write!(out, "
");
     }
+    write!(out, "");
 }
 
 /// Convert the given `src` source code into HTML by adding classes for highlighting.
@@ -101,7 +102,7 @@ fn write_code(
 }
 
 fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
-    writeln!(out, "
{}", playground_button.unwrap_or_default()); + writeln!(out, "
{}", playground_button.unwrap_or_default()); } /// How a span of text is classified. Mostly corresponds to token kinds. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 472323daf30..7c6d7dff816 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -234,7 +234,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { return Some(Event::Html( format!( "
\ -
{}
\ +
{}
\
", lang, Escape(&text), diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index f31305c76e6..c1d95c8c252 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -455,24 +455,25 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: + name.as_str().len() + generics_len; - w.write_str("
");
-    render_attributes_in_pre(w, it, "");
-    w.reserve(header_len);
-    write!(
-        w,
-        "{vis}{constness}{asyncness}{unsafety}{abi}fn \
-         {name}{generics}{decl}{notable_traits}{where_clause}
", - vis = vis, - constness = constness, - asyncness = asyncness, - unsafety = unsafety, - abi = abi, - name = name, - generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, true), - decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), - notable_traits = notable_traits_decl(&f.decl, cx), - ); + wrap_item(w, "fn", |w| { + render_attributes_in_pre(w, it, ""); + w.reserve(header_len); + write!( + w, + "{vis}{constness}{asyncness}{unsafety}{abi}fn \ + {name}{generics}{decl}{notable_traits}{where_clause}", + vis = vis, + constness = constness, + asyncness = asyncness, + unsafety = unsafety, + abi = abi, + name = name, + generics = f.generics.print(cx), + where_clause = print_where_clause(&f.generics, cx, 0, true), + decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), + notable_traits = notable_traits_decl(&f.decl, cx), + ); + }); document(w, cx, it, None) } @@ -488,108 +489,111 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra // Output the trait definition wrap_into_docblock(w, |w| { - w.write_str("
");
-        render_attributes_in_pre(w, it, "");
-        write!(
-            w,
-            "{}{}{}trait {}{}{}",
-            it.visibility.print_with_space(it.def_id, cx),
-            t.unsafety.print_with_space(),
-            if t.is_auto { "auto " } else { "" },
-            it.name.as_ref().unwrap(),
-            t.generics.print(cx),
-            bounds
-        );
+        wrap_item(w, "trait", |w| {
+            render_attributes_in_pre(w, it, "");
+            write!(
+                w,
+                "{}{}{}trait {}{}{}",
+                it.visibility.print_with_space(it.def_id, cx),
+                t.unsafety.print_with_space(),
+                if t.is_auto { "auto " } else { "" },
+                it.name.as_ref().unwrap(),
+                t.generics.print(cx),
+                bounds
+            );
 
-        if !t.generics.where_predicates.is_empty() {
-            write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
-        } else {
-            w.write_str(" ");
-        }
+            if !t.generics.where_predicates.is_empty() {
+                write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
+            } else {
+                w.write_str(" ");
+            }
 
-        if t.items.is_empty() {
-            w.write_str("{ }");
-        } else {
-            // FIXME: we should be using a derived_id for the Anchors here
-            w.write_str("{\n");
-            let mut toggle = false;
+            if t.items.is_empty() {
+                w.write_str("{ }");
+            } else {
+                // FIXME: we should be using a derived_id for the Anchors here
+                w.write_str("{\n");
+                let mut toggle = false;
 
-            // If there are too many associated types, hide _everything_
-            if should_hide_fields(count_types) {
-                toggle = true;
-                toggle_open(
-                    w,
-                    format_args!("{} associated items", count_types + count_consts + count_methods),
-                );
-            }
-            for t in &types {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-            }
-            // If there are too many associated constants, hide everything after them
-            // We also do this if the types + consts is large because otherwise we could
-            // render a bunch of types and _then_ a bunch of consts just because both were
-            // _just_ under the limit
-            if !toggle && should_hide_fields(count_types + count_consts) {
-                toggle = true;
-                toggle_open(
-                    w,
-                    format_args!(
-                        "{} associated constant{} and {} method{}",
-                        count_consts,
-                        pluralize(count_consts),
-                        count_methods,
-                        pluralize(count_methods),
-                    ),
-                );
-            }
-            if !types.is_empty() && !consts.is_empty() {
-                w.write_str("\n");
-            }
-            for t in &consts {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-            }
-            if !toggle && should_hide_fields(count_methods) {
-                toggle = true;
-                toggle_open(w, format_args!("{} methods", count_methods));
-            }
-            if !consts.is_empty() && !required.is_empty() {
-                w.write_str("\n");
-            }
-            for (pos, m) in required.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-
-                if pos < required.len() - 1 {
-                    w.write_str("
"); + // If there are too many associated types, hide _everything_ + if should_hide_fields(count_types) { + toggle = true; + toggle_open( + w, + format_args!( + "{} associated items", + count_types + count_consts + count_methods + ), + ); } - } - if !required.is_empty() && !provided.is_empty() { - w.write_str("\n"); - } - for (pos, m) in provided.iter().enumerate() { - render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); - match *m.kind { - clean::MethodItem(ref inner, _) - if !inner.generics.where_predicates.is_empty() => - { - w.write_str(",\n { ... }\n"); - } - _ => { - w.write_str(" { ... }\n"); + for t in &types { + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); + w.write_str(";\n"); + } + // If there are too many associated constants, hide everything after them + // We also do this if the types + consts is large because otherwise we could + // render a bunch of types and _then_ a bunch of consts just because both were + // _just_ under the limit + if !toggle && should_hide_fields(count_types + count_consts) { + toggle = true; + toggle_open( + w, + format_args!( + "{} associated constant{} and {} method{}", + count_consts, + pluralize(count_consts), + count_methods, + pluralize(count_methods), + ), + ); + } + if !types.is_empty() && !consts.is_empty() { + w.write_str("\n"); + } + for t in &consts { + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); + w.write_str(";\n"); + } + if !toggle && should_hide_fields(count_methods) { + toggle = true; + toggle_open(w, format_args!("{} methods", count_methods)); + } + if !consts.is_empty() && !required.is_empty() { + w.write_str("\n"); + } + for (pos, m) in required.iter().enumerate() { + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); + w.write_str(";\n"); + + if pos < required.len() - 1 { + w.write_str("
"); } } - if pos < provided.len() - 1 { - w.write_str("
"); + if !required.is_empty() && !provided.is_empty() { + w.write_str("\n"); } + for (pos, m) in provided.iter().enumerate() { + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx); + match *m.kind { + clean::MethodItem(ref inner, _) + if !inner.generics.where_predicates.is_empty() => + { + w.write_str(",\n { ... }\n"); + } + _ => { + w.write_str(" { ... }\n"); + } + } + if pos < provided.len() - 1 { + w.write_str("
"); + } + } + if toggle { + toggle_close(w); + } + w.write_str("}"); } - if toggle { - toggle_close(w); - } - w.write_str("}"); - } - w.write_str("
") + }); }); // Trait documentation @@ -812,16 +816,17 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) { - w.write_str("
");
-    render_attributes_in_pre(w, it, "");
-    write!(
-        w,
-        "trait {}{}{} = {};
", - it.name.as_ref().unwrap(), - t.generics.print(cx), - print_where_clause(&t.generics, cx, 0, true), - bounds(&t.bounds, true, cx) - ); + wrap_item(w, "trait-alias", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "trait {}{}{} = {};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + print_where_clause(&t.generics, cx, 0, true), + bounds(&t.bounds, true, cx) + ); + }); document(w, cx, it, None); @@ -833,16 +838,17 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea } fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { - w.write_str("
");
-    render_attributes_in_pre(w, it, "");
-    write!(
-        w,
-        "type {}{}{where_clause} = impl {bounds};
", - it.name.as_ref().unwrap(), - t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), - bounds = bounds(&t.bounds, false, cx), - ); + wrap_item(w, "opaque", |w| { + render_attributes_in_pre(w, it, ""); + write!( + w, + "type {}{}{where_clause} = impl {bounds};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, true), + bounds = bounds(&t.bounds, false, cx), + ); + }); document(w, cx, it, None); @@ -860,19 +866,20 @@ fn item_typedef( t: &clean::Typedef, is_associated: bool, ) { - w.write_str("
");
-    render_attributes_in_pre(w, it, "");
-    if !is_associated {
-        write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
-    }
-    write!(
-        w,
-        "type {}{}{where_clause} = {type_};
", - it.name.as_ref().unwrap(), - t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), - type_ = t.type_.print(cx), - ); + wrap_item(w, "typedef", |w| { + render_attributes_in_pre(w, it, ""); + if !is_associated { + write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); + } + write!( + w, + "type {}{}{where_clause} = {type_};", + it.name.as_ref().unwrap(), + t.generics.print(cx), + where_clause = print_where_clause(&t.generics, cx, 0, true), + type_ = t.type_.print(cx), + ); + }); document(w, cx, it, None); @@ -886,10 +893,10 @@ fn item_typedef( fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { wrap_into_docblock(w, |w| { - w.write_str("
");
-        render_attributes_in_pre(w, it, "");
-        render_union(w, it, Some(&s.generics), &s.fields, "", cx);
-        w.write_str("
") + wrap_item(w, "union", |w| { + render_attributes_in_pre(w, it, ""); + render_union(w, it, Some(&s.generics), &s.fields, "", cx); + }); }); document(w, cx, it, None); @@ -935,59 +942,68 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { wrap_into_docblock(w, |w| { - w.write_str("
");
-        render_attributes_in_pre(w, it, "");
-        write!(
-            w,
-            "{}enum {}{}{}",
-            it.visibility.print_with_space(it.def_id, cx),
-            it.name.as_ref().unwrap(),
-            e.generics.print(cx),
-            print_where_clause(&e.generics, cx, 0, true),
-        );
-        if e.variants.is_empty() && !e.variants_stripped {
-            w.write_str(" {}");
-        } else {
-            w.write_str(" {\n");
-            let count_variants = e.variants.len();
-            let toggle = should_hide_fields(count_variants);
-            if toggle {
-                toggle_open(w, format_args!("{} variants", count_variants));
-            }
-            for v in &e.variants {
-                w.write_str("    ");
-                let name = v.name.as_ref().unwrap();
-                match *v.kind {
-                    clean::VariantItem(ref var) => match var {
-                        clean::Variant::CLike => write!(w, "{}", name),
-                        clean::Variant::Tuple(ref tys) => {
-                            write!(w, "{}(", name);
-                            for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 {
-                                    w.write_str(", ")
-                                }
-                                write!(w, "{}", ty.print(cx));
-                            }
-                            w.write_str(")");
-                        }
-                        clean::Variant::Struct(ref s) => {
-                            render_struct(w, v, None, s.struct_type, &s.fields, "    ", false, cx);
-                        }
-                    },
-                    _ => unreachable!(),
+        wrap_item(w, "enum", |w| {
+            render_attributes_in_pre(w, it, "");
+            write!(
+                w,
+                "{}enum {}{}{}",
+                it.visibility.print_with_space(it.def_id, cx),
+                it.name.as_ref().unwrap(),
+                e.generics.print(cx),
+                print_where_clause(&e.generics, cx, 0, true),
+            );
+            if e.variants.is_empty() && !e.variants_stripped {
+                w.write_str(" {}");
+            } else {
+                w.write_str(" {\n");
+                let count_variants = e.variants.len();
+                let toggle = should_hide_fields(count_variants);
+                if toggle {
+                    toggle_open(w, format_args!("{} variants", count_variants));
+                }
+                for v in &e.variants {
+                    w.write_str("    ");
+                    let name = v.name.as_ref().unwrap();
+                    match *v.kind {
+                        clean::VariantItem(ref var) => match var {
+                            clean::Variant::CLike => write!(w, "{}", name),
+                            clean::Variant::Tuple(ref tys) => {
+                                write!(w, "{}(", name);
+                                for (i, ty) in tys.iter().enumerate() {
+                                    if i > 0 {
+                                        w.write_str(", ")
+                                    }
+                                    write!(w, "{}", ty.print(cx));
+                                }
+                                w.write_str(")");
+                            }
+                            clean::Variant::Struct(ref s) => {
+                                render_struct(
+                                    w,
+                                    v,
+                                    None,
+                                    s.struct_type,
+                                    &s.fields,
+                                    "    ",
+                                    false,
+                                    cx,
+                                );
+                            }
+                        },
+                        _ => unreachable!(),
+                    }
+                    w.write_str(",\n");
                 }
-                w.write_str(",\n");
-            }
 
-            if e.variants_stripped {
-                w.write_str("    // some variants omitted\n");
+                if e.variants_stripped {
+                    w.write_str("    // some variants omitted\n");
+                }
+                if toggle {
+                    toggle_close(w);
+                }
+                w.write_str("}");
             }
-            if toggle {
-                toggle_close(w);
-            }
-            w.write_str("}");
-        }
-        w.write_str("
") + }); }); document(w, cx, it, None); @@ -1091,27 +1107,27 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean let name = it.name.as_ref().expect("proc-macros always have names"); match m.kind { MacroKind::Bang => { - w.push_str("
");
-            write!(w, "{}!() {{ /* proc-macro */ }}", name);
-            w.push_str("
"); + wrap_item(w, "macro", |w| { + write!(w, "{}!() {{ /* proc-macro */ }}", name); + }); } MacroKind::Attr => { - w.push_str("
");
-            write!(w, "#[{}]", name);
-            w.push_str("
"); + wrap_item(w, "attr", |w| { + write!(w, "#[{}]", name); + }); } MacroKind::Derive => { - w.push_str("
");
-            write!(w, "#[derive({})]", name);
-            if !m.helpers.is_empty() {
-                w.push_str("\n{\n");
-                w.push_str("    // Attributes available to this derive:\n");
-                for attr in &m.helpers {
-                    writeln!(w, "    #[{}]", attr);
+            wrap_item(w, "derive", |w| {
+                write!(w, "#[derive({})]", name);
+                if !m.helpers.is_empty() {
+                    w.push_str("\n{\n");
+                    w.push_str("    // Attributes available to this derive:\n");
+                    for attr in &m.helpers {
+                        writeln!(w, "    #[{}]", attr);
+                    }
+                    w.push_str("}\n");
                 }
-                w.push_str("}\n");
-            }
-            w.push_str("
"); + }); } } document(w, cx, it, None) @@ -1123,49 +1139,49 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { } fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) { - w.write_str("
");
-    render_attributes_in_code(w, it);
+    wrap_item(w, "const", |w| {
+        render_attributes_in_code(w, it);
 
-    write!(
-        w,
-        "{vis}const {name}: {typ}",
-        vis = it.visibility.print_with_space(it.def_id, cx),
-        name = it.name.as_ref().unwrap(),
-        typ = c.type_.print(cx),
-    );
+        write!(
+            w,
+            "{vis}const {name}: {typ}",
+            vis = it.visibility.print_with_space(it.def_id, cx),
+            name = it.name.as_ref().unwrap(),
+            typ = c.type_.print(cx),
+        );
 
-    let value = c.value(cx.tcx());
-    let is_literal = c.is_literal(cx.tcx());
-    let expr = c.expr(cx.tcx());
-    if value.is_some() || is_literal {
-        write!(w, " = {expr};", expr = Escape(&expr));
-    } else {
-        w.write_str(";");
-    }
+        let value = c.value(cx.tcx());
+        let is_literal = c.is_literal(cx.tcx());
+        let expr = c.expr(cx.tcx());
+        if value.is_some() || is_literal {
+            write!(w, " = {expr};", expr = Escape(&expr));
+        } else {
+            w.write_str(";");
+        }
 
-    if !is_literal {
-        if let Some(value) = &value {
-            let value_lowercase = value.to_lowercase();
-            let expr_lowercase = expr.to_lowercase();
+        if !is_literal {
+            if let Some(value) = &value {
+                let value_lowercase = value.to_lowercase();
+                let expr_lowercase = expr.to_lowercase();
 
-            if value_lowercase != expr_lowercase
-                && value_lowercase.trim_end_matches("i32") != expr_lowercase
-            {
-                write!(w, " // {value}", value = Escape(value));
+                if value_lowercase != expr_lowercase
+                    && value_lowercase.trim_end_matches("i32") != expr_lowercase
+                {
+                    write!(w, " // {value}", value = Escape(value));
+                }
             }
         }
-    }
+    });
 
-    w.write_str("
"); document(w, cx, it, None) } fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) { wrap_into_docblock(w, |w| { - w.write_str("
");
-        render_attributes_in_code(w, it);
-        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
-        w.write_str("
") + wrap_item(w, "struct", |w| { + render_attributes_in_code(w, it); + render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx); + }); }); document(w, cx, it, None); @@ -1214,28 +1230,31 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St } fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) { - w.write_str("
");
-    render_attributes_in_code(w, it);
-    write!(
-        w,
-        "{vis}static {mutability}{name}: {typ}
", - vis = it.visibility.print_with_space(it.def_id, cx), - mutability = s.mutability.print_with_space(), - name = it.name.as_ref().unwrap(), - typ = s.type_.print(cx) - ); + wrap_item(w, "static", |w| { + render_attributes_in_code(w, it); + write!( + w, + "{vis}static {mutability}{name}: {typ}", + vis = it.visibility.print_with_space(it.def_id, cx), + mutability = s.mutability.print_with_space(), + name = it.name.as_ref().unwrap(), + typ = s.type_.print(cx) + ); + }); document(w, cx, it, None) } fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { - w.write_str("
extern {\n");
-    render_attributes_in_code(w, it);
-    write!(
-        w,
-        "    {}type {};\n}}
", - it.visibility.print_with_space(it.def_id, cx), - it.name.as_ref().unwrap(), - ); + wrap_item(w, "foreigntype", |w| { + w.write_str("extern {\n"); + render_attributes_in_code(w, it); + write!( + w, + " {}type {};\n}}", + it.visibility.print_with_space(it.def_id, cx), + it.name.as_ref().unwrap(), + ); + }); document(w, cx, it, None); @@ -1322,6 +1341,15 @@ where w.write_str("") } +fn wrap_item(w: &mut Buffer, item_name: &str, f: F) +where + F: FnOnce(&mut Buffer), +{ + w.write_fmt(format_args!("
", item_name));
+    f(w);
+    w.write_str("
"); +} + fn render_stability_since( w: &mut Buffer, item: &clean::Item, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index bbc48f49e63..0f95b6aaa89 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -249,7 +249,6 @@ code, pre, a.test-arrow, .code-header { } .docblock pre code, .docblock-short pre code { padding: 0; - padding-right: 1ex; } pre { padding: 14px; diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml new file mode 100644 index 00000000000..200569a28d4 --- /dev/null +++ b/src/test/rustdoc-gui/code-tags.goml @@ -0,0 +1,20 @@ +// This test ensures that items and documentation code blocks are wrapped in

+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+size: (1080, 600)
+// There should be three doc codeblocks
+// Check that their content is inside 

+assert-count: (".example-wrap pre > code", 3)
+// Check that function signature is inside 

+assert: "pre.rust.fn > code"
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert: "pre.rust.struct > code"
+
+goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html
+assert: "pre.rust.enum > code"
+
+goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
+assert: "pre.rust.trait > code"
+
+goto: file://|DOC_PATH|/test_docs/type.SomeType.html
+assert: "pre.rust.typedef > code"
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index d7bae93c211..5a49807e180 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -12,4 +12,4 @@ assert-attribute: (".line-numbers > span:nth-child(5)", {"class": "line-highligh
 assert-attribute: (".line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
 assert-attribute-false: (".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 > span", ("y"))
+compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))