Skip to content

Commit

Permalink
Make unions never have needs_drop
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Jan 9, 2017
1 parent d2c7959 commit b9b0732
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/librustc/ty/contents.rs
Expand Up @@ -235,6 +235,11 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
})
});

if def.is_union() {
// unions don't have destructors regardless of the child types
res = res - TC::NeedsDrop;
}

if def.has_dtor() {
res = res | TC::OwnsDtor;
}
Expand Down
63 changes: 63 additions & 0 deletions src/test/run-pass/union/union-nodrop.rs
@@ -0,0 +1,63 @@
// Copyright 2016 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.

#![feature(core_intrinsics)]
#![feature(untagged_unions)]

#![allow(unions_with_drop_fields)]
#![allow(dead_code)]

use std::intrinsics::needs_drop;

// drop types in destructors should not require
// drop_types_in_const
static X: Option<NoDrop<Box<u8>>> = None;

// A union that scrubs the drop glue from its inner type
union NoDrop<T> {inner: T}

// Copy currently can't be implemented on drop-containing unions,
// this may change later
// https://github.com/rust-lang/rust/pull/38934#issuecomment-271219289

// // We should be able to implement Copy for NoDrop
// impl<T> Copy for NoDrop<T> {}
// impl<T> Clone for NoDrop<T> {fn clone(&self) -> Self { *self }}

// // We should be able to implement Copy for things using NoDrop
// #[derive(Copy, Clone)]
struct Foo {
x: NoDrop<Box<u8>>
}

struct Baz {
x: NoDrop<Box<u8>>,
y: Box<u8>,
}

union ActuallyDrop<T> {inner: T}

impl<T> Drop for ActuallyDrop<T> {
fn drop(&mut self) {}
}

fn main() {
unsafe {
// NoDrop should not make needs_drop true
assert!(!needs_drop::<Foo>());
assert!(!needs_drop::<NoDrop<u8>>());
assert!(!needs_drop::<NoDrop<Box<u8>>>());
// presence of other drop types should still work
assert!(needs_drop::<Baz>());
// drop impl on union itself should work
assert!(needs_drop::<ActuallyDrop<u8>>());
assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
}
}

0 comments on commit b9b0732

Please sign in to comment.