Skip to content

Commit

Permalink
Auto merge of rust-lang#138031 - workingjubilee:rollup-5bsotpz, r=wor…
Browse files Browse the repository at this point in the history
…kingjubilee

Rollup of 15 pull requests

Successful merges:

 - rust-lang#137829 (Stabilize [T]::split_off... methods)
 - rust-lang#137850 (Stabilize `box_uninit_write`)
 - rust-lang#137912 (Do not recover missing lifetime with random in-scope lifetime)
 - rust-lang#137913 (Allow struct field default values to reference struct's generics)
 - rust-lang#137923 (Simplify `<Postorder as Iterator>::size_hint`)
 - rust-lang#137949 (Update MSVC INSTALL.md instructions to recommend VS 2022 + recent Windows 10/11 SDK)
 - rust-lang#137963 (Add ``dyn`` keyword to `E0373` examples)
 - rust-lang#137975 (Remove unused `PpMode::needs_hir`)
 - rust-lang#137981 (rustdoc search: increase strictness of typechecking)
 - rust-lang#137986 (Fix some typos)
 - rust-lang#137991 (Add `avr-none` to SUMMARY.md and platform-support.md)
 - rust-lang#137993 (Remove obsolete comment from DeduceReadOnly)
 - rust-lang#137996 (Revert "compiler/rustc_data_structures/src/sync/worker_local.rs: delete "unsafe impl Sync"")
 - rust-lang#138019 (Pretty-print `#[deprecated]` attribute in HIR.)
 - rust-lang#138026 (Make CrateItem::body() function return an option)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 5, 2025
2 parents ac951d3 + 3065925 commit 4559163
Show file tree
Hide file tree
Showing 57 changed files with 426 additions and 400 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For submodules, changes need to be made against the repository corresponding the
submodule, and not the main `rust-lang/rust` repository.

For subtrees, prefer sending a PR against the subtree's repository if it does
not need to be made against the main `rust-lang/rust` repostory (e.g. a
not need to be made against the main `rust-lang/rust` repository (e.g. a
rustc-dev-guide change that does not accompany a compiler change).

## About the [rustc-dev-guide]
Expand Down
10 changes: 7 additions & 3 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,13 @@ itself back on after some time).

### MSVC

