diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 86fbbd4c3cc59..ce9ffd3cecf6f 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -40,8 +40,9 @@ struct RcBox { } /// Immutable reference counted pointer type -#[unsafe_no_drop_flag] #[no_send] +#[unsafe_no_drop_flag] +#[unsafe_non_zero_word] pub struct Rc { priv ptr: *mut RcBox, } @@ -167,6 +168,7 @@ struct RcMutBox { #[no_send] #[no_freeze] #[unsafe_no_drop_flag] +#[unsafe_non_zero_word] pub struct RcMut { priv ptr: *mut RcMutBox, } @@ -255,6 +257,7 @@ impl DeepClone for RcMut { #[cfg(test)] mod test_rc_mut { use super::*; + use std::sys::size_of; #[test] fn test_clone() { @@ -372,4 +375,10 @@ mod test_rc_mut { do y.with_mut_borrow |_| {} } } + + #[test] + fn non_zero_word() { + assert_eq!(size_of::>>(), size_of::>()); + assert_eq!(size_of::>>(), size_of::>()); + } } diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index a00cfa2912380..084f541a0799e 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -145,8 +145,8 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { fn is_zerolen(&self, cx: &mut CrateContext) -> bool { mk_struct(cx, self.tys, false).size == 0 } - fn find_ptr(&self) -> Option { - self.tys.iter().position(|&ty| mono_data_classify(ty) == MonoNonNull) + fn find_ptr(&self, tcx: ty::ctxt) -> Option { + self.tys.iter().position(|&ty| mono_data_classify(tcx, ty) == MonoNonNull) } } @@ -187,7 +187,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { let mut discr = 0; while discr < 2 { if cases[1 - discr].is_zerolen(cx) { - match cases[discr].find_ptr() { + match cases[discr].find_ptr(cx.tcx) { Some(ptrfield) => { return NullablePointer { nndiscr: discr, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index d8c7b916a0232..3804f9ed9ce86 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -904,7 +904,7 @@ pub enum MonoDataClass { MonoFloat } -pub fn mono_data_classify(t: ty::t) -> MonoDataClass { +pub fn mono_data_classify(tcx: ty::ctxt, t: ty::t) -> MonoDataClass { match ty::get(t).sty { ty::ty_float(_) => MonoFloat, ty::ty_rptr(*) | ty::ty_uniq(*) | @@ -912,6 +912,8 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass { ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) | ty::ty_bare_fn(*) => MonoNonNull, + ty::ty_struct(id, _) | ty::ty_enum(id, _) + if ty::has_attr(tcx, id, "unsafe_non_zero_word") => MonoNonNull, // Is that everything? Would closures or slices qualify? _ => MonoBits } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index ab458f2799dda..6121d71a04236 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -407,7 +407,7 @@ pub fn make_mono_id(ccx: @mut CrateContext, let size = machine::llbitsize_of_real(ccx, llty); let align = machine::llalign_of_min(ccx, llty); let mode = datum::appropriate_mode(ccx.tcx, subst); - let data_class = mono_data_classify(subst); + let data_class = mono_data_classify(ccx.tcx, subst); debug!("make_mono_id: type %s -> size %u align %u mode %? class %?", ty_to_str(ccx.tcx, subst), diff --git a/src/test/run-pass/attr-unsafe_non_zero_word.rs b/src/test/run-pass/attr-unsafe_non_zero_word.rs new file mode 100644 index 0000000000000..c0316395195f0 --- /dev/null +++ b/src/test/run-pass/attr-unsafe_non_zero_word.rs @@ -0,0 +1,20 @@ +// Copyright 2013 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. + +use std::sys::size_of; + +#[unsafe_non_zero_word] +struct Test { + foo: *int +} + +fn main() { + assert_eq!(size_of::>(), size_of::<*int>()); +}