]> git.lizzy.rs Git - rust.git/commitdiff
Address attribute naming and use `Bound` enum
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Mon, 10 Sep 2018 11:40:34 +0000 (13:40 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Tue, 11 Sep 2018 09:25:51 +0000 (11:25 +0200)
src/libcore/nonzero.rs
src/librustc/ty/context.rs
src/librustc/ty/layout.rs
src/librustc_data_structures/indexed_vec.rs

index 6f27d3207bb7ab841c967538016e389837554070..30067d7e163d21bf43e1f9ab466109c48a553efb 100644 (file)
@@ -15,7 +15,7 @@
 /// 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);
index 922308d51fb763e3000f68595225123271cddd32..9c759b38d38a500f35abd58a6d9e310e316a71c0 100644 (file)
@@ -66,7 +66,7 @@
 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 @@ pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
         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> {
index be9357dd4a7cf8e130f704232dbbd412234e50b4..71cdec0f83eca09dda8abaedb8d2400f2f1b7fe7 100644 (file)
@@ -20,6 +20,7 @@
 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 @@ enum StructKind {
 
                     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 @@ pub fn compute(ty: Ty<'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 {
index 2d1709f2374a9ceab6e46accb9757d7ac9d37a9c..0b5fb97f0e1fc7a2d6fa7532f7613124318b99b8 100644 (file)
@@ -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
         }