Commit Graph

36767 Commits

Author SHA1 Message Date
Nick Cameron
8f3a424322 Fix the obsolete message 2015-01-06 14:25:06 +13:00
Nick Cameron
e0684e8769 Fallout 2015-01-06 14:20:48 +13:00
Nick Cameron
48f50e1e98 Obsolete Sized? T
[breaking-change]

Use `T: ?Sized`
2015-01-06 14:20:47 +13:00
Nick Cameron
595a082587 Remove the prefix in ObsoleteSyntax variants 2015-01-06 13:23:29 +13:00
bors
c7dd3c4d69 auto merge of #20578 : japaric/rust/no-more-bc, r=nmatsakis
This PR removes boxed closures from the language, the closure type syntax (`let f: |int| -> bool = /* ... */`) has been obsoleted. Move all your uses of closures to the new unboxed closure system (i.e. `Fn*` traits).

[breaking-change] patterns

- `lef f = || {}`

This binding used to type check to a boxed closure. Now that boxed closures are gone, you need to annotate the "kind" of the unboxed closure, i.e. you need pick one of these: `|&:| {}`, `|&mut:| {}` or `|:| {}`.

In the (near) future we'll have closure "kind" inference, so the compiler will infer which `Fn*` trait to use based on how the closure is used. Once this inference machinery is in place, we'll be able to remove the kind annotation from most closures.

- `type Alias<'a> = |int|:'a -> bool`

Use a trait object: `type Alias<'a> = Box<FnMut(int) -> bool + 'a>`. Use the `Fn*` trait that makes sense for your use case.

- `fn foo(&self, f: |uint| -> bool)`

In this case you can use either a trait object or an unboxed closure:

``` rust
fn foo(&self, f: F) where F: FnMut(uint) -> bool;
// or
fn foo(&self, f: Box<FnMut(uint) -> bool>);
```

- `struct Struct<'a> { f: |uint|:'a -> bool }`

Again, you can use either a trait object or an unboxed closure:

``` rust
struct Struct<F> where F: FnMut(uint) -> bool { f: F }
// or
struct Struct<'a> { f: Box<FnMut(uint) -> bool + 'a> }
```

- Using `|x, y| f(x, y)` for closure "borrows"

This comes up in recursive functions, consider the following (contrived) example:

``` rust
fn foo(x: uint, f: |uint| -> bool) -> bool {
    //foo(x / 2, f) && f(x)  // can't use this because `f` gets moved away in the `foo` call
    foo(x / 2, |x| f(x)) && f(x)  // instead "borrow" `f` in the `foo` call
}
```

If you attempt to do the same with unboxed closures you'll hit ""error: reached the recursion limit during monomorphization" (see #19596):

``` rust
fn foo<F>(x: uint, mut f: F) -> bool where F: FnMut(uint) -> bool {
    foo(x / 2, |x| f(x)) && f(x)
    //~^ error: reached the recursion limit during monomorphization
}
```

Instead you *should* be able to write this:

``` rust
fn foo<F>(x: uint, mut f: F) -> bool where F: FnMut(uint) -> bool {
    foo(x / 2, &mut f) && f(x)
    //~^ error: the trait `FnMut` is not implemented for the type `&mut F`
}
```

But as you see above `&mut F` doesn't implement the `FnMut` trait. `&mut F` *should* implement the `FnMut` and the above code *should* work, but due to a bug (see #18835) it doesn't (for now).

You can work around the issue by rewriting the function to take `&mut F` instead of `F`:

``` rust
fn foo<F>(x: uint, f: &mut F) -> bool where F: FnMut(uint) -> bool {
    foo(x / 2, f) && (*f)(x)
}
```

This finally works! However writing `foo(0, &mut |x| x == 0)` is unergonomic. So you can use a private helper function to avoid this:

``` rust
// public API function
pub fn foo<F>(x: uint, mut f: F) -> bool where F: FnMut(uint) -> bool {
    foo_(x, &mut f)
}

// private helper function
fn foo_<F>(x: uint, f: &mut F) -> bool where F: FnMut(uint) -> bool {
    foo_(x / 2, f) && (*f)(x)
}
```

Closes #14798

---

There is more cleanup to do: like renaming functions/types from `unboxed_closure` to just `closure`, removing more dead code, simplify functions which now have unused arguments, update the documentation, etc. But that can be done in another PR.

