Skip to content

Commit e8423e6

Browse files
committed
Auto merge of #91033 - JohnTitor:rollup-sr9zg6o, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #89258 (Make char conversion functions unstably const) - #90578 (add const generics test) - #90633 (Refactor single variant `Candidate` enum into a struct) - #90800 (bootstap: create .cargo/config only if not present) - #90942 (windows: Return the "Not Found" error when a path is empty) - #90947 (Move some tests to more reasonable directories - 9.5) - #90961 (Suggest removal of arguments for unit variant, not replacement) - #90990 (Arenas cleanup) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ce3f3a5 + 1576a7c commit e8423e6

File tree

153 files changed

+331
-407
lines changed

Some content is hidden

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

153 files changed

+331
-407
lines changed

compiler/rustc_arena/src/lib.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<T> Default for TypedArena<T> {
111111
// alloc() will trigger a grow().
112112
ptr: Cell::new(ptr::null_mut()),
113113
end: Cell::new(ptr::null_mut()),
114-
chunks: RefCell::new(vec![]),
114+
chunks: Default::default(),
115115
_own: PhantomData,
116116
}
117117
}
@@ -325,13 +325,17 @@ unsafe impl<#[may_dangle] T> Drop for TypedArena<T> {
325325

326326
unsafe impl<T: Send> Send for TypedArena<T> {}
327327

328+
/// An arena that can hold objects of multiple different types that impl `Copy`
329+
/// and/or satisfy `!mem::needs_drop`.
328330
pub struct DroplessArena {
329331
/// A pointer to the start of the free space.
330332
start: Cell<*mut u8>,
331333

332334
/// A pointer to the end of free space.
333335
///
334-
/// The allocation proceeds from the end of the chunk towards the start.
336+
/// The allocation proceeds downwards from the end of the chunk towards the
337+
/// start. (This is slightly simpler and faster than allocating upwards,
338+
/// see <https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html>.)
335339
/// When this pointer crosses the start pointer, a new chunk is allocated.
336340
end: Cell<*mut u8>,
337341

@@ -516,10 +520,14 @@ impl DroplessArena {
516520
}
517521
}
518522

523+
// Declare an `Arena` containing one dropless arena and many typed arenas (the
524+
// types of the typed arenas are specified by the arguments). The dropless
525+
// arena will be used for any types that impl `Copy`, and also for any of the
526+
// specified types that satisfy `!mem::needs_drop`.
519527
#[rustc_macro_transparency = "semitransparent"]
520-
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
528+
pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
521529
#[derive(Default)]
522-
pub struct Arena<$tcx> {
530+
pub struct Arena<'tcx> {
523531
pub dropless: $crate::DroplessArena,
524532
$($name: $crate::TypedArena<$ty>,)*
525533
}
@@ -532,6 +540,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
532540
) -> &'a mut [Self];
533541
}
534542

