Skip to content
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7a47786
Makes docs for references a little less confusing
WaffleLapkin Aug 26, 2021
9a4530b
Update library/std/src/primitive_docs.rs
WaffleLapkin Aug 26, 2021
26aec6c
Update core primitives_docs.rs up to date with std
WaffleLapkin Oct 10, 2021
69df43b
Improve display of enum variants
jsha Oct 20, 2021
8f6fa4f
Add a regression test for #87573
JohnTitor Nov 16, 2021
2f1a1f5
fix CTFE/Miri simd_insert/extract on array-style repr(simd) types
RalfJung Nov 18, 2021
0304e16
CTFE SIMD: also test 1-element array
RalfJung Nov 18, 2021
214ad2f
rustdoc doctest: detect `fn main` after an unexpected semicolon
notriddle Nov 18, 2021
592178c
Put back removed empty line
GuillaumeGomez Nov 19, 2021
cdb0c29
Remove unnecessary doc links
WaffleLapkin Nov 19, 2021
a2d7857
Turn all 0x1b_u8 into '\x1b' or b'\x1b'
Nov 19, 2021
0ae053a
rustdoc: Fix some unescaped HTML tags in docs
camelid Nov 19, 2021
97bd45b
Rollup merge of #88361 - WaffleLapkin:patch-2, r=jyn514
matthiaskrgr Nov 20, 2021
c0695bb
Rollup merge of #90089 - jsha:enum-fields-headings, r=camelid,Guillau…
matthiaskrgr Nov 20, 2021
5c98cf1
Rollup merge of #90956 - JohnTitor:issue-87573, r=Mark-Simulacrum
matthiaskrgr Nov 20, 2021
cf69f9e
Rollup merge of #90999 - RalfJung:miri_simd, r=oli-obk
matthiaskrgr Nov 20, 2021
a9858ce
Rollup merge of #91026 - notriddle:notriddle/rustdoc-doctest-semicolo…
matthiaskrgr Nov 20, 2021
98540c6
Rollup merge of #91035 - GuillaumeGomez:put-back-removed-empty-line, …
matthiaskrgr Nov 20, 2021
62b259c
Rollup merge of #91044 - r00ster91:x1b, r=joshtriplett
matthiaskrgr Nov 20, 2021
54bc333
Rollup merge of #91054 - camelid:fix-tags, r=GuillaumeGomez
matthiaskrgr Nov 20, 2021
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
47 changes: 16 additions & 31 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -419,48 +419,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
sym::simd_insert => {
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
let elem = &args[2];
let input = &args[0];
let (len, e_ty) = input.layout.ty.simd_size_and_type(*self.tcx);
let (input, input_len) = self.operand_to_simd(&args[0])?;
let (dest, dest_len) = self.place_to_simd(dest)?;
assert_eq!(input_len, dest_len, "Return vector length must match input length");
assert!(
index < len,
"Index `{}` must be in bounds of vector type `{}`: `[0, {})`",
index < dest_len,
"Index `{}` must be in bounds of vector with length {}`",
index,
e_ty,
len
);
assert_eq!(
input.layout, dest.layout,
"Return type `{}` must match vector type `{}`",
dest.layout.ty, input.layout.ty
);
assert_eq!(
elem.layout.ty, e_ty,
"Scalar element type `{}` must match vector element type `{}`",
elem.layout.ty, e_ty
dest_len
);

for i in 0..len {
let place = self.place_index(dest, i)?;
let value = if i == index { *elem } else { self.operand_index(input, i)? };
self.copy_op(&value, &place)?;
for i in 0..dest_len {
let place = self.mplace_index(&dest, i)?;
let value =
if i == index { *elem } else { self.mplace_index(&input, i)?.into() };
self.copy_op(&value, &place.into())?;
}
}
sym::simd_extract => {
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
let (len, e_ty) = args[0].layout.ty.simd_size_and_type(*self.tcx);
let (input, input_len) = self.operand_to_simd(&args[0])?;
assert!(
index < len,
"index `{}` is out-of-bounds of vector type `{}` with length `{}`",
index < input_len,
"index `{}` must be in bounds of vector with length `{}`",
index,
e_ty,
len
);
assert_eq!(
e_ty, dest.layout.ty,
"Return type `{}` must match vector element type `{}`",
dest.layout.ty, e_ty
input_len
);
self.copy_op(&self.operand_index(&args[0], index)?, dest)?;
self.copy_op(&self.mplace_index(&input, index)?.into(), dest)?;
}
sym::likely | sym::unlikely | sym::black_box => {
// These just return their argument
12 changes: 12 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
@@ -437,6 +437,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
})
}

