Skip to content

Commit ef663a8

Browse files
committed
Auto merge of rust-lang#77372 - jonas-schievink:rollup-e5bdzga, r=jonas-schievink
Rollup of 12 pull requests Successful merges: - rust-lang#77037 (more tiny clippy cleanups) - rust-lang#77233 (BTreeMap: keep an eye out on the size of the main components) - rust-lang#77280 (Ensure that all LLVM components requested by tests are available on CI) - rust-lang#77284 (library: Forward compiler-builtins "mem" feature) - rust-lang#77296 (liveness: Use Option::None to represent absent live nodes) - rust-lang#77322 (Add unstable book docs for `-Zunsound-mir-opts`) - rust-lang#77328 (Use `rtassert!` instead of `assert!` from the child process after fork() in std::sys::unix::process::Command::spawn()) - rust-lang#77331 (Add test for async/await combined with const-generics.) - rust-lang#77338 (Fix typo in alloc vec comment) - rust-lang#77340 (Alloc vec use imported path) - rust-lang#77345 (Add test for issue rust-lang#74761) - rust-lang#77348 (Update books) Failed merges: r? `@ghost`
2 parents 867bd42 + 3624a90 commit ef663a8

File tree

17 files changed

+127
-54
lines changed

17 files changed

+127
-54
lines changed

compiler/rustc_mir/src/borrow_check/type_check/constraint_conversion.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
6262
// `self.constraints`, but we also want to be mutating
6363
// `self.member_constraints`. For now, just swap out the value
6464
// we want and replace at the end.
65-
let mut tmp =
66-
std::mem::replace(&mut self.constraints.member_constraints, Default::default());
65+
let mut tmp = std::mem::take(&mut self.constraints.member_constraints);
6766
for member_constraint in member_constraints {
6867
tmp.push_constraint(member_constraint, |r| self.to_region_vid(r));
6968
}