MSVC builds of Rust additionally require an installation of Visual Studio 2017
(or later) so `rustc` can use its linker. The simplest way is to get
[Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload.
MSVC builds of Rust additionally requires an installation of:

- Visual Studio 2022 (or later) build tools so `rustc` can use its linker. Older
Visual Studio versions such as 2019 *may* work but aren't actively tested.
- A recent Windows 10 or 11 SDK.

The simplest way is to get [Visual Studio], check the "C++ build tools".

[Visual Studio]: https://visualstudio.microsoft.com/downloads/

Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_data_structures/src/sync/worker_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ pub struct WorkerLocal<T> {
registry: Registry,
}

// This is safe because the `deref` call will return a reference to a `T` unique to each thread
// or it will panic for threads without an associated local. So there isn't a need for `T` to do
// it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
// can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
unsafe impl<T: Send> Sync for WorkerLocal<T> {}

impl<T> WorkerLocal<T> {
/// Creates a new worker local where the `initial` closure computes the
/// value this worker local should take for each thread in the registry.
Expand All @@ -132,11 +138,6 @@ impl<T> Deref for WorkerLocal<T> {
fn deref(&self) -> &T {
// This is safe because `verify` will only return values less than
// `self.registry.thread_limit` which is the size of the `self.locals` array.

// The `deref` call will return a reference to a `T` unique to each thread
// or it will panic for threads without an associated local. So there isn't a need for `T` to do
// it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
// can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
unsafe { &self.locals.get_unchecked(self.registry.id().verify()).0 }
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0373.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ A captured variable in a closure may not live long enough.
Erroneous code example:

```compile_fail,E0373
fn foo() -> Box<Fn(u32) -> u32> {
fn foo() -> Box<dyn Fn(u32) -> u32> {
let x = 0u32;
Box::new(|y| x + y)
}
Expand Down Expand Up @@ -42,7 +42,7 @@ This approach moves (or copies, where possible) data into the closure, rather
than taking references to it. For example:

```
fn foo() -> Box<Fn(u32) -> u32> {
fn foo() -> Box<dyn Fn(u32) -> u32> {
let x = 0u32;
Box::new(move |y| x + y)
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
Some(parent_did)
}
Node::TyPat(_) => Some(parent_did),
// Field default values inherit the ADT's generics.
Node::Field(_) => Some(parent_did),
_ => None,
}
}
Expand Down
74 changes: 74 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,80 @@ impl<'a> State<'a> {
));
self.hardbreak()
}
hir::Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => {
self.word("#[deprecated");

// There are three possible forms here:
// 1. a form with explicit components like
// `#[deprecated(since = "1.2.3", note = "some note", suggestion = "something")]`
// where each component may be present or absent.
// 2. `#[deprecated = "message"]`
// 3. `#[deprecated]`
//
// Let's figure out which we need.
// If there's a `since` or `suggestion` value, we're definitely in form 1.
if matches!(
deprecation.since,
rustc_attr_parsing::DeprecatedSince::RustcVersion(..)
| rustc_attr_parsing::DeprecatedSince::Future
| rustc_attr_parsing::DeprecatedSince::NonStandard(..)
) || deprecation.suggestion.is_some()
{
self.word("(");
let mut use_comma = false;

match &deprecation.since {
rustc_attr_parsing::DeprecatedSince::RustcVersion(rustc_version) => {
self.word("since = \"");
self.word(format!(
"{}.{}.{}",
rustc_version.major, rustc_version.minor, rustc_version.patch
));
self.word("\"");
use_comma = true;
}
rustc_attr_parsing::DeprecatedSince::Future => {
self.word("since = \"future\"");
use_comma = true;
}
rustc_attr_parsing::DeprecatedSince::NonStandard(symbol) => {
self.word("since = \"");
self.word(symbol.to_ident_string());
self.word("\"");
use_comma = true;
}
_ => {}
}

if let Some(note) = &deprecation.note {
if use_comma {
self.word(", ");
}
self.word("note = \"");
self.word(note.to_ident_string());
self.word("\"");
use_comma = true;
}

if let Some(suggestion) = &deprecation.suggestion {
if use_comma {
self.word(", ");
}
self.word("suggestion = \"");
self.word(suggestion.to_ident_string());
self.word("\"");
}
} else if let Some(note) = &deprecation.note {
// We're in form 2: `#[deprecated = "message"]`.
self.word(" = \"");
self.word(note.to_ident_string());
self.word("\"");
} else {
// We're in form 3: `#[deprecated]`. Nothing to do here.
}

self.word("]");
}
hir::Attribute::Parsed(pa) => {
self.word("#[attr=\"");
pa.print_attribute(self);
Expand Down
37 changes: 11 additions & 26 deletions compiler/rustc_middle/src/mir/traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ pub struct Preorder<'a, 'tcx> {
body: &'a Body<'tcx>,
visited: DenseBitSet<BasicBlock>,
worklist: Vec<BasicBlock>,
root_is_start_block: bool,
}

impl<'a, 'tcx> Preorder<'a, 'tcx> {
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
let worklist = vec![root];

Preorder {
body,
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
worklist,
root_is_start_block: root == START_BLOCK,
}
Preorder { body, visited: DenseBitSet::new_empty(body.basic_blocks.len()), worklist }
}
}

Expand Down Expand Up @@ -71,15 +65,11 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
}

fn size_hint(&self) -> (usize, Option<usize>) {
// All the blocks, minus the number of blocks we've visited.
let upper = self.body.basic_blocks.len() - self.visited.count();
// The worklist might be only things already visited.
let lower = 0;

let lower = if self.root_is_start_block {
// We will visit all remaining blocks exactly once.
upper
} else {
self.worklist.len()
};
// This is extremely loose, but it's not worth a popcnt loop to do better.
let upper = self.body.basic_blocks.len();

(lower, Some(upper))
}
Expand Down Expand Up @@ -108,7 +98,6 @@ pub struct Postorder<'a, 'tcx> {
basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
visited: DenseBitSet<BasicBlock>,
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
root_is_start_block: bool,
/// A non-empty `extra` allows for a precise calculation of the successors.
extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
}
Expand All @@ -123,7 +112,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
basic_blocks,
visited: DenseBitSet::new_empty(basic_blocks.len()),
visit_stack: Vec::new(),
root_is_start_block: root == START_BLOCK,
extra,
};

Expand Down Expand Up @@ -211,16 +199,13 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> {
}

