diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index b7e761fa4b9..0b4d7e602be 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -389,7 +389,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { if !self.type_needs_drop(ty) { return; } let drop = box DropValue { is_immediate: false, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: false, @@ -415,7 +414,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { let drop = box DropValue { is_immediate: false, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: true, @@ -447,7 +445,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { let drop = box DropValue { is_immediate: false, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: false, @@ -473,7 +470,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { if !self.type_needs_drop(ty) { return; } let drop = box DropValue { is_immediate: true, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: false, @@ -1031,7 +1027,6 @@ impl EarlyExitLabel { #[derive(Copy, Clone)] pub struct DropValue<'tcx> { is_immediate: bool, - must_unwind: bool, val: ValueRef, ty: Ty<'tcx>, fill_on_drop: bool, @@ -1040,11 +1035,11 @@ pub struct DropValue<'tcx> { impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> { fn must_unwind(&self) -> bool { - self.must_unwind + true } fn clean_on_unwind(&self) -> bool { - self.must_unwind + true } fn is_lifetime_end(&self) -> bool { diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 483d82f508f..9c2aea1e67a 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -25,7 +25,7 @@ use middle::lang_items::LangItem; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; use middle::region; -use middle::subst::{self, Subst, Substs}; +use middle::subst::{self, Substs}; use trans::base; use trans::build; use trans::cleanup; @@ -54,8 +54,6 @@ use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::InternedString; use syntax::parse::token; -use util::common::memoized; -use util::nodemap::FnvHashSet; pub use trans::context::CrateContext; @@ -136,47 +134,6 @@ pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { } } -// Some things don't need cleanups during unwinding because the -// thread can free them all at once later. Currently only things -// that only contain scalars and shared boxes can avoid unwind -// cleanups. -pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { - return memoized(ccx.needs_unwind_cleanup_cache(), ty, |ty| { - type_needs_unwind_cleanup_(ccx.tcx(), ty, &mut FnvHashSet()) - }); - - fn type_needs_unwind_cleanup_<'tcx>(tcx: &ty::ctxt<'tcx>, - ty: Ty<'tcx>, - tycache: &mut FnvHashSet>) - -> bool - { - // Prevent infinite recursion - if !tycache.insert(ty) { - return false; - } - - let mut needs_unwind_cleanup = false; - ty.maybe_walk(|ty| { - needs_unwind_cleanup |= match ty.sty { - ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | - ty::TyFloat(_) | ty::TyTuple(_) | ty::TyRawPtr(_) => false, - - ty::TyEnum(did, substs) => - tcx.enum_variants(did).iter().any(|v| - v.args.iter().any(|&aty| { - let t = aty.subst(tcx, substs); - type_needs_unwind_cleanup_(tcx, t, tycache) - }) - ), - - _ => true - }; - !needs_unwind_cleanup - }); - needs_unwind_cleanup - } -} - /// If `type_needs_drop` returns true, then `ty` is definitely /// non-copy and *might* have a destructor attached; if it returns /// false, then `ty` definitely has no destructor (i.e. no drop glue). diff --git a/src/test/run-pass/issue-26655.rs b/src/test/run-pass/issue-26655.rs new file mode 100644 index 00000000000..bdd3a80d74c --- /dev/null +++ b/src/test/run-pass/issue-26655.rs @@ -0,0 +1,34 @@ +// 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. + +#![feature(const_fn)] + +// Check that the destructors of simple enums are run on unwinding + +use std::sync::atomic::{Ordering, AtomicUsize}; +use std::thread; + +static LOG: AtomicUsize = AtomicUsize::new(0); + +enum WithDtor { Val } +impl Drop for WithDtor { + fn drop(&mut self) { + LOG.store(LOG.load(Ordering::SeqCst)+1,Ordering::SeqCst); + } +} + +pub fn main() { + thread::spawn(move|| { + let _e: WithDtor = WithDtor::Val; + panic!("fail"); + }).join().unwrap_err(); + + assert_eq!(LOG.load(Ordering::SeqCst), 1); +}