diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 5e7bbc0113271..9bbb42eb01961 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -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 diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index b6682b13ed216..de9e94ce2ac0c 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -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. /// diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index d425b84bdaf26..d7f2853fc86f5 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -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( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 610f9bd8f82d7..c79e25f4781c8 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1805,10 +1805,13 @@ 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 @@ -1816,6 +1819,8 @@ impl<'tcx> TyS<'tcx> { // 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), } } diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index d5ad0c385c701..7250dca2adfe4 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -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()); diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index a8f2ded46594e..e3eab07b9df6d 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -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()); diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 0de9126dab2fe..f47a30c9b5d7d 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -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 T: [Sync]) /// /// [`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 T: [Sync]) /// * [`io::Write`] /// * [`Read`] /// * [`Seek`] diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 0de9126dab2fe..f47a30c9b5d7d 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -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 T: [Sync]) /// /// [`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 T: [Sync]) /// * [`io::Write`] /// * [`Read`] /// * [`Seek`] diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 16532215c6f33..8da1d22a4d172 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -398,6 +398,7 @@ undocumented item: ```rust /// This item has documentation pub fn foo() {} + pub fn no_documentation() {} ``` diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c10eebf49fc8d..37db20aaefa8d 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -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(); } } diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 302fc5a677771..6ed911b8d2409 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -8,13 +8,13 @@ use serde::Serialize; #[derive(Clone, Debug, Serialize)] crate struct ExternalHtml { - /// Content that will be included inline in the section of a + /// Content that will be included inline in the `` section of a /// rendered Markdown file or generated documentation crate in_header: String, - /// Content that will be included inline between and the content of + /// Content that will be included inline between `` 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 of + /// Content that will be included inline between the content and `` of /// a rendered Markdown file or generated documentation crate after_content: String, } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 7ef773fe5ff29..049d17a4b477a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -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, - "
\ + "

\ \ {name}", id = id, @@ -1093,9 +1093,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum } w.write_str(""); render_stability_since(w, variant, it, cx.tcx()); - w.write_str("

"); - document(w, cx, variant, Some(it), HeadingOffset::H3); - document_non_exhaustive(w, variant); + w.write_str(""); 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, "
", id = variant_id); - write!( - w, - "

{extra}Fields of {name}

", - extra = extra, - name = variant.name.as_ref().unwrap(), - ); + write!(w, "

{extra}Fields

", extra = extra,); + document_non_exhaustive(w, variant); for field in fields { match *field.kind { clean::StrippedItem(box clean::StructFieldItem(_)) => {} @@ -1126,7 +1120,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum )); write!( w, - "\ + "
\ + \ \ {f}: {t}\ ", @@ -1134,13 +1129,16 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum 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, "
"); } _ => unreachable!(), } } - w.write_str("
"); + w.write_str(""); } + + document(w, cx, variant, Some(it), HeadingOffset::H4); } } let def_id = it.def_id.expect_def_id(); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 89a763ef6d707..cb1df15bbb152 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -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 { diff --git a/src/test/rustdoc-gui/headings.goml b/src/test/rustdoc-gui/headings.goml index bdf17ec457057..87c512468e05f 100644 --- a/src/test/rustdoc-gui/headings.goml +++ b/src/test/rustdoc-gui/headings.goml @@ -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"}) diff --git a/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.rs b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.rs new file mode 100644 index 0000000000000..16d737106ea89 --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.rs @@ -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 + +/// +/// +/// ```rust +/// struct S {}; // unexpected semicolon after struct def +/// +/// fn main() { +/// assert_eq!(0, 1); +/// } +/// ``` +mod m {} diff --git a/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout new file mode 100644 index 0000000000000..61468b6c7457b --- /dev/null +++ b/src/test/rustdoc-ui/failed-doctest-extra-semicolon-on-item.stdout @@ -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 + diff --git a/src/test/rustdoc/enum-headings.rs b/src/test/rustdoc/enum-headings.rs new file mode 100644 index 0000000000000..2e5c34391c4af --- /dev/null +++ b/src/test/rustdoc/enum-headings.rs @@ -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, + }, +} diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs index f3d8e39ea2d26..139c5b4391ab7 100644 --- a/src/test/rustdoc/tuple-struct-fields-doc.rs +++ b/src/test/rustdoc/tuple-struct-fields-doc.rs @@ -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 diff --git a/src/test/ui/consts/const-eval/simd/insert_extract.rs b/src/test/ui/consts/const-eval/simd/insert_extract.rs index cae8fcf1068ad..a1d6c5e51b498 100644 --- a/src/test/ui/consts/const-eval/simd/insert_extract.rs +++ b/src/test/ui/consts/const-eval/simd/insert_extract.rs @@ -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) }; diff --git a/src/test/ui/lang-items/issue-87573.rs b/src/test/ui/lang-items/issue-87573.rs new file mode 100644 index 0000000000000..aeb0c245a72ec --- /dev/null +++ b/src/test/ui/lang-items/issue-87573.rs @@ -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(){} diff --git a/src/test/ui/lang-items/issue-87573.stderr b/src/test/ui/lang-items/issue-87573.stderr new file mode 100644 index 0000000000000..25560cfa0e6c7 --- /dev/null +++ b/src/test/ui/lang-items/issue-87573.stderr @@ -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`.