543+
// Any type that impls `Copy` can be arena-allocated in the `DroplessArena`.
535544
impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T {
536545
#[inline]
537546
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
@@ -544,12 +553,11 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
544553
) -> &'a mut [Self] {
545554
arena.dropless.alloc_from_iter(iter)
546555
}
547-
548556
}
549557
$(
550-
impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty {
558+
impl<'tcx> ArenaAllocatable<'tcx, $ty> for $ty {
551559
#[inline]
552-
fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self {
560+
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
553561
if !::std::mem::needs_drop::<Self>() {
554562
arena.dropless.alloc(self)
555563
} else {
@@ -559,7 +567,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
559567

560568
#[inline]
561569
fn allocate_from_iter<'a>(
562-
arena: &'a Arena<$tcx>,
570+
arena: &'a Arena<'tcx>,
563571
iter: impl ::std::iter::IntoIterator<Item = Self>,
564572
) -> &'a mut [Self] {
565573
if !::std::mem::needs_drop::<Self>() {
@@ -577,6 +585,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
577585
value.allocate_on(self)
578586
}
579587

588+
// Any type that impls `Copy` can have slices be arena-allocated in the `DroplessArena`.
580589
#[inline]
581590
pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] {
582591
if value.is_empty() {

compiler/rustc_ast_lowering/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ mod item;
8484
mod pat;
8585
mod path;
8686

87-
rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx);
87+
rustc_hir::arena_types!(rustc_arena::declare_arena);
8888

8989
struct LoweringContext<'a, 'hir: 'a> {
9090
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.

compiler/rustc_const_eval/src/transform/promote_consts.rs

+82-101
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,8 @@ impl TempState {
9393
/// returned value in a promoted MIR, unless it's a subset
9494
/// of a larger candidate.
9595
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
96-
pub enum Candidate {
97-
/// Borrow of a constant temporary, candidate for lifetime extension.
98-
Ref(Location),
99-
}
100-
101-
impl Candidate {
102-
fn source_info(&self, body: &Body<'_>) -> SourceInfo {
103-
match self {
104-
Candidate::Ref(location) => *body.source_info(*location),
105-
}
106-
}
96+
pub struct Candidate {
97+
location: Location,
10798
}
10899

109100
struct Collector<'a, 'tcx> {
@@ -167,7 +158,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
167158

168159
match *rvalue {
169160
Rvalue::Ref(..) => {
170-
self.candidates.push(Candidate::Ref(location));
161+
self.candidates.push(Candidate { location });
171162
}
172163
_ => {}
173164
}
@@ -209,36 +200,33 @@ struct Unpromotable;
209200

210201
impl<'tcx> Validator<'_, 'tcx> {
211202
fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> {
212-
match candidate {
213-
Candidate::Ref(loc) => {
214-
let statement = &self.body[loc.block].statements[loc.statement_index];
215-
match &statement.kind {
216-
StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
217-
// We can only promote interior borrows of promotable temps (non-temps
218-
// don't get promoted anyway).
219-
self.validate_local(place.local)?;
220-
221-
// The reference operation itself must be promotable.
222-
// (Needs to come after `validate_local` to avoid ICEs.)
223-
self.validate_ref(*kind, place)?;
224-
225-
// We do not check all the projections (they do not get promoted anyway),
226-
// but we do stay away from promoting anything involving a dereference.
227-
if place.projection.contains(&ProjectionElem::Deref) {
228-
return Err(Unpromotable);
229-
}
203+
let loc = candidate.location;
204+
let statement = &self.body[loc.block].statements[loc.statement_index];
205+
match &statement.kind {
206+
StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
207+
// We can only promote interior borrows of promotable temps (non-temps
208+
// don't get promoted anyway).
209+
self.validate_local(place.local)?;
210+
211+
// The reference operation itself must be promotable.
212+
// (Needs to come after `validate_local` to avoid ICEs.)
213+
self.validate_ref(*kind, place)?;
230214

231-
// We cannot promote things that need dropping, since the promoted value
232-
// would not get dropped.
233-
if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
234-
return Err(Unpromotable);
235-
}
215+
// We do not check all the projections (they do not get promoted anyway),
216+
// but we do stay away from promoting anything involving a dereference.
217+
if place.projection.contains(&ProjectionElem::Deref) {
218+
return Err(Unpromotable);
219+
}
236220

237-
Ok(())
238-
}
239-
_ => bug!(),
221+
// We cannot promote things that need dropping, since the promoted value
222+
// would not get dropped.
223+
if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
224+
return Err(Unpromotable);
240225
}
226+
227+
Ok(())
241228
}
229+
_ => bug!(),
242230
}
243231
}
244232

@@ -871,58 +859,55 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
871859
}))
872860
};
873861
let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
874-
match candidate {
875-
Candidate::Ref(loc) => {
876-
let statement = &mut blocks[loc.block].statements[loc.statement_index];
877-
match statement.kind {
878-
StatementKind::Assign(box (
879-
_,
880-
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
881-
)) => {
882-
// Use the underlying local for this (necessarily interior) borrow.
883-
let ty = local_decls.local_decls()[place.local].ty;
884-
let span = statement.source_info.span;
885-
886-
let ref_ty = tcx.mk_ref(
887-
tcx.lifetimes.re_erased,
888-
ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
889-
);
890-
891-
*region = tcx.lifetimes.re_erased;
892-
893-
let mut projection = vec![PlaceElem::Deref];
894-
projection.extend(place.projection);
895-
place.projection = tcx.intern_place_elems(&projection);
896-
897-
// Create a temp to hold the promoted reference.
898-
// This is because `*r` requires `r` to be a local,
899-
// otherwise we would use the `promoted` directly.
900-
let mut promoted_ref = LocalDecl::new(ref_ty, span);
901-
promoted_ref.source_info = statement.source_info;
902-
let promoted_ref = local_decls.push(promoted_ref);
903-
assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
904-
905-
let promoted_ref_statement = Statement {
906-
source_info: statement.source_info,
907-
kind: StatementKind::Assign(Box::new((
908-
Place::from(promoted_ref),
909-
Rvalue::Use(promoted_operand(ref_ty, span)),
910-
))),
911-
};
912-
self.extra_statements.push((loc, promoted_ref_statement));
913-
914-
Rvalue::Ref(
915-
tcx.lifetimes.re_erased,
916-
borrow_kind,
917-
Place {
918-
local: mem::replace(&mut place.local, promoted_ref),
919-
projection: List::empty(),
920-
},
921-
)
922-
}
923-
_ => bug!(),
924-
}
862+
let loc = candidate.location;
863+
let statement = &mut blocks[loc.block].statements[loc.statement_index];
864+
match statement.kind {
865+
StatementKind::Assign(box (
866+
_,
867+
Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
868+
)) => {
869+
// Use the underlying local for this (necessarily interior) borrow.
870+
let ty = local_decls.local_decls()[place.local].ty;
871+
let span = statement.source_info.span;
872+
873+
let ref_ty = tcx.mk_ref(
874+
tcx.lifetimes.re_erased,
875+
ty::TypeAndMut { ty, mutbl: borrow_kind.to_mutbl_lossy() },
876+
);
877+
878+
*region = tcx.lifetimes.re_erased;
879+
880+
let mut projection = vec![PlaceElem::Deref];
881+
projection.extend(place.projection);
882+
place.projection = tcx.intern_place_elems(&projection);
883+
884+
// Create a temp to hold the promoted reference.
885+
// This is because `*r` requires `r` to be a local,
886+
// otherwise we would use the `promoted` directly.
887+
let mut promoted_ref = LocalDecl::new(ref_ty, span);
888+
promoted_ref.source_info = statement.source_info;
889+
let promoted_ref = local_decls.push(promoted_ref);
890+
assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
891+
892+
let promoted_ref_statement = Statement {
893+
source_info: statement.source_info,
894+
kind: StatementKind::Assign(Box::new((
895+
Place::from(promoted_ref),
896+
Rvalue::Use(promoted_operand(ref_ty, span)),
897+
))),
898+
};
899+
self.extra_statements.push((loc, promoted_ref_statement));
900+
901+
Rvalue::Ref(
902+
tcx.lifetimes.re_erased,
903+
borrow_kind,
904+
Place {
905+
local: mem::replace(&mut place.local, promoted_ref),
906+
projection: List::empty(),
907+
},
908+
)
925909
}
910+
_ => bug!(),
926911
}
927912
};
928913

@@ -964,25 +949,21 @@ pub fn promote_candidates<'tcx>(
964949

965950
let mut extra_statements = vec![];
966951
for candidate in candidates.into_iter().rev() {
967-
match candidate {
968-
Candidate::Ref(Location { block, statement_index }) => {
969-
if let StatementKind::Assign(box (place, _)) =
970-
&body[block].statements[statement_index].kind
971-
{
972-
if let Some(local) = place.as_local() {
973-
if temps[local] == TempState::PromotedOut {
974-
// Already promoted.
975-
continue;
976-
}
977-
}
952+
let Location { block, statement_index } = candidate.location;
953+
if let StatementKind::Assign(box (place, _)) = &body[block].statements[statement_index].kind
954+
{
955+
if let Some(local) = place.as_local() {
956+
if temps[local] == TempState::PromotedOut {
957+
// Already promoted.
958+
continue;
978959
}
979960
}
980961
}
981962

982963
// Declare return place local so that `mir::Body::new` doesn't complain.
983964
let initial_locals = iter::once(LocalDecl::new(tcx.types.never, body.span)).collect();
984965

985-
let mut scope = body.source_scopes[candidate.source_info(body).scope].clone();
966+
let mut scope = body.source_scopes[body.source_info(candidate.location).scope].clone();
986967
scope.parent_scope = None;
987968

988969
let promoted = Body::new(

0 commit comments

Comments
 (0)