291 Commits

Author SHA1 Message Date
Felix S. Klock II
d3202354f5 AST refactoring: merge PatWild and PatWildMulti into one variant with a flag. 2014-08-06 17:04:44 +02:00
Patrick Walton
caa564bea3 librustc: Stop desugaring for expressions and translate them directly.
This makes edge cases in which the `Iterator` trait was not in scope
and/or `Option` or its variants were not in scope work properly.

This breaks code that looks like:

    struct MyStruct { ... }

    impl MyStruct {
        fn next(&mut self) -> Option<int> { ... }
    }

    for x in MyStruct { ... } { ... }

Change ad-hoc `next` methods like the above to implementations of the
`Iterator` trait. For example:

    impl Iterator<int> for MyStruct {
        fn next(&mut self) -> Option<int> { ... }
    }

Closes #15392.

[breaking-change]
2014-07-24 18:58:12 -07:00
Björn Steinbrink
0d6f257657 Improve usage of lifetime intrinsics in match expressions
The allocas used in match expression currently don't get good lifetime
markers, in fact they only get lifetime start markers, because their
lifetimes don't match to cleanup scopes.

While the bindings themselves are bog standard and just need a matching
pair of start and end markers, they might need them twice, once for a
guard clause and once for the match body.

The __llmatch alloca OTOH needs a single lifetime start marker, but
when there's a guard clause, it needs two end markers, because its
lifetime ends either when the guard doesn't match or after the match
body.

With these intrinsics in place, LLVM can now, for example, optimize
code like this:

````rust
enum E {
  A1(int),
  A2(int),
  A3(int),
  A4(int),
}

pub fn variants(x: E) {
  match x {
    A1(m) => bar(&m),
    A2(m) => bar(&m),
    A3(m) => bar(&m),
    A4(m) => bar(&m),
  }
}
````

To a single call to bar, using only a single stack slot. It still fails
to eliminate some of checks.

````gas
.Ltmp5:
	.cfi_def_cfa_offset 16
	movb	(%rdi), %al
	testb	%al, %al
	je	.LBB3_5
	movzbl	%al, %eax
	cmpl	$1, %eax
	je	.LBB3_5
	cmpl	$2, %eax
.LBB3_5:
	movq	8(%rdi), %rax
	movq	%rax, (%rsp)
	leaq	(%rsp), %rdi
	callq	_ZN3bar20hcb7a0d8be8e17e37daaE@PLT
	popq	%rax
	retq
````
2014-07-23 17:39:13 +02:00
bors
31c908b7be auto merge of #15863 : dotdash/rust/lifetimes3, r=alexcrichton
Lifetime intrinsics help to reduce stack usage, because LLVM can apply
stack coloring to reuse the stack slots of dead allocas for new ones.

For example these functions now both use the same amount of stack, while
previous `bar()` used five times as much as `foo()`:

````rust
fn foo() {
  println("{}", 5);
}

fn bar() {
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
}
````

On top of that, LLVM can also optimize out certain operations when it
knows that memory is dead after a certain point. For example, it can
sometimes remove the zeroing used to cancel the drop glue. This is
possible when the glue drop itself was already removed because the
zeroing dominated the drop glue call. For example in:

````rust
pub fn bar(x: (Box<int>, int)) -> (Box<int>, int) {
    x
}
````

With optimizations, this currently results in:

````llvm
define void @_ZN3bar20h330fa42547df8179niaE({ i64*, i64 }* noalias nocapture nonnull sret, { i64*, i64 }* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN29_$LP$Box$LT$int$GT$$C$int$RP$39glue_drop.$x22glue_drop$x22$LP$1347$RP$17h88cf42702e5a322aE.exit":
  %2 = bitcast { i64*, i64 }* %1 to i8*
  %3 = bitcast { i64*, i64 }* %0 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  tail call void @llvm.memset.p0i8.i64(i8* %2, i8 0, i64 16, i32 8, i1 false)
  ret void
}
````

But with lifetime intrinsics we get:

````llvm
define void @_ZN3bar20h330fa42547df8179niaE({ i64*, i64 }* noalias nocapture nonnull sret, { i64*, i64 }* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN29_$LP$Box$LT$int$GT$$C$int$RP$39glue_drop.$x22glue_drop$x22$LP$1347$RP$17h88cf42702e5a322aE.exit":
  %2 = bitcast { i64*, i64 }* %1 to i8*
  %3 = bitcast { i64*, i64 }* %0 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  tail call void @llvm.lifetime.end(i64 16, i8* %2)
  ret void
}
````