/// Converts a repr(simd) operand into an operand where `place_index` accesses the SIMD elements.
/// Also returns the number of elements.
pub fn operand_to_simd(
&self,
base: &OpTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
// Basically we just transmute this place into an array following simd_size_and_type.
// This only works in memory, but repr(simd) types should never be immediates anyway.
assert!(base.layout.ty.is_simd());
self.mplace_to_simd(&base.assert_mem_place())
}

/// Read from a local. Will not actually access the local if reading from a ZST.
/// Will not access memory, instead an indirect `Operand` is returned.
///
28 changes: 27 additions & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
@@ -200,7 +200,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
}
} else {
// Go through the layout. There are lots of types that support a length,
// e.g., SIMD types.
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
match self.layout.fields {
FieldsShape::Array { count, .. } => Ok(count),
_ => bug!("len not supported on sized type {:?}", self.layout.ty),
@@ -533,6 +533,22 @@ where
})
}

/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
/// Also returns the number of elements.
pub fn mplace_to_simd(
&self,
base: &MPlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
// Basically we just transmute this place into an array following simd_size_and_type.
// (Transmuting is okay since this is an in-memory place. We also double-check the size
// stays the same.)
let (len, e_ty) = base.layout.ty.simd_size_and_type(*self.tcx);
let array = self.tcx.mk_array(e_ty, len);
let layout = self.layout_of(array)?;
assert_eq!(layout.size, base.layout.size);
Ok((MPlaceTy { layout, ..*base }, len))
}

/// Gets the place of a field inside the place, and also the field's type.
/// Just a convenience function, but used quite a bit.
/// This is the only projection that might have a side-effect: We cannot project
@@ -594,6 +610,16 @@ where
})
}

/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
/// Also returns the number of elements.
pub fn place_to_simd(
&mut self,
base: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
let mplace = self.force_allocation(base)?;
self.mplace_to_simd(&mplace)
}

