Skip to content

Commit 4559163

Browse files
committed
Auto merge of #138031 - workingjubilee:rollup-5bsotpz, r=workingjubilee
Rollup of 15 pull requests Successful merges: - #137829 (Stabilize [T]::split_off... methods) - #137850 (Stabilize `box_uninit_write`) - #137912 (Do not recover missing lifetime with random in-scope lifetime) - #137913 (Allow struct field default values to reference struct's generics) - #137923 (Simplify `<Postorder as Iterator>::size_hint`) - #137949 (Update MSVC INSTALL.md instructions to recommend VS 2022 + recent Windows 10/11 SDK) - #137963 (Add ``dyn`` keyword to `E0373` examples) - #137975 (Remove unused `PpMode::needs_hir`) - #137981 (rustdoc search: increase strictness of typechecking) - #137986 (Fix some typos) - #137991 (Add `avr-none` to SUMMARY.md and platform-support.md) - #137993 (Remove obsolete comment from DeduceReadOnly) - #137996 (Revert "compiler/rustc_data_structures/src/sync/worker_local.rs: delete "unsafe impl Sync"") - #138019 (Pretty-print `#[deprecated]` attribute in HIR.) - #138026 (Make CrateItem::body() function return an option) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ac951d3 + 3065925 commit 4559163

File tree

57 files changed

+426
-400
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+426
-400
lines changed

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ For submodules, changes need to be made against the repository corresponding the
1818
submodule, and not the main `rust-lang/rust` repository.
1919

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

2424
## About the [rustc-dev-guide]

INSTALL.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,13 @@ itself back on after some time).
210210

211211
### MSVC
212212

213-
MSVC builds of Rust additionally require an installation of Visual Studio 2017
214-
(or later) so `rustc` can use its linker. The simplest way is to get
215-
[Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload.
213+
MSVC builds of Rust additionally requires an installation of:
214+
215+
- Visual Studio 2022 (or later) build tools so `rustc` can use its linker. Older
216+
Visual Studio versions such as 2019 *may* work but aren't actively tested.
217+
- A recent Windows 10 or 11 SDK.
218+
219+
The simplest way is to get [Visual Studio], check the "C++ build tools".
216220

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

compiler/rustc_data_structures/src/sync/worker_local.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ pub struct WorkerLocal<T> {
106106
registry: Registry,
107107
}
108108

109+
// This is safe because the `deref` call will return a reference to a `T` unique to each thread
110+
// or it will panic for threads without an associated local. So there isn't a need for `T` to do
111+
// it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
112+
// can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
113+
unsafe impl<T: Send> Sync for WorkerLocal<T> {}
114+
109115
impl<T> WorkerLocal<T> {
110116
/// Creates a new worker local where the `initial` closure computes the
111117
/// value this worker local should take for each thread in the registry.
@@ -132,11 +138,6 @@ impl<T> Deref for WorkerLocal<T> {
132138
fn deref(&self) -> &T {
133139
// This is safe because `verify` will only return values less than
134140
// `self.registry.thread_limit` which is the size of the `self.locals` array.
135-
136-
// The `deref` call will return a reference to a `T` unique to each thread
137-
// or it will panic for threads without an associated local. So there isn't a need for `T` to do
138-
// it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
139-
// can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
140141
unsafe { &self.locals.get_unchecked(self.registry.id().verify()).0 }
141142
}
142143
}

compiler/rustc_error_codes/src/error_codes/E0373.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ A captured variable in a closure may not live long enough.
33
Erroneous code example:
44

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

4444
```
45-
fn foo() -> Box<Fn(u32) -> u32> {
45+
fn foo() -> Box<dyn Fn(u32) -> u32> {
4646
let x = 0u32;
4747
Box::new(move |y| x + y)
4848
}

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+2
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
187187
Some(parent_did)
188188
}
189189
Node::TyPat(_) => Some(parent_did),
190+
// Field default values inherit the ADT's generics.
191+
Node::Field(_) => Some(parent_did),
190192
_ => None,
191193
}
192194
}

compiler/rustc_hir_pretty/src/lib.rs

+74
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,80 @@ impl<'a> State<'a> {
117117
));
118118
self.hardbreak()
119119
}
120+
hir::Attribute::Parsed(AttributeKind::Deprecation { deprecation, .. }) => {
121+
self.word("#[deprecated");
122+
123+
// There are three possible forms here:
124+
// 1. a form with explicit components like
125+
// `#[deprecated(since = "1.2.3", note = "some note", suggestion = "something")]`
126+
// where each component may be present or absent.
127+
// 2. `#[deprecated = "message"]`
128+
// 3. `#[deprecated]`
129+
//
130+
// Let's figure out which we need.
131+
// If there's a `since` or `suggestion` value, we're definitely in form 1.
132+
if matches!(
133+
deprecation.since,
134+
rustc_attr_parsing::DeprecatedSince::RustcVersion(..)
135+
| rustc_attr_parsing::DeprecatedSince::Future
136+
| rustc_attr_parsing::DeprecatedSince::NonStandard(..)
137+
) || deprecation.suggestion.is_some()
138+
{
139+
self.word("(");
140+
let mut use_comma = false;
141+
142+
match &deprecation.since {
143+
rustc_attr_parsing::DeprecatedSince::RustcVersion(rustc_version) => {
144+
self.word("since = \"");
145+
self.word(format!(
146+
"{}.{}.{}",
147+
rustc_version.major, rustc_version.minor, rustc_version.patch
148+
));
149+
self.word("\"");
150+
use_comma = true;
151+
}
152+
rustc_attr_parsing::DeprecatedSince::Future => {
153+
self.word("since = \"future\"");
154+
use_comma = true;
155+
}
156+
rustc_attr_parsing::DeprecatedSince::NonStandard(symbol) => {
157+
self.word("since = \"");
158+
self.word(symbol.to_ident_string());
159+
self.word("\"");
160+
use_comma = true;
161+
}
162+
_ => {}
163+
}
164+
165+
if let Some(note) = &deprecation.note {
166+
if use_comma {
167+
self.word(", ");
168+
}
169+
self.word("note = \"");
170+
self.word(note.to_ident_string());
171+
self.word("\"");
172+
use_comma = true;
173+
}
174+
175+
if let Some(suggestion) = &deprecation.suggestion {
176+
if use_comma {
177+
self.word(", ");
178+
}
179+
self.word("suggestion = \"");
180+
self.word(suggestion.to_ident_string());
181+
self.word("\"");
182+
}
183+
} else if let Some(note) = &deprecation.note {
184+
// We're in form 2: `#[deprecated = "message"]`.
185+
self.word(" = \"");
186+
self.word(note.to_ident_string());
187+
self.word("\"");
188+
} else {
189+
// We're in form 3: `#[deprecated]`. Nothing to do here.
190+
}
191+
192+
self.word("]");
193+
}
120194
hir::Attribute::Parsed(pa) => {
121195
self.word("#[attr=\"");
122196
pa.print_attribute(self);

compiler/rustc_middle/src/mir/traversal.rs

+11-26
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,13 @@ pub struct Preorder<'a, 'tcx> {
2323
body: &'a Body<'tcx>,
2424
visited: DenseBitSet<BasicBlock>,
2525
worklist: Vec<BasicBlock>,
26-
root_is_start_block: bool,
2726
}
2827

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

33-
Preorder {
34-
body,
35-
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
36-
worklist,
37-
root_is_start_block: root == START_BLOCK,
38-
}
32+
Preorder { body, visited: DenseBitSet::new_empty(body.basic_blocks.len()), worklist }
3933
}
4034
}
4135