Fixes #15665
2014-07-22 17:56:15 +00:00
Björn Steinbrink
92d1f155da Emit LLVM lifetime intrinsics to improve stack usage and codegen in general
Lifetime intrinsics help to reduce stack usage, because LLVM can apply
stack coloring to reuse the stack slots of dead allocas for new ones.

For example these functions now both use the same amount of stack, while
previous `bar()` used five times as much as `foo()`:

````rust
fn foo() {
  println("{}", 5);
}

fn bar() {
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
  println("{}", 5);
}
````

On top of that, LLVM can also optimize out certain operations when it
knows that memory is dead after a certain point. For example, it can
sometimes remove the zeroing used to cancel the drop glue. This is
possible when the glue drop itself was already removed because the
zeroing dominated the drop glue call. For example in:

````rust
pub fn bar(x: (Box<int>, int)) -> (Box<int>, int) {
    x
}
````

With optimizations, this currently results in:

````llvm
define void @_ZN3bar20h330fa42547df8179niaE({ i64*, i64 }* noalias nocapture nonnull sret, { i64*, i64 }* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN29_$LP$Box$LT$int$GT$$C$int$RP$39glue_drop.$x22glue_drop$x22$LP$1347$RP$17h88cf42702e5a322aE.exit":
  %2 = bitcast { i64*, i64 }* %1 to i8*
  %3 = bitcast { i64*, i64 }* %0 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  tail call void @llvm.memset.p0i8.i64(i8* %2, i8 0, i64 16, i32 8, i1 false)
  ret void
}
````

But with lifetime intrinsics we get:

````llvm
define void @_ZN3bar20h330fa42547df8179niaE({ i64*, i64 }* noalias nocapture nonnull sret, { i64*, i64 }* noalias nocapture nonnull) unnamed_addr #0 {
"_ZN29_$LP$Box$LT$int$GT$$C$int$RP$39glue_drop.$x22glue_drop$x22$LP$1347$RP$17h88cf42702e5a322aE.exit":
  %2 = bitcast { i64*, i64 }* %1 to i8*
  %3 = bitcast { i64*, i64 }* %0 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* %2, i64 16, i32 8, i1 false)
  tail call void @llvm.lifetime.end(i64 16, i8* %2)
  ret void
}
````

Fixes #15665
2014-07-22 09:17:41 +02:00
Jakub Wieczorek
5819ee1d45 Remove runtime failure from pattern matching
It's an artifact of the old refutable version of `match`
and is no longer necessary.
2014-07-21 17:39:35 +02:00
Jakub Wieczorek
fba1194841 Add support for patterns referencing non-trivial statics
This is accomplished by rewriting static expressions into equivalent patterns.
This way, patterns referencing static variables can both participate
in exhaustiveness analysis as well as be compiled down into the appropriate
branch of the decision trees that match expressions are codegened to.

Fixes #6533.
Fixes #13626.
Fixes #13731.
Fixes #14576.
Fixes #15393.
2014-07-19 01:09:22 +02:00
Patrick Walton
de70d76373 librustc: Remove cross-borrowing of Box<T> to &T from the language,
except where trait objects are involved.

Part of issue #15349, though I'm leaving it open for trait objects.
Cross borrowing for trait objects remains because it is needed until we
have DST.

This will break code like:

    fn foo(x: &int) { ... }

    let a = box 3i;
    foo(a);

Change this code to:

    fn foo(x: &int) { ... }

    let a = box 3i;
    foo(&*a);

[breaking-change]
2014-07-17 14:05:36 -07:00
Brian Anderson
3096d9bf94 rustc_llvm: Remove the inner llvm module
This makes it much saner for clients to use the library since
they don't have to worry about shadowing one llvm with another.
2014-07-14 12:27:08 -07:00
Richo Healey
12c334a77b std: Rename the ToStr trait to ToString, and to_str to to_string.
[breaking-change]
2014-07-08 13:01:43 -07:00
bors
c175ed4425 auto merge of #15440 : pcwalton/rust/struct-aliases, r=brson
Closes #4508.