/// Computes a place. You should only use this if you intend to write into this
/// place; for reading, a more efficient alternative is `eval_place_for_read`.
pub fn eval_place(
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -1805,17 +1805,22 @@ impl<'tcx> TyS<'tcx> {
pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
match self.kind() {
Adt(def, substs) => {
assert!(def.repr.simd(), "`simd_size_and_type` called on non-SIMD type");
let variant = def.non_enum_variant();
let f0_ty = variant.fields[0].ty(tcx, substs);

match f0_ty.kind() {
// If the first field is an array, we assume it is the only field and its
// elements are the SIMD components.
Array(f0_elem_ty, f0_len) => {
// FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112
// The way we evaluate the `N` in `[T; N]` here only works since we use
// `simd_size_and_type` post-monomorphization. It will probably start to ICE
// if we use it in generic code. See the `simd-array-trait` ui test.
(f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, f0_elem_ty)
}
// Otherwise, the fields of this Adt are the SIMD components (and we assume they
// all have the same type).
_ => (variant.fields.len() as u64, f0_ty),
}
}
20 changes: 10 additions & 10 deletions library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
@@ -1250,7 +1250,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(uppercase_a.is_ascii_alphabetic());
/// assert!(uppercase_g.is_ascii_alphabetic());
@@ -1284,7 +1284,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(uppercase_a.is_ascii_uppercase());
/// assert!(uppercase_g.is_ascii_uppercase());
@@ -1318,7 +1318,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(!uppercase_a.is_ascii_lowercase());
/// assert!(!uppercase_g.is_ascii_lowercase());
@@ -1355,7 +1355,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(uppercase_a.is_ascii_alphanumeric());
/// assert!(uppercase_g.is_ascii_alphanumeric());
@@ -1389,7 +1389,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(!uppercase_a.is_ascii_digit());
/// assert!(!uppercase_g.is_ascii_digit());
@@ -1426,7 +1426,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(uppercase_a.is_ascii_hexdigit());
/// assert!(!uppercase_g.is_ascii_hexdigit());
@@ -1464,7 +1464,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(!uppercase_a.is_ascii_punctuation());
/// assert!(!uppercase_g.is_ascii_punctuation());
@@ -1498,7 +1498,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(uppercase_a.is_ascii_graphic());
/// assert!(uppercase_g.is_ascii_graphic());
@@ -1549,7 +1549,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(!uppercase_a.is_ascii_whitespace());
/// assert!(!uppercase_g.is_ascii_whitespace());
@@ -1585,7 +1585,7 @@ impl char {
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
/// let esc = '\x1b';
///
/// assert!(!uppercase_a.is_ascii_control());
/// assert!(!uppercase_g.is_ascii_control());
20 changes: 10 additions & 10 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
@@ -428,7 +428,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(uppercase_a.is_ascii_alphabetic());
/// assert!(uppercase_g.is_ascii_alphabetic());
@@ -462,7 +462,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(uppercase_a.is_ascii_uppercase());
/// assert!(uppercase_g.is_ascii_uppercase());
@@ -496,7 +496,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(!uppercase_a.is_ascii_lowercase());
/// assert!(!uppercase_g.is_ascii_lowercase());
@@ -533,7 +533,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(uppercase_a.is_ascii_alphanumeric());
/// assert!(uppercase_g.is_ascii_alphanumeric());
@@ -567,7 +567,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(!uppercase_a.is_ascii_digit());
/// assert!(!uppercase_g.is_ascii_digit());
@@ -604,7 +604,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(uppercase_a.is_ascii_hexdigit());
/// assert!(!uppercase_g.is_ascii_hexdigit());
@@ -642,7 +642,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(!uppercase_a.is_ascii_punctuation());
/// assert!(!uppercase_g.is_ascii_punctuation());
@@ -676,7 +676,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(uppercase_a.is_ascii_graphic());
/// assert!(uppercase_g.is_ascii_graphic());
@@ -727,7 +727,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(!uppercase_a.is_ascii_whitespace());
/// assert!(!uppercase_g.is_ascii_whitespace());
@@ -763,7 +763,7 @@ impl u8 {
/// let percent = b'%';
/// let space = b' ';
/// let lf = b'\n';
/// let esc = 0x1b_u8;
/// let esc = b'\x1b';
///
/// assert!(!uppercase_a.is_ascii_control());
/// assert!(!uppercase_g.is_ascii_control());
8 changes: 3 additions & 5 deletions library/core/src/primitive_docs.rs
Original file line number Diff line number Diff line change
@@ -1104,11 +1104,10 @@ mod prim_usize {}
/// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!)
/// * [`Deref`]
/// * [`Borrow`]
/// * [`Pointer`]
/// * [`fmt::Pointer`]
///
/// [`Deref`]: ops::Deref
/// [`Borrow`]: borrow::Borrow
/// [`Pointer`]: fmt::Pointer
///
/// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating
/// multiple simultaneous mutable borrows), plus the following, regardless of the type of its
@@ -1124,7 +1123,7 @@ mod prim_usize {}
/// The following traits are implemented on `&T` references if the underlying `T` also implements
/// that trait:
///
/// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`]
/// * All the traits in [`std::fmt`] except [`fmt::Pointer`] (which is implemented regardless of the type of its referent) and [`fmt::Write`]
/// * [`PartialOrd`]
/// * [`Ord`]
/// * [`PartialEq`]
@@ -1133,9 +1132,9 @@ mod prim_usize {}
/// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`)
/// * [`Hash`]
/// * [`ToSocketAddrs`]
/// * [`Send`] \(`&T` references also require <code>T: [Sync]</code>)
///
/// [`std::fmt`]: fmt
/// ['Pointer`]: fmt::Pointer
/// [`Hash`]: hash::Hash
#[doc = concat!("[`ToSocketAddrs`]: ", include_str!("../primitive_docs/net_tosocketaddrs.md"))]
///
@@ -1150,7 +1149,6 @@ mod prim_usize {}
/// * [`ExactSizeIterator`]
/// * [`FusedIterator`]
/// * [`TrustedLen`]
/// * [`Send`] \(note that `&T` references only get `Send` if <code>T: [Sync]</code>)
/// * [`io::Write`]
/// * [`Read`]
/// * [`Seek`]
8 changes: 3 additions & 5 deletions library/std/src/primitive_docs.rs
Original file line number Diff line number Diff line change
@@ -1104,11 +1104,10 @@ mod prim_usize {}
/// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!)
/// * [`Deref`]
/// * [`Borrow`]
/// * [`Pointer`]
/// * [`fmt::Pointer`]
///
/// [`Deref`]: ops::Deref
/// [`Borrow`]: borrow::Borrow
/// [`Pointer`]: fmt::Pointer
///
/// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating
/// multiple simultaneous mutable borrows), plus the following, regardless of the type of its
@@ -1124,7 +1123,7 @@ mod prim_usize {}
/// The following traits are implemented on `&T` references if the underlying `T` also implements
/// that trait:
///
/// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`]
/// * All the traits in [`std::fmt`] except [`fmt::Pointer`] (which is implemented regardless of the type of its referent) and [`fmt::Write`]
/// * [`PartialOrd`]
/// * [`Ord`]
/// * [`PartialEq`]
@@ -1133,9 +1132,9 @@ mod prim_usize {}
/// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`)
/// * [`Hash`]
/// * [`ToSocketAddrs`]
/// * [`Send`] \(`&T` references also require <code>T: [Sync]</code>)
///
/// [`std::fmt`]: fmt
/// ['Pointer`]: fmt::Pointer
/// [`Hash`]: hash::Hash
#[doc = concat!("[`ToSocketAddrs`]: ", include_str!("../primitive_docs/net_tosocketaddrs.md"))]
///
@@ -1150,7 +1149,6 @@ mod prim_usize {}
/// * [`ExactSizeIterator`]
/// * [`FusedIterator`]
/// * [`TrustedLen`]
/// * [`Send`] \(note that `&T` references only get `Send` if <code>T: [Sync]</code>)
/// * [`io::Write`]
/// * [`Read`]
/// * [`Seek`]
1 change: 1 addition & 0 deletions src/doc/rustdoc/src/unstable-features.md
Original file line number Diff line number Diff line change
@@ -398,6 +398,7 @@ undocumented item:
```rust
/// This item has documentation
pub fn foo() {}

pub fn no_documentation() {}
```

17 changes: 7 additions & 10 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rustc_ast as ast;
use rustc_ast::{self as ast, token};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{ColorConfig, ErrorReported, FatalError};
@@ -537,7 +537,6 @@ crate fn make_test(
use rustc_errors::emitter::{Emitter, EmitterWriter};
use rustc_errors::Handler;
use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::parser::ForceCollect;
use rustc_session::parse::ParseSess;
use rustc_span::source_map::FilePathMapping;

@@ -573,9 +572,9 @@ crate fn make_test(
}
};

loop {
match parser.parse_item(ForceCollect::No) {
Ok(Some(item)) => {
match parser.parse_mod(&token::Eof) {
Ok((_attrs, items, _span)) => {
for item in items {
if !found_main {
if let ast::ItemKind::Fn(..) = item.kind {
if item.ident.name == sym::main {
@@ -607,11 +606,9 @@ crate fn make_test(
break;
}
}
Ok(None) => break,
Err(mut e) => {
e.cancel();
break;
}
}
Err(mut e) => {
e.cancel();
}
}

6 changes: 3 additions & 3 deletions src/librustdoc/externalfiles.rs
Original file line number Diff line number Diff line change
@@ -8,13 +8,13 @@ use serde::Serialize;

#[derive(Clone, Debug, Serialize)]
crate struct ExternalHtml {
/// Content that will be included inline in the <head> section of a
/// Content that will be included inline in the `<head>` section of a
/// rendered Markdown file or generated documentation
crate in_header: String,
/// Content that will be included inline between <body> and the content of
/// Content that will be included inline between `<body>` and the content of
/// a rendered Markdown file or generated documentation
crate before_content: String,
/// Content that will be included inline between the content and </body> of
/// Content that will be included inline between the content and `</body>` of
/// a rendered Markdown file or generated documentation
crate after_content: String,
}
24 changes: 11 additions & 13 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
@@ -1080,7 +1080,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.as_ref().unwrap()));
write!(
w,
"<div id=\"{id}\" class=\"variant small-section-header\">\
"<h3 id=\"{id}\" class=\"variant small-section-header\">\
<a href=\"#{id}\" class=\"anchor field\"></a>\
<code>{name}",
id = id,
@@ -1093,9 +1093,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
}
w.write_str("</code>");
render_stability_since(w, variant, it, cx.tcx());
w.write_str("</div>");
document(w, cx, variant, Some(it), HeadingOffset::H3);
document_non_exhaustive(w, variant);
w.write_str("</h3>");

use crate::clean::Variant;
if let Some((extra, fields)) = match *variant.kind {
@@ -1109,12 +1107,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
variant.name.as_ref().unwrap()
));
write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
write!(
w,
"<h3>{extra}Fields of <b>{name}</b></h3><div>",
extra = extra,
name = variant.name.as_ref().unwrap(),
);
write!(w, "<h4>{extra}Fields</h4>", extra = extra,);
document_non_exhaustive(w, variant);
for field in fields {
match *field.kind {
clean::StrippedItem(box clean::StructFieldItem(_)) => {}
@@ -1126,21 +1120,25 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
));
write!(
w,
"<span id=\"{id}\" class=\"variant small-section-header\">\
"<div class=\"sub-variant-field\">\
<span id=\"{id}\" class=\"variant small-section-header\">\
<a href=\"#{id}\" class=\"anchor field\"></a>\
<code>{f}:&nbsp;{t}</code>\
</span>",
id = id,
f = field.name.as_ref().unwrap(),
t = ty.print(cx)
);
document(w, cx, field, Some(variant), HeadingOffset::H4);
document(w, cx, field, Some(variant), HeadingOffset::H5);
write!(w, "</div>");
}
_ => unreachable!(),
}
}
w.write_str("</div></div>");
w.write_str("</div>");
}

document(w, cx, variant, Some(it), HeadingOffset::H4);
}
}
let def_id = it.def_id.expect_def_id();
29 changes: 16 additions & 13 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
@@ -1102,25 +1102,28 @@ a.test-arrow:hover{
margin-right: 5px;
}

.sub-variant, .sub-variant > h3 {
margin-top: 0px !important;
padding-top: 1px;
h3.variant {
font-weight: 600;
font-size: 1.1em;
margin-bottom: 10px;
border-bottom: none;
}

#main .sub-variant > h3 {
font-size: 15px;
margin-left: 25px;
margin-bottom: 5px;
.sub-variant h4 {
font-size: 1em;
font-weight: 400;
border-bottom: none;
margin-top: 0;
margin-bottom: 0;
}

.sub-variant > div {
margin-left: 20px;
margin-bottom: 10px;
.sub-variant {
margin-left: 24px;
margin-bottom: 40px;
}

.sub-variant > div > span {
display: block;
position: relative;
.sub-variant > .sub-variant-field {
margin-left: 24px;
}

.toggle-label {
40 changes: 20 additions & 20 deletions src/test/rustdoc-gui/headings.goml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This test check that headers (a) have the correct heading level, (b) are the right size,
// This test checks that headers (a) have the correct heading level, (b) are the right size,
// and (c) have the correct underlining (or absence of underlining).
// The sizes may change as design changes, but try to make sure a lower header is never bigger than
// its parent headers. Also make sure lower headers don't have underlines when their parents lack
@@ -67,25 +67,25 @@ assert-css: ("h4#top-doc-prose-sub-sub-heading", {"border-bottom-width": "1px"})
assert-css: ("h2#variants", {"font-size": "22.4px"})
assert-css: ("h2#variants", {"border-bottom-width": "1px"})

assert-css: ("h3#none-prose-title", {"font-size": "20.8px"})
assert-css: ("h3#none-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h4#none-prose-sub-heading", {"font-size": "16px"})
assert-css: ("h4#none-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h3#wrapped-prose-title", {"font-size": "20.8px"})
assert-css: ("h3#wrapped-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h4#wrapped-prose-sub-heading", {"font-size": "16px"})
assert-css: ("h4#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h4#wrapped0-prose-title", {"font-size": "16px"})
assert-css: ("h4#wrapped0-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h5#wrapped0-prose-sub-heading", {"font-size": "16px"})
assert-css: ("h5#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h4#structy-prose-title", {"font-size": "16px"})
assert-css: ("h4#structy-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h5#structy-prose-sub-heading", {"font-size": "16px"})
assert-css: ("h5#structy-prose-sub-heading", {"border-bottom-width": "0px"})
assert-css: ("h4#none-prose-title", {"font-size": "16px"})
assert-css: ("h4#none-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h5#none-prose-sub-heading", {"font-size": "16px"})
assert-css: ("h5#none-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h4#wrapped-prose-title", {"font-size": "16px"})
assert-css: ("h4#wrapped-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h5#wrapped-prose-sub-heading", {"font-size": "16px"})
assert-css: ("h5#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h5#wrapped0-prose-title", {"font-size": "16px"})
assert-css: ("h5#wrapped0-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h6#wrapped0-prose-sub-heading", {"font-size": "15.2px"})
assert-css: ("h6#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h5#structy-prose-title", {"font-size": "16px"})
assert-css: ("h5#structy-prose-title", {"border-bottom-width": "0px"})
assert-css: ("h6#structy-prose-sub-heading", {"font-size": "15.2px"})
assert-css: ("h6#structy-prose-sub-heading", {"border-bottom-width": "0px"})

assert-css: ("h2#implementations", {"font-size": "22.4px"})
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
18 changes: 18 additions & 0 deletions src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// FIXME: if/when the output of the test harness can be tested on its own, this test should be
// adapted to use that, and that normalize line can go away

// compile-flags:--test
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
// failure-status: 101

/// <https://github.com/rust-lang/rust/issues/91014>
///
/// ```rust
/// struct S {}; // unexpected semicolon after struct def
///
/// fn main() {
/// assert_eq!(0, 1);
/// }
/// ```
mod m {}
24 changes: 24 additions & 0 deletions src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

running 1 test
test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... FAILED

failures:

---- $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) stdout ----
error: expected item, found `;`
--> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12
|
LL | struct S {}; // unexpected semicolon after struct def
| ^ help: remove this semicolon
|
= help: braced struct declarations are not followed by a semicolon

error: aborting due to previous error

Couldn't compile the test.

failures:
$DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11)

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

40 changes: 40 additions & 0 deletions src/test/rustdoc/enum-headings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![crate_name = "foo"]
// @has foo/enum.Token.html
/// A token!
/// # First
/// Some following text...
// @has - '//h2[@id="first"]' "First"
pub enum Token {
/// A declaration!
/// # Variant-First
/// Some following text...
// @has - '//h4[@id="variant-first"]' "Variant-First"
Declaration {
/// A version!
/// # Variant-Field-First
/// Some following text...
// @has - '//h5[@id="variant-field-first"]' "Variant-Field-First"
version: String,
},
/// A Zoople!
/// # Variant-First
Zoople(
// @has - '//h5[@id="variant-tuple-field-first"]' "Variant-Tuple-Field-First"
/// Zoople's first variant!
/// # Variant-Tuple-Field-First
/// Some following text...
usize,
),
/// Unfinished business!
/// # Non-Exhaustive-First
/// Some following text...
// @has - '//h4[@id="non-exhaustive-first"]' "Non-Exhaustive-First"
#[non_exhaustive]
Unfinished {
/// This is x.
/// # X-First
/// Some following text...
// @has - '//h5[@id="x-first"]' "X-First"
x: usize,
},
}
4 changes: 2 additions & 2 deletions src/test/rustdoc/tuple-struct-fields-doc.rs
Original file line number Diff line number Diff line change
@@ -20,10 +20,10 @@ pub struct Foo(

// @has foo/enum.Bar.html
// @has - '//pre[@class="rust enum"]' 'BarVariant(String),'
// @matches - '//*[@id="variant.BarVariant.fields"]/h3' '^Tuple Fields of BarVariant$'
// @matches - '//*[@id="variant.BarVariant.fields"]/h4' '^Tuple Fields$'
// @has - '//*[@id="variant.BarVariant.field.0"]' '0: String'
// @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs'
// @matches - '//*[@id="variant.FooVariant.fields"]/h3' '^Fields of FooVariant$'
// @matches - '//*[@id="variant.FooVariant.fields"]/h4' '^Fields$'
pub enum Bar {
BarVariant(
/// Hello docs
22 changes: 16 additions & 6 deletions src/test/ui/consts/const-eval/simd/insert_extract.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,9 @@

#[repr(simd)] struct i8x1(i8);
#[repr(simd)] struct u16x2(u16, u16);
#[repr(simd)] struct f32x4(f32, f32, f32, f32);
// Make some of them array types to ensure those also work.
#[repr(simd)] struct i8x1_arr([i8; 1]);
#[repr(simd)] struct f32x4([f32; 4]);

extern "platform-intrinsic" {
#[rustc_const_stable(feature = "foo", since = "1.3.37")]
@@ -25,6 +27,14 @@ fn main() {
assert_eq!(X0, 42);
assert_eq!(Y0, 42);
}
{
const U: i8x1_arr = i8x1_arr([13]);
const V: i8x1_arr = unsafe { simd_insert(U, 0_u32, 42_i8) };
const X0: i8 = V.0[0];
const Y0: i8 = unsafe { simd_extract(V, 0) };
assert_eq!(X0, 42);
assert_eq!(Y0, 42);
}
{
const U: u16x2 = u16x2(13, 14);
const V: u16x2 = unsafe { simd_insert(U, 1_u32, 42_u16) };
@@ -38,12 +48,12 @@ fn main() {
assert_eq!(Y1, 42);
}
{
const U: f32x4 = f32x4(13., 14., 15., 16.);
const U: f32x4 = f32x4([13., 14., 15., 16.]);
const V: f32x4 = unsafe { simd_insert(U, 1_u32, 42_f32) };
const X0: f32 = V.0;
const X1: f32 = V.1;
const X2: f32 = V.2;
const X3: f32 = V.3;
const X0: f32 = V.0[0];
const X1: f32 = V.0[1];
const X2: f32 = V.0[2];
const X3: f32 = V.0[3];
const Y0: f32 = unsafe { simd_extract(V, 0) };
const Y1: f32 = unsafe { simd_extract(V, 1) };
const Y2: f32 = unsafe { simd_extract(V, 2) };
28 changes: 28 additions & 0 deletions src/test/ui/lang-items/issue-87573.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Regression test for #87573, ensures that duplicate lang items or invalid generics
// for lang items doesn't cause ICE.

#![feature(no_core, lang_items)]
#![no_core]
#![crate_type = "lib"]

pub static STATIC_BOOL: bool = true;

#[lang = "sized"]
trait Sized {}

#[lang = "copy"]
trait Copy {}

#[lang = "sync"]
trait Sync {}
impl Sync for bool {}

#[lang = "drop_in_place"]
//~^ ERROR: `drop_in_place` language item must be applied to a function with at least 1 generic argument
fn drop_fn() {
while false {}
}

#[lang = "start"]
//~^ ERROR: `start` language item must be applied to a function with 1 generic argument
fn start(){}
21 changes: 21 additions & 0 deletions src/test/ui/lang-items/issue-87573.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0718]: `drop_in_place` language item must be applied to a function with at least 1 generic argument
--> $DIR/issue-87573.rs:20:1
|
LL | #[lang = "drop_in_place"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | fn drop_fn() {
| - this function has 0 generic arguments

error[E0718]: `start` language item must be applied to a function with 1 generic argument
--> $DIR/issue-87573.rs:26:1
|
LL | #[lang = "start"]
| ^^^^^^^^^^^^^^^^^
LL |
LL | fn start(){}
| - this function has 0 generic arguments

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0718`.