r? @nikomatsakis @aturon (You probably want to focus on the deleted/modified tests.)
cc @eddyb
2015-01-05 23:51:00 +00:00
Steve Klabnik
f031671c6e Remove i suffix in docs 2015-01-05 17:35:16 -05:00
Aaron Turon
c6f4a03d12 Stabilization of impls and fallout from stabilization 2015-01-05 14:26:04 -08:00
Jorge Aparicio
eb2506cc1b remove more stage0 stuff 2015-01-05 17:22:18 -05:00
Jorge Aparicio
97f870a1fc unignore and fix doctests in guide and reference 2015-01-05 17:22:18 -05:00
Jorge Aparicio
a55011e788 fix tests 2015-01-05 17:22:18 -05:00
Jorge Aparicio
ec11f66dbf replace f.call_mut(a, b, ..) with f(a, b, ..) 2015-01-05 17:22:18 -05:00
Niko Matsakis
c98814b124 Correctly "detuple" arguments when creating trait object shims for a trait method with rust-call ABI. 2015-01-05 17:22:18 -05:00
Niko Matsakis
f97b124a44 Fix ICE caused by forgotten bcx 2015-01-05 17:22:18 -05:00
Jorge Aparicio
79af277623 address Niko's comments 2015-01-05 17:22:17 -05:00
Jorge Aparicio
ab0c7af376 ignore boxed closure doctests in the guide/reference 2015-01-05 17:22:17 -05:00
Jorge Aparicio
a9ea4d0127 fix benchmarks 2015-01-05 17:22:17 -05:00
Jorge Aparicio
ef726591f8 fix debuginfo tests 2015-01-05 17:22:17 -05:00
Jorge Aparicio
1bbeb37582 fix pretty tests 2015-01-05 17:22:17 -05:00
Jorge Aparicio
d6a948e8f4 fix run-make test 2015-01-05 17:22:17 -05:00
Jorge Aparicio
7d5b0454e9 fix cfail tests 2015-01-05 17:22:17 -05:00
Jorge Aparicio
ca17d08126 fix rpass tests 2015-01-05 17:22:16 -05:00
Jorge Aparicio
8d0d7521d6 typeck: remove dead code 2015-01-05 17:22:16 -05:00
Jorge Aparicio
643826150b trans: remove dead code 2015-01-05 17:22:16 -05:00
Jorge Aparicio
5d6a6f5957 rustc: remove dead code 2015-01-05 17:22:16 -05:00
Jorge Aparicio
799332fa3f syntax: remove dead code 2015-01-05 17:22:16 -05:00
Jorge Aparicio
f258ee7d96 typeck: there are only unboxed closures now 2015-01-05 17:22:16 -05:00
Jorge Aparicio
58b0d7479f syntax: make the closure type f: |uint| -> bool syntax obsolete 2015-01-05 17:22:16 -05:00
Jorge Aparicio
865aabb662 trans: remove Closure 2015-01-05 17:22:15 -05:00
Jorge Aparicio
8a6d7a68b1 remove mk_closure 2015-01-05 17:22:15 -05:00
Jorge Aparicio
4e9c50e081 remove AdjustAddEnv 2015-01-05 17:22:15 -05:00
Jorge Aparicio
714a5b7f5e remove TyClosure 2015-01-05 17:22:15 -05:00
Jorge Aparicio
5f7f2c9a05 remove ty_closure 2015-01-05 17:22:15 -05:00
Jorge Aparicio
18e2026ff8 coretest: remove/ignore tests 2015-01-05 17:22:15 -05:00
Jorge Aparicio
37448506ea compiletest: remove boxed closures 2015-01-05 17:22:14 -05:00
Jorge Aparicio
b4ccc90166 driver: remove unboxed closures 2015-01-05 17:22:14 -05:00
Jorge Aparicio
bf52e262e2 trans: remove remaining boxed closures 2015-01-05 17:22:14 -05:00
Jorge Aparicio
977e151b9a typeck: remove remaining boxed closures 2015-01-05 17:22:14 -05:00
Jorge Aparicio
8570f0acc7 rustc: remove remaining boxed closures 2015-01-05 17:22:13 -05:00
Jorge Aparicio
0cb34a3609 EncodeInlinedItem: convert to "unboxed" closures 2015-01-05 17:22:13 -05:00
Jorge Aparicio
bd9eef7ac6 DecodeInlinedItem: convert to "unboxed" closures 2015-01-05 17:22:13 -05:00
Jorge Aparicio
98fda878d8 conv_did: convert to "unboxed" closure 2015-01-05 17:22:12 -05:00
Jorge Aparicio
07a8e7cfb5 syntax: remove remaining boxed closures 2015-01-05 17:22:12 -05:00
Jorge Aparicio
37f62ae1c0 std: remove remaining boxed closures 2015-01-05 17:22:12 -05:00
Jorge Aparicio
a291a80fbe register snapshot 2015-01-05 17:22:11 -05:00
Niko Matsakis
6e68fd09ed Implement new orphan rule that requires that impls of remote traits meet the following two criteria:
- the self type includes some local type; and,
- type parameters in the self type must be constrained by a local type.