r? @nick29581
2014-07-07 21:01:42 +00:00
Jakub Wieczorek
9f460e7af8 Properly bind nested pattern bindings when there's more than one
Fixes #15488.
2014-07-07 00:26:41 +02:00
bors
342321def6 auto merge of #15442 : luqmana/rust/odp, r=pnkfelix
Inadvertently changed the order in which destructors ran in certain cases with #15076.

Fixes #15438.
2014-07-05 11:11:47 +00:00
bors
29d6a8ecc6 auto merge of #15425 : jbclements/rust/hygiene-for-3-kinds-of-args, r=cmr
This pull request adds hygiene for 3 kinds of argument bindings:
- arguments to item fns,
- arguments to `ExprFnBlock`s, and
- arguments to `ExprProc`s

It also adds a bunch of unit tests, fixes a few macro uses to be non-capturing, and has a few cleanup items.

local `make check` succeeds.
2014-07-05 03:16:50 +00:00
Luqman Aden
1af8663579 librustc: Make sure to run destructors in the right order when matching on moved value. 2014-07-04 18:05:09 -07:00
Patrick Walton
aaaf7e00ec librustc: Accept type aliases for structures in structure literals and
structure patterns.

Closes #4508.
2014-07-04 17:07:31 -07:00
John Clements
3e99309bfc make any_pat! and u64_from_be_bytes_bench_impl! macros hygienic 2014-07-04 13:20:14 -07:00
bors
c0b76abf91 auto merge of #15388 : jakub-/rust/issue-12285, r=pcwalton
Unit-like struct patterns are irrefutable, no need for a branch.

And some cleanup while I'm at it.
2014-07-04 12:01:22 +00:00
Jakub Wieczorek
c2c27faa35 Fix #12285
Unit-like struct patterns are irrefutable, no need for a branch.
2014-07-04 00:29:47 +02:00
bors
5d5c20647f auto merge of #15377 : alexcrichton/rust/rollup, r=alexcrichton
Closes #15276 (Guide: if)
Closes #15280 (std::os - Add join_paths, make setenv non-utf8 capable)
Closes #15314 (Guide: functions)
Closes #15327 (Simplify PatIdent to contain an Ident rather than a Path)
Closes #15340 (Guide: add mutable binding section)
Closes #15342 (Fix ICE with nested macro_rules!-style macros)
Closes #15350 (Remove duplicated slash in install script path)
Closes #15351 (correct a few spelling mistakes in the tutorial)
Closes #15352 (librustc: Have the kind checker check sub-bounds in trait casts.)
Closes #15359 (Fix spelling errors.)
Closes #15361 (Rename set_broadast() to set_broadcast().)
Closes #15366 (Simplify creating a parser from a token tree)
Closes #15367 (Add examples for StrVector methods)
Closes #15372 (Vec::grow should use reserve_additional, Vec::reserve should check against capacity)
Closes #15373 (Fix minor issues in the documentation of libtime.)
2014-07-03 21:46:47 +00:00
bors
dd812ccbb5 auto merge of #15076 : luqmana/rust/naim, r=pcwalton
```Rust
struct With {
    x: int,
    f: NoCopy
}

#[no_mangle]
fn bar() {
    let mine = With { x: 3, f: NoCopy };
    match mine {
        c => {
            foo(c);
        }
    }
}

#[no_mangle]
fn foo(_: With) {}
```

Before:
```LLVM
define internal void @bar() unnamed_addr #1 {
entry-block:
  %mine = alloca %"struct.With<[]>"
  %__llmatch = alloca %"struct.With<[]>"*
  %c = alloca %"struct.With<[]>"
  %0 = getelementptr inbounds %"struct.With<[]>"* %mine, i32 0, i32 0
  store i64 3, i64* %0
  %1 = getelementptr inbounds %"struct.With<[]>"* %mine, i32 0, i32 1
  store %"struct.With<[]>"* %mine, %"struct.With<[]>"** %__llmatch
  br label %case_body

case_body:                                        ; preds = %entry-block
  %2 = load %"struct.With<[]>"** %__llmatch
  %3 = bitcast %"struct.With<[]>"* %2 to i8*
  %4 = bitcast %"struct.With<[]>"* %c to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %4, i8* %3, i64 8, i32 8, i1 false)
  %5 = load %"struct.With<[]>"* %c
  call void @foo(%"struct.With<[]>" %5)
  br label %join

join:                                             ; preds = %case_body
  ret void
}
```

