From 79a22f4954704d65f8356be59c3d07851e31f074 Mon Sep 17 00:00:00 2001 From: Vidhan Bhatt Date: Fri, 5 May 2023 09:32:33 -0400 Subject: [PATCH 1/8] feat: merge functionality of `io::Sink` into `io::Empty` --- library/std/src/io/util.rs | 100 +++++++++++++++++++++++-------- library/std/src/io/util/tests.rs | 13 +++- 2 files changed, 87 insertions(+), 26 deletions(-) diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index f076ee0923c80..202c0a9a69cec 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -8,24 +8,41 @@ use crate::io::{ self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write, }; -/// A reader which is always at EOF. +/// `Empty` ignores any data written via [`Write`], and will always be empty +/// (returning zero bytes) when read via [`Read`]. /// -/// This struct is generally created by calling [`empty()`]. Please see -/// the documentation of [`empty()`] for more details. +/// This struct is generally created by calling [`empty()`]. Please +/// see the documentation of [`empty()`] for more details. #[stable(feature = "rust1", since = "1.0.0")] #[non_exhaustive] -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone, Debug, Default)] pub struct Empty; -/// Constructs a new handle to an empty reader. +/// Creates a value that is always at EOF for reads, and ignores all data written. /// -/// All reads from the returned reader will return [Ok]\(0). +/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`] +/// and the contents of the buffer will not be inspected. +/// +/// All calls to [`read`] from the returned reader will return [`Ok(0)`]. +/// +/// [`Ok(buf.len())`]: Ok +/// [`Ok(0)`]: Ok +/// +/// [`write`]: Write::write +/// [`read`]: Read::read /// /// # Examples /// -/// A slightly sad example of not reading anything into a buffer: +/// ```rust +/// use std::io::{self, Write}; /// +/// let buffer = vec![1, 2, 3, 5, 8]; +/// let num_bytes = io::empty().write(&buffer).unwrap(); +/// assert_eq!(num_bytes, 5); /// ``` +/// +/// +/// ```rust /// use std::io::{self, Read}; /// /// let mut buffer = String::new(); @@ -76,13 +93,6 @@ impl Seek for Empty { } } -#[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Empty { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Empty").finish_non_exhaustive() - } -} - impl SizeHint for Empty { #[inline] fn upper_bound(&self) -> Option { @@ -90,6 +100,54 @@ impl SizeHint for Empty { } } +#[stable(feature = "empty_write", since = "1.64.0")] +impl Write for Empty { + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + + #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + let total_len = bufs.iter().map(|b| b.len()).sum(); + Ok(total_len) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[stable(feature = "empty_write", since = "1.64.0")] +impl Write for &Empty { + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + + #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + let total_len = bufs.iter().map(|b| b.len()).sum(); + Ok(total_len) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } + + #[inline] + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + /// A reader which yields one byte over and over and over and over and over and... /// /// This struct is generally created by calling [`repeat()`]. Please @@ -182,19 +240,20 @@ impl fmt::Debug for Repeat { /// A writer which will move data into the void. /// -/// This struct is generally created by calling [`sink`]. Please +/// This struct is generally created by calling [`sink()`]. Please /// see the documentation of [`sink()`] for more details. #[stable(feature = "rust1", since = "1.0.0")] #[non_exhaustive] -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone, Debug, Default)] pub struct Sink; /// Creates an instance of a writer which will successfully consume all data. /// -/// All calls to [`write`] on the returned instance will return `Ok(buf.len())` +/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`] /// and the contents of the buffer will not be inspected. /// /// [`write`]: Write::write +/// [`Ok(buf.len())`]: Ok /// /// # Examples /// @@ -259,10 +318,3 @@ impl Write for &Sink { Ok(()) } } - -#[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Sink { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Sink").finish_non_exhaustive() - } -} diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index ce5e2c9da1dbf..2d0f97c74cf74 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -77,7 +77,7 @@ fn empty_reads() { assert_eq!(e.read(&mut []).unwrap(), 0); assert_eq!(e.read(&mut [0]).unwrap(), 0); assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0); - assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0); + assert_eq!(Read::by_ref(&mut e).read(&mut [0; 1024]).unwrap(), 0); let buf: &mut [MaybeUninit<_>] = &mut []; let mut buf: BorrowedBuf<'_> = buf.into(); @@ -99,7 +99,7 @@ fn empty_reads() { let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; let mut buf: BorrowedBuf<'_> = buf.into(); - e.by_ref().read_buf(buf.unfilled()).unwrap(); + Read::by_ref(&mut e).read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); assert_eq!(buf.init_len(), 0); } @@ -124,6 +124,15 @@ fn empty_seeks() { assert!(matches!(e.seek(SeekFrom::Current(i64::MAX)), Ok(0))); } +#[test] +fn empty_sinks() { + let mut e = empty(); + assert_eq!(e.write(&[]).unwrap(), 0); + assert_eq!(e.write(&[0]).unwrap(), 1); + assert_eq!(e.write(&[0; 1024]).unwrap(), 1024); + assert_eq!(Write::by_ref(&mut e).write(&[0; 1024]).unwrap(), 1024); +} + #[test] fn repeat_repeats() { let mut r = repeat(4); From 3e07965244623ea709b842381f475178cf49879a Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 23 Sep 2022 17:52:31 +0200 Subject: [PATCH 2/8] const stabilize `NonNull::as_ref` --- library/core/src/ptr/non_null.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index b492d2f07bc13..ebed58ccf0389 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -367,13 +367,14 @@ impl NonNull { /// /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] - #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] + #[rustc_const_stable(feature = "const_nonnull_as_ref", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline(always)] pub const unsafe fn as_ref<'a>(&self) -> &'a T { // SAFETY: the caller must guarantee that `self` meets all the // requirements for a reference. - unsafe { &*self.as_ptr() } + // `cast_const` avoids a mutable raw pointer deref. + unsafe { &*self.as_ptr().cast_const() } } /// Returns a unique reference to the value. If the value may be uninitialized, [`as_uninit_mut`] From 855b8b82a5859a5bd50a59757b2ddacf779784e0 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 23 Sep 2022 17:52:53 +0200 Subject: [PATCH 3/8] add tests for const `NonNull::as_ref` --- tests/ui/consts/const-eval/nonnull_as_ref.rs | 8 ++++++++ tests/ui/consts/const-eval/nonnull_as_ref_ub.rs | 6 ++++++ .../consts/const-eval/nonnull_as_ref_ub.stderr | 16 ++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/ui/consts/const-eval/nonnull_as_ref.rs create mode 100644 tests/ui/consts/const-eval/nonnull_as_ref_ub.rs create mode 100644 tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr diff --git a/tests/ui/consts/const-eval/nonnull_as_ref.rs b/tests/ui/consts/const-eval/nonnull_as_ref.rs new file mode 100644 index 0000000000000..eb4683e2c3088 --- /dev/null +++ b/tests/ui/consts/const-eval/nonnull_as_ref.rs @@ -0,0 +1,8 @@ +// check-pass + +use std::ptr::NonNull; + +const NON_NULL: NonNull = unsafe { NonNull::new_unchecked((&42u8 as *const u8).cast_mut()) }; +const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() }); + +fn main() {} diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs b/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs new file mode 100644 index 0000000000000..3b48e972923d8 --- /dev/null +++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.rs @@ -0,0 +1,6 @@ +use std::ptr::NonNull; + +const NON_NULL: NonNull = unsafe { NonNull::dangling() }; +const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() }); + +fn main() {} diff --git a/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr new file mode 100644 index 0000000000000..de93cb0c3ca6a --- /dev/null +++ b/tests/ui/consts/const-eval/nonnull_as_ref_ub.stderr @@ -0,0 +1,16 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + | + = note: dereferencing pointer failed: 0x1[noalloc] is a dangling pointer (it has no provenance) + | +note: inside `NonNull::::as_ref::<'_>` + --> $SRC_DIR/core/src/ptr/non_null.rs:LL:COL +note: inside `_` + --> $DIR/nonnull_as_ref_ub.rs:4:39 + | +LL | const _: () = assert!(42 == *unsafe { NON_NULL.as_ref() }); + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. From 08dc6769228457200937dd182efe16e36c963c57 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 27 Jul 2023 13:59:17 +0300 Subject: [PATCH 4/8] support `--stage` for `x clean` Signed-off-by: ozkanonur --- src/bootstrap/flags.rs | 4 ++++ src/etc/completions/x.py.fish | 4 ++-- src/etc/completions/x.py.ps1 | 4 ++-- src/etc/completions/x.py.sh | 10 +++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index d67aafff841f4..c46d2422d178d 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -366,7 +366,11 @@ pub enum Subcommand { /// Clean out build directories Clean { #[arg(long)] + /// Clean the entire build directory (not used by default) all: bool, + #[arg(long, value_name = "N")] + /// Clean a specific stage (specified by ) without touching other artifacts. By default, every stage is cleaned if this option is not used. + stage: Option, }, /// Build distribution artifacts Dist, diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 9f65f1eeeb7e5..32689c2ac7865 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -305,6 +305,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l json-output -d 'use m complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build' complete -c x.py -n "__fish_seen_subcommand_from bench" -s h -l help -d 'Print help' +complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'Clean a specific stage (specified by ) without touching other artifacts. By default, every stage is cleaned if this option is not used' -r complete -c x.py -n "__fish_seen_subcommand_from clean" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from clean" -l build -d 'build target of the stage0 compiler' -r -f @@ -313,7 +314,6 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l target -d 'target tar complete -c x.py -n "__fish_seen_subcommand_from clean" -l exclude -d 'build paths to exclude' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" -complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)" @@ -327,7 +327,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-use -d ' complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l set -d 'override options in config.toml' -r -f -complete -c x.py -n "__fish_seen_subcommand_from clean" -l all +complete -c x.py -n "__fish_seen_subcommand_from clean" -l all -d 'Clean the entire build directory (not used by default)' complete -c x.py -n "__fish_seen_subcommand_from clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_seen_subcommand_from clean" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_seen_subcommand_from clean" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index 569c186555cc2..421e7b6f8c538 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -391,6 +391,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { break } 'x.py;clean' { + [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'Clean a specific stage (specified by ) without touching other artifacts. By default, every stage is cleaned if this option is not used') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') @@ -399,7 +400,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') - [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout') @@ -414,7 +414,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build') [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml') - [CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'all') + [CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'Clean the entire build directory (not used by default)') [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index 322afdb28835f..efce2758b920b 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -489,12 +489,16 @@ _x.py() { return 0 ;; x.py__clean) - opts="-v -i -j -h --all --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in + --stage) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --config) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -527,10 +531,6 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --stage) - COMPREPLY=("${cur}") - return 0 - ;; --keep-stage) COMPREPLY=("${cur}") return 0 From 0ea852f2adfe2e23721ee9f72ecc15344d02ef36 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 27 Jul 2023 13:59:52 +0300 Subject: [PATCH 5/8] remove stage-specific artifacts when --stage is specified Signed-off-by: ozkanonur --- src/bootstrap/clean.rs | 84 +++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index ea8334eaeb6f4..7389816b44c78 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -26,10 +26,15 @@ impl Step for CleanAll { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let Subcommand::Clean { all, .. } = builder.config.cmd else { + let Subcommand::Clean { all, stage } = builder.config.cmd else { unreachable!("wrong subcommand?") }; - clean_default(builder.build, all) + + if all && stage.is_some() { + panic!("--all and --stage can't be used at the same time for `x clean`"); + } + + clean(builder.build, all, stage) } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -86,35 +91,70 @@ clean_crate_tree! { Std, Mode::Std, "sysroot"; } -fn clean_default(build: &Build, all: bool) { +fn clean(build: &Build, all: bool, stage: Option) { if build.config.dry_run() { return; } rm_rf("tmp".as_ref()); + // Clean the entire build directory if all { rm_rf(&build.out); - } else { - rm_rf(&build.out.join("tmp")); - rm_rf(&build.out.join("dist")); - rm_rf(&build.out.join("bootstrap")); - rm_rf(&build.out.join("rustfmt.stamp")); - - for host in &build.hosts { - let entries = match build.out.join(host.triple).read_dir() { - Ok(iter) => iter, - Err(_) => continue, - }; - - for entry in entries { - let entry = t!(entry); - if entry.file_name().to_str() == Some("llvm") { - continue; - } - let path = t!(entry.path().canonicalize()); - rm_rf(&path); + return; + } + + // Clean the target stage artifacts + if let Some(stage) = stage { + clean_specific_stage(build, stage); + return; + } + + // Follow the default behaviour + clean_default(build); +} + +fn clean_specific_stage(build: &Build, stage: u32) { + for host in &build.hosts { + let entries = match build.out.join(host.triple).read_dir() { + Ok(iter) => iter, + Err(_) => continue, + }; + + for entry in entries { + let entry = t!(entry); + let stage_prefix = format!("stage{}", stage); + + // if current entry is not related with the target stage, continue + if !entry.file_name().to_str().unwrap_or("").contains(&stage_prefix) { + continue; + } + + let path = t!(entry.path().canonicalize()); + rm_rf(&path); + } + } +} + +fn clean_default(build: &Build) { + rm_rf(&build.out.join("tmp")); + rm_rf(&build.out.join("dist")); + rm_rf(&build.out.join("bootstrap")); + rm_rf(&build.out.join("rustfmt.stamp")); + + for host in &build.hosts { + let entries = match build.out.join(host.triple).read_dir() { + Ok(iter) => iter, + Err(_) => continue, + }; + + for entry in entries { + let entry = t!(entry); + if entry.file_name().to_str() == Some("llvm") { + continue; } + let path = t!(entry.path().canonicalize()); + rm_rf(&path); } } } From 8203d1ddf6e6185e54dc56abddfb84c5101e2378 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Sun, 30 Jul 2023 14:00:18 +0300 Subject: [PATCH 6/8] Weaken unnameable_types lint --- compiler/rustc_privacy/src/lib.rs | 6 +----- tests/ui/privacy/unnameable_types.rs | 4 ++-- tests/ui/privacy/unnameable_types.stderr | 14 +------------- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e2827252509db..5fa780a372b72 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1941,7 +1941,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { let reexported_at_vis = effective_vis.at_level(Level::Reexported); let reachable_at_vis = effective_vis.at_level(Level::Reachable); - if reexported_at_vis != reachable_at_vis { + if reachable_at_vis.is_public() && reexported_at_vis != reachable_at_vis { let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); let span = self.tcx.def_span(def_id.to_def_id()); self.tcx.emit_spanned_lint( @@ -1973,10 +1973,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true), }; - if is_assoc_ty { - self.check_unnameable(def_id, self.get(def_id)); - } - check.in_assoc_ty = is_assoc_ty; check.generics().predicates(); if check_ty { diff --git a/tests/ui/privacy/unnameable_types.rs b/tests/ui/privacy/unnameable_types.rs index eae20dd9df374..46e249152594b 100644 --- a/tests/ui/privacy/unnameable_types.rs +++ b/tests/ui/privacy/unnameable_types.rs @@ -11,12 +11,12 @@ mod m { pub trait PubTr { //~ ERROR trait `PubTr` is reachable but cannot be named const C : i32 = 0; - type Alias; //~ ERROR associated type `PubTr::Alias` is reachable but cannot be named + type Alias; fn f() {} } impl PubTr for PubStruct { - type Alias = i32; //~ ERROR associated type `::Alias` is reachable but cannot be named + type Alias = i32; fn f() {} } } diff --git a/tests/ui/privacy/unnameable_types.stderr b/tests/ui/privacy/unnameable_types.stderr index 25eb5c9434a8f..904127525758f 100644 --- a/tests/ui/privacy/unnameable_types.stderr +++ b/tests/ui/privacy/unnameable_types.stderr @@ -22,17 +22,5 @@ error: trait `PubTr` is reachable but cannot be named LL | pub trait PubTr { | ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` -error: associated type `PubTr::Alias` is reachable but cannot be named - --> $DIR/unnameable_types.rs:14:9 - | -LL | type Alias; - | ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` - -error: associated type `::Alias` is reachable but cannot be named - --> $DIR/unnameable_types.rs:19:9 - | -LL | type Alias = i32; - | ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors From 8ea7e45e44b6bc6437932415a3e0f54caad890b6 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 30 Jul 2023 16:42:16 +0200 Subject: [PATCH 7/8] Fix invalid suggestion for mismatched types in closure arguments The invalid suggestion came from a wrongly created span in `rustc_parse' for closure arguments that didn't have a type specified. Specifically, the span in this case was the last token span, but in the case of tuples, the span represented the last parenthesis instead of the whole tuple, which is fixed by taking the more accurate span of the pattern. --- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- .../ui/impl-trait/hidden-type-is-opaque-2.rs | 6 ++- .../impl-trait/hidden-type-is-opaque-2.stderr | 24 ++++++++-- .../ui/mismatched_types/closure-ref-114180.rs | 8 ++++ .../closure-ref-114180.stderr | 22 ++++++++++ .../ref-pat-suggestions.stderr | 44 +++++++++---------- 7 files changed, 78 insertions(+), 30 deletions(-) create mode 100644 tests/ui/mismatched_types/closure-ref-114180.rs create mode 100644 tests/ui/mismatched_types/closure-ref-114180.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 4d236a86dda1f..d8eb8c71b5ea3 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -755,7 +755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match binding_parent { // Check that there is explicit type (ie this is not a closure param with inferred type) // so we don't suggest moving something to the type that does not exist - hir::Node::Param(hir::Param { ty_span, .. }) if binding.span != *ty_span => { + hir::Node::Param(hir::Param { ty_span, pat, .. }) if pat.span != *ty_span => { err.multipart_suggestion_verbose( format!("to take parameter `{binding}` by reference, move `&{mutability}` to the type"), vec![ diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b54cb8c5a0c10..634e2720b16ac 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2342,7 +2342,7 @@ impl<'a> Parser<'a> { let ty = if this.eat(&token::Colon) { this.parse_ty()? } else { - this.mk_ty(this.prev_token.span, TyKind::Infer) + this.mk_ty(pat.span, TyKind::Infer) }; Ok(( diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.rs b/tests/ui/impl-trait/hidden-type-is-opaque-2.rs index 970d84120e07e..212e7b1080216 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.rs +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.rs @@ -6,7 +6,8 @@ fn reify_as() -> Thunk Continuation> { Thunk::new(|mut cont| { - cont.reify_as(); //~ ERROR type annotations needed + //~^ ERROR type annotations needed + cont.reify_as(); cont }) } @@ -15,7 +16,8 @@ type Tait = impl FnOnce(Continuation) -> Continuation; fn reify_as_tait() -> Thunk { Thunk::new(|mut cont| { - cont.reify_as(); //~ ERROR type annotations needed + //~^ ERROR type annotations needed + cont.reify_as(); cont }) } diff --git a/tests/ui/impl-trait/hidden-type-is-opaque-2.stderr b/tests/ui/impl-trait/hidden-type-is-opaque-2.stderr index 957052feba95b..39bf22142326a 100644 --- a/tests/ui/impl-trait/hidden-type-is-opaque-2.stderr +++ b/tests/ui/impl-trait/hidden-type-is-opaque-2.stderr @@ -1,14 +1,30 @@ error[E0282]: type annotations needed - --> $DIR/hidden-type-is-opaque-2.rs:9:9 + --> $DIR/hidden-type-is-opaque-2.rs:8:17 | +LL | Thunk::new(|mut cont| { + | ^^^^^^^^ +LL | LL | cont.reify_as(); - | ^^^^ cannot infer type + | ---- type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | Thunk::new(|mut cont: /* Type */| { + | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/hidden-type-is-opaque-2.rs:18:9 + --> $DIR/hidden-type-is-opaque-2.rs:18:17 | +LL | Thunk::new(|mut cont| { + | ^^^^^^^^ +LL | LL | cont.reify_as(); - | ^^^^ cannot infer type + | ---- type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | Thunk::new(|mut cont: /* Type */| { + | ++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/mismatched_types/closure-ref-114180.rs b/tests/ui/mismatched_types/closure-ref-114180.rs new file mode 100644 index 0000000000000..d84bdbedaf650 --- /dev/null +++ b/tests/ui/mismatched_types/closure-ref-114180.rs @@ -0,0 +1,8 @@ +// check-fail + +fn main() { + let mut v = vec![(1,)]; + let compare = |(a,), (e,)| todo!(); + v.sort_by(compare); + //~^ ERROR type mismatch in closure arguments +} diff --git a/tests/ui/mismatched_types/closure-ref-114180.stderr b/tests/ui/mismatched_types/closure-ref-114180.stderr new file mode 100644 index 0000000000000..8a146d784e297 --- /dev/null +++ b/tests/ui/mismatched_types/closure-ref-114180.stderr @@ -0,0 +1,22 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-ref-114180.rs:6:15 + | +LL | let compare = |(a,), (e,)| todo!(); + | ------------ found signature defined here +LL | v.sort_by(compare); + | ------- ^^^^^^^ expected due to this + | | + | required by a bound introduced by this call + | + = note: expected closure signature `for<'a, 'b> fn(&'a ({integer},), &'b ({integer},)) -> _` + found closure signature `fn((_,), (_,)) -> _` +note: required by a bound in `slice::::sort_by` + --> $SRC_DIR/alloc/src/slice.rs:LL:COL +help: consider adjusting the signature so it borrows its arguments + | +LL | let compare = |&(a,), &(e,)| todo!(); + | + + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0631`. diff --git a/tests/ui/mismatched_types/ref-pat-suggestions.stderr b/tests/ui/mismatched_types/ref-pat-suggestions.stderr index 62824004db5bf..148ed00b01d14 100644 --- a/tests/ui/mismatched_types/ref-pat-suggestions.stderr +++ b/tests/ui/mismatched_types/ref-pat-suggestions.stderr @@ -103,10 +103,10 @@ error[E0308]: mismatched types --> $DIR/ref-pat-suggestions.rs:11:23 | LL | let _: fn(u32) = |&_a| (); - | ^-- - | || - | |expected due to this + | ^^^ + | | | expected `u32`, found `&_` + | expected due to this | = note: expected type `u32` found reference `&_` @@ -120,10 +120,10 @@ error[E0308]: mismatched types --> $DIR/ref-pat-suggestions.rs:12:23 | LL | let _: fn(u32) = |&mut _a| (); - | ^^^^^-- - | | | - | | expected due to this + | ^^^^^^^ + | | | expected `u32`, found `&mut _` + | expected due to this | = note: expected type `u32` found mutable reference `&mut _` @@ -142,10 +142,10 @@ error[E0308]: mismatched types --> $DIR/ref-pat-suggestions.rs:13:25 | LL | let _: fn(&u32) = |&&_a| (); - | ^-- - | || - | |expected due to this - | expected `u32`, found `&_` + | -^^^ + | || + | |expected `u32`, found `&_` + | expected due to this | = note: expected type `u32` found reference `&_` @@ -159,10 +159,10 @@ error[E0308]: mismatched types --> $DIR/ref-pat-suggestions.rs:14:33 | LL | let _: fn(&mut u32) = |&mut &_a| (); - | ^-- - | || - | |expected due to this - | expected `u32`, found `&_` + | -----^^^ + | | | + | | expected `u32`, found `&_` + | expected due to this | = note: expected type `u32` found reference `&_` @@ -176,10 +176,10 @@ error[E0308]: mismatched types --> $DIR/ref-pat-suggestions.rs:15:25 | LL | let _: fn(&u32) = |&&mut _a| (); - | ^^^^^-- - | | | - | | expected due to this - | expected `u32`, found `&mut _` + | -^^^^^^^ + | || + | |expected `u32`, found `&mut _` + | expected due to this | = note: expected type `u32` found mutable reference `&mut _` @@ -193,10 +193,10 @@ error[E0308]: mismatched types --> $DIR/ref-pat-suggestions.rs:16:33 | LL | let _: fn(&mut u32) = |&mut &mut _a| (); - | ^^^^^-- - | | | - | | expected due to this - | expected `u32`, found `&mut _` + | -----^^^^^^^ + | | | + | | expected `u32`, found `&mut _` + | expected due to this | = note: expected type `u32` found mutable reference `&mut _` From a3838780f21b56377f1002476b17c6d91070cbfc Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 30 Jul 2023 15:37:39 +0000 Subject: [PATCH 8/8] Simplify `Span::can_be_used_for_suggestions` a little tiny bit --- compiler/rustc_span/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ecaa82874a3ca..fbd9bf0552850 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -605,7 +605,7 @@ impl Span { // FIXME: If this span comes from a `derive` macro but it points at code the user wrote, // the callsite span and the span will be pointing at different places. It also means that // we can safely provide suggestions on this span. - || (matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _)) + || (self.in_derive_expansion() && self.parent_callsite().map(|p| (p.lo(), p.hi())) != Some((self.lo(), self.hi()))) }