Skip to content

Commit e7a81cc

Browse files
committed
---
yaml --- r: 145223 b: refs/heads/try2 c: e12c3bf h: refs/heads/master i: 145221: a1ea35d 145219: 4680cf0 145215: 2850ff1 v: v3
1 parent 6a39c49 commit e7a81cc

File tree

23 files changed

+329
-1556
lines changed

23 files changed

+329
-1556
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: 460021bdf2106ee76daf7d81ec7e50e972e26901
8+
refs/heads/try2: e12c3bfbf999bb565b45b58ae9475d60c9e63ceb
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: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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/src/libextra/workcache.rs

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

201+
// FIXME #4330: use &mut self here
201202
#[unsafe_destructor]
202203
impl Drop for Database {
203204
fn drop(&mut self) {

branches/try2/src/librustc/middle/trans/base.rs

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,7 +2559,10 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
25592559
// LLVM type is not fully determined by the Rust type.
25602560
let (v, inlineable) = consts::const_expr(ccx, expr);
25612561
ccx.const_values.insert(id, v);
2562-
let mut inlineable = inlineable;
2562+
if !inlineable {
2563+
debug!("%s not inlined", sym);
2564+
ccx.non_inlineable_statics.insert(id);
2565+
}
25632566
exprt = true;
25642567

25652568
unsafe {
@@ -2575,30 +2578,8 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
25752578
lib::llvm::SetUnnamedAddr(g, true);
25762579
lib::llvm::SetLinkage(g,
25772580
lib::llvm::InternalLinkage);
2578-
2579-
// This is a curious case where we must make
2580-
// all of these statics inlineable. If a
2581-
// global is tagged as
2582-
// address_insignificant, then LLVM won't
2583-
// coalesce globals unless they have an
2584-
// internal linkage type. This means that
2585-
// external crates cannot use this global.
2586-
// This is a problem for things like inner
2587-
// statics in generic functions, because the
2588-
// function will be inlined into another
2589-
// crate and then attempt to link to the
2590-
// static in the original crate, only to
2591-
// find that it's not there. On the other
2592-
// side of inlininig, the crates knows to
2593-
// not declare this static as
2594-
// available_externally (because it isn't)
2595-
inlineable = true;
25962581
}
25972582

2598-
if !inlineable {
2599-
debug!("%s not inlined", sym);
2600-
ccx.non_inlineable_statics.insert(id);
2601-
}
26022583
ccx.item_symbols.insert(i.id, sym);
26032584
g
26042585
}

branches/try2/src/librustc/middle/trans/inline.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use std::vec;
2121
use syntax::ast;
2222
use syntax::ast_map::path_name;
2323
use syntax::ast_util::local_def;
24-
use syntax::attr;
2524

2625
pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::DefId)
2726
-> ast::DefId {
@@ -69,12 +68,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::DefId)
6968
match item.node {
7069
ast::item_static(*) => {
7170
let g = get_item_val(ccx, item.id);
72-
// see the comment in get_item_val() as to why this check is
73-
// performed here.
74-
if !attr::contains_name(item.attrs,
75-
"address_insignificant") {
76-
SetLinkage(g, AvailableExternallyLinkage);
77-
}
71+
SetLinkage(g, AvailableExternallyLinkage);
7872
}
7973
_ => {}
8074
}

branches/try2/src/librustpkg/rustpkg.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ pub trait CtxMethods {
189189
fn test(&self);
190190
fn uninstall(&self, _id: &str, _vers: Option<~str>);
191191
fn unprefer(&self, _id: &str, _vers: Option<~str>);
192-
fn init(&self);
193192
}
194193

195194
impl CtxMethods for BuildContext {
@@ -320,13 +319,6 @@ impl CtxMethods for BuildContext {
320319
"test" => {
321320
self.test();
322321
}
323-
"init" => {
324-
if args.len() != 0 {
325-
return usage::init();
326-
} else {
327-
self.init();
328-
}
329-
}
330322
"uninstall" => {
331323
if args.len() < 1 {
332324
return usage::uninstall();
@@ -548,13 +540,6 @@ impl CtxMethods for BuildContext {
548540
fail!("test not yet implemented");
549541
}
550542

551-
fn init(&self) {
552-
os::mkdir_recursive(&Path("src"), U_RWX);
553-
os::mkdir_recursive(&Path("lib"), U_RWX);
554-
os::mkdir_recursive(&Path("bin"), U_RWX);
555-
os::mkdir_recursive(&Path("build"), U_RWX);
556-
}
557-
558543
fn uninstall(&self, _id: &str, _vers: Option<~str>) {
559544
fail!("uninstall not yet implemented");
560545
}
@@ -703,7 +688,6 @@ pub fn main_args(args: &[~str]) {
703688
~"list" => usage::list(),
704689
~"prefer" => usage::prefer(),
705690
~"test" => usage::test(),
706-
~"init" => usage::init(),
707691
~"uninstall" => usage::uninstall(),
708692
~"unprefer" => usage::unprefer(),
709693
_ => usage::general()

branches/try2/src/librustpkg/tests.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,6 @@ fn no_rebuilding() {
939939
}
940940
941941
#[test]
942-
#[ignore]
943942
fn no_rebuilding_dep() {
944943
let p_id = PkgId::new("foo");
945944
let dep_id = PkgId::new("bar");

branches/try2/src/librustpkg/usage.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,3 @@ and exit code will be redirected.
148148
Options:
149149
-c, --cfg Pass a cfg flag to the package script");
150150
}
151-
152-
pub fn init() {
153-
io::println("rustpkg init name
154-
155-
This makes a new workspace for working on a project named name.
156-
");
157-
}

branches/try2/src/librustpkg/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use workcache_support::{digest_file_with_date, digest_only_date};
3333
// you could update the match in rustpkg.rc but forget to update this list. I think
3434
// that should be fixed.
3535
static COMMANDS: &'static [&'static str] =
36-
&["build", "clean", "do", "info", "init", "install", "list", "prefer", "test", "uninstall",
36+
&["build", "clean", "do", "info", "install", "list", "prefer", "test", "uninstall",
3737
"unprefer"];
3838

3939

branches/try2/src/libstd/os.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,16 @@ pub fn env() -> ~[(~str,~str)] {
196196
if (ch as uint == 0) {
197197
fail!("os::env() failure getting env string from OS: %s", os::last_os_error());
198198
}
199-
let result = str::raw::from_c_multistring(ch as *libc::c_char, None);
199+
let mut curr_ptr: uint = ch as uint;
200+
let mut result = ~[];
201+
while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char) {
202+
let env_pair = str::raw::from_c_str(
203+
curr_ptr as *libc::c_char);
204+
result.push(env_pair);
205+
curr_ptr +=
206+
libc::strlen(curr_ptr as *libc::c_char) as uint
207+
+ 1;
208+
}
200209
FreeEnvironmentStringsA(ch);
201210
result
202211
}

0 commit comments

Comments
 (0)