@@ -23,7 +23,7 @@ use std::fmt;
2323use std:: i128;
2424use std:: iter;
2525use std:: mem;
26- use std:: ops:: { Add , Sub , Mul , AddAssign , Deref , RangeInclusive } ;
26+ use std:: ops:: { Add , Sub , Mul , AddAssign , Deref , Range , RangeInclusive } ;
2727
2828use ich:: StableHashingContext ;
2929use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher ,
@@ -648,6 +648,25 @@ impl Scalar {
648648 false
649649 }
650650 }
651+
652+ /// Returns a range suitable to be passed to LLVM for range metadata.
653+ pub fn range_metadata < C : HasDataLayout > ( & self , cx : C ) -> Option < Range < u128 > > {
654+ // For a (max) value of -1, max will be `-1 as usize`, which overflows.
655+ // However, that is fine here (it would still represent the full range),
656+ // i.e., if the range is everything.
657+ let bits = self . value . size ( cx) . bits ( ) ;
658+ assert ! ( bits <= 128 ) ;
659+ let mask = !0u128 >> ( 128 - bits) ;
660+ let start = self . valid_range . start ;
661+ let end = self . valid_range . end . wrapping_add ( 1 ) ;
662+ if start & mask == end & mask {
663+ // The lo==hi case would be rejected by the LLVM verifier
664+ // (it would mean either an empty set, which is impossible, or the
665+ // entire range of the type, which is pointless).
666+ return None ;
667+ }
668+ Some ( start..end)
669+ }
651670}
652671
653672/// The first half of a fat pointer.
0 commit comments