From 5857ec6d78fec2cf457a5557d89677354eb7d0d1 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 13 Sep 2014 15:35:21 -0700 Subject: [PATCH 1/2] Fix issue #17216 The cleanup scope of for loop bindings should translated when popped to ensure resources are not leaked. --- src/librustc/middle/trans/controlflow.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 164ddd65f3540..607b70317a848 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -357,7 +357,10 @@ pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // Codegen the body. body_bcx_out = trans_block(body_bcx_out, body, expr::Ignore); - body_bcx_out.fcx.pop_custom_cleanup_scope(binding_cleanup_scope); + body_bcx_out = + body_bcx_out.fcx + .pop_and_trans_custom_cleanup_scope(body_bcx_out, + binding_cleanup_scope); body_bcx_out = body_bcx_out.fcx .pop_and_trans_custom_cleanup_scope(body_bcx_out, From f1c4e476e9ecfcbcce167ce2c34840ccee71a1d4 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 13 Sep 2014 15:36:58 -0700 Subject: [PATCH 2/2] Add regression test for issue #17216 --- src/test/run-pass/issue-17216.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/run-pass/issue-17216.rs diff --git a/src/test/run-pass/issue-17216.rs b/src/test/run-pass/issue-17216.rs new file mode 100644 index 0000000000000..538b837d11731 --- /dev/null +++ b/src/test/run-pass/issue-17216.rs @@ -0,0 +1,32 @@ +// Copyright 2014 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. + +#![feature(unsafe_destructor)] + +struct Leak<'a> { + dropped: &'a mut bool +} + +#[unsafe_destructor] +impl<'a> Drop for Leak<'a> { + fn drop(&mut self) { + *self.dropped = true; + } +} + +fn main() { + let mut dropped = false; + { + let leak = Leak { dropped: &mut dropped }; + for ((), leaked) in Some(((),leak)).move_iter() {} + } + + assert!(dropped); +}