auto merge of #17853 : alexcrichton/rust/issue-17718, r=pcwalton
This change is an implementation of [RFC 69][rfc] which adds a third kind of global to the language, `const`. This global is most similar to what the old `static` was, and if you're unsure about what to use then you should use a `const`. The semantics of these three kinds of globals are: * A `const` does not represent a memory location, but only a value. Constants are translated as rvalues, which means that their values are directly inlined at usage location (similar to a #define in C/C++). Constant values are, well, constant, and can not be modified. Any "modification" is actually a modification to a local value on the stack rather than the actual constant itself. Almost all values are allowed inside constants, whether they have interior mutability or not. There are a few minor restrictions listed in the RFC, but they should in general not come up too often. * A `static` now always represents a memory location (unconditionally). Any references to the same `static` are actually a reference to the same memory location. Only values whose types ascribe to `Sync` are allowed in a `static`. This restriction is in place because many threads may access a `static` concurrently. Lifting this restriction (and allowing unsafe access) is a future extension not implemented at this time. * A `static mut` continues to always represent a memory location. All references to a `static mut` continue to be `unsafe`. This is a large breaking change, and many programs will need to be updated accordingly. A summary of the breaking changes is: * Statics may no longer be used in patterns. Statics now always represent a memory location, which can sometimes be modified. To fix code, repurpose the matched-on-`static` to a `const`. static FOO: uint = 4; match n { FOO => { /* ... */ } _ => { /* ... */ } } change this code to: const FOO: uint = 4; match n { FOO => { /* ... */ } _ => { /* ... */ } } * Statics may no longer refer to other statics by value. Due to statics being able to change at runtime, allowing them to reference one another could possibly lead to confusing semantics. If you are in this situation, use a constant initializer instead. Note, however, that statics may reference other statics by address, however. * Statics may no longer be used in constant expressions, such as array lengths. This is due to the same restrictions as listed above. Use a `const` instead. [breaking-change] Closes #17718 [rfc]: https://github.com/rust-lang/rfcs/pull/246
This commit is contained in:
commit
f9fc49c06e
193 changed files with 3932 additions and 3152 deletions
|
@ -1383,44 +1383,87 @@ a = Cat { name: "Spotty".to_string(), weight: 2.7 };
|
|||
In this example, `Cat` is a _struct-like enum variant_,
|
||||
whereas `Dog` is simply called an enum variant.
|
||||
|
||||
### Static items
|
||||
### Constant items
|
||||
|
||||
```{.ebnf .gram}
|
||||
static_item : "static" ident ':' type '=' expr ';' ;
|
||||
const_item : "const" ident ':' type '=' expr ';' ;
|
||||
```
|
||||
|
||||
A *static item* is a named _constant value_ stored in the global data section
|
||||
of a crate. Immutable static items are stored in the read-only data section.
|
||||
The constant value bound to a static item is, like all constant values,
|
||||
evaluated at compile time. Static items have the `static` lifetime, which
|
||||
outlives all other lifetimes in a Rust program. Only values stored in the
|
||||
global data section (such as string constants and static items) can have the
|
||||
`static` lifetime; dynamically constructed values cannot safely be assigned the
|
||||
`static` lifetime. Static items are declared with the `static` keyword. A
|
||||
static item must have a _constant expression_ giving its definition.
|
||||
A *constant item* is a named _constant value_ which is not associated with a
|
||||
specific memory location in the program. Constants are essentially inlined
|
||||
wherever they are used, meaning that they are copied directly into the relevant
|
||||
context when used. References to the same constant are not necessarily
|
||||
guaranteed to refer to the same memory address.
|
||||
|
||||
Static items must be explicitly typed. The type may be `bool`, `char`,
|
||||
a number, or a type derived from those primitive types. The derived types are
|
||||
references with the `static` lifetime, fixed-size arrays, tuples, and structs.
|
||||
Constant values must not have destructors, and otherwise permit most forms of
|
||||
data. Constants may refer to the address of other constants, in which case the
|
||||
address will have the `static` lifetime. The compiler is, however, still at
|
||||
liberty to translate the constant many times, so the address referred to may not
|
||||
be stable.
|
||||
|
||||
Constants must be explicitly typed. The type may be `bool`, `char`, a number, or
|
||||
a type derived from those primitive types. The derived types are references with
|
||||
the `static` lifetime, fixed-size arrays, tuples, enum variants, and structs.
|
||||
|
||||
```
|
||||
static BIT1: uint = 1 << 0;
|
||||
static BIT2: uint = 1 << 1;
|
||||
const BIT1: uint = 1 << 0;
|
||||
const BIT2: uint = 1 << 1;
|
||||
|
||||
static BITS: [uint, ..2] = [BIT1, BIT2];
|
||||
static STRING: &'static str = "bitstring";
|
||||
const BITS: [uint, ..2] = [BIT1, BIT2];
|
||||
const STRING: &'static str = "bitstring";
|
||||
|
||||
struct BitsNStrings<'a> {
|
||||
mybits: [uint, ..2],
|
||||
mystring: &'a str
|
||||
}
|
||||
|
||||
static BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
|
||||
const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
|
||||
mybits: BITS,
|
||||
mystring: STRING
|
||||
};
|
||||
```
|
||||
|
||||
### Static items
|
||||
|
||||
```{.ebnf .gram}
|
||||
static_item : "static" ident ':' type '=' expr ';' ;
|
||||
```
|
||||
|
||||
A *static item* is similar to a *constant*, except that it represents a precise
|
||||
memory location in the program. A static is never "inlined" at the usage site,
|
||||
and all references to it refer to the same memory location. Static items have
|
||||
the `static` lifetime, which outlives all other lifetimes in a Rust program.
|
||||
Static items may be placed in read-only memory if they do not contain any
|
||||
interior mutability.
|
||||
|
||||
Statics may contain interior mutability through the `UnsafeCell` language item.
|
||||
All access to a static is safe, but there are a number of restrictions on
|
||||
statics:
|
||||
|
||||
* Statics may not contain any destructors.
|
||||
* The types of static values must ascribe to `Sync` to allow threadsafe access.
|
||||
* Statics may not refer to other statics by value, only by reference.
|
||||
* Constants cannot refer to statics.
|
||||
|
||||
Constants should in general be preferred over statics, unless large amounts of
|
||||
data are being stored, or single-address and mutability properties are required.
|
||||
|
||||
```
|
||||
use std::sync::atomic;
|
||||
|
||||
// Note that INIT_ATOMIC_UINT is a *const*, but it may be used to initialize a
|
||||
// static. This static can be modified, so it is not placed in read-only memory.
|
||||
static COUNTER: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
|
||||
|
||||
// This table is a candidate to be placed in read-only memory.
|
||||
static TABLE: &'static [uint] = &[1, 2, 3, /* ... */];
|
||||
|
||||
for slot in TABLE.iter() {
|
||||
println!("{}", slot);
|
||||
}
|
||||
COUNTER.fetch_add(1, atomic::SeqCst);
|
||||
```
|
||||
|
||||
#### Mutable statics
|
||||
|
||||
If a static item is declared with the `mut` keyword, then it is allowed to
|
||||
|
@ -1455,6 +1498,9 @@ unsafe fn bump_levels_unsafe2() -> uint {
|
|||
}
|
||||
```
|
||||
|
||||
Mutable statics have the same restrictions as normal statics, except that the
|
||||
type of the value is not required to ascribe to `Sync`.
|
||||
|
||||
### Traits
|
||||
|
||||
A _trait_ describes a set of method types.
|
||||
|
|
|
@ -333,14 +333,14 @@ def emit_property_module(f, mod, tbl, emit_fn):
|
|||
def emit_regex_module(f, cats, w_data):
|
||||
f.write("pub mod regex {\n")
|
||||
regex_class = "&'static [(char, char)]"
|
||||
class_table = "&'static [(&'static str, %s)]" % regex_class
|
||||
class_table = "&'static [(&'static str, &'static %s)]" % regex_class
|
||||
|
||||
emit_table(f, "UNICODE_CLASSES", cats, class_table,
|
||||
pfun=lambda x: "(\"%s\",super::%s::%s_table)" % (x[0], x[1], x[0]))
|
||||
pfun=lambda x: "(\"%s\",&super::%s::%s_table)" % (x[0], x[1], x[0]))
|
||||
|
||||
f.write(" pub static PERLD: %s = super::general_category::Nd_table;\n\n"
|
||||
f.write(" pub static PERLD: &'static %s = &super::general_category::Nd_table;\n\n"
|
||||
% regex_class)
|
||||
f.write(" pub static PERLS: %s = super::property::White_Space_table;\n\n"
|
||||
f.write(" pub static PERLS: &'static %s = &super::property::White_Space_table;\n\n"
|
||||
% regex_class)
|
||||
|
||||
emit_table(f, "PERLW", w_data, regex_class)
|
||||
|
|
|
@ -85,7 +85,7 @@ pub fn stats_print() {
|
|||
///
|
||||
/// This preserves the non-null invariant for types like `Box<T>`. The address may overlap with
|
||||
/// non-zero-size memory allocations.
|
||||
pub static EMPTY: *mut () = 0x1 as *mut ();
|
||||
pub const EMPTY: *mut () = 0x1 as *mut ();
|
||||
|
||||
/// The allocator for unique pointers.
|
||||
#[cfg(not(test))]
|
||||
|
|
|
@ -34,10 +34,10 @@ use slice::{Items, MutItems};
|
|||
use slice;
|
||||
|
||||
// FIXME: #5244: need to manually update the TrieNode constructor
|
||||
static SHIFT: uint = 4;
|
||||
static SIZE: uint = 1 << SHIFT;
|
||||
static MASK: uint = SIZE - 1;
|
||||
static NUM_CHUNKS: uint = uint::BITS / SHIFT;
|
||||
const SHIFT: uint = 4;
|
||||
const SIZE: uint = 1 << SHIFT;
|
||||
const MASK: uint = SIZE - 1;
|
||||
const NUM_CHUNKS: uint = uint::BITS / SHIFT;
|
||||
|
||||
#[deriving(Clone)]
|
||||
enum Child<T> {
|
||||
|
|
|
@ -77,19 +77,19 @@ pub enum Ordering {
|
|||
|
||||
/// An `AtomicBool` initialized to `false`
|
||||
#[unstable = "may be renamed, pending conventions for static initalizers"]
|
||||
pub static INIT_ATOMIC_BOOL: AtomicBool =
|
||||
pub const INIT_ATOMIC_BOOL: AtomicBool =
|
||||
AtomicBool { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy };
|
||||
/// An `AtomicInt` initialized to `0`
|
||||
#[unstable = "may be renamed, pending conventions for static initalizers"]
|
||||
pub static INIT_ATOMIC_INT: AtomicInt =
|
||||
pub const INIT_ATOMIC_INT: AtomicInt =
|
||||
AtomicInt { v: UnsafeCell { value: 0 }, nocopy: marker::NoCopy };
|
||||
/// An `AtomicUint` initialized to `0`
|
||||
#[unstable = "may be renamed, pending conventions for static initalizers"]
|
||||
pub static INIT_ATOMIC_UINT: AtomicUint =
|
||||
pub const INIT_ATOMIC_UINT: AtomicUint =
|
||||
AtomicUint { v: UnsafeCell { value: 0, }, nocopy: marker::NoCopy };
|
||||
|
||||
// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
|
||||
static UINT_TRUE: uint = -1;
|
||||
const UINT_TRUE: uint = -1;
|
||||
|
||||
#[stable]
|
||||
impl AtomicBool {
|
||||
|
|
|
@ -219,8 +219,8 @@ pub struct RefCell<T> {
|
|||
// Values [1, MAX-1] represent the number of `Ref` active
|
||||
// (will not outgrow its range since `uint` is the size of the address space)
|
||||
type BorrowFlag = uint;
|
||||
static UNUSED: BorrowFlag = 0;
|
||||
static WRITING: BorrowFlag = -1;
|
||||
const UNUSED: BorrowFlag = 0;
|
||||
const WRITING: BorrowFlag = -1;
|
||||
|
||||
impl<T> RefCell<T> {
|
||||
/// Create a new `RefCell` containing `value`
|
||||
|
|
|
@ -63,7 +63,7 @@ static MAX_THREE_B: u32 = 0x10000u32;
|
|||
*/
|
||||
|
||||
/// The highest valid code point
|
||||
pub static MAX: char = '\U0010ffff';
|
||||
pub const MAX: char = '\U0010ffff';
|
||||
|
||||
/// Converts from `u32` to a `char`
|
||||
#[inline]
|
||||
|
|
|
@ -20,29 +20,29 @@ use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
|
|||
use num::Float;
|
||||
use option::Option;
|
||||
|
||||
pub static RADIX: uint = 2u;
|
||||
pub const RADIX: uint = 2u;
|
||||
|
||||
pub static MANTISSA_DIGITS: uint = 24u;
|
||||
pub static DIGITS: uint = 6u;
|
||||
pub const MANTISSA_DIGITS: uint = 24u;
|
||||
pub const DIGITS: uint = 6u;
|
||||
|
||||
pub static EPSILON: f32 = 1.19209290e-07_f32;
|
||||
pub const EPSILON: f32 = 1.19209290e-07_f32;
|
||||
|
||||
/// Smallest finite f32 value
|
||||
pub static MIN_VALUE: f32 = -3.40282347e+38_f32;
|
||||
pub const MIN_VALUE: f32 = -3.40282347e+38_f32;
|
||||
/// Smallest positive, normalized f32 value
|
||||
pub static MIN_POS_VALUE: f32 = 1.17549435e-38_f32;
|
||||
pub const MIN_POS_VALUE: f32 = 1.17549435e-38_f32;
|
||||
/// Largest finite f32 value
|
||||
pub static MAX_VALUE: f32 = 3.40282347e+38_f32;
|
||||
pub const MAX_VALUE: f32 = 3.40282347e+38_f32;
|
||||
|
||||
pub static MIN_EXP: int = -125;
|
||||
pub static MAX_EXP: int = 128;
|
||||
pub const MIN_EXP: int = -125;
|
||||
pub const MAX_EXP: int = 128;
|
||||
|
||||
pub static MIN_10_EXP: int = -37;
|
||||
pub static MAX_10_EXP: int = 38;
|
||||
pub const MIN_10_EXP: int = -37;
|
||||
pub const MAX_10_EXP: int = 38;
|
||||
|
||||
pub static NAN: f32 = 0.0_f32/0.0_f32;
|
||||
pub static INFINITY: f32 = 1.0_f32/0.0_f32;
|
||||
pub static NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
|
||||
pub const NAN: f32 = 0.0_f32/0.0_f32;
|
||||
pub const INFINITY: f32 = 1.0_f32/0.0_f32;
|
||||
pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
|
||||
|
||||
/// Various useful constants.
|
||||
pub mod consts {
|
||||
|
@ -53,55 +53,55 @@ pub mod consts {
|
|||
// of `Float`.
|
||||
|
||||
/// Archimedes' constant
|
||||
pub static PI: f32 = 3.14159265358979323846264338327950288_f32;
|
||||
pub const PI: f32 = 3.14159265358979323846264338327950288_f32;
|
||||
|
||||
/// pi * 2.0
|
||||
pub static PI_2: f32 = 6.28318530717958647692528676655900576_f32;
|
||||
pub const PI_2: f32 = 6.28318530717958647692528676655900576_f32;
|
||||
|
||||
/// pi/2.0
|
||||
pub static FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
|
||||
pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
|
||||
|
||||
/// pi/3.0
|
||||
pub static FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32;
|
||||
pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32;
|
||||
|
||||
/// pi/4.0
|
||||
pub static FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
|
||||
pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
|
||||
|
||||
/// pi/6.0
|
||||
pub static FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32;
|
||||
pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32;
|
||||
|
||||
/// pi/8.0
|
||||
pub static FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32;
|
||||
pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32;
|
||||
|
||||
/// 1.0/pi
|
||||
pub static FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
|
||||
pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
|
||||
|
||||
/// 2.0/pi
|
||||
pub static FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
|
||||
pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
|
||||
|
||||
/// 2.0/sqrt(pi)
|
||||
pub static FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32;
|
||||
pub const FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32;
|
||||
|
||||
/// sqrt(2.0)
|
||||
pub static SQRT2: f32 = 1.41421356237309504880168872420969808_f32;
|
||||
pub const SQRT2: f32 = 1.41421356237309504880168872420969808_f32;
|
||||
|
||||
/// 1.0/sqrt(2.0)
|
||||
pub static FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32;
|
||||
pub const FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32;
|
||||
|
||||
/// Euler's number
|
||||
pub static E: f32 = 2.71828182845904523536028747135266250_f32;
|
||||
pub const E: f32 = 2.71828182845904523536028747135266250_f32;
|
||||
|
||||
/// log2(e)
|
||||
pub static LOG2_E: f32 = 1.44269504088896340735992468100189214_f32;
|
||||
pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32;
|
||||
|
||||
/// log10(e)
|
||||
pub static LOG10_E: f32 = 0.434294481903251827651128918916605082_f32;
|
||||
pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32;
|
||||
|
||||
/// ln(2.0)
|
||||
pub static LN_2: f32 = 0.693147180559945309417232121458176568_f32;
|
||||
pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32;
|
||||
|
||||
/// ln(10.0)
|
||||
pub static LN_10: f32 = 2.30258509299404568401799145468436421_f32;
|
||||
pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32;
|
||||
}
|
||||
|
||||
impl Float for f32 {
|
||||
|
@ -143,8 +143,8 @@ impl Float for f32 {
|
|||
/// is going to be tested, it is generally faster to use the specific
|
||||
/// predicate instead.
|
||||
fn classify(self) -> FPCategory {
|
||||
static EXP_MASK: u32 = 0x7f800000;
|
||||
static MAN_MASK: u32 = 0x007fffff;
|
||||
const EXP_MASK: u32 = 0x7f800000;
|
||||
const MAN_MASK: u32 = 0x007fffff;
|
||||
|
||||
let bits: u32 = unsafe { mem::transmute(self) };
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
|
|
|
@ -24,31 +24,31 @@ use option::Option;
|
|||
// constants are implemented in favour of referencing the respective
|
||||
// members of `Bounded` and `Float`.
|
||||
|
||||
pub static RADIX: uint = 2u;
|
||||
pub const RADIX: uint = 2u;
|
||||
|
||||
pub static MANTISSA_DIGITS: uint = 53u;
|
||||
pub static DIGITS: uint = 15u;
|
||||
pub const MANTISSA_DIGITS: uint = 53u;
|
||||
pub const DIGITS: uint = 15u;
|
||||
|
||||
pub static EPSILON: f64 = 2.2204460492503131e-16_f64;
|
||||
pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
|
||||
|
||||
/// Smallest finite f64 value
|
||||
pub static MIN_VALUE: f64 = -1.7976931348623157e+308_f64;
|
||||
pub const MIN_VALUE: f64 = -1.7976931348623157e+308_f64;
|
||||
/// Smallest positive, normalized f64 value
|
||||
pub static MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64;
|
||||
pub const MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64;
|
||||
/// Largest finite f64 value
|
||||
pub static MAX_VALUE: f64 = 1.7976931348623157e+308_f64;
|
||||
pub const MAX_VALUE: f64 = 1.7976931348623157e+308_f64;
|
||||
|
||||
pub static MIN_EXP: int = -1021;
|
||||
pub static MAX_EXP: int = 1024;
|
||||
pub const MIN_EXP: int = -1021;
|
||||
pub const MAX_EXP: int = 1024;
|
||||
|
||||
pub static MIN_10_EXP: int = -307;
|
||||
pub static MAX_10_EXP: int = 308;
|
||||
pub const MIN_10_EXP: int = -307;
|
||||
pub const MAX_10_EXP: int = 308;
|
||||
|
||||
pub static NAN: f64 = 0.0_f64/0.0_f64;
|
||||
pub const NAN: f64 = 0.0_f64/0.0_f64;
|
||||
|
||||
pub static INFINITY: f64 = 1.0_f64/0.0_f64;
|
||||
pub const INFINITY: f64 = 1.0_f64/0.0_f64;
|
||||
|
||||
pub static NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
|
||||
pub const NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
|
||||
|
||||
/// Various useful constants.
|
||||
pub mod consts {
|
||||
|
@ -59,55 +59,55 @@ pub mod consts {
|
|||
// of `Float`.
|
||||
|
||||
/// Archimedes' constant
|
||||
pub static PI: f64 = 3.14159265358979323846264338327950288_f64;
|
||||
pub const PI: f64 = 3.14159265358979323846264338327950288_f64;
|
||||
|
||||
/// pi * 2.0
|
||||
pub static PI_2: f64 = 6.28318530717958647692528676655900576_f64;
|
||||
pub const PI_2: f64 = 6.28318530717958647692528676655900576_f64;
|
||||
|
||||
/// pi/2.0
|
||||
pub static FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
|
||||
pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
|
||||
|
||||
/// pi/3.0
|
||||
pub static FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64;
|
||||
pub const FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64;
|
||||
|
||||
/// pi/4.0
|
||||
pub static FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64;
|
||||
pub const FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64;
|
||||
|
||||
/// pi/6.0
|
||||
pub static FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64;
|
||||
pub const FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64;
|
||||
|
||||
/// pi/8.0
|
||||
pub static FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64;
|
||||
pub const FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64;
|
||||
|
||||
/// 1.0/pi
|
||||
pub static FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
|
||||
pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
|
||||
|
||||
/// 2.0/pi
|
||||
pub static FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64;
|
||||
pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64;
|
||||
|
||||
/// 2.0/sqrt(pi)
|
||||
pub static FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64;
|
||||
pub const FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64;
|
||||
|
||||
/// sqrt(2.0)
|
||||
pub static SQRT2: f64 = 1.41421356237309504880168872420969808_f64;
|
||||
pub const SQRT2: f64 = 1.41421356237309504880168872420969808_f64;
|
||||
|
||||
/// 1.0/sqrt(2.0)
|
||||
pub static FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64;
|
||||
pub const FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64;
|
||||
|
||||
/// Euler's number
|
||||
pub static E: f64 = 2.71828182845904523536028747135266250_f64;
|
||||
pub const E: f64 = 2.71828182845904523536028747135266250_f64;
|
||||
|
||||
/// log2(e)
|
||||
pub static LOG2_E: f64 = 1.44269504088896340735992468100189214_f64;
|
||||
pub const LOG2_E: f64 = 1.44269504088896340735992468100189214_f64;
|
||||
|
||||
/// log10(e)
|
||||
pub static LOG10_E: f64 = 0.434294481903251827651128918916605082_f64;
|
||||
pub const LOG10_E: f64 = 0.434294481903251827651128918916605082_f64;
|
||||
|
||||
/// ln(2.0)
|
||||
pub static LN_2: f64 = 0.693147180559945309417232121458176568_f64;
|
||||
pub const LN_2: f64 = 0.693147180559945309417232121458176568_f64;
|
||||
|
||||
/// ln(10.0)
|
||||
pub static LN_10: f64 = 2.30258509299404568401799145468436421_f64;
|
||||
pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64;
|
||||
}
|
||||
|
||||
impl Float for f64 {
|
||||
|
@ -149,8 +149,8 @@ impl Float for f64 {
|
|||
/// is going to be tested, it is generally faster to use the specific
|
||||
/// predicate instead.
|
||||
fn classify(self) -> FPCategory {
|
||||
static EXP_MASK: u64 = 0x7ff0000000000000;
|
||||
static MAN_MASK: u64 = 0x000fffffffffffff;
|
||||
const EXP_MASK: u64 = 0x7ff0000000000000;
|
||||
const MAN_MASK: u64 = 0x000fffffffffffff;
|
||||
|
||||
let bits: u64 = unsafe { mem::transmute(self) };
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
|
|
|
@ -16,20 +16,20 @@ macro_rules! int_module (($T:ty, $bits:expr) => (
|
|||
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
|
||||
// calling the `mem::size_of` function.
|
||||
#[unstable]
|
||||
pub static BITS : uint = $bits;
|
||||
pub const BITS : uint = $bits;
|
||||
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
|
||||
// calling the `mem::size_of` function.
|
||||
#[unstable]
|
||||
pub static BYTES : uint = ($bits / 8);
|
||||
pub const BYTES : uint = ($bits / 8);
|
||||
|
||||
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
|
||||
// calling the `Bounded::min_value` function.
|
||||
#[unstable]
|
||||
pub static MIN: $T = (-1 as $T) << (BITS - 1);
|
||||
pub const MIN: $T = (-1 as $T) << (BITS - 1);
|
||||
// FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0.
|
||||
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
|
||||
// calling the `Bounded::max_value` function.
|
||||
#[unstable]
|
||||
pub static MAX: $T = !MIN;
|
||||
pub const MAX: $T = !MIN;
|
||||
|
||||
))
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (
|
||||
|
||||
#[unstable]
|
||||
pub static BITS : uint = $bits;
|
||||
pub const BITS : uint = $bits;
|
||||
#[unstable]
|
||||
pub static BYTES : uint = ($bits / 8);
|
||||
pub const BYTES : uint = ($bits / 8);
|
||||
|
||||
#[unstable]
|
||||
pub static MIN: $T = 0 as $T;
|
||||
pub const MIN: $T = 0 as $T;
|
||||
#[unstable]
|
||||
pub static MAX: $T = 0 as $T - 1 as $T;
|
||||
pub const MAX: $T = 0 as $T - 1 as $T;
|
||||
|
||||
))
|
||||
|
|
|
@ -1049,9 +1049,9 @@ pub struct CharRange {
|
|||
}
|
||||
|
||||
/// Mask of the value bits of a continuation byte
|
||||
static CONT_MASK: u8 = 0b0011_1111u8;
|
||||
const CONT_MASK: u8 = 0b0011_1111u8;
|
||||
/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
|
||||
static TAG_CONT_U8: u8 = 0b1000_0000u8;
|
||||
const TAG_CONT_U8: u8 = 0b1000_0000u8;
|
||||
|
||||
/// Unsafe operations
|
||||
pub mod raw {
|
||||
|
|
3312
src/liblibc/lib.rs
3312
src/liblibc/lib.rs
File diff suppressed because it is too large
Load diff
|
@ -188,10 +188,10 @@ mod directive;
|
|||
|
||||
/// Maximum logging level of a module that can be specified. Common logging
|
||||
/// levels are found in the DEBUG/INFO/WARN/ERROR constants.
|
||||
pub static MAX_LOG_LEVEL: u32 = 255;
|
||||
pub const MAX_LOG_LEVEL: u32 = 255;
|
||||
|
||||
/// The default logging level of a crate if no other is specified.
|
||||
static DEFAULT_LOG_LEVEL: u32 = 1;
|
||||
const DEFAULT_LOG_LEVEL: u32 = 1;
|
||||
|
||||
/// An unsafe constant that is the maximum logging level of any module
|
||||
/// specified. This is the first line of defense to determining whether a
|
||||
|
@ -205,13 +205,13 @@ static mut DIRECTIVES: *const Vec<directive::LogDirective> =
|
|||
static mut FILTER: *const Regex = 0 as *const _;
|
||||
|
||||
/// Debug log level
|
||||
pub static DEBUG: u32 = 4;
|
||||
pub const DEBUG: u32 = 4;
|
||||
/// Info log level
|
||||
pub static INFO: u32 = 3;
|
||||
pub const INFO: u32 = 3;
|
||||
/// Warn log level
|
||||
pub static WARN: u32 = 2;
|
||||
pub const WARN: u32 = 2;
|
||||
/// Error log level
|
||||
pub static ERROR: u32 = 1;
|
||||
pub const ERROR: u32 = 1;
|
||||
|
||||
local_data_key!(local_logger: Box<Logger + Send>)
|
||||
|
||||
|
|
|
@ -23,41 +23,41 @@ use libc;
|
|||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"))]
|
||||
pub static FIONBIO: libc::c_ulong = 0x8004667e;
|
||||
pub const FIONBIO: libc::c_ulong = 0x8004667e;
|
||||
#[cfg(any(all(target_os = "linux",
|
||||
any(target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "arm")),
|
||||
target_os = "android"))]
|
||||
pub static FIONBIO: libc::c_ulong = 0x5421;
|
||||
pub const FIONBIO: libc::c_ulong = 0x5421;
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips", target_arch = "mipsel")))]
|
||||
pub static FIONBIO: libc::c_ulong = 0x667e;
|
||||
pub const FIONBIO: libc::c_ulong = 0x667e;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"))]
|
||||
pub static FIOCLEX: libc::c_ulong = 0x20006601;
|
||||
pub const FIOCLEX: libc::c_ulong = 0x20006601;
|
||||
#[cfg(any(all(target_os = "linux",
|
||||
any(target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "arm")),
|
||||
target_os = "android"))]
|
||||
pub static FIOCLEX: libc::c_ulong = 0x5451;
|
||||
pub const FIOCLEX: libc::c_ulong = 0x5451;
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips", target_arch = "mipsel")))]
|
||||
pub static FIOCLEX: libc::c_ulong = 0x6601;
|
||||
pub const FIOCLEX: libc::c_ulong = 0x6601;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"))]
|
||||
pub static MSG_DONTWAIT: libc::c_int = 0x80;
|
||||
pub const MSG_DONTWAIT: libc::c_int = 0x80;
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub static MSG_DONTWAIT: libc::c_int = 0x40;
|
||||
pub const MSG_DONTWAIT: libc::c_int = 0x40;
|
||||
|
||||
pub static WNOHANG: libc::c_int = 1;
|
||||
pub const WNOHANG: libc::c_int = 1;
|
||||
|
||||
extern {
|
||||
pub fn gettimeofday(timeval: *mut libc::timeval,
|
||||
|
@ -89,7 +89,7 @@ extern {
|
|||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
mod select {
|
||||
pub static FD_SETSIZE: uint = 1024;
|
||||
pub const FD_SETSIZE: uint = 1024;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fd_set {
|
||||
|
@ -109,7 +109,7 @@ mod select {
|
|||
use std::uint;
|
||||
use libc;
|
||||
|
||||
pub static FD_SETSIZE: uint = 1024;
|
||||
pub const FD_SETSIZE: uint = 1024;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct fd_set {
|
||||
|
@ -131,14 +131,14 @@ mod select {
|
|||
mod signal {
|
||||
use libc;
|
||||
|
||||
pub static SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
|
||||
pub static SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
|
||||
pub static SA_NODEFER: libc::c_ulong = 0x40000000;
|
||||
pub static SA_ONSTACK: libc::c_ulong = 0x08000000;
|
||||
pub static SA_RESETHAND: libc::c_ulong = 0x80000000;
|
||||
pub static SA_RESTART: libc::c_ulong = 0x10000000;
|
||||
pub static SA_SIGINFO: libc::c_ulong = 0x00000004;
|
||||
pub static SIGCHLD: libc::c_int = 17;
|
||||
pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
|
||||
pub const SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
|
||||
pub const SA_NODEFER: libc::c_ulong = 0x40000000;
|
||||
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
|
||||
pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
|
||||
pub const SA_RESTART: libc::c_ulong = 0x10000000;
|
||||
pub const SA_SIGINFO: libc::c_ulong = 0x00000004;
|
||||
pub const SIGCHLD: libc::c_int = 17;
|
||||
|
||||
// This definition is not as accurate as it could be, {pid, uid, status} is
|
||||
// actually a giant union. Currently we're only interested in these fields,
|
||||
|
@ -179,14 +179,14 @@ mod signal {
|
|||
mod signal {
|
||||
use libc;
|
||||
|
||||
pub static SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
|
||||
pub static SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
|
||||
pub static SA_NODEFER: libc::c_ulong = 0x40000000;
|
||||
pub static SA_ONSTACK: libc::c_ulong = 0x08000000;
|
||||
pub static SA_RESETHAND: libc::c_ulong = 0x80000000;
|
||||
pub static SA_RESTART: libc::c_ulong = 0x10000000;
|
||||
pub static SA_SIGINFO: libc::c_ulong = 0x00000008;
|
||||
pub static SIGCHLD: libc::c_int = 18;
|
||||
pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
|
||||
pub const SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
|
||||
pub const SA_NODEFER: libc::c_ulong = 0x40000000;
|
||||
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
|
||||
pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
|
||||
pub const SA_RESTART: libc::c_ulong = 0x10000000;
|
||||
pub const SA_SIGINFO: libc::c_ulong = 0x00000008;
|
||||
pub const SIGCHLD: libc::c_int = 18;
|
||||
|
||||
// This definition is not as accurate as it could be, {pid, uid, status} is
|
||||
// actually a giant union. Currently we're only interested in these fields,
|
||||
|
@ -223,14 +223,14 @@ mod signal {
|
|||
mod signal {
|
||||
use libc;
|
||||
|
||||
pub static SA_ONSTACK: libc::c_int = 0x0001;
|
||||
pub static SA_RESTART: libc::c_int = 0x0002;
|
||||
pub static SA_RESETHAND: libc::c_int = 0x0004;
|
||||
pub static SA_NOCLDSTOP: libc::c_int = 0x0008;
|
||||
pub static SA_NODEFER: libc::c_int = 0x0010;
|
||||
pub static SA_NOCLDWAIT: libc::c_int = 0x0020;
|
||||
pub static SA_SIGINFO: libc::c_int = 0x0040;
|
||||
pub static SIGCHLD: libc::c_int = 20;
|
||||
pub const SA_ONSTACK: libc::c_int = 0x0001;
|
||||
pub const SA_RESTART: libc::c_int = 0x0002;
|
||||
pub const SA_RESETHAND: libc::c_int = 0x0004;
|
||||
pub const SA_NOCLDSTOP: libc::c_int = 0x0008;
|
||||
pub const SA_NODEFER: libc::c_int = 0x0010;
|
||||
pub const SA_NOCLDWAIT: libc::c_int = 0x0020;
|
||||
pub const SA_SIGINFO: libc::c_int = 0x0040;
|
||||
pub const SIGCHLD: libc::c_int = 20;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub type sigset_t = u32;
|
||||
|
|
|
@ -14,26 +14,26 @@
|
|||
|
||||
use libc;
|
||||
|
||||
pub static WSADESCRIPTION_LEN: uint = 256;
|
||||
pub static WSASYS_STATUS_LEN: uint = 128;
|
||||
pub static FIONBIO: libc::c_long = 0x8004667e;
|
||||
static FD_SETSIZE: uint = 64;
|
||||
pub static MSG_DONTWAIT: libc::c_int = 0;
|
||||
pub static ERROR_ILLEGAL_CHARACTER: libc::c_int = 582;
|
||||
pub static ENABLE_ECHO_INPUT: libc::DWORD = 0x4;
|
||||
pub static ENABLE_EXTENDED_FLAGS: libc::DWORD = 0x80;
|
||||
pub static ENABLE_INSERT_MODE: libc::DWORD = 0x20;
|
||||
pub static ENABLE_LINE_INPUT: libc::DWORD = 0x2;
|
||||
pub static ENABLE_PROCESSED_INPUT: libc::DWORD = 0x1;
|
||||
pub static ENABLE_QUICK_EDIT_MODE: libc::DWORD = 0x40;
|
||||
pub static WSA_INVALID_EVENT: WSAEVENT = 0 as WSAEVENT;
|
||||
pub const WSADESCRIPTION_LEN: uint = 256;
|
||||
pub const WSASYS_STATUS_LEN: uint = 128;
|
||||
pub const FIONBIO: libc::c_long = 0x8004667e;
|
||||
pub const FD_SETSIZE: uint = 64;
|
||||
pub const MSG_DONTWAIT: libc::c_int = 0;
|
||||
pub const ERROR_ILLEGAL_CHARACTER: libc::c_int = 582;
|
||||
pub const ENABLE_ECHO_INPUT: libc::DWORD = 0x4;
|
||||
pub const ENABLE_EXTENDED_FLAGS: libc::DWORD = 0x80;
|
||||
pub const ENABLE_INSERT_MODE: libc::DWORD = 0x20;
|
||||
pub const ENABLE_LINE_INPUT: libc::DWORD = 0x2;
|
||||
pub const ENABLE_PROCESSED_INPUT: libc::DWORD = 0x1;
|
||||
pub const ENABLE_QUICK_EDIT_MODE: libc::DWORD = 0x40;
|
||||
pub const WSA_INVALID_EVENT: WSAEVENT = 0 as WSAEVENT;
|
||||
|
||||
pub static FD_ACCEPT: libc::c_long = 0x08;
|
||||
pub static FD_MAX_EVENTS: uint = 10;
|
||||
pub static WSA_INFINITE: libc::DWORD = libc::INFINITE;
|
||||
pub static WSA_WAIT_TIMEOUT: libc::DWORD = libc::consts::os::extra::WAIT_TIMEOUT;
|
||||
pub static WSA_WAIT_EVENT_0: libc::DWORD = libc::consts::os::extra::WAIT_OBJECT_0;
|
||||
pub static WSA_WAIT_FAILED: libc::DWORD = libc::consts::os::extra::WAIT_FAILED;
|
||||
pub const FD_ACCEPT: libc::c_long = 0x08;
|
||||
pub const FD_MAX_EVENTS: uint = 10;
|
||||
pub const WSA_INFINITE: libc::DWORD = libc::INFINITE;
|
||||
pub const WSA_WAIT_TIMEOUT: libc::DWORD = libc::consts::os::extra::WAIT_TIMEOUT;
|
||||
pub const WSA_WAIT_EVENT_0: libc::DWORD = libc::consts::os::extra::WAIT_OBJECT_0;
|
||||
pub const WSA_WAIT_FAILED: libc::DWORD = libc::consts::os::extra::WAIT_FAILED;
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(target_arch = "x86")]
|
||||
|
|
|
@ -77,7 +77,7 @@ pub type BigDigit = u32;
|
|||
/// size is the double of the size of `BigDigit`.
|
||||
pub type DoubleBigDigit = u64;
|
||||
|
||||
pub static ZERO_BIG_DIGIT: BigDigit = 0;
|
||||
pub const ZERO_BIG_DIGIT: BigDigit = 0;
|
||||
static ZERO_VEC: [BigDigit, ..1] = [ZERO_BIG_DIGIT];
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -87,10 +87,10 @@ pub mod BigDigit {
|
|||
|
||||
// `DoubleBigDigit` size dependent
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static bits: uint = 32;
|
||||
pub const bits: uint = 32;
|
||||
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static base: DoubleBigDigit = 1 << bits;
|
||||
pub const base: DoubleBigDigit = 1 << bits;
|
||||
#[allow(non_uppercase_statics)]
|
||||
static lo_mask: DoubleBigDigit = (-1 as DoubleBigDigit) >> bits;
|
||||
|
||||
|
|
|
@ -194,13 +194,13 @@ mod test {
|
|||
use std::num::{Zero, One, Float};
|
||||
use std::hash::hash;
|
||||
|
||||
pub static _0_0i : Complex64 = Complex { re: 0.0, im: 0.0 };
|
||||
pub static _1_0i : Complex64 = Complex { re: 1.0, im: 0.0 };
|
||||
pub static _1_1i : Complex64 = Complex { re: 1.0, im: 1.0 };
|
||||
pub static _0_1i : Complex64 = Complex { re: 0.0, im: 1.0 };
|
||||
pub static _neg1_1i : Complex64 = Complex { re: -1.0, im: 1.0 };
|
||||
pub static _05_05i : Complex64 = Complex { re: 0.5, im: 0.5 };
|
||||
pub static all_consts : [Complex64, .. 5] = [_0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i];
|
||||
pub const _0_0i : Complex64 = Complex { re: 0.0, im: 0.0 };
|
||||
pub const _1_0i : Complex64 = Complex { re: 1.0, im: 0.0 };
|
||||
pub const _1_1i : Complex64 = Complex { re: 1.0, im: 1.0 };
|
||||
pub const _0_1i : Complex64 = Complex { re: 0.0, im: 1.0 };
|
||||
pub const _neg1_1i : Complex64 = Complex { re: -1.0, im: 1.0 };
|
||||
pub const _05_05i : Complex64 = Complex { re: 0.5, im: 0.5 };
|
||||
pub const all_consts : [Complex64, .. 5] = [_0_0i, _1_0i, _1_1i, _neg1_1i, _05_05i];
|
||||
|
||||
#[test]
|
||||
fn test_consts() {
|
||||
|
|
|
@ -14,9 +14,9 @@ use core::prelude::*;
|
|||
|
||||
use {Rng, SeedableRng, Rand};
|
||||
|
||||
static KEY_WORDS : uint = 8; // 8 words for the 256-bit key
|
||||
static STATE_WORDS : uint = 16;
|
||||
static CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of this writing
|
||||
const KEY_WORDS : uint = 8; // 8 words for the 256-bit key
|
||||
const STATE_WORDS : uint = 16;
|
||||
const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of this writing
|
||||
|
||||
/// A random number generator that uses the ChaCha20 algorithm [1].
|
||||
///
|
||||
|
|
|
@ -16,9 +16,9 @@ use core::slice::raw;
|
|||
|
||||
use {Rng, SeedableRng, Rand};
|
||||
|
||||
static RAND_SIZE_LEN: u32 = 8;
|
||||
static RAND_SIZE: u32 = 1 << (RAND_SIZE_LEN as uint);
|
||||
static RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint);
|
||||
const RAND_SIZE_LEN: u32 = 8;
|
||||
const RAND_SIZE: u32 = 1 << (RAND_SIZE_LEN as uint);
|
||||
const RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint);
|
||||
|
||||
/// A random number generator that uses the ISAAC algorithm[1].
|
||||
///
|
||||
|
@ -251,8 +251,8 @@ impl Rand for IsaacRng {
|
|||
}
|
||||
}
|
||||
|
||||
static RAND_SIZE_64_LEN: uint = 8;
|
||||
static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
|
||||
const RAND_SIZE_64_LEN: uint = 8;
|
||||
const RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
|
||||
|
||||
/// A random number generator that uses ISAAC-64[1], the 64-bit
|
||||
/// variant of the ISAAC algorithm.
|
||||
|
@ -356,8 +356,8 @@ impl Isaac64Rng {
|
|||
// abbreviations
|
||||
let mut a = self.a;
|
||||
let mut b = self.b + self.c;
|
||||
static MIDPOINT: uint = RAND_SIZE_64 / 2;
|
||||
static MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
|
||||
const MIDPOINT: uint = RAND_SIZE_64 / 2;
|
||||
const MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
|
||||
macro_rules! ind (
|
||||
($x:expr) => {
|
||||
*self.mem.unsafe_get(($x as uint >> 3) & (RAND_SIZE_64 - 1))
|
||||
|
|
|
@ -162,12 +162,12 @@ impl BuildAst {
|
|||
/// expression.
|
||||
pub type Flags = u8;
|
||||
|
||||
pub static FLAG_EMPTY: u8 = 0;
|
||||
pub static FLAG_NOCASE: u8 = 1 << 0; // i
|
||||
pub static FLAG_MULTI: u8 = 1 << 1; // m
|
||||
pub static FLAG_DOTNL: u8 = 1 << 2; // s
|
||||
pub static FLAG_SWAP_GREED: u8 = 1 << 3; // U
|
||||
pub static FLAG_NEGATED: u8 = 1 << 4; // char class or not word boundary
|
||||
pub const FLAG_EMPTY: u8 = 0;
|
||||
pub const FLAG_NOCASE: u8 = 1 << 0; // i
|
||||
pub const FLAG_MULTI: u8 = 1 << 1; // m
|
||||
pub const FLAG_DOTNL: u8 = 1 << 2; // s
|
||||
pub const FLAG_SWAP_GREED: u8 = 1 << 3; // U
|
||||
pub const FLAG_NEGATED: u8 = 1 << 4; // char class or not word boundary
|
||||
|
||||
struct Parser<'a> {
|
||||
// The input, parsed only as a sequence of UTF8 code points.
|
||||
|
@ -1025,7 +1025,7 @@ fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
|
|||
}
|
||||
|
||||
type Class = &'static [(char, char)];
|
||||
type NamedClasses = &'static [(&'static str, Class)];
|
||||
type NamedClasses = &'static [(&'static str, &'static Class)];
|
||||
|
||||
static ASCII_CLASSES: NamedClasses = &[
|
||||
// Classes must be in alphabetical order so that bsearch works.
|
||||
|
@ -1044,19 +1044,34 @@ static ASCII_CLASSES: NamedClasses = &[
|
|||
// [:word:] word characters (== [0-9A-Za-z_])
|
||||
// [:xdigit:] hex digit (== [0-9A-Fa-f])
|
||||
// Taken from: http://golang.org/pkg/regex/syntax/
|
||||
("alnum", &[('0', '9'), ('A', 'Z'), ('a', 'z')]),
|
||||
("alpha", &[('A', 'Z'), ('a', 'z')]),
|
||||
("ascii", &[('\x00', '\x7F')]),
|
||||
("blank", &[(' ', ' '), ('\t', '\t')]),
|
||||
("cntrl", &[('\x00', '\x1F'), ('\x7F', '\x7F')]),
|
||||
("digit", &[('0', '9')]),
|
||||
("graph", &[('!', '~')]),
|
||||
("lower", &[('a', 'z')]),
|
||||
("print", &[(' ', '~')]),
|
||||
("punct", &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')]),
|
||||
("space", &[('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'), ('\x0C', '\x0C'),
|
||||
('\r', '\r'), (' ', ' ')]),
|
||||
("upper", &[('A', 'Z')]),
|
||||
("word", &[('0', '9'), ('A', 'Z'), ('a', 'z'), ('_', '_')]),
|
||||
("xdigit", &[('0', '9'), ('A', 'F'), ('a', 'f')]),
|
||||
("alnum", &ALNUM),
|
||||
("alpha", &ALPHA),
|
||||
("ascii", &ASCII),
|
||||
("blank", &BLANK),
|
||||
("cntrl", &CNTRL),
|
||||
("digit", &DIGIT),
|
||||
("graph", &GRAPH),
|
||||
("lower", &LOWER),
|
||||
("print", &PRINT),
|
||||
("punct", &PUNCT),
|
||||
("space", &SPACE),
|
||||
("upper", &UPPER),
|
||||
("word", &WORD),
|
||||
("xdigit", &XDIGIT),
|
||||
];
|
||||
|
||||
static ALNUM: Class = &[('0', '9'), ('A', 'Z'), ('a', 'z')];
|
||||
static ALPHA: Class = &[('A', 'Z'), ('a', 'z')];
|
||||
static ASCII: Class = &[('\x00', '\x7F')];
|
||||
static BLANK: Class = &[(' ', ' '), ('\t', '\t')];
|
||||
static CNTRL: Class = &[('\x00', '\x1F'), ('\x7F', '\x7F')];
|
||||
static DIGIT: Class = &[('0', '9')];
|
||||
static GRAPH: Class = &[('!', '~')];
|
||||
static LOWER: Class = &[('a', 'z')];
|
||||
static PRINT: Class = &[(' ', '~')];
|
||||
static PUNCT: Class = &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')];
|
||||
static SPACE: Class = &[('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'),
|
||||
('\x0C', '\x0C'), ('\r', '\r'), (' ', ' ')];
|
||||
static UPPER: Class = &[('A', 'Z')];
|
||||
static WORD: Class = &[('0', '9'), ('A', 'Z'), ('a', 'z'), ('_', '_')];
|
||||
static XDIGIT: Class = &[('0', '9'), ('A', 'F'), ('a', 'f')];
|
||||
|
|
|
@ -128,7 +128,7 @@ pub struct ExNative {
|
|||
#[doc(hidden)]
|
||||
pub original: &'static str,
|
||||
#[doc(hidden)]
|
||||
pub names: &'static [Option<&'static str>],
|
||||
pub names: &'static &'static [Option<&'static str>],
|
||||
#[doc(hidden)]
|
||||
pub prog: fn(MatchKind, &str, uint, uint) -> Vec<Option<uint>>
|
||||
}
|
||||
|
|
|
@ -324,7 +324,7 @@ fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
|
|||
|
||||
::regex::native::Native(::regex::native::ExNative {
|
||||
original: $regex,
|
||||
names: CAP_NAMES,
|
||||
names: &CAP_NAMES,
|
||||
prog: exec,
|
||||
})
|
||||
})
|
||||
|
|
|
@ -55,22 +55,22 @@ use syntax::parse::token;
|
|||
|
||||
// This is the "magic number" expected at the beginning of a LLVM bytecode
|
||||
// object in an rlib.
|
||||
pub static RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
|
||||
pub const RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
|
||||
|
||||
// The version number this compiler will write to bytecode objects in rlibs
|
||||
pub static RLIB_BYTECODE_OBJECT_VERSION: u32 = 1;
|
||||
pub const RLIB_BYTECODE_OBJECT_VERSION: u32 = 1;
|
||||
|
||||
// The offset in bytes the bytecode object format version number can be found at
|
||||
pub static RLIB_BYTECODE_OBJECT_VERSION_OFFSET: uint = 11;
|
||||
pub const RLIB_BYTECODE_OBJECT_VERSION_OFFSET: uint = 11;
|
||||
|
||||
// The offset in bytes the size of the compressed bytecode can be found at in
|
||||
// format version 1
|
||||
pub static RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: uint =
|
||||
pub const RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: uint =
|
||||
RLIB_BYTECODE_OBJECT_VERSION_OFFSET + 4;
|
||||
|
||||
// The offset in bytes the compressed LLVM bytecode can be found at in format
|
||||
// version 1
|
||||
pub static RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: uint =
|
||||
pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: uint =
|
||||
RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8;
|
||||
|
||||
|
||||
|
|
|
@ -154,10 +154,10 @@ pub enum CrateType {
|
|||
|
||||
macro_rules! debugging_opts(
|
||||
([ $opt:ident ] $cnt:expr ) => (
|
||||
pub static $opt: u64 = 1 << $cnt;
|
||||
pub const $opt: u64 = 1 << $cnt;
|
||||
);
|
||||
([ $opt:ident, $($rest:ident),* ] $cnt:expr ) => (
|
||||
pub static $opt: u64 = 1 << $cnt;
|
||||
pub const $opt: u64 = 1 << $cnt;
|
||||
debugging_opts!([ $($rest),* ] $cnt + 1)
|
||||
)
|
||||
)
|
||||
|
@ -268,7 +268,7 @@ macro_rules! cgoptions(
|
|||
}
|
||||
|
||||
pub type CodegenSetter = fn(&mut CodegenOptions, v: Option<&str>) -> bool;
|
||||
pub static CG_OPTIONS: &'static [(&'static str, CodegenSetter,
|
||||
pub const CG_OPTIONS: &'static [(&'static str, CodegenSetter,
|
||||
&'static str)] =
|
||||
&[ $( (stringify!($opt), cgsetters::$opt, $desc) ),* ];
|
||||
|
||||
|
|
|
@ -978,7 +978,8 @@ impl LintPass for NonUppercaseStatics {
|
|||
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
|
||||
match it.node {
|
||||
// only check static constants
|
||||
ast::ItemStatic(_, ast::MutImmutable, _) => {
|
||||
ast::ItemStatic(_, ast::MutImmutable, _) |
|
||||
ast::ItemConst(..) => {
|
||||
let s = token::get_ident(it.ident);
|
||||
// check for lowercase letters rather than non-uppercase
|
||||
// ones (some scripts don't have a concept of
|
||||
|
@ -998,7 +999,7 @@ impl LintPass for NonUppercaseStatics {
|
|||
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
|
||||
// Lint for constants that look like binding identifiers (#7526)
|
||||
match (&p.node, cx.tcx.def_map.borrow().find(&p.id)) {
|
||||
(&ast::PatIdent(_, ref path1, _), Some(&def::DefStatic(_, false))) => {
|
||||
(&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
|
||||
let s = token::get_ident(path1.node);
|
||||
if s.get().chars().any(|c| c.is_lowercase()) {
|
||||
cx.span_lint(NON_UPPERCASE_STATICS, path1.span,
|
||||
|
|
|
@ -112,9 +112,9 @@ impl LintStore {
|
|||
pub fn register_pass(&mut self, sess: Option<&Session>,
|
||||
from_plugin: bool, pass: LintPassObject) {
|
||||
for &lint in pass.get_lints().iter() {
|
||||
self.lints.push((lint, from_plugin));
|
||||
self.lints.push((*lint, from_plugin));
|
||||
|
||||
let id = LintId::of(lint);
|
||||
let id = LintId::of(*lint);
|
||||
if !self.by_name.insert(lint.name_lower(), id) {
|
||||
let msg = format!("duplicate specification of lint {}", lint.name_lower());
|
||||
match (sess, from_plugin) {
|
||||
|
|
|
@ -99,12 +99,12 @@ macro_rules! declare_lint (
|
|||
macro_rules! lint_array ( ($( $lint:expr ),*) => (
|
||||
{
|
||||
#[allow(non_uppercase_statics)]
|
||||
static array: LintArray = &[ $( $lint ),* ];
|
||||
static array: LintArray = &[ $( &$lint ),* ];
|
||||
array
|
||||
}
|
||||
))
|
||||
|
||||
pub type LintArray = &'static [&'static Lint];
|
||||
pub type LintArray = &'static [&'static &'static Lint];
|
||||
|
||||
/// Trait for types providing lint checks.
|
||||
///
|
||||
|
|
|
@ -15,83 +15,83 @@ use back::svh::Svh;
|
|||
|
||||
// EBML enum definitions and utils shared by the encoder and decoder
|
||||
|
||||
pub static tag_items: uint = 0x00;
|
||||
pub const tag_items: uint = 0x00;
|
||||
|
||||
pub static tag_paths_data_name: uint = 0x01;
|
||||
pub const tag_paths_data_name: uint = 0x01;
|
||||
|
||||
pub static tag_def_id: uint = 0x02;
|
||||
pub const tag_def_id: uint = 0x02;
|
||||
|
||||
pub static tag_items_data: uint = 0x03;
|
||||
pub const tag_items_data: uint = 0x03;
|
||||
|
||||
pub static tag_items_data_item: uint = 0x04;
|
||||
pub const tag_items_data_item: uint = 0x04;
|
||||
|
||||
pub static tag_items_data_item_family: uint = 0x05;
|
||||
pub const tag_items_data_item_family: uint = 0x05;
|
||||
|
||||
pub static tag_items_data_item_type: uint = 0x07;
|
||||
pub const tag_items_data_item_type: uint = 0x07;
|
||||
|
||||
pub static tag_items_data_item_symbol: uint = 0x08;
|
||||
pub const tag_items_data_item_symbol: uint = 0x08;
|
||||
|
||||
pub static tag_items_data_item_variant: uint = 0x09;
|
||||
pub const tag_items_data_item_variant: uint = 0x09;
|
||||
|
||||
pub static tag_items_data_parent_item: uint = 0x0a;
|
||||
pub const tag_items_data_parent_item: uint = 0x0a;
|
||||
|
||||
pub static tag_items_data_item_is_tuple_struct_ctor: uint = 0x0b;
|
||||
pub const tag_items_data_item_is_tuple_struct_ctor: uint = 0x0b;
|
||||
|
||||
pub static tag_index: uint = 0x0c;
|
||||
pub const tag_index: uint = 0x0c;
|
||||
|
||||
pub static tag_index_buckets: uint = 0x0d;
|
||||
pub const tag_index_buckets: uint = 0x0d;
|
||||
|
||||
pub static tag_index_buckets_bucket: uint = 0x0e;
|
||||
pub const tag_index_buckets_bucket: uint = 0x0e;
|
||||
|
||||
pub static tag_index_buckets_bucket_elt: uint = 0x0f;
|
||||
pub const tag_index_buckets_bucket_elt: uint = 0x0f;
|
||||
|
||||
pub static tag_index_table: uint = 0x10;
|
||||
pub const tag_index_table: uint = 0x10;
|
||||
|
||||
pub static tag_meta_item_name_value: uint = 0x11;
|
||||
pub const tag_meta_item_name_value: uint = 0x11;
|
||||
|
||||
pub static tag_meta_item_name: uint = 0x12;
|
||||
pub const tag_meta_item_name: uint = 0x12;
|
||||
|
||||
pub static tag_meta_item_value: uint = 0x13;
|
||||
pub const tag_meta_item_value: uint = 0x13;
|
||||
|
||||
pub static tag_attributes: uint = 0x14;
|
||||
pub const tag_attributes: uint = 0x14;
|
||||
|
||||
pub static tag_attribute: uint = 0x15;
|
||||
pub const tag_attribute: uint = 0x15;
|
||||
|
||||
pub static tag_meta_item_word: uint = 0x16;
|
||||
pub const tag_meta_item_word: uint = 0x16;
|
||||
|
||||
pub static tag_meta_item_list: uint = 0x17;
|
||||
pub const tag_meta_item_list: uint = 0x17;
|
||||
|
||||
// The list of crates that this crate depends on
|
||||
pub static tag_crate_deps: uint = 0x18;
|
||||
pub const tag_crate_deps: uint = 0x18;
|
||||
|
||||
// A single crate dependency
|
||||
pub static tag_crate_dep: uint = 0x19;
|
||||
pub const tag_crate_dep: uint = 0x19;
|
||||
|
||||
pub static tag_crate_hash: uint = 0x1a;
|
||||
pub static tag_crate_crate_name: uint = 0x1b;
|
||||
pub const tag_crate_hash: uint = 0x1a;
|
||||
pub const tag_crate_crate_name: uint = 0x1b;
|
||||
|
||||
pub static tag_crate_dep_crate_name: uint = 0x1d;
|
||||
pub static tag_crate_dep_hash: uint = 0x1e;
|
||||
pub const tag_crate_dep_crate_name: uint = 0x1d;
|
||||
pub const tag_crate_dep_hash: uint = 0x1e;
|
||||
|
||||
pub static tag_mod_impl: uint = 0x1f;
|
||||
pub const tag_mod_impl: uint = 0x1f;
|
||||
|
||||
pub static tag_item_trait_item: uint = 0x20;
|
||||
pub const tag_item_trait_item: uint = 0x20;
|
||||
|
||||
pub static tag_item_trait_ref: uint = 0x21;
|
||||
pub static tag_item_super_trait_ref: uint = 0x22;
|
||||
pub const tag_item_trait_ref: uint = 0x21;
|
||||
pub const tag_item_super_trait_ref: uint = 0x22;
|
||||
|
||||
// discriminator value for variants
|
||||
pub static tag_disr_val: uint = 0x23;
|
||||
pub const tag_disr_val: uint = 0x23;
|
||||
|
||||
// used to encode ast_map::PathElem
|
||||
pub static tag_path: uint = 0x24;
|
||||
pub static tag_path_len: uint = 0x25;
|
||||
pub static tag_path_elem_mod: uint = 0x26;
|
||||
pub static tag_path_elem_name: uint = 0x27;
|
||||
pub static tag_item_field: uint = 0x28;
|
||||
pub static tag_item_field_origin: uint = 0x29;
|
||||
pub const tag_path: uint = 0x24;
|
||||
pub const tag_path_len: uint = 0x25;
|
||||
pub const tag_path_elem_mod: uint = 0x26;
|
||||
pub const tag_path_elem_name: uint = 0x27;
|
||||
pub const tag_item_field: uint = 0x28;
|
||||
pub const tag_item_field_origin: uint = 0x29;
|
||||
|
||||
pub static tag_item_variances: uint = 0x2a;
|
||||
pub const tag_item_variances: uint = 0x2a;
|
||||
/*
|
||||
trait items contain tag_item_trait_item elements,
|
||||
impl items contain tag_item_impl_item elements, and classes
|
||||
|
@ -100,15 +100,15 @@ pub static tag_item_variances: uint = 0x2a;
|
|||
both, tag_item_trait_item and tag_item_impl_item have to be two
|
||||
different tags.
|
||||
*/
|
||||
pub static tag_item_impl_item: uint = 0x30;
|
||||
pub static tag_item_trait_method_explicit_self: uint = 0x31;
|
||||
pub const tag_item_impl_item: uint = 0x30;
|
||||
pub const tag_item_trait_method_explicit_self: uint = 0x31;
|
||||
|
||||
|
||||
// Reexports are found within module tags. Each reexport contains def_ids
|
||||
// and names.
|
||||
pub static tag_items_data_item_reexport: uint = 0x38;
|
||||
pub static tag_items_data_item_reexport_def_id: uint = 0x39;
|
||||
pub static tag_items_data_item_reexport_name: uint = 0x3a;
|
||||
pub const tag_items_data_item_reexport: uint = 0x38;
|
||||
pub const tag_items_data_item_reexport_def_id: uint = 0x39;
|
||||
pub const tag_items_data_item_reexport_name: uint = 0x3a;
|
||||
|
||||
// used to encode crate_ctxt side tables
|
||||
#[deriving(PartialEq)]
|
||||
|
@ -153,15 +153,15 @@ impl astencode_tag {
|
|||
}
|
||||
}
|
||||
|
||||
pub static tag_item_trait_item_sort: uint = 0x60;
|
||||
pub const tag_item_trait_item_sort: uint = 0x60;
|
||||
|
||||
pub static tag_item_trait_parent_sort: uint = 0x61;
|
||||
pub const tag_item_trait_parent_sort: uint = 0x61;
|
||||
|
||||
pub static tag_item_impl_type_basename: uint = 0x62;
|
||||
pub const tag_item_impl_type_basename: uint = 0x62;
|
||||
|
||||
pub static tag_crate_triple: uint = 0x66;
|
||||
pub const tag_crate_triple: uint = 0x66;
|
||||
|
||||
pub static tag_dylib_dependency_formats: uint = 0x67;
|
||||
pub const tag_dylib_dependency_formats: uint = 0x67;
|
||||
|
||||
// Language items are a top-level directory (for speed). Hierarchy:
|
||||
//
|
||||
|
@ -170,51 +170,51 @@ pub static tag_dylib_dependency_formats: uint = 0x67;
|
|||
// - tag_lang_items_item_id: u32
|
||||
// - tag_lang_items_item_node_id: u32
|
||||
|
||||
pub static tag_lang_items: uint = 0x70;
|
||||
pub static tag_lang_items_item: uint = 0x71;
|
||||
pub static tag_lang_items_item_id: uint = 0x72;
|
||||
pub static tag_lang_items_item_node_id: uint = 0x73;
|
||||
pub static tag_lang_items_missing: uint = 0x74;
|
||||
pub const tag_lang_items: uint = 0x70;
|
||||
pub const tag_lang_items_item: uint = 0x71;
|
||||
pub const tag_lang_items_item_id: uint = 0x72;
|
||||
pub const tag_lang_items_item_node_id: uint = 0x73;
|
||||
pub const tag_lang_items_missing: uint = 0x74;
|
||||
|
||||
pub static tag_item_unnamed_field: uint = 0x75;
|
||||
pub static tag_items_data_item_visibility: uint = 0x76;
|
||||
pub const tag_item_unnamed_field: uint = 0x75;
|
||||
pub const tag_items_data_item_visibility: uint = 0x76;
|
||||
|
||||
pub static tag_item_method_tps: uint = 0x79;
|
||||
pub static tag_item_method_fty: uint = 0x7a;
|
||||
pub const tag_item_method_tps: uint = 0x79;
|
||||
pub const tag_item_method_fty: uint = 0x7a;
|
||||
|
||||
pub static tag_mod_child: uint = 0x7b;
|
||||
pub static tag_misc_info: uint = 0x7c;
|
||||
pub static tag_misc_info_crate_items: uint = 0x7d;
|
||||
pub const tag_mod_child: uint = 0x7b;
|
||||
pub const tag_misc_info: uint = 0x7c;
|
||||
pub const tag_misc_info_crate_items: uint = 0x7d;
|
||||
|
||||
pub static tag_item_method_provided_source: uint = 0x7e;
|
||||
pub static tag_item_impl_vtables: uint = 0x7f;
|
||||
pub const tag_item_method_provided_source: uint = 0x7e;
|
||||
pub const tag_item_impl_vtables: uint = 0x7f;
|
||||
|
||||
pub static tag_impls: uint = 0x80;
|
||||
pub static tag_impls_impl: uint = 0x81;
|
||||
pub const tag_impls: uint = 0x80;
|
||||
pub const tag_impls_impl: uint = 0x81;
|
||||
|
||||
pub static tag_items_data_item_inherent_impl: uint = 0x82;
|
||||
pub static tag_items_data_item_extension_impl: uint = 0x83;
|
||||
pub const tag_items_data_item_inherent_impl: uint = 0x82;
|
||||
pub const tag_items_data_item_extension_impl: uint = 0x83;
|
||||
|
||||
// GAP 0x84, 0x85, 0x86
|
||||
|
||||
pub static tag_native_libraries: uint = 0x87;
|
||||
pub static tag_native_libraries_lib: uint = 0x88;
|
||||
pub static tag_native_libraries_name: uint = 0x89;
|
||||
pub static tag_native_libraries_kind: uint = 0x8a;
|
||||
pub const tag_native_libraries: uint = 0x87;
|
||||
pub const tag_native_libraries_lib: uint = 0x88;
|
||||
pub const tag_native_libraries_name: uint = 0x89;
|
||||
pub const tag_native_libraries_kind: uint = 0x8a;
|
||||
|
||||
pub static tag_plugin_registrar_fn: uint = 0x8b;
|
||||
pub static tag_exported_macros: uint = 0x8c;
|
||||
pub static tag_macro_def: uint = 0x8d;
|
||||
pub const tag_plugin_registrar_fn: uint = 0x8b;
|
||||
pub const tag_exported_macros: uint = 0x8c;
|
||||
pub const tag_macro_def: uint = 0x8d;
|
||||
|
||||
pub static tag_method_argument_names: uint = 0x8e;
|
||||
pub static tag_method_argument_name: uint = 0x8f;
|
||||
pub const tag_method_argument_names: uint = 0x8e;
|
||||
pub const tag_method_argument_name: uint = 0x8f;
|
||||
|
||||
pub static tag_reachable_extern_fns: uint = 0x90;
|
||||
pub static tag_reachable_extern_fn_id: uint = 0x91;
|
||||
pub const tag_reachable_extern_fns: uint = 0x90;
|
||||
pub const tag_reachable_extern_fn_id: uint = 0x91;
|
||||
|
||||
pub static tag_items_data_item_stability: uint = 0x92;
|
||||
pub const tag_items_data_item_stability: uint = 0x92;
|
||||
|
||||
pub static tag_items_data_item_repr: uint = 0x93;
|
||||
pub const tag_items_data_item_repr: uint = 0x93;
|
||||
|
||||
#[deriving(Clone, Show)]
|
||||
pub struct LinkMeta {
|
||||
|
@ -222,29 +222,29 @@ pub struct LinkMeta {
|
|||
pub crate_hash: Svh,
|
||||
}
|
||||
|
||||
pub static tag_unboxed_closures: uint = 0x95;
|
||||
pub static tag_unboxed_closure: uint = 0x96;
|
||||
pub static tag_unboxed_closure_type: uint = 0x97;
|
||||
pub static tag_unboxed_closure_kind: uint = 0x98;
|
||||
pub const tag_unboxed_closures: uint = 0x95;
|
||||
pub const tag_unboxed_closure: uint = 0x96;
|
||||
pub const tag_unboxed_closure_type: uint = 0x97;
|
||||
pub const tag_unboxed_closure_kind: uint = 0x98;
|
||||
|
||||
pub static tag_struct_fields: uint = 0x99;
|
||||
pub static tag_struct_field: uint = 0x9a;
|
||||
pub static tag_struct_field_id: uint = 0x9b;
|
||||
pub const tag_struct_fields: uint = 0x99;
|
||||
pub const tag_struct_field: uint = 0x9a;
|
||||
pub const tag_struct_field_id: uint = 0x9b;
|
||||
|
||||
pub static tag_attribute_is_sugared_doc: uint = 0x9c;
|
||||
pub const tag_attribute_is_sugared_doc: uint = 0x9c;
|
||||
|
||||
pub static tag_trait_def_bounds: uint = 0x9d;
|
||||
pub const tag_trait_def_bounds: uint = 0x9d;
|
||||
|
||||
pub static tag_items_data_region: uint = 0x9e;
|
||||
pub const tag_items_data_region: uint = 0x9e;
|
||||
|
||||
pub static tag_region_param_def: uint = 0xa0;
|
||||
pub static tag_region_param_def_ident: uint = 0xa1;
|
||||
pub static tag_region_param_def_def_id: uint = 0xa2;
|
||||
pub static tag_region_param_def_space: uint = 0xa3;
|
||||
pub static tag_region_param_def_index: uint = 0xa4;
|
||||
pub const tag_region_param_def: uint = 0xa0;
|
||||
pub const tag_region_param_def_ident: uint = 0xa1;
|
||||
pub const tag_region_param_def_def_id: uint = 0xa2;
|
||||
pub const tag_region_param_def_space: uint = 0xa3;
|
||||
pub const tag_region_param_def_index: uint = 0xa4;
|
||||
|
||||
pub static tag_type_param_def: uint = 0xa5;
|
||||
pub const tag_type_param_def: uint = 0xa5;
|
||||
|
||||
pub static tag_item_generics: uint = 0xa6;
|
||||
pub static tag_method_ty_generics: uint = 0xa7;
|
||||
pub const tag_item_generics: uint = 0xa6;
|
||||
pub const tag_method_ty_generics: uint = 0xa7;
|
||||
|
||||
|
|
|
@ -126,12 +126,14 @@ enum Family {
|
|||
Trait, // I
|
||||
Struct, // S
|
||||
PublicField, // g
|
||||
InheritedField // N
|
||||
InheritedField, // N
|
||||
Constant, // C
|
||||
}
|
||||
|
||||
fn item_family(item: rbml::Doc) -> Family {
|
||||
let fam = reader::get_doc(item, tag_items_data_item_family);
|
||||
match reader::doc_as_u8(fam) as char {
|
||||
'C' => Constant,
|
||||
'c' => ImmStatic,
|
||||
'b' => MutStatic,
|
||||
'f' => Fn,
|
||||
|
@ -303,6 +305,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
|
|||
-> DefLike {
|
||||
let fam = item_family(item);
|
||||
match fam {
|
||||
Constant => DlDef(def::DefConst(did)),
|
||||
ImmStatic => DlDef(def::DefStatic(did, false)),
|
||||
MutStatic => DlDef(def::DefStatic(did, true)),
|
||||
Struct => DlDef(def::DefStruct(did)),
|
||||
|
|
|
@ -69,7 +69,6 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
|
|||
pub tcx: &'a ty::ctxt<'tcx>,
|
||||
pub reexports2: &'a middle::resolve::ExportMap2,
|
||||
pub item_symbols: &'a RefCell<NodeMap<String>>,
|
||||
pub non_inlineable_statics: &'a RefCell<NodeSet>,
|
||||
pub link_meta: &'a LinkMeta,
|
||||
pub cstore: &'a cstore::CStore,
|
||||
pub encode_inlined_item: EncodeInlinedItem<'a>,
|
||||
|
@ -81,7 +80,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
|
|||
pub tcx: &'a ty::ctxt<'tcx>,
|
||||
pub reexports2: &'a middle::resolve::ExportMap2,
|
||||
pub item_symbols: &'a RefCell<NodeMap<String>>,
|
||||
pub non_inlineable_statics: &'a RefCell<NodeSet>,
|
||||
pub link_meta: &'a LinkMeta,
|
||||
pub cstore: &'a cstore::CStore,
|
||||
pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
|
||||
|
@ -1069,12 +1067,20 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_symbol(ecx, rbml_w, item.id);
|
||||
encode_name(rbml_w, item.ident.name);
|
||||
encode_path(rbml_w, path);
|
||||
|
||||
let inlineable = !ecx.non_inlineable_statics.borrow().contains(&item.id);
|
||||
|
||||
if inlineable {
|
||||
encode_inlined_item(ecx, rbml_w, IIItemRef(item));
|
||||
encode_visibility(rbml_w, vis);
|
||||
encode_stability(rbml_w, stab);
|
||||
encode_attributes(rbml_w, item.attrs.as_slice());
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
ItemConst(_, _) => {
|
||||
add_to_index(item, rbml_w, index);
|
||||
rbml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(rbml_w, def_id);
|
||||
encode_family(rbml_w, 'C');
|
||||
encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
|
||||
encode_name(rbml_w, item.ident.name);
|
||||
encode_path(rbml_w, path);
|
||||
encode_inlined_item(ecx, rbml_w, IIItemRef(item));
|
||||
encode_visibility(rbml_w, vis);
|
||||
encode_stability(rbml_w, stab);
|
||||
rbml_w.end_tag();
|
||||
|
@ -2029,7 +2035,7 @@ fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
|
|||
|
||||
// NB: Increment this as you change the metadata encoding version.
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 1 ];
|
||||
pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 1 ];
|
||||
|
||||
pub fn encode_metadata(parms: EncodeParams, krate: &Crate) -> Vec<u8> {
|
||||
let mut wr = SeekableMemWriter::new();
|
||||
|
@ -2076,7 +2082,6 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, parms: EncodeParams, krate:
|
|||
cstore,
|
||||
encode_inlined_item,
|
||||
link_meta,
|
||||
non_inlineable_statics,
|
||||
reachable,
|
||||
..
|
||||
} = parms;
|
||||
|
@ -2085,7 +2090,6 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, parms: EncodeParams, krate:
|
|||
tcx: tcx,
|
||||
reexports2: reexports2,
|
||||
item_symbols: item_symbols,
|
||||
non_inlineable_statics: non_inlineable_statics,
|
||||
link_meta: link_meta,
|
||||
cstore: cstore,
|
||||
encode_inlined_item: RefCell::new(encode_inlined_item),
|
||||
|
|
|
@ -241,23 +241,23 @@ use std::collections::hashmap::{Occupied, Vacant};
|
|||
use flate;
|
||||
use time;
|
||||
|
||||
pub static MACOS_DLL_PREFIX: &'static str = "lib";
|
||||
pub static MACOS_DLL_SUFFIX: &'static str = ".dylib";
|
||||
pub const MACOS_DLL_PREFIX: &'static str = "lib";
|
||||
pub const MACOS_DLL_SUFFIX: &'static str = ".dylib";
|
||||
|
||||
pub static WIN32_DLL_PREFIX: &'static str = "";
|
||||
pub static WIN32_DLL_SUFFIX: &'static str = ".dll";
|
||||
pub const WIN32_DLL_PREFIX: &'static str = "";
|
||||
pub const WIN32_DLL_SUFFIX: &'static str = ".dll";
|
||||
|
||||
pub static LINUX_DLL_PREFIX: &'static str = "lib";
|
||||
pub static LINUX_DLL_SUFFIX: &'static str = ".so";
|
||||
pub const LINUX_DLL_PREFIX: &'static str = "lib";
|
||||
pub const LINUX_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub static FREEBSD_DLL_PREFIX: &'static str = "lib";
|
||||
pub static FREEBSD_DLL_SUFFIX: &'static str = ".so";
|
||||
pub const FREEBSD_DLL_PREFIX: &'static str = "lib";
|
||||
pub const FREEBSD_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub static DRAGONFLY_DLL_PREFIX: &'static str = "lib";
|
||||
pub static DRAGONFLY_DLL_SUFFIX: &'static str = ".so";
|
||||
pub const DRAGONFLY_DLL_PREFIX: &'static str = "lib";
|
||||
pub const DRAGONFLY_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub static ANDROID_DLL_PREFIX: &'static str = "lib";
|
||||
pub static ANDROID_DLL_SUFFIX: &'static str = ".so";
|
||||
pub const ANDROID_DLL_PREFIX: &'static str = "lib";
|
||||
pub const ANDROID_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub struct CrateMismatch {
|
||||
path: Path,
|
||||
|
|
|
@ -460,6 +460,7 @@ impl tr for def::Def {
|
|||
def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
|
||||
def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
|
||||
def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
|
||||
def::DefConst(did) => { def::DefConst(did.tr(dcx)) }
|
||||
def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) }
|
||||
def::DefVariant(e_did, v_did, is_s) => {
|
||||
def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
|
||||
|
|
|
@ -169,15 +169,11 @@ fn check_aliasability(bccx: &BorrowckCtxt,
|
|||
// Borrow of an immutable static item:
|
||||
match safety {
|
||||
mc::InteriorUnsafe => {
|
||||
// If the static item contains an Unsafe<T>, it has interior mutability.
|
||||
// In such cases, we cannot permit it to be borrowed, because the
|
||||
// static item resides in immutable memory and mutating it would
|
||||
// cause segfaults.
|
||||
bccx.tcx.sess.span_err(borrow_span,
|
||||
"borrow of immutable static items \
|
||||
with unsafe interior is not \
|
||||
allowed");
|
||||
Err(())
|
||||
// If the static item contains an Unsafe<T>, it has interior
|
||||
// mutability. In such cases, another phase of the compiler
|
||||
// will ensure that the type is `Sync` and then trans will
|
||||
// not put it in rodata, so this is ok to allow.
|
||||
Ok(())
|
||||
}
|
||||
mc::InteriorSafe => {
|
||||
// Immutable static can be borrowed, no problem.
|
||||
|
|
|
@ -106,7 +106,8 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
|
|||
// loan step is intended for things that have a data
|
||||
// flow dependent conditions.
|
||||
match item.node {
|
||||
ast::ItemStatic(_, _, ref ex) => {
|
||||
ast::ItemStatic(_, _, ref ex) |
|
||||
ast::ItemConst(_, ref ex) => {
|
||||
gather_loans::gather_loans_in_static_initializer(this, &**ex);
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -47,7 +47,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
check_pat(self, p);
|
||||
}
|
||||
fn visit_expr(&mut self, ex: &Expr) {
|
||||
check_expr(self, ex);
|
||||
if check_expr(self, ex) {
|
||||
visit::walk_expr(self, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,8 @@ pub fn check_crate(tcx: &ty::ctxt) {
|
|||
|
||||
fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
|
||||
match it.node {
|
||||
ItemStatic(_, _, ref ex) => {
|
||||
ItemStatic(_, _, ref ex) |
|
||||
ItemConst(_, ref ex) => {
|
||||
v.inside_const(|v| v.visit_expr(&**ex));
|
||||
}
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
|
@ -96,20 +99,23 @@ fn check_pat(v: &mut CheckCrateVisitor, p: &Pat) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
||||
if v.in_const {
|
||||
fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool {
|
||||
if !v.in_const { return true }
|
||||
|
||||
match e.node {
|
||||
ExprUnary(UnDeref, _) => {}
|
||||
ExprUnary(UnUniq, _) => {
|
||||
span_err!(v.tcx.sess, e.span, E0010, "cannot do allocations in constant expressions");
|
||||
return;
|
||||
span_err!(v.tcx.sess, e.span, E0010,
|
||||
"cannot do allocations in constant expressions");
|
||||
return false;
|
||||
}
|
||||
ExprLit(ref lit) if ast_util::lit_is_str(&**lit) => {}
|
||||
ExprBinary(..) | ExprUnary(..) => {
|
||||
let method_call = typeck::MethodCall::expr(e.id);
|
||||
if v.tcx.method_map.borrow().contains_key(&method_call) {
|
||||
span_err!(v.tcx.sess, e.span, E0011,
|
||||
"user-defined operators are not allowed in constant expressions");
|
||||
"user-defined operators are not allowed in constant \
|
||||
expressions");
|
||||
}
|
||||
}
|
||||
ExprLit(_) => (),
|
||||
|
@ -118,8 +124,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
if !ty::type_is_numeric(ety) && !ty::type_is_unsafe_ptr(ety) {
|
||||
span_err!(v.tcx.sess, e.span, E0012,
|
||||
"can not cast to `{}` in a constant expression",
|
||||
ppaux::ty_to_string(v.tcx, ety)
|
||||
);
|
||||
ppaux::ty_to_string(v.tcx, ety));
|
||||
}
|
||||
}
|
||||
ExprPath(ref pth) => {
|
||||
|
@ -129,10 +134,12 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
// a path in trans::callee that only works in block contexts.
|
||||
if !pth.segments.iter().all(|segment| segment.types.is_empty()) {
|
||||
span_err!(v.tcx.sess, e.span, E0013,
|
||||
"paths in constants may only refer to items without type parameters");
|
||||
"paths in constants may only refer to items without \
|
||||
type parameters");
|
||||
}
|
||||
match v.tcx.def_map.borrow().find(&e.id) {
|
||||
Some(&DefStatic(..)) |
|
||||
Some(&DefConst(..)) |
|
||||
Some(&DefFn(..)) |
|
||||
Some(&DefVariant(_, _, _)) |
|
||||
Some(&DefStruct(_)) => { }
|
||||
|
@ -140,7 +147,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
Some(&def) => {
|
||||
debug!("(checking const) found bad def: {:?}", def);
|
||||
span_err!(v.tcx.sess, e.span, E0014,
|
||||
"paths in constants may only refer to constants or functions");
|
||||
"paths in constants may only refer to constants \
|
||||
or functions");
|
||||
}
|
||||
None => {
|
||||
v.tcx.sess.span_bug(e.span, "unbound path in const?!");
|
||||
|
@ -151,9 +159,11 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
match v.tcx.def_map.borrow().find(&callee.id) {
|
||||
Some(&DefStruct(..)) |
|
||||
Some(&DefVariant(..)) => {} // OK.
|
||||
|
||||
_ => {
|
||||
span_err!(v.tcx.sess, e.span, E0015,
|
||||
"function calls in constants are limited to struct and enum constructors");
|
||||
"function calls in constants are limited to \
|
||||
struct and enum constructors");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +172,8 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
for stmt in block.stmts.iter() {
|
||||
let block_span_err = |span|
|
||||
span_err!(v.tcx.sess, span, E0016,
|
||||
"blocks in constants are limited to items and tail expressions");
|
||||
"blocks in constants are limited to items and \
|
||||
tail expressions");
|
||||
match stmt.node {
|
||||
StmtDecl(ref span, _) => {
|
||||
match span.node {
|
||||
|
@ -174,12 +185,14 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
}
|
||||
StmtExpr(ref expr, _) => block_span_err(expr.span),
|
||||
StmtSemi(ref semi, _) => block_span_err(semi.span),
|
||||
StmtMac(..) => v.tcx.sess.span_bug(e.span,
|
||||
"unexpanded statement macro in const?!")
|
||||
StmtMac(..) => {
|
||||
v.tcx.sess.span_bug(e.span, "unexpanded statement \
|
||||
macro in const?!")
|
||||
}
|
||||
}
|
||||
}
|
||||
match block.expr {
|
||||
Some(ref expr) => check_expr(v, &**expr),
|
||||
Some(ref expr) => { check_expr(v, &**expr); }
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
@ -192,22 +205,23 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
ExprTup(..) |
|
||||
ExprRepeat(..) |
|
||||
ExprStruct(..) => {}
|
||||
|
||||
ExprAddrOf(_, ref inner) => {
|
||||
match inner.node {
|
||||
// Mutable slices are allowed.
|
||||
ExprVec(_) => {}
|
||||
_ => span_err!(v.tcx.sess, e.span, E0017,
|
||||
"references in constants may only refer to immutable values")
|
||||
"references in constants may only refer \
|
||||
to immutable values")
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_ => {
|
||||
span_err!(v.tcx.sess, e.span, E0019,
|
||||
"constant contains unimplemented expression type");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
visit::walk_expr(v, e);
|
||||
true
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ use syntax::ptr::P;
|
|||
use syntax::visit::{mod, Visitor, FnKind};
|
||||
use util::ppaux::ty_to_string;
|
||||
|
||||
static DUMMY_WILD_PAT: Pat = Pat {
|
||||
pub const DUMMY_WILD_PAT: Pat = Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatWild(PatWildSingle),
|
||||
span: DUMMY_SP
|
||||
|
@ -299,9 +299,10 @@ fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
|
|||
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
|
||||
match is_useful(cx, matrix, &[&DUMMY_WILD_PAT], ConstructWitness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
let dummy = DUMMY_WILD_PAT.clone();
|
||||
let witness = match pats.as_slice() {
|
||||
[ref witness] => &**witness,
|
||||
[] => &DUMMY_WILD_PAT,
|
||||
[] => &dummy,
|
||||
_ => unreachable!()
|
||||
};
|
||||
span_err!(cx.tcx.sess, sp, E0004,
|
||||
|
@ -349,7 +350,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
|||
PatIdent(..) | PatEnum(..) => {
|
||||
let def = self.tcx.def_map.borrow().find_copy(&pat.id);
|
||||
match def {
|
||||
Some(DefStatic(did, _)) => match lookup_const_by_id(self.tcx, did) {
|
||||
Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did) {
|
||||
Some(const_expr) => {
|
||||
const_expr_to_pat(self.tcx, const_expr).map(|mut new_pat| {
|
||||
new_pat.span = pat.span;
|
||||
|
@ -359,7 +360,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
|||
None => {
|
||||
self.failed = true;
|
||||
span_err!(self.tcx.sess, pat.span, E0158,
|
||||
"extern statics cannot be referenced in patterns");
|
||||
"statics cannot be referenced in patterns");
|
||||
pat
|
||||
}
|
||||
},
|
||||
|
@ -555,8 +556,9 @@ fn is_useful(cx: &MatchCheckCtxt,
|
|||
let arity = constructor_arity(cx, &c, left_ty);
|
||||
let mut result = {
|
||||
let pat_slice = pats.as_slice();
|
||||
let dummy = DUMMY_WILD_PAT.clone();
|
||||
let subpats = Vec::from_fn(arity, |i| {
|
||||
pat_slice.get(i).map_or(&DUMMY_WILD_PAT, |p| &**p)
|
||||
pat_slice.get(i).map_or(&dummy, |p| &**p)
|
||||
});
|
||||
vec![construct_witness(cx, &c, subpats, left_ty)]
|
||||
};
|
||||
|
@ -578,8 +580,9 @@ fn is_useful(cx: &MatchCheckCtxt,
|
|||
}).collect();
|
||||
match is_useful(cx, &matrix, v.tail(), witness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
let dummy = DUMMY_WILD_PAT.clone();
|
||||
let arity = constructor_arity(cx, &constructor, left_ty);
|
||||
let wild_pats = Vec::from_elem(arity, &DUMMY_WILD_PAT);
|
||||
let wild_pats = Vec::from_elem(arity, &dummy);
|
||||
let enum_pat = construct_witness(cx, &constructor, wild_pats, left_ty);
|
||||
let mut new_pats = vec![enum_pat];
|
||||
new_pats.extend(pats.into_iter());
|
||||
|
@ -600,10 +603,11 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix,
|
|||
v: &[&Pat], ctor: Constructor, lty: ty::t,
|
||||
witness: WitnessPreference) -> Usefulness {
|
||||
let arity = constructor_arity(cx, &ctor, lty);
|
||||
let dummy = DUMMY_WILD_PAT.clone();
|
||||
let matrix = Matrix(m.iter().filter_map(|r| {
|
||||
specialize(cx, r.as_slice(), &ctor, 0u, arity)
|
||||
specialize(cx, r.as_slice(), &dummy, &ctor, 0u, arity)
|
||||
}).collect());
|
||||
match specialize(cx, v, &ctor, 0u, arity) {
|
||||
match specialize(cx, v, &dummy, &ctor, 0u, arity) {
|
||||
Some(v) => is_useful(cx, &matrix, v.as_slice(), witness),
|
||||
None => NotUseful
|
||||
}
|
||||
|
@ -624,23 +628,26 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
|
|||
match pat.node {
|
||||
PatIdent(..) =>
|
||||
match cx.tcx.def_map.borrow().find(&pat.id) {
|
||||
Some(&DefStatic(..)) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "static pattern should've been rewritten"),
|
||||
Some(&DefConst(..)) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
|
||||
been rewritten"),
|
||||
Some(&DefStruct(_)) => vec!(Single),
|
||||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||
_ => vec!()
|
||||
},
|
||||
PatEnum(..) =>
|
||||
match cx.tcx.def_map.borrow().find(&pat.id) {
|
||||
Some(&DefStatic(..)) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "static pattern should've been rewritten"),
|
||||
Some(&DefConst(..)) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "static pattern should've \
|
||||
been rewritten"),
|
||||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||
_ => vec!(Single)
|
||||
},
|
||||
PatStruct(..) =>
|
||||
match cx.tcx.def_map.borrow().find(&pat.id) {
|
||||
Some(&DefStatic(..)) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "static pattern should've been rewritten"),
|
||||
Some(&DefConst(..)) =>
|
||||
cx.tcx.sess.span_bug(pat.span, "static pattern should've \
|
||||
been rewritten"),
|
||||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||
_ => vec!(Single)
|
||||
},
|
||||
|
@ -722,7 +729,7 @@ fn range_covered_by_constructor(ctor: &Constructor,
|
|||
/// different patterns.
|
||||
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
|
||||
/// fields filled with wild patterns.
|
||||
pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
||||
pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], dummy: &'a Pat,
|
||||
constructor: &Constructor, col: uint, arity: uint) -> Option<Vec<&'a Pat>> {
|
||||
let &Pat {
|
||||
id: pat_id, node: ref node, span: pat_span
|
||||
|
@ -730,32 +737,34 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
|||
let head: Option<Vec<&Pat>> = match node {
|
||||
|
||||
&PatWild(_) =>
|
||||
Some(Vec::from_elem(arity, &DUMMY_WILD_PAT)),
|
||||
Some(Vec::from_elem(arity, dummy)),
|
||||
|
||||
&PatIdent(_, _, _) => {
|
||||
let opt_def = cx.tcx.def_map.borrow().find_copy(&pat_id);
|
||||
match opt_def {
|
||||
Some(DefStatic(..)) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "static pattern should've been rewritten"),
|
||||
Some(DefConst(..)) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||
been rewritten"),
|
||||
Some(DefVariant(_, id, _)) => if *constructor == Variant(id) {
|
||||
Some(vec!())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
_ => Some(Vec::from_elem(arity, &DUMMY_WILD_PAT))
|
||||
_ => Some(Vec::from_elem(arity, dummy))
|
||||
}
|
||||
}
|
||||
|
||||
&PatEnum(_, ref args) => {
|
||||
let def = cx.tcx.def_map.borrow().get_copy(&pat_id);
|
||||
match def {
|
||||
DefStatic(..) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "static pattern should've been rewritten"),
|
||||
DefConst(..) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||
been rewritten"),
|
||||
DefVariant(_, id, _) if *constructor != Variant(id) => None,
|
||||
DefVariant(..) | DefStruct(..) => {
|
||||
Some(match args {
|
||||
&Some(ref args) => args.iter().map(|p| &**p).collect(),
|
||||
&None => Vec::from_elem(arity, &DUMMY_WILD_PAT)
|
||||
&None => Vec::from_elem(arity, dummy)
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
|
@ -766,8 +775,9 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
|||
// Is this a struct or an enum variant?
|
||||
let def = cx.tcx.def_map.borrow().get_copy(&pat_id);
|
||||
let class_id = match def {
|
||||
DefStatic(..) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "static pattern should've been rewritten"),
|
||||
DefConst(..) =>
|
||||
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
|
||||
been rewritten"),
|
||||
DefVariant(_, variant_id, _) => if *constructor == Variant(variant_id) {
|
||||
Some(variant_id)
|
||||
} else {
|
||||
|
@ -790,7 +800,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
|||
let args = struct_fields.iter().map(|sf| {
|
||||
match pattern_fields.iter().find(|f| f.ident.name == sf.name) {
|
||||
Some(ref f) => &*f.pat,
|
||||
_ => &DUMMY_WILD_PAT
|
||||
_ => dummy
|
||||
}
|
||||
}).collect();
|
||||
args
|
||||
|
@ -833,13 +843,13 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
|||
// Fixed-length vectors.
|
||||
Single => {
|
||||
let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect();
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| &DUMMY_WILD_PAT);
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| dummy);
|
||||
pats.extend(after.iter().map(|p| &**p));
|
||||
Some(pats)
|
||||
},
|
||||
Slice(length) if before.len() + after.len() <= length && slice.is_some() => {
|
||||
let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect();
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| &DUMMY_WILD_PAT);
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| dummy);
|
||||
pats.extend(after.iter().map(|p| &**p));
|
||||
Some(pats)
|
||||
},
|
||||
|
|
|
@ -25,48 +25,103 @@
|
|||
// by borrowck::gather_loans
|
||||
|
||||
use middle::ty;
|
||||
use middle::def;
|
||||
use middle::typeck;
|
||||
use middle::traits;
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::expr_use_visitor as euv;
|
||||
use util::nodemap::NodeSet;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
use syntax::print::pprust;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::codemap::{DUMMY_SP, Span};
|
||||
use syntax::visit;
|
||||
|
||||
|
||||
fn safe_type_for_static_mut(cx: &ty::ctxt, e: &ast::Expr) -> Option<String> {
|
||||
let node_ty = ty::node_id_to_type(cx, e.id);
|
||||
let tcontents = ty::type_contents(cx, node_ty);
|
||||
debug!("safe_type_for_static_mut(dtor={}, managed={}, owned={})",
|
||||
tcontents.has_dtor(), tcontents.owns_managed(), tcontents.owns_owned())
|
||||
|
||||
let suffix = if tcontents.has_dtor() {
|
||||
"destructors"
|
||||
} else if tcontents.owns_managed() {
|
||||
"managed pointers"
|
||||
} else if tcontents.owns_owned() {
|
||||
"owned pointers"
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(format!("mutable static items are not allowed to have {}", suffix))
|
||||
#[deriving(Eq, PartialEq)]
|
||||
enum Mode {
|
||||
InConstant,
|
||||
InStatic,
|
||||
InStaticMut,
|
||||
InNothing,
|
||||
}
|
||||
|
||||
struct CheckStaticVisitor<'a, 'tcx: 'a> {
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
in_const: bool
|
||||
mode: Mode,
|
||||
checker: &'a mut GlobalChecker,
|
||||
}
|
||||
|
||||
struct GlobalVisitor<'a, 'b, 't: 'b>(euv::ExprUseVisitor<'a, 'b, ty::ctxt<'t>>);
|
||||
struct GlobalChecker {
|
||||
static_consumptions: NodeSet,
|
||||
const_borrows: NodeSet,
|
||||
static_interior_borrows: NodeSet,
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx, in_const: false },
|
||||
tcx.map.krate())
|
||||
let mut checker = GlobalChecker {
|
||||
static_consumptions: NodeSet::new(),
|
||||
const_borrows: NodeSet::new(),
|
||||
static_interior_borrows: NodeSet::new(),
|
||||
};
|
||||
{
|
||||
let visitor = euv::ExprUseVisitor::new(&mut checker, tcx);
|
||||
visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate());
|
||||
}
|
||||
visit::walk_crate(&mut CheckStaticVisitor {
|
||||
tcx: tcx,
|
||||
mode: InNothing,
|
||||
checker: &mut checker,
|
||||
}, tcx.map.krate());
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
|
||||
fn with_const(&mut self, in_const: bool, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
|
||||
let was_const = self.in_const;
|
||||
self.in_const = in_const;
|
||||
fn with_mode(&mut self, mode: Mode, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
|
||||
let old = self.mode;
|
||||
self.mode = mode;
|
||||
f(self);
|
||||
self.in_const = was_const;
|
||||
self.mode = old;
|
||||
}
|
||||
|
||||
fn msg(&self) -> &'static str {
|
||||
match self.mode {
|
||||
InConstant => "constants",
|
||||
InStaticMut | InStatic => "statics",
|
||||
InNothing => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_static_mut_type(&self, e: &ast::Expr) {
|
||||
let node_ty = ty::node_id_to_type(self.tcx, e.id);
|
||||
let tcontents = ty::type_contents(self.tcx, node_ty);
|
||||
|
||||
let suffix = if tcontents.has_dtor() {
|
||||
"destructors"
|
||||
} else if tcontents.owns_owned() {
|
||||
"owned pointers"
|
||||
} else {
|
||||
return
|
||||
};
|
||||
|
||||
self.tcx.sess.span_err(e.span, format!("mutable statics are not allowed \
|
||||
to have {}", suffix).as_slice());
|
||||
}
|
||||
|
||||
fn check_static_type(&self, e: &ast::Expr) {
|
||||
let ty = ty::node_id_to_type(self.tcx, e.id);
|
||||
let infcx = typeck::infer::new_infer_ctxt(self.tcx);
|
||||
let mut fulfill_cx = traits::FulfillmentContext::new();
|
||||
let cause = traits::ObligationCause::misc(DUMMY_SP);
|
||||
let obligation = traits::obligation_for_builtin_bound(self.tcx, cause, ty,
|
||||
ty::BoundSync);
|
||||
fulfill_cx.register_obligation(self.tcx, obligation.unwrap());
|
||||
let env = ty::empty_parameter_environment();
|
||||
let result = fulfill_cx.select_all_or_error(&infcx, &env, self.tcx).is_ok();
|
||||
if !result {
|
||||
self.tcx.sess.span_err(e.span, "shared static items must have a \
|
||||
type which implements Sync");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,24 +129,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
|
|||
fn visit_item(&mut self, i: &ast::Item) {
|
||||
debug!("visit_item(item={})", pprust::item_to_string(i));
|
||||
match i.node {
|
||||
ast::ItemStatic(_, mutability, ref expr) => {
|
||||
match mutability {
|
||||
ast::MutImmutable => {
|
||||
self.with_const(true, |v| v.visit_expr(&**expr));
|
||||
ast::ItemStatic(_, ast::MutImmutable, ref expr) => {
|
||||
self.check_static_type(&**expr);
|
||||
self.with_mode(InStatic, |v| v.visit_expr(&**expr));
|
||||
}
|
||||
ast::MutMutable => {
|
||||
match safe_type_for_static_mut(self.tcx, &**expr) {
|
||||
Some(msg) => {
|
||||
self.tcx.sess.span_err(expr.span, msg.as_slice());
|
||||
ast::ItemStatic(_, ast::MutMutable, ref expr) => {
|
||||
self.check_static_mut_type(&**expr);
|
||||
self.with_mode(InStaticMut, |v| v.visit_expr(&**expr));
|
||||
}
|
||||
None => {}
|
||||
ast::ItemConst(_, ref expr) => {
|
||||
self.with_mode(InConstant, |v| v.visit_expr(&**expr));
|
||||
}
|
||||
_ => {
|
||||
self.with_mode(InNothing, |v| visit::walk_item(v, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => self.with_const(false, |v| visit::walk_item(v, i))
|
||||
}
|
||||
}
|
||||
|
||||
/// This method is used to enforce the constraints on
|
||||
/// immutable static items. It walks through the *value*
|
||||
|
@ -100,36 +153,76 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
|
|||
/// of a static item, this method does nothing but walking
|
||||
/// down through it.
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
debug!("visit_expr(expr={})", pprust::expr_to_string(e));
|
||||
|
||||
if !self.in_const {
|
||||
if self.mode == InNothing {
|
||||
return visit::walk_expr(self, e);
|
||||
}
|
||||
|
||||
match e.node {
|
||||
ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) |
|
||||
ast::ExprBlock(..) | ast::ExprTup(..) => {
|
||||
visit::walk_expr(self, e);
|
||||
}
|
||||
ast::ExprAddrOf(ast::MutMutable, _) => {
|
||||
span_err!(self.tcx.sess, e.span, E0020,
|
||||
"static items are not allowed to have mutable slices");
|
||||
},
|
||||
ast::ExprBox(..) |
|
||||
ast::ExprUnary(ast::UnUniq, _) => {
|
||||
span_err!(self.tcx.sess, e.span, E0022,
|
||||
"static items are not allowed to have custom pointers");
|
||||
}
|
||||
_ => {
|
||||
let node_ty = ty::node_id_to_type(self.tcx, e.id);
|
||||
|
||||
match ty::get(node_ty).sty {
|
||||
ty::ty_struct(did, _) |
|
||||
ty::ty_enum(did, _) => {
|
||||
if ty::has_dtor(self.tcx, did) {
|
||||
ty::ty_enum(did, _) if ty::has_dtor(self.tcx, did) => {
|
||||
self.tcx.sess.span_err(e.span,
|
||||
"static items are not allowed to have destructors");
|
||||
return;
|
||||
format!("{} are not allowed to have \
|
||||
destructors", self.msg()).as_slice())
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// statics cannot be consumed by value at any time, that would imply
|
||||
// that they're an initializer (what a const is for) or kept in sync
|
||||
// over time (not feasible), so deny it outright.
|
||||
if self.checker.static_consumptions.remove(&e.id) {
|
||||
self.tcx.sess.span_err(e.span, "cannot refer to other statics by \
|
||||
value, use the address-of operator \
|
||||
or a constant instead");
|
||||
}
|
||||
|
||||
// Borrowed statics can specifically *only* have their address taken,
|
||||
// not any number of other borrows such as borrowing fields, reading
|
||||
// elements of an array, etc.
|
||||
if self.checker.static_interior_borrows.remove(&e.id) {
|
||||
self.tcx.sess.span_err(e.span, "cannot refer to the interior of \
|
||||
another static, use a constant \
|
||||
instead");
|
||||
}
|
||||
|
||||
// constants cannot be borrowed if they contain interior mutability as
|
||||
// it means that our "silent insertion of statics" could change
|
||||
// initializer values (very bad).
|
||||
if self.checker.const_borrows.remove(&e.id) {
|
||||
let node_ty = ty::node_id_to_type(self.tcx, e.id);
|
||||
let tcontents = ty::type_contents(self.tcx, node_ty);
|
||||
if tcontents.interior_unsafe() {
|
||||
self.tcx.sess.span_err(e.span, "cannot borrow a constant which \
|
||||
contains interior mutability, \
|
||||
create a static instead");
|
||||
}
|
||||
}
|
||||
|
||||
match e.node {
|
||||
ast::ExprAddrOf(ast::MutMutable, _) => {
|
||||
if self.mode != InStaticMut {
|
||||
span_err!(self.tcx.sess, e.span, E0020,
|
||||
"{} are not allowed to have mutable references",
|
||||
self.msg());
|
||||
}
|
||||
},
|
||||
ast::ExprBox(..) |
|
||||
ast::ExprUnary(ast::UnUniq, _) => {
|
||||
span_err!(self.tcx.sess, e.span, E0022,
|
||||
"{} are not allowed to have custom pointers",
|
||||
self.msg());
|
||||
}
|
||||
ast::ExprPath(..) => {
|
||||
match ty::resolve_expr(self.tcx, e) {
|
||||
def::DefStatic(..) if self.mode == InConstant => {
|
||||
let msg = "constants cannot refer to other statics, \
|
||||
insert an intermediate constant \
|
||||
instead";
|
||||
self.tcx.sess.span_err(e.span, msg.as_slice());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -137,5 +230,93 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
|
|||
visit::walk_expr(self, e);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 't, 'v> Visitor<'v> for GlobalVisitor<'a, 'b, 't> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
match item.node {
|
||||
ast::ItemConst(_, ref e) |
|
||||
ast::ItemStatic(_, _, ref e) => {
|
||||
let GlobalVisitor(ref mut v) = *self;
|
||||
v.consume_expr(&**e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
}
|
||||
|
||||
impl euv::Delegate for GlobalChecker {
|
||||
fn consume(&mut self,
|
||||
consume_id: ast::NodeId,
|
||||
_consume_span: Span,
|
||||
cmt: mc::cmt,
|
||||
_mode: euv::ConsumeMode) {
|
||||
let mut cur = &cmt;
|
||||
loop {
|
||||
match cur.cat {
|
||||
mc::cat_static_item => {
|
||||
self.static_consumptions.insert(consume_id);
|
||||
break
|
||||
}
|
||||
mc::cat_deref(ref cmt, _, _) |
|
||||
mc::cat_discr(ref cmt, _) |
|
||||
mc::cat_downcast(ref cmt) |
|
||||
mc::cat_interior(ref cmt, _) => cur = cmt,
|
||||
|
||||
mc::cat_rvalue(..) |
|
||||
mc::cat_copied_upvar(..) |
|
||||
mc::cat_upvar(..) |
|
||||
mc::cat_local(..) => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
fn borrow(&mut self,
|
||||
borrow_id: ast::NodeId,
|
||||
_borrow_span: Span,
|
||||
cmt: mc::cmt,
|
||||
_loan_region: ty::Region,
|
||||
_bk: ty::BorrowKind,
|
||||
_loan_cause: euv::LoanCause) {
|
||||
let mut cur = &cmt;
|
||||
let mut is_interior = false;
|
||||
loop {
|
||||
match cur.cat {
|
||||
mc::cat_rvalue(..) => {
|
||||
self.const_borrows.insert(borrow_id);
|
||||
break
|
||||
}
|
||||
mc::cat_static_item => {
|
||||
if is_interior {
|
||||
self.static_interior_borrows.insert(borrow_id);
|
||||
}
|
||||
break
|
||||
}
|
||||
mc::cat_deref(ref cmt, _, _) |
|
||||
mc::cat_interior(ref cmt, _) => {
|
||||
is_interior = true;
|
||||
cur = cmt;
|
||||
}
|
||||
|
||||
mc::cat_downcast(..) |
|
||||
mc::cat_discr(..) |
|
||||
mc::cat_copied_upvar(..) |
|
||||
mc::cat_upvar(..) |
|
||||
mc::cat_local(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn decl_without_init(&mut self,
|
||||
_id: ast::NodeId,
|
||||
_span: Span) {}
|
||||
fn mutate(&mut self,
|
||||
_assignment_id: ast::NodeId,
|
||||
_assignment_span: Span,
|
||||
_assignee_cmt: mc::cmt,
|
||||
_mode: euv::MutateMode) {}
|
||||
fn consume_pat(&mut self,
|
||||
_consume_pat: &ast::Pat,
|
||||
_cmt: mc::cmt,
|
||||
_mode: euv::ConsumeMode) {}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
use driver::session::Session;
|
||||
use middle::resolve;
|
||||
use middle::def::DefStatic;
|
||||
use middle::def::{DefStatic, DefConst};
|
||||
|
||||
use syntax::ast::{Crate, Expr, ExprPath, Item, ItemStatic, NodeId};
|
||||
use syntax::ast;
|
||||
use syntax::{ast_util, ast_map};
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
|
@ -27,13 +27,13 @@ struct CheckCrateVisitor<'a, 'ast: 'a> {
|
|||
}
|
||||
|
||||
impl<'v, 'a, 'ast> Visitor<'v> for CheckCrateVisitor<'a, 'ast> {
|
||||
fn visit_item(&mut self, i: &Item) {
|
||||
fn visit_item(&mut self, i: &ast::Item) {
|
||||
check_item(self, i);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate<'ast>(sess: &Session,
|
||||
krate: &Crate,
|
||||
krate: &ast::Crate,
|
||||
def_map: &resolve::DefMap,
|
||||
ast_map: &ast_map::Map<'ast>) {
|
||||
let mut visitor = CheckCrateVisitor {
|
||||
|
@ -45,9 +45,10 @@ pub fn check_crate<'ast>(sess: &Session,
|
|||
sess.abort_if_errors();
|
||||
}
|
||||
|
||||
fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
|
||||
fn check_item(v: &mut CheckCrateVisitor, it: &ast::Item) {
|
||||
match it.node {
|
||||
ItemStatic(_, _, ref ex) => {
|
||||
ast::ItemStatic(_, _, ref ex) |
|
||||
ast::ItemConst(_, ref ex) => {
|
||||
check_item_recursion(v.sess, v.ast_map, v.def_map, it);
|
||||
visit::walk_expr(v, &**ex)
|
||||
},
|
||||
|
@ -56,11 +57,11 @@ fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
|
|||
}
|
||||
|
||||
struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
|
||||
root_it: &'a Item,
|
||||
root_it: &'a ast::Item,
|
||||
sess: &'a Session,
|
||||
ast_map: &'a ast_map::Map<'ast>,
|
||||
def_map: &'a resolve::DefMap,
|
||||
idstack: Vec<NodeId>
|
||||
idstack: Vec<ast::NodeId>
|
||||
}
|
||||
|
||||
// Make sure a const item doesn't recursively refer to itself
|
||||
|
@ -68,7 +69,7 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
|
|||
pub fn check_item_recursion<'a>(sess: &'a Session,
|
||||
ast_map: &'a ast_map::Map,
|
||||
def_map: &'a resolve::DefMap,
|
||||
it: &'a Item) {
|
||||
it: &'a ast::Item) {
|
||||
|
||||
let mut visitor = CheckItemRecursionVisitor {
|
||||
root_it: it,
|
||||
|
@ -81,7 +82,7 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
|
|||
}
|
||||
|
||||
impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
|
||||
fn visit_item(&mut self, it: &Item) {
|
||||
fn visit_item(&mut self, it: &ast::Item) {
|
||||
if self.idstack.iter().any(|x| x == &(it.id)) {
|
||||
self.sess.span_err(self.root_it.span, "recursive constant");
|
||||
return;
|
||||
|
@ -91,11 +92,12 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
|
|||
self.idstack.pop();
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, e: &Expr) {
|
||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||
match e.node {
|
||||
ExprPath(..) => {
|
||||
ast::ExprPath(..) => {
|
||||
match self.def_map.borrow().find(&e.id) {
|
||||
Some(&DefStatic(def_id, _)) if
|
||||
Some(&DefStatic(def_id, _)) |
|
||||
Some(&DefConst(def_id)) if
|
||||
ast_util::is_local(def_id) => {
|
||||
self.visit_item(&*self.ast_map.expect_item(def_id.node));
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ pub fn join_all<It: Iterator<constness>>(mut cs: It) -> constness {
|
|||
fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
|
||||
let opt_def = tcx.def_map.borrow().find_copy(&e.id);
|
||||
match opt_def {
|
||||
Some(def::DefStatic(def_id, false)) => {
|
||||
Some(def::DefConst(def_id)) => {
|
||||
lookup_const_by_id(tcx, def_id)
|
||||
}
|
||||
Some(def::DefVariant(enum_def, variant_def, _)) => {
|
||||
|
@ -155,7 +155,7 @@ pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
|
|||
match tcx.map.find(def_id.node) {
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
ItemStatic(_, ast::MutImmutable, ref const_expr) => {
|
||||
ItemConst(_, ref const_expr) => {
|
||||
Some(&**const_expr)
|
||||
}
|
||||
_ => None
|
||||
|
@ -173,7 +173,7 @@ pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
|
|||
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
|
||||
|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
|
||||
csearch::found(&ast::IIItem(ref item)) => match item.node {
|
||||
ItemStatic(_, ast::MutImmutable, ref const_expr) => Some(const_expr.id),
|
||||
ItemConst(_, ref const_expr) => Some(const_expr.id),
|
||||
_ => None
|
||||
},
|
||||
_ => None
|
||||
|
|
|
@ -215,7 +215,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
|||
ast::ItemFn(..)
|
||||
| ast::ItemEnum(..)
|
||||
| ast::ItemTy(..)
|
||||
| ast::ItemStatic(..) => {
|
||||
| ast::ItemStatic(..)
|
||||
| ast::ItemConst(..) => {
|
||||
visit::walk_item(self, &*item);
|
||||
}
|
||||
_ => ()
|
||||
|
|
|
@ -20,6 +20,7 @@ pub enum Def {
|
|||
DefMod(ast::DefId),
|
||||
DefForeignMod(ast::DefId),
|
||||
DefStatic(ast::DefId, bool /* is_mutbl */),
|
||||
DefConst(ast::DefId),
|
||||
DefLocal(ast::NodeId),
|
||||
DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
|
||||
DefTy(ast::DefId, bool /* is_enum */),
|
||||
|
@ -61,7 +62,7 @@ impl Def {
|
|||
DefForeignMod(id) | DefStatic(id, _) |
|
||||
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
|
||||
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
|
||||
DefMethod(id, _) => {
|
||||
DefMethod(id, _) | DefConst(id) => {
|
||||
id
|
||||
}
|
||||
DefLocal(id) |
|
||||
|
|
|
@ -267,7 +267,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
}
|
||||
}
|
||||
|
||||
fn consume_expr(&mut self, expr: &ast::Expr) {
|
||||
pub fn consume_expr(&mut self, expr: &ast::Expr) {
|
||||
debug!("consume_expr(expr={})", expr.repr(self.tcx()));
|
||||
|
||||
let cmt = return_if_err!(self.mc.cat_expr(expr));
|
||||
|
|
|
@ -58,20 +58,20 @@ pub struct Edge<E> {
|
|||
#[deriving(Clone, PartialEq, Show)]
|
||||
pub struct NodeIndex(pub uint);
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
|
||||
pub const InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub struct EdgeIndex(pub uint);
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
|
||||
pub const InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
|
||||
|
||||
// Use a private field here to guarantee no more instances are created:
|
||||
#[deriving(Show)]
|
||||
pub struct Direction { repr: uint }
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static Outgoing: Direction = Direction { repr: 0 };
|
||||
pub const Outgoing: Direction = Direction { repr: 0 };
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static Incoming: Direction = Direction { repr: 1 };
|
||||
pub const Incoming: Direction = Direction { repr: 1 };
|
||||
|
||||
impl NodeIndex {
|
||||
fn get(&self) -> uint { let NodeIndex(v) = *self; v }
|
||||
|
|
|
@ -544,7 +544,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||
|
||||
match def {
|
||||
def::DefStruct(..) | def::DefVariant(..) | def::DefFn(..) |
|
||||
def::DefStaticMethod(..) => {
|
||||
def::DefStaticMethod(..) | def::DefConst(..) => {
|
||||
Ok(self.cat_rvalue_node(id, span, expr_ty))
|
||||
}
|
||||
def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
|
||||
|
@ -1104,7 +1104,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||
|x,y,z| op(x,y,z)));
|
||||
}
|
||||
}
|
||||
Some(&def::DefStatic(..)) => {
|
||||
Some(&def::DefConst(..)) => {
|
||||
for subpat in subpats.iter() {
|
||||
if_ok!(self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z)));
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ pub fn pat_is_const(dm: &resolve::DefMap, pat: &Pat) -> bool {
|
|||
match pat.node {
|
||||
PatIdent(_, _, None) | PatEnum(..) => {
|
||||
match dm.borrow().find(&pat.id) {
|
||||
Some(&DefStatic(_, false)) => true,
|
||||
Some(&DefConst(..)) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -805,6 +805,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
def::DefStaticMethod(..) => ck("static method"),
|
||||
def::DefFn(..) => ck("function"),
|
||||
def::DefStatic(..) => ck("static"),
|
||||
def::DefConst(..) => ck("const"),
|
||||
def::DefVariant(..) => ck("variant"),
|
||||
def::DefTy(_, false) => ck("type"),
|
||||
def::DefTy(_, true) => ck("enum"),
|
||||
|
@ -1181,7 +1182,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ast::ItemStatic(..) | ast::ItemStruct(..) |
|
||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
|
||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||
ast::ItemMac(..) => {}
|
||||
}
|
||||
|
@ -1245,7 +1246,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ast::ItemStatic(..) |
|
||||
ast::ItemStatic(..) | ast::ItemConst(..) |
|
||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||
ast::ItemMac(..) => {}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ use syntax::abi;
|
|||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util::{is_local, PostExpansionMethod};
|
||||
use syntax::ast_util;
|
||||
use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone};
|
||||
use syntax::attr;
|
||||
use syntax::visit::Visitor;
|
||||
|
@ -121,15 +120,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
|||
self.worklist.push(def_id.node)
|
||||
} else {
|
||||
match def {
|
||||
// If this path leads to a static, then we may have
|
||||
// to do some work to figure out whether the static
|
||||
// is indeed reachable. (Inlineable statics are
|
||||
// never reachable.)
|
||||
def::DefStatic(..) => {
|
||||
// If this path leads to a constant, then we need to
|
||||
// recurse into the constant to continue finding
|
||||
// items that are reachable.
|
||||
def::DefConst(..) => {
|
||||
self.worklist.push(def_id.node);
|
||||
}
|
||||
|
||||
// If this wasn't a static, then this destination is
|
||||
// If this wasn't a static, then the destination is
|
||||
// surely reachable.
|
||||
_ => {
|
||||
self.reachable_symbols.insert(def_id.node);
|
||||
|
@ -238,15 +236,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
|||
fn propagate(&mut self) {
|
||||
let mut scanned = HashSet::new();
|
||||
loop {
|
||||
if self.worklist.len() == 0 {
|
||||
break
|
||||
}
|
||||
let search_item = self.worklist.pop().unwrap();
|
||||
if scanned.contains(&search_item) {
|
||||
let search_item = match self.worklist.pop() {
|
||||
Some(item) => item,
|
||||
None => break,
|
||||
};
|
||||
if !scanned.insert(search_item) {
|
||||
continue
|
||||
}
|
||||
|
||||
scanned.insert(search_item);
|
||||
match self.tcx.map.find(search_item) {
|
||||
Some(ref item) => self.propagate_node(item, search_item),
|
||||
None if search_item == ast::CRATE_NODE_ID => {}
|
||||
|
@ -297,21 +294,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Statics with insignificant addresses are not reachable
|
||||
// because they're inlined specially into all other crates.
|
||||
ast::ItemStatic(_, mutbl, ref init) => {
|
||||
if !ast_util::static_has_significant_address(
|
||||
mutbl,
|
||||
item.attrs.as_slice()) {
|
||||
self.reachable_symbols.remove(&search_item);
|
||||
}
|
||||
visit::walk_expr(self, &**init);
|
||||
// Reachable constants will be inlined into other crates
|
||||
// unconditionally, so we need to make sure that their
|
||||
// contents are also reachable.
|
||||
ast::ItemConst(_, ref init) => {
|
||||
self.visit_expr(&**init);
|
||||
}
|
||||
|
||||
// These are normal, nothing reachable about these
|
||||
// inherently and their children are already in the
|
||||
// worklist, as determined by the privacy pass
|
||||
ast::ItemTy(..) |
|
||||
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
|
||||
ast::ItemMod(..) | ast::ItemForeignMod(..) |
|
||||
ast::ItemImpl(..) | ast::ItemTrait(..) |
|
||||
ast::ItemStruct(..) | ast::ItemEnum(..) => {}
|
||||
|
|
|
@ -29,7 +29,7 @@ use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
|
|||
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
|
||||
use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
|
||||
use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
|
||||
use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local};
|
||||
use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst};
|
||||
use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
|
||||
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
|
||||
use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
|
||||
|
@ -1243,6 +1243,12 @@ impl<'a> Resolver<'a> {
|
|||
(DefStatic(local_def(item.id), mutbl), sp, is_public);
|
||||
parent
|
||||
}
|
||||
ItemConst(_, _) => {
|
||||
self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp)
|
||||
.define_value(DefConst(local_def(item.id)),
|
||||
sp, is_public);
|
||||
parent
|
||||
}
|
||||
ItemFn(_, fn_style, _, _, _) => {
|
||||
let name_bindings =
|
||||
self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
|
||||
|
@ -1829,7 +1835,7 @@ impl<'a> Resolver<'a> {
|
|||
csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
|
||||
.map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, is_public);
|
||||
}
|
||||
DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
|
||||
DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) => {
|
||||
debug!("(building reduced graph for external \
|
||||
crate) building value (fn/static) {}", final_ident);
|
||||
child_name_bindings.define_value(def, DUMMY_SP, is_public);
|
||||
|
@ -4216,7 +4222,7 @@ impl<'a> Resolver<'a> {
|
|||
&**block);
|
||||
}
|
||||
|
||||
ItemStatic(..) => {
|
||||
ItemConst(..) | ItemStatic(..) => {
|
||||
self.with_constant_rib(|this| {
|
||||
visit::walk_item(this, item);
|
||||
});
|
||||
|
@ -5106,6 +5112,7 @@ impl<'a> Resolver<'a> {
|
|||
Some(def @ (DefFn(..), _)) |
|
||||
Some(def @ (DefVariant(..), _)) |
|
||||
Some(def @ (DefStruct(..), _)) |
|
||||
Some(def @ (DefConst(..), _)) |
|
||||
Some(def @ (DefStatic(..), _)) => {
|
||||
self.record_def(pattern.id, def);
|
||||
}
|
||||
|
@ -5193,12 +5200,14 @@ impl<'a> Resolver<'a> {
|
|||
def @ DefVariant(..) | def @ DefStruct(..) => {
|
||||
return FoundStructOrEnumVariant(def, LastMod(AllPublic));
|
||||
}
|
||||
def @ DefStatic(_, false) => {
|
||||
def @ DefConst(..) => {
|
||||
return FoundConst(def, LastMod(AllPublic));
|
||||
}
|
||||
DefStatic(_, true) => {
|
||||
DefStatic(..) => {
|
||||
self.resolve_error(span,
|
||||
"mutable static variables cannot be referenced in a pattern");
|
||||
"static variables cannot be \
|
||||
referenced in a pattern, \
|
||||
use a `const` instead");
|
||||
return BareIdentifierPatternUnresolved;
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -92,7 +92,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
ast::ItemMod(..) |
|
||||
ast::ItemMac(..) |
|
||||
ast::ItemForeignMod(..) |
|
||||
ast::ItemStatic(..) => {
|
||||
ast::ItemStatic(..) | ast::ItemConst(..) => {
|
||||
self.with(|_, f| f(RootScope), |v| visit::walk_item(v, item));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -230,6 +230,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
def::DefAssociatedTy(..) |
|
||||
def::DefTrait(_) => Some(recorder::TypeRef),
|
||||
def::DefStatic(_, _) |
|
||||
def::DefConst(_) |
|
||||
def::DefLocal(_) |
|
||||
def::DefVariant(_, _, _) |
|
||||
def::DefUpvar(..) => Some(recorder::VarRef),
|
||||
|
@ -521,6 +522,29 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
self.visit_expr(expr);
|
||||
}
|
||||
|
||||
fn process_const(&mut self,
|
||||
item: &ast::Item,
|
||||
typ: &ast::Ty,
|
||||
expr: &ast::Expr)
|
||||
{
|
||||
let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span,
|
||||
keywords::Const);
|
||||
self.fmt.static_str(item.span,
|
||||
sub_span,
|
||||
item.id,
|
||||
get_ident(item.ident).get(),
|
||||
qualname.as_slice(),
|
||||
"",
|
||||
ty_to_string(&*typ).as_slice(),
|
||||
self.cur_scope);
|
||||
|
||||
// walk type and init value
|
||||
self.visit_ty(&*typ);
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
|
||||
fn process_struct(&mut self,
|
||||
item: &ast::Item,
|
||||
def: &ast::StructDef,
|
||||
|
@ -740,6 +764,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
def::DefUpvar(..) |
|
||||
def::DefLocal(..) |
|
||||
def::DefStatic(..) |
|
||||
def::DefConst(..) |
|
||||
def::DefVariant(..) => self.fmt.ref_str(recorder::VarRef,
|
||||
ex.span,
|
||||
sub_span,
|
||||
|
@ -807,6 +832,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
},
|
||||
def::DefLocal(_) |
|
||||
def::DefStatic(_,_) |
|
||||
def::DefConst(..) |
|
||||
def::DefStruct(_) |
|
||||
def::DefFn(..) => self.write_sub_paths_truncated(path),
|
||||
_ => {},
|
||||
|
@ -1008,6 +1034,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
self.process_fn(item, &**decl, ty_params, &**body),
|
||||
ast::ItemStatic(ref typ, mt, ref expr) =>
|
||||
self.process_static(item, &**typ, mt, &**expr),
|
||||
ast::ItemConst(ref typ, ref expr) =>
|
||||
self.process_const(item, &**typ, &**expr),
|
||||
ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params),
|
||||
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
|
||||
ast::ItemImpl(ref ty_params,
|
||||
|
@ -1386,6 +1414,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
self.cur_scope),
|
||||
// FIXME(nrc) what is this doing here?
|
||||
def::DefStatic(_, _) => {}
|
||||
def::DefConst(..) => {}
|
||||
_ => error!("unexpected definition kind when processing collected paths: {:?}",
|
||||
*def)
|
||||
}
|
||||
|
|
0
src/librustc/middle/traexpr
Normal file
0
src/librustc/middle/traexpr
Normal file
|
@ -271,14 +271,14 @@ impl<'a> Opt<'a> {
|
|||
match *self {
|
||||
ConstantValue(ConstantExpr(lit_expr)) => {
|
||||
let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id);
|
||||
let (llval, _, _) = consts::const_expr(ccx, &*lit_expr, true);
|
||||
let (llval, _) = consts::const_expr(ccx, &*lit_expr);
|
||||
let lit_datum = immediate_rvalue(llval, lit_ty);
|
||||
let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
|
||||
SingleResult(Result::new(bcx, lit_datum.val))
|
||||
}
|
||||
ConstantRange(ConstantExpr(ref l1), ConstantExpr(ref l2)) => {
|
||||
let (l1, _, _) = consts::const_expr(ccx, &**l1, true);
|
||||
let (l2, _, _) = consts::const_expr(ccx, &**l2, true);
|
||||
let (l1, _) = consts::const_expr(ccx, &**l1);
|
||||
let (l2, _) = consts::const_expr(ccx, &**l2);
|
||||
RangeResult(Result::new(bcx, l1), Result::new(bcx, l2))
|
||||
}
|
||||
Variant(disr_val, ref repr, _) => {
|
||||
|
@ -350,7 +350,20 @@ struct ArmData<'p, 'blk, 'tcx: 'blk> {
|
|||
struct Match<'a, 'p: 'a, 'blk: 'a, 'tcx: 'blk> {
|
||||
pats: Vec<&'p ast::Pat>,
|
||||
data: &'a ArmData<'p, 'blk, 'tcx>,
|
||||
bound_ptrs: Vec<(Ident, ValueRef)>
|
||||
bound_ptrs: Vec<(Ident, ValueRef)>,
|
||||
|
||||
// This is a pointer to an instance of check_match::DUMMY_WILD_PAT. The
|
||||
// check_match code requires that we pass this in (with the same lifetime as
|
||||
// the patterns passed in). Unfortunately this is required to be propagated
|
||||
// into this structure in order to get the lifetimes to work.
|
||||
//
|
||||
// Lots of the `check_match` code will deal with &DUMMY_WILD_PAT when
|
||||
// returning references, which used to have the `'static` lifetime before
|
||||
// const was added to the language. The DUMMY_WILD_PAT does not implement
|
||||
// Sync, however, so it must be a const, which longer has a static lifetime,
|
||||
// hence we're passing it in here. This certainly isn't crucial, and if it
|
||||
// can be removed, please do!
|
||||
dummy: &'p ast::Pat,
|
||||
}
|
||||
|
||||
impl<'a, 'p, 'blk, 'tcx> Repr for Match<'a, 'p, 'blk, 'tcx> {
|
||||
|
@ -403,20 +416,21 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
*pats.get_mut(col) = pat;
|
||||
Match {
|
||||
pats: pats,
|
||||
dummy: br.dummy,
|
||||
data: &*br.data,
|
||||
bound_ptrs: bound_ptrs
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
type EnterPatterns<'a> = <'p> |&[&'p ast::Pat]|: 'a -> Option<Vec<&'p ast::Pat>>;
|
||||
type EnterPatterns<'a, 'p> = |&[&'p ast::Pat]|: 'a -> Option<Vec<&'p ast::Pat>>;
|
||||
|
||||
fn enter_match<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
fn enter_match<'a, 'b, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
dm: &DefMap,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef,
|
||||
e: EnterPatterns)
|
||||
e: EnterPatterns<'b, 'p>)
|
||||
-> Vec<Match<'a, 'p, 'blk, 'tcx>> {
|
||||
debug!("enter_match(bcx={}, m={}, col={}, val={})",
|
||||
bcx.to_str(),
|
||||
|
@ -450,6 +464,7 @@ fn enter_match<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
Match {
|
||||
pats: pats,
|
||||
dummy: br.dummy,
|
||||
data: br.data,
|
||||
bound_ptrs: bound_ptrs
|
||||
}
|
||||
|
@ -544,7 +559,8 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
|
|||
|
||||
let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() };
|
||||
enter_match(bcx, dm, m, col, val, |pats|
|
||||
check_match::specialize(&mcx, pats.as_slice(), &ctor, col, variant_size)
|
||||
check_match::specialize(&mcx, pats.as_slice(), m[0].dummy, &ctor, col,
|
||||
variant_size)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1041,9 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
match adt_vals {
|
||||
Some(field_vals) => {
|
||||
let pats = enter_match(bcx, dm, m, col, val, |pats|
|
||||
check_match::specialize(&mcx, pats, &check_match::Single, col, field_vals.len())
|
||||
check_match::specialize(&mcx, pats, m[0].dummy,
|
||||
&check_match::Single, col,
|
||||
field_vals.len())
|
||||
);
|
||||
let vals = field_vals.append(vals_left.as_slice());
|
||||
compile_submatch(bcx, pats.as_slice(), vals.as_slice(), chk, has_genuine_default);
|
||||
|
@ -1347,6 +1365,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
|
|||
bindings_map: create_bindings_map(bcx, &**arm.pats.get(0), discr_expr, &*arm.body)
|
||||
}).collect();
|
||||
|
||||
let dummy = check_match::DUMMY_WILD_PAT.clone();
|
||||
let mut static_inliner = StaticInliner::new(scope_cx.tcx());
|
||||
let arm_pats: Vec<Vec<P<ast::Pat>>> = arm_datas.iter().map(|arm_data| {
|
||||
arm_data.arm.pats.iter().map(|p| static_inliner.fold_pat((*p).clone())).collect()
|
||||
|
@ -1355,6 +1374,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
|
|||
for (arm_data, pats) in arm_datas.iter().zip(arm_pats.iter()) {
|
||||
matches.extend(pats.iter().map(|p| Match {
|
||||
pats: vec![&**p],
|
||||
dummy: &dummy,
|
||||
data: arm_data,
|
||||
bound_ptrs: Vec::new(),
|
||||
}));
|
||||
|
|
|
@ -32,7 +32,7 @@ use driver::config::{NoDebugInfo, FullDebugInfo};
|
|||
use driver::driver::{CrateAnalysis, CrateTranslation, ModuleTranslation};
|
||||
use driver::session::Session;
|
||||
use lint;
|
||||
use llvm::{BasicBlockRef, ModuleRef, ValueRef, Vector, get_param};
|
||||
use llvm::{BasicBlockRef, ValueRef, Vector, get_param};
|
||||
use llvm;
|
||||
use metadata::{csearch, encoder, loader};
|
||||
use middle::astencode;
|
||||
|
@ -89,7 +89,7 @@ use std::rc::Rc;
|
|||
use std::{i8, i16, i32, i64};
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel, Rust, RustCall};
|
||||
use syntax::abi::{RustIntrinsic, Abi, OsWindows};
|
||||
use syntax::ast_util::{local_def, is_local};
|
||||
use syntax::ast_util::local_def;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
|
@ -317,17 +317,31 @@ pub fn decl_internal_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> Va
|
|||
llfn
|
||||
}
|
||||
|
||||
pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
|
||||
name: &str, ty: Type) -> ValueRef {
|
||||
match externs.find_equiv(&name) {
|
||||
pub fn get_extern_const(ccx: &CrateContext, did: ast::DefId,
|
||||
t: ty::t) -> ValueRef {
|
||||
let name = csearch::get_symbol(&ccx.sess().cstore, did);
|
||||
let ty = type_of(ccx, t);
|
||||
match ccx.externs().borrow_mut().find(&name) {
|
||||
Some(n) => return *n,
|
||||
None => ()
|
||||
}
|
||||
unsafe {
|
||||
let c = name.with_c_str(|buf| {
|
||||
llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf)
|
||||
llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf)
|
||||
});
|
||||
externs.insert(name.to_string(), c);
|
||||
// Thread-local statics in some other crate need to *always* be linked
|
||||
// against in a thread-local fashion, so we need to be sure to apply the
|
||||
// thread-local attribute locally if it was present remotely. If we
|
||||
// don't do this then linker errors can be generated where the linker
|
||||
// complains that one object files has a thread local version of the
|
||||
// symbol and another one doesn't.
|
||||
ty::each_attr(ccx.tcx(), did, |attr| {
|
||||
if attr.check_name("thread_local") {
|
||||
llvm::set_thread_local(c, true);
|
||||
}
|
||||
true
|
||||
});
|
||||
ccx.externs().borrow_mut().insert(name.to_string(), c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
@ -935,11 +949,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
|
|||
get_extern_rust_fn(ccx, t, name.as_slice(), did)
|
||||
}
|
||||
_ => {
|
||||
let llty = type_of(ccx, t);
|
||||
get_extern_const(&mut *ccx.externs().borrow_mut(),
|
||||
ccx.llmod(),
|
||||
name.as_slice(),
|
||||
llty)
|
||||
get_extern_const(ccx, did, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2228,21 +2238,19 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
|||
ast::ItemEnum(ref enum_definition, _) => {
|
||||
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
|
||||
}
|
||||
ast::ItemConst(_, ref expr) => {
|
||||
// Recurse on the expression to catch items in blocks
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
v.visit_expr(&**expr);
|
||||
}
|
||||
ast::ItemStatic(_, m, ref expr) => {
|
||||
// Recurse on the expression to catch items in blocks
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
v.visit_expr(&**expr);
|
||||
|
||||
let trans_everywhere = attr::requests_inline(item.attrs.as_slice());
|
||||
for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) {
|
||||
consts::trans_const(ccx, m, item.id);
|
||||
|
||||
consts::trans_static(ccx, m, item.id);
|
||||
let g = get_item_val(ccx, item.id);
|
||||
update_linkage(ccx,
|
||||
g,
|
||||
Some(item.id),
|
||||
if is_origin { OriginalTranslation } else { InlinedCopy });
|
||||
}
|
||||
update_linkage(ccx, g, Some(item.id), OriginalTranslation);
|
||||
|
||||
// Do static_assert checking. It can't really be done much earlier
|
||||
// because we need to get the value of the bool out of LLVM
|
||||
|
@ -2253,7 +2261,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
|||
static");
|
||||
}
|
||||
|
||||
let v = ccx.const_values().borrow().get_copy(&item.id);
|
||||
let v = ccx.static_values().borrow().get_copy(&item.id);
|
||||
unsafe {
|
||||
if !(llvm::LLVMConstIntGetZExtValue(v) != 0) {
|
||||
ccx.sess().span_fatal(expr.span, "static assertion failed");
|
||||
|
@ -2667,23 +2675,21 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
let val = match item {
|
||||
ast_map::NodeItem(i) => {
|
||||
let ty = ty::node_id_to_type(ccx.tcx(), i.id);
|
||||
let sym = exported_name(ccx, id, ty, i.attrs.as_slice());
|
||||
let sym = || exported_name(ccx, id, ty, i.attrs.as_slice());
|
||||
|
||||
let v = match i.node {
|
||||
ast::ItemStatic(_, mutbl, ref expr) => {
|
||||
ast::ItemStatic(_, _, ref expr) => {
|
||||
// If this static came from an external crate, then
|
||||
// we need to get the symbol from csearch instead of
|
||||
// using the current crate's name/version
|
||||
// information in the hash of the symbol
|
||||
let sym = sym();
|
||||
debug!("making {}", sym);
|
||||
let is_local = !ccx.external_srcs().borrow().contains_key(&id);
|
||||
|
||||
// We need the translated value here, because for enums the
|
||||
// LLVM type is not fully determined by the Rust type.
|
||||
let (v, inlineable, ty) = consts::const_expr(ccx, &**expr, is_local);
|
||||
ccx.const_values().borrow_mut().insert(id, v);
|
||||
let mut inlineable = inlineable;
|
||||
|
||||
let (v, ty) = consts::const_expr(ccx, &**expr);
|
||||
ccx.static_values().borrow_mut().insert(id, v);
|
||||
unsafe {
|
||||
// boolean SSA values are i1, but they have to be stored in i8 slots,
|
||||
// otherwise some LLVM optimization passes don't work as expected
|
||||
|
@ -2694,55 +2700,30 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
};
|
||||
if contains_null(sym.as_slice()) {
|
||||
ccx.sess().fatal(
|
||||
format!("Illegal null byte in export_name value: `{}`",
|
||||
sym).as_slice());
|
||||
format!("Illegal null byte in export_name \
|
||||
value: `{}`", sym).as_slice());
|
||||
}
|
||||
let g = sym.as_slice().with_c_str(|buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod(), llty, buf)
|
||||
});
|
||||
|
||||
// Apply the `unnamed_addr` attribute if
|
||||
// requested
|
||||
if !ast_util::static_has_significant_address(
|
||||
mutbl,
|
||||
i.attrs.as_slice()) {
|
||||
llvm::SetUnnamedAddr(g, true);
|
||||
|
||||
// This is a curious case where we must make
|
||||
// all of these statics inlineable. If a
|
||||
// global is not tagged as `#[inline(never)]`,
|
||||
// then LLVM won't coalesce globals unless they
|
||||
// have an internal linkage type. This means that
|
||||
// external crates cannot use this global.
|
||||
// This is a problem for things like inner
|
||||
// statics in generic functions, because the
|
||||
// function will be inlined into another
|
||||
// crate and then attempt to link to the
|
||||
// static in the original crate, only to
|
||||
// find that it's not there. On the other
|
||||
// side of inlining, the crates knows to
|
||||
// not declare this static as
|
||||
// available_externally (because it isn't)
|
||||
inlineable = true;
|
||||
}
|
||||
|
||||
if attr::contains_name(i.attrs.as_slice(),
|
||||
"thread_local") {
|
||||
llvm::set_thread_local(g, true);
|
||||
}
|
||||
|
||||
if !inlineable {
|
||||
debug!("{} not inlined", sym);
|
||||
ccx.non_inlineable_statics().borrow_mut()
|
||||
.insert(id);
|
||||
}
|
||||
|
||||
ccx.item_symbols().borrow_mut().insert(i.id, sym);
|
||||
g
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemConst(_, ref expr) => {
|
||||
let (v, _) = consts::const_expr(ccx, &**expr);
|
||||
ccx.const_values().borrow_mut().insert(id, v);
|
||||
v
|
||||
}
|
||||
|
||||
ast::ItemFn(_, _, abi, _, _) => {
|
||||
let sym = sym();
|
||||
let llfn = if abi == Rust {
|
||||
register_fn(ccx, i.span, sym, i.id, ty)
|
||||
} else {
|
||||
|
@ -2911,7 +2892,6 @@ pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
|
|||
tcx: cx.tcx(),
|
||||
reexports2: cx.exp_map2(),
|
||||
item_symbols: cx.item_symbols(),
|
||||
non_inlineable_statics: cx.non_inlineable_statics(),
|
||||
link_meta: cx.link_meta(),
|
||||
cstore: &cx.sess().cstore,
|
||||
encode_inlined_item: ie,
|
||||
|
|
|
@ -196,6 +196,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
|
|||
}
|
||||
}
|
||||
def::DefStatic(..) |
|
||||
def::DefConst(..) |
|
||||
def::DefLocal(..) |
|
||||
def::DefUpvar(..) => {
|
||||
datum_callee(bcx, ref_expr)
|
||||
|
|
|
@ -49,9 +49,9 @@ pub struct CustomScopeIndex {
|
|||
index: uint
|
||||
}
|
||||
|
||||
pub static EXIT_BREAK: uint = 0;
|
||||
pub static EXIT_LOOP: uint = 1;
|
||||
pub static EXIT_MAX: uint = 2;
|
||||
pub const EXIT_BREAK: uint = 0;
|
||||
pub const EXIT_LOOP: uint = 1;
|
||||
pub const EXIT_MAX: uint = 2;
|
||||
|
||||
pub enum CleanupScopeKind<'blk, 'tcx: 'blk> {
|
||||
CustomScopeKind,
|
||||
|
|
|
@ -33,7 +33,6 @@ use middle::ty;
|
|||
use util::ppaux::{Repr, ty_to_string};
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::vec;
|
||||
use libc::c_uint;
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::ptr::P;
|
||||
|
@ -96,24 +95,20 @@ pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
|
|||
}
|
||||
}
|
||||
|
||||
// Helper function because we don't have tuple-swizzling.
|
||||
fn first_two<R, S, T>((a, b, _): (R, S, T)) -> (R, S) {
|
||||
(a, b)
|
||||
}
|
||||
|
||||
fn const_vec(cx: &CrateContext, e: &ast::Expr,
|
||||
es: &[P<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
|
||||
es: &[P<ast::Expr>]) -> (ValueRef, Type) {
|
||||
let vec_ty = ty::expr_ty(cx.tcx(), e);
|
||||
let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
|
||||
let llunitty = type_of::type_of(cx, unit_ty);
|
||||
let (vs, inlineable) = vec::unzip(es.iter().map(|e| first_two(const_expr(cx, &**e, is_local))));
|
||||
let vs = es.iter().map(|e| const_expr(cx, &**e).val0())
|
||||
.collect::<Vec<_>>();
|
||||
// If the vector contains enums, an LLVM array won't work.
|
||||
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
|
||||
C_struct(cx, vs.as_slice(), false)
|
||||
} else {
|
||||
C_array(llunitty, vs.as_slice())
|
||||
};
|
||||
(v, llunitty, inlineable.iter().fold(true, |a, &b| a && b))
|
||||
(v, llunitty)
|
||||
}
|
||||
|
||||
pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) -> ValueRef {
|
||||
|
@ -177,7 +172,7 @@ fn const_deref(cx: &CrateContext, v: ValueRef, t: ty::t, explicit: bool)
|
|||
}
|
||||
|
||||
pub fn get_const_val(cx: &CrateContext,
|
||||
mut def_id: ast::DefId) -> (ValueRef, bool) {
|
||||
mut def_id: ast::DefId) -> ValueRef {
|
||||
let contains_key = cx.const_values().borrow().contains_key(&def_id.node);
|
||||
if !ast_util::is_local(def_id) || !contains_key {
|
||||
if !ast_util::is_local(def_id) {
|
||||
|
@ -185,21 +180,17 @@ pub fn get_const_val(cx: &CrateContext,
|
|||
}
|
||||
|
||||
match cx.tcx().map.expect_item(def_id.node).node {
|
||||
ast::ItemStatic(_, ast::MutImmutable, _) => {
|
||||
trans_const(cx, ast::MutImmutable, def_id.node);
|
||||
}
|
||||
ast::ItemConst(..) => { base::get_item_val(cx, def_id.node); }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
(cx.const_values().borrow().get_copy(&def_id.node),
|
||||
!cx.non_inlineable_statics().borrow().contains(&def_id.node))
|
||||
cx.const_values().borrow().get_copy(&def_id.node)
|
||||
}
|
||||
|
||||
pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool, ty::t) {
|
||||
let (llconst, inlineable) = const_expr_unadjusted(cx, e, is_local);
|
||||
pub fn const_expr(cx: &CrateContext, e: &ast::Expr) -> (ValueRef, ty::t) {
|
||||
let llconst = const_expr_unadjusted(cx, e);
|
||||
let mut llconst = llconst;
|
||||
let mut inlineable = inlineable;
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
let mut ety_adjusted = ty::expr_ty_adjusted(cx.tcx(), e);
|
||||
let opt_adj = cx.tcx().adjustments.borrow().find_copy(&e.id);
|
||||
|
@ -213,7 +204,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
|||
ety_adjusted,
|
||||
def,
|
||||
llconst,
|
||||
is_local);
|
||||
true);
|
||||
llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
|
||||
}
|
||||
ty::AdjustAddEnv(store) => {
|
||||
|
@ -250,7 +241,6 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
|||
// Don't copy data to do a deref+ref
|
||||
// (i.e., skip the last auto-deref).
|
||||
if adj.autoderefs == 0 {
|
||||
inlineable = false;
|
||||
llconst = const_addr_of(cx, llconst, ast::MutImmutable);
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +261,6 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
|||
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_vec(unit_ty, Some(len)) => {
|
||||
inlineable = false;
|
||||
let llunitty = type_of::type_of(cx, unit_ty);
|
||||
let llptr = const_ptrcast(cx, llconst, llunitty);
|
||||
assert_eq!(abi::slice_elt_base, 0);
|
||||
|
@ -314,29 +303,25 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
|||
e.repr(cx.tcx()), ty_to_string(cx.tcx(), ety),
|
||||
csize, tsize).as_slice());
|
||||
}
|
||||
(llconst, inlineable, ety_adjusted)
|
||||
(llconst, ety_adjusted)
|
||||
}
|
||||
|
||||
// the bool returned is whether this expression can be inlined into other crates
|
||||
// if it's assigned to a static.
|
||||
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
is_local: bool) -> (ValueRef, bool) {
|
||||
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef {
|
||||
let map_list = |exprs: &[P<ast::Expr>]| {
|
||||
exprs.iter().map(|e| first_two(const_expr(cx, &**e, is_local)))
|
||||
.fold((Vec::new(), true),
|
||||
|(l, all_inlineable), (val, inlineable)| {
|
||||
(l.append_one(val), all_inlineable && inlineable)
|
||||
})
|
||||
exprs.iter().map(|e| const_expr(cx, &**e).val0())
|
||||
.fold(Vec::new(), |l, val| l.append_one(val))
|
||||
};
|
||||
unsafe {
|
||||
let _icx = push_ctxt("const_expr");
|
||||
return match e.node {
|
||||
ast::ExprLit(ref lit) => {
|
||||
(consts::const_lit(cx, e, &**lit), true)
|
||||
consts::const_lit(cx, e, &**lit)
|
||||
}
|
||||
ast::ExprBinary(b, ref e1, ref e2) => {
|
||||
let (te1, _, _) = const_expr(cx, &**e1, is_local);
|
||||
let (te2, _, _) = const_expr(cx, &**e2, is_local);
|
||||
let (te1, _) = const_expr(cx, &**e1);
|
||||
let (te2, _) = const_expr(cx, &**e2);
|
||||
|
||||
let te2 = base::cast_shift_const_rhs(b, te1, te2);
|
||||
|
||||
|
@ -345,7 +330,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
let ty = ty::expr_ty(cx.tcx(), &**e1);
|
||||
let is_float = ty::type_is_fp(ty);
|
||||
let signed = ty::type_is_signed(ty);
|
||||
return (match b {
|
||||
return match b {
|
||||
ast::BiAdd => {
|
||||
if is_float { llvm::LLVMConstFAdd(te1, te2) }
|
||||
else { llvm::LLVMConstAdd(te1, te2) }
|
||||
|
@ -414,13 +399,13 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
else { ConstICmp(IntUGT, te1, te2) }
|
||||
}
|
||||
},
|
||||
}, true)
|
||||
}
|
||||
},
|
||||
ast::ExprUnary(u, ref e) => {
|
||||
let (te, _, _) = const_expr(cx, &**e, is_local);
|
||||
let (te, _) = const_expr(cx, &**e);
|
||||
let ty = ty::expr_ty(cx.tcx(), &**e);
|
||||
let is_float = ty::type_is_fp(ty);
|
||||
return (match u {
|
||||
return match u {
|
||||
ast::UnUniq | ast::UnDeref => {
|
||||
let (dv, _dt) = const_deref(cx, te, ty, true);
|
||||
dv
|
||||
|
@ -430,26 +415,26 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
if is_float { llvm::LLVMConstFNeg(te) }
|
||||
else { llvm::LLVMConstNeg(te) }
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
ast::ExprField(ref base, field, _) => {
|
||||
let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
|
||||
let (bv, bt) = const_expr(cx, &**base);
|
||||
let brepr = adt::represent_type(cx, bt);
|
||||
expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| {
|
||||
let ix = ty::field_idx_strict(cx.tcx(), field.node.name, field_tys);
|
||||
(adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
|
||||
adt::const_get_field(cx, &*brepr, bv, discr, ix)
|
||||
})
|
||||
}
|
||||
ast::ExprTupField(ref base, idx, _) => {
|
||||
let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
|
||||
let (bv, bt) = const_expr(cx, &**base);
|
||||
let brepr = adt::represent_type(cx, bt);
|
||||
expr::with_field_tys(cx.tcx(), bt, None, |discr, _| {
|
||||
(adt::const_get_field(cx, &*brepr, bv, discr, idx.node), inlineable)
|
||||
adt::const_get_field(cx, &*brepr, bv, discr, idx.node)
|
||||
})
|
||||
}
|
||||
|
||||
ast::ExprIndex(ref base, ref index) => {
|
||||
let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
|
||||
let (bv, bt) = const_expr(cx, &**base);
|
||||
let iv = match const_eval::eval_const_expr(cx.tcx(), &**index) {
|
||||
const_eval::const_int(i) => i as u64,
|
||||
const_eval::const_uint(u) => u,
|
||||
|
@ -500,13 +485,13 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
cx.sess().span_err(e.span,
|
||||
"const index-expr is out of bounds");
|
||||
}
|
||||
(const_get_elt(cx, arr, [iv as c_uint]), inlineable)
|
||||
const_get_elt(cx, arr, [iv as c_uint])
|
||||
}
|
||||
ast::ExprCast(ref base, _) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
let llty = type_of::type_of(cx, ety);
|
||||
let (v, inlineable, basety) = const_expr(cx, &**base, is_local);
|
||||
return (match (expr::cast_type_kind(cx.tcx(), basety),
|
||||
let (v, basety) = const_expr(cx, &**base);
|
||||
return match (expr::cast_type_kind(cx.tcx(), basety),
|
||||
expr::cast_type_kind(cx.tcx(), ety)) {
|
||||
|
||||
(expr::cast_integral, expr::cast_integral) => {
|
||||
|
@ -554,17 +539,38 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
cx.sess().impossible_case(e.span,
|
||||
"bad combination of types for cast")
|
||||
}
|
||||
}, inlineable)
|
||||
}
|
||||
}
|
||||
ast::ExprAddrOf(mutbl, ref sub) => {
|
||||
let (e, _, _) = const_expr(cx, &**sub, is_local);
|
||||
(const_addr_of(cx, e, mutbl), false)
|
||||
// If this is the address of some static, then we need to return
|
||||
// the actual address of the static itself (short circuit the rest
|
||||
// of const eval).
|
||||
let mut cur = sub;
|
||||
loop {
|
||||
match cur.node {
|
||||
ast::ExprParen(ref sub) => cur = sub,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
let opt_def = cx.tcx().def_map.borrow().find_copy(&cur.id);
|
||||
match opt_def {
|
||||
Some(def::DefStatic(def_id, _)) => {
|
||||
let ty = ty::expr_ty(cx.tcx(), e);
|
||||
return get_static_val(cx, def_id, ty);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// If this isn't the address of a static, then keep going through
|
||||
// normal constant evaluation.
|
||||
let (e, _) = const_expr(cx, &**sub);
|
||||
const_addr_of(cx, e, mutbl)
|
||||
}
|
||||
ast::ExprTup(ref es) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
let repr = adt::represent_type(cx, ety);
|
||||
let (vals, inlineable) = map_list(es.as_slice());
|
||||
(adt::trans_const(cx, &*repr, 0, vals.as_slice()), inlineable)
|
||||
let vals = map_list(es.as_slice());
|
||||
adt::trans_const(cx, &*repr, 0, vals.as_slice())
|
||||
}
|
||||
ast::ExprStruct(_, ref fs, ref base_opt) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
|
@ -572,36 +578,34 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
let tcx = cx.tcx();
|
||||
|
||||
let base_val = match *base_opt {
|
||||
Some(ref base) => Some(const_expr(cx, &**base, is_local)),
|
||||
Some(ref base) => Some(const_expr(cx, &**base)),
|
||||
None => None
|
||||
};
|
||||
|
||||
expr::with_field_tys(tcx, ety, Some(e.id), |discr, field_tys| {
|
||||
let (cs, inlineable) = vec::unzip(field_tys.iter().enumerate()
|
||||
let cs = field_tys.iter().enumerate()
|
||||
.map(|(ix, &field_ty)| {
|
||||
match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) {
|
||||
Some(ref f) => first_two(const_expr(cx, &*f.expr, is_local)),
|
||||
Some(ref f) => const_expr(cx, &*f.expr).val0(),
|
||||
None => {
|
||||
match base_val {
|
||||
Some((bv, inlineable, _)) => {
|
||||
(adt::const_get_field(cx, &*repr, bv, discr, ix),
|
||||
inlineable)
|
||||
Some((bv, _)) => {
|
||||
adt::const_get_field(cx, &*repr, bv,
|
||||
discr, ix)
|
||||
}
|
||||
None => cx.sess().span_bug(e.span, "missing struct field")
|
||||
None => {
|
||||
cx.sess().span_bug(e.span,
|
||||
"missing struct field")
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
(adt::trans_const(cx, &*repr, discr, cs.as_slice()),
|
||||
inlineable.iter().fold(true, |a, &b| a && b))
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
adt::trans_const(cx, &*repr, discr, cs.as_slice())
|
||||
})
|
||||
}
|
||||
ast::ExprVec(ref es) => {
|
||||
let (v, _, inlineable) = const_vec(cx,
|
||||
e,
|
||||
es.as_slice(),
|
||||
is_local);
|
||||
(v, inlineable)
|
||||
const_vec(cx, e, es.as_slice()).val0()
|
||||
}
|
||||
ast::ExprRepeat(ref elem, ref count) => {
|
||||
let vec_ty = ty::expr_ty(cx.tcx(), e);
|
||||
|
@ -612,13 +616,12 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
const_eval::const_uint(i) => i as uint,
|
||||
_ => cx.sess().span_bug(count.span, "count must be integral const expression.")
|
||||
};
|
||||
let vs = Vec::from_elem(n, const_expr(cx, &**elem, is_local).val0());
|
||||
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
|
||||
let vs = Vec::from_elem(n, const_expr(cx, &**elem).val0());
|
||||
if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
|
||||
C_struct(cx, vs.as_slice(), false)
|
||||
} else {
|
||||
C_array(llunitty, vs.as_slice())
|
||||
};
|
||||
(v, true)
|
||||
}
|
||||
}
|
||||
ast::ExprPath(ref pth) => {
|
||||
// Assert that there are no type parameters in this path.
|
||||
|
@ -629,13 +632,13 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
Some(def::DefFn(def_id, _fn_style, _)) => {
|
||||
if !ast_util::is_local(def_id) {
|
||||
let ty = csearch::get_type(cx.tcx(), def_id).ty;
|
||||
(base::trans_external_path(cx, def_id, ty), true)
|
||||
base::trans_external_path(cx, def_id, ty)
|
||||
} else {
|
||||
assert!(ast_util::is_local(def_id));
|
||||
(base::get_item_val(cx, def_id.node), true)
|
||||
base::get_item_val(cx, def_id.node)
|
||||
}
|
||||
}
|
||||
Some(def::DefStatic(def_id, false)) => {
|
||||
Some(def::DefConst(def_id)) => {
|
||||
get_const_val(cx, def_id)
|
||||
}
|
||||
Some(def::DefVariant(enum_did, variant_did, _)) => {
|
||||
|
@ -644,15 +647,16 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
let vinfo = ty::enum_variant_with_id(cx.tcx(),
|
||||
enum_did,
|
||||
variant_did);
|
||||
(adt::trans_const(cx, &*repr, vinfo.disr_val, []), true)
|
||||
adt::trans_const(cx, &*repr, vinfo.disr_val, [])
|
||||
}
|
||||
Some(def::DefStruct(_)) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
let llty = type_of::type_of(cx, ety);
|
||||
(C_null(llty), true)
|
||||
C_null(llty)
|
||||
}
|
||||
_ => {
|
||||
cx.sess().span_bug(e.span, "expected a const, fn, struct, or variant def")
|
||||
cx.sess().span_bug(e.span, "expected a const, fn, struct, \
|
||||
or variant def")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -662,9 +666,8 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
Some(def::DefStruct(_)) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
let repr = adt::represent_type(cx, ety);
|
||||
let (arg_vals, inlineable) = map_list(args.as_slice());
|
||||
(adt::trans_const(cx, &*repr, 0, arg_vals.as_slice()),
|
||||
inlineable)
|
||||
let arg_vals = map_list(args.as_slice());
|
||||
adt::trans_const(cx, &*repr, 0, arg_vals.as_slice())
|
||||
}
|
||||
Some(def::DefVariant(enum_did, variant_did, _)) => {
|
||||
let ety = ty::expr_ty(cx.tcx(), e);
|
||||
|
@ -672,20 +675,20 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
let vinfo = ty::enum_variant_with_id(cx.tcx(),
|
||||
enum_did,
|
||||
variant_did);
|
||||
let (arg_vals, inlineable) = map_list(args.as_slice());
|
||||
(adt::trans_const(cx,
|
||||
let arg_vals = map_list(args.as_slice());
|
||||
adt::trans_const(cx,
|
||||
&*repr,
|
||||
vinfo.disr_val,
|
||||
arg_vals.as_slice()), inlineable)
|
||||
arg_vals.as_slice())
|
||||
}
|
||||
_ => cx.sess().span_bug(e.span, "expected a struct or variant def")
|
||||
}
|
||||
}
|
||||
ast::ExprParen(ref e) => first_two(const_expr(cx, &**e, is_local)),
|
||||
ast::ExprParen(ref e) => const_expr(cx, &**e).val0(),
|
||||
ast::ExprBlock(ref block) => {
|
||||
match block.expr {
|
||||
Some(ref expr) => first_two(const_expr(cx, &**expr, is_local)),
|
||||
None => (C_nil(cx), true)
|
||||
Some(ref expr) => const_expr(cx, &**expr).val0(),
|
||||
None => C_nil(cx)
|
||||
}
|
||||
}
|
||||
_ => cx.sess().span_bug(e.span,
|
||||
|
@ -694,13 +697,13 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
|
||||
pub fn trans_static(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
|
||||
unsafe {
|
||||
let _icx = push_ctxt("trans_const");
|
||||
let _icx = push_ctxt("trans_static");
|
||||
let g = base::get_item_val(ccx, id);
|
||||
// At this point, get_item_val has already translated the
|
||||
// constant's initializer to determine its LLVM type.
|
||||
let v = ccx.const_values().borrow().get_copy(&id);
|
||||
let v = ccx.static_values().borrow().get_copy(&id);
|
||||
// boolean SSA values are i1, but they have to be stored in i8 slots,
|
||||
// otherwise some LLVM optimization passes don't work as expected
|
||||
let v = if llvm::LLVMTypeOf(v) == Type::i1(ccx).to_ref() {
|
||||
|
@ -710,17 +713,20 @@ pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
|
|||
};
|
||||
llvm::LLVMSetInitializer(g, v);
|
||||
|
||||
// `get_item_val` left `g` with external linkage, but we just set an
|
||||
// initializer for it. But we don't know yet if `g` should really be
|
||||
// defined in this compilation unit, so we set its linkage to
|
||||
// `AvailableExternallyLinkage`. (It's still a definition, but acts
|
||||
// like a declaration for most purposes.) If `g` really should be
|
||||
// declared here, then `trans_item` will fix up the linkage later on.
|
||||
llvm::SetLinkage(g, llvm::AvailableExternallyLinkage);
|
||||
|
||||
// As an optimization, all shared statics which do not have interior
|
||||
// mutability are placed into read-only memory.
|
||||
if m != ast::MutMutable {
|
||||
let node_ty = ty::node_id_to_type(ccx.tcx(), id);
|
||||
let tcontents = ty::type_contents(ccx.tcx(), node_ty);
|
||||
if !tcontents.interior_unsafe() {
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
}
|
||||
}
|
||||
debuginfo::create_global_var_metadata(ccx, id, g);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_static_val(ccx: &CrateContext, did: ast::DefId, ty: ty::t) -> ValueRef {
|
||||
if ast_util::is_local(did) { return base::get_item_val(ccx, did.node) }
|
||||
base::trans_external_path(ccx, did, ty)
|
||||
}
|
||||
|
|
|
@ -66,10 +66,6 @@ pub struct SharedCrateContext<'tcx> {
|
|||
reachable: NodeSet,
|
||||
item_symbols: RefCell<NodeMap<String>>,
|
||||
link_meta: LinkMeta,
|
||||
/// A set of static items which cannot be inlined into other crates. This
|
||||
/// will prevent in IIItem() structures from being encoded into the metadata
|
||||
/// that is generated
|
||||
non_inlineable_statics: RefCell<NodeSet>,
|
||||
symbol_hasher: RefCell<Sha256>,
|
||||
tcx: ty::ctxt<'tcx>,
|
||||
stats: Stats,
|
||||
|
@ -121,6 +117,9 @@ pub struct LocalCrateContext {
|
|||
/// Cache of emitted const values
|
||||
const_values: RefCell<NodeMap<ValueRef>>,
|
||||
|
||||
/// Cache of emitted static values
|
||||
static_values: RefCell<NodeMap<ValueRef>>,
|
||||
|
||||
/// Cache of external const values
|
||||
extern_const_values: RefCell<DefIdMap<ValueRef>>,
|
||||
|
||||
|
@ -259,7 +258,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
|
|||
reachable: reachable,
|
||||
item_symbols: RefCell::new(NodeMap::new()),
|
||||
link_meta: link_meta,
|
||||
non_inlineable_statics: RefCell::new(NodeSet::new()),
|
||||
symbol_hasher: RefCell::new(symbol_hasher),
|
||||
tcx: tcx,
|
||||
stats: Stats {
|
||||
|
@ -351,10 +349,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
|
|||
&self.link_meta
|
||||
}
|
||||
|
||||
pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell<NodeSet> {
|
||||
&self.non_inlineable_statics
|
||||
}
|
||||
|
||||
pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
|
||||
&self.symbol_hasher
|
||||
}
|
||||
|
@ -414,6 +408,7 @@ impl LocalCrateContext {
|
|||
const_cstr_cache: RefCell::new(HashMap::new()),
|
||||
const_globals: RefCell::new(HashMap::new()),
|
||||
const_values: RefCell::new(NodeMap::new()),
|
||||
static_values: RefCell::new(NodeMap::new()),
|
||||
extern_const_values: RefCell::new(DefIdMap::new()),
|
||||
impl_method_cache: RefCell::new(HashMap::new()),
|
||||
closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
|
||||
|
@ -610,10 +605,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
&self.local.external_srcs
|
||||
}
|
||||
|
||||
pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell<NodeSet> {
|
||||
&self.shared.non_inlineable_statics
|
||||
}
|
||||
|
||||
pub fn monomorphized<'a>(&'a self) -> &'a RefCell<HashMap<MonoId, ValueRef>> {
|
||||
&self.local.monomorphized
|
||||
}
|
||||
|
@ -638,6 +629,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
&self.local.const_values
|
||||
}
|
||||
|
||||
pub fn static_values<'a>(&'a self) -> &'a RefCell<NodeMap<ValueRef>> {
|
||||
&self.local.static_values
|
||||
}
|
||||
|
||||
pub fn extern_const_values<'a>(&'a self) -> &'a RefCell<DefIdMap<ValueRef>> {
|
||||
&self.local.extern_const_values
|
||||
}
|
||||
|
|
|
@ -776,6 +776,7 @@ pub fn create_global_var_metadata(cx: &CrateContext,
|
|||
ast_map::NodeItem(item) => {
|
||||
match item.node {
|
||||
ast::ItemStatic(..) => (item.ident, item.span),
|
||||
ast::ItemConst(..) => (item.ident, item.span),
|
||||
_ => {
|
||||
cx.sess()
|
||||
.span_bug(item.span,
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
use back::abi;
|
||||
use llvm;
|
||||
use llvm::{ValueRef};
|
||||
use metadata::csearch;
|
||||
use middle::def;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::subst;
|
||||
|
@ -839,25 +838,20 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
trans_def_fn_unadjusted(bcx, ref_expr, def)
|
||||
}
|
||||
def::DefStatic(did, _) => {
|
||||
// There are three things that may happen here:
|
||||
// There are two things that may happen here:
|
||||
// 1) If the static item is defined in this crate, it will be
|
||||
// translated using `get_item_val`, and we return a pointer to
|
||||
// the result.
|
||||
// 2) If the static item is defined in another crate, but is
|
||||
// marked inlineable, then it will be inlined into this crate
|
||||
// and then translated with `get_item_val`. Again, we return a
|
||||
// pointer to the result.
|
||||
// 3) If the static item is defined in another crate and is not
|
||||
// marked inlineable, then we add (or reuse) a declaration of
|
||||
// an external global, and return a pointer to that.
|
||||
// 2) If the static item is defined in another crate then we add
|
||||
// (or reuse) a declaration of an external global, and return a
|
||||
// pointer to that.
|
||||
let const_ty = expr_ty(bcx, ref_expr);
|
||||
|
||||
fn get_val<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, did: ast::DefId, const_ty: ty::t)
|
||||
-> ValueRef {
|
||||
fn get_val<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, did: ast::DefId,
|
||||
const_ty: ty::t) -> ValueRef {
|
||||
// For external constants, we don't inline.
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
// Case 1 or 2. (The inlining in case 2 produces a new
|
||||
// DefId in LOCAL_CRATE.)
|
||||
// Case 1.
|
||||
|
||||
// The LLVM global has the type of its initializer,
|
||||
// which may not be equal to the enum's type for
|
||||
|
@ -866,36 +860,41 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let pty = type_of::type_of(bcx.ccx(), const_ty).ptr_to();
|
||||
PointerCast(bcx, val, pty)
|
||||
} else {
|
||||
// Case 3.
|
||||
match bcx.ccx().extern_const_values().borrow().find(&did) {
|
||||
None => {} // Continue.
|
||||
Some(llval) => {
|
||||
return *llval;
|
||||
// Case 2.
|
||||
base::get_extern_const(bcx.ccx(), did, const_ty)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let llty = type_of::type_of(bcx.ccx(), const_ty);
|
||||
let symbol = csearch::get_symbol(
|
||||
&bcx.ccx().sess().cstore,
|
||||
did);
|
||||
let llval = symbol.as_slice().with_c_str(|buf| {
|
||||
llvm::LLVMAddGlobal(bcx.ccx().llmod(),
|
||||
llty.to_ref(),
|
||||
buf)
|
||||
});
|
||||
bcx.ccx().extern_const_values().borrow_mut()
|
||||
.insert(did, llval);
|
||||
llval
|
||||
}
|
||||
}
|
||||
}
|
||||
// The DefId produced by `maybe_instantiate_inline`
|
||||
// may be in the LOCAL_CRATE or not.
|
||||
let did = inline::maybe_instantiate_inline(bcx.ccx(), did);
|
||||
let val = get_val(bcx, did, const_ty);
|
||||
DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr))
|
||||
}
|
||||
def::DefConst(did) => {
|
||||
// First, inline any external constants into the local crate so we
|
||||
// can be sure to get the LLVM value corresponding to it.
|
||||
let did = inline::maybe_instantiate_inline(bcx.ccx(), did);
|
||||
if did.krate != ast::LOCAL_CRATE {
|
||||
bcx.tcx().sess.span_bug(ref_expr.span,
|
||||
"cross crate constant could not \
|
||||
be inlined");
|
||||
}
|
||||
let val = base::get_item_val(bcx.ccx(), did.node);
|
||||
|
||||
// Next, we need to crate a ByRef rvalue datum to return. We can't
|
||||
// use the normal .to_ref_datum() function because the type of
|
||||
// `val` is not actually the same as `const_ty`.
|
||||
//
|
||||
// To get around this, we make a custom alloca slot with the
|
||||
// appropriate type (const_ty), and then we cast it to a pointer of
|
||||
// typeof(val), store the value, and then hand this slot over to
|
||||
// the datum infrastructure.
|
||||
let const_ty = expr_ty(bcx, ref_expr);
|
||||
let llty = type_of::type_of(bcx.ccx(), const_ty);
|
||||
let slot = alloca(bcx, llty, "const");
|
||||
let pty = Type::from_ref(unsafe { llvm::LLVMTypeOf(val) }).ptr_to();
|
||||
Store(bcx, val, PointerCast(bcx, slot, pty));
|
||||
|
||||
let datum = Datum::new(slot, const_ty, Rvalue::new(ByRef));
|
||||
DatumBlock::new(bcx, datum.to_expr_datum())
|
||||
}
|
||||
_ => {
|
||||
DatumBlock::new(bcx, trans_local_var(bcx, def).to_expr_datum())
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ use middle::ty;
|
|||
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::{local_def, PostExpansionMethod};
|
||||
use syntax::ast_util;
|
||||
|
||||
fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
-> Option<ast::DefId> {
|
||||
|
@ -76,21 +75,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::ItemStatic(_, mutbl, _) => {
|
||||
if !ast_util::static_has_significant_address(mutbl, item.attrs.as_slice()) {
|
||||
// Inlined static items use internal linkage when
|
||||
// possible, so that LLVM will coalesce globals with
|
||||
// identical initializers. (It only does this for
|
||||
// globals with unnamed_addr and either internal or
|
||||
// private linkage.)
|
||||
Some(InternalLinkage)
|
||||
} else {
|
||||
// The address is significant, so we can't create an
|
||||
// internal copy of the static. (The copy would have a
|
||||
// different address from the original.)
|
||||
Some(AvailableExternallyLinkage)
|
||||
}
|
||||
}
|
||||
ast::ItemConst(..) => None,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ use std::collections::enum_set::{EnumSet, CLike};
|
|||
|
||||
pub type Disr = u64;
|
||||
|
||||
pub static INITIAL_DISCRIMINANT_VALUE: Disr = 0;
|
||||
pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
|
||||
|
||||
// Data types
|
||||
|
||||
|
@ -918,7 +918,7 @@ mod primitives {
|
|||
flags: super::has_ty_err as uint,
|
||||
};
|
||||
|
||||
pub static LAST_PRIMITIVE_ID: uint = 18;
|
||||
pub const LAST_PRIMITIVE_ID: uint = 18;
|
||||
}
|
||||
|
||||
// NB: If you change this, you'll probably want to change the corresponding
|
||||
|
@ -1374,6 +1374,7 @@ impl ParameterEnvironment {
|
|||
ast::ItemEnum(..) |
|
||||
ast::ItemStruct(..) |
|
||||
ast::ItemImpl(..) |
|
||||
ast::ItemConst(..) |
|
||||
ast::ItemStatic(..) => {
|
||||
let def_id = ast_util::local_def(id);
|
||||
let pty = ty::lookup_item_type(cx, def_id);
|
||||
|
@ -2199,7 +2200,7 @@ macro_rules! def_type_content_sets(
|
|||
use middle::ty::TypeContents;
|
||||
$(
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static $name: TypeContents = TypeContents { bits: $bits };
|
||||
pub const $name: TypeContents = TypeContents { bits: $bits };
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
@ -3576,6 +3577,8 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
|||
def::DefUpvar(..) |
|
||||
def::DefLocal(..) => LvalueExpr,
|
||||
|
||||
def::DefConst(..) => RvalueDatumExpr,
|
||||
|
||||
def => {
|
||||
tcx.sess.span_bug(
|
||||
expr.span,
|
||||
|
|
|
@ -440,8 +440,8 @@ pub fn ast_path_to_ty_relaxed<'tcx, AC: AstConv<'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
pub static NO_REGIONS: uint = 1;
|
||||
pub static NO_TPS: uint = 2;
|
||||
pub const NO_REGIONS: uint = 1;
|
||||
pub const NO_TPS: uint = 2;
|
||||
|
||||
fn check_path_args(tcx: &ty::ctxt,
|
||||
path: &ast::Path,
|
||||
|
|
|
@ -677,7 +677,8 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
let _indenter = indenter();
|
||||
|
||||
match it.node {
|
||||
ast::ItemStatic(_, _, ref e) => check_const(ccx, it.span, &**e, it.id),
|
||||
ast::ItemStatic(_, _, ref e) |
|
||||
ast::ItemConst(_, ref e) => check_const(ccx, it.span, &**e, it.id),
|
||||
ast::ItemEnum(ref enum_definition, _) => {
|
||||
check_enum_variants(ccx,
|
||||
it.span,
|
||||
|
@ -5083,7 +5084,7 @@ pub fn polytype_for_def(fcx: &FnCtxt,
|
|||
}
|
||||
def::DefFn(id, _, _) | def::DefStaticMethod(id, _, _) |
|
||||
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
|
||||
def::DefStruct(id) => {
|
||||
def::DefStruct(id) | def::DefConst(id) => {
|
||||
return ty::lookup_item_type(fcx.ccx.tcx, id);
|
||||
}
|
||||
def::DefTrait(_) |
|
||||
|
@ -5211,6 +5212,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
|||
|
||||
// Case 2. Reference to a top-level value.
|
||||
def::DefFn(..) |
|
||||
def::DefConst(..) |
|
||||
def::DefStatic(..) => {
|
||||
segment_spaces = Vec::from_elem(path.segments.len() - 1, None);
|
||||
segment_spaces.push(Some(subst::FnSpace));
|
||||
|
|
|
@ -69,6 +69,9 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||
ast::ItemStatic(..) => {
|
||||
self.check_item_type(item);
|
||||
}
|
||||
ast::ItemConst(..) => {
|
||||
self.check_item_type(item);
|
||||
}
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
self.check_type_defn(item, |fcx| {
|
||||
vec![struct_variant(fcx, &**struct_def)]
|
||||
|
|
|
@ -1550,7 +1550,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
|
|||
_ => {}
|
||||
}
|
||||
match it.node {
|
||||
ast::ItemStatic(ref t, _, _) => {
|
||||
ast::ItemStatic(ref t, _, _) | ast::ItemConst(ref t, _) => {
|
||||
let typ = ccx.to_ty(&ExplicitRscope, &**t);
|
||||
let pty = no_params(typ);
|
||||
|
||||
|
|
|
@ -57,21 +57,21 @@ use middle::typeck::infer::{unresolved_int_ty,unresolved_float_ty,unresolved_ty}
|
|||
use syntax::codemap::Span;
|
||||
use util::ppaux::{Repr, ty_to_string};
|
||||
|
||||
pub static resolve_nested_tvar: uint = 0b0000000001;
|
||||
pub static resolve_rvar: uint = 0b0000000010;
|
||||
pub static resolve_ivar: uint = 0b0000000100;
|
||||
pub static resolve_fvar: uint = 0b0000001000;
|
||||
pub static resolve_all: uint = 0b0000001111;
|
||||
pub static force_tvar: uint = 0b0000100000;
|
||||
pub static force_rvar: uint = 0b0001000000;
|
||||
pub static force_ivar: uint = 0b0010000000;
|
||||
pub static force_fvar: uint = 0b0100000000;
|
||||
pub static force_all: uint = 0b0111100000;
|
||||
pub const resolve_nested_tvar: uint = 0b0000000001;
|
||||
pub const resolve_rvar: uint = 0b0000000010;
|
||||
pub const resolve_ivar: uint = 0b0000000100;
|
||||
pub const resolve_fvar: uint = 0b0000001000;
|
||||
pub const resolve_all: uint = 0b0000001111;
|
||||
pub const force_tvar: uint = 0b0000100000;
|
||||
pub const force_rvar: uint = 0b0001000000;
|
||||
pub const force_ivar: uint = 0b0010000000;
|
||||
pub const force_fvar: uint = 0b0100000000;
|
||||
pub const force_all: uint = 0b0111100000;
|
||||
|
||||
pub static not_regions: uint = !(force_rvar | resolve_rvar);
|
||||
pub const not_regions: uint = !(force_rvar | resolve_rvar);
|
||||
|
||||
pub static try_resolve_tvar_shallow: uint = 0;
|
||||
pub static resolve_and_force_all_but_regions: uint =
|
||||
pub const try_resolve_tvar_shallow: uint = 0;
|
||||
pub const resolve_and_force_all_but_regions: uint =
|
||||
(resolve_all | force_all) & not_regions;
|
||||
|
||||
pub struct ResolveState<'a, 'tcx: 'a> {
|
||||
|
|
|
@ -197,7 +197,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||
}
|
||||
|
||||
return match it.node {
|
||||
ast::ItemStatic(..) | ast::ItemFn(..) |
|
||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
|
||||
ast::ItemForeignMod(..) | ast::ItemTy(..) => {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -384,6 +384,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
|||
|
||||
ast::ItemImpl(..) |
|
||||
ast::ItemStatic(..) |
|
||||
ast::ItemConst(..) |
|
||||
ast::ItemFn(..) |
|
||||
ast::ItemMod(..) |
|
||||
ast::ItemForeignMod(..) |
|
||||
|
@ -528,6 +529,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ast::ItemStatic(..) |
|
||||
ast::ItemConst(..) |
|
||||
ast::ItemFn(..) |
|
||||
ast::ItemMod(..) |
|
||||
ast::ItemForeignMod(..) |
|
||||
|
|
|
@ -10,20 +10,20 @@
|
|||
|
||||
#![allow(non_uppercase_statics)]
|
||||
|
||||
pub static box_field_refcnt: uint = 0u;
|
||||
pub static box_field_drop_glue: uint = 1u;
|
||||
pub static box_field_body: uint = 4u;
|
||||
pub const box_field_refcnt: uint = 0u;
|
||||
pub const box_field_drop_glue: uint = 1u;
|
||||
pub const box_field_body: uint = 4u;
|
||||
|
||||
pub static tydesc_field_visit_glue: uint = 3u;
|
||||
pub const tydesc_field_visit_glue: uint = 3u;
|
||||
|
||||
// The two halves of a closure: code and environment.
|
||||
pub static fn_field_code: uint = 0u;
|
||||
pub static fn_field_box: uint = 1u;
|
||||
pub const fn_field_code: uint = 0u;
|
||||
pub const fn_field_box: uint = 1u;
|
||||
|
||||
// The two fields of a trait object/trait instance: vtable and box.
|
||||
// The vtable contains the type descriptor as first element.
|
||||
pub static trt_field_box: uint = 0u;
|
||||
pub static trt_field_vtable: uint = 1u;
|
||||
pub const trt_field_box: uint = 0u;
|
||||
pub const trt_field_vtable: uint = 1u;
|
||||
|
||||
pub static slice_elt_base: uint = 0u;
|
||||
pub static slice_elt_len: uint = 1u;
|
||||
pub const slice_elt_base: uint = 0u;
|
||||
pub const slice_elt_len: uint = 1u;
|
||||
|
|
|
@ -43,8 +43,8 @@ pub mod diagnostic;
|
|||
pub type Opcode = u32;
|
||||
pub type Bool = c_uint;
|
||||
|
||||
pub static True: Bool = 1 as Bool;
|
||||
pub static False: Bool = 0 as Bool;
|
||||
pub const True: Bool = 1 as Bool;
|
||||
pub const False: Bool = 0 as Bool;
|
||||
|
||||
// Consts for the LLVM CallConv type, pre-cast to uint.
|
||||
|
||||
|
@ -93,32 +93,32 @@ pub enum DiagnosticSeverity {
|
|||
|
||||
bitflags! {
|
||||
flags Attribute : u32 {
|
||||
static ZExtAttribute = 1 << 0,
|
||||
static SExtAttribute = 1 << 1,
|
||||
static NoReturnAttribute = 1 << 2,
|
||||
static InRegAttribute = 1 << 3,
|
||||
static StructRetAttribute = 1 << 4,
|
||||
static NoUnwindAttribute = 1 << 5,
|
||||
static NoAliasAttribute = 1 << 6,
|
||||
static ByValAttribute = 1 << 7,
|
||||
static NestAttribute = 1 << 8,
|
||||
static ReadNoneAttribute = 1 << 9,
|
||||
static ReadOnlyAttribute = 1 << 10,
|
||||
static NoInlineAttribute = 1 << 11,
|
||||
static AlwaysInlineAttribute = 1 << 12,
|
||||
static OptimizeForSizeAttribute = 1 << 13,
|
||||
static StackProtectAttribute = 1 << 14,
|
||||
static StackProtectReqAttribute = 1 << 15,
|
||||
static AlignmentAttribute = 31 << 16,
|
||||
static NoCaptureAttribute = 1 << 21,
|
||||
static NoRedZoneAttribute = 1 << 22,
|
||||
static NoImplicitFloatAttribute = 1 << 23,
|
||||
static NakedAttribute = 1 << 24,
|
||||
static InlineHintAttribute = 1 << 25,
|
||||
static StackAttribute = 7 << 26,
|
||||
static ReturnsTwiceAttribute = 1 << 29,
|
||||
static UWTableAttribute = 1 << 30,
|
||||
static NonLazyBindAttribute = 1 << 31,
|
||||
const ZExtAttribute = 1 << 0,
|
||||
const SExtAttribute = 1 << 1,
|
||||
const NoReturnAttribute = 1 << 2,
|
||||
const InRegAttribute = 1 << 3,
|
||||
const StructRetAttribute = 1 << 4,
|
||||
const NoUnwindAttribute = 1 << 5,
|
||||
const NoAliasAttribute = 1 << 6,
|
||||
const ByValAttribute = 1 << 7,
|
||||
const NestAttribute = 1 << 8,
|
||||
const ReadNoneAttribute = 1 << 9,
|
||||
const ReadOnlyAttribute = 1 << 10,
|
||||
const NoInlineAttribute = 1 << 11,
|
||||
const AlwaysInlineAttribute = 1 << 12,
|
||||
const OptimizeForSizeAttribute = 1 << 13,
|
||||
const StackProtectAttribute = 1 << 14,
|
||||
const StackProtectReqAttribute = 1 << 15,
|
||||
const AlignmentAttribute = 31 << 16,
|
||||
const NoCaptureAttribute = 1 << 21,
|
||||
const NoRedZoneAttribute = 1 << 22,
|
||||
const NoImplicitFloatAttribute = 1 << 23,
|
||||
const NakedAttribute = 1 << 24,
|
||||
const InlineHintAttribute = 1 << 25,
|
||||
const StackAttribute = 7 << 26,
|
||||
const ReturnsTwiceAttribute = 1 << 29,
|
||||
const UWTableAttribute = 1 << 30,
|
||||
const NonLazyBindAttribute = 1 << 31,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -300,6 +300,7 @@ pub enum ItemEnum {
|
|||
ModuleItem(Module),
|
||||
TypedefItem(Typedef),
|
||||
StaticItem(Static),
|
||||
ConstantItem(Constant),
|
||||
TraitItem(Trait),
|
||||
ImplItem(Impl),
|
||||
/// `use` and `extern crate`
|
||||
|
@ -347,6 +348,7 @@ impl Clean<Item> for doctree::Module {
|
|||
self.mods.clean(cx),
|
||||
self.typedefs.clean(cx),
|
||||
self.statics.clean(cx),
|
||||
self.constants.clean(cx),
|
||||
self.traits.clean(cx),
|
||||
self.impls.clean(cx),
|
||||
self.view_items.clean(cx).into_iter()
|
||||
|
@ -1741,6 +1743,29 @@ impl Clean<Item> for doctree::Static {
|
|||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub struct Constant {
|
||||
pub type_: Type,
|
||||
pub expr: String,
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::Constant {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
name: Some(self.name.clean(cx)),
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.whence.clean(cx),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
inner: ConstantItem(Constant {
|
||||
type_: self.type_.clean(cx),
|
||||
expr: self.expr.span.to_src(cx),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Show, Clone, Encodable, Decodable, PartialEq)]
|
||||
pub enum Mutability {
|
||||
Mutable,
|
||||
|
|
|
@ -30,6 +30,7 @@ pub struct Module {
|
|||
pub id: NodeId,
|
||||
pub typedefs: Vec<Typedef>,
|
||||
pub statics: Vec<Static>,
|
||||
pub constants: Vec<Constant>,
|
||||
pub traits: Vec<Trait>,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
|
@ -56,6 +57,7 @@ impl Module {
|
|||
mods : Vec::new(),
|
||||
typedefs : Vec::new(),
|
||||
statics : Vec::new(),
|
||||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
impls : Vec::new(),
|
||||
view_items : Vec::new(),
|
||||
|
@ -151,6 +153,17 @@ pub struct Static {
|
|||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub struct Constant {
|
||||
pub type_: P<ast::Ty>,
|
||||
pub expr: P<ast::Expr>,
|
||||
pub name: Ident,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub vis: ast::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub id: ast::NodeId,
|
||||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub struct Trait {
|
||||
pub name: Ident,
|
||||
pub items: Vec<ast::TraitItem>, //should be TraitItem
|
||||
|
|
|
@ -38,10 +38,10 @@ mod imp {
|
|||
pub l_sysid: libc::c_int,
|
||||
}
|
||||
|
||||
pub static F_WRLCK: libc::c_short = 1;
|
||||
pub static F_UNLCK: libc::c_short = 2;
|
||||
pub static F_SETLK: libc::c_int = 6;
|
||||
pub static F_SETLKW: libc::c_int = 7;
|
||||
pub const F_WRLCK: libc::c_short = 1;
|
||||
pub const F_UNLCK: libc::c_short = 2;
|
||||
pub const F_SETLK: libc::c_int = 6;
|
||||
pub const F_SETLKW: libc::c_int = 7;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
|
@ -57,10 +57,10 @@ mod imp {
|
|||
pub l_sysid: libc::c_int,
|
||||
}
|
||||
|
||||
pub static F_UNLCK: libc::c_short = 2;
|
||||
pub static F_WRLCK: libc::c_short = 3;
|
||||
pub static F_SETLK: libc::c_int = 12;
|
||||
pub static F_SETLKW: libc::c_int = 13;
|
||||
pub const F_UNLCK: libc::c_short = 2;
|
||||
pub const F_WRLCK: libc::c_short = 3;
|
||||
pub const F_SETLK: libc::c_int = 12;
|
||||
pub const F_SETLKW: libc::c_int = 13;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
|
@ -78,10 +78,10 @@ mod imp {
|
|||
pub l_sysid: libc::c_int,
|
||||
}
|
||||
|
||||
pub static F_UNLCK: libc::c_short = 2;
|
||||
pub static F_WRLCK: libc::c_short = 3;
|
||||
pub static F_SETLK: libc::c_int = 8;
|
||||
pub static F_SETLKW: libc::c_int = 9;
|
||||
pub const F_UNLCK: libc::c_short = 2;
|
||||
pub const F_WRLCK: libc::c_short = 3;
|
||||
pub const F_SETLK: libc::c_int = 8;
|
||||
pub const F_SETLKW: libc::c_int = 9;
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
|
@ -99,10 +99,10 @@ mod imp {
|
|||
pub l_sysid: libc::c_int,
|
||||
}
|
||||
|
||||
pub static F_UNLCK: libc::c_short = 2;
|
||||
pub static F_WRLCK: libc::c_short = 3;
|
||||
pub static F_SETLK: libc::c_int = 8;
|
||||
pub static F_SETLKW: libc::c_int = 9;
|
||||
pub const F_UNLCK: libc::c_short = 2;
|
||||
pub const F_WRLCK: libc::c_short = 3;
|
||||
pub const F_SETLK: libc::c_int = 8;
|
||||
pub const F_SETLKW: libc::c_int = 9;
|
||||
}
|
||||
|
||||
pub struct Lock {
|
||||
|
|
|
@ -39,6 +39,7 @@ pub enum ItemType {
|
|||
Macro = 15,
|
||||
Primitive = 16,
|
||||
AssociatedType = 17,
|
||||
Constant = 18,
|
||||
}
|
||||
|
||||
impl ItemType {
|
||||
|
@ -62,6 +63,7 @@ impl ItemType {
|
|||
Macro => "macro",
|
||||
Primitive => "primitive",
|
||||
AssociatedType => "associatedtype",
|
||||
Constant => "constant",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +88,7 @@ pub fn shortty(item: &clean::Item) -> ItemType {
|
|||
clean::FunctionItem(..) => Function,
|
||||
clean::TypedefItem(..) => Typedef,
|
||||
clean::StaticItem(..) => Static,
|
||||
clean::ConstantItem(..) => Constant,
|
||||
clean::TraitItem(..) => Trait,
|
||||
clean::ImplItem(..) => Impl,
|
||||
clean::ViewItemItem(..) => ViewItem,
|
||||
|
|
|
@ -48,16 +48,16 @@ pub struct Markdown<'a>(pub &'a str);
|
|||
/// table of contents.
|
||||
pub struct MarkdownWithToc<'a>(pub &'a str);
|
||||
|
||||
static DEF_OUNIT: libc::size_t = 64;
|
||||
static HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 10;
|
||||
static HOEDOWN_EXT_TABLES: libc::c_uint = 1 << 0;
|
||||
static HOEDOWN_EXT_FENCED_CODE: libc::c_uint = 1 << 1;
|
||||
static HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3;
|
||||
static HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4;
|
||||
static HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8;
|
||||
static HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2;
|
||||
const DEF_OUNIT: libc::size_t = 64;
|
||||
const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 10;
|
||||
const HOEDOWN_EXT_TABLES: libc::c_uint = 1 << 0;
|
||||
const HOEDOWN_EXT_FENCED_CODE: libc::c_uint = 1 << 1;
|
||||
const HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3;
|
||||
const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4;
|
||||
const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8;
|
||||
const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2;
|
||||
|
||||
static HOEDOWN_EXTENSIONS: libc::c_uint =
|
||||
const HOEDOWN_EXTENSIONS: libc::c_uint =
|
||||
HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES |
|
||||
HOEDOWN_EXT_FENCED_CODE | HOEDOWN_EXT_AUTOLINK |
|
||||
HOEDOWN_EXT_STRIKETHROUGH | HOEDOWN_EXT_SUPERSCRIPT |
|
||||
|
|
|
@ -1471,6 +1471,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
(_, &clean::StructItem(..)) => Greater,
|
||||
(&clean::EnumItem(..), _) => Less,
|
||||
(_, &clean::EnumItem(..)) => Greater,
|
||||
(&clean::ConstantItem(..), _) => Less,
|
||||
(_, &clean::ConstantItem(..)) => Greater,
|
||||
(&clean::StaticItem(..), _) => Less,
|
||||
(_, &clean::StaticItem(..)) => Greater,
|
||||
(&clean::ForeignFunctionItem(..), _) => Less,
|
||||
|
@ -1507,6 +1509,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
clean::FunctionItem(..) => ("functions", "Functions"),
|
||||
clean::TypedefItem(..) => ("types", "Type Definitions"),
|
||||
clean::StaticItem(..) => ("statics", "Statics"),
|
||||
clean::ConstantItem(..) => ("constants", "Constants"),
|
||||
clean::TraitItem(..) => ("traits", "Traits"),
|
||||
clean::ImplItem(..) => ("impls", "Implementations"),
|
||||
clean::ViewItemItem(..) => ("reexports", "Reexports"),
|
||||
|
@ -1526,8 +1529,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
id = short, name = name));
|
||||
}
|
||||
|
||||
match myitem.inner {
|
||||
clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => {
|
||||
struct Initializer<'a>(&'a str, Item<'a>);
|
||||
impl<'a> fmt::Show for Initializer<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -1548,6 +1549,8 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
}
|
||||
}
|
||||
|
||||
match myitem.inner {
|
||||
clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => {
|
||||
try!(write!(w, "
|
||||
<tr>
|
||||
<td>{}<code>{}static {}{}: {}</code>{}</td>
|
||||
|
@ -1562,6 +1565,20 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
Initializer(s.expr.as_slice(), Item { cx: cx, item: myitem }),
|
||||
Markdown(blank(myitem.doc_value()))));
|
||||
}
|
||||
clean::ConstantItem(ref s) => {
|
||||
try!(write!(w, "
|
||||
<tr>
|
||||
<td>{}<code>{}const {}: {}</code>{}</td>
|
||||
<td class='docblock'>{} </td>
|
||||
</tr>
|
||||
",
|
||||
ConciseStability(&myitem.stability),
|
||||
VisSpace(myitem.visibility),
|
||||
*myitem.name.get_ref(),
|
||||
s.type_,
|
||||
Initializer(s.expr.as_slice(), Item { cx: cx, item: myitem }),
|
||||
Markdown(blank(myitem.doc_value()))));
|
||||
}
|
||||
|
||||
clean::ViewItemItem(ref item) => {
|
||||
match item.inner {
|
||||
|
|
|
@ -569,7 +569,9 @@
|
|||
"ffi",
|
||||
"ffs",
|
||||
"macro",
|
||||
"primitive"];
|
||||
"primitive",
|
||||
"associatedtype",
|
||||
"constant"];
|
||||
|
||||
function itemTypeFromName(typename) {
|
||||
for (var i = 0; i < itemTypes.length; ++i) {
|
||||
|
|
|
@ -134,7 +134,8 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
|||
clean::StructItem(..) | clean::EnumItem(..) |
|
||||
clean::TraitItem(..) | clean::FunctionItem(..) |
|
||||
clean::VariantItem(..) | clean::MethodItem(..) |
|
||||
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) => {
|
||||
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
|
||||
clean::ConstantItem(..) => {
|
||||
if ast_util::is_local(i.def_id) &&
|
||||
!self.exported_items.contains(&i.def_id.node) {
|
||||
return None;
|
||||
|
|
|
@ -308,6 +308,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
};
|
||||
om.statics.push(s);
|
||||
},
|
||||
ast::ItemConst(ref ty, ref exp) => {
|
||||
let s = Constant {
|
||||
type_: ty.clone(),
|
||||
expr: exp.clone(),
|
||||
id: item.id,
|
||||
name: name,
|
||||
attrs: item.attrs.clone(),
|
||||
whence: item.span,
|
||||
vis: item.vis,
|
||||
stab: self.stability(item.id),
|
||||
};
|
||||
om.constants.push(s);
|
||||
},
|
||||
ast::ItemTrait(ref gen, _, ref b, ref items) => {
|
||||
let t = Trait {
|
||||
name: name,
|
||||
|
|
|
@ -414,7 +414,7 @@ impl ToCStr for String {
|
|||
}
|
||||
|
||||
// The length of the stack allocated buffer for `vec.with_c_str()`
|
||||
static BUF_LEN: uint = 128;
|
||||
const BUF_LEN: uint = 128;
|
||||
|
||||
impl<'a> ToCStr for &'a [u8] {
|
||||
fn to_c_str(&self) -> CString {
|
||||
|
|
|
@ -100,7 +100,7 @@ pub trait Runtime {
|
|||
|
||||
/// The default error code of the rust runtime if the main task fails instead
|
||||
/// of exiting cleanly.
|
||||
pub static DEFAULT_ERROR_CODE: int = 101;
|
||||
pub const DEFAULT_ERROR_CODE: int = 101;
|
||||
|
||||
/// One-time runtime initialization.
|
||||
///
|
||||
|
|
|
@ -57,19 +57,19 @@ pub type _Unwind_Exception_Class = u64;
|
|||
pub type _Unwind_Word = libc::uintptr_t;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub static unwinder_private_data_size: uint = 5;
|
||||
pub const unwinder_private_data_size: uint = 5;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub static unwinder_private_data_size: uint = 6;
|
||||
pub const unwinder_private_data_size: uint = 6;
|
||||
|
||||
#[cfg(all(target_arch = "arm", not(target_os = "ios")))]
|
||||
pub static unwinder_private_data_size: uint = 20;
|
||||
pub const unwinder_private_data_size: uint = 20;
|
||||
|
||||
#[cfg(all(target_arch = "arm", target_os = "ios"))]
|
||||
pub static unwinder_private_data_size: uint = 5;
|
||||
pub const unwinder_private_data_size: uint = 5;
|
||||
|
||||
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
|
||||
pub static unwinder_private_data_size: uint = 2;
|
||||
pub const unwinder_private_data_size: uint = 2;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _Unwind_Exception {
|
||||
|
|
|
@ -88,7 +88,7 @@ pub struct LockGuard<'a> {
|
|||
lock: &'a StaticNativeMutex
|
||||
}
|
||||
|
||||
pub static NATIVE_MUTEX_INIT: StaticNativeMutex = StaticNativeMutex {
|
||||
pub const NATIVE_MUTEX_INIT: StaticNativeMutex = StaticNativeMutex {
|
||||
inner: imp::MUTEX_INIT,
|
||||
};
|
||||
|
||||
|
@ -353,9 +353,9 @@ mod imp {
|
|||
pub type pthread_mutex_t = *mut libc::c_void;
|
||||
pub type pthread_cond_t = *mut libc::c_void;
|
||||
|
||||
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t =
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t =
|
||||
0 as pthread_mutex_t;
|
||||
pub static PTHREAD_COND_INITIALIZER: pthread_cond_t =
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t =
|
||||
0 as pthread_cond_t;
|
||||
}
|
||||
|
||||
|
@ -364,20 +364,20 @@ mod imp {
|
|||
use libc;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static __PTHREAD_MUTEX_SIZE__: uint = 56;
|
||||
const __PTHREAD_MUTEX_SIZE__: uint = 56;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static __PTHREAD_COND_SIZE__: uint = 40;
|
||||
const __PTHREAD_COND_SIZE__: uint = 40;
|
||||
#[cfg(target_arch = "x86")]
|
||||
static __PTHREAD_MUTEX_SIZE__: uint = 40;
|
||||
const __PTHREAD_MUTEX_SIZE__: uint = 40;
|
||||
#[cfg(target_arch = "x86")]
|
||||
static __PTHREAD_COND_SIZE__: uint = 24;
|
||||
const __PTHREAD_COND_SIZE__: uint = 24;
|
||||
#[cfg(target_arch = "arm")]
|
||||
static __PTHREAD_MUTEX_SIZE__: uint = 40;
|
||||
const __PTHREAD_MUTEX_SIZE__: uint = 40;
|
||||
#[cfg(target_arch = "arm")]
|
||||
static __PTHREAD_COND_SIZE__: uint = 24;
|
||||
const __PTHREAD_COND_SIZE__: uint = 24;
|
||||
|
||||
static _PTHREAD_MUTEX_SIG_INIT: libc::c_long = 0x32AAABA7;
|
||||
static _PTHREAD_COND_SIG_INIT: libc::c_long = 0x3CB0B1BB;
|
||||
const _PTHREAD_MUTEX_SIG_INIT: libc::c_long = 0x32AAABA7;
|
||||
const _PTHREAD_COND_SIG_INIT: libc::c_long = 0x3CB0B1BB;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
|
@ -390,11 +390,11 @@ mod imp {
|
|||
__opaque: [u8, ..__PTHREAD_COND_SIZE__],
|
||||
}
|
||||
|
||||
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
__sig: _PTHREAD_MUTEX_SIG_INIT,
|
||||
__opaque: [0, ..__PTHREAD_MUTEX_SIZE__],
|
||||
};
|
||||
pub static PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
__sig: _PTHREAD_COND_SIG_INIT,
|
||||
__opaque: [0, ..__PTHREAD_COND_SIZE__],
|
||||
};
|
||||
|
@ -406,25 +406,25 @@ mod imp {
|
|||
|
||||
// minus 8 because we have an 'align' field
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static __SIZEOF_PTHREAD_MUTEX_T: uint = 40 - 8;
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 40 - 8;
|
||||
#[cfg(target_arch = "x86")]
|
||||
static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
#[cfg(target_arch = "arm")]
|
||||
static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
#[cfg(target_arch = "mips")]
|
||||
static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
#[cfg(target_arch = "x86")]
|
||||
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
#[cfg(target_arch = "arm")]
|
||||
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
#[cfg(target_arch = "mips")]
|
||||
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
|
@ -437,11 +437,11 @@ mod imp {
|
|||
size: [u8, ..__SIZEOF_PTHREAD_COND_T],
|
||||
}
|
||||
|
||||
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
__align: 0,
|
||||
size: [0, ..__SIZEOF_PTHREAD_MUTEX_T],
|
||||
};
|
||||
pub static PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
__align: 0,
|
||||
size: [0, ..__SIZEOF_PTHREAD_COND_T],
|
||||
};
|
||||
|
@ -455,10 +455,10 @@ mod imp {
|
|||
#[repr(C)]
|
||||
pub struct pthread_cond_t { value: libc::c_int }
|
||||
|
||||
pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
value: 0,
|
||||
};
|
||||
pub static PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
value: 0,
|
||||
};
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ mod imp {
|
|||
cond: UnsafeCell<pthread_cond_t>,
|
||||
}
|
||||
|
||||
pub static MUTEX_INIT: Mutex = Mutex {
|
||||
pub const MUTEX_INIT: Mutex = Mutex {
|
||||
lock: UnsafeCell { value: PTHREAD_MUTEX_INITIALIZER },
|
||||
cond: UnsafeCell { value: PTHREAD_COND_INITIALIZER },
|
||||
};
|
||||
|
@ -523,11 +523,11 @@ mod imp {
|
|||
use libc;
|
||||
|
||||
type LPCRITICAL_SECTION = *mut c_void;
|
||||
static SPIN_COUNT: DWORD = 4000;
|
||||
const SPIN_COUNT: DWORD = 4000;
|
||||
#[cfg(target_arch = "x86")]
|
||||
static CRIT_SECTION_SIZE: uint = 24;
|
||||
const CRIT_SECTION_SIZE: uint = 24;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static CRIT_SECTION_SIZE: uint = 40;
|
||||
const CRIT_SECTION_SIZE: uint = 40;
|
||||
|
||||
pub struct Mutex {
|
||||
// pointers for the lock/cond handles, atomically updated
|
||||
|
@ -535,7 +535,7 @@ mod imp {
|
|||
cond: atomic::AtomicUint,
|
||||
}
|
||||
|
||||
pub static MUTEX_INIT: Mutex = Mutex {
|
||||
pub const MUTEX_INIT: Mutex = Mutex {
|
||||
lock: atomic::INIT_ATOMIC_UINT,
|
||||
cond: atomic::INIT_ATOMIC_UINT,
|
||||
};
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
// corresponding prolog, decision was taken to disable segmented
|
||||
// stack support on iOS.
|
||||
|
||||
pub static RED_ZONE: uint = 20 * 1024;
|
||||
pub const RED_ZONE: uint = 20 * 1024;
|
||||
|
||||
/// This function is invoked from rust's current __morestack function. Segmented
|
||||
/// stacks are currently not enabled as segmented stacks, but rather one giant
|
||||
|
|
|
@ -91,7 +91,7 @@ pub type Callback = fn(msg: &Any + Send, file: &'static str, line: uint);
|
|||
// Variables used for invoking callbacks when a task starts to unwind.
|
||||
//
|
||||
// For more information, see below.
|
||||
static MAX_CALLBACKS: uint = 16;
|
||||
const MAX_CALLBACKS: uint = 16;
|
||||
static mut CALLBACKS: [atomic::AtomicUint, ..MAX_CALLBACKS] =
|
||||
[atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
|
||||
atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT,
|
||||
|
|
|
@ -23,15 +23,15 @@ use libc;
|
|||
//
|
||||
// FIXME: Once the runtime matures remove the `true` below to turn off rtassert,
|
||||
// etc.
|
||||
pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
|
||||
pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
|
||||
cfg!(rtassert);
|
||||
|
||||
pub struct Stdio(libc::c_int);
|
||||
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
|
||||
pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
|
||||
#[allow(non_uppercase_statics)]
|
||||
pub static Stderr: Stdio = Stdio(libc::STDERR_FILENO);
|
||||
pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);
|
||||
|
||||
impl fmt::FormatWriter for Stdio {
|
||||
fn write(&mut self, data: &[u8]) -> fmt::Result {
|
||||
|
|
|
@ -360,18 +360,16 @@ fn escape_char(writer: &mut io::Writer, v: char) -> Result<(), io::IoError> {
|
|||
}
|
||||
|
||||
fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
|
||||
#[allow(non_uppercase_statics)]
|
||||
static len: uint = 16;
|
||||
#[allow(non_uppercase_statics)]
|
||||
static buf: [u8, ..len] = [b' ', ..len];
|
||||
const LEN: uint = 16;
|
||||
static BUF: [u8, ..LEN] = [b' ', ..LEN];
|
||||
|
||||
while n >= len {
|
||||
try!(wr.write(buf));
|
||||
n -= len;
|
||||
while n >= LEN {
|
||||
try!(wr.write(BUF));
|
||||
n -= LEN;
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
wr.write(buf[..n])
|
||||
wr.write(BUF[..n])
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
/// ```{.rust}
|
||||
/// bitflags! {
|
||||
/// flags Flags: u32 {
|
||||
/// static FLAG_A = 0x00000001,
|
||||
/// static FLAG_B = 0x00000010,
|
||||
/// static FLAG_C = 0x00000100,
|
||||
/// static FLAG_ABC = FLAG_A.bits
|
||||
/// const FLAG_A = 0x00000001,
|
||||
/// const FLAG_B = 0x00000010,
|
||||
/// const FLAG_C = 0x00000100,
|
||||
/// const FLAG_ABC = FLAG_A.bits
|
||||
/// | FLAG_B.bits
|
||||
/// | FLAG_C.bits,
|
||||
/// }
|
||||
|
@ -50,8 +50,8 @@
|
|||
///
|
||||
/// bitflags! {
|
||||
/// flags Flags: u32 {
|
||||
/// static FLAG_A = 0x00000001,
|
||||
/// static FLAG_B = 0x00000010,
|
||||
/// const FLAG_A = 0x00000001,
|
||||
/// const FLAG_B = 0x00000010,
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
|
@ -115,7 +115,7 @@
|
|||
#[macro_export]
|
||||
macro_rules! bitflags {
|
||||
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
|
||||
$($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
|
||||
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+
|
||||
}) => {
|
||||
#[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
|
||||
$(#[$attr])*
|
||||
|
@ -123,7 +123,7 @@ macro_rules! bitflags {
|
|||
bits: $T,
|
||||
}
|
||||
|
||||
$($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+
|
||||
$($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
|
||||
|
||||
impl $BitFlags {
|
||||
/// Returns an empty set of flags.
|
||||
|
@ -235,12 +235,12 @@ macro_rules! bitflags {
|
|||
}
|
||||
};
|
||||
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
|
||||
$($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
|
||||
$($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+,
|
||||
}) => {
|
||||
bitflags! {
|
||||
$(#[$attr])*
|
||||
flags $BitFlags: $T {
|
||||
$($(#[$Flag_attr])* static $Flag = $value),+
|
||||
$($(#[$Flag_attr])* const $Flag = $value),+
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -259,14 +259,14 @@ mod tests {
|
|||
#[doc = "> "]
|
||||
#[doc = "> - Richard Feynman"]
|
||||
flags Flags: u32 {
|
||||
static FlagA = 0x00000001,
|
||||
const FlagA = 0x00000001,
|
||||
#[doc = "<pcwalton> macros are way better at generating code than trans is"]
|
||||
static FlagB = 0x00000010,
|
||||
static FlagC = 0x00000100,
|
||||
const FlagB = 0x00000010,
|
||||
const FlagC = 0x00000100,
|
||||
#[doc = "* cmr bed"]
|
||||
#[doc = "* strcat table"]
|
||||
#[doc = "<strcat> wait what?"]
|
||||
static FlagABC = FlagA.bits
|
||||
const FlagABC = FlagA.bits
|
||||
| FlagB.bits
|
||||
| FlagC.bits,
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ mod tests {
|
|||
|
||||
bitflags! {
|
||||
flags AnotherSetOfFlags: uint {
|
||||
static AnotherFlag = 1u,
|
||||
const AnotherFlag = 1u,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ use super::table::{
|
|||
SafeHash
|
||||
};
|
||||
|
||||
static INITIAL_LOG2_CAP: uint = 5;
|
||||
pub static INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
|
||||
const INITIAL_LOG2_CAP: uint = 5;
|
||||
pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
|
||||
|
||||
/// The default behavior of HashMap implements a load factor of 90.9%.
|
||||
/// This behavior is characterized by the following conditions:
|
||||
|
|
|
@ -24,7 +24,7 @@ use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory};
|
|||
use ptr;
|
||||
use rt::heap::{allocate, deallocate};
|
||||
|
||||
static EMPTY_BUCKET: u64 = 0u64;
|
||||
const EMPTY_BUCKET: u64 = 0u64;
|
||||
|
||||
/// The raw hashtable, providing safe-ish access to the unzipped and highly
|
||||
/// optimized arrays of hashes, keys, and values.
|
||||
|
|
|
@ -283,7 +283,7 @@ pub mod util;
|
|||
/// The default buffer size for various I/O operations
|
||||
// libuv recommends 64k buffers to maximize throughput
|
||||
// https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
|
||||
static DEFAULT_BUF_SIZE: uint = 1024 * 64;
|
||||
const DEFAULT_BUF_SIZE: uint = 1024 * 64;
|
||||
|
||||
/// A convenient typedef of the return value of any I/O action.
|
||||
pub type IoResult<T> = Result<T, IoError>;
|
||||
|
@ -1803,93 +1803,93 @@ bitflags! {
|
|||
#[doc = "A set of permissions for a file or directory is represented"]
|
||||
#[doc = "by a set of flags which are or'd together."]
|
||||
flags FilePermission: u32 {
|
||||
static USER_READ = 0o400,
|
||||
static USER_WRITE = 0o200,
|
||||
static USER_EXECUTE = 0o100,
|
||||
static GROUP_READ = 0o040,
|
||||
static GROUP_WRITE = 0o020,
|
||||
static GROUP_EXECUTE = 0o010,
|
||||
static OTHER_READ = 0o004,
|
||||
static OTHER_WRITE = 0o002,
|
||||
static OTHER_EXECUTE = 0o001,
|
||||
const USER_READ = 0o400,
|
||||
const USER_WRITE = 0o200,
|
||||
const USER_EXECUTE = 0o100,
|
||||
const GROUP_READ = 0o040,
|
||||
const GROUP_WRITE = 0o020,
|
||||
const GROUP_EXECUTE = 0o010,
|
||||
const OTHER_READ = 0o004,
|
||||
const OTHER_WRITE = 0o002,
|
||||
const OTHER_EXECUTE = 0o001,
|
||||
|
||||
static USER_RWX = USER_READ.bits | USER_WRITE.bits | USER_EXECUTE.bits,
|
||||
static GROUP_RWX = GROUP_READ.bits | GROUP_WRITE.bits | GROUP_EXECUTE.bits,
|
||||
static OTHER_RWX = OTHER_READ.bits | OTHER_WRITE.bits | OTHER_EXECUTE.bits,
|
||||
const USER_RWX = USER_READ.bits | USER_WRITE.bits | USER_EXECUTE.bits,
|
||||
const GROUP_RWX = GROUP_READ.bits | GROUP_WRITE.bits | GROUP_EXECUTE.bits,
|
||||
const OTHER_RWX = OTHER_READ.bits | OTHER_WRITE.bits | OTHER_EXECUTE.bits,
|
||||
|
||||
#[doc = "Permissions for user owned files, equivalent to 0644 on"]
|
||||
#[doc = "unix-like systems."]
|
||||
static USER_FILE = USER_READ.bits | USER_WRITE.bits | GROUP_READ.bits | OTHER_READ.bits,
|
||||
const USER_FILE = USER_READ.bits | USER_WRITE.bits | GROUP_READ.bits | OTHER_READ.bits,
|
||||
|
||||
#[doc = "Permissions for user owned directories, equivalent to 0755 on"]
|
||||
#[doc = "unix-like systems."]
|
||||
static USER_DIR = USER_RWX.bits | GROUP_READ.bits | GROUP_EXECUTE.bits |
|
||||
const USER_DIR = USER_RWX.bits | GROUP_READ.bits | GROUP_EXECUTE.bits |
|
||||
OTHER_READ.bits | OTHER_EXECUTE.bits,
|
||||
|
||||
#[doc = "Permissions for user owned executables, equivalent to 0755"]
|
||||
#[doc = "on unix-like systems."]
|
||||
static USER_EXEC = USER_DIR.bits,
|
||||
const USER_EXEC = USER_DIR.bits,
|
||||
|
||||
#[doc = "All possible permissions enabled."]
|
||||
static ALL_PERMISSIONS = USER_RWX.bits | GROUP_RWX.bits | OTHER_RWX.bits,
|
||||
const ALL_PERMISSIONS = USER_RWX.bits | GROUP_RWX.bits | OTHER_RWX.bits,
|
||||
|
||||
// Deprecated names
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_READ instead"]
|
||||
static UserRead = USER_READ.bits,
|
||||
const UserRead = USER_READ.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_WRITE instead"]
|
||||
static UserWrite = USER_WRITE.bits,
|
||||
const UserWrite = USER_WRITE.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_EXECUTE instead"]
|
||||
static UserExecute = USER_EXECUTE.bits,
|
||||
const UserExecute = USER_EXECUTE.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use GROUP_READ instead"]
|
||||
static GroupRead = GROUP_READ.bits,
|
||||
const GroupRead = GROUP_READ.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use GROUP_WRITE instead"]
|
||||
static GroupWrite = GROUP_WRITE.bits,
|
||||
const GroupWrite = GROUP_WRITE.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use GROUP_EXECUTE instead"]
|
||||
static GroupExecute = GROUP_EXECUTE.bits,
|
||||
const GroupExecute = GROUP_EXECUTE.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use OTHER_READ instead"]
|
||||
static OtherRead = OTHER_READ.bits,
|
||||
const OtherRead = OTHER_READ.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use OTHER_WRITE instead"]
|
||||
static OtherWrite = OTHER_WRITE.bits,
|
||||
const OtherWrite = OTHER_WRITE.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use OTHER_EXECUTE instead"]
|
||||
static OtherExecute = OTHER_EXECUTE.bits,
|
||||
const OtherExecute = OTHER_EXECUTE.bits,
|
||||
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_RWX instead"]
|
||||
static UserRWX = USER_RWX.bits,
|
||||
const UserRWX = USER_RWX.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use GROUP_RWX instead"]
|
||||
static GroupRWX = GROUP_RWX.bits,
|
||||
const GroupRWX = GROUP_RWX.bits,
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use OTHER_RWX instead"]
|
||||
static OtherRWX = OTHER_RWX.bits,
|
||||
const OtherRWX = OTHER_RWX.bits,
|
||||
|
||||
#[doc = "Deprecated: use `USER_FILE` instead."]
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_FILE instead"]
|
||||
static UserFile = USER_FILE.bits,
|
||||
const UserFile = USER_FILE.bits,
|
||||
|
||||
#[doc = "Deprecated: use `USER_DIR` instead."]
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_DIR instead"]
|
||||
static UserDir = USER_DIR.bits,
|
||||
const UserDir = USER_DIR.bits,
|
||||
#[doc = "Deprecated: use `USER_EXEC` instead."]
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use USER_EXEC instead"]
|
||||
static UserExec = USER_EXEC.bits,
|
||||
const UserExec = USER_EXEC.bits,
|
||||
|
||||
#[doc = "Deprecated: use `ALL_PERMISSIONS` instead"]
|
||||
#[allow(non_uppercase_statics)]
|
||||
#[deprecated = "use ALL_PERMISSIONS instead"]
|
||||
static AllPermissions = ALL_PERMISSIONS.bits,
|
||||
const AllPermissions = ALL_PERMISSIONS.bits,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,16 +32,16 @@ use std::hash::sip::SipState;
|
|||
|
||||
/// Signal a process to exit, without forcibly killing it. Corresponds to
|
||||
/// SIGTERM on unix platforms.
|
||||
#[cfg(windows)] pub static PleaseExitSignal: int = 15;
|
||||
#[cfg(windows)] pub const PleaseExitSignal: int = 15;
|
||||
/// Signal a process to exit immediately, forcibly killing it. Corresponds to
|
||||
/// SIGKILL on unix platforms.
|
||||
#[cfg(windows)] pub static MustDieSignal: int = 9;
|
||||
#[cfg(windows)] pub const MustDieSignal: int = 9;
|
||||
/// Signal a process to exit, without forcibly killing it. Corresponds to
|
||||
/// SIGTERM on unix platforms.
|
||||
#[cfg(not(windows))] pub static PleaseExitSignal: int = libc::SIGTERM as int;
|
||||
#[cfg(not(windows))] pub const PleaseExitSignal: int = libc::SIGTERM as int;
|
||||
/// Signal a process to exit immediately, forcibly killing it. Corresponds to
|
||||
/// SIGKILL on unix platforms.
|
||||
#[cfg(not(windows))] pub static MustDieSignal: int = libc::SIGKILL as int;
|
||||
#[cfg(not(windows))] pub const MustDieSignal: int = libc::SIGKILL as int;
|
||||
|
||||
/// Representation of a running or exited child process.
|
||||
///
|
||||
|
|
106
src/libstd/os.rs
106
src/libstd/os.rs
|
@ -66,8 +66,8 @@ pub fn num_cpus() -> uint {
|
|||
}
|
||||
}
|
||||
|
||||
pub static TMPBUF_SZ : uint = 1000u;
|
||||
static BUF_BYTES : uint = 2048u;
|
||||
pub const TMPBUF_SZ : uint = 1000u;
|
||||
const BUF_BYTES : uint = 2048u;
|
||||
|
||||
/// Returns the current working directory as a Path.
|
||||
///
|
||||
|
@ -1672,230 +1672,230 @@ impl MemoryMap {
|
|||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
pub const FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `linux`.
|
||||
pub static SYSNAME: &'static str = "linux";
|
||||
pub const SYSNAME: &'static str = "linux";
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, `lib`.
|
||||
pub static DLL_PREFIX: &'static str = "lib";
|
||||
pub const DLL_PREFIX: &'static str = "lib";
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.so`.
|
||||
pub static DLL_SUFFIX: &'static str = ".so";
|
||||
pub const DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
/// Specifies the file extension used for shared libraries on this
|
||||
/// platform that goes after the dot: in this case, `so`.
|
||||
pub static DLL_EXTENSION: &'static str = "so";
|
||||
pub const DLL_EXTENSION: &'static str = "so";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
pub const EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
pub const EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
pub const FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `macos`.
|
||||
pub static SYSNAME: &'static str = "macos";
|
||||
pub const SYSNAME: &'static str = "macos";
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, `lib`.
|
||||
pub static DLL_PREFIX: &'static str = "lib";
|
||||
pub const DLL_PREFIX: &'static str = "lib";
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.dylib`.
|
||||
pub static DLL_SUFFIX: &'static str = ".dylib";
|
||||
pub const DLL_SUFFIX: &'static str = ".dylib";
|
||||
|
||||
/// Specifies the file extension used for shared libraries on this
|
||||
/// platform that goes after the dot: in this case, `dylib`.
|
||||
pub static DLL_EXTENSION: &'static str = "dylib";
|
||||
pub const DLL_EXTENSION: &'static str = "dylib";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
pub const EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
pub const EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
pub const FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `ios`.
|
||||
pub static SYSNAME: &'static str = "ios";
|
||||
pub const SYSNAME: &'static str = "ios";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
pub const EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
pub const EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
pub const FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `freebsd`.
|
||||
pub static SYSNAME: &'static str = "freebsd";
|
||||
pub const SYSNAME: &'static str = "freebsd";
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, `lib`.
|
||||
pub static DLL_PREFIX: &'static str = "lib";
|
||||
pub const DLL_PREFIX: &'static str = "lib";
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.so`.
|
||||
pub static DLL_SUFFIX: &'static str = ".so";
|
||||
pub const DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
/// Specifies the file extension used for shared libraries on this
|
||||
/// platform that goes after the dot: in this case, `so`.
|
||||
pub static DLL_EXTENSION: &'static str = "so";
|
||||
pub const DLL_EXTENSION: &'static str = "so";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
pub const EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
pub const EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
pub const FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `dragonfly`.
|
||||
pub static SYSNAME: &'static str = "dragonfly";
|
||||
pub const SYSNAME: &'static str = "dragonfly";
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, `lib`.
|
||||
pub static DLL_PREFIX: &'static str = "lib";
|
||||
pub const DLL_PREFIX: &'static str = "lib";
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.so`.
|
||||
pub static DLL_SUFFIX: &'static str = ".so";
|
||||
pub const DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
/// Specifies the file extension used for shared libraries on this
|
||||
/// platform that goes after the dot: in this case, `so`.
|
||||
pub static DLL_EXTENSION: &'static str = "so";
|
||||
pub const DLL_EXTENSION: &'static str = "so";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
pub const EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
pub const EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "unix";
|
||||
pub const FAMILY: &'static str = "unix";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `android`.
|
||||
pub static SYSNAME: &'static str = "android";
|
||||
pub const SYSNAME: &'static str = "android";
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, `lib`.
|
||||
pub static DLL_PREFIX: &'static str = "lib";
|
||||
pub const DLL_PREFIX: &'static str = "lib";
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.so`.
|
||||
pub static DLL_SUFFIX: &'static str = ".so";
|
||||
pub const DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
/// Specifies the file extension used for shared libraries on this
|
||||
/// platform that goes after the dot: in this case, `so`.
|
||||
pub static DLL_EXTENSION: &'static str = "so";
|
||||
pub const DLL_EXTENSION: &'static str = "so";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static EXE_SUFFIX: &'static str = "";
|
||||
pub const EXE_SUFFIX: &'static str = "";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, the empty string.
|
||||
pub static EXE_EXTENSION: &'static str = "";
|
||||
pub const EXE_EXTENSION: &'static str = "";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub mod consts {
|
||||
pub use os::arch_consts::ARCH;
|
||||
|
||||
pub static FAMILY: &'static str = "windows";
|
||||
pub const FAMILY: &'static str = "windows";
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `windows`.
|
||||
pub static SYSNAME: &'static str = "windows";
|
||||
pub const SYSNAME: &'static str = "windows";
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, the empty string.
|
||||
pub static DLL_PREFIX: &'static str = "";
|
||||
pub const DLL_PREFIX: &'static str = "";
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.dll`.
|
||||
pub static DLL_SUFFIX: &'static str = ".dll";
|
||||
pub const DLL_SUFFIX: &'static str = ".dll";
|
||||
|
||||
/// Specifies the file extension used for shared libraries on this
|
||||
/// platform that goes after the dot: in this case, `dll`.
|
||||
pub static DLL_EXTENSION: &'static str = "dll";
|
||||
pub const DLL_EXTENSION: &'static str = "dll";
|
||||
|
||||
/// Specifies the filename suffix used for executable binaries on this
|
||||
/// platform: in this case, `.exe`.
|
||||
pub static EXE_SUFFIX: &'static str = ".exe";
|
||||
pub const EXE_SUFFIX: &'static str = ".exe";
|
||||
|
||||
/// Specifies the file extension, if any, used for executable binaries
|
||||
/// on this platform: in this case, `exe`.
|
||||
pub static EXE_EXTENSION: &'static str = "exe";
|
||||
pub const EXE_EXTENSION: &'static str = "exe";
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
mod arch_consts {
|
||||
pub static ARCH: &'static str = "x86";
|
||||
pub const ARCH: &'static str = "x86";
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod arch_consts {
|
||||
pub static ARCH: &'static str = "x86_64";
|
||||
pub const ARCH: &'static str = "x86_64";
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
mod arch_consts {
|
||||
pub static ARCH: &'static str = "arm";
|
||||
pub const ARCH: &'static str = "arm";
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
mod arch_consts {
|
||||
pub static ARCH: &'static str = "mips";
|
||||
pub const ARCH: &'static str = "mips";
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "mipsel")]
|
||||
mod arch_consts {
|
||||
pub static ARCH: &'static str = "mipsel";
|
||||
pub const ARCH: &'static str = "mipsel";
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -42,10 +42,10 @@ pub struct Path {
|
|||
}
|
||||
|
||||
/// The standard path separator character
|
||||
pub static SEP: char = '/';
|
||||
pub const SEP: char = '/';
|
||||
|
||||
/// The standard path separator byte
|
||||
pub static SEP_BYTE: u8 = SEP as u8;
|
||||
pub const SEP_BYTE: u8 = SEP as u8;
|
||||
|
||||
/// Returns whether the given byte is a path separator
|
||||
#[inline]
|
||||
|
|
|
@ -958,14 +958,14 @@ pub fn make_non_verbatim(path: &Path) -> Option<Path> {
|
|||
}
|
||||
|
||||
/// The standard path separator character
|
||||
pub static SEP: char = '\\';
|
||||
pub const SEP: char = '\\';
|
||||
/// The standard path separator byte
|
||||
pub static SEP_BYTE: u8 = SEP as u8;
|
||||
pub const SEP_BYTE: u8 = SEP as u8;
|
||||
|
||||
/// The alternative path separator character
|
||||
pub static SEP2: char = '/';
|
||||
pub const SEP2: char = '/';
|
||||
/// The alternative path separator character
|
||||
pub static SEP2_BYTE: u8 = SEP2 as u8;
|
||||
pub const SEP2_BYTE: u8 = SEP2 as u8;
|
||||
|
||||
/// Returns whether the given char is a path separator.
|
||||
/// Allows both the primary separator '\' and the alternative separator '/'.
|
||||
|
|
|
@ -45,8 +45,8 @@ pub fn log_enabled() -> bool {
|
|||
val == 2
|
||||
}
|
||||
|
||||
#[cfg(target_word_size = "64")] static HEX_WIDTH: uint = 18;
|
||||
#[cfg(target_word_size = "32")] static HEX_WIDTH: uint = 10;
|
||||
#[cfg(target_word_size = "64")] const HEX_WIDTH: uint = 18;
|
||||
#[cfg(target_word_size = "32")] const HEX_WIDTH: uint = 10;
|
||||
|
||||
// All rust symbols are in theory lists of "::"-separated identifiers. Some
|
||||
// assemblers, however, can't handle these characters in symbol names. To get
|
||||
|
@ -273,7 +273,7 @@ mod imp {
|
|||
|
||||
try!(writeln!(w, "stack backtrace:"));
|
||||
// 100 lines should be enough
|
||||
static SIZE: uint = 100;
|
||||
const SIZE: uint = 100;
|
||||
let mut buf: [*mut libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
|
||||
let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as uint};
|
||||
|
||||
|
@ -697,10 +697,10 @@ mod imp {
|
|||
*mut libc::c_void, *mut libc::c_void,
|
||||
*mut libc::c_void, *mut libc::c_void) -> libc::BOOL;
|
||||
|
||||
static MAX_SYM_NAME: uint = 2000;
|
||||
static IMAGE_FILE_MACHINE_I386: libc::DWORD = 0x014c;
|
||||
static IMAGE_FILE_MACHINE_IA64: libc::DWORD = 0x0200;
|
||||
static IMAGE_FILE_MACHINE_AMD64: libc::DWORD = 0x8664;
|
||||
const MAX_SYM_NAME: uint = 2000;
|
||||
const IMAGE_FILE_MACHINE_I386: libc::DWORD = 0x014c;
|
||||
const IMAGE_FILE_MACHINE_IA64: libc::DWORD = 0x0200;
|
||||
const IMAGE_FILE_MACHINE_AMD64: libc::DWORD = 0x8664;
|
||||
|
||||
#[repr(C)]
|
||||
struct SYMBOL_INFO {
|
||||
|
@ -772,7 +772,7 @@ mod imp {
|
|||
mod arch {
|
||||
use libc;
|
||||
|
||||
static MAXIMUM_SUPPORTED_EXTENSION: uint = 512;
|
||||
const MAXIMUM_SUPPORTED_EXTENSION: uint = 512;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CONTEXT {
|
||||
|
|
|
@ -20,23 +20,23 @@ use num::{CheckedAdd, CheckedMul};
|
|||
use result::{Result, Ok, Err};
|
||||
|
||||
/// The number of nanoseconds in a microsecond.
|
||||
static NANOS_PER_MICRO: i32 = 1000;
|
||||
const NANOS_PER_MICRO: i32 = 1000;
|
||||
/// The number of nanoseconds in a millisecond.
|
||||
static NANOS_PER_MILLI: i32 = 1000_000;
|
||||
const NANOS_PER_MILLI: i32 = 1000_000;
|
||||
/// The number of nanoseconds in seconds.
|
||||
static NANOS_PER_SEC: i32 = 1_000_000_000;
|
||||
const NANOS_PER_SEC: i32 = 1_000_000_000;
|
||||
/// The number of microseconds per second.
|
||||
static MICROS_PER_SEC: i64 = 1000_000;
|
||||
const MICROS_PER_SEC: i64 = 1000_000;
|
||||
/// The number of milliseconds per second.
|
||||
static MILLIS_PER_SEC: i64 = 1000;
|
||||
const MILLIS_PER_SEC: i64 = 1000;
|
||||
/// The number of seconds in a minute.
|
||||
static SECS_PER_MINUTE: i64 = 60;
|
||||
const SECS_PER_MINUTE: i64 = 60;
|
||||
/// The number of seconds in an hour.
|
||||
static SECS_PER_HOUR: i64 = 3600;
|
||||
const SECS_PER_HOUR: i64 = 3600;
|
||||
/// The number of (non-leap) seconds in days.
|
||||
static SECS_PER_DAY: i64 = 86400;
|
||||
const SECS_PER_DAY: i64 = 86400;
|
||||
/// The number of (non-leap) seconds in a week.
|
||||
static SECS_PER_WEEK: i64 = 604800;
|
||||
const SECS_PER_WEEK: i64 = 604800;
|
||||
|
||||
macro_rules! try_opt(
|
||||
($e:expr) => (match $e { Some(v) => v, None => return None })
|
||||
|
@ -52,13 +52,13 @@ pub struct Duration {
|
|||
}
|
||||
|
||||
/// The minimum possible `Duration`: `i64::MIN` milliseconds.
|
||||
pub static MIN: Duration = Duration {
|
||||
pub const MIN: Duration = Duration {
|
||||
secs: i64::MIN / MILLIS_PER_SEC - 1,
|
||||
nanos: NANOS_PER_SEC + (i64::MIN % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI
|
||||
};
|
||||
|
||||
/// The maximum possible `Duration`: `i64::MAX` milliseconds.
|
||||
pub static MAX: Duration = Duration {
|
||||
pub const MAX: Duration = Duration {
|
||||
secs: i64::MAX / MILLIS_PER_SEC,
|
||||
nanos: (i64::MAX % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI
|
||||
};
|
||||
|
@ -456,7 +456,7 @@ mod tests {
|
|||
assert_eq!(MIN.num_microseconds(), None);
|
||||
|
||||
// overflow checks
|
||||
static MICROS_PER_DAY: i64 = 86400_000_000;
|
||||
const MICROS_PER_DAY: i64 = 86400_000_000;
|
||||
assert_eq!(Duration::days(i64::MAX / MICROS_PER_DAY).num_microseconds(),
|
||||
Some(i64::MAX / MICROS_PER_DAY * MICROS_PER_DAY));
|
||||
assert_eq!(Duration::days(i64::MIN / MICROS_PER_DAY).num_microseconds(),
|
||||
|
@ -477,7 +477,7 @@ mod tests {
|
|||
assert_eq!(MIN.num_nanoseconds(), None);
|
||||
|
||||
// overflow checks
|
||||
static NANOS_PER_DAY: i64 = 86400_000_000_000;
|
||||
const NANOS_PER_DAY: i64 = 86400_000_000_000;
|
||||
assert_eq!(Duration::days(i64::MAX / NANOS_PER_DAY).num_nanoseconds(),
|
||||
Some(i64::MAX / NANOS_PER_DAY * NANOS_PER_DAY));
|
||||
assert_eq!(Duration::days(i64::MIN / NANOS_PER_DAY).num_nanoseconds(),
|
||||
|
|
|
@ -43,9 +43,9 @@ use atomic;
|
|||
use comm::Receiver;
|
||||
|
||||
// Various states you can find a port in.
|
||||
static EMPTY: uint = 0;
|
||||
static DATA: uint = 1;
|
||||
static DISCONNECTED: uint = 2;
|
||||
const EMPTY: uint = 0;
|
||||
const DATA: uint = 1;
|
||||
const DISCONNECTED: uint = 2;
|
||||
|
||||
pub struct Packet<T> {
|
||||
// Internal state of the chan/port pair (stores the blocked task as well)
|
||||
|
|
|
@ -31,12 +31,12 @@ use rustrt::thread::Thread;
|
|||
use atomic;
|
||||
use mpsc_queue as mpsc;
|
||||
|
||||
static DISCONNECTED: int = int::MIN;
|
||||
static FUDGE: int = 1024;
|
||||
const DISCONNECTED: int = int::MIN;
|
||||
const FUDGE: int = 1024;
|
||||
#[cfg(test)]
|
||||
static MAX_STEALS: int = 5;
|
||||
const MAX_STEALS: int = 5;
|
||||
#[cfg(not(test))]
|
||||
static MAX_STEALS: int = 1 << 20;
|
||||
const MAX_STEALS: int = 1 << 20;
|
||||
|
||||
pub struct Packet<T> {
|
||||
queue: mpsc::Queue<T>,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue