Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #114261

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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![
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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((
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())))
}

Expand Down
5 changes: 3 additions & 2 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,14 @@ impl<T: ?Sized> NonNull<T> {
///
/// [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`]
Expand Down
100 changes: 76 additions & 24 deletions library/std/src/io/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <code>[Ok]\(0)</code>.
/// 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();
Expand Down Expand Up @@ -76,20 +93,61 @@ 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<usize> {
Some(0)
}
}

#[stable(feature = "empty_write", since = "1.64.0")]
impl Write for Empty {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Ok(buf.len())
}

#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
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<usize> {
Ok(buf.len())
}

#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
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
Expand Down Expand Up @@ -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
///
Expand Down Expand Up @@ -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()
}
}
13 changes: 11 additions & 2 deletions library/std/src/io/util/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,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();
Expand All @@ -40,7 +40,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);
}
Expand All @@ -65,6 +65,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);
Expand Down
84 changes: 62 additions & 22 deletions src/bootstrap/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<'_> {
Expand Down Expand Up @@ -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<u32>) {
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);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <N>) without touching other artifacts. By default, every stage is cleaned if this option is not used.
stage: Option<u32>,
},
/// Build distribution artifacts
Dist,
Expand Down
4 changes: 2 additions & 2 deletions src/etc/completions/x.py.fish
Original file line number Diff line number Diff line change
Expand Up @@ -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 <N>) 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
Expand All @@ -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)"
Expand All @@ -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'
Expand Down
Loading