Skip to content

Commit b092982

Browse files
committed
---
yaml --- r: 140756 b: refs/heads/try2 c: 935b7ba h: refs/heads/master v: v3
1 parent 31a95fc commit b092982

File tree

17 files changed

+250
-66
lines changed

17 files changed

+250
-66
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: 2210d2d5d5166674fdb8412573e8ae78b39e4e99
8+
refs/heads/try2: 935b7ba51645cb738da6bd65df4f8eedf0a62bcb
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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,8 @@ names are effectively reserved. Some significant attributes include:
14251425
* The `test` attribute, for marking functions as unit tests.
14261426
* The `allow`, `warn`, `forbid`, and `deny` attributes, for controlling lint checks. Lint checks supported
14271427
by the compiler can be found via `rustc -W help`.
1428+
* The `deriving` attribute, for automatically generating
1429+
implementations of certain traits.
14281430

14291431
Other attributes may be added or removed during development of the language.
14301432

@@ -1526,6 +1528,47 @@ A complete list of the built-in language items follows:
15261528
> **Note:** This list is likely to become out of date. We should auto-generate it
15271529
> from `librustc/middle/lang_items.rs`.
15281530
1531+
### Deriving
1532+
1533+
The `deriving` attribute allows certain traits to be automatically
1534+
implemented for data structures. For example, the following will
1535+
create an `impl` for the `Eq` and `Clone` traits for `Foo`, the type
1536+
parameter `T` will be given the `Eq` or `Clone` constraints for the
1537+
appropriate `impl`:
1538+
1539+
~~~
1540+
#[deriving(Eq, Clone)]
1541+
struct Foo<T> {
1542+
a: int,
1543+
b: T
1544+
}
1545+
~~~
1546+
1547+
The generated `impl` for `Eq` is equivalent to
1548+
1549+
~~~
1550+
# struct Foo<T> { a: int, b: T }
1551+
impl<T: Eq> Eq for Foo<T> {
1552+
fn eq(&self, other: &Foo<T>) -> bool {
1553+
self.a == other.a && self.b == other.b
1554+
}
1555+
1556+
fn ne(&self, other: &Foo<T>) -> bool {
1557+
self.a != other.a || self.b != other.b
1558+
}
1559+
}
1560+
~~~
1561+
1562+
Supported traits for `deriving` are:
1563+
1564+
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
1565+
* Serialization: `Encodable`, `Decodable`. These require `std`.
1566+
* `Clone`, to perform deep copies.
1567+
* `IterBytes`, to iterate over the bytes in a data type.
1568+
* `Rand`, to create a random instance of a data type.
1569+
* `ToStr`, to convert to a string. For a type with this instance,
1570+
`obj.to_str()` has the same output as `fmt!("%?", obj)`.
1571+
15291572
# Statements and expressions
15301573

15311574
Rust is _primarily_ an expression language. This means that most forms of

branches/try2/doc/tutorial.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,6 +2290,27 @@ let nonsense = mycircle.radius() * mycircle.area();
22902290

22912291
> ***Note:*** Trait inheritance does not actually work with objects yet
22922292
2293+
## Deriving implementations for traits
2294+
2295+
A small number of traits in `core` and `std` can have implementations
2296+
that can be automatically derived. These instances are specified by
2297+
placing the `deriving` attribute on a data type declaration. For
2298+
example, the following will mean that `Circle` has an implementation
2299+
for `Eq` and can be used with the equality operators, and that a value
2300+
of type `ABC` can be randomly generated and converted to a string:
2301+
2302+
~~~
2303+
#[deriving(Eq)]
2304+
struct Circle { radius: float }
2305+
2306+
#[deriving(Rand, ToStr)]
2307+
enum ABC { A, B, C }
2308+
~~~
2309+
2310+
The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
2311+
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `IterBytes`, `Rand` and
2312+
`ToStr`.
2313+
22932314
# Modules and crates
22942315

22952316
The Rust namespace is arranged in a hierarchy of modules. Each source

branches/try2/src/driver/driver.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[no_core];
12-
extern mod core(vers = "0.7-pre");
13-
1411
#[cfg(rustpkg)]
1512
extern mod this(name = "rustpkg", vers = "0.7-pre");
1613

