Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3b65165

Browse files
committedNov 20, 2021
Auto merge of #91064 - matthiaskrgr:rollup-2ijidpt, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #88361 (Makes docs for references a little less confusing) - #90089 (Improve display of enum variants) - #90956 (Add a regression test for #87573) - #90999 (fix CTFE/Miri simd_insert/extract on array-style repr(simd) types) - #91026 (rustdoc doctest: detect `fn main` after an unexpected semicolon) - #91035 (Put back removed empty line) - #91044 (Turn all 0x1b_u8 into '\x1b' or b'\x1b') - #91054 (rustdoc: Fix some unescaped HTML tags in docs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents a77da2d + 54bc333 commit 3b65165

File tree

21 files changed

+293
-129
lines changed

21 files changed

+293
-129
lines changed
 

‎compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -419,48 +419,33 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
419419
sym::simd_insert => {
420420
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
421421
let elem = &args[2];
422-
let input = &args[0];
423-
let (len, e_ty) = input.layout.ty.simd_size_and_type(*self.tcx);
422+
let (input, input_len) = self.operand_to_simd(&args[0])?;
423+
let (dest, dest_len) = self.place_to_simd(dest)?;
424+
assert_eq!(input_len, dest_len, "Return vector length must match input length");
424425
assert!(
425-
index < len,
426-
"Index `{}` must be in bounds of vector type `{}`: `[0, {})`",
426+
index < dest_len,
427+
"Index `{}` must be in bounds of vector with length {}`",
427428
index,
428-
e_ty,
429-
len
430-
);
431-
assert_eq!(
432-
input.layout, dest.layout,
433-
"Return type `{}` must match vector type `{}`",
434-
dest.layout.ty, input.layout.ty
435-
);
436-
assert_eq!(
437-
elem.layout.ty, e_ty,
438-
"Scalar element type `{}` must match vector element type `{}`",
439-
elem.layout.ty, e_ty
429+
dest_len
440430
);
441431

442-
for i in 0..len {
443-
let place = self.place_index(dest, i)?;
444-
let value = if i == index { *elem } else { self.operand_index(input, i)? };
445-
self.copy_op(&value, &place)?;
432+
for i in 0..dest_len {
433+
let place = self.mplace_index(&dest, i)?;
434+
let value =
435+
if i == index { *elem } else { self.mplace_index(&input, i)?.into() };
436+
self.copy_op(&value, &place.into())?;
446437
}
447438
}
448439
sym::simd_extract => {
449440
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
450-
let (len, e_ty) = args[0].layout.ty.simd_size_and_type(*self.tcx);
441+
let (input, input_len) = self.operand_to_simd(&args[0])?;
451442
assert!(
452-
index < len,
453-
"index `{}` is out-of-bounds of vector type `{}` with length `{}`",
443+
index < input_len,
444+
"index `{}` must be in bounds of vector with length `{}`",
454445
index,
455-
e_ty,
456-
len
457-
);
458-
assert_eq!(
459-
e_ty, dest.layout.ty,
460-
"Return type `{}` must match vector element type `{}`",
461-
dest.layout.ty, e_ty
446+
input_len
462447
);
463-
self.copy_op(&self.operand_index(&args[0], index)?, dest)?;
448+
self.copy_op(&self.mplace_index(&input, index)?.into(), dest)?;
464449
}
465450
sym::likely | sym::unlikely | sym::black_box => {
466451
// These just return their argument

‎compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
437437
})
438438
}
439439

440+
/// Converts a repr(simd) operand into an operand where `place_index` accesses the SIMD elements.
441+
/// Also returns the number of elements.
442+
pub fn operand_to_simd(
443+
&self,
444+
base: &OpTy<'tcx, M::PointerTag>,
445+
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
446+
// Basically we just transmute this place into an array following simd_size_and_type.
447+
// This only works in memory, but repr(simd) types should never be immediates anyway.
448+
assert!(base.layout.ty.is_simd());
449+
self.mplace_to_simd(&base.assert_mem_place())
450+
}
451+
440452
/// Read from a local. Will not actually access the local if reading from a ZST.
441453
/// Will not access memory, instead an indirect `Operand` is returned.
442454
///

‎compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
200200
}
201201
} else {
202202
// Go through the layout. There are lots of types that support a length,
203-
// e.g., SIMD types.
203+
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
204204
match self.layout.fields {
205205
FieldsShape::Array { count, .. } => Ok(count),
206206
_ => bug!("len not supported on sized type {:?}", self.layout.ty),
@@ -533,6 +533,22 @@ where
533533
})
534534
}
535535

