diff options
| author | Oliver Schneider <github35764891676564198441@oli-obk.de> | 2018-09-10 13:40:34 +0200 |
|---|---|---|
| committer | Oliver Schneider <github35764891676564198441@oli-obk.de> | 2018-09-11 11:25:51 +0200 |
| commit | 833dc7e6826483b19c819fc19727efe4e8ddbf12 (patch) | |
| tree | e3129c36ae23408fcdb7a5db0edf2c6d7d07136d | |
| parent | a2c924b5ae21b67be77aa7e944ae9d9f883a0bde (diff) | |
| download | rust-833dc7e6826483b19c819fc19727efe4e8ddbf12.tar.gz rust-833dc7e6826483b19c819fc19727efe4e8ddbf12.zip | |
Address attribute naming and use `Bound` enum
| -rw-r--r-- | src/libcore/nonzero.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 33 | ||||
| -rw-r--r-- | src/librustc/ty/layout.rs | 46 | ||||
| -rw-r--r-- | src/librustc_data_structures/indexed_vec.rs | 2 |
4 files changed, 44 insertions, 39 deletions
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 6f27d3207bb..30067d7e163 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -15,7 +15,7 @@ use ops::CoerceUnsized; /// A wrapper type for raw pointers and integers that will never be /// NULL or 0 that might allow certain optimizations. #[cfg_attr(stage0, lang = "non_zero")] -#[cfg_attr(not(stage0), rustc_layout_scalar_range_start(1))] +#[cfg_attr(not(stage0), rustc_layout_scalar_valid_range_start(1))] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub(crate) struct NonZero<T>(pub(crate) T); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 922308d51fb..9c759b38d38 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -66,7 +66,7 @@ use std::collections::hash_map::{self, Entry}; use std::hash::{Hash, Hasher}; use std::fmt; use std::mem; -use std::ops::Deref; +use std::ops::{Deref, Bound}; use std::iter; use std::sync::mpsc; use std::sync::Arc; @@ -1083,27 +1083,24 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { interned } - /// Returns a range of the start/end indices specified with the `rustc_layout_scalar_range` - /// attribute. Missing range ends may be denoted by `None` and will just use the max/min of - /// the type. - pub fn layout_scalar_range(self, def_id: DefId) -> Option<(Option<u128>, Option<u128>)> { + /// Returns a range of the start/end indices specified with the + /// `rustc_layout_scalar_valid_range` attribute. + pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) { let attrs = self.get_attrs(def_id); - let get = |name| -> Option<u128> { - let attr = attrs.iter().find(|a| a.check_name(name))?; - for meta in attr.meta_item_list().expect("rustc_layout_scalar_range takes args") { - match meta.literal().expect("rustc_layout_scalar_range attribute takes lit").node { - ast::LitKind::Int(a, _) => return Some(a), - _ => span_bug!(attr.span, "rustc_layout_scalar_range expects integer arg"), + let get = |name| { + let attr = match attrs.iter().find(|a| a.check_name(name)) { + Some(attr) => attr, + None => return Bound::Unbounded, + }; + for meta in attr.meta_item_list().expect("rustc_layout_scalar_valid_range takes args") { + match meta.literal().expect("attribute takes lit").node { + ast::LitKind::Int(a, _) => return Bound::Included(a), + _ => span_bug!(attr.span, "rustc_layout_scalar_valid_range expects int arg"), } } - bug!("no arguments to `rustc_layout_scalar_range` attribute"); + span_bug!(attr.span, "no arguments to `rustc_layout_scalar_valid_range` attribute"); }; - let start = get("rustc_layout_scalar_range_start"); - let end = get("rustc_layout_scalar_range_end"); - if start.is_none() && end.is_none() { - return None; - } - Some((start, end)) + (get("rustc_layout_scalar_valid_range_start"), get("rustc_layout_scalar_valid_range_end")) } pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index be9357dd4a7..71cdec0f83e 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -20,6 +20,7 @@ use std::fmt; use std::i128; use std::iter; use std::mem; +use std::ops::Bound; use ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, @@ -761,20 +762,28 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let mut st = univariant_uninterned(&variants[v], &def.repr, kind)?; st.variants = Variants::Single { index: v }; - if let Some((start, end)) = self.tcx.layout_scalar_range(def.did) { - match st.abi { - Abi::Scalar(ref mut scalar) | - Abi::ScalarPair(ref mut scalar, _) => { - let start = start.unwrap_or(*scalar.valid_range.start()); - let end = end.unwrap_or(*scalar.valid_range.end()); - scalar.valid_range = start..=end; + let (start, end) = self.tcx.layout_scalar_valid_range(def.did); + match st.abi { + Abi::Scalar(ref mut scalar) | + Abi::ScalarPair(ref mut scalar, _) => { + // the asserts ensure that we are not using the + // `#[rustc_layout_scalar_valid_range(n)]` + // attribute to widen the range of anything as that would probably + // result in UB somewhere + if let Bound::Included(start) = start { + assert!(*scalar.valid_range.start() <= start); + scalar.valid_range = start..=*scalar.valid_range.end(); + } + if let Bound::Included(end) = end { + assert!(*scalar.valid_range.end() >= end); + scalar.valid_range = *scalar.valid_range.start()..=end; } - _ => bug!( - "nonscalar layout for rustc_layout_scalar_range type {:?}: {:#?}", - def, - st, - ), } + _ => bug!( + "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}", + def, + st, + ), } return Ok(tcx.intern_layout(st)); } @@ -1353,13 +1362,12 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { if def.variants.len() == 1 { if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 { return Ok(SizeSkeleton::Pointer { - non_zero: non_zero || - tcx.layout_scalar_range(def.did).map_or(false, |(start, end)| { - // `n..` for `n > 0` or `n..m` for `n > 0 && m > n` - start.map_or(true, |start| start > 0 && end.map_or(true, |end| { - end > start - })) - }), + non_zero: non_zero || match tcx.layout_scalar_valid_range(def.did) { + (Bound::Included(start), Bound::Unbounded) => start > 0, + (Bound::Included(start), Bound::Included(end)) => + 0 < start && start < end, + _ => false, + }, tail, }); } else { diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 2d1709f2374..0b5fb97f0e1 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -97,7 +97,7 @@ macro_rules! newtype_index { @vis [$v:vis] @debug_format [$debug_format:tt]) => ( #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] - #[rustc_layout_scalar_range_end($max)] + #[rustc_layout_scalar_valid_range_end($max)] $v struct $type { private: u32 } |