fn size_hint(&self) -> (usize, Option<usize>) {
// All the blocks, minus the number of blocks we've visited.
let upper = self.basic_blocks.len() - self.visited.count();

let lower = if self.root_is_start_block {
// We will visit all remaining blocks exactly once.
upper
} else {
self.visit_stack.len()
};
// These bounds are not at all tight, but that's fine.
// It's not worth a popcnt loop in `DenseBitSet` to improve the upper,
// and in mono-reachable we can't be precise anyway.
// Leaning on amortized growth is fine.

let lower = self.visit_stack.len();
let upper = self.basic_blocks.len();
(lower, Some(upper))
}
}
Expand Down
29 changes: 0 additions & 29 deletions compiler/rustc_mir_transform/src/deduce_param_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,35 +80,6 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
// `f` passes. Note that function arguments are the only situation in which this problem can
// arise: every other use of `move` in MIR doesn't actually write to the value it moves
// from.
//
// Anyway, right now this situation doesn't actually arise in practice. Instead, the MIR for
// that function looks like this:
//
// fn f(_1: BigStruct) -> () {
// let mut _0: ();
// let mut _2: BigStruct;
// bb0: {
// _2 = move _1;
// _0 = g(move _2) -> bb1;
// }
// ...
// }
//
// Because of that extra move that MIR construction inserts, `x` (i.e. `_1`) can *in
// practice* safely be marked `readonly`.
//
// To handle the possibility that other optimizations (for example, destination propagation)
// might someday generate MIR like the first example above, we panic upon seeing an argument
// to *our* function that is directly moved into *another* function as an argument. Having
// eliminated that problematic case, we can safely treat moves as copies in this analysis.
//
// In the future, if MIR optimizations cause arguments of a caller to be directly moved into
// the argument of a callee, we can just add that argument to `mutated_args` instead of
// panicking.
//
// Note that, because the problematic MIR is never actually generated, we can't add a test
// case for this.

if let TerminatorKind::Call { ref args, .. } = terminator.kind {
for arg in args {
if let Operand::Move(place) = arg.node {
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct IsNeverPattern;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum AnonConstKind {
EnumDiscriminant,
FieldDefaultValue,
InlineConst,
ConstArg(IsRepeatExpr),
}
Expand Down Expand Up @@ -1406,7 +1407,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
visit_opt!(self, visit_ident, ident);
try_visit!(self.visit_ty(ty));
if let Some(v) = &default {
self.resolve_anon_const(v, AnonConstKind::ConstArg(IsRepeatExpr::No));
self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue);
}
}
}
Expand Down Expand Up @@ -4659,6 +4660,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
AnonConstKind::EnumDiscriminant => {
ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
}
AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
AnonConstKind::ConstArg(_) => {
if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg {
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3515,12 +3515,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}
}
}

// Record as using the suggested resolution.
let (_, (_, res)) = in_scope_lifetimes[0];
for &lt in &lifetime_refs {
self.r.lifetimes_res_map.insert(lt.id, res);
}
}
_ => {
let lifetime_spans: Vec<_> =
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2887,14 +2887,6 @@ impl PpMode {
| StableMir => true,
}
}
pub fn needs_hir(&self) -> bool {
use PpMode::*;
match *self {
Source(_) | AstTree | AstTreeExpanded => false,

Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | StableMir => true,
}
}

pub fn needs_analysis(&self) -> bool {
use PpMode::*;
Expand Down
21 changes: 16 additions & 5 deletions compiler/stable_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,21 @@ crate_def_with_ty! {
}

impl CrateItem {
/// This will return the body of an item.
///
/// This will panic if no body is available.
pub fn body(&self) -> mir::Body {
/// This will return the body of an item or panic if it's not available.
pub fn expect_body(&self) -> mir::Body {
with(|cx| cx.mir_body(self.0))
}

/// Return the body of an item if available.
pub fn body(&self) -> Option<mir::Body> {
with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
}

/// Check if a body is available for this item.
pub fn has_body(&self) -> bool {
with(|cx| cx.has_body(self.0))
}

pub fn span(&self) -> Span {
with(|cx| cx.span_of_an_item(self.0))
}
Expand All @@ -156,8 +164,11 @@ impl CrateItem {
with(|cx| cx.is_foreign_item(self.0))
}

/// Emit MIR for this item body.
pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
self.body().dump(w, &self.name())
self.body()
.ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
.dump(w, &self.name())
}
}

Expand Down
4 changes: 1 addition & 3 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -937,8 +937,6 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
/// # Examples
///
/// ```
/// #![feature(box_uninit_write)]
///
/// let big_box = Box::<[usize; 1024]>::new_uninit();
///
/// let mut array = [0; 1024];
Expand All @@ -954,7 +952,7 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
/// assert_eq!(*x, i);
/// }
/// ```
#[unstable(feature = "box_uninit_write", issue = "129397")]
#[stable(feature = "box_uninit_write", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
unsafe {
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
#![feature(assert_matches)]
#![feature(async_fn_traits)]
#![feature(async_iterator)]
#![feature(box_uninit_write)]
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(char_max_len)]
Expand Down
Loading

0 comments on commit 4559163

Please sign in to comment.