Skip to content

Regression tests #24268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 11, 2015
Merged
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
66 changes: 66 additions & 0 deletions src/test/run-pass/issue-21400.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2015 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.

// Regression test for #21400 which itself was extracted from
// stackoverflow.com/questions/28031155/is-my-borrow-checker-drunk/28031580

fn main() {
let mut t = Test;
assert_eq!(t.method1("one"), Ok(1));
assert_eq!(t.method2("two"), Ok(2));
assert_eq!(t.test(), Ok(2));
}

struct Test;

impl Test {
fn method1(&mut self, _arg: &str) -> Result<usize, &str> {
Ok(1)
}

fn method2(self: &mut Test, _arg: &str) -> Result<usize, &str> {
Ok(2)
}

fn test(self: &mut Test) -> Result<usize, &str> {
let s = format!("abcde");
// (Originally, this invocation of method2 was saying that `s`
// does not live long enough.)
let data = match self.method2(&*s) {
Ok(r) => r,
Err(e) => return Err(e)
};
Ok(data)
}
}

// Below is a closer match for the original test that was failing to compile

pub struct GitConnect;

impl GitConnect {
fn command(self: &mut GitConnect, _s: &str) -> Result<Vec<Vec<u8>>, &str> {
unimplemented!()
}

pub fn git_upload_pack(self: &mut GitConnect) -> Result<String, &str> {
let c = format!("git-upload-pack");

let mut out = String::new();
let data = try!(self.command(&c));

for line in data.iter() {
out.push_str(&format!("{:?}", line));
}

Ok(out)
}
}

86 changes: 86 additions & 0 deletions src/test/run-pass/issue-21486.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2015 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.

// Issue #21486: Make sure that all structures are dropped, even when
// created via FRU and control-flow breaks in the middle of
// construction.


use std::sync::atomic::{Ordering, AtomicUsize, ATOMIC_USIZE_INIT};

#[derive(Debug)]
struct Noisy(u8);
impl Drop for Noisy {
fn drop(&mut self) {
// println!("splat #{}", self.0);
event(self.0);
}
}

#[allow(dead_code)]
#[derive(Debug)]
struct Foo { n0: Noisy, n1: Noisy }
impl Foo {
fn vals(&self) -> (u8, u8) { (self.n0.0, self.n1.0) }
}

fn leak_1_ret() -> Foo {
let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
Foo { n0: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
.._old_foo
};
}

fn leak_2_ret() -> Foo {
let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
.._old_foo
};
}

// In this case, the control flow break happens *before* we construct
// `Foo(Noisy(1),Noisy(2))`, so there should be no record of it in the
// event log.
fn leak_3_ret() -> Foo {
let _old_foo = || Foo { n0: Noisy(1), n1: Noisy(2) };
Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
.._old_foo()
};
}

pub fn main() {
reset_log();
assert_eq!(leak_1_ret().vals(), (3,4));
assert_eq!(0x01_02_03_04, event_log());

reset_log();
assert_eq!(leak_2_ret().vals(), (3,4));
assert_eq!(0x01_02_03_04, event_log());

reset_log();
assert_eq!(leak_3_ret().vals(), (3,4));
assert_eq!(0x03_04, event_log());
}

static LOG: AtomicUsize = ATOMIC_USIZE_INIT;

fn reset_log() {
LOG.store(0, Ordering::SeqCst);
}

fn event_log() -> usize {
LOG.load(Ordering::SeqCst)
}

fn event(tag: u8) {
let old_log = LOG.load(Ordering::SeqCst);
let new_log = (old_log << 8) + tag as usize;
LOG.store(new_log, Ordering::SeqCst);
}