From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/drop/drop_order.rs | 64 ++++++++ src/test/ui/drop/dropck_legal_cycles.rs | 14 +- src/test/ui/drop/dynamic-drop-async.rs | 1 - src/test/ui/drop/dynamic-drop.rs | 1 - src/test/ui/drop/issue-100276.rs | 12 ++ src/test/ui/drop/issue-17718-const-destructors.rs | 10 ++ .../ui/drop/issue-23338-ensure-param-drop-order.rs | 162 +++++++++++++++++++++ src/test/ui/drop/issue-48962.rs | 34 +++++ src/test/ui/drop/repeat-drop-2.rs | 2 +- src/test/ui/drop/repeat-drop-2.stderr | 9 +- src/test/ui/drop/repeat-drop.rs | 3 - 11 files changed, 297 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/drop/issue-100276.rs create mode 100644 src/test/ui/drop/issue-17718-const-destructors.rs create mode 100644 src/test/ui/drop/issue-23338-ensure-param-drop-order.rs create mode 100644 src/test/ui/drop/issue-48962.rs (limited to 'src/test/ui/drop') diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs index e42150dcc..42385216a 100644 --- a/src/test/ui/drop/drop_order.rs +++ b/src/test/ui/drop/drop_order.rs @@ -1,4 +1,6 @@ // run-pass +// compile-flags: -Z validate-mir +#![feature(let_chains)] use std::cell::RefCell; use std::convert::TryInto; @@ -116,6 +118,58 @@ impl DropOrderCollector { } } + fn let_chain(&self) { + // take the "then" branch + if self.option_loud_drop(2).is_some() // 2 + && self.option_loud_drop(1).is_some() // 1 + && let Some(_d) = self.option_loud_drop(4) { // 4 + self.print(3); // 3 + } + + // take the "else" branch + if self.option_loud_drop(6).is_some() // 2 + && self.option_loud_drop(5).is_some() // 1 + && let None = self.option_loud_drop(8) { // 4 + unreachable!(); + } else { + self.print(7); // 3 + } + + // let exprs interspersed + if self.option_loud_drop(9).is_some() // 1 + && let Some(_d) = self.option_loud_drop(13) // 5 + && self.option_loud_drop(10).is_some() // 2 + && let Some(_e) = self.option_loud_drop(12) { // 4 + self.print(11); // 3 + } + + // let exprs first + if let Some(_d) = self.option_loud_drop(18) // 5 + && let Some(_e) = self.option_loud_drop(17) // 4 + && self.option_loud_drop(14).is_some() // 1 + && self.option_loud_drop(15).is_some() { // 2 + self.print(16); // 3 + } + + // let exprs last + if self.option_loud_drop(20).is_some() // 2 + && self.option_loud_drop(19).is_some() // 1 + && let Some(_d) = self.option_loud_drop(23) // 5 + && let Some(_e) = self.option_loud_drop(22) { // 4 + self.print(21); // 3 + } + } + + fn while_(&self) { + let mut v = self.option_loud_drop(4); + while let Some(_d) = v + && self.option_loud_drop(1).is_some() + && self.option_loud_drop(2).is_some() { + self.print(3); + v = None; + } + } + fn assert_sorted(self) { assert!( self.0 @@ -142,4 +196,14 @@ fn main() { let collector = DropOrderCollector::default(); collector.match_(); collector.assert_sorted(); + + println!("-- let chain --"); + let collector = DropOrderCollector::default(); + collector.let_chain(); + collector.assert_sorted(); + + println!("-- while --"); + let collector = DropOrderCollector::default(); + collector.while_(); + collector.assert_sorted(); } diff --git a/src/test/ui/drop/dropck_legal_cycles.rs b/src/test/ui/drop/dropck_legal_cycles.rs index 27a599315..6a0fe7784 100644 --- a/src/test/ui/drop/dropck_legal_cycles.rs +++ b/src/test/ui/drop/dropck_legal_cycles.rs @@ -1017,7 +1017,7 @@ impl<'a> Children<'a> for HM<'a> { where C: Context + PrePost, Self: Sized { if let Some(ref hm) = self.contents.get() { - for (k, v) in hm.iter().nth(index / 2) { + if let Some((k, v)) = hm.iter().nth(index / 2) { [k, v][index % 2].descend_into_self(context); } } @@ -1032,7 +1032,7 @@ impl<'a> Children<'a> for VD<'a> { where C: Context + PrePost, Self: Sized { if let Some(ref vd) = self.contents.get() { - for r in vd.iter().nth(index) { + if let Some(r) = vd.iter().nth(index) { r.descend_into_self(context); } } @@ -1047,7 +1047,7 @@ impl<'a> Children<'a> for VM<'a> { where C: Context + PrePost> { if let Some(ref vd) = self.contents.get() { - for (_idx, r) in vd.iter().nth(index) { + if let Some((_idx, r)) = vd.iter().nth(index) { r.descend_into_self(context); } } @@ -1062,7 +1062,7 @@ impl<'a> Children<'a> for LL<'a> { where C: Context + PrePost> { if let Some(ref ll) = self.contents.get() { - for r in ll.iter().nth(index) { + if let Some(r) = ll.iter().nth(index) { r.descend_into_self(context); } } @@ -1077,7 +1077,7 @@ impl<'a> Children<'a> for BH<'a> { where C: Context + PrePost> { if let Some(ref bh) = self.contents.get() { - for r in bh.iter().nth(index) { + if let Some(r) = bh.iter().nth(index) { r.descend_into_self(context); } } @@ -1092,7 +1092,7 @@ impl<'a> Children<'a> for BTM<'a> { where C: Context + PrePost> { if let Some(ref bh) = self.contents.get() { - for (k, v) in bh.iter().nth(index / 2) { + if let Some((k, v)) = bh.iter().nth(index / 2) { [k, v][index % 2].descend_into_self(context); } } @@ -1107,7 +1107,7 @@ impl<'a> Children<'a> for BTS<'a> { where C: Context + PrePost> { if let Some(ref bh) = self.contents.get() { - for r in bh.iter().nth(index) { + if let Some(r) = bh.iter().nth(index) { r.descend_into_self(context); } } diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index 13bd71ecb..8f1cc6691 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -6,7 +6,6 @@ // run-pass // needs-unwind // edition:2018 -// ignore-wasm32-bare compiled with panic=abort by default #![allow(unused)] diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index e70686774..9e51d3ada 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -1,6 +1,5 @@ // run-pass // needs-unwind -// ignore-wasm32-bare compiled with panic=abort by default #![feature(generators, generator_trait)] diff --git a/src/test/ui/drop/issue-100276.rs b/src/test/ui/drop/issue-100276.rs new file mode 100644 index 000000000..6401a8d14 --- /dev/null +++ b/src/test/ui/drop/issue-100276.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: -Z validate-mir +#![feature(let_chains)] + +fn let_chains(entry: std::io::Result) { + if let Ok(entry) = entry + && let Some(s) = entry.file_name().to_str() + && s.contains("") + {} +} + +fn main() {} diff --git a/src/test/ui/drop/issue-17718-const-destructors.rs b/src/test/ui/drop/issue-17718-const-destructors.rs new file mode 100644 index 000000000..c9a729c7b --- /dev/null +++ b/src/test/ui/drop/issue-17718-const-destructors.rs @@ -0,0 +1,10 @@ +// check-pass +#![allow(dead_code)] +struct A; +impl Drop for A { + fn drop(&mut self) {} +} + +const FOO: A = A; + +fn main() {} diff --git a/src/test/ui/drop/issue-23338-ensure-param-drop-order.rs b/src/test/ui/drop/issue-23338-ensure-param-drop-order.rs new file mode 100644 index 000000000..a99f260dd --- /dev/null +++ b/src/test/ui/drop/issue-23338-ensure-param-drop-order.rs @@ -0,0 +1,162 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// This test is ensuring that parameters are indeed dropped after +// temporaries in a fn body. + +use std::cell::RefCell; + +use self::d::D; + +pub fn main() { + let log = RefCell::new(vec![]); + d::println("created empty log"); + test(&log); + + assert_eq!(&log.borrow()[..], + [ + // created empty log + // +-- Make D(da_0, 0) + // | +-- Make D(de_1, 1) + // | | calling foo + // | | entered foo + // | | +-- Make D(de_2, 2) + // | | | +-- Make D(da_1, 3) + // | | | | +-- Make D(de_3, 4) + // | | | | | +-- Make D(de_4, 5) + 3, // | | | +-- Drop D(da_1, 3) + // | | | | | + 4, // | | | +-- Drop D(de_3, 4) + // | | | | + // | | | | eval tail of foo + // | | | +-- Make D(de_5, 6) + // | | | | +-- Make D(de_6, 7) + 5, // | | | | | +-- Drop D(de_4, 5) + // | | | | | + 2, // | | +-- Drop D(de_2, 2) + // | | | | + 6, // | | +-- Drop D(de_5, 6) + // | | | + 1, // | +-- Drop D(de_1, 1) + // | | + 0, // +-- Drop D(da_0, 0) + // | + // | result D(de_6, 7) + 7 // +-- Drop D(de_6, 7) + + ]); +} + +fn test<'a>(log: d::Log<'a>) { + let da = D::new("da", 0, log); + let de = D::new("de", 1, log); + d::println("calling foo"); + let result = foo(da, de); + d::println(&format!("result {}", result)); +} + +fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> { + d::println("entered foo"); + let de2 = de1.incr(); // creates D(de_2, 2) + let de4 = { + let _da1 = da0.incr(); // creates D(da_1, 3) + de2.incr().incr() // creates D(de_3, 4) and D(de_4, 5) + }; + d::println("eval tail of foo"); + de4.incr().incr() // creates D(de_5, 6) and D(de_6, 7) +} + +// This module provides simultaneous printouts of the dynamic extents +// of all of the D values, in addition to logging the order that each +// is dropped. + +const PREF_INDENT: u32 = 16; + +pub mod d { + #![allow(unused_parens)] + use std::fmt; + use std::mem; + use std::cell::RefCell; + + static mut counter: u32 = 0; + static mut trails: u64 = 0; + + pub type Log<'a> = &'a RefCell>; + + pub fn current_width() -> u32 { + unsafe { max_width() - trails.leading_zeros() } + } + + pub fn max_width() -> u32 { + unsafe { + (mem::size_of_val(&trails)*8) as u32 + } + } + + pub fn indent_println(my_trails: u32, s: &str) { + let mut indent: String = String::new(); + for i in 0..my_trails { + unsafe { + if trails & (1 << i) != 0 { + indent = indent + "| "; + } else { + indent = indent + " "; + } + } + } + println!("{}{}", indent, s); + } + + pub fn println(s: &str) { + indent_println(super::PREF_INDENT, s); + } + + fn first_avail() -> u32 { + unsafe { + for i in 0..64 { + if trails & (1 << i) == 0 { + return i; + } + } + } + panic!("exhausted trails"); + } + + pub struct D<'a> { + name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a> + } + + impl<'a> fmt::Display for D<'a> { + fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + write!(w, "D({}_{}, {})", self.name, self.i, self.uid) + } + } + + impl<'a> D<'a> { + pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> { + unsafe { + let trail = first_avail(); + let ctr = counter; + counter += 1; + trails |= (1 << trail); + let ret = D { + name: name, i: i, log: log, uid: ctr, trail: trail + }; + indent_println(trail, &format!("+-- Make {}", ret)); + ret + } + } + pub fn incr(&self) -> D<'a> { + D::new(self.name, self.i + 1, self.log) + } + } + + impl<'a> Drop for D<'a> { + fn drop(&mut self) { + unsafe { trails &= !(1 << self.trail); }; + self.log.borrow_mut().push(self.uid); + indent_println(self.trail, &format!("+-- Drop {}", self)); + indent_println(::PREF_INDENT, ""); + } + } +} diff --git a/src/test/ui/drop/issue-48962.rs b/src/test/ui/drop/issue-48962.rs new file mode 100644 index 000000000..80d815379 --- /dev/null +++ b/src/test/ui/drop/issue-48962.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(unused_must_use)] +// Test that we are able to reinitialize box with moved referent +static mut ORDER: [usize; 3] = [0, 0, 0]; +static mut INDEX: usize = 0; + +struct Dropee (usize); + +impl Drop for Dropee { + fn drop(&mut self) { + unsafe { + ORDER[INDEX] = self.0; + INDEX = INDEX + 1; + } + } +} + +fn add_sentintel() { + unsafe { + ORDER[INDEX] = 2; + INDEX = INDEX + 1; + } +} + +fn main() { + let mut x = Box::new(Dropee(1)); + *x; // move out from `*x` + add_sentintel(); + *x = Dropee(3); // re-initialize `*x` + {x}; // drop value + unsafe { + assert_eq!(ORDER, [1, 2, 3]); + } +} diff --git a/src/test/ui/drop/repeat-drop-2.rs b/src/test/ui/drop/repeat-drop-2.rs index 59d5ef202..3cfacea5e 100644 --- a/src/test/ui/drop/repeat-drop-2.rs +++ b/src/test/ui/drop/repeat-drop-2.rs @@ -5,7 +5,7 @@ fn borrowck_catch() { } const _: [String; 0] = [String::new(); 0]; -//~^ ERROR destructors cannot be evaluated at compile-time [E0493] +//~^ ERROR destructor of `String` cannot be evaluated at compile-time [E0493] fn must_be_init() { let x: u8; diff --git a/src/test/ui/drop/repeat-drop-2.stderr b/src/test/ui/drop/repeat-drop-2.stderr index 48fa2bfa9..7357551c4 100644 --- a/src/test/ui/drop/repeat-drop-2.stderr +++ b/src/test/ui/drop/repeat-drop-2.stderr @@ -8,13 +8,13 @@ LL | let _bar = foo; LL | let _baz = [foo; 0]; | ^^^ value used here after move -error[E0493]: destructors cannot be evaluated at compile-time +error[E0493]: destructor of `String` cannot be evaluated at compile-time --> $DIR/repeat-drop-2.rs:7:25 | LL | const _: [String; 0] = [String::new(); 0]; | -^^^^^^^^^^^^^---- | || - | |constants cannot evaluate destructors + | |the destructor for this type cannot be evaluated in constants | value is dropped here error[E0381]: used binding `x` isn't initialized @@ -24,6 +24,11 @@ LL | let x: u8; | - binding declared here but left uninitialized LL | let _ = [x; 0]; | ^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x: u8 = 0; + | +++ error: aborting due to 3 previous errors diff --git a/src/test/ui/drop/repeat-drop.rs b/src/test/ui/drop/repeat-drop.rs index a43612e5d..8fd46ecaf 100644 --- a/src/test/ui/drop/repeat-drop.rs +++ b/src/test/ui/drop/repeat-drop.rs @@ -1,8 +1,5 @@ // run-pass // needs-unwind -// ignore-wasm32-bare no unwinding panic -// ignore-avr no unwinding panic -// ignore-nvptx64 no unwinding panic static mut CHECK: usize = 0; -- cgit v1.2.3