From 0503bc0149d310cf8d07bbb793687eda5ac2ce72 Mon Sep 17 00:00:00 2001 From: Aron Parker Date: Thu, 9 Jun 2022 15:29:58 +0200 Subject: [PATCH 01/12] Implement ExitCodeExt for Windows --- library/std/src/os/windows/process.rs | 19 +++++++++++++++++++ library/std/src/process.rs | 16 ++++++++++++++++ library/std/src/sys/windows/process.rs | 6 ++++++ 3 files changed, 41 insertions(+) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 1c7e361c2a4a..179c6e78807b 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -194,3 +194,22 @@ impl ChildExt for process::Child { self.handle.main_thread_handle() } } + +/// Windows-specific extensions to [`process::ExitCode`]. +/// +/// This trait is sealed: it cannot be implemented outside the standard library. +/// This is so that future additional methods are not breaking changes. +#[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] +pub trait ExitCodeExt: Sealed { + /// Creates a new `ExitStatus` from the raw underlying `u32` return value of + /// a process. + #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] + fn from_raw(raw: u32) -> Self; +} + +#[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] +impl ExitCodeExt for process::ExitCode { + fn from_raw(raw: u32) -> Self { + process::ExitCode::from_inner(From::from(raw)) + } +} diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 1def9fe09720..903ad01a2007 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1708,6 +1708,10 @@ impl crate::error::Error for ExitStatusError {} #[stable(feature = "process_exitcode", since = "1.61.0")] pub struct ExitCode(imp::ExitCode); +/// Allows extension traits within `std`. +#[unstable(feature = "sealed", issue = "none")] +impl crate::sealed::Sealed for ExitCode {} + #[stable(feature = "process_exitcode", since = "1.61.0")] impl ExitCode { /// The canonical `ExitCode` for successful termination on this platform. @@ -1798,6 +1802,18 @@ impl From for ExitCode { } } +impl AsInner for ExitCode { + fn as_inner(&self) -> &imp::ExitCode { + &self.0 + } +} + +impl FromInner for ExitCode { + fn from_inner(s: imp::ExitCode) -> ExitCode { + ExitCode(s) + } +} + impl Child { /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`] /// error is returned. diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 9fd399f4ba1d..02d5af4719ae 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -707,6 +707,12 @@ impl From for ExitCode { } } +impl From for ExitCode { + fn from(code: u32) -> Self { + ExitCode(c::DWORD::from(code)) + } +} + fn zeroed_startupinfo() -> c::STARTUPINFO { c::STARTUPINFO { cb: 0, From 5d32f313fb6da996d57258e6a0a8fd916a5702b9 Mon Sep 17 00:00:00 2001 From: Aron Parker Date: Fri, 10 Jun 2022 14:21:49 +0200 Subject: [PATCH 02/12] Fix copy paste error --- library/std/src/os/windows/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 179c6e78807b..027a901c08c5 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -201,7 +201,7 @@ impl ChildExt for process::Child { /// This is so that future additional methods are not breaking changes. #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] pub trait ExitCodeExt: Sealed { - /// Creates a new `ExitStatus` from the raw underlying `u32` return value of + /// Creates a new `ExitCode` from the raw underlying `u32` return value of /// a process. #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] fn from_raw(raw: u32) -> Self; From eb783d9632e054f318ac35613408a3d13774d67f Mon Sep 17 00:00:00 2001 From: Aron Parker Date: Fri, 10 Jun 2022 14:33:19 +0200 Subject: [PATCH 03/12] Incorporate warning for potential exit code ambiguities --- library/std/src/os/windows/process.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 027a901c08c5..2da1b159d723 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -203,6 +203,10 @@ impl ChildExt for process::Child { pub trait ExitCodeExt: Sealed { /// Creates a new `ExitCode` from the raw underlying `u32` return value of /// a process. + /// + /// The exit code should not be 259, as this conflicts with the `STILL_ACTIVE` + /// macro returned from the `GetExitCodeProcess` function to signal that the + /// process has yet to run to completion. #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] fn from_raw(raw: u32) -> Self; } From b13af732f74bb84a5af522c4e2f5b51950747f0d Mon Sep 17 00:00:00 2001 From: Aron Parker Date: Fri, 10 Jun 2022 14:55:13 +0200 Subject: [PATCH 04/12] Make "windows_process_exit_code_from" unstable --- library/std/src/os/windows/process.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 2da1b159d723..164da2a49f72 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -199,7 +199,7 @@ impl ChildExt for process::Child { /// /// This trait is sealed: it cannot be implemented outside the standard library. /// This is so that future additional methods are not breaking changes. -#[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] +#[unstable(feature = "windows_process_exit_code_from", issue = "none")] pub trait ExitCodeExt: Sealed { /// Creates a new `ExitCode` from the raw underlying `u32` return value of /// a process. @@ -207,11 +207,11 @@ pub trait ExitCodeExt: Sealed { /// The exit code should not be 259, as this conflicts with the `STILL_ACTIVE` /// macro returned from the `GetExitCodeProcess` function to signal that the /// process has yet to run to completion. - #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] + #[unstable(feature = "windows_process_exit_code_from", issue = "none")] fn from_raw(raw: u32) -> Self; } -#[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] +#[unstable(feature = "windows_process_exit_code_from", issue = "none")] impl ExitCodeExt for process::ExitCode { fn from_raw(raw: u32) -> Self { process::ExitCode::from_inner(From::from(raw)) From 27b7b3dcd6b0dddc1dae6d4412f05c4aec8aa72f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Jul 2022 10:52:20 -0400 Subject: [PATCH 05/12] interpret: use AllocRange in UninitByteAccess also use nice new format string syntax in interpret/error.rs --- .../src/interpret/validity.rs | 4 +- .../src/mir/interpret/allocation.rs | 21 +++-- .../rustc_middle/src/mir/interpret/error.rs | 90 ++++++++----------- .../intrinsic-raw_eq-const-padding.stderr | 2 +- 4 files changed, 54 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 0bf78446e37f..08102585a7b7 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -427,7 +427,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' err_ub!(DanglingIntPointer(0, _)) => { "a null {kind}" }, err_ub!(DanglingIntPointer(i, _)) => - { "a dangling {kind} (address 0x{i:x} is unallocated)" }, + { "a dangling {kind} (address {i:#x} is unallocated)" }, err_ub!(PointerOutOfBounds { .. }) => { "a dangling {kind} (going beyond the bounds of its allocation)" }, // This cannot happen during const-eval (because interning already detects @@ -941,7 +941,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // element that byte belongs to so we can // provide an index. let i = usize::try_from( - access.uninit_offset.bytes() / layout.size.bytes(), + access.uninit.start.bytes() / layout.size.bytes(), ) .unwrap(); self.path.push(PathElem::ArrayElem(i)); diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 1bbd71c3f1f5..ae333846f067 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -179,6 +179,11 @@ pub fn alloc_range(start: Size, size: Size) -> AllocRange { } impl AllocRange { + #[inline] + pub fn from(r: Range) -> Self { + alloc_range(r.start, r.end - r.start) // `Size` subtraction (overflow-checked) + } + #[inline(always)] pub fn end(self) -> Size { self.start + self.size // This does overflow checking. @@ -1095,9 +1100,9 @@ impl InitMask { /// Returns `Ok(())` if it's initialized. Otherwise returns a range of byte /// indexes for the first contiguous span of the uninitialized access. #[inline] - pub fn is_range_initialized(&self, start: Size, end: Size) -> Result<(), Range> { + pub fn is_range_initialized(&self, start: Size, end: Size) -> Result<(), AllocRange> { if end > self.len { - return Err(self.len..end); + return Err(AllocRange::from(self.len..end)); } let uninit_start = self.find_bit(start, end, false); @@ -1105,7 +1110,7 @@ impl InitMask { match uninit_start { Some(uninit_start) => { let uninit_end = self.find_bit(uninit_start, end, true).unwrap_or(end); - Err(uninit_start..uninit_end) + Err(AllocRange::from(uninit_start..uninit_end)) } None => Ok(()), } @@ -1176,19 +1181,17 @@ impl Allocation { /// /// Returns `Ok(())` if it's initialized. Otherwise returns the range of byte /// indexes of the first contiguous uninitialized access. - fn is_init(&self, range: AllocRange) -> Result<(), Range> { + fn is_init(&self, range: AllocRange) -> Result<(), AllocRange> { self.init_mask.is_range_initialized(range.start, range.end()) // `Size` addition } /// Checks that a range of bytes is initialized. If not, returns the `InvalidUninitBytes` /// error which will report the first range of bytes which is uninitialized. fn check_init(&self, range: AllocRange) -> AllocResult { - self.is_init(range).map_err(|idx_range| { + self.is_init(range).map_err(|uninit_range| { AllocError::InvalidUninitBytes(Some(UninitBytesAccess { - access_offset: range.start, - access_size: range.size, - uninit_offset: idx_range.start, - uninit_size: idx_range.end - idx_range.start, // `Size` subtraction + access: range, + uninit: uninit_range, })) }) } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2a1fd6f736e9..795f23edb318 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,4 +1,4 @@ -use super::{AllocId, ConstAlloc, Pointer, Scalar}; +use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar}; use crate::mir::interpret::ConstValue; use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty, ValTree}; @@ -162,9 +162,9 @@ impl fmt::Display for InvalidProgramInfo<'_> { AlreadyReported(ErrorGuaranteed { .. }) => { write!(f, "encountered constants with type errors, stopping evaluation") } - Layout(ref err) => write!(f, "{}", err), - FnAbiAdjustForForeignAbi(ref err) => write!(f, "{}", err), - SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{}`", ty), + Layout(ref err) => write!(f, "{err}"), + FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"), + SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"), } } } @@ -205,14 +205,10 @@ impl fmt::Display for CheckInAllocMsg { /// Details of an access to uninitialized bytes where it is not allowed. #[derive(Debug)] pub struct UninitBytesAccess { - /// Location of the original memory access. - pub access_offset: Size, - /// Size of the original memory access. - pub access_size: Size, - /// Location of the first uninitialized byte that was accessed. - pub uninit_offset: Size, - /// Number of consecutive uninitialized bytes that were accessed. - pub uninit_size: Size, + /// Range of the original memory access. + pub access: AllocRange, + /// Range of the uninit memory that was encountered. (Might not be maximal.) + pub uninit: AllocRange, } /// Information about a size mismatch. @@ -308,30 +304,28 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use UndefinedBehaviorInfo::*; match self { - Ub(msg) => write!(f, "{}", msg), + Ub(msg) => write!(f, "{msg}"), Unreachable => write!(f, "entering unreachable code"), BoundsCheckFailed { ref len, ref index } => { - write!(f, "indexing out of bounds: the len is {} but the index is {}", len, index) + write!(f, "indexing out of bounds: the len is {len} but the index is {index}") } DivisionByZero => write!(f, "dividing by zero"), RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"), DivisionOverflow => write!(f, "overflow in signed division (dividing MIN by -1)"), RemainderOverflow => write!(f, "overflow in signed remainder (dividing MIN by -1)"), PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"), - InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg), + InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {msg}"), InvalidVtableDropFn(sig) => write!( f, - "invalid drop function signature: got {}, expected exactly one argument which must be a pointer type", - sig + "invalid drop function signature: got {sig}, expected exactly one argument which must be a pointer type", ), InvalidVtableSize => { write!(f, "invalid vtable: size is bigger than largest supported object") } - InvalidVtableAlignment(msg) => write!(f, "invalid vtable: alignment {}", msg), + InvalidVtableAlignment(msg) => write!(f, "invalid vtable: alignment {msg}"), UnterminatedCString(p) => write!( f, - "reading a null-terminated string starting at {:?} with no null found before end of allocation", - p, + "reading a null-terminated string starting at {p:?} with no null found before end of allocation", ), PointerUseAfterFree(a) => { write!(f, "pointer to {a:?} was dereferenced after this allocation got freed") @@ -359,41 +353,36 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { } AlignmentCheckFailed { required, has } => write!( f, - "accessing memory with alignment {}, but alignment {} is required", - has.bytes(), - required.bytes() + "accessing memory with alignment {has}, but alignment {required} is required", + has = has.bytes(), + required = required.bytes() ), WriteToReadOnly(a) => write!(f, "writing to {a:?} which is read-only"), DerefFunctionPointer(a) => write!(f, "accessing {a:?} which contains a function"), ValidationFailure { path: None, msg } => { - write!(f, "constructing invalid value: {}", msg) + write!(f, "constructing invalid value: {msg}") } ValidationFailure { path: Some(path), msg } => { - write!(f, "constructing invalid value at {}: {}", path, msg) + write!(f, "constructing invalid value at {path}: {msg}") } InvalidBool(b) => { - write!(f, "interpreting an invalid 8-bit value as a bool: 0x{:02x}", b) + write!(f, "interpreting an invalid 8-bit value as a bool: 0x{b:02x}") } InvalidChar(c) => { - write!(f, "interpreting an invalid 32-bit value as a char: 0x{:08x}", c) + write!(f, "interpreting an invalid 32-bit value as a char: 0x{c:08x}") } - InvalidTag(val) => write!(f, "enum value has invalid tag: {:x}", val), + InvalidTag(val) => write!(f, "enum value has invalid tag: {val:x}"), InvalidFunctionPointer(p) => { - write!(f, "using {:?} as function pointer but it does not point to a function", p) + write!(f, "using {p:?} as function pointer but it does not point to a function") } - InvalidStr(err) => write!(f, "this string is not valid UTF-8: {}", err), - InvalidUninitBytes(Some((alloc, access))) => write!( + InvalidStr(err) => write!(f, "this string is not valid UTF-8: {err}"), + InvalidUninitBytes(Some((alloc, info))) => write!( f, - "reading {} byte{} of memory starting at {:?}, \ - but {} byte{} {} uninitialized starting at {:?}, \ + "reading memory at {alloc:?}{access:?}, \ + but memory is uninitialized at {uninit:?}, \ and this operation requires initialized memory", - access.access_size.bytes(), - pluralize!(access.access_size.bytes()), - Pointer::new(*alloc, access.access_offset), - access.uninit_size.bytes(), - pluralize!(access.uninit_size.bytes()), - pluralize!("is", access.uninit_size.bytes()), - Pointer::new(*alloc, access.uninit_offset), + access = info.access, + uninit = info.uninit, ), InvalidUninitBytes(None) => write!( f, @@ -402,8 +391,7 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { DeadLocal => write!(f, "accessing a dead local variable"), ScalarSizeMismatch(self::ScalarSizeMismatch { target_size, data_size }) => write!( f, - "scalar size mismatch: expected {} bytes but got {} bytes instead", - target_size, data_size + "scalar size mismatch: expected {target_size} bytes but got {data_size} bytes instead", ), UninhabitedEnumVariantWritten => { write!(f, "writing discriminant of an uninhabited enum") @@ -437,13 +425,13 @@ impl fmt::Display for UnsupportedOpInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use UnsupportedOpInfo::*; match self { - Unsupported(ref msg) => write!(f, "{}", msg), + Unsupported(ref msg) => write!(f, "{msg}"), ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes"), PartialPointerOverwrite(ptr) => { - write!(f, "unable to overwrite parts of a pointer in memory at {:?}", ptr) + write!(f, "unable to overwrite parts of a pointer in memory at {ptr:?}") } - ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({:?})", did), - ReadExternStatic(did) => write!(f, "cannot read from extern static ({:?})", did), + ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({did:?})"), + ReadExternStatic(did) => write!(f, "cannot read from extern static ({did:?})"), } } } @@ -526,11 +514,11 @@ impl fmt::Display for InterpError<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InterpError::*; match *self { - Unsupported(ref msg) => write!(f, "{}", msg), - InvalidProgram(ref msg) => write!(f, "{}", msg), - UndefinedBehavior(ref msg) => write!(f, "{}", msg), - ResourceExhaustion(ref msg) => write!(f, "{}", msg), - MachineStop(ref msg) => write!(f, "{}", msg), + Unsupported(ref msg) => write!(f, "{msg}"), + InvalidProgram(ref msg) => write!(f, "{msg}"), + UndefinedBehavior(ref msg) => write!(f, "{msg}"), + ResourceExhaustion(ref msg) => write!(f, "{msg}"), + MachineStop(ref msg) => write!(f, "{msg}"), } } } diff --git a/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr b/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr index ff78c252731b..9322654b2928 100644 --- a/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr +++ b/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/intrinsic-raw_eq-const-padding.rs:6:5 | LL | std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading 4 bytes of memory starting at alloc3, but 1 byte is uninitialized starting at alloc3+0x1, and this operation requires initialized memory + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at alloc3[0x0..0x4], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory error: aborting due to previous error From deaa92b34b50bffcd043da6a558338870436db36 Mon Sep 17 00:00:00 2001 From: pierwill <19642016+pierwill@users.noreply.github.com> Date: Wed, 6 Jul 2022 13:26:26 -0500 Subject: [PATCH 06/12] Fix missing word in comment --- compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index eae9313b7713..f6b5af90a85c 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -153,7 +153,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc _: &mir::Statement<'tcx>, loc: Location, ) { - // If we move from a place then only stops needing storage *after* + // If we move from a place then it only stops needing storage *after* // that statement. self.check_for_move(trans, loc); } From 2a0e659dfd6fba0fd49b4596a57c62ffef515baa Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 7 Jul 2022 11:33:56 +0900 Subject: [PATCH 07/12] add a test for #80471 --- src/test/ui/const-generics/issue-80471.rs | 13 +++++++++++++ src/test/ui/const-generics/issue-80471.stderr | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/ui/const-generics/issue-80471.rs create mode 100644 src/test/ui/const-generics/issue-80471.stderr diff --git a/src/test/ui/const-generics/issue-80471.rs b/src/test/ui/const-generics/issue-80471.rs new file mode 100644 index 000000000000..d0af8a5eaa89 --- /dev/null +++ b/src/test/ui/const-generics/issue-80471.rs @@ -0,0 +1,13 @@ +#![feature(adt_const_params)] +//~^ WARN the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] + +#[derive(PartialEq, Eq)] +enum Nat { + Z, + S(Box), +} + +fn foo() {} +//~^ ERROR `Box` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter + +fn main() {} diff --git a/src/test/ui/const-generics/issue-80471.stderr b/src/test/ui/const-generics/issue-80471.stderr new file mode 100644 index 000000000000..dbcc0b7b6007 --- /dev/null +++ b/src/test/ui/const-generics/issue-80471.stderr @@ -0,0 +1,18 @@ +warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-80471.rs:1:12 + | +LL | #![feature(adt_const_params)] + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #95174 for more information + +error[E0741]: `Box` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter + --> $DIR/issue-80471.rs:10:17 + | +LL | fn foo() {} + | ^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0741`. From d6de276bd9288cfe7d178ee21dfcbf1229680155 Mon Sep 17 00:00:00 2001 From: toshiki goto Date: Wed, 6 Jul 2022 15:05:44 +0900 Subject: [PATCH 08/12] squash the commits implement detail_exit but I'm not sure it is right. not create new file and write detail exit in lib.rs replace std::process::exit to detail_exit that is not related to code runnning. remove pub --- src/bootstrap/builder.rs | 10 +++------- src/bootstrap/compile.rs | 4 ++-- src/bootstrap/config.rs | 8 +++----- src/bootstrap/flags.rs | 13 ++++++------- src/bootstrap/format.rs | 4 ++-- src/bootstrap/lib.rs | 20 +++++++++++++++++--- src/bootstrap/sanity.rs | 2 +- src/bootstrap/setup.rs | 4 ++-- src/bootstrap/test.rs | 6 +++--- src/bootstrap/tool.rs | 4 ++-- src/bootstrap/toolstate.rs | 8 ++++---- src/bootstrap/util.rs | 6 +++--- 12 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index fa2a530d9db6..245832245d1f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -348,11 +348,7 @@ impl StepDescription { eprintln!( "note: if you are adding a new Step to bootstrap itself, make sure you register it with `describe!`" ); - #[cfg(not(test))] - std::process::exit(1); - #[cfg(test)] - // so we can use #[should_panic] - panic!() + crate::detail_exit(1); } } } @@ -1001,7 +997,7 @@ impl<'a> Builder<'a> { if !help_on_error.is_empty() { eprintln!("{}", help_on_error); } - std::process::exit(1); + crate::detail_exit(1); } } @@ -1430,7 +1426,7 @@ impl<'a> Builder<'a> { "error: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component" ); eprintln!("help: try `rustup component add clippy`"); - std::process::exit(1); + crate::detail_exit(1); }); if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") { rustflags.arg("--cfg=bootstrap"); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b4807d1ab3af..d50950888db9 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -13,7 +13,7 @@ use std::fs; use std::io::prelude::*; use std::io::BufReader; use std::path::{Path, PathBuf}; -use std::process::{exit, Command, Stdio}; +use std::process::{Command, Stdio}; use std::str; use serde::Deserialize; @@ -1328,7 +1328,7 @@ pub fn run_cargo( }); if !ok { - exit(1); + crate::detail_exit(1); } // Ok now we need to actually find all the files listed in `toplevel`. We've diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 2fc18c9e79e3..e71fbff14dd1 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -11,7 +11,7 @@ use std::ffi::OsStr; use std::fmt; use std::fs; use std::path::{Path, PathBuf}; -use std::process::{exit, Command}; +use std::process::Command; use std::str::FromStr; use crate::builder::{Builder, TaskPath}; @@ -805,8 +805,6 @@ impl Config { let get_toml = |_| TomlConfig::default(); #[cfg(not(test))] let get_toml = |file: &Path| { - use std::process; - let contents = t!(fs::read_to_string(file), format!("config file {} not found", file.display())); // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of @@ -817,7 +815,7 @@ impl Config { Ok(table) => table, Err(err) => { eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err); - process::exit(2); + crate::detail_exit(2); } } }; @@ -1487,7 +1485,7 @@ fn download_ci_rustc_commit( println!("help: maybe your repository history is too shallow?"); println!("help: consider disabling `download-rustc`"); println!("help: or fetch enough history to include one upstream commit"); - exit(1); + crate::detail_exit(1); } // Warn if there were changes to the compiler or standard library since the ancestor commit. diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 7ebae55efc16..eec19ab4fc90 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -4,7 +4,6 @@ //! has various flags to configure how it's run. use std::path::PathBuf; -use std::process; use getopts::Options; @@ -261,7 +260,7 @@ To learn more about a subcommand, run `./x.py -h`", // subcommand. println!("{}\n", subcommand_help); let exit_code = if args.is_empty() { 0 } else { 1 }; - process::exit(exit_code); + crate::detail_exit(exit_code); } }; @@ -347,7 +346,7 @@ To learn more about a subcommand, run `./x.py -h`", } else if verbose { panic!("No paths available for subcommand `{}`", subcommand.as_str()); } - process::exit(exit_code); + crate::detail_exit(exit_code); }; // Done specifying what options are possible, so do the getopts parsing @@ -379,7 +378,7 @@ To learn more about a subcommand, run `./x.py -h`", "Sorry, I couldn't figure out which subcommand you were trying to specify.\n\ You may need to move some options to after the subcommand.\n" ); - process::exit(1); + crate::detail_exit(1); } // Extra help text for some commands match subcommand { @@ -600,7 +599,7 @@ Arguments: eprintln!("error: {}", err); eprintln!("help: the available profiles are:"); eprint!("{}", Profile::all_for_help("- ")); - std::process::exit(1); + crate::detail_exit(1); }) } else { t!(crate::setup::interactive_path()) @@ -614,7 +613,7 @@ Arguments: || matches.opt_str("keep-stage-std").is_some() { eprintln!("--keep-stage not yet supported for x.py check"); - process::exit(1); + crate::detail_exit(1); } } @@ -805,7 +804,7 @@ fn parse_deny_warnings(matches: &getopts::Matches) -> Option { Some("warn") => Some(false), Some(value) => { eprintln!(r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#, value,); - process::exit(1); + crate::detail_exit(1); } None => None, } diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 60a53c28686b..f25977c1d463 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -32,7 +32,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F code, run `./x.py fmt` instead.", cmd_debug, ); - std::process::exit(1); + crate::detail_exit(1); } } } @@ -114,7 +114,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| { eprintln!("./x.py fmt is not supported on this channel"); - std::process::exit(1); + crate::detail_exit(1); }); assert!(rustfmt_path.exists(), "{}", rustfmt_path.display()); let src = build.src.clone(); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 73bd588472df..82025efcbe0e 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -109,7 +109,7 @@ use std::env; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; -use std::process::{self, Command}; +use std::process::Command; use std::str; use filetime::FileTime; @@ -711,7 +711,7 @@ impl Build { for failure in failures.iter() { eprintln!(" - {}\n", failure); } - process::exit(1); + detail_exit(1); } #[cfg(feature = "build-metrics")] @@ -1617,7 +1617,7 @@ Alternatively, set `download-ci-llvm = true` in that `[llvm]` section to download LLVM rather than building it. " ); - std::process::exit(1); + detail_exit(1); } } @@ -1646,6 +1646,20 @@ fn chmod(path: &Path, perms: u32) { #[cfg(windows)] fn chmod(_path: &Path, _perms: u32) {} +/// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.) +/// If the test is running and code is an error code, it will cause a panic. +fn detail_exit(code: i32) -> ! { + // Successful exit + if code == 0 { + std::process::exit(0); + } + if cfg!(test) { + panic!("status code: {}", code); + } else { + std::panic::resume_unwind(Box::new(code)); + } +} + impl Compiler { pub fn with_stage(mut self, stage: u32) -> Compiler { self.stage = stage; diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 64c5dd7aea72..cae41286f087 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -104,7 +104,7 @@ You should install cmake, or set `download-ci-llvm = true` in the than building it. " ); - std::process::exit(1); + crate::detail_exit(1); } } diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 82f55440ce50..740c12ed725e 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -94,7 +94,7 @@ pub fn setup(config: &Config, profile: Profile) { "note: this will use the configuration in {}", profile.include_path(&config.src).display() ); - std::process::exit(1); + crate::detail_exit(1); } let settings = format!( @@ -287,7 +287,7 @@ pub fn interactive_path() -> io::Result { io::stdin().read_line(&mut input)?; if input.is_empty() { eprintln!("EOF on stdin, when expecting answer to question. Giving up."); - std::process::exit(1); + crate::detail_exit(1); } break match parse_with_abbrev(&input) { Ok(profile) => profile, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f3395507bb08..e4909d64b98c 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -673,7 +673,7 @@ impl Step for Clippy { } if !builder.config.cmd.bless() { - std::process::exit(1); + crate::detail_exit(1); } let mut cargo = builder.cargo(compiler, Mode::ToolRustc, SourceType::InTree, host, "run"); @@ -1021,7 +1021,7 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` PATH = inferred_rustfmt_dir.display(), CHAN = builder.config.channel, ); - std::process::exit(1); + crate::detail_exit(1); } crate::format::format(&builder, !builder.config.cmd.bless(), &[]); } @@ -1251,7 +1251,7 @@ help: to test the compiler, use `--stage 1` instead help: to test the standard library, use `--stage 0 library/std` instead note: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `COMPILETEST_FORCE_STAGE0=1`." ); - std::process::exit(1); + crate::detail_exit(1); } let compiler = self.compiler; diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 5be6841e988a..4e8ff75cc67c 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::env; use std::fs; use std::path::{Path, PathBuf}; -use std::process::{exit, Command}; +use std::process::Command; use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::channel::GitInfo; @@ -204,7 +204,7 @@ impl Step for ToolBuild { if !is_expected { if !is_optional_tool { - exit(1); + crate::detail_exit(1); } else { None } diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 3ee6a42d987a..2cfeae7dc785 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -93,7 +93,7 @@ fn print_error(tool: &str, submodule: &str) { eprintln!("If you do NOT intend to update '{}', please ensure you did not accidentally", tool); eprintln!("change the submodule at '{}'. You may ask your reviewer for the", submodule); eprintln!("proper steps."); - std::process::exit(3); + crate::detail_exit(3); } fn check_changed_files(toolstates: &HashMap, ToolState>) { @@ -108,7 +108,7 @@ fn check_changed_files(toolstates: &HashMap, ToolState>) { Ok(o) => o, Err(e) => { eprintln!("Failed to get changed files: {:?}", e); - std::process::exit(1); + crate::detail_exit(1); } }; @@ -179,7 +179,7 @@ impl Step for ToolStateCheck { } if did_error { - std::process::exit(1); + crate::detail_exit(1); } check_changed_files(&toolstates); @@ -225,7 +225,7 @@ impl Step for ToolStateCheck { } if did_error { - std::process::exit(1); + crate::detail_exit(1); } if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() { diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 6f4266a7f294..b627e5037899 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -336,7 +336,7 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef>( pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) { if !try_run(cmd, print_cmd_on_fail) { - std::process::exit(1); + crate::detail_exit(1); } } @@ -375,7 +375,7 @@ pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool { pub fn run_suppressed(cmd: &mut Command) { if !try_run_suppressed(cmd) { - std::process::exit(1); + crate::detail_exit(1); } } @@ -465,7 +465,7 @@ fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool { fn fail(s: &str) -> ! { eprintln!("\n\n{}\n\n", s); - std::process::exit(1); + crate::detail_exit(1); } /// Copied from `std::path::absolute` until it stabilizes. From 2f0ccdfbba1a721844a7ba83d6e87e12728d19c3 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 7 Jul 2022 04:57:01 +0000 Subject: [PATCH 09/12] suggest adding a derive for #[default] applied to variants --- compiler/rustc_resolve/src/diagnostics.rs | 14 ++++++++++---- src/test/ui/enum/suggest-default-attribute.rs | 2 +- src/test/ui/enum/suggest-default-attribute.stderr | 8 ++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 0f58206eee9f..ec9ae63ca366 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1499,10 +1499,16 @@ impl<'a> Resolver<'a> { && let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind && let Some(span) = self.opt_span(def_id) { - err.span_help( - self.session.source_map().guess_head_span(span), - "consider adding `#[derive(Default)]` to this enum", - ); + let source_map = self.session.source_map(); + let head_span = source_map.guess_head_span(span); + if let Ok(head) = source_map.span_to_snippet(head_span) { + err.span_suggestion(head_span, "consider adding a derive", format!("#[derive(Default)]\n{head}"), Applicability::MaybeIncorrect); + } else { + err.span_help( + head_span, + "consider adding `#[derive(Default)]` to this enum", + ); + } } for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] { if let Ok(binding) = self.early_resolve_ident_in_lexical_scope( diff --git a/src/test/ui/enum/suggest-default-attribute.rs b/src/test/ui/enum/suggest-default-attribute.rs index 33bd0d240813..1d7567e60a57 100644 --- a/src/test/ui/enum/suggest-default-attribute.rs +++ b/src/test/ui/enum/suggest-default-attribute.rs @@ -1,4 +1,4 @@ -pub enum Test { //~ HELP consider adding `#[derive(Default)]` to this enum +pub enum Test { //~ HELP consider adding a derive #[default] //~^ ERROR cannot find attribute `default` in this scope First, diff --git a/src/test/ui/enum/suggest-default-attribute.stderr b/src/test/ui/enum/suggest-default-attribute.stderr index 791f219e8f95..fb830d3f78b6 100644 --- a/src/test/ui/enum/suggest-default-attribute.stderr +++ b/src/test/ui/enum/suggest-default-attribute.stderr @@ -4,11 +4,11 @@ error: cannot find attribute `default` in this scope LL | #[default] | ^^^^^^^ | -help: consider adding `#[derive(Default)]` to this enum - --> $DIR/suggest-default-attribute.rs:1:1 +help: consider adding a derive + | +LL + #[derive(Default)] +LL ~ pub enum Test { | -LL | pub enum Test { - | ^^^^^^^^^^^^^ error: aborting due to previous error From a80bb5b387a76b169c2a6fe80d0e87fb8c2f6e3f Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 7 Jul 2022 15:42:48 +0900 Subject: [PATCH 10/12] add a test for #70408 --- src/test/ui/const-generics/issue-70408.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/const-generics/issue-70408.rs diff --git a/src/test/ui/const-generics/issue-70408.rs b/src/test/ui/const-generics/issue-70408.rs new file mode 100644 index 000000000000..f7557cb492c0 --- /dev/null +++ b/src/test/ui/const-generics/issue-70408.rs @@ -0,0 +1,13 @@ +// build-pass + +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +pub fn function_with_bytes() -> &'static [u8] { + BYTES +} + +pub fn main() { + assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); + assert_eq!(function_with_bytes::<{ &[0x41, 0x41, 0x41, 0x41] }>(), b"AAAA"); +} From 111df9e6eda1d752233482c1309d00d20a4bbf98 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 3 Jul 2022 15:28:57 +0200 Subject: [PATCH 11/12] Reword comments and rename HIR visiting methods. --- compiler/rustc_hir/src/intravisit.rs | 4 +- .../rustc_incremental/src/assert_dep_graph.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 66 +++++++++-------- .../rustc_middle/src/hir/nested_filter.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_passes/src/check_const.rs | 2 +- compiler/rustc_passes/src/hir_id_validator.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_passes/src/loops.rs | 2 +- compiler/rustc_passes/src/naked_functions.rs | 2 +- compiler/rustc_passes/src/stability.rs | 4 +- compiler/rustc_typeck/src/collect.rs | 2 +- src/librustdoc/scrape_examples.rs | 2 +- .../dep-graph-struct-signature.stderr | 72 +++++++++---------- .../ui/dep-graph/dep-graph-type-alias.stderr | 36 +++++----- .../missing-const-stability.stderr | 12 ++-- 18 files changed, 113 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 384a0f9c2253..531d9f140402 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -19,7 +19,7 @@ //! - Example: Examine each expression to look for its type and do some check or other. //! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to //! `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use -//! `tcx.hir().deep_visit_all_item_likes(&mut visitor)`. Within your +//! `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your //! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke //! `intravisit::walk_expr()` to keep walking the subparts). //! - Pro: Visitor methods for any kind of HIR node, not just item-like things. @@ -190,7 +190,7 @@ use nested_filter::NestedFilter; /// (this is why the module is called `intravisit`, to distinguish it /// from the AST's `visit` module, which acts differently). If you /// simply want to visit all items in the crate in some order, you -/// should call `Crate::visit_all_items`. Otherwise, see the comment +/// should call `tcx.hir().visit_all_item_likes_in_crate`. Otherwise, see the comment /// on `visit_nested_item` for details on how to visit nested items. /// /// If you want to ensure that your code handles every variant diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index a89b9eafaa62..93528b4514b5 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -75,7 +75,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) { let mut visitor = IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] }; visitor.process_attrs(hir::CRATE_HIR_ID); - tcx.hir().deep_visit_all_item_likes(&mut visitor); + tcx.hir().visit_all_item_likes_in_crate(&mut visitor); (visitor.if_this_changed, visitor.then_this_would_need) }; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index bb4b502bded4..0442cbc0c932 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -419,7 +419,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { return; } - self.tcx.hir().deep_visit_all_item_likes(self); + self.tcx.hir().visit_all_item_likes_in_crate(self); } fn encode_def_path_table(&mut self) { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index cda0a60fa4e1..419ce2996fb6 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -568,7 +568,7 @@ impl<'hir> Map<'hir> { } } - /// Walks the contents of a crate. See also `Crate::visit_all_items`. + /// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`. pub fn walk_toplevel_module(self, visitor: &mut impl Visitor<'hir>) { let (top_mod, span, hir_id) = self.get_module(CRATE_DEF_ID); visitor.visit_mod(top_mod, span, hir_id); @@ -588,53 +588,61 @@ impl<'hir> Map<'hir> { } } - /// Visits all items in the crate in some deterministic (but - /// unspecified) order. If you need to process every item, - /// and care about nesting -- usually because your algorithm - /// follows lexical scoping rules -- then this method is the best choice. - /// If you don't care about nesting, you should use the `tcx.hir_crate_items()` query - /// or `items()` instead. + /// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you + /// need to process every item-like, and don't care about visiting nested items in a particular + /// order then this method is the best choice. If you do care about this nesting, you should + /// use the `tcx.hir().walk_toplevel_module`. + /// + /// Note that this function will access HIR for all the item-likes in the crate. If you only + /// need to access some of them, it is usually better to manually loop on the iterators + /// provided by `tcx.hir_crate_items(())`. /// /// Please see the notes in `intravisit.rs` for more information. - pub fn deep_visit_all_item_likes(self, visitor: &mut V) + pub fn visit_all_item_likes_in_crate(self, visitor: &mut V) where V: Visitor<'hir>, { - let krate = self.krate(); - for owner in krate.owners.iter().filter_map(|i| i.as_owner()) { - match owner.node() { - OwnerNode::Item(item) => visitor.visit_item(item), - OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), - OwnerNode::ImplItem(item) => visitor.visit_impl_item(item), - OwnerNode::TraitItem(item) => visitor.visit_trait_item(item), - OwnerNode::Crate(_) => {} - } + let krate = self.tcx.hir_crate_items(()); + + for id in krate.items() { + visitor.visit_item(self.item(id)); + } + + for id in krate.trait_items() { + visitor.visit_trait_item(self.trait_item(id)); + } + + for id in krate.impl_items() { + visitor.visit_impl_item(self.impl_item(id)); + } + + for id in krate.foreign_items() { + visitor.visit_foreign_item(self.foreign_item(id)); } } - /// If you don't care about nesting, you should use the - /// `tcx.hir_module_items()` query or `module_items()` instead. - /// Please see notes in `deep_visit_all_item_likes`. - pub fn deep_visit_item_likes_in_module(self, module: LocalDefId, visitor: &mut V) + /// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to + /// item-likes in a single module. + pub fn visit_item_likes_in_module(self, module: LocalDefId, visitor: &mut V) where V: Visitor<'hir>, { let module = self.tcx.hir_module_items(module); - for id in module.items.iter() { - visitor.visit_item(self.item(*id)); + for id in module.items() { + visitor.visit_item(self.item(id)); } - for id in module.trait_items.iter() { - visitor.visit_trait_item(self.trait_item(*id)); + for id in module.trait_items() { + visitor.visit_trait_item(self.trait_item(id)); } - for id in module.impl_items.iter() { - visitor.visit_impl_item(self.impl_item(*id)); + for id in module.impl_items() { + visitor.visit_impl_item(self.impl_item(id)); } - for id in module.foreign_items.iter() { - visitor.visit_foreign_item(self.foreign_item(*id)); + for id in module.foreign_items() { + visitor.visit_foreign_item(self.foreign_item(id)); } } diff --git a/compiler/rustc_middle/src/hir/nested_filter.rs b/compiler/rustc_middle/src/hir/nested_filter.rs index d56e87bbb474..6896837aa910 100644 --- a/compiler/rustc_middle/src/hir/nested_filter.rs +++ b/compiler/rustc_middle/src/hir/nested_filter.rs @@ -8,7 +8,7 @@ use rustc_hir::intravisit::nested_filter::NestedFilter; /// constant arguments of types, e.g. in `let _: [(); /* HERE */];`. /// /// **This is the most common choice.** A very common pattern is -/// to use `deep_visit_all_item_likes()` as an outer loop, +/// to use `visit_all_item_likes_in_crate()` as an outer loop, /// and to have the visitor that visits the contents of each item /// using this setting. pub struct OnlyBodies(()); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9776cd0ab8bc..0887775aae5e 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -173,7 +173,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { intravisit::walk_struct_def(self, v) } } - tcx.hir().deep_visit_all_item_likes(&mut GatherCtors { tcx, set: &mut set }); + tcx.hir().visit_all_item_likes_in_crate(&mut GatherCtors { tcx, set: &mut set }); set } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8c123c052e5a..d0723c68a77e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2428,7 +2428,7 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { let check_attr_visitor = &mut CheckAttrVisitor { tcx }; - tcx.hir().deep_visit_item_likes_in_module(module_def_id, check_attr_visitor); + tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor); if module_def_id.is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None); check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs()); diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 996ca66de0e4..31c159c1f756 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -56,7 +56,7 @@ impl NonConstExpr { fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { let mut vis = CheckConstVisitor::new(tcx); - tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut vis); + tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis); } pub(crate) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 550c062f4de0..9deb0042ff36 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -28,7 +28,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { errors: &errors, }; - tcx.hir().deep_visit_item_likes_in_module(module_id, &mut v); + tcx.hir().visit_item_likes_in_module(module_id, &mut v); }); let errors = errors.into_inner(); diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 80a263f4cb2d..0070c0699a4a 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -140,7 +140,7 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String { } fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx)); + tcx.hir().visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx)); } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 9cfef26fd031..68b2a052391f 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -31,7 +31,7 @@ struct CheckLoopVisitor<'a, 'hir> { } fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir().deep_visit_item_likes_in_module( + tcx.hir().visit_item_likes_in_module( module_def_id, &mut CheckLoopVisitor { sess: &tcx.sess, hir_map: tcx.hir(), cx: Normal }, ); diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 40844b84af07..20765abf3928 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -14,7 +14,7 @@ use rustc_span::Span; use rustc_target::spec::abi::Abi; fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut CheckNakedFunctions { tcx }); + tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckNakedFunctions { tcx }); } pub(crate) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 9eaefc8b8aa8..12050dceb60a 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -660,7 +660,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); + tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); } pub(crate) fn provide(providers: &mut Providers) { @@ -890,7 +890,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let mut missing = MissingStabilityAnnotations { tcx, access_levels }; missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID)); tcx.hir().walk_toplevel_module(&mut missing); - tcx.hir().deep_visit_all_item_likes(&mut missing); + tcx.hir().visit_all_item_likes_in_crate(&mut missing); } let declared_lang_features = &tcx.features().declared_lang_features; diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index a0cbb7c2c5ae..44b9c8392f86 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -59,7 +59,7 @@ struct OnlySelfBounds(bool); // Main entry point fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx }); + tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx }); } pub fn provide(providers: &mut Providers) { diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index f6c599297fcd..c0fe8b49cfd1 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -303,7 +303,7 @@ pub(crate) fn run( // Run call-finder on all items let mut calls = FxHashMap::default(); let mut finder = FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates }; - tcx.hir().deep_visit_all_item_likes(&mut finder); + tcx.hir().visit_all_item_likes_in_crate(&mut finder); // Sort call locations within a given file in document order for fn_calls in calls.values_mut() { diff --git a/src/test/ui/dep-graph/dep-graph-struct-signature.stderr b/src/test/ui/dep-graph/dep-graph-struct-signature.stderr index 60bfbe94a8a8..cfe1e62d9318 100644 --- a/src/test/ui/dep-graph/dep-graph-struct-signature.stderr +++ b/src/test/ui/dep-graph/dep-graph-struct-signature.stderr @@ -16,12 +16,6 @@ error: no path from `WillChange` to `trait_def` LL | #[rustc_then_this_would_need(trait_def)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: OK - --> $DIR/dep-graph-struct-signature.rs:32:9 - | -LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: OK --> $DIR/dep-graph-struct-signature.rs:36:5 | @@ -52,36 +46,12 @@ error: OK LL | #[rustc_then_this_would_need(type_of)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: OK - --> $DIR/dep-graph-struct-signature.rs:48:9 - | -LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: OK - --> $DIR/dep-graph-struct-signature.rs:49:9 - | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: OK --> $DIR/dep-graph-struct-signature.rs:53:5 | LL | #[rustc_then_this_would_need(type_of)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: OK - --> $DIR/dep-graph-struct-signature.rs:55:9 - | -LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: OK - --> $DIR/dep-graph-struct-signature.rs:56:9 - | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: OK --> $DIR/dep-graph-struct-signature.rs:61:9 | @@ -106,12 +76,6 @@ error: no path from `WillChange` to `type_of` LL | #[rustc_then_this_would_need(type_of)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:77:9 - | -LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: no path from `WillChange` to `fn_sig` --> $DIR/dep-graph-struct-signature.rs:81:5 | @@ -130,5 +94,41 @@ error: no path from `WillChange` to `typeck` LL | #[rustc_then_this_would_need(typeck)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: OK + --> $DIR/dep-graph-struct-signature.rs:32:9 + | +LL | #[rustc_then_this_would_need(fn_sig)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: no path from `WillChange` to `fn_sig` + --> $DIR/dep-graph-struct-signature.rs:77:9 + | +LL | #[rustc_then_this_would_need(fn_sig)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: OK + --> $DIR/dep-graph-struct-signature.rs:48:9 + | +LL | #[rustc_then_this_would_need(fn_sig)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: OK + --> $DIR/dep-graph-struct-signature.rs:49:9 + | +LL | #[rustc_then_this_would_need(typeck)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: OK + --> $DIR/dep-graph-struct-signature.rs:55:9 + | +LL | #[rustc_then_this_would_need(fn_sig)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: OK + --> $DIR/dep-graph-struct-signature.rs:56:9 + | +LL | #[rustc_then_this_would_need(typeck)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 22 previous errors diff --git a/src/test/ui/dep-graph/dep-graph-type-alias.stderr b/src/test/ui/dep-graph/dep-graph-type-alias.stderr index c59cf8014c3d..42ac803b22ec 100644 --- a/src/test/ui/dep-graph/dep-graph-type-alias.stderr +++ b/src/test/ui/dep-graph/dep-graph-type-alias.stderr @@ -28,30 +28,12 @@ error: no path from `TypeAlias` to `type_of` LL | #[rustc_then_this_would_need(type_of)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: OK - --> $DIR/dep-graph-type-alias.rs:36:5 - | -LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: no path from `TypeAlias` to `type_of` --> $DIR/dep-graph-type-alias.rs:42:1 | LL | #[rustc_then_this_would_need(type_of)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: OK - --> $DIR/dep-graph-type-alias.rs:44:5 - | -LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: OK - --> $DIR/dep-graph-type-alias.rs:45:5 - | -LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: OK --> $DIR/dep-graph-type-alias.rs:49:1 | @@ -70,5 +52,23 @@ error: OK LL | #[rustc_then_this_would_need(typeck)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: OK + --> $DIR/dep-graph-type-alias.rs:36:5 + | +LL | #[rustc_then_this_would_need(fn_sig)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: OK + --> $DIR/dep-graph-type-alias.rs:44:5 + | +LL | #[rustc_then_this_would_need(fn_sig)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: OK + --> $DIR/dep-graph-type-alias.rs:45:5 + | +LL | #[rustc_then_this_would_need(typeck)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 12 previous errors diff --git a/src/test/ui/stability-attribute/missing-const-stability.stderr b/src/test/ui/stability-attribute/missing-const-stability.stderr index 6f2ade0d0abf..10978728fa36 100644 --- a/src/test/ui/stability-attribute/missing-const-stability.stderr +++ b/src/test/ui/stability-attribute/missing-const-stability.stderr @@ -4,12 +4,6 @@ error: function has missing const stability attribute LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: associated function has missing const stability attribute - --> $DIR/missing-const-stability.rs:15:5 - | -LL | pub const fn foo() {} - | ^^^^^^^^^^^^^^^^^^^^^ - error: implementation has missing const stability attribute --> $DIR/missing-const-stability.rs:27:1 | @@ -19,5 +13,11 @@ LL | | fn fun() {} LL | | } | |_^ +error: associated function has missing const stability attribute + --> $DIR/missing-const-stability.rs:15:5 + | +LL | pub const fn foo() {} + | ^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 3 previous errors From d96d54103e9596a0b0916358b858278b5e6072ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Jul 2022 16:16:35 +0200 Subject: [PATCH 12/12] Replace boolean argument for print_where_clause with an enum to make code more clear --- src/librustdoc/html/format.rs | 14 ++++++++++---- src/librustdoc/html/render/mod.rs | 8 ++++---- src/librustdoc/html/render/print_item.rs | 18 +++++++++--------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0982c4b3acec..84ab8d988bdb 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -268,6 +268,12 @@ impl clean::Generics { } } +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) enum Ending { + Newline, + NoNewline, +} + /// * The Generics from which to emit a where-clause. /// * The number of spaces to indent each line with. /// * Whether the where-clause needs to add a comma and newline after the last bound. @@ -275,7 +281,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( gens: &'a clean::Generics, cx: &'a Context<'tcx>, indent: usize, - end_newline: bool, + ending: Ending, ) -> impl fmt::Display + 'a + Captures<'tcx> { use fmt::Write; @@ -342,7 +348,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( let where_preds = comma_sep(where_predicates, false); let clause = if f.alternate() { - if end_newline { + if ending == Ending::Newline { // add a space so stripping
tags and breaking spaces still renders properly format!(" where{where_preds}, ") } else { @@ -356,7 +362,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } let where_preds = where_preds.to_string().replace("
", &br_with_padding); - if end_newline { + if ending == Ending::Newline { let mut clause = " ".repeat(indent.saturating_sub(1)); // add a space so stripping
tags and breaking spaces still renders properly write!( @@ -1167,7 +1173,7 @@ impl clean::Impl { fmt_type(&self.for_, f, use_absolute, cx)?; } - fmt::Display::fmt(&print_where_clause(&self.generics, cx, 0, true), f)?; + fmt::Display::fmt(&print_where_clause(&self.generics, cx, 0, Ending::Newline), f)?; Ok(()) }) } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 548f6c3a9872..3828b671e3b5 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -70,7 +70,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::{ href, join_with_double_colon, print_abi_with_space, print_constness_with_space, - print_default_space, print_generic_bounds, print_where_clause, Buffer, HrefError, + print_default_space, print_generic_bounds, print_where_clause, Buffer, Ending, HrefError, PrintWithSpace, }; use crate::html::highlight; @@ -748,7 +748,7 @@ fn assoc_type( if !bounds.is_empty() { write!(w, ": {}", print_generic_bounds(bounds, cx)) } - write!(w, "{}", print_where_clause(generics, cx, indent, false)); + write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline)); if let Some(default) = default { write!(w, " = {}", default.print(cx)) } @@ -797,10 +797,10 @@ fn assoc_method( header_len += 4; let indent_str = " "; render_attributes_in_pre(w, meth, indent_str); - (4, indent_str, false) + (4, indent_str, Ending::NoNewline) } else { render_attributes_in_code(w, meth); - (0, "", true) + (0, "", Ending::Newline) }; w.reserve(header_len + "{".len() + "".len()); write!( diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3525007baf36..421765e78603 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -29,7 +29,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::html::escape::Escape; use crate::html::format::{ join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause, - Buffer, PrintWithSpace, + Buffer, Ending, PrintWithSpace, }; use crate::html::highlight; use crate::html::layout::Page; @@ -69,7 +69,7 @@ fn print_where_clause_and_check<'a, 'tcx: 'a>( cx: &'a Context<'tcx>, ) -> bool { let len_before = buffer.len(); - write!(buffer, "{}", print_where_clause(gens, cx, 0, true)); + write!(buffer, "{}", print_where_clause(gens, cx, 0, Ending::Newline)); len_before != buffer.len() } @@ -519,7 +519,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle abi = abi, name = name, generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, true), + where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), decl = f.decl.full_print(header_len, 0, header.asyncness, cx), notable_traits = notable_traits_decl(&f.decl, cx), ); @@ -556,7 +556,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: ); if !t.generics.where_predicates.is_empty() { - write!(w, "{}", print_where_clause(&t.generics, cx, 0, true)); + write!(w, "{}", print_where_clause(&t.generics, cx, 0, Ending::Newline)); } else { w.write_str(" "); } @@ -1026,7 +1026,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: & "trait {}{}{} = {};", it.name.unwrap(), t.generics.print(cx), - print_where_clause(&t.generics, cx, 0, true), + print_where_clause(&t.generics, cx, 0, Ending::Newline), bounds(&t.bounds, true, cx) ); }); @@ -1050,7 +1050,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &cl "type {}{}{where_clause} = impl {bounds};", it.name.unwrap(), t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), + where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), bounds = bounds(&t.bounds, false, cx), ); }); @@ -1075,7 +1075,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea "type {}{}{where_clause} = {type_};", it.name.unwrap(), t.generics.print(cx), - where_clause = print_where_clause(&t.generics, cx, 0, true), + where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline), type_ = t.type_.print(cx), ); }); @@ -1786,7 +1786,7 @@ fn render_struct( } w.write_str(")"); if let Some(g) = g { - write!(w, "{}", print_where_clause(g, cx, 0, false)); + write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline)); } // We only want a ";" when we are displaying a tuple struct, not a variant tuple struct. if structhead { @@ -1796,7 +1796,7 @@ fn render_struct( CtorKind::Const => { // Needed for PhantomData. if let Some(g) = g { - write!(w, "{}", print_where_clause(g, cx, 0, false)); + write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline)); } w.write_str(";"); }