After:
```LLVM
define internal void @bar() unnamed_addr #1 {
entry-block:
  %mine = alloca %"struct.With<[]>"
  %c = alloca %"struct.With<[]>"*
  %0 = getelementptr inbounds %"struct.With<[]>"* %mine, i32 0, i32 0
  store i64 3, i64* %0
  %1 = getelementptr inbounds %"struct.With<[]>"* %mine, i32 0, i32 1
  store %"struct.With<[]>"* %mine, %"struct.With<[]>"** %c
  br label %case_body

case_body:                                        ; preds = %entry-block
  %2 = load %"struct.With<[]>"** %c
  %3 = load %"struct.With<[]>"* %2
  call void @foo(%"struct.With<[]>" %3)
  br label %join

join:                                             ; preds = %case_body
  ret void
}
```

r? @pcwalton
2014-07-03 19:56:47 +00:00
John Clements
e38cb972dc Simplify PatIdent to contain an Ident rather than a Path
Rationale: for what appear to be historical reasons only, the PatIdent contains
a Path rather than an Ident.  This means that there are many places in the code
where an ident is artificially promoted to a path, and---much more problematically---
a bunch of elements from a path are simply thrown away, which seems like an invitation
to some really nasty bugs.

This commit replaces the Path in a PatIdent with a SpannedIdent, which just contains an ident
and a span.
2014-07-03 12:54:51 -07:00
Jakub Wieczorek
6b6edf4702 Improve code reuse between trans/_match.rs and check_match.rs
The specialization logic for patterns is really the same in both
exhaustiveness/reachability checking and codegen.
2014-07-03 09:17:47 +02:00
Luqman Aden
df88646828 librustc: Don't schedule redundant cleanups. 2014-07-02 20:22:34 -07:00
Luqman Aden
bedc41b257 librustc: Use different alloca slot for non-move bindings. 2014-07-02 20:22:34 -07:00
Luqman Aden
94a56a3758 librustc: Don't create extra alloca slot for by value bindings in match. 2014-07-02 20:22:33 -07:00
Björn Steinbrink
d747de5a92 Compile bools to i1
We currently compiled bools to i8 values, because there was a bug in
LLVM that sometimes caused miscompilations when using i1 in, for
example, structs.

Using i8 means a lot of unnecessary zero-extend and truncate operations
though, since we have to convert the value from and to i1 when using for
example icmp or br instructions. Besides the unnecessary overhead caused
by this, it also sometimes made LLVM miss some optimizations.

Fixes #8106.
2014-06-21 19:59:58 +02:00
Jakub Wieczorek
1e68d57682 Add support for fixed size vectors in let/arg patterns
Fixes #7784
2014-06-20 17:08:57 +02:00
Edward Wang
b1df9aa16f Fix #14865
Fixes a codegen bug which generates illegal non-terminated LLVM block
when there are wildcard pattern with guard and enum patterns in a match
expression. Also refactors the code a little.

Closes #14865
2014-06-18 17:01:58 -07:00
Simon Sapin
d7e01b5809 Add a b"xx" byte string literal of type &'static [u8]. 2014-06-17 23:43:18 +02:00
Alex Crichton
ade807c6dc rustc: Obsolete the @ syntax entirely
This removes all remnants of `@` pointers from rustc. Additionally, this removes
the `GC` structure from the prelude as it seems odd exporting an experimental
type in the prelude by default.

Closes #14193
[breaking-change]
2014-06-14 10:45:37 -07:00
Alex Crichton
54c2a1e1ce rustc: Move the AST from @T to Gc<T> 2014-06-11 09:51:37 -07:00
Jakub Wieczorek
a2bbcb594f Fix an LLVM assertion when matching against static strings
Fixes #8315
Fixes #11940
2014-06-08 19:43:38 +02:00
Niko Matsakis
0f03b5608c Move Def out of syntax crate, where it does not belong 2014-06-06 19:51:23 -04:00
Alex Crichton
760b93adc0 Fallout from the libcollections movement 2014-06-05 13:55:11 -07:00
Alex Crichton
748bc3ca49 std: Rename {Eq,Ord} to Partial{Eq,Ord}
This is part of the ongoing renaming of the equality traits. See #12517 for more
details. All code using Eq/Ord will temporarily need to move to Partial{Eq,Ord}
or the Total{Eq,Ord} traits. The Total traits will soon be renamed to {Eq,Ord}.

cc #12517

[breaking-change]
2014-05-30 15:52:24 -07:00
Kevin Butler
09fc34066b librustc: Fix snake case errors.
A number of functions/methods have been moved or renamed to align
better with rust standard conventions.

