Skip to content
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
28 changes: 24 additions & 4 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,22 @@ impl<T> TypedArena<T> {
available_bytes >= additional_bytes
}

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

Expand Down Expand Up @@ -208,7 +222,7 @@ impl<T> TypedArena<T> {
&self,
iter: impl IntoIterator<Item = Result<T, E>>,
) -> Result<&mut [T], E> {
// Despite the similarlty with `DroplessArena`, we cannot reuse their fast case. The reason
// Despite the similarity with `DroplessArena`, we cannot reuse their fast case. The reason
// is subtle: these arenas are reentrant. In other words, `iter` may very well be holding a
// reference to `self` and adding elements to the arena during iteration.
//
Expand All @@ -229,9 +243,15 @@ impl<T> TypedArena<T> {
}
// Move the content to the arena by copying and then forgetting it.
let len = vec.len();
let start_ptr = self.alloc_raw_slice(len);

// SAFETY: After allocating raw storage for exactly `len` values, we
// must fully initialize the storage without panicking, and we must
// also prevent the stale values in the vec from being dropped.
Ok(unsafe {
let start_ptr = self.alloc_raw_slice(len);
// Initialize the newly-allocated storage without panicking.
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
// Prevent the stale values in the vec from being dropped.
vec.set_len(0);
slice::from_raw_parts_mut(start_ptr, len)
})
Expand Down Expand Up @@ -584,7 +604,7 @@ impl DroplessArena {
&self,
iter: impl IntoIterator<Item = Result<T, E>>,
) -> Result<&mut [T], E> {
// Despite the similarlty with `alloc_from_iter`, we cannot reuse their fast case, as we
// Despite the similarity with `alloc_from_iter`, we cannot reuse their fast case, as we
// cannot know the minimum length of the iterator in this case.
assert!(size_of::<T>() != 0);

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1961,7 +1961,8 @@ impl<'a> State<'a> {
}

fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
self.print_name(lifetime.ident.name)
self.word(lifetime.ident.name.to_string());
self.ann_post(lifetime.ident)
}

fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) {
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,10 @@ trait UnusedDelimLint {

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

ExprKind::Range(_lhs, Some(rhs), _limits) => {
Expand Down
2 changes: 1 addition & 1 deletion tests/rustdoc-gui/globals.goml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ assert-window-property-false: {"searchIndex": null}
// Form input
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
call-function: ("perform-search", {"query": "Foo"})
assert-window-property-false: {"searchIndex": null}
wait-for-window-property-false: {"searchIndex": null}

// source sidebar
go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/hygiene/unpretty-debug-lifetimes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ check-pass
//@ compile-flags: -Zunpretty=expanded,hygiene

// Regression test for lifetime hygiene annotations in -Zunpretty=expanded,hygiene
// Previously, lifetimes were missing the #N syntax context suffix.

// Don't break whenever Symbol numbering changes
//@ normalize-stdout: "\d+#" -> "0#"

#![feature(decl_macro)]
#![feature(no_core)]
#![no_core]

macro lifetime_hygiene($f:ident<$a:lifetime>) {
fn $f<$a, 'a>() {}
}

lifetime_hygiene!(f<'a>);
31 changes: 31 additions & 0 deletions tests/ui/hygiene/unpretty-debug-lifetimes.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//@ check-pass
//@ compile-flags: -Zunpretty=expanded,hygiene

// Regression test for lifetime hygiene annotations in -Zunpretty=expanded,hygiene
// Previously, lifetimes were missing the #N syntax context suffix.

// Don't break whenever Symbol numbering changes
//@ normalize-stdout: "\d+#" -> "0#"

#![feature /* 0#0 */(decl_macro)]
#![feature /* 0#0 */(no_core)]
#![no_core /* 0#0 */]

macro lifetime_hygiene
/*
0#0
*/ {
($f:ident<$a:lifetime>) => { fn $f<$a, 'a>() {} }
}
fn f /* 0#0 */<'a /* 0#0 */, 'a /* 0#1 */>() {}


/*
Expansions:
crate0::{{expn0}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Root
crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "lifetime_hygiene")

SyntaxContexts:
#0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque)
#1: parent: #0, outer_mark: (crate0::{{expn1}}, Opaque)
*/
25 changes: 25 additions & 0 deletions tests/ui/lint/unused-parens-labeled-break-issue-143256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ check-pass
// testcase for https://github.com/rust-lang/rust/issues/143256

#![deny(unused_parens)]
#![allow(unreachable_code, unused_variables, dead_code)]

fn foo() {
let _x = || 'outer: loop {
let inner = 'inner: loop {
let i = Default::default();
// the parentheses here are necessary
if (break 'outer i) {
loop {
break 'inner 5i8;
}
} else if true {
break 'inner 6;
}
break 7;
};
break inner < 8;
};
}

fn main() {}
1 change: 1 addition & 0 deletions typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ unstalled = "unstalled" # short for un-stalled
#
# tidy-alphabetical-start
definitinon = "definition"
similarlty = "similarity"
# tidy-alphabetical-end

[default.extend-identifiers]
Expand Down
Loading