branches/try2/src/libcore/unstable/intrinsics.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ pub extern "rust-intrinsic" {
2020
pub fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
2121
pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
2222

23+
#[cfg(not(stage0))]
24+
pub fn atomic_load(src: &int) -> int;
25+
#[cfg(not(stage0))]
26+
pub fn atomic_load_acq(src: &int) -> int;
27+
28+
#[cfg(not(stage0))]
29+
pub fn atomic_store(dst: &mut int, val: int);
30+
#[cfg(not(stage0))]
31+
pub fn atomic_store_rel(dst: &mut int, val: int);
32+
2333
pub fn atomic_xchg(dst: &mut int, src: int) -> int;
2434
pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
2535
pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int;

branches/try2/src/librust/rust.rc

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
#[license = "MIT/ASL2"];
2121
#[crate_type = "lib"];
2222

23+
extern mod rustpkg(vers = "0.7-pre");
24+
extern mod rustdoc(vers = "0.7-pre");
25+
extern mod rusti(vers = "0.7-pre");
26+
extern mod rustc(vers = "0.7-pre");
27+
2328
use core::run;
2429

2530
enum ValidUsage {
@@ -36,13 +41,13 @@ impl ValidUsage {
3641
}
3742

3843
enum Action<'self> {
39-
Exec(&'self str),
40-
Call(&'self fn(args: &[~str]) -> ValidUsage)
44+
Call(&'self fn(args: &[~str]) -> ValidUsage),
45+
CallMain(&'static str, &'self fn()),
4146
}
4247

4348
enum UsageSource<'self> {
44-
UsgExec(&'self str),
45-
UsgStr(&'self str)
49+
UsgStr(&'self str),
50+
UsgCall(&'self fn()),
4651
}
4752

4853
struct Command<'self> {
@@ -55,9 +60,9 @@ struct Command<'self> {
5560
static commands: &'static [Command<'static>] = &[
5661
Command{
5762
cmd: "build",
58-
action: Exec("rustc"),
63+
action: CallMain("rustc", rustc::main),
5964
usage_line: "compile rust source files",
60-
usage_full: UsgExec("rustc --help")
65+
usage_full: UsgCall(rustc_help),
6166
},
6267
Command{
6368
cmd: "run",
@@ -81,21 +86,21 @@ static commands: &'static [Command<'static>] = &[
8186
},
8287
Command{
8388
cmd: "doc",
84-
action: Exec("rustdoc"),
89+
action: CallMain("rustdoc", rustdoc::main),
8590
usage_line: "generate documentation from doc comments",
86-
usage_full: UsgExec("rustdoc --help")
91+
usage_full: UsgCall(rustdoc::config::usage),
8792
},
8893
Command{
8994
cmd: "pkg",
90-
action: Exec("rustpkg"),
95+
action: CallMain("rustpkg", rustpkg::main),
9196
usage_line: "download, build, install rust packages",
92-
usage_full: UsgExec("rustpkg --help")
97+
usage_full: UsgCall(rustpkg::usage::general),
9398
},
9499
Command{
95100
cmd: "sketch",
96-
action: Exec("rusti"),
101+
action: CallMain("rusti", rusti::main),
97102
usage_line: "run a rust interpreter",
98-
usage_full: UsgStr("\nUsage:\trusti")
103+
usage_full: UsgStr("\nUsage:\trusti"),
99104
},
100105
Command{
101106
cmd: "help",
@@ -109,6 +114,10 @@ static commands: &'static [Command<'static>] = &[
109114
}
110115
];
111116

117+
fn rustc_help() {
118+
rustc::usage(copy os::args()[0])
119+
}
120+
112121
fn find_cmd(command_string: &str) -> Option<Command> {
113122
do commands.find |command| {
114123
command.cmd == command_string
@@ -120,20 +129,14 @@ fn cmd_help(args: &[~str]) -> ValidUsage {
120129
match find_cmd(command_string) {
121130
Some(command) => {
122131
match command.action {
123-
Exec(s) => io::println(fmt!(
132+
CallMain(prog, _) => io::println(fmt!(
124133
"The %s command is an alias for the %s program.",
125-
command.cmd, s)),
134+
command.cmd, prog)),
126135
_ => ()
127136
}
128137
match command.usage_full {
129-
UsgStr(msg) => io::println(fmt!("%s\n", msg)),
130-
UsgExec(commandline) => {
131-
let mut words = ~[];
132-
for str::each_word(commandline) |word| { words.push(word.to_owned()) }
133-
let words = words;
134-
let (prog, args) = (words.head(), words.tail());
135-
run::run_program(*prog, args);
136-
}
138+
UsgStr(msg) => io::println(fmt!("%s\n", msg)),
139+
UsgCall(f) => f(),
137140
}
138141
Valid
139142
},
@@ -151,50 +154,40 @@ fn cmd_test(args: &[~str]) -> ValidUsage {
151154
match args {
152155
[filename] => {
153156
let test_exec = Path(filename).filestem().unwrap() + "test~";
154-
if run::run_program("rustc", [
155-
~"--test",
156-
filename.to_owned(),
157-
~"-o",
158-
test_exec.to_owned()
159-
]) == 0 {
160-
run::run_program(~"./" + test_exec, []);
161-
}
157+
invoke("rustc", &[~"--test", filename.to_owned(),
158+
~"-o", test_exec.to_owned()], rustc::main);
159+
run::run_program(~"./" + test_exec, []);
162160
Valid
163161
}
164-
_ => Invalid
162+
_ => Invalid
165163
}
166164
}
167165

168166
fn cmd_run(args: &[~str]) -> ValidUsage {
169167
match args {
170168
[filename, ..prog_args] => {
171169
let exec = Path(filename).filestem().unwrap() + "~";
172-
if run::run_program("rustc", [
173-
filename.to_owned(),
174-
~"-o",
175-
exec.to_owned()
176-
]) == 0 {
177-
run::run_program(~"./"+exec, prog_args);
178-
}
170+
invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
171+
rustc::main);
172+
run::run_program(~"./"+exec, prog_args);
179173
Valid
180174
}
181-
_ => Invalid
175+
_ => Invalid
182176
}
183177
}
184178

179+
fn invoke(prog: &str, args: &[~str], f: &fn()) {
180+
let mut osargs = ~[prog.to_owned()];
181+
osargs.push_all_move(args.to_owned());
182+
os::set_args(osargs);
183+
f();
184+
}
185+
185186
fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
186187
match command.action {
187188
Call(f) => f(args),
188-
Exec(commandline) => {
189-
let mut words = ~[];
190-
for str::each_word(commandline) |word| { words.push(word.to_owned()) }
191-
let words = words;
192-
let (prog, prog_args) = (words.head(), words.tail());
193-
let exitstatus = run::run_program(
194-
*prog,
195-
vec::append(vec::to_owned(prog_args), args)
196-
);
197-
os::set_exit_status(exitstatus);
189+
CallMain(prog, f) => {
190+
invoke(prog, args, f);
198191
Valid
199192
}
200193
}
@@ -232,11 +225,9 @@ pub fn main() {
232225
let args = os_args.tail();
233226

234227
if !args.is_empty() {
235-
for commands.each |command| {
236-
if command.cmd == *args.head() {
237-
let result = do_command(command, args.tail());
238-
if result.is_valid() { return; }
239-
}
228+
for find_cmd(*args.head()).each |command| {
229+
let result = do_command(command, args.tail());
230+
if result.is_valid() { return; }
240231
}
241232
}
242233

branches/try2/src/librustc/lib/llvm.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,13 +1339,16 @@ pub mod llvm {
13391339
PointerVal: ValueRef) -> ValueRef;
13401340
#[fast_ffi]
13411341
pub unsafe fn LLVMBuildLoad(B: BuilderRef,
1342-
PointerVal: ValueRef,
1343-
Name: *c_char)
1344-
-> ValueRef;
1342+
PointerVal: ValueRef,
1343+
Name: *c_char)
1344+
-> ValueRef;
1345+
13451346
#[fast_ffi]
13461347
pub unsafe fn LLVMBuildStore(B: BuilderRef,
13471348
Val: ValueRef,
1348-
Ptr: ValueRef) -> ValueRef;
1349+
Ptr: ValueRef)
1350+
-> ValueRef;
1351+
13491352
#[fast_ffi]
13501353
pub unsafe fn LLVMBuildGEP(B: BuilderRef,
13511354
Pointer: ValueRef,
@@ -1561,6 +1564,17 @@ pub mod llvm {
15611564
Name: *c_char) -> ValueRef;
15621565

15631566
/* Atomic Operations */
1567+
pub unsafe fn LLVMBuildAtomicLoad(B: BuilderRef,
1568+
PointerVal: ValueRef,
1569+
Order: AtomicOrdering)
1570+
-> ValueRef;
1571+
1572+
pub unsafe fn LLVMBuildAtomicStore(B: BuilderRef,
1573+
Val: ValueRef,
1574+
Ptr: ValueRef,
1575+
Order: AtomicOrdering)
1576+
-> ValueRef;
1577+
15641578
pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
15651579
LHS: ValueRef,
15661580
CMP: ValueRef,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ fn padding(size: u64) -> ValueRef {
574574
}
575575

576576
// XXX this utility routine should be somewhere more general
577-
#[always_inline]
577+
#[inline(always)]
578578
fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
579579

580580
/// Get the discriminant of a constant value. (Not currently used.)

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,18 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
537537
}
538538
}
539539
540+
pub fn AtomicLoad(cx: block, PointerVal: ValueRef, order: AtomicOrdering) -> ValueRef {
541+
unsafe {
542+
let ccx = cx.fcx.ccx;
543+
if cx.unreachable {
544+
return llvm::LLVMGetUndef(ccx.int_type);
545+
}
546+
count_insn(cx, "load.atomic");
547+
return llvm::LLVMBuildAtomicLoad(B(cx), PointerVal, order);
548+
}
549+
}
550+
551+
540552
pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
541553
hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
542554
let value = Load(cx, PointerVal);
@@ -567,6 +579,17 @@ pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
567579
}
568580
}
569581
582+
pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrdering) {
583+
unsafe {
584+
if cx.unreachable { return; }
585+
debug!("Store %s -> %s",
586+
val_str(cx.ccx().tn, Val),
587+
val_str(cx.ccx().tn, Ptr));
588+
count_insn(cx, "store.atomic");
589+
llvm::LLVMBuildAtomicStore(B(cx), Val, Ptr, order);
590+
}
591+
}
592+
570593
pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef {
571594
unsafe {
572595
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }

0 commit comments

Comments
 (0)