A type parameter is called *constrained* if it appears in some type-parameter of a local type.

Here are some examples that are accepted. In all of these examples, I
assume that `Foo` is a trait defined in another crate. If `Foo` were
defined in the local crate, then all the examples would be legal.

- `impl Foo for LocalType`
- `impl<T> Foo<T> for LocalType` -- T does not appear in Self, so it is OK
- `impl<T> Foo<T> for LocalType<T>` -- T here is constrained by LocalType
- `impl<T> Foo<T> for (LocalType<T>, T)` -- T here is constrained by LocalType

Here are some illegal examples (again, these examples assume that
`Foo` is not local to the current crate):

- `impl Foo for int` -- the Self type is not local
- `impl<T> Foo for T` -- T appears in Self unconstrained by a local type
- `impl<T> Foo for (LocalType, T)` -- T appears in Self unconstrained by a local type

This is a [breaking-change]. For the time being, you can opt out of
the new rules by placing `#[old_orphan_check]` on the trait (and
enabling the feature gate where the trait is defined). Longer term,
you should restructure your traits to avoid the problem. Usually this
means changing the order of parameters so that the "central" type
parameter is in the `Self` position.

As an example of that refactoring, consider the `BorrowFrom` trait:

```rust
pub trait BorrowFrom<Sized? Owned> for Sized? {
    fn borrow_from(owned: &Owned) -> &Self;
}
```

As defined, this trait is commonly implemented for custom pointer
types, such as `Arc`. Those impls follow the pattern:

```rust
impl<T> BorrowFrom<Arc<T>> for T {...}
```

Unfortunately, this impl is illegal because the self type `T` is not
local to the current crate. Therefore, we are going to change the order of the parameters,
so that `BorrowFrom` becomes `Borrow`:

```rust
pub trait Borrow<Sized? Borrowed> for Sized? {
    fn borrow_from(owned: &Self) -> &Borrowed;
}
```

Now the `Arc` impl is written:

```rust
impl<T> Borrow<T> for Arc<T> { ... }
```

This impl is legal because the self type (`Arc<T>`) is local.
2015-01-05 17:17:26 -05:00
Aaron Turon
cb765ce7e1 Stabilize collection modules
The earlier collections stabilization did not cover the modules
themselves. This commit marks as stable those modules whose types have
been stabilized.
2015-01-05 14:08:22 -08:00
Aaron Turon
121f6c6673 Final alpha stabilization of std::slice
Marks as `#[stable]`:

* Various iterator structs for stable methods, e.g. `Chunks` and
  `Windows`.
* The `SliceExt` trait itself.
2015-01-05 14:08:21 -08:00
Aaron Turon
e921afddd8 Stabilize core::ops
This commit marks as stable those parts of `core::ops` that are in their
final planned form: `Drop`, all of the mathematical operators (`Add`,
`Sub`, etc), `Deref`/`DerefMut`. It leaves the `Index*`, `Slice*` and
`Fn*` traits unstable, as they are still undergoing active changes.
2015-01-05 14:01:05 -08:00
Aaron Turon
64ec47c9d2 Final alpha stabilization of core::iter
This commit wraps up the adjustments to the iterator for recent language
changes.

* Moves `rposition` from `ExactSizeIterator` to `IteratorExt` using a
  `where` clause, thereby removing the `ExactSizeIterator:
  DoubleEndedIterator` constraint.

* Merges `MutableDoubleEndedIterator` into `IteratorExt`, renaming
  `reverse_` to `reverse_in_place`.

* Merges `IteratorOrdExt`, `IteratorCloneExt` and `CloneIteratorExt`
  into `IteratorExt` using `where` clauses.

Marks as `#[stable]`:

* the `iter` module itself
* `FromIterator`, `Extend`
* `Iterator`, `IteratorExt`
* `map`
* `filter`
* `filter_map`
* `skip_while`
* `take_while`
* `scan`
* `flat_map`
* `inspect`
* `collect`
* `fold`
* `all`
* `any`
* `find`
* `rposition`
* `max`, `min`
* Various adapter types related to the above methods

Because of the trait merging, this is a:

[breaking-change]
2015-01-05 14:01:05 -08:00
FakeKane
f7f5d0958b removing whitespace 2015-01-05 16:46:46 -05:00