From a55c7be98add97e1040fd18af96db151992fbe61 Mon Sep 17 00:00:00 2001 From: Jakub Wieczorek Date: Tue, 10 Jun 2014 19:04:28 +0200 Subject: [PATCH] Fix an ICE when implementing Drop on enums Fixes #13041. --- src/librustc/middle/kind.rs | 22 ++++++++++++++++------ src/test/run-pass/issue-13041.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/test/run-pass/issue-13041.rs diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 39f2e8425833c..3e1df17465516 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -13,6 +13,8 @@ use middle::freevars::freevar_entry; use middle::freevars; use middle::subst; use middle::ty; +use middle::ty_fold; +use middle::ty_fold::TypeFoldable; use middle::typeck; use util::ppaux::{Repr, ty_to_str}; use util::ppaux::UserString; @@ -82,17 +84,25 @@ pub fn check_crate(tcx: &ty::ctxt, tcx.sess.abort_if_errors(); } +struct EmptySubstsFolder<'a> { + tcx: &'a ty::ctxt +} +impl<'a> ty_fold::TypeFolder for EmptySubstsFolder<'a> { + fn tcx<'a>(&'a self) -> &'a ty::ctxt { + self.tcx + } + fn fold_substs(&mut self, _: &subst::Substs) -> subst::Substs { + subst::Substs::empty() + } +} + fn check_struct_safe_for_destructor(cx: &mut Context, span: Span, struct_did: DefId) { let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did); if !struct_tpt.generics.has_type_params() { - let struct_ty = ty::mk_struct(cx.tcx, struct_did, subst::Substs { - regions: subst::NonerasedRegions(Vec::new()), - self_ty: None, - tps: Vec::new() - }); - if !ty::type_is_sendable(cx.tcx, struct_ty) { + let mut folder = EmptySubstsFolder { tcx: cx.tcx }; + if !ty::type_is_sendable(cx.tcx, struct_tpt.ty.fold_with(&mut folder)) { cx.tcx.sess.span_err(span, "cannot implement a destructor on a \ structure that does not satisfy Send"); diff --git a/src/test/run-pass/issue-13041.rs b/src/test/run-pass/issue-13041.rs new file mode 100644 index 0000000000000..6d86c71434d56 --- /dev/null +++ b/src/test/run-pass/issue-13041.rs @@ -0,0 +1,26 @@ +// 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. + +enum Foo { + Bar(bool), Baz +} + +impl Drop for Foo { + fn drop(&mut self) { + match *self { + Bar(..) => (), + Baz => unreachable!() + } + } +} + +fn main() { + let _ = Bar(false); +}