Auto merge of #43216 - steveklabnik:rollup, r=steveklabnik
Rollup of 7 pull requests - Successful merges: #42926, #43125, #43157, #43167, #43187, #43203, #43204 - Failed merges:
This commit is contained in:
commit
ab91c70cc6
12
.mailmap
12
.mailmap
@ -6,6 +6,7 @@
|
||||
#
|
||||
|
||||
Aaron Todd <github@opprobrio.us>
|
||||
Aaron Power <theaaronepower@gmail.com>
|
||||
Abhishek Chanda <abhishek.becs@gmail.com> Abhishek Chanda <abhishek@cloudscaling.com>
|
||||
Adolfo Ochagavía <aochagavia92@gmail.com>
|
||||
Adrien Tétar <adri-from-59@hotmail.fr>
|
||||
@ -56,6 +57,7 @@ Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net>
|
||||
Cyryl Płotnicki <cyplo@cyplo.net>
|
||||
Damien Schoof <damien.schoof@gmail.com>
|
||||
Daniel Ramos <dan@daramos.com>
|
||||
Daniel J Rollins <drollins@financialforce.com>
|
||||
David Klein <david.klein@baesystemsdetica.com>
|
||||
David Manescu <david.manescu@gmail.com> <dman2626@uni.sydney.edu.au>
|
||||
David Ross <daboross@daboross.net>
|
||||
@ -63,11 +65,12 @@ Derek Chiang <derekchiang93@gmail.com> Derek Chiang (Enchi Jiang) <derekchiang93
|
||||
Diggory Hardy <diggory.hardy@gmail.com> Diggory Hardy <github@dhardy.name>
|
||||
Dylan Braithwaite <dylanbraithwaite1@gmail.com> <mail@dylanb.me>
|
||||
Dzmitry Malyshau <kvarkus@gmail.com>
|
||||
E. Dunham <edunham@mozilla.com> edunham <edunham@mozilla.com>
|
||||
Eduardo Bautista <me@eduardobautista.com> <=>
|
||||
Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com>
|
||||
Eduard-Mihai Burtescu <edy.burt@gmail.com>
|
||||
Elliott Slaughter <elliottslaughter@gmail.com> <eslaughter@mozilla.com>
|
||||
Elly Fong-Jones <elly@leptoquark.net>
|
||||
Emily Dunham <edunham@mozilla.com> edunham <edunham@mozilla.com>
|
||||
Eric Holk <eric.holk@gmail.com> <eholk@cs.indiana.edu>
|
||||
Eric Holk <eric.holk@gmail.com> <eholk@mozilla.com>
|
||||
Eric Holmes <eric@ejholmes.net>
|
||||
@ -83,6 +86,8 @@ Gareth Daniel Smith <garethdanielsmith@gmail.com> Gareth Smith <garethdanielsmit
|
||||
Georges Dubus <georges.dubus@gmail.com> <georges.dubus@compiletoi.net>
|
||||
Graham Fawcett <graham.fawcett@gmail.com> Graham Fawcett <fawcett@uwindsor.ca>
|
||||
Graydon Hoare <graydon@pobox.com> Graydon Hoare <graydon@mozilla.com>
|
||||
Guillaume Gomez <guillaume1.gomez@gmail.com>
|
||||
Guillaume Gomez <guillaume1.gomez@gmail.com> ggomez <ggomez@ggo.ifr.lan>
|
||||
Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <ggomez@ggo.ifr.lan>
|
||||
Heather <heather@cynede.net> <Cynede@Gentoo.org>
|
||||
Heather <heather@cynede.net> <Heather@cynede.net>
|
||||
@ -114,6 +119,7 @@ John Kåre Alsaker <john.kare.alsaker@gmail.com>
|
||||
John Talling <inrustwetrust@users.noreply.github.com>
|
||||
Jonathan Bailey <jbailey@mozilla.com> <jbailey@jbailey-20809.local>
|
||||
Jonathan S <gereeter@gmail.com> Jonathan S <gereeter+code@gmail.com>
|
||||
Jonathan Turner <probata@hotmail.com>
|
||||
Jorge Aparicio <japaric@linux.com> <japaricious@gmail.com>
|
||||
Joseph Martin <pythoner6@gmail.com>
|
||||
João Oliveira <hello@jxs.pt> joaoxsouls <joaoxsouls@gmail.com>
|
||||
@ -136,6 +142,7 @@ NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com>
|
||||
NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm+github@gmail.com>
|
||||
Marcell Pardavi <marcell.pardavi@gmail.com>
|
||||
Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew>
|
||||
Mark Simulacrum <mark.simulacrum@gmail.com>
|
||||
Mark Sinclair <mark.edward.x@gmail.com>
|
||||
Mark Sinclair <mark.edward.x@gmail.com> =Mark Sinclair <=125axel125@gmail.com>
|
||||
Markus Westerlind <marwes91@gmail.com> Markus <marwes91@gmail.com>
|
||||
@ -171,6 +178,7 @@ Peter Zotov <whitequark@whitequark.org>
|
||||
Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com>
|
||||
Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>
|
||||
Philipp Brüschweiler <blei42@gmail.com> <bruphili@student.ethz.ch>
|
||||
Philipp Matthias Schäfer <philipp.matthias.schaefer@posteo.de>
|
||||
Przemysław Wesołek <jest@go.art.pl> Przemek Wesołek <jest@go.art.pl>
|
||||
Rafael Ávila de Espíndola <respindola@mozilla.com> Rafael Avila de Espindola <espindola@dream.(none)>
|
||||
Ralph Giles <giles@thaumas.net> Ralph Giles <giles@mozilla.com>
|
||||
@ -189,11 +197,13 @@ S Pradeep Kumar <gohanpra@gmail.com>
|
||||
Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org>
|
||||
Sean Gillespie <sean.william.g@gmail.com> swgillespie <sean.william.g@gmail.com>
|
||||
Seonghyun Kim <sh8281.kim@samsung.com>
|
||||
Shyam Sundar B <shyambaskaran@outlook.com>
|
||||
Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server>
|
||||
Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org>
|
||||
Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me>
|
||||
startling <tdixon51793@gmail.com>
|
||||
Stepan Koltsov <stepan.koltsov@gmail.com> Stepan Koltsov <nga@yandex-team.ru>
|
||||
Steve Klabnik <steve@steveklabnik.com>
|
||||
Steven Fackler <sfackler@gmail.com> <sfackler@palantir.com>
|
||||
Steven Stewart-Gallus <sstewartgallus00@langara.bc.ca> <sstewartgallus00@mylangara.bc.ca>
|
||||
Stuart Pernsteiner <stuart@pernsteiner.org> Stuart Pernsteiner <spernsteiner@mozilla.com>
|
||||
|
@ -122,7 +122,7 @@ matrix:
|
||||
- env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1
|
||||
- env: >
|
||||
RUST_CHECK_TARGET=dist
|
||||
RUST_CONFIGURE_ARGS="--enable-extended"
|
||||
RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler"
|
||||
SRC=.
|
||||
DEPLOY_ALT=1
|
||||
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
|
||||
|
38
CODE_OF_CONDUCT.md
Normal file
38
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,38 @@
|
||||
# The Rust Code of Conduct
|
||||
|
||||
A version of this document [can be found online](https://www.rust-lang.org/conduct.html).
|
||||
|
||||
## Conduct
|
||||
|
||||
**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org)
|
||||
|
||||
* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
|
||||
* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
|
||||
* Please be kind and courteous. There's no need to be mean or rude.
|
||||
* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
|
||||
* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
|
||||
* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term "harassment" as including the definition in the <a href="http://citizencodeofconduct.org/">Citizen Code of Conduct</a>; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
|
||||
* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team](/team.html#Moderation) immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
|
||||
* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome.
|
||||
|
||||
## Moderation
|
||||
|
||||
|
||||
These are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team](/team.html#Moderation).
|
||||
|
||||
1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
|
||||
2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.
|
||||
3. Moderators will first respond to such remarks with a warning.
|
||||
4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off.
|
||||
5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.
|
||||
6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.
|
||||
7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed.
|
||||
8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.
|
||||
|
||||
In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.
|
||||
|
||||
And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
|
||||
|
||||
The enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.
|
||||
|
||||
*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/).*
|
@ -75,7 +75,7 @@ environment:
|
||||
|
||||
# "alternate" deployment, see .travis.yml for more info
|
||||
- MSYS_BITS: 64
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended
|
||||
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
|
||||
SCRIPT: python x.py dist
|
||||
DEPLOY_ALT: 1
|
||||
|
||||
|
@ -2216,12 +2216,22 @@ impl Path {
|
||||
/// This function will traverse symbolic links to query information about the
|
||||
/// destination file. In case of broken symbolic links this will return `false`.
|
||||
///
|
||||
/// If you cannot access the directory containing the file, e.g. because of a
|
||||
/// permission error, this will return `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::path::Path;
|
||||
/// assert_eq!(Path::new("does_not_exist.txt").exists(), false);
|
||||
/// ```
|
||||
///
|
||||
/// # See Also
|
||||
///
|
||||
/// This is a convenience function that coerces errors to false. If you want to
|
||||
/// check errors, call [fs::metadata].
|
||||
///
|
||||
/// [fs::metadata]: ../../std/fs/fn.metadata.html
|
||||
#[stable(feature = "path_ext", since = "1.5.0")]
|
||||
pub fn exists(&self) -> bool {
|
||||
fs::metadata(self).is_ok()
|
||||
@ -2232,6 +2242,9 @@ impl Path {
|
||||
/// This function will traverse symbolic links to query information about the
|
||||
/// destination file. In case of broken symbolic links this will return `false`.
|
||||
///
|
||||
/// If you cannot access the directory containing the file, e.g. because of a
|
||||
/// permission error, this will return `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
@ -2239,6 +2252,15 @@ impl Path {
|
||||
/// assert_eq!(Path::new("./is_a_directory/").is_file(), false);
|
||||
/// assert_eq!(Path::new("a_file.txt").is_file(), true);
|
||||
/// ```
|
||||
///
|
||||
/// # See Also
|
||||
///
|
||||
/// This is a convenience function that coerces errors to false. If you want to
|
||||
/// check errors, call [fs::metadata] and handle its Result. Then call
|
||||
/// [fs::Metadata::is_file] if it was Ok.
|
||||
///
|
||||
/// [fs::metadata]: ../../std/fs/fn.metadata.html
|
||||
/// [fs::Metadata::is_file]: ../../std/fs/struct.Metadata.html#method.is_file
|
||||
#[stable(feature = "path_ext", since = "1.5.0")]
|
||||
pub fn is_file(&self) -> bool {
|
||||
fs::metadata(self).map(|m| m.is_file()).unwrap_or(false)
|
||||
@ -2249,6 +2271,9 @@ impl Path {
|
||||
/// This function will traverse symbolic links to query information about the
|
||||
/// destination file. In case of broken symbolic links this will return `false`.
|
||||
///
|
||||
/// If you cannot access the directory containing the file, e.g. because of a
|
||||
/// permission error, this will return `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
@ -2256,6 +2281,15 @@ impl Path {
|
||||
/// assert_eq!(Path::new("./is_a_directory/").is_dir(), true);
|
||||
/// assert_eq!(Path::new("a_file.txt").is_dir(), false);
|
||||
/// ```
|
||||
///
|
||||
/// # See Also
|
||||
///
|
||||
/// This is a convenience function that coerces errors to false. If you want to
|
||||
/// check errors, call [fs::metadata] and handle its Result. Then call
|
||||
/// [fs::Metadata::is_dir] if it was Ok.
|
||||
///
|
||||
/// [fs::metadata]: ../../std/fs/fn.metadata.html
|
||||
/// [fs::Metadata::is_dir]: ../../std/fs/struct.Metadata.html#method.is_dir
|
||||
#[stable(feature = "path_ext", since = "1.5.0")]
|
||||
pub fn is_dir(&self) -> bool {
|
||||
fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
|
||||
|
@ -383,9 +383,10 @@ pub fn unlink(p: &Path) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
|
||||
::sys_common::util::dumb_print(format_args!("Rename\n"));
|
||||
unimplemented!();
|
||||
pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
|
||||
copy(old, new)?;
|
||||
unlink(old)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
|
||||
|
@ -39,25 +39,7 @@ pub mod thread_local;
|
||||
pub mod time;
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn init() {
|
||||
use alloc::oom;
|
||||
|
||||
oom::set_oom_handler(oom_handler);
|
||||
|
||||
// A nicer handler for out-of-memory situations than the default one. This
|
||||
// one prints a message to stderr before aborting. It is critical that this
|
||||
// code does not allocate any memory since we are in an OOM situation. Any
|
||||
// errors are ignored while printing since there's nothing we can do about
|
||||
// them and we are about to exit anyways.
|
||||
fn oom_handler() -> ! {
|
||||
use intrinsics;
|
||||
let msg = "fatal runtime error: out of memory\n";
|
||||
unsafe {
|
||||
let _ = syscall::write(2, msg.as_bytes());
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn init() {}
|
||||
|
||||
pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
||||
match errno {
|
||||
|
231
src/test/run-pass/rfc1857-drop-order.rs
Normal file
231
src/test/run-pass/rfc1857-drop-order.rs
Normal file
@ -0,0 +1,231 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code, unreachable_code)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::panic::{self, AssertUnwindSafe, UnwindSafe};
|
||||
|
||||
// This struct is used to record the order in which elements are dropped
|
||||
struct PushOnDrop {
|
||||
vec: Rc<RefCell<Vec<u32>>>,
|
||||
val: u32
|
||||
}
|
||||
|
||||
impl PushOnDrop {
|
||||
fn new(val: u32, vec: Rc<RefCell<Vec<u32>>>) -> PushOnDrop {
|
||||
PushOnDrop { vec, val }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PushOnDrop {
|
||||
fn drop(&mut self) {
|
||||
self.vec.borrow_mut().push(self.val)
|
||||
}
|
||||
}
|
||||
|
||||
impl UnwindSafe for PushOnDrop { }
|
||||
|
||||
// Structs
|
||||
struct TestStruct {
|
||||
x: PushOnDrop,
|
||||
y: PushOnDrop,
|
||||
z: PushOnDrop
|
||||
}
|
||||
|
||||
// Tuple structs
|
||||
struct TestTupleStruct(PushOnDrop, PushOnDrop, PushOnDrop);
|
||||
|
||||
// Enum variants
|
||||
enum TestEnum {
|
||||
Tuple(PushOnDrop, PushOnDrop, PushOnDrop),
|
||||
Struct { x: PushOnDrop, y: PushOnDrop, z: PushOnDrop }
|
||||
}
|
||||
|
||||
fn test_drop_tuple() {
|
||||
// Tuple fields are dropped in the same order they are declared
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let test_tuple = (PushOnDrop::new(1, dropped_fields.clone()),
|
||||
PushOnDrop::new(2, dropped_fields.clone()));
|
||||
drop(test_tuple);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
|
||||
// Panic during construction means that fields are treated as local variables
|
||||
// Therefore they are dropped in reverse order of initialization
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
(PushOnDrop::new(2, cloned.clone()),
|
||||
PushOnDrop::new(1, cloned.clone()),
|
||||
panic!("this panic is catched :D"));
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
}
|
||||
|
||||
fn test_drop_struct() {
|
||||
// Struct fields are dropped in the same order they are declared
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let test_struct = TestStruct {
|
||||
x: PushOnDrop::new(1, dropped_fields.clone()),
|
||||
y: PushOnDrop::new(2, dropped_fields.clone()),
|
||||
z: PushOnDrop::new(3, dropped_fields.clone()),
|
||||
};
|
||||
drop(test_struct);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
|
||||
|
||||
// The same holds for tuple structs
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let test_tuple_struct = TestTupleStruct(PushOnDrop::new(1, dropped_fields.clone()),
|
||||
PushOnDrop::new(2, dropped_fields.clone()),
|
||||
PushOnDrop::new(3, dropped_fields.clone()));
|
||||
drop(test_tuple_struct);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
|
||||
|
||||
// Panic during struct construction means that fields are treated as local variables
|
||||
// Therefore they are dropped in reverse order of initialization
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
TestStruct {
|
||||
x: PushOnDrop::new(2, cloned.clone()),
|
||||
y: PushOnDrop::new(1, cloned.clone()),
|
||||
z: panic!("this panic is catched :D")
|
||||
};
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
|
||||
// Test with different initialization order
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
TestStruct {
|
||||
y: PushOnDrop::new(2, cloned.clone()),
|
||||
x: PushOnDrop::new(1, cloned.clone()),
|
||||
z: panic!("this panic is catched :D")
|
||||
};
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
|
||||
// The same holds for tuple structs
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
TestTupleStruct(PushOnDrop::new(2, cloned.clone()),
|
||||
PushOnDrop::new(1, cloned.clone()),
|
||||
panic!("this panic is catched :D"));
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
}
|
||||
|
||||
fn test_drop_enum() {
|
||||
// Enum variants are dropped in the same order they are declared
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let test_struct_enum = TestEnum::Struct {
|
||||
x: PushOnDrop::new(1, dropped_fields.clone()),
|
||||
y: PushOnDrop::new(2, dropped_fields.clone()),
|
||||
z: PushOnDrop::new(3, dropped_fields.clone())
|
||||
};
|
||||
drop(test_struct_enum);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
|
||||
|
||||
// The same holds for tuple enum variants
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let test_tuple_enum = TestEnum::Tuple(PushOnDrop::new(1, dropped_fields.clone()),
|
||||
PushOnDrop::new(2, dropped_fields.clone()),
|
||||
PushOnDrop::new(3, dropped_fields.clone()));
|
||||
drop(test_tuple_enum);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
|
||||
|
||||
// Panic during enum construction means that fields are treated as local variables
|
||||
// Therefore they are dropped in reverse order of initialization
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
TestEnum::Struct {
|
||||
x: PushOnDrop::new(2, cloned.clone()),
|
||||
y: PushOnDrop::new(1, cloned.clone()),
|
||||
z: panic!("this panic is catched :D")
|
||||
};
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
|
||||
// Test with different initialization order
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
TestEnum::Struct {
|
||||
y: PushOnDrop::new(2, cloned.clone()),
|
||||
x: PushOnDrop::new(1, cloned.clone()),
|
||||
z: panic!("this panic is catched :D")
|
||||
};
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
|
||||
// The same holds for tuple enum variants
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
TestEnum::Tuple(PushOnDrop::new(2, cloned.clone()),
|
||||
PushOnDrop::new(1, cloned.clone()),
|
||||
panic!("this panic is catched :D"));
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
}
|
||||
|
||||
fn test_drop_list() {
|
||||
// Elements in a Vec are dropped in the same order they are pushed
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let xs = vec![PushOnDrop::new(1, dropped_fields.clone()),
|
||||
PushOnDrop::new(2, dropped_fields.clone()),
|
||||
PushOnDrop::new(3, dropped_fields.clone())];
|
||||
drop(xs);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
|
||||
|
||||
// The same holds for arrays
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let xs = [PushOnDrop::new(1, dropped_fields.clone()),
|
||||
PushOnDrop::new(2, dropped_fields.clone()),
|
||||
PushOnDrop::new(3, dropped_fields.clone())];
|
||||
drop(xs);
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]);
|
||||
|
||||
// Panic during vec construction means that fields are treated as local variables
|
||||
// Therefore they are dropped in reverse order of initialization
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
vec![
|
||||
PushOnDrop::new(2, cloned.clone()),
|
||||
PushOnDrop::new(1, cloned.clone()),
|
||||
panic!("this panic is catched :D")
|
||||
];
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
|
||||
// The same holds for arrays
|
||||
let dropped_fields = Rc::new(RefCell::new(Vec::new()));
|
||||
let cloned = AssertUnwindSafe(dropped_fields.clone());
|
||||
panic::catch_unwind(|| {
|
||||
[
|
||||
PushOnDrop::new(2, cloned.clone()),
|
||||
PushOnDrop::new(1, cloned.clone()),
|
||||
panic!("this panic is catched :D")
|
||||
];
|
||||
}).err().unwrap();
|
||||
assert_eq!(*dropped_fields.borrow(), &[1, 2]);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_drop_tuple();
|
||||
test_drop_struct();
|
||||
test_drop_enum();
|
||||
test_drop_list();
|
||||
}
|
Loading…
Reference in New Issue
Block a user