// 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 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Issue #29793, big regression test: do not let borrows of // parameters to ever be returned (expanded with exploration of // variations). // // This is the version of the test that actually exposed unsound // behavior (because the improperly accepted closure was actually // able to be invoked). // ignore-tidy-linelength // revisions: ast mir //[mir]compile-flags: -Z borrowck=mir struct WrapA(Option); impl WrapA { fn new() -> WrapA { WrapA(None) } fn set(mut self, f: F) -> Self { self.0 = Some(f); self } } struct WrapB(Option); impl WrapB { fn new() -> WrapB { WrapB(None) } fn set(mut self, f: F) -> Self { self.0 = Some(f); self } } trait DoStuff : Sized { fn handle(self); } impl DoStuff for WrapA where F: FnMut(usize, usize) -> T, T: DoStuff { fn handle(mut self) { if let Some(ref mut f) = self.0 { let x = f(1, 2); let _foo = [0usize; 16]; x.handle(); } } } impl DoStuff for WrapB where F: FnMut(bool) -> usize { fn handle(mut self) { if let Some(ref mut f) = self.0 { println!("{}", f(true)); } } } impl WrapA where F: FnMut(usize, usize) -> T, T: DoStuff { fn handle_ref(&mut self) { if let Some(ref mut f) = self.0 { let x = f(1, 2); } } } fn main() { let mut w = WrapA::new().set(|x: usize, y: usize| { WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) //[ast]~^ ERROR `x` does not live long enough //[ast]~| ERROR `y` does not live long enough //[mir]~^^^ ERROR `x` does not live long enough //[mir]~| ERROR `y` does not live long enough }); w.handle(); // This works // w.handle_ref(); // This doesn't }