rustc:🔙🔗:WriteOutputFile => write_output_file
rustc::middle::ty::EmptyBuiltinBounds => empty_builtin_bounds
rustc::middle::ty::AllBuiltinBounds => all_builtin_bounds
rustc::middle::liveness::IrMaps => IrMaps::new
rustc::middle::liveness::Liveness => Liveness::new
rustc::middle::resolve::NameBindings => NameBindings::new
rustc::middle::resolve::PrimitiveTypeTable => PrimitiveTypeTable::new
rustc::middle::resolve::Resolver => Resolver::new
rustc::middle::trans::datum::Datum => Datum::new
rustc::middle::trans::datum::DatumBlock => DatumBlock::new
rustc::middle::trans::datum::Rvalue => Rvalue::new
rustc::middle::typeck::infer::new_ValsAndBindings => ::infer::unify::ValsAndBindings::new
rustc::middle::typeck::infer::region_inference::RegionVarBindings => RegionVarBindings::new

[breaking-change]
2014-05-30 17:55:42 +01:00
bors
729ee20338 auto merge of #14483 : ahmedcharles/rust/patbox, r=alexcrichton 2014-05-29 12:11:40 -07:00
bors
ff2bf58e9e auto merge of #14481 : alexcrichton/rust/no-format-strbuf, r=sfackler
* Removes `format_strbuf!()`
2014-05-29 03:31:39 -07:00
Keegan McAllister
5fdd0e4b05 Add AST node for pattern macros 2014-05-28 12:42:21 -07:00
Alex Crichton
42aed6bde2 std: Remove format_strbuf!()
This was only ever a transitionary macro.
2014-05-28 08:35:41 -07:00
Ahmed Charles
4e3db5e0f4 Rename PatUniq to PatBox. Fixes part of #13910. 2014-05-27 22:19:29 -07:00
Richo Healey
553074506e core: rename strbuf::StrBuf to string::String
[breaking-change]
2014-05-24 21:48:10 -07:00
bors
c329a1fcdc auto merge of #14313 : kballard/rust/tuple_dotdot_match_ice, r=cmr
Fixes #14308.
2014-05-23 11:46:26 -07:00
Patrick Walton
36195eb91f libstd: Remove ~str from all libstd modules except fmt and str. 2014-05-22 14:42:01 -07:00
Kevin Ballard
0718259ae0 Fix LLVM error with tuple struct match using (..)
Consider PatEnums constructed with A(..) to be candidates for tuple
struct patterns, not just ones constructed with A(a,b,c). If these
patterns shouldn't be valid tuple struct patterns (as they're equivalent
to _), this needs to be caught before we get to trans.

Fixes #14308.
2014-05-20 19:52:43 -07:00
Kevin Ballard
d5b5aa4d4a Fix ICE regarding tuple struct matches using (..)
Fixes half of #14308.
2014-05-20 19:52:39 -07:00
Patrick Walton
6559a3675e librustc: Remove all uses of ~str from librustc. 2014-05-12 11:28:57 -07:00
Nick Cameron
37ca36783c Reorganise driver code.
The goal of this refactoring is to make the rustc driver code easier to understand and use. Since this is as close to an API as we have, I think it is important that it is nice. On getting stuck in, I found that there wasn't as much to change as I'd hoped to make the stage... fns easier to use by tools.

This patch only moves code around - mostly just moving code to different files, but a few extracted method refactorings too. To summarise the changes: I added driver::config which handles everything about configuring the compiler. driver::session now just defines and builds session objects. I moved driver code from librustc/lib.rs to librustc/driver/mod.rs so all the code is one place. I extracted methods to make emulating the compiler without being the compiler a little easier. Within the driver directory, I moved code around to more logically fit in the modules.
2014-05-11 11:08:01 +12:00
Patrick Walton
090040bf40 librustc: Remove ~EXPR, ~TYPE, and ~PAT from the language, except
for `~str`/`~[]`.

Note that `~self` still remains, since I forgot to add support for
`Box<self>` before the snapshot.

How to update your code:

* Instead of `~EXPR`, you should write `box EXPR`.

* Instead of `~TYPE`, you should write `Box<Type>`.

* Instead of `~PATTERN`, you should write `box PATTERN`.

[breaking-change]
2014-05-06 23:12:54 -07:00