Skip to content

Commit 8e7f413

Browse files
committed
---
yaml --- r: 145238 b: refs/heads/try2 c: 10d26f8 h: refs/heads/master v: v3
1 parent 15f87c5 commit 8e7f413

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1860
-293
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 34ac5b05f695b21f286f85d2391d116b8ad7a4d5
8+
refs/heads/try2: 10d26f8daf52ca60b785712682c1962e98954fd9
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/doc/rust.md

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ string_body : non_double_quote
248248
| '\x5c' [ '\x22' | common_escape ] ;
249249
250250
common_escape : '\x5c'
251-
| 'n' | 'r' | 't'
251+
| 'n' | 'r' | 't' | '0'
252252
| 'x' hex_digit 2
253253
| 'u' hex_digit 4
254254
| 'U' hex_digit 8 ;
@@ -962,24 +962,76 @@ parameters to allow methods with that trait to be called on values
962962
of that type.
963963

964964

965-
#### Unsafe functions
966-
967-
Unsafe functions are those containing unsafe operations that are not contained in an [`unsafe` block](#unsafe-blocks).
968-
Such a function must be prefixed with the keyword `unsafe`.
965+
#### Unsafety
969966

970967
Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
971-
Specifically, the following operations are considered unsafe:
968+
969+
The following language level features cannot be used in the safe subset of Rust:
972970

973971
- Dereferencing a [raw pointer](#pointer-types).
974-
- Casting a [raw pointer](#pointer-types) to a safe pointer type.
975-
- Calling an unsafe function.
972+
- Calling an unsafe function (including an intrinsic or foreign function).
976973

977-
##### Unsafe blocks
974+
##### Unsafe functions
978975

979-
A block of code can also be prefixed with the `unsafe` keyword, to permit a sequence of unsafe operations in an otherwise-safe function.
980-
This facility exists because the static semantics of Rust are a necessary approximation of the dynamic semantics.
981-
When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe, they can encapsulate that sequence (taken as a whole) within an `unsafe` block. The compiler will consider uses of such code "safe", to the surrounding context.
976+
Unsafe functions are functions that are not safe in all contexts and/or for all possible inputs.
977+
Such a function must be prefixed with the keyword `unsafe`.
978+
979+
##### Unsafe blocks
982980

981+
A block of code can also be prefixed with the `unsafe` keyword, to permit calling `unsafe` functions
982+
or dereferencing raw pointers within a safe function.
983+
984+
When a programmer has sufficient conviction that a sequence of potentially unsafe operations is
985+
actually safe, they can encapsulate that sequence (taken as a whole) within an `unsafe` block. The
986+
compiler will consider uses of such code safe, in the surrounding context.
987+
988+
Unsafe blocks are used to wrap foreign libraries, make direct use of hardware or implement features
989+
not directly present in the language. For example, Rust provides the language features necessary to
990+
implement memory-safe concurrency in the language but the implementation of tasks and message
991+
passing is in the standard library.
992+
993+
Rust's type system is a conservative approximation of the dynamic safety requirements, so in some
994+
cases there is a performance cost to using safe code. For example, a doubly-linked list is not a
995+
tree structure and can only be represented with managed or reference-counted pointers in safe code.
996+
By using `unsafe` blocks to represent the reverse links as raw pointers, it can be implemented with
997+
only owned pointers.
998+
999+
##### Behavior considered unsafe
1000+
1001+
This is a list of behavior which is forbidden in all Rust code. Type checking provides the guarantee
1002+
that these issues are never caused by safe code. An `unsafe` block or function is responsible for
1003+
never invoking this behaviour or exposing an API making it possible for it to occur in safe code.
1004+
1005+
* Data races
1006+
* Dereferencing a null/dangling raw pointer
1007+
* Mutating an immutable value/reference, if it is not marked as non-`Freeze`
1008+
* Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values) (uninitialized) memory
1009+
* Breaking the [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
1010+
with raw pointers (a subset of the rules used by C)
1011+
* Invoking undefined behavior via compiler intrinsics:
1012+
* Indexing outside of the bounds of an object with `std::ptr::offset` (`offset` intrinsic), with
1013+
the exception of one byte past the end which is permitted.
1014+
* Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64` instrinsics) on
1015+
overlapping buffers
1016+
* Invalid values in primitive types, even in private fields/locals:
1017+
* Dangling/null pointers in non-raw pointers, or slices
1018+
* A value other than `false` (0) or `true` (1) in a `bool`
1019+
* A discriminant in an `enum` not included in the type definition
1020+
* A value in a `char` which is a surrogate or above `char::MAX`
1021+
* non-UTF-8 byte sequences in a `str`
1022+
1023+
##### Behaviour not considered unsafe
1024+
1025+
This is a list of behaviour not considered *unsafe* in Rust terms, but that may be undesired.
1026+
1027+
* Deadlocks
1028+
* Reading data from private fields (`std::repr`, `format!("{:?}", x)`)
1029+
* Leaks due to reference count cycles, even in the global heap
1030+
* Exiting without calling destructors
1031+
* Sending signals
1032+
* Accessing/modifying the file system
1033+
* Unsigned integer overflow (well-defined as wrapping)
1034+
* Signed integer overflow (well-defined as two's complement representation wrapping)
9831035

9841036
#### Diverging functions
9851037

branches/try2/mk/llvm.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ LLVM_STAMP_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-auto-clean-stamp
2828

2929
$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS) $$(LLVM_STAMP_$(1))
3030
@$$(call E, make: llvm)
31-
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) $$(CFG_LLVM_BUILD_ENV)
31+
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) $$(CFG_LLVM_BUILD_ENV_$(1))
3232
$$(Q)touch $$(LLVM_CONFIG_$(1))
3333
endif
3434

branches/try2/mk/platform.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ AR_i686-pc-mingw32=$(AR)
352352
CFG_LIB_NAME_i686-pc-mingw32=$(1).dll
353353
CFG_LIB_GLOB_i686-pc-mingw32=$(1)-*.dll
354354
CFG_LIB_DSYM_GLOB_i686-pc-mingw32=$(1)-*.dylib.dSYM
355-
CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -m32 -march=i686 -D_WIN32_WINNT=0x0600
355+
CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -m32 -march=i686 -D_WIN32_WINNT=0x0600 -I$(CFG_SRC_DIR)src/etc/mingw-fix-include
356356
CFG_GCCISH_CXXFLAGS_i686-pc-mingw32 := -fno-rtti
357357
CFG_GCCISH_LINK_FLAGS_i686-pc-mingw32 := -shared -fPIC -g -m32
358358
CFG_GCCISH_DEF_FLAG_i686-pc-mingw32 :=
@@ -361,6 +361,7 @@ CFG_GCCISH_POST_LIB_FLAGS_i686-pc-mingw32 :=
361361
CFG_DEF_SUFFIX_i686-pc-mingw32 := .mingw32.def
362362
CFG_INSTALL_NAME_i686-pc-mingw32 =
363363
CFG_LIBUV_LINK_FLAGS_i686-pc-mingw32 := -lWs2_32 -lpsapi -liphlpapi
364+
CFG_LLVM_BUILD_ENV_i686-pc-mingw32 := CPATH=$(CFG_SRC_DIR)src/etc/mingw-fix-include
364365
CFG_EXE_SUFFIX_i686-pc-mingw32 := .exe
365366
CFG_WINDOWSY_i686-pc-mingw32 := 1
366367
CFG_UNIXY_i686-pc-mingw32 :=

branches/try2/mk/rt.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
# working under these assumptions).
2525

2626
# Hack for passing flags into LIBUV, see below.
27-
LIBUV_FLAGS_i386 = -m32 -fPIC
27+
LIBUV_FLAGS_i386 = -m32 -fPIC -I$(S)src/etc/mingw-fix-include
2828
LIBUV_FLAGS_x86_64 = -m64 -fPIC
2929
ifeq ($(OSTYPE_$(1)), linux-androideabi)
3030
LIBUV_FLAGS_arm = -fPIC -DANDROID -std=gnu99
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
The purpose of these headers is to fix issues with mingw v4.0, as described in #9246.
2+
3+
This works by adding this directory to GCC include search path before mingw system headers directories,
4+
so we can intercept their inclusions and add missing definitions without having to modify files in mingw/include.
5+
6+
Once mingw fixes all 3 issues mentioned in #9246, this directory and all references to it from rust/mk/* may be removed.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef _FIX_CXXCONFIG_H
2+
#define _FIX_CXXCONFIG_H 1
3+
4+
#define _GLIBCXX_HAVE_FENV_H 1
5+
6+
#include_next <bits/c++config.h>
7+
8+
#endif
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef _FIX_WINBASE_H
2+
#define _FIX_WINBASE_H 1
3+
4+
#define NTDDK_VERSION NTDDI_VERSION
5+
6+
#include_next <winbase.h>
7+
8+
#endif
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef _FIX_WINSOCK2_H
2+
#define _FIX_WINSOCK2_H 1
3+
4+
#include_next <winsock2.h>
5+
6+
typedef struct pollfd {
7+
SOCKET fd;
8+
short events;
9+
short revents;
10+
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
11+
12+
#endif

branches/try2/src/libextra/num/bigint.rs

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,13 @@ impl BigUint {
697697
}
698698
return BigUint::new(shifted);
699699
}
700+
701+
/// Determines the fewest bits necessary to express the BigUint.
702+
pub fn bits(&self) -> uint {
703+
if self.is_zero() { return 0; }
704+
let zeros = self.data.last().leading_zeros();
705+
return self.data.len()*BigDigit::bits - (zeros as uint);
706+
}
700707
}
701708

702709
#[cfg(target_word_size = "64")]
@@ -1115,10 +1122,23 @@ trait RandBigInt {
11151122
11161123
/// Generate a random BigInt of the given bit size.
11171124
fn gen_bigint(&mut self, bit_size: uint) -> BigInt;
1125+
1126+
/// Generate a random BigUint less than the given bound. Fails
1127+
/// when the bound is zero.
1128+
fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint;
1129+
1130+
/// Generate a random BigUint within the given range. The lower
1131+
/// bound is inclusive; the upper bound is exclusive. Fails when
1132+
/// the upper bound is not greater than the lower bound.
1133+
fn gen_biguint_range(&mut self, lbound: &BigUint, ubound: &BigUint) -> BigUint;
1134+
1135+
/// Generate a random BigInt within the given range. The lower
1136+
/// bound is inclusive; the upper bound is exclusive. Fails when
1137+
/// the upper bound is not greater than the lower bound.
1138+
fn gen_bigint_range(&mut self, lbound: &BigInt, ubound: &BigInt) -> BigInt;
11181139
}
11191140
11201141
impl<R: Rng> RandBigInt for R {
1121-
/// Generate a random BigUint of the given bit size.
11221142
fn gen_biguint(&mut self, bit_size: uint) -> BigUint {
11231143
let (digits, rem) = bit_size.div_rem(&BigDigit::bits);
11241144
let mut data = vec::with_capacity(digits+1);
@@ -1132,7 +1152,6 @@ impl<R: Rng> RandBigInt for R {
11321152
return BigUint::new(data);
11331153
}
11341154
1135-
/// Generate a random BigInt of the given bit size.
11361155
fn gen_bigint(&mut self, bit_size: uint) -> BigInt {
11371156
// Generate a random BigUint...
11381157
let biguint = self.gen_biguint(bit_size);
@@ -1154,6 +1173,32 @@ impl<R: Rng> RandBigInt for R {
11541173
};
11551174
return BigInt::from_biguint(sign, biguint);
11561175
}
1176+
1177+
fn gen_biguint_below(&mut self, bound: &BigUint) -> BigUint {
1178+
assert!(!bound.is_zero());
1179+
let bits = bound.bits();
1180+
loop {
1181+
let n = self.gen_biguint(bits);
1182+
if n < *bound { return n; }
1183+
}
1184+
}
1185+
1186+
fn gen_biguint_range(&mut self,
1187+
lbound: &BigUint,
1188+
ubound: &BigUint)
1189+
-> BigUint {
1190+
assert!(*lbound < *ubound);
1191+
return *lbound + self.gen_biguint_below(&(*ubound - *lbound));
1192+
}
1193+
1194+
fn gen_bigint_range(&mut self,
1195+
lbound: &BigInt,
1196+
ubound: &BigInt)
1197+
-> BigInt {
1198+
assert!(*lbound < *ubound);
1199+
let delta = (*ubound - *lbound).to_biguint();
1200+
return *lbound + self.gen_biguint_below(&delta).to_bigint();
1201+
}
11571202
}
11581203
11591204
impl BigInt {
@@ -1780,12 +1825,63 @@ mod biguint_tests {
17801825
check(30, "265252859812191058636308480000000");
17811826
}
17821827

1828+
#[test]
1829+
fn test_bits() {
1830+
assert_eq!(BigUint::new(~[0,0,0,0]).bits(), 0);
1831+
assert_eq!(BigUint::from_uint(0).bits(), 0);
1832+
assert_eq!(BigUint::from_uint(1).bits(), 1);
1833+
assert_eq!(BigUint::from_uint(3).bits(), 2);
1834+
let n: BigUint = FromStrRadix::from_str_radix("4000000000", 16).unwrap();
1835+
assert_eq!(n.bits(), 39);
1836+
let one: BigUint = One::one();
1837+
assert_eq!((one << 426).bits(), 427);
1838+
}
1839+
17831840
#[test]
17841841
fn test_rand() {
17851842
let mut rng = task_rng();
17861843
let _n: BigUint = rng.gen_biguint(137);
17871844
assert!(rng.gen_biguint(0).is_zero());
17881845
}
1846+
1847+
#[test]
1848+
fn test_rand_range() {
1849+
let mut rng = task_rng();
1850+
1851+
do 10.times {
1852+
assert_eq!(rng.gen_bigint_range(&BigInt::from_uint(236),
1853+
&BigInt::from_uint(237)),
1854+
BigInt::from_uint(236));
1855+
}
1856+
1857+
let l = BigUint::from_uint(403469000 + 2352);
1858+
let u = BigUint::from_uint(403469000 + 3513);
1859+
do 1000.times {
1860+
let n: BigUint = rng.gen_biguint_below(&u);
1861+
assert!(n < u);
1862+
1863+
let n: BigUint = rng.gen_biguint_range(&l, &u);
1864+
assert!(n >= l);
1865+
assert!(n < u);
1866+
}
1867+
}
1868+
1869+
#[test]
1870+
#[should_fail]
1871+
fn test_zero_rand_range() {
1872+
task_rng().gen_biguint_range(&BigUint::from_uint(54),
1873+
&BigUint::from_uint(54));
1874+
}
1875+
1876+
#[test]
1877+
#[should_fail]
1878+
fn test_negative_rand_range() {
1879+
let mut rng = task_rng();
1880+
let l = BigUint::from_uint(2352);
1881+
let u = BigUint::from_uint(3513);
1882+
// Switching u and l should fail:
1883+
let _n: BigUint = rng.gen_biguint_range(&u, &l);
1884+
}
17891885
}
17901886

17911887
#[cfg(test)]
@@ -2237,6 +2333,48 @@ mod bigint_tests {
22372333
let _n: BigInt = rng.gen_bigint(137);
22382334
assert!(rng.gen_bigint(0).is_zero());
22392335
}
2336+
2337+
#[test]
2338+
fn test_rand_range() {
2339+
let mut rng = task_rng();
2340+
2341+
do 10.times {
2342+
assert_eq!(rng.gen_bigint_range(&BigInt::from_uint(236),
2343+
&BigInt::from_uint(237)),
2344+
BigInt::from_uint(236));
2345+
}
2346+
2347+
fn check(l: BigInt, u: BigInt) {
2348+
let mut rng = task_rng();
2349+
do 1000.times {
2350+
let n: BigInt = rng.gen_bigint_range(&l, &u);
2351+
assert!(n >= l);
2352+
assert!(n < u);
2353+
}
2354+
}
2355+
let l = BigInt::from_uint(403469000 + 2352);
2356+
let u = BigInt::from_uint(403469000 + 3513);
2357+
check( l.clone(), u.clone());
2358+
check(-l.clone(), u.clone());
2359+
check(-u.clone(), -l.clone());
2360+
}
2361+
2362+
#[test]
2363+
#[should_fail]
2364+
fn test_zero_rand_range() {
2365+
task_rng().gen_bigint_range(&IntConvertible::from_int(54),
2366+
&IntConvertible::from_int(54));
2367+
}
2368+
2369+
#[test]
2370+
#[should_fail]
2371+
fn test_negative_rand_range() {
2372+
let mut rng = task_rng();
2373+
let l = BigInt::from_uint(2352);
2374+
let u = BigInt::from_uint(3513);
2375+
// Switching u and l should fail:
2376+
let _n: BigInt = rng.gen_bigint_range(&u, &l);
2377+
}
22402378
}
22412379

22422380
#[cfg(test)]

branches/try2/src/libextra/workcache.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ impl Database {
198198
}
199199
}
200200

201-
// FIXME #4330: use &mut self here
202201
#[unsafe_destructor]
203202
impl Drop for Database {
204203
fn drop(&mut self) {

0 commit comments

Comments
 (0)