compiler/rustc_mir/src/transform/early_otherwise_branch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
9191
let not_equal_rvalue = Rvalue::BinaryOp(
9292
not_equal,
9393
Operand::Copy(Place::from(second_discriminant_temp)),
94-
Operand::Copy(Place::from(first_descriminant_place)),
94+
Operand::Copy(first_descriminant_place),
9595
);
9696
patch.add_statement(
9797
end_of_block_location,

compiler/rustc_passes/src/liveness.rs

+36-40
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@
6262
//! - `reader`: the `LiveNode` ID of some node which will read the value
6363
//! that `V` holds on entry to `N`. Formally: a node `M` such
6464
//! that there exists a path `P` from `N` to `M` where `P` does not
65-
//! write `V`. If the `reader` is `INVALID_NODE`, then the current
65+
//! write `V`. If the `reader` is `None`, then the current
6666
//! value will never be read (the variable is dead, essentially).
6767
//!
6868
//! - `writer`: the `LiveNode` ID of some node which will write the
6969
//! variable `V` and which is reachable from `N`. Formally: a node `M`
7070
//! such that there exists a path `P` from `N` to `M` and `M` writes
71-
//! `V`. If the `writer` is `INVALID_NODE`, then there is no writer
71+
//! `V`. If the `writer` is `None`, then there is no writer
7272
//! of `V` that follows `N`.
7373
//!
7474
//! - `used`: a boolean value indicating whether `V` is *used*. We
@@ -114,7 +114,6 @@ rustc_index::newtype_index! {
114114
rustc_index::newtype_index! {
115115
pub struct LiveNode {
116116
DEBUG_FORMAT = "ln({})",
117-
const INVALID_NODE = LiveNode::MAX_AS_U32,
118117
}
119118
}
120119

@@ -168,12 +167,6 @@ pub fn provide(providers: &mut Providers) {
168167
// variable must not be assigned if there is some successor
169168
// assignment. And so forth.
170169

171-
impl LiveNode {
172-
fn is_valid(self) -> bool {
173-
self != INVALID_NODE
174-
}
175-
}
176-
177170
struct CaptureInfo {
178171
ln: LiveNode,
179172
var_hid: HirId,
@@ -467,8 +460,8 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
467460

468461
#[derive(Clone, Copy)]
469462
struct RWU {
470-
reader: LiveNode,
471-
writer: LiveNode,
463+
reader: Option<LiveNode>,
464+
writer: Option<LiveNode>,
472465
used: bool,
473466
}
474467

@@ -490,10 +483,10 @@ struct RWUTable {
490483
unpacked_rwus: Vec<RWU>,
491484
}
492485

493-
// A constant representing `RWU { reader: INVALID_NODE; writer: INVALID_NODE; used: false }`.
486+
// A constant representing `RWU { reader: None; writer: None; used: false }`.
494487
const INV_INV_FALSE: u32 = u32::MAX;
495488

496-
// A constant representing `RWU { reader: INVALID_NODE; writer: INVALID_NODE; used: true }`.
489+
// A constant representing `RWU { reader: None; writer: None; used: true }`.
497490
const INV_INV_TRUE: u32 = u32::MAX - 1;
498491

499492
impl RWUTable {
@@ -504,24 +497,24 @@ impl RWUTable {
504497
fn get(&self, idx: usize) -> RWU {
505498
let packed_rwu = self.packed_rwus[idx];
506499
match packed_rwu {
507-
INV_INV_FALSE => RWU { reader: INVALID_NODE, writer: INVALID_NODE, used: false },
508-
INV_INV_TRUE => RWU { reader: INVALID_NODE, writer: INVALID_NODE, used: true },
500+
INV_INV_FALSE => RWU { reader: None, writer: None, used: false },
501+
INV_INV_TRUE => RWU { reader: None, writer: None, used: true },
509502
_ => self.unpacked_rwus[packed_rwu as usize],
510503
}
511504
}
512505

513-
fn get_reader(&self, idx: usize) -> LiveNode {
506+
fn get_reader(&self, idx: usize) -> Option<LiveNode> {
514507
let packed_rwu = self.packed_rwus[idx];
515508
match packed_rwu {
516-
INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE,
509+
INV_INV_FALSE | INV_INV_TRUE => None,
517510
_ => self.unpacked_rwus[packed_rwu as usize].reader,
518511
}
519512
}
520513

521-
fn get_writer(&self, idx: usize) -> LiveNode {
514+
fn get_writer(&self, idx: usize) -> Option<LiveNode> {
522515
let packed_rwu = self.packed_rwus[idx];
523516
match packed_rwu {
524-
INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE,
517+
INV_INV_FALSE | INV_INV_TRUE => None,
525518
_ => self.unpacked_rwus[packed_rwu as usize].writer,
526519
}
527520
}
@@ -541,7 +534,7 @@ impl RWUTable {
541534
}
542535

543536
fn assign_unpacked(&mut self, idx: usize, rwu: RWU) {
544-
if rwu.reader == INVALID_NODE && rwu.writer == INVALID_NODE {
537+
if rwu.reader == None && rwu.writer == None {
545538
// When we overwrite an indexing entry in `self.packed_rwus` with
546539
// `INV_INV_{TRUE,FALSE}` we don't remove the corresponding entry
547540
// from `self.unpacked_rwus`; it's not worth the effort, and we
@@ -570,7 +563,7 @@ struct Liveness<'a, 'tcx> {
570563
typeck_results: &'a ty::TypeckResults<'tcx>,
571564
param_env: ty::ParamEnv<'tcx>,
572565
upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
573-
successors: IndexVec<LiveNode, LiveNode>,
566+
successors: IndexVec<LiveNode, Option<LiveNode>>,
574567
rwu_table: RWUTable,
575568

576569
/// A live node representing a point of execution before closure entry &
@@ -606,7 +599,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
606599
typeck_results,
607600
param_env,
608601
upvars,
609-
successors: IndexVec::from_elem_n(INVALID_NODE, num_live_nodes),
602+
successors: IndexVec::from_elem_n(None, num_live_nodes),
610603
rwu_table: RWUTable::new(num_live_nodes * num_vars),
611604
closure_ln,
612605
exit_ln,
@@ -651,30 +644,33 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
651644
}
652645

653646
fn live_on_entry(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
654-
assert!(ln.is_valid());
655-
let reader = self.rwu_table.get_reader(self.idx(ln, var));
656-
if reader.is_valid() { Some(self.ir.lnks[reader]) } else { None }
647+
if let Some(reader) = self.rwu_table.get_reader(self.idx(ln, var)) {
648+
Some(self.ir.lnks[reader])
649+
} else {
650+
None
651+
}
657652
}
658653

659654
// Is this variable live on entry to any of its successor nodes?
660655
fn live_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
661-
let successor = self.successors[ln];
656+
let successor = self.successors[ln].unwrap();
662657
self.live_on_entry(successor, var)
663658
}
664659

665660
fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool {
666-
assert!(ln.is_valid());
667661
self.rwu_table.get_used(self.idx(ln, var))
668662
}
669663

670664
fn assigned_on_entry(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
671-
assert!(ln.is_valid());
672-
let writer = self.rwu_table.get_writer(self.idx(ln, var));
673-
if writer.is_valid() { Some(self.ir.lnks[writer]) } else { None }
665+
if let Some(writer) = self.rwu_table.get_writer(self.idx(ln, var)) {
666+
Some(self.ir.lnks[writer])
667+
} else {
668+
None
669+
}
674670
}
675671

676672
fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
677-
let successor = self.successors[ln];
673+
let successor = self.successors[ln].unwrap();
678674
self.assigned_on_entry(successor, var)
679675
}
680676

@@ -709,9 +705,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
709705
{
710706
let wr = &mut wr as &mut dyn Write;
711707
write!(wr, "[{:?} of kind {:?} reads", ln, self.ir.lnks[ln]);
712-
self.write_vars(wr, ln, |idx| self.rwu_table.get_reader(idx).is_valid());
708+
self.write_vars(wr, ln, |idx| self.rwu_table.get_reader(idx).is_some());
713709
write!(wr, " writes");
714-
self.write_vars(wr, ln, |idx| self.rwu_table.get_writer(idx).is_valid());
710+
self.write_vars(wr, ln, |idx| self.rwu_table.get_writer(idx).is_some());
715711
write!(wr, " uses");
716712
self.write_vars(wr, ln, |idx| self.rwu_table.get_used(idx));
717713

@@ -735,7 +731,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
735731
}
736732

737733
fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) {
738-
self.successors[ln] = succ_ln;
734+
self.successors[ln] = Some(succ_ln);
739735

740736
// It is not necessary to initialize the RWUs here because they are all
741737
// set to INV_INV_FALSE when they are created, and the sets only grow
@@ -744,7 +740,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
744740

745741
fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) {
746742
// more efficient version of init_empty() / merge_from_succ()
747-
self.successors[ln] = succ_ln;
743+
self.successors[ln] = Some(succ_ln);
748744

749745
self.indices2(ln, succ_ln, |this, idx, succ_idx| {
750746
this.rwu_table.copy_packed(idx, succ_idx);
@@ -768,12 +764,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
768764
let mut changed = false;
769765
let mut rwu = this.rwu_table.get(idx);
770766
let succ_rwu = this.rwu_table.get(succ_idx);
771-
if succ_rwu.reader.is_valid() && !rwu.reader.is_valid() {
767+
if succ_rwu.reader.is_some() && rwu.reader.is_none() {
772768
rwu.reader = succ_rwu.reader;
773769
changed = true
774770
}
775771

776-
if succ_rwu.writer.is_valid() && !rwu.writer.is_valid() {
772+
if succ_rwu.writer.is_some() && rwu.writer.is_none() {
777773
rwu.writer = succ_rwu.writer;
778774
changed = true
779775
}
@@ -817,14 +813,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
817813
let mut rwu = self.rwu_table.get(idx);
818814

819815
if (acc & ACC_WRITE) != 0 {
820-
rwu.reader = INVALID_NODE;
821-
rwu.writer = ln;
816+
rwu.reader = None;
817+
rwu.writer = Some(ln);
822818
}
823819

824820
// Important: if we both read/write, must do read second
825821
// or else the write will override.
826822
if (acc & ACC_READ) != 0 {
827-
rwu.reader = ln;
823+
rwu.reader = Some(ln);
828824
}
829825

830826
if (acc & ACC_USE) != 0 {

compiler/rustc_typeck/src/check/writeback.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7070
debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
7171
wbcx.typeck_results.used_trait_imports = used_trait_imports;
7272

73-
wbcx.typeck_results.closure_captures = mem::replace(
74-
&mut self.typeck_results.borrow_mut().closure_captures,
75-
Default::default(),
76-
);
73+
wbcx.typeck_results.closure_captures =
74+
mem::take(&mut self.typeck_results.borrow_mut().closure_captures);
7775

7876
if self.is_tainted_by_errors() {
7977
// FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted.

library/alloc/src/collections/btree/node/tests.rs

+9
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ fn test_splitpoint() {
2323
assert!(left_len + right_len == CAPACITY);
2424
}
2525
}
26+
27+
#[test]
28+
#[cfg(target_arch = "x86_64")]
29+
fn test_sizes() {
30+
assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16);
31+
assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 8 * 2);
32+
assert_eq!(core::mem::size_of::<InternalNode<(), ()>>(), 112);
33+
assert_eq!(core::mem::size_of::<InternalNode<i64, i64>>(), 112 + CAPACITY * 8 * 2);
34+
}

library/alloc/src/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2281,14 +2281,14 @@ where
22812281

22822282
// use try-fold since
22832283
// - it vectorizes better for some iterator adapters
2284-
// - unlike most internal iteration methods methods it only takes a &mut self
2284+
// - unlike most internal iteration methods, it only takes a &mut self
22852285
// - it lets us thread the write pointer through its innards and get it back in the end
22862286
let sink = InPlaceDrop { inner: dst_buf, dst: dst_buf };
22872287
let sink = iterator
22882288
.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(dst_end))
22892289
.unwrap();
22902290
// iteration succeeded, don't drop head
2291-
let dst = mem::ManuallyDrop::new(sink).dst;
2291+
let dst = ManuallyDrop::new(sink).dst;
22922292

22932293
let src = unsafe { iterator.as_inner().as_into_iter() };
22942294
// check if SourceIter contract was upheld

library/std/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ gimli-symbolize = []
5959
panic-unwind = ["panic_unwind"]
6060
profiler = ["profiler_builtins"]
6161
compiler-builtins-c = ["alloc/compiler-builtins-c"]
62+
compiler-builtins-mem = ["alloc/compiler-builtins-mem"]
6263
llvm-libunwind = ["unwind/llvm-libunwind"]
6364

6465
# Make panics and failed asserts immediately abort without formatting any message

library/std/src/sys/unix/process/process_unix.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl Command {
6767
// pipe I/O up to PIPE_BUF bytes should be atomic, and then
6868
// we want to be sure we *don't* run at_exit destructors as
6969
// we're being torn down regardless
70-
assert!(output.write(&bytes).is_ok());
70+
rtassert!(output.write(&bytes).is_ok());
7171
libc::_exit(1)
7272
}
7373
n => n,

library/test/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ proc_macro = { path = "../proc_macro" }
2525
default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"]
2626
backtrace = ["std/backtrace"]
2727
compiler-builtins-c = ["std/compiler-builtins-c"]
28+
compiler-builtins-mem = ["std/compiler-builtins-mem"]
2829
llvm-libunwind = ["std/llvm-libunwind"]
2930
panic-unwind = ["std/panic_unwind"]
3031
panic_immediate_abort = ["std/panic_immediate_abort"]

src/ci/run.sh

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]
104104
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-missing-tools"
105105
fi
106106

107+
export COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS=1
108+
107109
# Print the date from the local machine and the date from an external source to
108110
# check for clock drifts. An HTTP URL is used instead of HTTPS since on Azure
109111
# Pipelines it happened that the certificates were marked as expired.

src/doc/embedded-book

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# `unsound-mir-opts`
2+
3+
--------------------
4+
5+
The `-Zunsound-mir-opts` compiler flag enables [MIR optimization passes] which can cause unsound behavior.
6+
This flag should only be used by MIR optimization tests in the rustc test suite.
7+
8+
[MIR optimization passes]: https://rustc-dev-guide.rust-lang.org/mir/optimizations.html
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// edition:2018
2+
// check-pass
3+
// revisions: full min
4+
#![cfg_attr(full, feature(const_generics))]
5+
#![cfg_attr(full, allow(incomplete_features))]
6+
#![cfg_attr(min, feature(min_const_generics))]
7+
8+
const SIZE: usize = 16;
9+
10+
struct Bar<const H: usize> {}
11+
12+
struct Foo<const H: usize> {}
13+
14+
impl<const H: usize> Foo<H> {
15+
async fn biz(_: &[[u8; SIZE]]) -> Vec<()> {
16+
vec![]
17+
}
18+
19+
pub async fn baz(&self) -> Bar<H> {
20+
Self::biz(&vec![]).await;
21+
Bar {}
22+
}
23+
}
24+
25+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(member_constraints)]
2+
#![feature(type_alias_impl_trait)]
3+
4+
pub trait A {
5+
type B;
6+
fn f(&self) -> Self::B;
7+
}
8+
impl<'a, 'b> A for () {
9+
//~^ ERROR the lifetime parameter `'a` is not constrained
10+
//~| ERROR the lifetime parameter `'b` is not constrained
11+
type B = impl core::fmt::Debug;
12+
13+
fn f(&self) -> Self::B {}
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
2+
--> $DIR/issue-74761.rs:8:6
3+
|
4+
LL | impl<'a, 'b> A for () {
5+
| ^^ unconstrained lifetime parameter
6+
7+
error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
8+
--> $DIR/issue-74761.rs:8:10
9+
|
10+
LL | impl<'a, 'b> A for () {
11+
| ^^ unconstrained lifetime parameter
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0207`.

0 commit comments

Comments
 (0)