@@ -71,15 +65,11 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
7165
}
7266

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

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

8474
(lower, Some(upper))
8575
}
@@ -108,7 +98,6 @@ pub struct Postorder<'a, 'tcx> {
10898
basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
10999
visited: DenseBitSet<BasicBlock>,
110100
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
111-
root_is_start_block: bool,
112101
/// A non-empty `extra` allows for a precise calculation of the successors.
113102
extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
114103
}
@@ -123,7 +112,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
123112
basic_blocks,
124113
visited: DenseBitSet::new_empty(basic_blocks.len()),
125114
visit_stack: Vec::new(),
126-
root_is_start_block: root == START_BLOCK,
127115
extra,
128116
};
129117

@@ -211,16 +199,13 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> {
211199
}
212200

213201
fn size_hint(&self) -> (usize, Option<usize>) {
214-
// All the blocks, minus the number of blocks we've visited.
215-
let upper = self.basic_blocks.len() - self.visited.count();
216-
217-
let lower = if self.root_is_start_block {
218-
// We will visit all remaining blocks exactly once.
219-
upper
220-
} else {
221-
self.visit_stack.len()
222-
};
202+
// These bounds are not at all tight, but that's fine.
203+
// It's not worth a popcnt loop in `DenseBitSet` to improve the upper,
204+
// and in mono-reachable we can't be precise anyway.
205+
// Leaning on amortized growth is fine.
223206

207+
let lower = self.visit_stack.len();
208+
let upper = self.basic_blocks.len();
224209
(lower, Some(upper))
225210
}
226211
}

compiler/rustc_mir_transform/src/deduce_param_attrs.rs

