Skip to content

Commit 92324ee

Browse files
committed
Auto merge of #151837 - JonathanBrouwer:rollup-qIYP0mi, r=JonathanBrouwer
Rollup of 4 pull requests Successful merges: - #151808 (Document a safety condition for `TypedArena::alloc_raw_slice`) - #151811 (Fix false positive in unused_parens caused by break) - #151817 (Fix missing syntax context in lifetime hygiene debug output) - #151836 (Fix flakyness issue with `tests/rustdoc-gui/globals.goml` test)
2 parents 842bd5b + 9a357bb commit 92324ee

8 files changed

Lines changed: 106 additions & 7 deletions

File tree

compiler/rustc_arena/src/lib.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,22 @@ impl<T> TypedArena<T> {
172172
available_bytes >= additional_bytes
173173
}
174174

175+
/// Allocates storage for `len >= 1` values in this arena, and returns a
176+
/// raw pointer to the first value's storage.
177+
///
178+
/// # Safety
179+
///
180+
/// Caller must initialize each of the `len` slots to a droppable value
181+
/// before the arena is dropped.
182+
///
183+
/// In practice, this typically means that the caller must be able to
184+
/// raw-copy `len` already-initialized values into the slice without any
185+
/// possibility of panicking.
186+
///
187+
/// FIXME(Zalathar): This is *very* fragile; perhaps we need a different
188+
/// approach to arena-allocating slices of droppable values.
175189
#[inline]
176-
fn alloc_raw_slice(&self, len: usize) -> *mut T {
190+
unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T {
177191
assert!(size_of::<T>() != 0);
178192
assert!(len != 0);
179193

@@ -208,7 +222,7 @@ impl<T> TypedArena<T> {
208222
&self,
209223
iter: impl IntoIterator<Item = Result<T, E>>,
210224
) -> Result<&mut [T], E> {
211-
// Despite the similarlty with `DroplessArena`, we cannot reuse their fast case. The reason
225+
// Despite the similarity with `DroplessArena`, we cannot reuse their fast case. The reason
212226
// is subtle: these arenas are reentrant. In other words, `iter` may very well be holding a
213227
// reference to `self` and adding elements to the arena during iteration.
214228
//
@@ -229,9 +243,15 @@ impl<T> TypedArena<T> {
229243
}
230244
// Move the content to the arena by copying and then forgetting it.
231245
let len = vec.len();
232-
let start_ptr = self.alloc_raw_slice(len);
246+
247+
// SAFETY: After allocating raw storage for exactly `len` values, we
248+
// must fully initialize the storage without panicking, and we must
249+
// also prevent the stale values in the vec from being dropped.
233250
Ok(unsafe {
251+
let start_ptr = self.alloc_raw_slice(len);
252+
// Initialize the newly-allocated storage without panicking.
234253
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
254+
// Prevent the stale values in the vec from being dropped.
235255
vec.set_len(0);
236256
slice::from_raw_parts_mut(start_ptr, len)
237257
})
@@ -584,7 +604,7 @@ impl DroplessArena {
584604
&self,
585605
iter: impl IntoIterator<Item = Result<T, E>>,
586606
) -> Result<&mut [T], E> {
587-
// Despite the similarlty with `alloc_from_iter`, we cannot reuse their fast case, as we
607+
// Despite the similarity with `alloc_from_iter`, we cannot reuse their fast case, as we
588608
// cannot know the minimum length of the iterator in this case.
589609
assert!(size_of::<T>() != 0);
590610

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,8 @@ impl<'a> State<'a> {
19611961
}
19621962

19631963
fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
1964-
self.print_name(lifetime.ident.name)
1964+
self.word(lifetime.ident.name.to_string());
1965+
self.ann_post(lifetime.ident)
19651966
}
19661967

19671968
fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) {

compiler/rustc_lint/src/unused.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,10 @@ trait UnusedDelimLint {
805805

806806
ExprKind::Break(_label, None) => return false,
807807
ExprKind::Break(_label, Some(break_expr)) => {
808-
return matches!(break_expr.kind, ExprKind::Block(..));
808+
// `if (break 'label i) { ... }` removing parens would make `i { ... }`
809+
// be parsed as a struct literal, so keep parentheses if the break value
810+
// ends with a path (which could be mistaken for a struct name).
811+
return matches!(break_expr.kind, ExprKind::Block(..) | ExprKind::Path(..));
809812
}
810813

811814
ExprKind::Range(_lhs, Some(rhs), _limits) => {

tests/rustdoc-gui/globals.goml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ assert-window-property-false: {"searchIndex": null}
1111
// Form input
1212
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
1313
call-function: ("perform-search", {"query": "Foo"})
14-
assert-window-property-false: {"searchIndex": null}
14+
wait-for-window-property-false: {"searchIndex": null}
1515

1616
// source sidebar
1717
go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-pass
2+
//@ compile-flags: -Zunpretty=expanded,hygiene
3+
4+
// Regression test for lifetime hygiene annotations in -Zunpretty=expanded,hygiene
5+
// Previously, lifetimes were missing the #N syntax context suffix.
6+
7+
// Don't break whenever Symbol numbering changes
8+
//@ normalize-stdout: "\d+#" -> "0#"
9+
10+
#![feature(decl_macro)]
11+
#![feature(no_core)]
12+
#![no_core]
13+
14+
macro lifetime_hygiene($f:ident<$a:lifetime>) {
15+
fn $f<$a, 'a>() {}
16+
}
17+
18+
lifetime_hygiene!(f<'a>);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//@ check-pass
2+
//@ compile-flags: -Zunpretty=expanded,hygiene
3+
4+
// Regression test for lifetime hygiene annotations in -Zunpretty=expanded,hygiene
5+
// Previously, lifetimes were missing the #N syntax context suffix.
6+
7+
// Don't break whenever Symbol numbering changes
8+
//@ normalize-stdout: "\d+#" -> "0#"
9+
10+
#![feature /* 0#0 */(decl_macro)]
11+
#![feature /* 0#0 */(no_core)]
12+
#![no_core /* 0#0 */]
13+
14+
macro lifetime_hygiene
15+
/*
16+
0#0
17+
*/ {
18+
($f:ident<$a:lifetime>) => { fn $f<$a, 'a>() {} }
19+
}
20+
fn f /* 0#0 */<'a /* 0#0 */, 'a /* 0#1 */>() {}
21+
22+
23+
/*
24+
Expansions:
25+
crate0::{{expn0}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
26+
crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "lifetime_hygiene")
27+
28+
SyntaxContexts:
29+
#0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque)
30+
#1: parent: #0, outer_mark: (crate0::{{expn1}}, Opaque)
31+
*/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//@ check-pass
2+
// testcase for https://github.com/rust-lang/rust/issues/143256
3+
4+
#![deny(unused_parens)]
5+
#![allow(unreachable_code, unused_variables, dead_code)]
6+
7+
fn foo() {
8+
let _x = || 'outer: loop {
9+
let inner = 'inner: loop {
10+
let i = Default::default();
11+
// the parentheses here are necessary
12+
if (break 'outer i) {
13+
loop {
14+
break 'inner 5i8;
15+
}
16+
} else if true {
17+
break 'inner 6;
18+
}
19+
break 7;
20+
};
21+
break inner < 8;
22+
};
23+
}
24+
25+
fn main() {}

typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ unstalled = "unstalled" # short for un-stalled
4646
#
4747
# tidy-alphabetical-start
4848
definitinon = "definition"
49+
similarlty = "similarity"
4950
# tidy-alphabetical-end
5051

5152
[default.extend-identifiers]

0 commit comments

Comments
 (0)