-
Notifications
You must be signed in to change notification settings - Fork 12.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #21692 - pnkfelix:fsk-fix-coerce-match-20055, r=eddyb
trans: When coercing to `Box<Trait>` or `Box<[T]>`, leave datum in it's original L-/R-value state. This fixes a subtle issue where temporaries were being allocated (but not necessarily initialized) to the (parent) terminating scope of a match expression; in particular, the code to zero out the temporary emitted by `datum.store_to` is only attached to the particular match-arm for that temporary, but when going down other arms of the match expression, the temporary may falsely appear to have been initialized, depending on what the stack held at that location, and thus may have its destructor erroneously run at the end of the terminating scope. FIx #20055. (There may be a latent bug still remaining in `fn into_fat_ptr`, but I am so annoyed by the test/run-pass/coerce_match.rs failures that I want to land this now.)
- Loading branch information
Showing
3 changed files
with
102 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// 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. | ||
|
||
// See Issues #20055 and #21695. | ||
|
||
// We are checking here that the temporaries `Box<[i8, k]>`, for `k` | ||
// in 1, 2, 3, 4, that are induced by the match expression are | ||
// properly handled, in that only *one* will be initialized by | ||
// whichever arm is run, and subsequently dropped at the end of the | ||
// statement surrounding the `match`. | ||
|
||
trait Boo { } | ||
|
||
impl Boo for [i8; 1] { } | ||
impl Boo for [i8; 2] { } | ||
impl Boo for [i8; 3] { } | ||
impl Boo for [i8; 4] { } | ||
|
||
pub fn foo(box_1: fn () -> Box<[i8; 1]>, | ||
box_2: fn () -> Box<[i8; 2]>, | ||
box_3: fn () -> Box<[i8; 3]>, | ||
box_4: fn () -> Box<[i8; 4]>, | ||
) { | ||
println!("Hello World 1"); | ||
let _: Box<Boo> = match 3 { | ||
1 => box_1(), | ||
2 => box_2(), | ||
3 => box_3(), | ||
_ => box_4(), | ||
}; | ||
println!("Hello World 2"); | ||
} | ||
|
||
pub fn main() { | ||
fn box_1() -> Box<[i8; 1]> { Box::new( [1i8; 1] ) } | ||
fn box_2() -> Box<[i8; 2]> { Box::new( [1i8; 2] ) } | ||
fn box_3() -> Box<[i8; 3]> { Box::new( [1i8; 3] ) } | ||
fn box_4() -> Box<[i8; 4]> { Box::new( [1i8; 4] ) } | ||
|
||
foo(box_1, box_2, box_3, box_4); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// 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 #2005: Check that boxed fixed-size arrays are properly | ||
// accounted for (namely, only deallocated if they were actually | ||
// created) when they appear as temporaries in unused arms of a match | ||
// expression. | ||
|
||
pub fn foo(box_1: fn () -> Box<[i8; 1]>, | ||
box_2: fn () -> Box<[i8; 20]>, | ||
box_3: fn () -> Box<[i8; 300]>, | ||
box_4: fn () -> Box<[i8; 4000]>, | ||
) { | ||
println!("Hello World 1"); | ||
let _: Box<[i8]> = match 3 { | ||
1 => box_1(), | ||
2 => box_2(), | ||
3 => box_3(), | ||
_ => box_4(), | ||
}; | ||
println!("Hello World 2"); | ||
} | ||
|
||
pub fn main() { | ||
fn box_1() -> Box<[i8; 1]> { Box::new( [1i8] ) } | ||
fn box_2() -> Box<[i8; 20]> { Box::new( [1i8; 20] ) } | ||
fn box_3() -> Box<[i8; 300]> { Box::new( [1i8; 300] ) } | ||
fn box_4() -> Box<[i8; 4000]> { Box::new( [1i8; 4000] ) } | ||
|
||
foo(box_1, box_2, box_3, box_4); | ||
} |