-29
Original file line numberDiff line numberDiff line change
@@ -80,35 +80,6 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
8080
// `f` passes. Note that function arguments are the only situation in which this problem can
8181
// arise: every other use of `move` in MIR doesn't actually write to the value it moves
8282
// from.
83-
//
84-
// Anyway, right now this situation doesn't actually arise in practice. Instead, the MIR for
85-
// that function looks like this:
86-
//
87-
// fn f(_1: BigStruct) -> () {
88-
// let mut _0: ();
89-
// let mut _2: BigStruct;
90-
// bb0: {
91-
// _2 = move _1;
92-
// _0 = g(move _2) -> bb1;
93-
// }
94-
// ...
95-
// }
96-
//
97-
// Because of that extra move that MIR construction inserts, `x` (i.e. `_1`) can *in
98-
// practice* safely be marked `readonly`.
99-
//
100-
// To handle the possibility that other optimizations (for example, destination propagation)
101-
// might someday generate MIR like the first example above, we panic upon seeing an argument
102-
// to *our* function that is directly moved into *another* function as an argument. Having
103-
// eliminated that problematic case, we can safely treat moves as copies in this analysis.
104-
//
105-
// In the future, if MIR optimizations cause arguments of a caller to be directly moved into
106-
// the argument of a callee, we can just add that argument to `mutated_args` instead of
107-
// panicking.
108-
//
109-
// Note that, because the problematic MIR is never actually generated, we can't add a test
110-
// case for this.
111-
11283
if let TerminatorKind::Call { ref args, .. } = terminator.kind {
11384
for arg in args {
11485
if let Operand::Move(place) = arg.node {

compiler/rustc_resolve/src/late.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct IsNeverPattern;
7878
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
7979
enum AnonConstKind {
8080
EnumDiscriminant,
81+
FieldDefaultValue,
8182
InlineConst,
8283
ConstArg(IsRepeatExpr),
8384
}
@@ -1406,7 +1407,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
14061407
visit_opt!(self, visit_ident, ident);
14071408
try_visit!(self.visit_ty(ty));
14081409
if let Some(v) = &default {
1409-
self.resolve_anon_const(v, AnonConstKind::ConstArg(IsRepeatExpr::No));
1410+
self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue);
14101411
}
14111412
}
14121413
}
@@ -4659,6 +4660,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46594660
AnonConstKind::EnumDiscriminant => {
46604661
ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
46614662
}
4663+
AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
46624664
AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
46634665
AnonConstKind::ConstArg(_) => {
46644666
if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg {

compiler/rustc_resolve/src/late/diagnostics.rs

-6
Original file line numberDiff line numberDiff line change
@@ -3515,12 +3515,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
35153515
}
35163516
}
35173517
}
3518-
3519-
// Record as using the suggested resolution.
3520-
let (_, (_, res)) = in_scope_lifetimes[0];
3521-
for &lt in &lifetime_refs {
3522-
self.r.lifetimes_res_map.insert(lt.id, res);
3523-
}
35243518
}
35253519
_ => {
35263520
let lifetime_spans: Vec<_> =

compiler/rustc_session/src/config.rs

-8
Original file line numberDiff line numberDiff line change
@@ -2887,14 +2887,6 @@ impl PpMode {
28872887
| StableMir => true,
28882888
}
28892889
}
2890-
pub fn needs_hir(&self) -> bool {
2891-
use PpMode::*;
2892-
match *self {
2893-
Source(_) | AstTree | AstTreeExpanded => false,
2894-
2895-
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | StableMir => true,
2896-
}
2897-
}
28982890

28992891
pub fn needs_analysis(&self) -> bool {
29002892
use PpMode::*;

compiler/stable_mir/src/lib.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,21 @@ crate_def_with_ty! {
129129
}
130130

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

137+
/// Return the body of an item if available.
138+
pub fn body(&self) -> Option<mir::Body> {
139+
with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
140+
}
141+
142+
/// Check if a body is available for this item.
143+
pub fn has_body(&self) -> bool {
144+
with(|cx| cx.has_body(self.0))
145+
}
146+
139147
pub fn span(&self) -> Span {
140148
with(|cx| cx.span_of_an_item(self.0))
141149
}
@@ -156,8 +164,11 @@ impl CrateItem {
156164
with(|cx| cx.is_foreign_item(self.0))
157165
}
158166

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

library/alloc/src/boxed.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -937,8 +937,6 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
937937
/// # Examples
938938
///
939939
/// ```
940-
/// #![feature(box_uninit_write)]
941-
///
942940
/// let big_box = Box::<[usize; 1024]>::new_uninit();
943941
///
944942
/// let mut array = [0; 1024];
@@ -954,7 +952,7 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
954952
/// assert_eq!(*x, i);
955953
/// }
956954
/// ```
957-
#[unstable(feature = "box_uninit_write", issue = "129397")]
955+
#[stable(feature = "box_uninit_write", since = "CURRENT_RUSTC_VERSION")]
958956
#[inline]
959957
pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
960958
unsafe {

library/alloc/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@
102102
#![feature(assert_matches)]
103103
#![feature(async_fn_traits)]
104104
#![feature(async_iterator)]
105-
#![feature(box_uninit_write)]
106105
#![feature(bstr)]
107106
#![feature(bstr_internals)]
108107
#![feature(char_max_len)]

0 commit comments

Comments
 (0)