Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5b04bbf

Browse files
committedAug 19, 2020
Auto merge of rust-lang#75692 - JohnTitor:rollup-8gr04ah, r=JohnTitor
Rollup of 9 pull requests Successful merges: - rust-lang#75038 (See also X-Link mem::{swap, take, replace}) - rust-lang#75049 (docs(marker/copy): provide example for `&T` being `Copy`) - rust-lang#75499 (Fix documentation error) - rust-lang#75554 (Fix clashing_extern_declarations stack overflow for recursive types.) - rust-lang#75646 (Move to intra doc links for keyword documentation) - rust-lang#75652 (Resolve true and false as booleans) - rust-lang#75658 (Don't emit "is not a logical operator" error outside of associative expressions) - rust-lang#75665 (Add doc examples coverage) - rust-lang#75685 (Switch to intra-doc links in /src/sys/unix/ext/*.rs) Failed merges: r? @ghost
2 parents c03c213 + 07ea340 commit 5b04bbf

32 files changed

+556
-449
lines changed
 

‎library/core/src/marker.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ pub trait StructuralEq {
291291
///
292292
/// ```
293293
/// # #[allow(dead_code)]
294+
/// #[derive(Copy, Clone)]
294295
/// struct Point {
295296
/// x: i32,
296297
/// y: i32,
@@ -315,6 +316,20 @@ pub trait StructuralEq {
315316
/// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy`
316317
/// ```
317318
///
319+
/// Shared references (`&T`) are also `Copy`, so a type can be `Copy`, even when it holds
320+
/// shared references of types `T` that are *not* `Copy`. Consider the following struct,
321+
/// which can implement `Copy`, because it only holds a *shared reference* to our non-`Copy`
322+
/// type `PointList` from above:
323+
///
324+
/// ```
325+
/// # #![allow(dead_code)]
326+
/// # struct PointList;
327+
/// #[derive(Copy, Clone)]
328+
/// struct PointListWrapper<'a> {
329+
/// point_list_ref: &'a PointList,
330+
/// }
331+
/// ```
332+
///
318333
/// ## When *can't* my type be `Copy`?
319334
///
320335
/// Some types can't be copied safely. For example, copying `&mut T` would create an aliased

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,9 @@ pub unsafe fn uninitialized<T>() -> T {
670670

671671
/// Swaps the values at two mutable locations, without deinitializing either one.
672672
///
673+
/// * If you want to swap with a default or dummy value, see [`take`].
674+
/// * If you want to swap with a passed value, returning the old value, see [`replace`].
675+
///
673676
/// # Examples
674677
///
675678
/// ```
@@ -683,6 +686,9 @@ pub unsafe fn uninitialized<T>() -> T {
683686
/// assert_eq!(42, x);
684687
/// assert_eq!(5, y);
685688
/// ```
689+
///
690+
/// [`replace`]: fn.replace.html
691+
/// [`take`]: fn.take.html
686692
#[inline]
687693
#[stable(feature = "rust1", since = "1.0.0")]
688694
pub fn swap<T>(x: &mut T, y: &mut T) {
@@ -695,6 +701,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
695701

696702
/// Replaces `dest` with the default value of `T`, returning the previous `dest` value.
697703
///
704+
/// * If you want to replace the values of two variables, see [`swap`].
705+
/// * If you want to replace with a passed value instead of the default value, see [`replace`].
706+
///
698707
/// # Examples
699708
///
700709
/// A simple example:
@@ -747,6 +756,8 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
747756
/// ```
748757
///
749758
/// [`Clone`]: ../../std/clone/trait.Clone.html
759+
/// [`replace`]: fn.replace.html
760+
/// [`swap`]: fn.swap.html
750761
#[inline]
751762
#[stable(feature = "mem_take", since = "1.40.0")]
752763
pub fn take<T: Default>(dest: &mut T) -> T {
@@ -757,6 +768,9 @@ pub fn take<T: Default>(dest: &mut T) -> T {
757768
///
758769
/// Neither value is dropped.
759770
///
771+
/// * If you want to replace the values of two variables, see [`swap`].
772+
/// * If you want to replace with a default value, see [`take`].
773+
///
760774
/// # Examples
761775
///
762776
/// A simple example:
@@ -810,6 +824,8 @@ pub fn take<T: Default>(dest: &mut T) -> T {
810824
/// ```
811825
///
812826
/// [`Clone`]: ../../std/clone/trait.Clone.html
827+
/// [`swap`]: fn.swap.html
828+
/// [`take`]: fn.take.html
813829
#[inline]
814830
#[stable(feature = "rust1", since = "1.0.0")]
815831
#[must_use = "if you don't need the old value, you can just assign the new value directly"]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2031,7 +2031,7 @@ mod traits {
20312031
/// # Panics
20322032
///
20332033
/// Panics if `begin` does not point to the starting byte offset of
2034-
/// a character (as defined by `is_char_boundary`), or if `begin >= len`.
2034+
/// a character (as defined by `is_char_boundary`), or if `begin > len`.
20352035
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
20362036
unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
20372037
type Output = str;

‎library/std/src/keyword_docs.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ mod as_keyword {}
9898
/// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions
9999
/// [Reference on "break and loop values"]:
100100
/// ../reference/expressions/loop-expr.html#break-and-loop-values
101-
///
102101
mod break_keyword {}
103102

104103
#[doc(keyword = "const")]
@@ -336,7 +335,6 @@ mod else_keyword {}
336335
/// For more information, take a look at the [Rust Book] or the [Reference]
337336
///
338337
/// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type
339-
/// [`Option`]: option/enum.Option.html
340338
/// [Rust Book]: ../book/ch06-01-defining-an-enum.html
341339
/// [Reference]: ../reference/items/enumerations.html
342340
mod enum_keyword {}
@@ -534,7 +532,6 @@ mod fn_keyword {}
534532
/// [`in`]: keyword.in.html
535533
/// [`impl`]: keyword.impl.html
536534
/// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds
537-
/// [`IntoIterator`]: iter/trait.IntoIterator.html
538535
/// [Rust book]:
539536
/// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
540537
/// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops
@@ -993,7 +990,6 @@ mod mod_keyword {}
993990
/// For more information on the `move` keyword, see the [closure]'s section
994991
/// of the Rust book or the [threads] section
995992
///
996-
/// [`Fn` trait]: ../std/ops/trait.Fn.html
997993
/// [closure]: ../book/ch13-01-closures.html
998994
/// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads
999995
mod move_keyword {}
@@ -1413,9 +1409,7 @@ mod self_upper_keyword {}
14131409
/// [`extern`]: keyword.extern.html
14141410
/// [`mut`]: keyword.mut.html
14151411
/// [`unsafe`]: keyword.unsafe.html
1416-
/// [`drop`]: mem/fn.drop.html
1417-
/// [`Sync`]: marker/trait.Sync.html
1418-
/// [`RefCell`]: cell/struct.RefCell.html
1412+
/// [`RefCell`]: cell::RefCell
14191413
/// [Reference]: ../reference/items/static-items.html
14201414
mod static_keyword {}
14211415

@@ -1522,7 +1516,7 @@ mod static_keyword {}
15221516
/// For more information on structs, take a look at the [Rust Book][book] or the
15231517
/// [Reference][reference].
15241518
///
1525-
/// [`PhantomData`]: marker/struct.PhantomData.html
1519+
/// [`PhantomData`]: marker::PhantomData
15261520
/// [book]: ../book/ch05-01-defining-structs.html
15271521
/// [reference]: ../reference/items/structs.html
15281522
mod struct_keyword {}
@@ -1733,8 +1727,6 @@ mod super_keyword {}
17331727
/// [`for`]: keyword.for.html
17341728
/// [`impl`]: keyword.impl.html
17351729
/// [`unsafe`]: keyword.unsafe.html
1736-
/// [`Send`]: marker/trait.Send.html
1737-
/// [`Sync`]: marker/trait.Sync.html
17381730
/// [Ref-Traits]: ../reference/items/traits.html
17391731
/// [Ref-Trait-Objects]: ../reference/types/trait-object.html
17401732
mod trait_keyword {}
@@ -1764,7 +1756,6 @@ mod trait_keyword {}
17641756
/// [`while`]: keyword.while.html
17651757
/// [`match`]: ../reference/expressions/match-expr.html#match-guards
17661758
/// [`false`]: keyword.false.html
1767-
/// [`bool`]: primitive.bool.html
17681759
mod true_keyword {}
17691760

17701761
#[doc(keyword = "type")]
@@ -1986,9 +1977,6 @@ mod type_keyword {}
19861977
/// [`static`]: keyword.static.html
19871978
/// [`union`]: keyword.union.html
19881979
/// [`impl`]: keyword.impl.html
1989-
/// [Send]: marker/trait.Send.html
1990-
/// [Sync]: marker/trait.Sync.html
1991-
/// [`Vec::set_len`]: vec/struct.Vec.html#method.set_len
19921980
/// [raw pointers]: ../reference/types/pointer.html
19931981
/// [memory safety]: ../book/ch19-01-unsafe-rust.html
19941982
/// [Rustnomicon]: ../nomicon/index.html
@@ -2178,7 +2166,7 @@ mod where_keyword {}
21782166
///
21792167
/// It is available for use in stable rust from version 1.39 onwards.
21802168
///
2181-
/// [`Future`]: ./future/trait.Future.html
2169+
/// [`Future`]: future::Future
21822170
/// [async book]: https://rust-lang.github.io/async-book/
21832171
mod async_keyword {}
21842172

@@ -2197,7 +2185,7 @@ mod async_keyword {}
21972185
///
21982186
/// It is available for use in stable rust from version 1.39 onwards.
21992187
///
2200-
/// [`Future`]: ./future/trait.Future.html
2188+
/// [`Future`]: future::Future
22012189
/// [async book]: https://rust-lang.github.io/async-book/
22022190
mod await_keyword {}
22032191

‎library/std/src/sys/unix/ext/fs.rs

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ use crate::sys;
99
use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
1010
use crate::sys_common::{AsInner, AsInnerMut, FromInner};
1111

12-
/// Unix-specific extensions to [`File`].
13-
///
14-
/// [`File`]: ../../../../std/fs/struct.File.html
12+
/// Unix-specific extensions to [`fs::File`].
1513
#[stable(feature = "file_offset", since = "1.15.0")]
1614
pub trait FileExt {
1715
/// Reads a number of bytes starting from a given offset.
@@ -55,19 +53,18 @@ pub trait FileExt {
5553
///
5654
/// The current file cursor is not affected by this function.
5755
///
58-
/// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`.
56+
/// Similar to [`io::Read::read_exact`] but uses [`read_at`] instead of `read`.
5957
///
60-
/// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact
61-
/// [`read_at`]: #tymethod.read_at
58+
/// [`read_at`]: FileExt::read_at
6259
///
6360
/// # Errors
6461
///
6562
/// If this function encounters an error of the kind
66-
/// [`ErrorKind::Interrupted`] then the error is ignored and the operation
63+
/// [`io::ErrorKind::Interrupted`] then the error is ignored and the operation
6764
/// will continue.
6865
///
6966
/// If this function encounters an "end of file" before completely filling
70-
/// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
67+
/// the buffer, it returns an error of the kind [`io::ErrorKind::UnexpectedEof`].
7168
/// The contents of `buf` are unspecified in this case.
7269
///
7370
/// If any other read error is encountered then this function immediately
@@ -77,9 +74,6 @@ pub trait FileExt {
7774
/// has read, but it will never read more than would be necessary to
7875
/// completely fill the buffer.
7976
///
80-
/// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
81-
/// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof
82-
///
8377
/// # Examples
8478
///
8579
/// ```no_run
@@ -161,19 +155,18 @@ pub trait FileExt {
161155
/// The current file cursor is not affected by this function.
162156
///
163157
/// This method will continuously call [`write_at`] until there is no more data
164-
/// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
158+
/// to be written or an error of non-[`io::ErrorKind::Interrupted`] kind is
165159
/// returned. This method will not return until the entire buffer has been
166160
/// successfully written or such an error occurs. The first error that is
167-
/// not of [`ErrorKind::Interrupted`] kind generated from this method will be
161+
/// not of [`io::ErrorKind::Interrupted`] kind generated from this method will be
168162
/// returned.
169163
///
170164
/// # Errors
171165
///
172166
/// This function will return the first error of
173-
/// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
167+
/// non-[`io::ErrorKind::Interrupted`] kind that [`write_at`] returns.
174168
///
175-
/// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
176-
/// [`write_at`]: #tymethod.write_at
169+
/// [`write_at`]: FileExt::write_at
177170
///
178171
/// # Examples
179172
///
@@ -223,8 +216,6 @@ impl FileExt for fs::File {
223216
}
224217

225218
/// Unix-specific extensions to [`fs::Permissions`].
226-
///
227-
/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html
228219
#[stable(feature = "fs_ext", since = "1.1.0")]
229220
pub trait PermissionsExt {
230221
/// Returns the underlying raw `st_mode` bits that contain the standard
@@ -302,8 +293,6 @@ impl PermissionsExt for Permissions {
302293
}
303294

304295
/// Unix-specific extensions to [`fs::OpenOptions`].
305-
///
306-
/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
307296
#[stable(feature = "fs_ext", since = "1.1.0")]
308297
pub trait OpenOptionsExt {
309298
/// Sets the mode bits that a new file will be created with.
@@ -372,8 +361,6 @@ impl OpenOptionsExt for OpenOptions {
372361
}
373362

374363
/// Unix-specific extensions to [`fs::Metadata`].
375-
///
376-
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
377364
#[stable(feature = "metadata_ext", since = "1.1.0")]
378365
pub trait MetadataExt {
379366
/// Returns the ID of the device containing the file.
@@ -535,7 +522,7 @@ pub trait MetadataExt {
535522
fn atime(&self) -> i64;
536523
/// Returns the last access time of the file, in nanoseconds since [`atime`].
537524
///
538-
/// [`atime`]: #tymethod.atime
525+
/// [`atime`]: MetadataExt::atime
539526
///
540527
/// # Examples
541528
///
@@ -571,7 +558,7 @@ pub trait MetadataExt {
571558
fn mtime(&self) -> i64;
572559
/// Returns the last modification time of the file, in nanoseconds since [`mtime`].
573560
///
574-
/// [`mtime`]: #tymethod.mtime
561+
/// [`mtime`]: MetadataExt::mtime
575562
///
576563
/// # Examples
577564
///
@@ -607,7 +594,7 @@ pub trait MetadataExt {
607594
fn ctime(&self) -> i64;
608595
/// Returns the last status change time of the file, in nanoseconds since [`ctime`].
609596
///
610-
/// [`ctime`]: #tymethod.ctime
597+
/// [`ctime`]: MetadataExt::ctime
611598
///
612599
/// # Examples
613600
///
@@ -714,12 +701,10 @@ impl MetadataExt for fs::Metadata {
714701
}
715702
}
716703

717-
/// Unix-specific extensions for [`FileType`].
704+
/// Unix-specific extensions for [`fs::FileType`].
718705
///
719706
/// Adds support for special Unix file types such as block/character devices,
720707
/// pipes, and sockets.
721-
///
722-
/// [`FileType`]: ../../../../std/fs/struct.FileType.html
723708
#[stable(feature = "file_type_ext", since = "1.5.0")]
724709
pub trait FileTypeExt {
725710
/// Returns `true` if this file type is a block device.
@@ -813,8 +798,6 @@ impl FileTypeExt for fs::FileType {
813798
}
814799

815800
/// Unix-specific extension methods for [`fs::DirEntry`].
816-
///
817-
/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
818801
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
819802
pub trait DirEntryExt {
820803
/// Returns the underlying `d_ino` field in the contained `dirent`
@@ -875,8 +858,6 @@ pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
875858
}
876859

877860
/// Unix-specific extensions to [`fs::DirBuilder`].
878-
///
879-
/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
880861
#[stable(feature = "dir_builder", since = "1.6.0")]
881862
pub trait DirBuilderExt {
882863
/// Sets the mode to create new directories with. This option defaults to

‎library/std/src/sys/unix/ext/net.rs

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,7 @@ impl UnixStream {
408408
/// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
409409
/// method.
410410
///
411-
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
412-
/// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
413-
/// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
414-
/// [`Duration`]: ../../../../std/time/struct.Duration.html
411+
/// [`read`]: io::Read::read
415412
///
416413
/// # Examples
417414
///
@@ -453,10 +450,7 @@ impl UnixStream {
453450
/// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
454451
/// passed to this method.
455452
///
456-
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
457-
/// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
458-
/// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
459-
/// [`Duration`]: ../../../../std/time/struct.Duration.html
453+
/// [`read`]: io::Read::read
460454
///
461455
/// # Examples
462456
///
@@ -581,8 +575,6 @@ impl UnixStream {
581575
/// specified portions to immediately return with an appropriate value
582576
/// (see the documentation of [`Shutdown`]).
583577
///
584-
/// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
585-
///
586578
/// # Examples
587579
///
588580
/// ```no_run
@@ -852,7 +844,7 @@ impl UnixListener {
852844
/// is established. When established, the corresponding [`UnixStream`] and
853845
/// the remote peer's address will be returned.
854846
///
855-
/// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
847+
/// [`UnixStream`]: crate::os::unix::net::UnixStream
856848
///
857849
/// # Examples
858850
///
@@ -937,8 +929,6 @@ impl UnixListener {
937929
/// Ok(())
938930
/// }
939931
/// ```
940-
///
941-
/// [`io::ErrorKind::WouldBlock`]: ../../../io/enum.ErrorKind.html#variant.WouldBlock
942932
#[stable(feature = "unix_socket", since = "1.10.0")]
943933
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
944934
self.0.set_nonblocking(nonblocking)
@@ -973,9 +963,6 @@ impl UnixListener {
973963
/// The iterator will never return [`None`] and will also not yield the
974964
/// peer's [`SocketAddr`] structure.
975965
///
976-
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
977-
/// [`SocketAddr`]: struct.SocketAddr.html
978-
///
979966
/// # Examples
980967
///
981968
/// ```no_run
@@ -1043,9 +1030,6 @@ impl<'a> IntoIterator for &'a UnixListener {
10431030
///
10441031
/// It will never return [`None`].
10451032
///
1046-
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1047-
/// [`UnixListener`]: struct.UnixListener.html
1048-
///
10491033
/// # Examples
10501034
///
10511035
/// ```no_run
@@ -1205,9 +1189,9 @@ impl UnixDatagram {
12051189
/// The [`send`] method may be used to send data to the specified address.
12061190
/// [`recv`] and [`recv_from`] will only receive data from that address.
12071191
///
1208-
/// [`send`]: #method.send
1209-
/// [`recv`]: #method.recv
1210-
/// [`recv_from`]: #method.recv_from
1192+
/// [`send`]: UnixDatagram::send
1193+
/// [`recv`]: UnixDatagram::recv
1194+
/// [`recv_from`]: UnixDatagram::recv_from
12111195
///
12121196
/// # Examples
12131197
///
@@ -1284,7 +1268,7 @@ impl UnixDatagram {
12841268
///
12851269
/// The [`connect`] method will connect the socket to a peer.
12861270
///
1287-
/// [`connect`]: #method.connect
1271+
/// [`connect`]: UnixDatagram::connect
12881272
///
12891273
/// # Examples
12901274
///
@@ -1432,11 +1416,8 @@ impl UnixDatagram {
14321416
/// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
14331417
/// is passed to this method.
14341418
///
1435-
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1436-
/// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
1437-
/// [`recv`]: #method.recv
1438-
/// [`recv_from`]: #method.recv_from
1439-
/// [`Duration`]: ../../../../std/time/struct.Duration.html
1419+
/// [`recv`]: UnixDatagram::recv
1420+
/// [`recv_from`]: UnixDatagram::recv_from
14401421
///
14411422
/// # Examples
14421423
///
@@ -1479,10 +1460,8 @@ impl UnixDatagram {
14791460
/// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
14801461
/// method.
14811462
///
1482-
/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1483-
/// [`send`]: #method.send
1484-
/// [`send_to`]: #method.send_to
1485-
/// [`Duration`]: ../../../../std/time/struct.Duration.html
1463+
/// [`send`]: UnixDatagram::send
1464+
/// [`send_to`]: UnixDatagram::send_to
14861465
///
14871466
/// # Examples
14881467
///
@@ -1605,8 +1584,6 @@ impl UnixDatagram {
16051584
/// specified portions to immediately return with an appropriate value
16061585
/// (see the documentation of [`Shutdown`]).
16071586
///
1608-
/// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
1609-
///
16101587
/// ```no_run
16111588
/// use std::os::unix::net::UnixDatagram;
16121589
/// use std::net::Shutdown;

‎library/std/src/sys/unix/ext/process.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ use crate::sys;
1010
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
1111

1212
/// Unix-specific extensions to the [`process::Command`] builder.
13-
///
14-
/// [`process::Command`]: ../../../../std/process/struct.Command.html
1513
#[stable(feature = "rust1", since = "1.0.0")]
1614
pub trait CommandExt {
1715
/// Sets the child process's user ID. This translates to a
@@ -65,7 +63,7 @@ pub trait CommandExt {
6563
/// This method is stable and usable, but it should be unsafe. To fix
6664
/// that, it got deprecated in favor of the unsafe [`pre_exec`].
6765
///
68-
/// [`pre_exec`]: #tymethod.pre_exec
66+
/// [`pre_exec`]: CommandExt::pre_exec
6967
#[stable(feature = "process_exec", since = "1.15.0")]
7068
#[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
7169
fn before_exec<F>(&mut self, f: F) -> &mut process::Command
@@ -94,8 +92,6 @@ pub trait CommandExt {
9492
/// a new child. Like spawn, however, the default behavior for the stdio
9593
/// descriptors will be to inherited from the current process.
9694
///
97-
/// [`process::exit`]: ../../../process/fn.exit.html
98-
///
9995
/// # Notes
10096
///
10197
/// The process may be in a "broken state" if this function returns in
@@ -151,8 +147,6 @@ impl CommandExt for process::Command {
151147
}
152148

153149
/// Unix-specific extensions to [`process::ExitStatus`].
154-
///
155-
/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html
156150
#[stable(feature = "rust1", since = "1.0.0")]
157151
pub trait ExitStatusExt {
158152
/// Creates a new `ExitStatus` from the raw underlying `i32` return value of

‎library/std/src/sys/unix/ext/thread.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ use crate::thread::JoinHandle;
1111
#[allow(deprecated)]
1212
pub type RawPthread = pthread_t;
1313

14-
/// Unix-specific extensions to [`thread::JoinHandle`].
15-
///
16-
/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html
14+
/// Unix-specific extensions to [`JoinHandle`].
1715
#[stable(feature = "thread_extensions", since = "1.9.0")]
1816
pub trait JoinHandleExt {
1917
/// Extracts the raw pthread_t without taking ownership

‎src/librustc_lint/builtin.rs

Lines changed: 132 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_ast::visit::{FnCtxt, FnKind};
2929
use rustc_ast::{self as ast, *};
3030
use rustc_ast_pretty::pprust::{self, expr_to_string};
3131
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
32+
use rustc_data_structures::stack::ensure_sufficient_stack;
3233
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
3334
use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType};
3435
use rustc_feature::{GateIssue, Stability};
@@ -2153,123 +2154,152 @@ impl ClashingExternDeclarations {
21532154
b: Ty<'tcx>,
21542155
ckind: CItemKind,
21552156
) -> bool {
2156-
debug!("structurally_same_type(cx, a = {:?}, b = {:?})", a, b);
2157-
let tcx = cx.tcx;
2158-
if a == b || rustc_middle::ty::TyS::same_type(a, b) {
2159-
// All nominally-same types are structurally same, too.
2160-
true
2161-
} else {
2162-
// Do a full, depth-first comparison between the two.
2163-
use rustc_middle::ty::TyKind::*;
2164-
let a_kind = &a.kind;
2165-
let b_kind = &b.kind;
2166-
2167-
let compare_layouts = |a, b| -> bool {
2168-
let a_layout = &cx.layout_of(a).unwrap().layout.abi;
2169-
let b_layout = &cx.layout_of(b).unwrap().layout.abi;
2170-
debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout);
2171-
a_layout == b_layout
2172-
};
2157+
fn structurally_same_type_impl<'tcx>(
2158+
seen_types: &mut FxHashSet<(Ty<'tcx>, Ty<'tcx>)>,
2159+
cx: &LateContext<'tcx>,
2160+
a: Ty<'tcx>,
2161+
b: Ty<'tcx>,
2162+
ckind: CItemKind,
2163+
) -> bool {
2164+
debug!("structurally_same_type_impl(cx, a = {:?}, b = {:?})", a, b);
2165+
if !seen_types.insert((a, b)) {
2166+
// We've encountered a cycle. There's no point going any further -- the types are
2167+
// structurally the same.
2168+
return true;
2169+
}
2170+
let tcx = cx.tcx;
2171+
if a == b || rustc_middle::ty::TyS::same_type(a, b) {
2172+
// All nominally-same types are structurally same, too.
2173+
true
2174+
} else {
2175+
// Do a full, depth-first comparison between the two.
2176+
use rustc_middle::ty::TyKind::*;
2177+
let a_kind = &a.kind;
2178+
let b_kind = &b.kind;
2179+
2180+
let compare_layouts = |a, b| -> bool {
2181+
let a_layout = &cx.layout_of(a).unwrap().layout.abi;
2182+
let b_layout = &cx.layout_of(b).unwrap().layout.abi;
2183+
debug!("{:?} == {:?} = {}", a_layout, b_layout, a_layout == b_layout);
2184+
a_layout == b_layout
2185+
};
2186+
2187+
#[allow(rustc::usage_of_ty_tykind)]
2188+
let is_primitive_or_pointer = |kind: &ty::TyKind<'_>| {
2189+
kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..))
2190+
};
21732191

2174-
#[allow(rustc::usage_of_ty_tykind)]
2175-
let is_primitive_or_pointer =
2176-
|kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..));
2177-
2178-
match (a_kind, b_kind) {
2179-
(Adt(_, a_substs), Adt(_, b_substs)) => {
2180-
let a = a.subst(cx.tcx, a_substs);
2181-
let b = b.subst(cx.tcx, b_substs);
2182-
debug!("Comparing {:?} and {:?}", a, b);
2183-
2184-
if let (Adt(a_def, ..), Adt(b_def, ..)) = (&a.kind, &b.kind) {
2185-
// Grab a flattened representation of all fields.
2186-
let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());
2187-
let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());
2188-
compare_layouts(a, b)
2192+
ensure_sufficient_stack(|| {
2193+
match (a_kind, b_kind) {
2194+
(Adt(a_def, a_substs), Adt(b_def, b_substs)) => {
2195+
let a = a.subst(cx.tcx, a_substs);
2196+
let b = b.subst(cx.tcx, b_substs);
2197+
debug!("Comparing {:?} and {:?}", a, b);
2198+
2199+
// Grab a flattened representation of all fields.
2200+
let a_fields = a_def.variants.iter().flat_map(|v| v.fields.iter());
2201+
let b_fields = b_def.variants.iter().flat_map(|v| v.fields.iter());
2202+
compare_layouts(a, b)
21892203
&& a_fields.eq_by(
21902204
b_fields,
21912205
|&ty::FieldDef { did: a_did, .. },
21922206
&ty::FieldDef { did: b_did, .. }| {
2193-
Self::structurally_same_type(
2207+
structurally_same_type_impl(
2208+
seen_types,
21942209
cx,
21952210
tcx.type_of(a_did),
21962211
tcx.type_of(b_did),
21972212
ckind,
21982213
)
21992214
},
22002215
)
2201-
} else {
2202-
unreachable!()
2203-
}
2204-
}
2205-
(Array(a_ty, a_const), Array(b_ty, b_const)) => {
2206-
// For arrays, we also check the constness of the type.
2207-
a_const.val == b_const.val
2208-
&& Self::structurally_same_type(cx, a_const.ty, b_const.ty, ckind)
2209-
&& Self::structurally_same_type(cx, a_ty, b_ty, ckind)
2210-
}
2211-
(Slice(a_ty), Slice(b_ty)) => Self::structurally_same_type(cx, a_ty, b_ty, ckind),
2212-
(RawPtr(a_tymut), RawPtr(b_tymut)) => {
2213-
a_tymut.mutbl == b_tymut.mutbl
2214-
&& Self::structurally_same_type(cx, &a_tymut.ty, &b_tymut.ty, ckind)
2215-
}
2216-
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
2217-
// For structural sameness, we don't need the region to be same.
2218-
a_mut == b_mut && Self::structurally_same_type(cx, a_ty, b_ty, ckind)
2219-
}
2220-
(FnDef(..), FnDef(..)) => {
2221-
let a_poly_sig = a.fn_sig(tcx);
2222-
let b_poly_sig = b.fn_sig(tcx);
2223-
2224-
// As we don't compare regions, skip_binder is fine.
2225-
let a_sig = a_poly_sig.skip_binder();
2226-
let b_sig = b_poly_sig.skip_binder();
2227-
2228-
(a_sig.abi, a_sig.unsafety, a_sig.c_variadic)
2229-
== (b_sig.abi, b_sig.unsafety, b_sig.c_variadic)
2230-
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
2231-
Self::structurally_same_type(cx, a, b, ckind)
2232-
})
2233-
&& Self::structurally_same_type(cx, a_sig.output(), b_sig.output(), ckind)
2234-
}
2235-
(Tuple(a_substs), Tuple(b_substs)) => {
2236-
a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| {
2237-
Self::structurally_same_type(cx, a_ty, b_ty, ckind)
2238-
})
2239-
}
2240-
// For these, it's not quite as easy to define structural-sameness quite so easily.
2241-
// For the purposes of this lint, take the conservative approach and mark them as
2242-
// not structurally same.
2243-
(Dynamic(..), Dynamic(..))
2244-
| (Error(..), Error(..))
2245-
| (Closure(..), Closure(..))
2246-
| (Generator(..), Generator(..))
2247-
| (GeneratorWitness(..), GeneratorWitness(..))
2248-
| (Projection(..), Projection(..))
2249-
| (Opaque(..), Opaque(..)) => false,
2250-
2251-
// These definitely should have been caught above.
2252-
(Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(),
2253-
2254-
// An Adt and a primitive type. This can be FFI-safe is the ADT is an enum with a
2255-
// non-null field.
2256-
(Adt(..), other_kind) | (other_kind, Adt(..))
2257-
if is_primitive_or_pointer(other_kind) =>
2258-
{
2259-
let (primitive, adt) =
2260-
if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) };
2261-
if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) {
2262-
ty == primitive
2263-
} else {
2264-
compare_layouts(a, b)
2216+
}
2217+
(Array(a_ty, a_const), Array(b_ty, b_const)) => {
2218+
// For arrays, we also check the constness of the type.
2219+
a_const.val == b_const.val
2220+
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2221+
}
2222+
(Slice(a_ty), Slice(b_ty)) => {
2223+
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2224+
}
2225+
(RawPtr(a_tymut), RawPtr(b_tymut)) => {
2226+
a_tymut.mutbl == b_tymut.mutbl
2227+
&& structurally_same_type_impl(
2228+
seen_types,
2229+
cx,
2230+
&a_tymut.ty,
2231+
&b_tymut.ty,
2232+
ckind,
2233+
)
2234+
}
2235+
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
2236+
// For structural sameness, we don't need the region to be same.
2237+
a_mut == b_mut
2238+
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2239+
}
2240+
(FnDef(..), FnDef(..)) => {
2241+
let a_poly_sig = a.fn_sig(tcx);
2242+
let b_poly_sig = b.fn_sig(tcx);
2243+
2244+
// As we don't compare regions, skip_binder is fine.
2245+
let a_sig = a_poly_sig.skip_binder();
2246+
let b_sig = b_poly_sig.skip_binder();
2247+
2248+
(a_sig.abi, a_sig.unsafety, a_sig.c_variadic)
2249+
== (b_sig.abi, b_sig.unsafety, b_sig.c_variadic)
2250+
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
2251+
structurally_same_type_impl(seen_types, cx, a, b, ckind)
2252+
})
2253+
&& structurally_same_type_impl(
2254+
seen_types,
2255+
cx,
2256+
a_sig.output(),
2257+
b_sig.output(),
2258+
ckind,
2259+
)
2260+
}
2261+
(Tuple(a_substs), Tuple(b_substs)) => {
2262+
a_substs.types().eq_by(b_substs.types(), |a_ty, b_ty| {
2263+
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
2264+
})
2265+
}
2266+
// For these, it's not quite as easy to define structural-sameness quite so easily.
2267+
// For the purposes of this lint, take the conservative approach and mark them as
2268+
// not structurally same.
2269+
(Dynamic(..), Dynamic(..))
2270+
| (Error(..), Error(..))
2271+
| (Closure(..), Closure(..))
2272+
| (Generator(..), Generator(..))
2273+
| (GeneratorWitness(..), GeneratorWitness(..))
2274+
| (Projection(..), Projection(..))
2275+
| (Opaque(..), Opaque(..)) => false,
2276+
2277+
// These definitely should have been caught above.
2278+
(Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(),
2279+
2280+
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null
2281+
// enum layout optimisation is being applied.
2282+
(Adt(..), other_kind) | (other_kind, Adt(..))
2283+
if is_primitive_or_pointer(other_kind) =>
2284+
{
2285+
let (primitive, adt) =
2286+
if is_primitive_or_pointer(&a.kind) { (a, b) } else { (b, a) };
2287+
if let Some(ty) = crate::types::repr_nullable_ptr(cx, adt, ckind) {
2288+
ty == primitive
2289+
} else {
2290+
compare_layouts(a, b)
2291+
}
2292+
}
2293+
// Otherwise, just compare the layouts. This may fail to lint for some
2294+
// incompatible types, but at the very least, will stop reads into
2295+
// uninitialised memory.
2296+
_ => compare_layouts(a, b),
22652297
}
2266-
}
2267-
// Otherwise, just compare the layouts. This may fail to lint for some
2268-
// incompatible types, but at the very least, will stop reads into
2269-
// uninitialised memory.
2270-
_ => compare_layouts(a, b),
2298+
})
22712299
}
22722300
}
2301+
let mut seen_types = FxHashSet::default();
2302+
structurally_same_type_impl(&mut seen_types, cx, a, b, ckind)
22732303
}
22742304
}
22752305

‎src/librustc_parse/parser/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ impl<'a> Parser<'a> {
308308
}
309309

310310
fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool {
311-
match (self.expr_is_complete(lhs), self.check_assoc_op().map(|op| op.node)) {
311+
match (self.expr_is_complete(lhs), AssocOp::from_token(&self.token)) {
312312
// Semi-statement forms are odd:
313313
// See https://github.com/rust-lang/rust/issues/29071
314314
(true, None) => false,

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,12 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
200200
match *clean_type {
201201
clean::ResolvedPath { ref path, .. } => {
202202
let segments = &path.segments;
203-
let path_segment = segments.iter().last().unwrap_or_else(|| panic!(
203+
let path_segment = segments.iter().last().unwrap_or_else(|| {
204+
panic!(
204205
"get_index_type_name(clean_type: {:?}, accept_generic: {:?}) had length zero path",
205206
clean_type, accept_generic
206-
));
207+
)
208+
});
207209
Some(path_segment.name.clone())
208210
}
209211
clean::Generic(ref s) if accept_generic => Some(s.clone()),

‎src/librustdoc/passes/calculate_doc_coverage.rs

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use crate::clean;
22
use crate::config::OutputFormat;
33
use crate::core::DocContext;
44
use crate::fold::{self, DocFolder};
5+
use crate::html::markdown::{find_testable_code, ErrorCodes};
6+
use crate::passes::doc_test_lints::Tests;
57
use crate::passes::Pass;
6-
78
use rustc_span::symbol::sym;
89
use rustc_span::FileName;
910
use serde::Serialize;
@@ -30,15 +31,19 @@ fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::C
3031
struct ItemCount {
3132
total: u64,
3233
with_docs: u64,
34+
with_examples: u64,
3335
}
3436

3537
impl ItemCount {
36-
fn count_item(&mut self, has_docs: bool) {
38+
fn count_item(&mut self, has_docs: bool, has_doc_example: bool) {
3739
self.total += 1;
3840

3941
if has_docs {
4042
self.with_docs += 1;
4143
}
44+
if has_doc_example {
45+
self.with_examples += 1;
46+
}
4247
}
4348

4449
fn percentage(&self) -> Option<f64> {
@@ -48,20 +53,33 @@ impl ItemCount {
4853
None
4954
}
5055
}
56+
57+
fn examples_percentage(&self) -> Option<f64> {
58+
if self.total > 0 {
59+
Some((self.with_examples as f64 * 100.0) / self.total as f64)
60+
} else {
61+
None
62+
}
63+
}
5164
}
5265

5366
impl ops::Sub for ItemCount {
5467
type Output = Self;
5568

5669
fn sub(self, rhs: Self) -> Self {
57-
ItemCount { total: self.total - rhs.total, with_docs: self.with_docs - rhs.with_docs }
70+
ItemCount {
71+
total: self.total - rhs.total,
72+
with_docs: self.with_docs - rhs.with_docs,
73+
with_examples: self.with_examples - rhs.with_examples,
74+
}
5875
}
5976
}
6077

6178
impl ops::AddAssign for ItemCount {
6279
fn add_assign(&mut self, rhs: Self) {
6380
self.total += rhs.total;
6481
self.with_docs += rhs.with_docs;
82+
self.with_examples += rhs.with_examples;
6583
}
6684
}
6785

@@ -103,40 +121,73 @@ impl CoverageCalculator {
103121
let mut total = ItemCount::default();
104122

105123
fn print_table_line() {
106-
println!("+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
124+
println!("+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
107125
}
108126

109-
fn print_table_record(name: &str, count: ItemCount, percentage: f64) {
127+
fn print_table_record(
128+
name: &str,
129+
count: ItemCount,
130+
percentage: f64,
131+
examples_percentage: f64,
132+
) {
110133
println!(
111-
"| {:<35} | {:>10} | {:>10} | {:>9.1}% |",
112-
name, count.with_docs, count.total, percentage
134+
"| {:<35} | {:>10} | {:>10} | {:>9.1}% | {:>10} | {:>9.1}% |",
135+
name,
136+
count.with_docs,
137+
count.total,
138+
percentage,
139+
count.with_examples,
140+
examples_percentage,
113141
);
114142
}
115143

116144
print_table_line();
117145
println!(
118-
"| {:<35} | {:>10} | {:>10} | {:>10} |",
119-
"File", "Documented", "Total", "Percentage"
146+
"| {:<35} | {:>10} | {:>10} | {:>10} | {:>10} | {:>10} |",
147+
"File", "Documented", "Total", "Percentage", "Examples", "Percentage",
120148
);
121149
print_table_line();
122150

123151
for (file, &count) in &self.items {
124-
if let Some(percentage) = count.percentage() {
125-
print_table_record(&limit_filename_len(file.to_string()), count, percentage);
152+
if let (Some(percentage), Some(examples_percentage)) =
153+
(count.percentage(), count.examples_percentage())
154+
{
155+
print_table_record(
156+
&limit_filename_len(file.to_string()),
157+
count,
158+
percentage,
159+
examples_percentage,
160+
);
126161

127162
total += count;
128163
}
129164
}
130165

131166
print_table_line();
132-
print_table_record("Total", total, total.percentage().unwrap_or(0.0));
167+
print_table_record(
168+
"Total",
169+
total,
170+
total.percentage().unwrap_or(0.0),
171+
total.examples_percentage().unwrap_or(0.0),
172+
);
133173
print_table_line();
134174
}
135175
}
136176

137177
impl fold::DocFolder for CoverageCalculator {
138178
fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
139179
let has_docs = !i.attrs.doc_strings.is_empty();
180+
let mut tests = Tests { found_tests: 0 };
181+
182+
find_testable_code(
183+
&i.attrs.doc_strings.iter().map(|d| d.as_str()).collect::<Vec<_>>().join("\n"),
184+
&mut tests,
185+
ErrorCodes::No,
186+
false,
187+
None,
188+
);
189+
190+
let has_doc_example = tests.found_tests != 0;
140191

141192
match i.inner {
142193
_ if !i.def_id.is_local() => {
@@ -187,7 +238,10 @@ impl fold::DocFolder for CoverageCalculator {
187238
}
188239
_ => {
189240
debug!("counting {:?} {:?} in {}", i.type_(), i.name, i.source.filename);
190-
self.items.entry(i.source.filename.clone()).or_default().count_item(has_docs);
241+
self.items
242+
.entry(i.source.filename.clone())
243+
.or_default()
244+
.count_item(has_docs, has_doc_example);
191245
}
192246
}
193247

‎src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
222222
disambiguator,
223223
None | Some(Disambiguator::Namespace(Namespace::TypeNS))
224224
) {
225-
if let Some(prim) = is_primitive(path_str, ns) {
225+
if let Some((path, prim)) = is_primitive(path_str, ns) {
226226
if extra_fragment.is_some() {
227227
return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
228228
}
229-
return Ok((prim, Some(path_str.to_owned())));
229+
return Ok((prim, Some(path.to_owned())));
230230
}
231231
}
232232
return Ok((res, extra_fragment.clone()));
@@ -239,11 +239,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
239239
if value != (ns == ValueNS) {
240240
return Err(ErrorKind::ResolutionFailure);
241241
}
242-
} else if let Some(prim) = is_primitive(path_str, ns) {
242+
} else if let Some((path, prim)) = is_primitive(path_str, ns) {
243243
if extra_fragment.is_some() {
244244
return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
245245
}
246-
return Ok((prim, Some(path_str.to_owned())));
246+
return Ok((prim, Some(path.to_owned())));
247247
} else {
248248
// If resolution failed, it may still be a method
249249
// because methods are not handled by the resolver
@@ -269,7 +269,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
269269
})
270270
.ok_or(ErrorKind::ResolutionFailure)?;
271271

272-
if let Some(prim) = is_primitive(&path, TypeNS) {
272+
if let Some((path, prim)) = is_primitive(&path, TypeNS) {
273273
let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?;
274274
return cx
275275
.tcx
@@ -1220,11 +1220,22 @@ const PRIMITIVES: &[(&str, Res)] = &[
12201220
("f64", Res::PrimTy(hir::PrimTy::Float(rustc_ast::FloatTy::F64))),
12211221
("str", Res::PrimTy(hir::PrimTy::Str)),
12221222
("bool", Res::PrimTy(hir::PrimTy::Bool)),
1223+
("true", Res::PrimTy(hir::PrimTy::Bool)),
1224+
("false", Res::PrimTy(hir::PrimTy::Bool)),
12231225
("char", Res::PrimTy(hir::PrimTy::Char)),
12241226
];
12251227

1226-
fn is_primitive(path_str: &str, ns: Namespace) -> Option<Res> {
1227-
if ns == TypeNS { PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1) } else { None }
1228+
fn is_primitive(path_str: &str, ns: Namespace) -> Option<(&'static str, Res)> {
1229+
if ns == TypeNS {
1230+
PRIMITIVES
1231+
.iter()
1232+
.filter(|x| x.0 == path_str)
1233+
.copied()
1234+
.map(|x| if x.0 == "true" || x.0 == "false" { ("bool", x.1) } else { x })
1235+
.next()
1236+
} else {
1237+
None
1238+
}
12281239
}
12291240

12301241
fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option<DefId> {

‎src/librustdoc/passes/doc_test_lints.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ impl<'a, 'tcx> DocFolder for PrivateItemDocTestLinter<'a, 'tcx> {
4343
}
4444
}
4545

46+
pub(crate) struct Tests {
47+
pub(crate) found_tests: usize,
48+
}
49+
50+
impl Tests {
51+
pub(crate) fn new() -> Tests {
52+
Tests { found_tests: 0 }
53+
}
54+
}
55+
56+
impl crate::test::Tester for Tests {
57+
fn add_test(&mut self, _: String, _: LangString, _: usize) {
58+
self.found_tests += 1;
59+
}
60+
}
61+
4662
pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
4763
let hir_id = match cx.as_local_hir_id(item.def_id) {
4864
Some(hir_id) => hir_id,
@@ -52,17 +68,7 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
5268
}
5369
};
5470

55-
struct Tests {
56-
found_tests: usize,
57-
}
58-
59-
impl crate::test::Tester for Tests {
60-
fn add_test(&mut self, _: String, _: LangString, _: usize) {
61-
self.found_tests += 1;
62-
}
63-
}
64-
65-
let mut tests = Tests { found_tests: 0 };
71+
let mut tests = Tests::new();
6672

6773
find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None);
6874

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...est/rustdoc-ui/coverage/basic.rs | 7 | 14 | 50.0% |
5-
+-------------------------------------+------------+------------+------------+
6-
| Total | 7 | 14 | 50.0% |
7-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...est/rustdoc-ui/coverage/basic.rs | 7 | 14 | 50.0% | 0 | 0.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 7 | 14 | 50.0% | 0 | 0.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// compile-flags:-Z unstable-options --show-coverage
2+
// check-pass
3+
4+
//! This test ensure that only rust code examples are counted.
5+
6+
/// Doc
7+
///
8+
/// ```
9+
/// let x = 2;
10+
/// ```
11+
pub struct Foo;
12+
13+
/// Doc
14+
///
15+
/// ```text
16+
/// yolo
17+
/// ```
18+
pub trait Bar {}
19+
20+
/// Doc
21+
///
22+
/// ```ignore (just for the sake of this test)
23+
/// let x = 2;
24+
/// ```
25+
pub fn foo<T: Bar, D: ::std::fmt::Debug>(a: Foo, b: u32, c: T, d: D) -> u32 {
26+
0
27+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...tdoc-ui/coverage/doc-examples.rs | 4 | 4 | 100.0% | 2 | 50.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 4 | 4 | 100.0% | 2 | 50.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...est/rustdoc-ui/coverage/empty.rs | 0 | 1 | 0.0% |
5-
+-------------------------------------+------------+------------+------------+
6-
| Total | 0 | 1 | 0.0% |
7-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...est/rustdoc-ui/coverage/empty.rs | 0 | 1 | 0.0% | 0 | 0.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 0 | 1 | 0.0% | 0 | 0.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...est/rustdoc-ui/coverage/enums.rs | 6 | 8 | 75.0% |
5-
+-------------------------------------+------------+------------+------------+
6-
| Total | 6 | 8 | 75.0% |
7-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...est/rustdoc-ui/coverage/enums.rs | 6 | 8 | 75.0% | 0 | 0.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 6 | 8 | 75.0% | 0 | 0.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...st/rustdoc-ui/coverage/exotic.rs | 1 | 1 | 100.0% |
5-
| <anon> | 2 | 2 | 100.0% |
6-
+-------------------------------------+------------+------------+------------+
7-
| Total | 3 | 3 | 100.0% |
8-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...st/rustdoc-ui/coverage/exotic.rs | 1 | 1 | 100.0% | 0 | 0.0% |
5+
| <anon> | 2 | 2 | 100.0% | 0 | 0.0% |
6+
+-------------------------------------+------------+------------+------------+------------+------------+
7+
| Total | 3 | 3 | 100.0% | 0 | 0.0% |
8+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"$DIR/json.rs":{"total":13,"with_docs":7}}
1+
{"$DIR/json.rs":{"total":13,"with_docs":7,"with_examples":0}}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...t/rustdoc-ui/coverage/private.rs | 4 | 7 | 57.1% |
5-
+-------------------------------------+------------+------------+------------+
6-
| Total | 4 | 7 | 57.1% |
7-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...t/rustdoc-ui/coverage/private.rs | 4 | 7 | 57.1% | 0 | 0.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 4 | 7 | 57.1% | 0 | 0.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...oc-ui/coverage/statics-consts.rs | 6 | 7 | 85.7% |
5-
+-------------------------------------+------------+------------+------------+
6-
| Total | 6 | 7 | 85.7% |
7-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...oc-ui/coverage/statics-consts.rs | 6 | 7 | 85.7% | 0 | 0.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 6 | 7 | 85.7% | 0 | 0.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
+-------------------------------------+------------+------------+------------+
2-
| File | Documented | Total | Percentage |
3-
+-------------------------------------+------------+------------+------------+
4-
| ...st/rustdoc-ui/coverage/traits.rs | 6 | 7 | 85.7% |
5-
+-------------------------------------+------------+------------+------------+
6-
| Total | 6 | 7 | 85.7% |
7-
+-------------------------------------+------------+------------+------------+
1+
+-------------------------------------+------------+------------+------------+------------+------------+
2+
| File | Documented | Total | Percentage | Examples | Percentage |
3+
+-------------------------------------+------------+------------+------------+------------+------------+
4+
| ...st/rustdoc-ui/coverage/traits.rs | 6 | 7 | 85.7% | 0 | 0.0% |
5+
+-------------------------------------+------------+------------+------------+------------+------------+
6+
| Total | 6 | 7 | 85.7% | 0 | 0.0% |
7+
+-------------------------------------+------------+------------+------------+------------+------------+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![deny(broken_intra_doc_links)]
2+
#![crate_name = "foo"]
3+
4+
// ignore-tidy-linelength
5+
6+
// @has foo/index.html
7+
// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'true'
8+
// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.bool.html"]' 'false'
9+
10+
//! A `bool` is either [`true`] or [`false`].

‎src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ fn test_and() {
55
let b = false;
66

77
let _ = a and b; //~ ERROR `and` is not a logical operator
8-
//~| ERROR `and` is not a logical operator
98

109
if a and b { //~ ERROR `and` is not a logical operator
11-
//~| ERROR `and` is not a logical operator
1210
println!("both");
1311
}
1412

@@ -20,10 +18,8 @@ fn test_or() {
2018
let b = false;
2119

2220
let _ = a or b; //~ ERROR `or` is not a logical operator
23-
//~| ERROR `or` is not a logical operator
2421

2522
if a or b { //~ ERROR `or` is not a logical operator
26-
//~| ERROR `or` is not a logical operator
2723
println!("both");
2824
}
2925
}
@@ -32,7 +28,6 @@ fn test_and_par() {
3228
let a = true;
3329
let b = false;
3430
if (a and b) { //~ ERROR `and` is not a logical operator
35-
//~| ERROR `and` is not a logical operator
3631
println!("both");
3732
}
3833
}
@@ -41,7 +36,6 @@ fn test_or_par() {
4136
let a = true;
4237
let b = false;
4338
if (a or b) { //~ ERROR `or` is not a logical operator
44-
//~| ERROR `or` is not a logical operator
4539
println!("both");
4640
}
4741
}
@@ -50,7 +44,6 @@ fn test_while_and() {
5044
let a = true;
5145
let b = false;
5246
while a and b { //~ ERROR `and` is not a logical operator
53-
//~| ERROR `and` is not a logical operator
5447
println!("both");
5548
}
5649
}
@@ -59,7 +52,6 @@ fn test_while_or() {
5952
let a = true;
6053
let b = false;
6154
while a or b { //~ ERROR `or` is not a logical operator
62-
//~| ERROR `or` is not a logical operator
6355
println!("both");
6456
}
6557
}

‎src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr

Lines changed: 9 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,133 +7,69 @@ LL | let _ = a and b;
77
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
88

99
error: `and` is not a logical operator
10-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15
11-
|
12-
LL | let _ = a and b;
13-
| ^^^ help: use `&&` to perform logical conjunction
14-
|
15-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
16-
17-
error: `and` is not a logical operator
18-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10
19-
|
20-
LL | if a and b {
21-
| ^^^ help: use `&&` to perform logical conjunction
22-
|
23-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
24-
25-
error: `and` is not a logical operator
26-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10
10+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10
2711
|
2812
LL | if a and b {
2913
| ^^^ help: use `&&` to perform logical conjunction
3014
|
3115
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
3216

3317
error: `or` is not a logical operator
34-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15
18+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15
3519
|
3620
LL | let _ = a or b;
3721
| ^^ help: use `||` to perform logical disjunction
3822
|
3923
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
4024

4125
error: `or` is not a logical operator
42-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15
43-
|
44-
LL | let _ = a or b;
45-
| ^^ help: use `||` to perform logical disjunction
46-
|
47-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
48-
49-
error: `or` is not a logical operator
50-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10
51-
|
52-
LL | if a or b {
53-
| ^^ help: use `||` to perform logical disjunction
54-
|
55-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
56-
57-
error: `or` is not a logical operator
58-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10
26+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10
5927
|
6028
LL | if a or b {
6129
| ^^ help: use `||` to perform logical disjunction
6230
|
6331
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
6432

6533
error: `and` is not a logical operator
66-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11
34+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11
6735
|
6836
LL | if (a and b) {
6937
| ^^^ help: use `&&` to perform logical conjunction
7038
|
7139
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
7240

73-
error: `and` is not a logical operator
74-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11
75-
|
76-
LL | if (a and b) {
77-
| ^^^ help: use `&&` to perform logical conjunction
78-
|
79-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
80-
81-
error: `or` is not a logical operator
82-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11
83-
|
84-
LL | if (a or b) {
85-
| ^^ help: use `||` to perform logical disjunction
86-
|
87-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
88-
8941
error: `or` is not a logical operator
90-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11
42+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11
9143
|
9244
LL | if (a or b) {
9345
| ^^ help: use `||` to perform logical disjunction
9446
|
9547
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
9648

9749
error: `and` is not a logical operator
98-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13
50+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13
9951
|
10052
LL | while a and b {
10153
| ^^^ help: use `&&` to perform logical conjunction
10254
|
10355
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
10456

105-
error: `and` is not a logical operator
106-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13
107-
|
108-
LL | while a and b {
109-
| ^^^ help: use `&&` to perform logical conjunction
110-
|
111-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
112-
113-
error: `or` is not a logical operator
114-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13
115-
|
116-
LL | while a or b {
117-
| ^^ help: use `||` to perform logical disjunction
118-
|
119-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
120-
12157
error: `or` is not a logical operator
122-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13
58+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13
12359
|
12460
LL | while a or b {
12561
| ^^ help: use `||` to perform logical disjunction
12662
|
12763
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
12864

12965
error[E0308]: mismatched types
130-
--> $DIR/issue-54109-and_instead_of_ampersands.rs:15:33
66+
--> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33
13167
|
13268
LL | let _recovery_witness: () = 0;
13369
| -- ^ expected `()`, found integer
13470
| |
13571
| expected due to this
13672

137-
error: aborting due to 17 previous errors
73+
error: aborting due to 9 previous errors
13874

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

‎src/test/ui/did_you_mean/issue-54109-without-witness.fixed

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ fn test_and() {
1111
let b = false;
1212

1313
let _ = a && b; //~ ERROR `and` is not a logical operator
14-
//~| ERROR `and` is not a logical operator
1514

1615
if a && b { //~ ERROR `and` is not a logical operator
17-
//~| ERROR `and` is not a logical operator
1816
println!("both");
1917
}
2018
}
@@ -24,10 +22,8 @@ fn test_or() {
2422
let b = false;
2523

2624
let _ = a || b; //~ ERROR `or` is not a logical operator
27-
//~| ERROR `or` is not a logical operator
2825

2926
if a || b { //~ ERROR `or` is not a logical operator
30-
//~| ERROR `or` is not a logical operator
3127
println!("both");
3228
}
3329
}
@@ -36,7 +32,6 @@ fn test_and_par() {
3632
let a = true;
3733
let b = false;
3834
if (a && b) { //~ ERROR `and` is not a logical operator
39-
//~| ERROR `and` is not a logical operator
4035
println!("both");
4136
}
4237
}
@@ -45,7 +40,6 @@ fn test_or_par() {
4540
let a = true;
4641
let b = false;
4742
if (a || b) { //~ ERROR `or` is not a logical operator
48-
//~| ERROR `or` is not a logical operator
4943
println!("both");
5044
}
5145
}
@@ -54,7 +48,6 @@ fn test_while_and() {
5448
let a = true;
5549
let b = false;
5650
while a && b { //~ ERROR `and` is not a logical operator
57-
//~| ERROR `and` is not a logical operator
5851
println!("both");
5952
}
6053
}
@@ -63,7 +56,6 @@ fn test_while_or() {
6356
let a = true;
6457
let b = false;
6558
while a || b { //~ ERROR `or` is not a logical operator
66-
//~| ERROR `or` is not a logical operator
6759
println!("both");
6860
}
6961
}

‎src/test/ui/did_you_mean/issue-54109-without-witness.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ fn test_and() {
1111
let b = false;
1212

1313
let _ = a and b; //~ ERROR `and` is not a logical operator
14-
//~| ERROR `and` is not a logical operator
1514

1615
if a and b { //~ ERROR `and` is not a logical operator
17-
//~| ERROR `and` is not a logical operator
1816
println!("both");
1917
}
2018
}
@@ -24,10 +22,8 @@ fn test_or() {
2422
let b = false;
2523

2624
let _ = a or b; //~ ERROR `or` is not a logical operator
27-
//~| ERROR `or` is not a logical operator
2825

2926
if a or b { //~ ERROR `or` is not a logical operator
30-
//~| ERROR `or` is not a logical operator
3127
println!("both");
3228
}
3329
}
@@ -36,7 +32,6 @@ fn test_and_par() {
3632
let a = true;
3733
let b = false;
3834
if (a and b) { //~ ERROR `and` is not a logical operator
39-
//~| ERROR `and` is not a logical operator
4035
println!("both");
4136
}
4237
}
@@ -45,7 +40,6 @@ fn test_or_par() {
4540
let a = true;
4641
let b = false;
4742
if (a or b) { //~ ERROR `or` is not a logical operator
48-
//~| ERROR `or` is not a logical operator
4943
println!("both");
5044
}
5145
}
@@ -54,7 +48,6 @@ fn test_while_and() {
5448
let a = true;
5549
let b = false;
5650
while a and b { //~ ERROR `and` is not a logical operator
57-
//~| ERROR `and` is not a logical operator
5851
println!("both");
5952
}
6053
}
@@ -63,7 +56,6 @@ fn test_while_or() {
6356
let a = true;
6457
let b = false;
6558
while a or b { //~ ERROR `or` is not a logical operator
66-
//~| ERROR `or` is not a logical operator
6759
println!("both");
6860
}
6961
}

‎src/test/ui/did_you_mean/issue-54109-without-witness.stderr

Lines changed: 8 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,124 +7,60 @@ LL | let _ = a and b;
77
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
88

99
error: `and` is not a logical operator
10-
--> $DIR/issue-54109-without-witness.rs:13:15
11-
|
12-
LL | let _ = a and b;
13-
| ^^^ help: use `&&` to perform logical conjunction
14-
|
15-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
16-
17-
error: `and` is not a logical operator
18-
--> $DIR/issue-54109-without-witness.rs:16:10
19-
|
20-
LL | if a and b {
21-
| ^^^ help: use `&&` to perform logical conjunction
22-
|
23-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
24-
25-
error: `and` is not a logical operator
26-
--> $DIR/issue-54109-without-witness.rs:16:10
10+
--> $DIR/issue-54109-without-witness.rs:15:10
2711
|
2812
LL | if a and b {
2913
| ^^^ help: use `&&` to perform logical conjunction
3014
|
3115
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
3216

3317
error: `or` is not a logical operator
34-
--> $DIR/issue-54109-without-witness.rs:26:15
18+
--> $DIR/issue-54109-without-witness.rs:24:15
3519
|
3620
LL | let _ = a or b;
3721
| ^^ help: use `||` to perform logical disjunction
3822
|
3923
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
4024

4125
error: `or` is not a logical operator
42-
--> $DIR/issue-54109-without-witness.rs:26:15
43-
|
44-
LL | let _ = a or b;
45-
| ^^ help: use `||` to perform logical disjunction
46-
|
47-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
48-
49-
error: `or` is not a logical operator
50-
--> $DIR/issue-54109-without-witness.rs:29:10
51-
|
52-
LL | if a or b {
53-
| ^^ help: use `||` to perform logical disjunction
54-
|
55-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
56-
57-
error: `or` is not a logical operator
58-
--> $DIR/issue-54109-without-witness.rs:29:10
26+
--> $DIR/issue-54109-without-witness.rs:26:10
5927
|
6028
LL | if a or b {
6129
| ^^ help: use `||` to perform logical disjunction
6230
|
6331
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
6432

6533
error: `and` is not a logical operator
66-
--> $DIR/issue-54109-without-witness.rs:38:11
34+
--> $DIR/issue-54109-without-witness.rs:34:11
6735
|
6836
LL | if (a and b) {
6937
| ^^^ help: use `&&` to perform logical conjunction
7038
|
7139
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
7240

73-
error: `and` is not a logical operator
74-
--> $DIR/issue-54109-without-witness.rs:38:11
75-
|
76-
LL | if (a and b) {
77-
| ^^^ help: use `&&` to perform logical conjunction
78-
|
79-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
80-
81-
error: `or` is not a logical operator
82-
--> $DIR/issue-54109-without-witness.rs:47:11
83-
|
84-
LL | if (a or b) {
85-
| ^^ help: use `||` to perform logical disjunction
86-
|
87-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
88-
8941
error: `or` is not a logical operator
90-
--> $DIR/issue-54109-without-witness.rs:47:11
42+
--> $DIR/issue-54109-without-witness.rs:42:11
9143
|
9244
LL | if (a or b) {
9345
| ^^ help: use `||` to perform logical disjunction
9446
|
9547
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
9648

9749
error: `and` is not a logical operator
98-
--> $DIR/issue-54109-without-witness.rs:56:13
50+
--> $DIR/issue-54109-without-witness.rs:50:13
9951
|
10052
LL | while a and b {
10153
| ^^^ help: use `&&` to perform logical conjunction
10254
|
10355
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
10456

105-
error: `and` is not a logical operator
106-
--> $DIR/issue-54109-without-witness.rs:56:13
107-
|
108-
LL | while a and b {
109-
| ^^^ help: use `&&` to perform logical conjunction
110-
|
111-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
112-
113-
error: `or` is not a logical operator
114-
--> $DIR/issue-54109-without-witness.rs:65:13
115-
|
116-
LL | while a or b {
117-
| ^^ help: use `||` to perform logical disjunction
118-
|
119-
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
120-
12157
error: `or` is not a logical operator
122-
--> $DIR/issue-54109-without-witness.rs:65:13
58+
--> $DIR/issue-54109-without-witness.rs:58:13
12359
|
12460
LL | while a or b {
12561
| ^^ help: use `||` to perform logical disjunction
12662
|
12763
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
12864

129-
error: aborting due to 16 previous errors
65+
error: aborting due to 8 previous errors
13066

‎src/test/ui/issues/issue-75599.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// check-pass
2+
#![allow(non_upper_case_globals)]
3+
4+
const or: usize = 1;
5+
const and: usize = 2;
6+
7+
mod or {
8+
pub const X: usize = 3;
9+
}
10+
11+
mod and {
12+
pub const X: usize = 4;
13+
}
14+
15+
fn main() {
16+
match 0 {
17+
0 => {}
18+
or => {}
19+
and => {}
20+
or::X => {}
21+
and::X => {}
22+
_ => {}
23+
}
24+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// check-pass
2+
//
3+
// This tests checks that clashing_extern_declarations handles types that are recursive through a
4+
// pointer or ref argument. See #75512.
5+
6+
#![crate_type = "lib"]
7+
8+
mod raw_ptr_recursion {
9+
mod a {
10+
#[repr(C)]
11+
struct Pointy {
12+
pointy: *const Pointy,
13+
}
14+
15+
extern "C" {
16+
fn run_pointy(pointy: Pointy);
17+
}
18+
}
19+
mod b {
20+
#[repr(C)]
21+
struct Pointy {
22+
pointy: *const Pointy,
23+
}
24+
25+
extern "C" {
26+
fn run_pointy(pointy: Pointy);
27+
}
28+
}
29+
}
30+
31+
mod raw_ptr_recursion_once_removed {
32+
mod a {
33+
#[repr(C)]
34+
struct Pointy1 {
35+
pointy_two: *const Pointy2,
36+
}
37+
38+
#[repr(C)]
39+
struct Pointy2 {
40+
pointy_one: *const Pointy1,
41+
}
42+
43+
extern "C" {
44+
fn run_pointy2(pointy: Pointy2);
45+
}
46+
}
47+
48+
mod b {
49+
#[repr(C)]
50+
struct Pointy1 {
51+
pointy_two: *const Pointy2,
52+
}
53+
54+
#[repr(C)]
55+
struct Pointy2 {
56+
pointy_one: *const Pointy1,
57+
}
58+
59+
extern "C" {
60+
fn run_pointy2(pointy: Pointy2);
61+
}
62+
}
63+
}
64+
65+
mod ref_recursion {
66+
mod a {
67+
#[repr(C)]
68+
struct Reffy<'a> {
69+
reffy: &'a Reffy<'a>,
70+
}
71+
72+
extern "C" {
73+
fn reffy_recursion(reffy: Reffy);
74+
}
75+
}
76+
mod b {
77+
#[repr(C)]
78+
struct Reffy<'a> {
79+
reffy: &'a Reffy<'a>,
80+
}
81+
82+
extern "C" {
83+
fn reffy_recursion(reffy: Reffy);
84+
}
85+
}
86+
}
87+
88+
mod ref_recursion_once_removed {
89+
mod a {
90+
#[repr(C)]
91+
struct Reffy1<'a> {
92+
reffy: &'a Reffy2<'a>,
93+
}
94+
95+
struct Reffy2<'a> {
96+
reffy: &'a Reffy1<'a>,
97+
}
98+
99+
extern "C" {
100+
#[allow(improper_ctypes)]
101+
fn reffy_once_removed(reffy: Reffy1);
102+
}
103+
}
104+
mod b {
105+
#[repr(C)]
106+
struct Reffy1<'a> {
107+
reffy: &'a Reffy2<'a>,
108+
}
109+
110+
struct Reffy2<'a> {
111+
reffy: &'a Reffy1<'a>,
112+
}
113+
114+
extern "C" {
115+
#[allow(improper_ctypes)]
116+
fn reffy_once_removed(reffy: Reffy1);
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)
This repository has been archived.