536+
/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
537+
/// Also returns the number of elements.
538+
pub fn mplace_to_simd(
539+
&self,
540+
base: &MPlaceTy<'tcx, M::PointerTag>,
541+
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
542+
// Basically we just transmute this place into an array following simd_size_and_type.
543+
// (Transmuting is okay since this is an in-memory place. We also double-check the size
544+
// stays the same.)
545+
let (len, e_ty) = base.layout.ty.simd_size_and_type(*self.tcx);
546+
let array = self.tcx.mk_array(e_ty, len);
547+
let layout = self.layout_of(array)?;
548+
assert_eq!(layout.size, base.layout.size);
549+
Ok((MPlaceTy { layout, ..*base }, len))
550+
}
551+
536552
/// Gets the place of a field inside the place, and also the field's type.
537553
/// Just a convenience function, but used quite a bit.
538554
/// This is the only projection that might have a side-effect: We cannot project
@@ -594,6 +610,16 @@ where
594610
})
595611
}
596612

613+
/// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
614+
/// Also returns the number of elements.
615+
pub fn place_to_simd(
616+
&mut self,
617+
base: &PlaceTy<'tcx, M::PointerTag>,
618+
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, u64)> {
619+
let mplace = self.force_allocation(base)?;
620+
self.mplace_to_simd(&mplace)
621+
}
622+
597623
/// Computes a place. You should only use this if you intend to write into this
598624
/// place; for reading, a more efficient alternative is `eval_place_for_read`.
599625
pub fn eval_place(

‎compiler/rustc_middle/src/ty/sty.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,17 +1805,22 @@ impl<'tcx> TyS<'tcx> {
18051805
pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
18061806
match self.kind() {
18071807
Adt(def, substs) => {
1808+
assert!(def.repr.simd(), "`simd_size_and_type` called on non-SIMD type");
18081809
let variant = def.non_enum_variant();
18091810
let f0_ty = variant.fields[0].ty(tcx, substs);
18101811

18111812
match f0_ty.kind() {
1813+
// If the first field is an array, we assume it is the only field and its
1814+
// elements are the SIMD components.
18121815
Array(f0_elem_ty, f0_len) => {
18131816
// FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112
18141817
// The way we evaluate the `N` in `[T; N]` here only works since we use
18151818
// `simd_size_and_type` post-monomorphization. It will probably start to ICE
18161819
// if we use it in generic code. See the `simd-array-trait` ui test.
18171820
(f0_len.eval_usize(tcx, ParamEnv::empty()) as u64, f0_elem_ty)
18181821
}
1822+
// Otherwise, the fields of this Adt are the SIMD components (and we assume they
1823+
// all have the same type).
18191824
_ => (variant.fields.len() as u64, f0_ty),
18201825
}
18211826
}

‎library/core/src/char/methods.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,7 @@ impl char {
12501250
/// let percent = '%';
12511251
/// let space = ' ';
12521252
/// let lf = '\n';
1253-
/// let esc: char = 0x1b_u8.into();
1253+
/// let esc = '\x1b';
12541254
///
12551255
/// assert!(uppercase_a.is_ascii_alphabetic());
12561256
/// assert!(uppercase_g.is_ascii_alphabetic());
@@ -1284,7 +1284,7 @@ impl char {
12841284
/// let percent = '%';
12851285
/// let space = ' ';
12861286
/// let lf = '\n';
1287-
/// let esc: char = 0x1b_u8.into();
1287+
/// let esc = '\x1b';
12881288
///
12891289
/// assert!(uppercase_a.is_ascii_uppercase());
12901290
/// assert!(uppercase_g.is_ascii_uppercase());
@@ -1318,7 +1318,7 @@ impl char {
13181318
/// let percent = '%';
13191319
/// let space = ' ';
13201320
/// let lf = '\n';
1321-
/// let esc: char = 0x1b_u8.into();
1321+
/// let esc = '\x1b';
13221322
///
13231323
/// assert!(!uppercase_a.is_ascii_lowercase());
13241324
/// assert!(!uppercase_g.is_ascii_lowercase());
@@ -1355,7 +1355,7 @@ impl char {
13551355
/// let percent = '%';
13561356
/// let space = ' ';
13571357
/// let lf = '\n';
1358-
/// let esc: char = 0x1b_u8.into();
1358+
/// let esc = '\x1b';
13591359
///
13601360
/// assert!(uppercase_a.is_ascii_alphanumeric());
13611361
/// assert!(uppercase_g.is_ascii_alphanumeric());
@@ -1389,7 +1389,7 @@ impl char {
13891389
/// let percent = '%';
13901390
/// let space = ' ';
13911391
/// let lf = '\n';
1392-
/// let esc: char = 0x1b_u8.into();
1392+
/// let esc = '\x1b';
13931393
///
13941394
/// assert!(!uppercase_a.is_ascii_digit());
13951395
/// assert!(!uppercase_g.is_ascii_digit());
@@ -1426,7 +1426,7 @@ impl char {
14261426
/// let percent = '%';
14271427
/// let space = ' ';
14281428
/// let lf = '\n';
1429-
/// let esc: char = 0x1b_u8.into();
1429+
/// let esc = '\x1b';
14301430
///
14311431
/// assert!(uppercase_a.is_ascii_hexdigit());
14321432
/// assert!(!uppercase_g.is_ascii_hexdigit());
@@ -1464,7 +1464,7 @@ impl char {
14641464
/// let percent = '%';
14651465
/// let space = ' ';
14661466
/// let lf = '\n';
1467-
/// let esc: char = 0x1b_u8.into();
1467+
/// let esc = '\x1b';
14681468
///
14691469
/// assert!(!uppercase_a.is_ascii_punctuation());
14701470
/// assert!(!uppercase_g.is_ascii_punctuation());
@@ -1498,7 +1498,7 @@ impl char {
14981498
/// let percent = '%';
14991499
/// let space = ' ';
15001500
/// let lf = '\n';
1501-
/// let esc: char = 0x1b_u8.into();
1501+
/// let esc = '\x1b';
15021502
///
15031503
/// assert!(uppercase_a.is_ascii_graphic());
15041504
/// assert!(uppercase_g.is_ascii_graphic());
@@ -1549,7 +1549,7 @@ impl char {
15491549
/// let percent = '%';
15501550
/// let space = ' ';
15511551
/// let lf = '\n';
1552-
/// let esc: char = 0x1b_u8.into();
1552+
/// let esc = '\x1b';
15531553
///
15541554
/// assert!(!uppercase_a.is_ascii_whitespace());
15551555
/// assert!(!uppercase_g.is_ascii_whitespace());
@@ -1585,7 +1585,7 @@ impl char {
15851585
/// let percent = '%';
15861586
/// let space = ' ';
15871587
/// let lf = '\n';
1588-
/// let esc: char = 0x1b_u8.into();
1588+
/// let esc = '\x1b';
15891589
///
15901590
/// assert!(!uppercase_a.is_ascii_control());
15911591
/// assert!(!uppercase_g.is_ascii_control());

‎library/core/src/num/mod.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ impl u8 {
428428
/// let percent = b'%';
429429
/// let space = b' ';
430430
/// let lf = b'\n';
431-
/// let esc = 0x1b_u8;
431+
/// let esc = b'\x1b';
432432
///
433433
/// assert!(uppercase_a.is_ascii_alphabetic());
434434
/// assert!(uppercase_g.is_ascii_alphabetic());
@@ -462,7 +462,7 @@ impl u8 {
462462
/// let percent = b'%';
463463
/// let space = b' ';
464464
/// let lf = b'\n';
465-
/// let esc = 0x1b_u8;
465+
/// let esc = b'\x1b';
466466
///
467467
/// assert!(uppercase_a.is_ascii_uppercase());
468468
/// assert!(uppercase_g.is_ascii_uppercase());
@@ -496,7 +496,7 @@ impl u8 {
496496
/// let percent = b'%';
497497
/// let space = b' ';
498498
/// let lf = b'\n';
499-
/// let esc = 0x1b_u8;
499+
/// let esc = b'\x1b';
500500
///
501501
/// assert!(!uppercase_a.is_ascii_lowercase());
502502
/// assert!(!uppercase_g.is_ascii_lowercase());
@@ -533,7 +533,7 @@ impl u8 {
533533
/// let percent = b'%';
534534
/// let space = b' ';
535535
/// let lf = b'\n';
536-
/// let esc = 0x1b_u8;
536+
/// let esc = b'\x1b';
537537
///
538538
/// assert!(uppercase_a.is_ascii_alphanumeric());
539539
/// assert!(uppercase_g.is_ascii_alphanumeric());
@@ -567,7 +567,7 @@ impl u8 {
567567
/// let percent = b'%';
568568
/// let space = b' ';
569569
/// let lf = b'\n';
570-
/// let esc = 0x1b_u8;
570+
/// let esc = b'\x1b';
571571
///
572572
/// assert!(!uppercase_a.is_ascii_digit());
573573
/// assert!(!uppercase_g.is_ascii_digit());
@@ -604,7 +604,7 @@ impl u8 {
604604
/// let percent = b'%';
605605
/// let space = b' ';
606606
/// let lf = b'\n';
607-
/// let esc = 0x1b_u8;
607+
/// let esc = b'\x1b';
608608
///
609609
/// assert!(uppercase_a.is_ascii_hexdigit());
610610
/// assert!(!uppercase_g.is_ascii_hexdigit());
@@ -642,7 +642,7 @@ impl u8 {
642642
/// let percent = b'%';
643643
/// let space = b' ';
644644
/// let lf = b'\n';
645-
/// let esc = 0x1b_u8;
645+
/// let esc = b'\x1b';
646646
///
647647
/// assert!(!uppercase_a.is_ascii_punctuation());
648648
/// assert!(!uppercase_g.is_ascii_punctuation());
@@ -676,7 +676,7 @@ impl u8 {
676676
/// let percent = b'%';
677677
/// let space = b' ';
678678
/// let lf = b'\n';
679-
/// let esc = 0x1b_u8;
679+
/// let esc = b'\x1b';
680680
///
681681
/// assert!(uppercase_a.is_ascii_graphic());
682682
/// assert!(uppercase_g.is_ascii_graphic());
@@ -727,7 +727,7 @@ impl u8 {
727727
/// let percent = b'%';
728728
/// let space = b' ';
729729
/// let lf = b'\n';
730-
/// let esc = 0x1b_u8;
730+
/// let esc = b'\x1b';
731731
///
732732
/// assert!(!uppercase_a.is_ascii_whitespace());
733733
/// assert!(!uppercase_g.is_ascii_whitespace());
@@ -763,7 +763,7 @@ impl u8 {
763763
/// let percent = b'%';
764764
/// let space = b' ';
765765
/// let lf = b'\n';
766-
/// let esc = 0x1b_u8;
766+
/// let esc = b'\x1b';
767767
///
768768
/// assert!(!uppercase_a.is_ascii_control());
769769
/// assert!(!uppercase_g.is_ascii_control());

‎library/core/src/primitive_docs.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,11 +1104,10 @@ mod prim_usize {}
11041104
/// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!)
11051105
/// * [`Deref`]
11061106
/// * [`Borrow`]
1107-
/// * [`Pointer`]
1107+
/// * [`fmt::Pointer`]
11081108
///
11091109
/// [`Deref`]: ops::Deref
11101110
/// [`Borrow`]: borrow::Borrow
1111-
/// [`Pointer`]: fmt::Pointer
11121111
///
11131112
/// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating
11141113
/// multiple simultaneous mutable borrows), plus the following, regardless of the type of its
@@ -1124,7 +1123,7 @@ mod prim_usize {}
11241123
/// The following traits are implemented on `&T` references if the underlying `T` also implements
11251124
/// that trait:
11261125
///
1127-
/// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`]
1126+
/// * All the traits in [`std::fmt`] except [`fmt::Pointer`] (which is implemented regardless of the type of its referent) and [`fmt::Write`]
11281127
/// * [`PartialOrd`]
11291128
/// * [`Ord`]
11301129
/// * [`PartialEq`]
@@ -1133,9 +1132,9 @@ mod prim_usize {}
11331132
/// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`)
11341133
/// * [`Hash`]
11351134
/// * [`ToSocketAddrs`]
1135+
/// * [`Send`] \(`&T` references also require <code>T: [Sync]</code>)
11361136
///
11371137
/// [`std::fmt`]: fmt
1138-
/// ['Pointer`]: fmt::Pointer
11391138
/// [`Hash`]: hash::Hash
11401139
#[doc = concat!("[`ToSocketAddrs`]: ", include_str!("../primitive_docs/net_tosocketaddrs.md"))]
11411140
///
@@ -1150,7 +1149,6 @@ mod prim_usize {}
11501149
/// * [`ExactSizeIterator`]
11511150
/// * [`FusedIterator`]
11521151
/// * [`TrustedLen`]
1153-
/// * [`Send`] \(note that `&T` references only get `Send` if <code>T: [Sync]</code>)
11541152
/// * [`io::Write`]
11551153
/// * [`Read`]
11561154
/// * [`Seek`]

‎library/std/src/primitive_docs.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,11 +1104,10 @@ mod prim_usize {}
11041104
/// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!)
11051105
/// * [`Deref`]
11061106
/// * [`Borrow`]
1107-
/// * [`Pointer`]
1107+
/// * [`fmt::Pointer`]
11081108
///
11091109
/// [`Deref`]: ops::Deref
11101110
/// [`Borrow`]: borrow::Borrow
1111-
/// [`Pointer`]: fmt::Pointer
11121111
///
11131112
/// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating
11141113
/// multiple simultaneous mutable borrows), plus the following, regardless of the type of its
@@ -1124,7 +1123,7 @@ mod prim_usize {}
11241123
/// The following traits are implemented on `&T` references if the underlying `T` also implements
11251124
/// that trait:
11261125
///
1127-
/// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`]
1126+
/// * All the traits in [`std::fmt`] except [`fmt::Pointer`] (which is implemented regardless of the type of its referent) and [`fmt::Write`]
11281127
/// * [`PartialOrd`]
11291128
/// * [`Ord`]
11301129
/// * [`PartialEq`]
@@ -1133,9 +1132,9 @@ mod prim_usize {}
11331132
/// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`)
11341133
/// * [`Hash`]
11351134
/// * [`ToSocketAddrs`]
1135+
/// * [`Send`] \(`&T` references also require <code>T: [Sync]</code>)
11361136
///
11371137
/// [`std::fmt`]: fmt
1138-
/// ['Pointer`]: fmt::Pointer
11391138
/// [`Hash`]: hash::Hash
11401139
#[doc = concat!("[`ToSocketAddrs`]: ", include_str!("../primitive_docs/net_tosocketaddrs.md"))]
11411140
///
@@ -1150,7 +1149,6 @@ mod prim_usize {}
11501149
/// * [`ExactSizeIterator`]
11511150
/// * [`FusedIterator`]
11521151
/// * [`TrustedLen`]
1153-
/// * [`Send`] \(note that `&T` references only get `Send` if <code>T: [Sync]</code>)
11541152
/// * [`io::Write`]
11551153
/// * [`Read`]
11561154
/// * [`Seek`]

‎src/doc/rustdoc/src/unstable-features.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ undocumented item:
398398
```rust
399399
/// This item has documentation
400400
pub fn foo() {}
401+
401402
pub fn no_documentation() {}
402403
```
403404

‎src/librustdoc/doctest.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_ast as ast;
1+
use rustc_ast::{self as ast, token};
22
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
33
use rustc_data_structures::sync::Lrc;
44
use rustc_errors::{ColorConfig, ErrorReported, FatalError};
@@ -537,7 +537,6 @@ crate fn make_test(
537537
use rustc_errors::emitter::{Emitter, EmitterWriter};
538538
use rustc_errors::Handler;
539539
use rustc_parse::maybe_new_parser_from_source_str;
540-
use rustc_parse::parser::ForceCollect;
541540
use rustc_session::parse::ParseSess;
542541
use rustc_span::source_map::FilePathMapping;
543542

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

576-
loop {
577-
match parser.parse_item(ForceCollect::No) {
578-
Ok(Some(item)) => {
575+
match parser.parse_mod(&token::Eof) {
576+
Ok((_attrs, items, _span)) => {
577+
for item in items {
579578
if !found_main {
580579
if let ast::ItemKind::Fn(..) = item.kind {
581580
if item.ident.name == sym::main {
@@ -607,11 +606,9 @@ crate fn make_test(
607606
break;
608607
}
609608
}
610-
Ok(None) => break,
611-
Err(mut e) => {
612-
e.cancel();
613-
break;
614-
}
609+
}
610+
Err(mut e) => {
611+
e.cancel();
615612
}
616613
}
617614

‎src/librustdoc/externalfiles.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use serde::Serialize;
88

99
#[derive(Clone, Debug, Serialize)]
1010
crate struct ExternalHtml {
11-
/// Content that will be included inline in the <head> section of a
11+
/// Content that will be included inline in the `<head>` section of a
1212
/// rendered Markdown file or generated documentation
1313
crate in_header: String,
14-
/// Content that will be included inline between <body> and the content of
14+
/// Content that will be included inline between `<body>` and the content of
1515
/// a rendered Markdown file or generated documentation
1616
crate before_content: String,
17-
/// Content that will be included inline between the content and </body> of
17+
/// Content that will be included inline between the content and `</body>` of
1818
/// a rendered Markdown file or generated documentation
1919
crate after_content: String,
2020
}

‎src/librustdoc/html/render/print_item.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
10801080
cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.as_ref().unwrap()));
10811081
write!(
10821082
w,
1083-
"<div id=\"{id}\" class=\"variant small-section-header\">\
1083+
"<h3 id=\"{id}\" class=\"variant small-section-header\">\
10841084
<a href=\"#{id}\" class=\"anchor field\"></a>\
10851085
<code>{name}",
10861086
id = id,
@@ -1093,9 +1093,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
10931093
}
10941094
w.write_str("</code>");
10951095
render_stability_since(w, variant, it, cx.tcx());
1096-
w.write_str("</div>");
1097-
document(w, cx, variant, Some(it), HeadingOffset::H3);
1098-
document_non_exhaustive(w, variant);
1096+
w.write_str("</h3>");
10991097

11001098
use crate::clean::Variant;
11011099
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
11091107
variant.name.as_ref().unwrap()
11101108
));
11111109
write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
1112-
write!(
1113-
w,
1114-
"<h3>{extra}Fields of <b>{name}</b></h3><div>",
1115-
extra = extra,
1116-
name = variant.name.as_ref().unwrap(),
1117-
);
1110+
write!(w, "<h4>{extra}Fields</h4>", extra = extra,);
1111+
document_non_exhaustive(w, variant);
11181112
for field in fields {
11191113
match *field.kind {
11201114
clean::StrippedItem(box clean::StructFieldItem(_)) => {}
@@ -1126,21 +1120,25 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
11261120
));
11271121
write!(
11281122
w,
1129-
"<span id=\"{id}\" class=\"variant small-section-header\">\
1123+
"<div class=\"sub-variant-field\">\
1124+
<span id=\"{id}\" class=\"variant small-section-header\">\
11301125
<a href=\"#{id}\" class=\"anchor field\"></a>\
11311126
<code>{f}:&nbsp;{t}</code>\
11321127
</span>",
11331128
id = id,
11341129
f = field.name.as_ref().unwrap(),
11351130
t = ty.print(cx)
11361131
);
1137-
document(w, cx, field, Some(variant), HeadingOffset::H4);
1132+
document(w, cx, field, Some(variant), HeadingOffset::H5);
1133+
write!(w, "</div>");
11381134
}
11391135
_ => unreachable!(),
11401136
}
11411137
}
1142-
w.write_str("</div></div>");
1138+
w.write_str("</div>");
11431139
}
1140+
1141+
document(w, cx, variant, Some(it), HeadingOffset::H4);
11441142
}
11451143
}
11461144
let def_id = it.def_id.expect_def_id();

‎src/librustdoc/html/static/css/rustdoc.css

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,25 +1102,28 @@ a.test-arrow:hover{
11021102
margin-right: 5px;
11031103
}
11041104

1105-
.sub-variant, .sub-variant > h3 {
1106-
margin-top: 0px !important;
1107-
padding-top: 1px;
1105+
h3.variant {
1106+
font-weight: 600;
1107+
font-size: 1.1em;
1108+
margin-bottom: 10px;
1109+
border-bottom: none;
11081110
}
11091111

1110-
#main .sub-variant > h3 {
1111-
font-size: 15px;
1112-
margin-left: 25px;
1113-
margin-bottom: 5px;
1112+
.sub-variant h4 {
1113+
font-size: 1em;
1114+
font-weight: 400;
1115+
border-bottom: none;
1116+
margin-top: 0;
1117+
margin-bottom: 0;
11141118
}
11151119

1116-
.sub-variant > div {
1117-
margin-left: 20px;
1118-
margin-bottom: 10px;
1120+
.sub-variant {
1121+
margin-left: 24px;
1122+
margin-bottom: 40px;
11191123
}
11201124

1121-
.sub-variant > div > span {
1122-
display: block;
1123-
position: relative;
1125+
.sub-variant > .sub-variant-field {
1126+
margin-left: 24px;
11241127
}
11251128

11261129
.toggle-label {

‎src/test/rustdoc-gui/headings.goml

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// This test check that headers (a) have the correct heading level, (b) are the right size,
1+
// This test checks that headers (a) have the correct heading level, (b) are the right size,
22
// and (c) have the correct underlining (or absence of underlining).
33
// The sizes may change as design changes, but try to make sure a lower header is never bigger than
44
// 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"})
6767
assert-css: ("h2#variants", {"font-size": "22.4px"})
6868
assert-css: ("h2#variants", {"border-bottom-width": "1px"})
6969

70-
assert-css: ("h3#none-prose-title", {"font-size": "20.8px"})
71-
assert-css: ("h3#none-prose-title", {"border-bottom-width": "0px"})
72-
assert-css: ("h4#none-prose-sub-heading", {"font-size": "16px"})
73-
assert-css: ("h4#none-prose-sub-heading", {"border-bottom-width": "0px"})
74-
75-
assert-css: ("h3#wrapped-prose-title", {"font-size": "20.8px"})
76-
assert-css: ("h3#wrapped-prose-title", {"border-bottom-width": "0px"})
77-
assert-css: ("h4#wrapped-prose-sub-heading", {"font-size": "16px"})
78-
assert-css: ("h4#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})
79-
80-
assert-css: ("h4#wrapped0-prose-title", {"font-size": "16px"})
81-
assert-css: ("h4#wrapped0-prose-title", {"border-bottom-width": "0px"})
82-
assert-css: ("h5#wrapped0-prose-sub-heading", {"font-size": "16px"})
83-
assert-css: ("h5#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})
84-
85-
assert-css: ("h4#structy-prose-title", {"font-size": "16px"})
86-
assert-css: ("h4#structy-prose-title", {"border-bottom-width": "0px"})
87-
assert-css: ("h5#structy-prose-sub-heading", {"font-size": "16px"})
88-
assert-css: ("h5#structy-prose-sub-heading", {"border-bottom-width": "0px"})
70+
assert-css: ("h4#none-prose-title", {"font-size": "16px"})
71+
assert-css: ("h4#none-prose-title", {"border-bottom-width": "0px"})
72+
assert-css: ("h5#none-prose-sub-heading", {"font-size": "16px"})
73+
assert-css: ("h5#none-prose-sub-heading", {"border-bottom-width": "0px"})
74+
75+
assert-css: ("h4#wrapped-prose-title", {"font-size": "16px"})
76+
assert-css: ("h4#wrapped-prose-title", {"border-bottom-width": "0px"})
77+
assert-css: ("h5#wrapped-prose-sub-heading", {"font-size": "16px"})
78+
assert-css: ("h5#wrapped-prose-sub-heading", {"border-bottom-width": "0px"})
79+
80+
assert-css: ("h5#wrapped0-prose-title", {"font-size": "16px"})
81+
assert-css: ("h5#wrapped0-prose-title", {"border-bottom-width": "0px"})
82+
assert-css: ("h6#wrapped0-prose-sub-heading", {"font-size": "15.2px"})
83+
assert-css: ("h6#wrapped0-prose-sub-heading", {"border-bottom-width": "0px"})
84+
85+
assert-css: ("h5#structy-prose-title", {"font-size": "16px"})
86+
assert-css: ("h5#structy-prose-title", {"border-bottom-width": "0px"})
87+
assert-css: ("h6#structy-prose-sub-heading", {"font-size": "15.2px"})
88+
assert-css: ("h6#structy-prose-sub-heading", {"border-bottom-width": "0px"})
8989

9090
assert-css: ("h2#implementations", {"font-size": "22.4px"})
9191
assert-css: ("h2#implementations", {"border-bottom-width": "1px"})
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// FIXME: if/when the output of the test harness can be tested on its own, this test should be
2+
// adapted to use that, and that normalize line can go away
3+
4+
// compile-flags:--test
5+
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
6+
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
7+
// failure-status: 101
8+
9+
/// <https://github.com/rust-lang/rust/issues/91014>
10+
///
11+
/// ```rust
12+
/// struct S {}; // unexpected semicolon after struct def
13+
///
14+
/// fn main() {
15+
/// assert_eq!(0, 1);
16+
/// }
17+
/// ```
18+
mod m {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
running 1 test
3+
test $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) ... FAILED
4+
5+
failures:
6+
7+
---- $DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11) stdout ----
8+
error: expected item, found `;`
9+
--> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12
10+
|
11+
LL | struct S {}; // unexpected semicolon after struct def
12+
| ^ help: remove this semicolon
13+
|
14+
= help: braced struct declarations are not followed by a semicolon
15+
16+
error: aborting due to previous error
17+
18+
Couldn't compile the test.
19+
20+
failures:
21+
$DIR/failed-doctest-extra-semicolon-on-item.rs - m (line 11)
22+
23+
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
24+

‎src/test/rustdoc/enum-headings.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![crate_name = "foo"]
2+
// @has foo/enum.Token.html
3+
/// A token!
4+
/// # First
5+
/// Some following text...
6+
// @has - '//h2[@id="first"]' "First"
7+
pub enum Token {
8+
/// A declaration!
9+
/// # Variant-First
10+
/// Some following text...
11+
// @has - '//h4[@id="variant-first"]' "Variant-First"
12+
Declaration {
13+
/// A version!
14+
/// # Variant-Field-First
15+
/// Some following text...
16+
// @has - '//h5[@id="variant-field-first"]' "Variant-Field-First"
17+
version: String,
18+
},
19+
/// A Zoople!
20+
/// # Variant-First
21+
Zoople(
22+
// @has - '//h5[@id="variant-tuple-field-first"]' "Variant-Tuple-Field-First"
23+
/// Zoople's first variant!
24+
/// # Variant-Tuple-Field-First
25+
/// Some following text...
26+
usize,
27+
),
28+
/// Unfinished business!
29+
/// # Non-Exhaustive-First
30+
/// Some following text...
31+
// @has - '//h4[@id="non-exhaustive-first"]' "Non-Exhaustive-First"
32+
#[non_exhaustive]
33+
Unfinished {
34+
/// This is x.
35+
/// # X-First
36+
/// Some following text...
37+
// @has - '//h5[@id="x-first"]' "X-First"
38+
x: usize,
39+
},
40+
}

‎src/test/rustdoc/tuple-struct-fields-doc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ pub struct Foo(
2020

2121
// @has foo/enum.Bar.html
2222
// @has - '//pre[@class="rust enum"]' 'BarVariant(String),'
23-
// @matches - '//*[@id="variant.BarVariant.fields"]/h3' '^Tuple Fields of BarVariant$'
23+
// @matches - '//*[@id="variant.BarVariant.fields"]/h4' '^Tuple Fields$'
2424
// @has - '//*[@id="variant.BarVariant.field.0"]' '0: String'
2525
// @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs'
26-
// @matches - '//*[@id="variant.FooVariant.fields"]/h3' '^Fields of FooVariant$'
26+
// @matches - '//*[@id="variant.FooVariant.fields"]/h4' '^Fields$'
2727
pub enum Bar {
2828
BarVariant(
2929
/// Hello docs

‎src/test/ui/consts/const-eval/simd/insert_extract.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

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

1214
extern "platform-intrinsic" {
1315
#[rustc_const_stable(feature = "foo", since = "1.3.37")]
@@ -25,6 +27,14 @@ fn main() {
2527
assert_eq!(X0, 42);
2628
assert_eq!(Y0, 42);
2729
}
30+
{
31+
const U: i8x1_arr = i8x1_arr([13]);
32+
const V: i8x1_arr = unsafe { simd_insert(U, 0_u32, 42_i8) };
33+
const X0: i8 = V.0[0];
34+
const Y0: i8 = unsafe { simd_extract(V, 0) };
35+
assert_eq!(X0, 42);
36+
assert_eq!(Y0, 42);
37+
}
2838
{
2939
const U: u16x2 = u16x2(13, 14);
3040
const V: u16x2 = unsafe { simd_insert(U, 1_u32, 42_u16) };
@@ -38,12 +48,12 @@ fn main() {
3848
assert_eq!(Y1, 42);
3949
}
4050
{
41-
const U: f32x4 = f32x4(13., 14., 15., 16.);
51+
const U: f32x4 = f32x4([13., 14., 15., 16.]);
4252
const V: f32x4 = unsafe { simd_insert(U, 1_u32, 42_f32) };
43-
const X0: f32 = V.0;
44-
const X1: f32 = V.1;
45-
const X2: f32 = V.2;
46-
const X3: f32 = V.3;
53+
const X0: f32 = V.0[0];
54+
const X1: f32 = V.0[1];
55+
const X2: f32 = V.0[2];
56+
const X3: f32 = V.0[3];
4757
const Y0: f32 = unsafe { simd_extract(V, 0) };
4858
const Y1: f32 = unsafe { simd_extract(V, 1) };
4959
const Y2: f32 = unsafe { simd_extract(V, 2) };

‎src/test/ui/lang-items/issue-87573.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Regression test for #87573, ensures that duplicate lang items or invalid generics
2+
// for lang items doesn't cause ICE.
3+
4+
#![feature(no_core, lang_items)]
5+
#![no_core]
6+
#![crate_type = "lib"]
7+
8+
pub static STATIC_BOOL: bool = true;
9+
10+
#[lang = "sized"]
11+
trait Sized {}
12+
13+
#[lang = "copy"]
14+
trait Copy {}
15+
16+
#[lang = "sync"]
17+
trait Sync {}
18+
impl Sync for bool {}
19+
20+
#[lang = "drop_in_place"]
21+
//~^ ERROR: `drop_in_place` language item must be applied to a function with at least 1 generic argument
22+
fn drop_fn() {
23+
while false {}
24+
}
25+
26+
#[lang = "start"]
27+
//~^ ERROR: `start` language item must be applied to a function with 1 generic argument
28+
fn start(){}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0718]: `drop_in_place` language item must be applied to a function with at least 1 generic argument
2+
--> $DIR/issue-87573.rs:20:1
3+
|
4+
LL | #[lang = "drop_in_place"]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
LL |
7+
LL | fn drop_fn() {
8+
| - this function has 0 generic arguments
9+
10+
error[E0718]: `start` language item must be applied to a function with 1 generic argument
11+
--> $DIR/issue-87573.rs:26:1
12+
|
13+
LL | #[lang = "start"]
14+
| ^^^^^^^^^^^^^^^^^
15+
LL |
16+
LL | fn start(){}
17+
| - this function has 0 generic arguments
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0718`.

0 commit comments

Comments
 (0)
Please sign in to comment.