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
This commit is contained in:
bors 2015-01-05 23:51:00 +00:00
commit c7dd3c4d69
331 changed files with 984 additions and 2487 deletions

View File

@ -339,8 +339,9 @@ pub fn is_test(config: &Config, testfile: &Path) -> bool {
return valid;
}
pub fn make_test(config: &Config, testfile: &Path, f: || -> test::TestFn)
-> test::TestDescAndFn {
pub fn make_test<F>(config: &Config, testfile: &Path, f: F) -> test::TestDescAndFn where
F: FnOnce() -> test::TestFn,
{
test::TestDescAndFn {
desc: test::TestDesc {
name: make_test_name(config, testfile),

View File

@ -220,7 +220,9 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
!val
}
fn iter_header(testfile: &Path, it: |&str| -> bool) -> bool {
fn iter_header<F>(testfile: &Path, mut it: F) -> bool where
F: FnMut(&str) -> bool,
{
use std::io::{BufferedReader, File};
let mut rdr = BufferedReader::new(File::open(testfile).unwrap());

View File

@ -1233,12 +1233,14 @@ enum TargetLocation {
ThisDirectory(Path),
}
fn make_compile_args(config: &Config,
props: &TestProps,
extras: Vec<String> ,
xform: |&Config, &Path| -> TargetLocation,
testfile: &Path)
-> ProcArgs {
fn make_compile_args<F>(config: &Config,
props: &TestProps,
extras: Vec<String> ,
xform: F,
testfile: &Path)
-> ProcArgs where
F: FnOnce(&Config, &Path) -> TargetLocation,
{
let xform_file = xform(config, testfile);
let target = if props.force_host {
config.host.as_slice()

View File

@ -537,7 +537,8 @@ computation entirely. This could be done for the example above by adjusting the
`b.iter` call to
```rust
# struct X; impl X { fn iter<T>(&self, _: || -> T) {} } let b = X;
# struct X;
# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
b.iter(|| {
// note lack of `;` (could also use an explicit `return`).
range(0u, 1000).fold(0, |old, new| old ^ new)
@ -552,7 +553,8 @@ argument as used.
extern crate test;
# fn main() {
# struct X; impl X { fn iter<T>(&self, _: || -> T) {} } let b = X;
# struct X;
# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
b.iter(|| {
test::black_box(range(0u, 1000).fold(0, |old, new| old ^ new));
});

View File

@ -4232,7 +4232,7 @@ arguments, really powerful things are possible.
Let's make a closure:
```{rust}
let add_one = |x| { 1 + x };
let add_one = |&: x| { 1 + x };
println!("The sum of 5 plus 1 is {}.", add_one(5));
```
@ -4244,8 +4244,8 @@ binding name and two parentheses, just like we would for a named function.
Let's compare syntax. The two are pretty close:
```{rust}
let add_one = |x: i32| -> i32 { 1 + x };
fn add_one (x: i32) -> i32 { 1 + x }
let add_one = |&: x: i32| -> i32 { 1 + x };
fn add_one (x: i32) -> i32 { 1 + x }
```
As you may have noticed, closures infer their argument and return types, so you
@ -4258,9 +4258,9 @@ this:
```{rust}
fn main() {
let x = 5;
let x: i32 = 5;
let printer = || { println!("x is: {}", x); };
let printer = |&:| { println!("x is: {}", x); };
printer(); // prints "x is: 5"
}
@ -4276,7 +4276,7 @@ defined. The closure borrows any variables it uses, so this will error:
fn main() {
let mut x = 5;
let printer = || { println!("x is: {}", x); };
let printer = |&:| { println!("x is: {}", x); };
x = 6; // error: cannot assign to `x` because it is borrowed
}
@ -4298,12 +4298,12 @@ now. We'll talk about them more in the "Threads" section of the guide.
Closures are most useful as an argument to another function. Here's an example:
```{rust}
fn twice(x: i32, f: |i32| -> i32) -> i32 {
fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
f(x) + f(x)
}
fn main() {
let square = |x: i32| { x * x };
let square = |&: x: i32| { x * x };
twice(5, square); // evaluates to 50
}
@ -4312,15 +4312,15 @@ fn main() {
Let's break the example down, starting with `main`:
```{rust}
let square = |x: i32| { x * x };
let square = |&: x: i32| { x * x };
```
We've seen this before. We make a closure that takes an integer, and returns
its square.
```{rust}
# fn twice(x: i32, f: |i32| -> i32) -> i32 { f(x) + f(x) }
# let square = |x: i32| { x * x };
# fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 { f(x) + f(x) }
# let square = |&: x: i32| { x * x };
twice(5, square); // evaluates to 50
```
@ -4343,8 +4343,8 @@ how the `|i32| -> i32` syntax looks a lot like our definition of `square`
above, if we added the return type in:
```{rust}
let square = |x: i32| -> i32 { x * x };
// |i32| -> i32
let square = |&: x: i32| -> i32 { x * x };
// |i32| -> i32
```
This function takes an `i32` and returns an `i32`.
@ -4358,7 +4358,7 @@ Finally, `twice` returns an `i32` as well.
Okay, let's look at the body of `twice`:
```{rust}
fn twice(x: i32, f: |i32| -> i32) -> i32 {
fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
f(x) + f(x)
}
```
@ -4376,7 +4376,7 @@ If we didn't want to give `square` a name, we could just define it inline.
This example is the same as the previous one:
```{rust}
fn twice(x: i32, f: |i32| -> i32) -> i32 {
fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
f(x) + f(x)
}
@ -4389,7 +4389,7 @@ A named function's name can be used wherever you'd use a closure. Another
way of writing the previous example:
```{rust}
fn twice(x: i32, f: |i32| -> i32) -> i32 {
fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
f(x) + f(x)
}

View File

@ -1563,7 +1563,7 @@ functions](#generic-functions).
trait Seq<T> {
fn len(&self) -> uint;
fn elt_at(&self, n: uint) -> T;
fn iter(&self, |T|);
fn iter<F>(&self, F) where F: Fn(T);
}
```
@ -3218,7 +3218,7 @@ In this example, we define a function `ten_times` that takes a higher-order
function argument, and call it with a lambda expression as an argument.
```
fn ten_times(f: |int|) {
fn ten_times<F>(f: F) where F: Fn(int) {
let mut i = 0;
while i < 10 {
f(i);
@ -3828,7 +3828,7 @@ fn add(x: int, y: int) -> int {
let mut x = add(5,7);
type Binop<'a> = |int,int|: 'a -> int;
type Binop = fn(int, int) -> int;
let bo: Binop = add;
x = bo(5,7);
```
@ -3852,14 +3852,14 @@ An example of creating and calling a closure:
```rust
let captured_var = 10i;
let closure_no_args = || println!("captured_var={}", captured_var);
let closure_no_args = |&:| println!("captured_var={}", captured_var);
let closure_args = |arg: int| -> int {
let closure_args = |&: arg: int| -> int {
println!("captured_var={}, arg={}", captured_var, arg);
arg // Note lack of semicolon after 'arg'
};
fn call_closure(c1: ||, c2: |int| -> int) {
fn call_closure<F: Fn(), G: Fn(int) -> int>(c1: F, c2: G) {
c1();
c2(2);
}

View File

@ -164,21 +164,6 @@ pub struct Bitv {
nbits: uint
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
// FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
impl Index<uint,bool> for Bitv {
#[inline]
fn index(&self, i: &uint) -> &bool {
if self.get(*i).expect("index out of bounds") {
&TRUE
} else {
&FALSE
}
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
// FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
impl Index<uint> for Bitv {
type Output = bool;

View File

@ -877,18 +877,6 @@ impl<K: Show, V: Show> Show for BTreeMap<K, V> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<K: Ord, Sized? Q, V> Index<Q, V> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
{
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<K: Ord, Sized? Q, V> Index<Q> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
@ -900,18 +888,6 @@ impl<K: Ord, Sized? Q, V> Index<Q> for BTreeMap<K, V>
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<K: Ord, Sized? Q, V> IndexMut<Q, V> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
{
fn index_mut(&mut self, key: &Q) -> &mut V {
self.get_mut(key).expect("no entry found for key")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<K: Ord, Sized? Q, V> IndexMut<Q> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord

View File

@ -1360,17 +1360,6 @@ impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<A> Index<uint, A> for RingBuf<A> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a A {
self.get(*i).expect("Out of bounds access")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<A> Index<uint> for RingBuf<A> {
type Output = A;
@ -1381,17 +1370,6 @@ impl<A> Index<uint> for RingBuf<A> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<A> IndexMut<uint, A> for RingBuf<A> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
self.get_mut(*i).expect("Out of bounds access")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<A> IndexMut<uint> for RingBuf<A> {
type Output = A;

View File

@ -1190,17 +1190,6 @@ impl<S: hash::Writer, T: Hash<S>> Hash<S> for Vec<T> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[experimental = "waiting on Index stability"]
impl<T> Index<uint,T> for Vec<T> {
#[inline]
fn index<'a>(&'a self, index: &uint) -> &'a T {
&self.as_slice()[*index]
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[experimental = "waiting on Index stability"]
impl<T> Index<uint> for Vec<T> {
type Output = T;
@ -1211,16 +1200,6 @@ impl<T> Index<uint> for Vec<T> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> IndexMut<uint,T> for Vec<T> {
#[inline]
fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
&mut self.as_mut_slice()[*index]
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> IndexMut<uint> for Vec<T> {
type Output = T;

View File

@ -517,17 +517,6 @@ impl<V> Extend<(uint, V)> for VecMap<V> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<V> Index<uint, V> for VecMap<V> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a V {
self.get(i).expect("key not present")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<V> Index<uint> for VecMap<V> {
type Output = V;
@ -537,17 +526,6 @@ impl<V> Index<uint> for VecMap<V> {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<V> IndexMut<uint, V> for VecMap<V> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V {
self.get_mut(i).expect("key not present")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<V> IndexMut<uint> for VecMap<V> {
type Output = V;

View File

@ -717,15 +717,6 @@ macro_rules! shr_impl {
shr_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
// NOTE(stage0) remove trait after a snapshot
#[cfg(stage0)]
#[allow(missing_docs)]
#[lang="index"]
pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
}
/// The `Index` trait is used to specify the functionality of indexing operations
/// like `arr[idx]` when used in an immutable context.
///
@ -755,7 +746,6 @@ pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// Foo[Foo];
/// }
/// ```
#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
#[lang="index"]
pub trait Index<Sized? Index> for Sized? {
type Sized? Output;
@ -764,15 +754,6 @@ pub trait Index<Sized? Index> for Sized? {
fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
}
// NOTE(stage0) remove trait after a snapshot
#[cfg(stage0)]
#[allow(missing_docs)]
#[lang="index_mut"]
pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
}
/// The `IndexMut` trait is used to specify the functionality of indexing
/// operations like `arr[idx]`, when used in a mutable context.
///
@ -802,7 +783,6 @@ pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
/// &mut Foo[Foo];
/// }
/// ```
#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
#[lang="index_mut"]
pub trait IndexMut<Sized? Index> for Sized? {
type Sized? Output;

View File

@ -531,17 +531,6 @@ impl<T> SliceExt for [T] {
}
}
// NOTE(stage0) remove impl after a snapshot
#[cfg(stage0)]
impl<T> ops::Index<uint, T> for [T] {
fn index(&self, &index: &uint) -> &T {
assert!(index < self.len());
unsafe { mem::transmute(self.repr().data.offset(index as int)) }
}
}
#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
impl<T> ops::Index<uint> for [T] {
type Output = T;
@ -552,17 +541,6 @@ impl<T> ops::Index<uint> for [T] {
}
}
// NOTE(stage0) remove impl after a snapshot
#[cfg(stage0)]
impl<T> ops::IndexMut<uint, T> for [T] {
fn index_mut(&mut self, &index: &uint) -> &mut T {
assert!(index < self.len());
unsafe { mem::transmute(self.repr().data.offset(index as int)) }
}
}
#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
impl<T> ops::IndexMut<uint> for [T] {
type Output = T;

View File

@ -30,7 +30,6 @@ mod num;
mod ops;
mod option;
mod ptr;
mod raw;
mod result;
mod slice;
mod str;

View File

@ -220,6 +220,7 @@ fn test_ord() {
assert!(big > None);
}
/* FIXME(#20575)
#[test]
fn test_collect() {
let v: Option<Vec<int>> = range(0i, 0).map(|_| Some(0i)).collect();
@ -234,12 +235,14 @@ fn test_collect() {
assert!(v == None);
// test that it does not take more elements than it needs
let mut functions = [|| Some(()), || None, || panic!()];
let mut functions: [Box<Fn() -> Option<()>>; 3] =
[box || Some(()), box || None, box || panic!()];
let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
assert!(v == None);
}
*/
#[test]
fn test_cloned() {

View File

@ -1,35 +0,0 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::raw::*;
use core::mem;
#[test]
fn synthesize_closure() {
unsafe {
let x = 10;
let f: |int| -> int = |y| x + y;
assert_eq!(f(20), 30);
let original_closure: Closure = mem::transmute(f);
let actual_function_pointer = original_closure.code;
let environment = original_closure.env;
let new_closure = Closure {
code: actual_function_pointer,
env: environment
};
let new_f: |int| -> int = mem::transmute(new_closure);
assert_eq!(new_f(20), 30);
}
}

View File

@ -67,6 +67,7 @@ pub fn test_impl_map_err() {
assert!(Err::<int, int>(1).map_err(|x| x + 1) == Err(2));
}
/* FIXME(#20575)
#[test]
fn test_collect() {
let v: Result<Vec<int>, ()> = range(0i, 0).map(|_| Ok::<int, ()>(0)).collect();
@ -81,11 +82,13 @@ fn test_collect() {
assert!(v == Err(2));
// test that it does not take more elements than it needs
let mut functions = [|| Ok(()), || Err(1i), || panic!()];
let mut functions: [Box<Fn() -> Result<(), int>>; 3] =
[box || Ok(()), box || Err(1i), box || panic!()];
let v: Result<Vec<()>, int> = functions.iter_mut().map(|f| (*f)()).collect();
assert!(v == Err(1));
}
*/
#[test]
pub fn test_fmt_default() {

View File

@ -494,11 +494,7 @@ impl BoxPointers {
let mut n_uniq = 0i;
ty::fold_ty(cx.tcx, ty, |t| {
match t.sty {
ty::ty_uniq(_) |
ty::ty_closure(box ty::ClosureTy {
store: ty::UniqTraitStore,
..
}) => {
ty::ty_uniq(_) => {
n_uniq += 1;
}

View File

@ -662,27 +662,27 @@ pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec<ast_map::PathElem> {
item_path(lookup_item(id, cdata.data()))
}
pub type DecodeInlinedItem<'a> = for<'tcx> |cdata: Cmd,
tcx: &ty::ctxt<'tcx>,
path: Vec<ast_map::PathElem>,
par_doc: rbml::Doc|: 'a
-> Result<&'tcx ast::InlinedItem,
Vec<ast_map::PathElem>>;
pub type DecodeInlinedItem<'a> =
Box<for<'tcx> FnMut(Cmd,
&ty::ctxt<'tcx>,
Vec<ast_map::PathElem>,
rbml::Doc)
-> Result<&'tcx ast::InlinedItem, Vec<ast_map::PathElem>> + 'a>;
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeId,
decode_inlined_item: DecodeInlinedItem)
mut decode_inlined_item: DecodeInlinedItem)
-> csearch::found_ast<'tcx> {
debug!("Looking up item: {}", id);
let item_doc = lookup_item(id, cdata.data());
let path = item_path(item_doc).init().to_vec();
match decode_inlined_item(cdata, tcx, path, item_doc) {
match decode_inlined_item.call_mut((cdata, tcx, path, item_doc)) {
Ok(ii) => csearch::found(ii),
Err(path) => {
match item_parent_item(item_doc) {
Some(did) => {
let did = translate_def_id(cdata, did);
let parent_item = lookup_item(did.node, cdata.data());
match decode_inlined_item(cdata, tcx, path, parent_item) {
match decode_inlined_item.call_mut((cdata, tcx, path, parent_item)) {
Ok(ii) => csearch::found_parent(did, ii),
Err(_) => csearch::not_found
}

View File

@ -59,9 +59,8 @@ pub enum InlinedItemRef<'a> {
pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
rbml_w: &mut Encoder,
ii: InlinedItemRef|: 'a;
pub type EncodeInlinedItem<'a> =
Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
pub struct EncodeParams<'a, 'tcx: 'a> {
pub diag: &'a SpanHandler,
@ -953,7 +952,7 @@ fn encode_inlined_item(ecx: &EncodeContext,
ii: InlinedItemRef) {
let mut eii = ecx.encode_inlined_item.borrow_mut();
let eii: &mut EncodeInlinedItem = &mut *eii;
(*eii)(ecx, rbml_w, ii)
eii.call_mut((ecx, rbml_w, ii))
}
const FN_FAMILY: char = 'f';

View File

@ -61,8 +61,7 @@ pub enum DefIdSource {
UnboxedClosureSource
}
pub type conv_did<'a> =
|source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
// type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId;
pub struct PState<'a, 'tcx: 'a> {
data: &'a [u8],
@ -145,70 +144,88 @@ fn data_log_string(data: &[u8], pos: uint) -> String {
buf
}
pub fn parse_ty_closure_data<'tcx>(data: &[u8],
crate_num: ast::CrateNum,
pos: uint,
tcx: &ty::ctxt<'tcx>,
conv: conv_did)
-> ty::ClosureTy<'tcx> {
pub fn parse_ty_closure_data<'tcx, F>(data: &[u8],
crate_num: ast::CrateNum,
pos: uint,
tcx: &ty::ctxt<'tcx>,
conv: F)
-> ty::ClosureTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_closure_ty(&mut st, conv)
}
pub fn parse_ty_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: conv_did) -> Ty<'tcx> {
pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: F) -> Ty<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
debug!("parse_ty_data {}", data_log_string(data, pos));
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_ty(&mut st, conv)
}
pub fn parse_region_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx: &ty::ctxt,
conv: conv_did) -> ty::Region {
pub fn parse_region_data<F>(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx: &ty::ctxt,
conv: F) -> ty::Region where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
debug!("parse_region_data {}", data_log_string(data, pos));
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_region(&mut st, conv)
}
pub fn parse_bare_fn_ty_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: conv_did)
-> ty::BareFnTy<'tcx> {
pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::BareFnTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
debug!("parse_bare_fn_ty_data {}", data_log_string(data, pos));
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_bare_fn_ty(&mut st, conv)
}
pub fn parse_trait_ref_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: conv_did)
-> Rc<ty::TraitRef<'tcx>> {
pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: F)
-> Rc<ty::TraitRef<'tcx>> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
debug!("parse_trait_ref_data {}", data_log_string(data, pos));
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_trait_ref(&mut st, conv)
}
pub fn parse_substs_data<'tcx>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: conv_did) -> subst::Substs<'tcx> {
pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
tcx: &ty::ctxt<'tcx>, conv: F) -> subst::Substs<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
debug!("parse_substs_data {}", data_log_string(data, pos));
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_substs(&mut st, conv)
}
pub fn parse_bounds_data<'tcx>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: conv_did)
-> ty::ParamBounds<'tcx> {
pub fn parse_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::ParamBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_bounds(&mut st, conv)
}
pub fn parse_existential_bounds_data<'tcx>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: conv_did)
-> ty::ExistentialBounds<'tcx> {
pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::ExistentialBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_existential_bounds(&mut st, conv)
}
pub fn parse_builtin_bounds_data(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt, conv: conv_did)
-> ty::BuiltinBounds {
pub fn parse_builtin_bounds_data<F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt, conv: F)
-> ty::BuiltinBounds where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut st = parse_state_from_data(data, crate_num, pos, tcx);
parse_builtin_bounds(&mut st, conv)
}
@ -226,10 +243,12 @@ fn parse_size(st: &mut PState) -> Option<uint> {
}
}
fn parse_trait_store(st: &mut PState, conv: conv_did) -> ty::TraitStore {
fn parse_trait_store_<F>(st: &mut PState, conv: &mut F) -> ty::TraitStore where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
match next(st) {
'~' => ty::UniqTraitStore,
'&' => ty::RegionTraitStore(parse_region(st, conv), parse_mutability(st)),
'&' => ty::RegionTraitStore(parse_region_(st, conv), parse_mutability(st)),
c => {
st.tcx.sess.bug(format!("parse_trait_store(): bad input '{}'",
c)[])
@ -253,31 +272,44 @@ fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>,
r
}
fn parse_substs<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did) -> subst::Substs<'tcx> {
fn parse_substs<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
mut conv: F) -> subst::Substs<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_substs_(st, &mut conv)
}
fn parse_substs_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
conv: &mut F) -> subst::Substs<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let regions =
parse_region_substs(st, |x,y| conv(x,y));
parse_region_substs_(st, conv);
let types =
parse_vec_per_param_space(st, |st| parse_ty(st, |x,y| conv(x,y)));
parse_vec_per_param_space(st, |st| parse_ty_(st, conv));
subst::Substs { types: types,
regions: regions }
}
fn parse_region_substs(st: &mut PState, conv: conv_did) -> subst::RegionSubsts {
fn parse_region_substs_<F>(st: &mut PState, conv: &mut F) -> subst::RegionSubsts where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
match next(st) {
'e' => subst::ErasedRegions,
'n' => {
subst::NonerasedRegions(
parse_vec_per_param_space(
st, |st| parse_region(st, |x,y| conv(x,y))))
st, |st| parse_region_(st, conv)))
}
_ => panic!("parse_bound_region: bad input")
}
}
fn parse_bound_region(st: &mut PState, conv: conv_did) -> ty::BoundRegion {
fn parse_bound_region_<F>(st: &mut PState, conv: &mut F) -> ty::BoundRegion where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
match next(st) {
'a' => {
let id = parse_u32(st);
@ -285,7 +317,7 @@ fn parse_bound_region(st: &mut PState, conv: conv_did) -> ty::BoundRegion {
ty::BrAnon(id)
}
'[' => {
let def = parse_def(st, RegionParameter, |x,y| conv(x,y));
let def = parse_def_(st, RegionParameter, conv);
let ident = token::str_to_ident(parse_str(st, ']')[]);
ty::BrNamed(def, ident.name)
}
@ -299,13 +331,21 @@ fn parse_bound_region(st: &mut PState, conv: conv_did) -> ty::BoundRegion {
}
}
fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
fn parse_region<F>(st: &mut PState, mut conv: F) -> ty::Region where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_region_(st, &mut conv)
}
fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
match next(st) {
'b' => {
assert_eq!(next(st), '[');
let id = ty::DebruijnIndex::new(parse_u32(st));
assert_eq!(next(st), '|');
let br = parse_bound_region(st, |x,y| conv(x,y));
let br = parse_bound_region_(st, conv);
assert_eq!(next(st), ']');
ty::ReLateBound(id, br)
}
@ -324,7 +364,7 @@ fn parse_region(st: &mut PState, conv: conv_did) -> ty::Region {
assert_eq!(next(st), '[');
let scope = parse_scope(st);
assert_eq!(next(st), '|');
let br = parse_bound_region(st, |x,y| conv(x,y));
let br = parse_bound_region_(st, conv);
assert_eq!(next(st), ']');
ty::ReFree(ty::FreeRegion { scope: scope,
bound_region: br})
@ -375,14 +415,31 @@ fn parse_str(st: &mut PState, term: char) -> String {
result
}
fn parse_trait_ref<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
-> Rc<ty::TraitRef<'tcx>> {
let def = parse_def(st, NominalType, |x,y| conv(x,y));
let substs = st.tcx.mk_substs(parse_substs(st, |x,y| conv(x,y)));
fn parse_trait_ref<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> Rc<ty::TraitRef<'tcx>> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_trait_ref_(st, &mut conv)
}
fn parse_trait_ref_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> Rc<ty::TraitRef<'tcx>> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let def = parse_def_(st, NominalType, conv);
let substs = st.tcx.mk_substs(parse_substs_(st, conv));
Rc::new(ty::TraitRef {def_id: def, substs: substs})
}
fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F) -> Ty<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_ty_(st, &mut conv)
}
fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let tcx = st.tcx;
match next(st) {
'b' => return tcx.types.bool,
@ -406,15 +463,15 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
'c' => return tcx.types.char,
't' => {
assert_eq!(next(st), '[');
let def = parse_def(st, NominalType, |x,y| conv(x,y));
let substs = parse_substs(st, |x,y| conv(x,y));
let def = parse_def_(st, NominalType, conv);
let substs = parse_substs_(st, conv);
assert_eq!(next(st), ']');
return ty::mk_enum(tcx, def, st.tcx.mk_substs(substs));
}
'x' => {
assert_eq!(next(st), '[');
let trait_ref = ty::Binder(parse_trait_ref(st, |x,y| conv(x,y)));
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
let trait_ref = ty::Binder(parse_trait_ref_(st, conv));
let bounds = parse_existential_bounds_(st, conv);
assert_eq!(next(st), ']');
return ty::mk_trait(tcx, trait_ref, bounds);
}
@ -427,15 +484,15 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
let name = token::intern(parse_str(st, ']')[]);
return ty::mk_param(tcx, space, index, name);
}
'~' => return ty::mk_uniq(tcx, parse_ty(st, |x,y| conv(x,y))),
'*' => return ty::mk_ptr(tcx, parse_mt(st, |x,y| conv(x,y))),
'~' => return ty::mk_uniq(tcx, parse_ty_(st, conv)),
'*' => return ty::mk_ptr(tcx, parse_mt_(st, conv)),
'&' => {
let r = parse_region(st, |x,y| conv(x,y));
let mt = parse_mt(st, |x,y| conv(x,y));
let r = parse_region_(st, conv);
let mt = parse_mt_(st, conv);
return ty::mk_rptr(tcx, tcx.mk_region(r), mt);
}
'V' => {
let t = parse_ty(st, |x,y| conv(x,y));
let t = parse_ty_(st, conv);
let sz = parse_size(st);
return ty::mk_vec(tcx, t, sz);
}
@ -445,21 +502,18 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
'T' => {
assert_eq!(next(st), '[');
let mut params = Vec::new();
while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); }
while peek(st) != ']' { params.push(parse_ty_(st, conv)); }
st.pos = st.pos + 1u;
return ty::mk_tup(tcx, params);
}
'f' => {
return ty::mk_closure(tcx, parse_closure_ty(st, |x,y| conv(x,y)));
}
'F' => {
let def_id = parse_def(st, NominalType, |x,y| conv(x,y));
let def_id = parse_def_(st, NominalType, conv);
return ty::mk_bare_fn(tcx, Some(def_id),
tcx.mk_bare_fn(parse_bare_fn_ty(st, |x,y| conv(x,y))));
tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv)));
}
'G' => {
return ty::mk_bare_fn(tcx, None,
tcx.mk_bare_fn(parse_bare_fn_ty(st, |x,y| conv(x,y))));
tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv)));
}
'#' => {
let pos = parse_hex(st);
@ -478,34 +532,34 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
pos: pos,
.. *st
};
let tt = parse_ty(&mut ps, |x,y| conv(x,y));
let tt = parse_ty_(&mut ps, conv);
tcx.rcache.borrow_mut().insert(key, tt);
return tt;
}
'\"' => {
let _ = parse_def(st, TypeWithId, |x,y| conv(x,y));
let inner = parse_ty(st, |x,y| conv(x,y));
let _ = parse_def_(st, TypeWithId, conv);
let inner = parse_ty_(st, conv);
inner
}
'a' => {
assert_eq!(next(st), '[');
let did = parse_def(st, NominalType, |x,y| conv(x,y));
let substs = parse_substs(st, |x,y| conv(x,y));
let did = parse_def_(st, NominalType, conv);
let substs = parse_substs_(st, conv);
assert_eq!(next(st), ']');
return ty::mk_struct(st.tcx, did, st.tcx.mk_substs(substs));
}
'k' => {
assert_eq!(next(st), '[');
let did = parse_def(st, UnboxedClosureSource, |x,y| conv(x,y));
let region = parse_region(st, |x,y| conv(x,y));
let substs = parse_substs(st, |x,y| conv(x,y));
let did = parse_def_(st, UnboxedClosureSource, conv);
let region = parse_region_(st, conv);
let substs = parse_substs_(st, conv);
assert_eq!(next(st), ']');
return ty::mk_unboxed_closure(st.tcx, did,
st.tcx.mk_region(region), st.tcx.mk_substs(substs));
}
'P' => {
assert_eq!(next(st), '[');
let trait_ref = parse_trait_ref(st, |x,y| conv(x,y));
let trait_ref = parse_trait_ref_(st, conv);
let name = token::intern(parse_str(st, ']').as_slice());
return ty::mk_projection(tcx, trait_ref, name);
}
@ -523,14 +577,17 @@ fn parse_mutability(st: &mut PState) -> ast::Mutability {
}
}
fn parse_mt<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::mt<'tcx> {
fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let m = parse_mutability(st);
ty::mt { ty: parse_ty(st, |x,y| conv(x,y)), mutbl: m }
ty::mt { ty: parse_ty_(st, conv), mutbl: m }
}
fn parse_def(st: &mut PState, source: DefIdSource,
conv: conv_did) -> ast::DefId {
return conv(source, scan(st, |c| { c == '|' }, parse_def_id));
fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
}
fn parse_uint(st: &mut PState) -> uint {
@ -592,13 +649,22 @@ fn parse_onceness(c: char) -> ast::Onceness {
}
}
fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did) -> ty::ClosureTy<'tcx> {
fn parse_closure_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
mut conv: F) -> ty::ClosureTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_closure_ty_(st, &mut conv)
}
fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
conv: &mut F) -> ty::ClosureTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let unsafety = parse_unsafety(next(st));
let onceness = parse_onceness(next(st));
let store = parse_trait_store(st, |x,y| conv(x,y));
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
let sig = parse_sig(st, |x,y| conv(x,y));
let store = parse_trait_store_(st, conv);
let bounds = parse_existential_bounds_(st, conv);
let sig = parse_sig_(st, conv);
let abi = parse_abi_set(st);
ty::ClosureTy {
unsafety: unsafety,
@ -610,11 +676,20 @@ fn parse_closure_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
}
}
fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did) -> ty::BareFnTy<'tcx> {
fn parse_bare_fn_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
mut conv: F) -> ty::BareFnTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_bare_fn_ty_(st, &mut conv)
}
fn parse_bare_fn_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>,
conv: &mut F) -> ty::BareFnTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let unsafety = parse_unsafety(next(st));
let abi = parse_abi_set(st);
let sig = parse_sig(st, |x,y| conv(x,y));
let sig = parse_sig_(st, conv);
ty::BareFnTy {
unsafety: unsafety,
abi: abi,
@ -622,11 +697,13 @@ fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
}
}
fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::PolyFnSig<'tcx> {
fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::PolyFnSig<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
assert_eq!(next(st), '[');
let mut inputs = Vec::new();
while peek(st) != ']' {
inputs.push(parse_ty(st, |x,y| conv(x,y)));
inputs.push(parse_ty_(st, conv));
}
st.pos += 1u; // eat the ']'
let variadic = match next(st) {
@ -639,7 +716,7 @@ fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::PolyFnS
st.pos += 1u;
ty::FnDiverging
}
_ => ty::FnConverging(parse_ty(st, |x,y| conv(x,y)))
_ => ty::FnConverging(parse_ty_(st, conv))
};
ty::Binder(ty::FnSig {inputs: inputs,
output: output,
@ -672,66 +749,87 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
ast::DefId { krate: crate_num, node: def_num }
}
pub fn parse_predicate_data<'tcx>(data: &[u8],
start: uint,
crate_num: ast::CrateNum,
tcx: &ty::ctxt<'tcx>,
conv: conv_did)
-> ty::Predicate<'tcx>
pub fn parse_predicate_data<'tcx, F>(data: &[u8],
start: uint,
crate_num: ast::CrateNum,
tcx: &ty::ctxt<'tcx>,
conv: F)
-> ty::Predicate<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut st = parse_state_from_data(data, crate_num, start, tcx);
parse_predicate(&mut st, conv)
}
pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
conv: conv_did)
-> ty::Predicate<'tcx>
pub fn parse_predicate<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
mut conv: F)
-> ty::Predicate<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_predicate_(st, &mut conv)
}
fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>,
conv: &mut F)
-> ty::Predicate<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
match next(st) {
't' => ty::Binder(parse_trait_ref(st, conv)).as_predicate(),
'e' => ty::Binder(ty::EquatePredicate(parse_ty(st, |x,y| conv(x,y)),
parse_ty(st, |x,y| conv(x,y)))).as_predicate(),
'r' => ty::Binder(ty::OutlivesPredicate(parse_region(st, |x,y| conv(x,y)),
parse_region(st, |x,y| conv(x,y)))).as_predicate(),
'o' => ty::Binder(ty::OutlivesPredicate(parse_ty(st, |x,y| conv(x,y)),
parse_region(st, |x,y| conv(x,y)))).as_predicate(),
'p' => ty::Binder(parse_projection_predicate(st, conv)).as_predicate(),
't' => ty::Binder(parse_trait_ref_(st, conv)).as_predicate(),
'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv),
parse_ty_(st, conv))).as_predicate(),
'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv),
parse_region_(st, conv))).as_predicate(),
'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv),
parse_region_(st, conv))).as_predicate(),
'p' => ty::Binder(parse_projection_predicate_(st, conv)).as_predicate(),
c => panic!("Encountered invalid character in metadata: {}", c)
}
}
fn parse_projection_predicate<'a,'tcx>(
fn parse_projection_predicate_<'a,'tcx, F>(
st: &mut PState<'a, 'tcx>,
conv: conv_did)
-> ty::ProjectionPredicate<'tcx>
conv: &mut F,
) -> ty::ProjectionPredicate<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
trait_ref: parse_trait_ref(st, |x,y| conv(x,y)),
trait_ref: parse_trait_ref_(st, conv),
item_name: token::str_to_ident(parse_str(st, '|').as_slice()).name,
},
ty: parse_ty(st, |x,y| conv(x,y)),
ty: parse_ty_(st, conv),
}
}
pub fn parse_type_param_def_data<'tcx>(data: &[u8], start: uint,
crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
conv: conv_did) -> ty::TypeParameterDef<'tcx>
pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: uint,
crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
conv: F) -> ty::TypeParameterDef<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut st = parse_state_from_data(data, crate_num, start, tcx);
parse_type_param_def(&mut st, conv)
}
fn parse_type_param_def<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
-> ty::TypeParameterDef<'tcx> {
fn parse_type_param_def<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::TypeParameterDef<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_type_param_def_(st, &mut conv)
}
fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::TypeParameterDef<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let name = parse_name(st, ':');
let def_id = parse_def(st, NominalType, |x,y| conv(x,y));
let def_id = parse_def_(st, NominalType, conv);
let space = parse_param_space(st);
assert_eq!(next(st), '|');
let index = parse_u32(st);
assert_eq!(next(st), '|');
let bounds = parse_bounds(st, |x,y| conv(x,y));
let default = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)));
let bounds = parse_bounds_(st, conv);
let default = parse_opt(st, |st| parse_ty_(st, conv));
ty::TypeParameterDef {
name: name,
@ -743,12 +841,21 @@ fn parse_type_param_def<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
}
}
fn parse_existential_bounds<'a,'tcx>(st: &mut PState<'a,'tcx>,
conv: conv_did)
-> ty::ExistentialBounds<'tcx>
fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
mut conv: F)
-> ty::ExistentialBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_existential_bounds_(st, &mut conv)
}
fn parse_existential_bounds_<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
conv: &mut F)
-> ty::ExistentialBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let ty::ParamBounds { trait_bounds, mut region_bounds, builtin_bounds, projection_bounds } =
parse_bounds(st, conv);
parse_bounds_(st, conv);
assert_eq!(region_bounds.len(), 1);
assert_eq!(trait_bounds.len(), 0);
let region_bound = region_bounds.pop().unwrap();
@ -757,7 +864,15 @@ fn parse_existential_bounds<'a,'tcx>(st: &mut PState<'a,'tcx>,
projection_bounds: projection_bounds };
}
fn parse_builtin_bounds(st: &mut PState, _conv: conv_did) -> ty::BuiltinBounds {
fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F) -> ty::BuiltinBounds where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_builtin_bounds_(st, &mut _conv)
}
fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F) -> ty::BuiltinBounds where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let mut builtin_bounds = ty::empty_builtin_bounds();
loop {
@ -784,9 +899,18 @@ fn parse_builtin_bounds(st: &mut PState, _conv: conv_did) -> ty::BuiltinBounds {
}
}
fn parse_bounds<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
-> ty::ParamBounds<'tcx> {
let builtin_bounds = parse_builtin_bounds(st, |x,y| conv(x,y));
fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::ParamBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
parse_bounds_(st, &mut conv)
}
fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::ParamBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let builtin_bounds = parse_builtin_bounds_(st, conv);
let mut param_bounds = ty::ParamBounds {
region_bounds: Vec::new(),
@ -798,15 +922,15 @@ fn parse_bounds<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
match next(st) {
'R' => {
param_bounds.region_bounds.push(
parse_region(st, |x, y| conv (x, y)));
parse_region_(st, conv));
}
'I' => {
param_bounds.trait_bounds.push(
ty::Binder(parse_trait_ref(st, |x,y| conv(x,y))));
ty::Binder(parse_trait_ref_(st, conv)));
}
'P' => {
param_bounds.projection_bounds.push(
ty::Binder(parse_projection_predicate(st, |x,y| conv(x,y))));
ty::Binder(parse_projection_predicate_(st, conv)));
}
'.' => {
return param_bounds;

View File

@ -119,10 +119,6 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
ty::ty_str => {
mywrite!(w, "v");
}
ty::ty_closure(ref f) => {
mywrite!(w, "f");
enc_closure_ty(w, cx, &**f);
}
ty::ty_bare_fn(Some(def_id), f) => {
mywrite!(w, "F");
mywrite!(w, "{}|", (cx.ds)(def_id));

View File

@ -1031,13 +1031,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
self.emit_enum("AutoAdjustment", |this| {
match *adj {
ty::AdjustAddEnv(def_id, store) => {
this.emit_enum_variant("AdjustAddEnv", 0, 2, |this| {
this.emit_enum_variant_arg(0, |this| def_id.encode(this));
this.emit_enum_variant_arg(1, |this| store.encode(this))
})
}
ty::AdjustReifyFnPointer(def_id) => {
this.emit_enum_variant("AdjustReifyFnPointer", 1, 2, |this| {
this.emit_enum_variant_arg(0, |this| def_id.encode(this))
@ -1678,14 +1671,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
let variants = ["AutoAddEnv", "AutoDerefRef"];
this.read_enum_variant(&variants, |this, i| {
Ok(match i {
0 => {
let def_id: ast::DefId =
this.read_def_id(dcx);
let store: ty::TraitStore =
this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
ty::AdjustAddEnv(def_id, store.tr(dcx))
}
1 => {
let def_id: ast::DefId =
this.read_def_id(dcx);

View File

@ -132,7 +132,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
None => {}
}
let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
csearch::found(&ast::IIItem(ref item)) => match item.node {
ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
// NOTE this doesn't do the right thing, it compares inlined
@ -172,7 +172,7 @@ pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
None => {}
}
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
csearch::found(&ast::IIItem(ref item)) => match item.node {
ast::ItemConst(_, ref const_expr) => Some(const_expr.id),
_ => None

View File

@ -33,7 +33,6 @@ enum UnsafeContext {
fn type_is_unsafe_function(ty: Ty) -> bool {
match ty.sty {
ty::ty_bare_fn(_, ref f) => f.unsafety == ast::Unsafety::Unsafe,
ty::ty_closure(ref f) => f.unsafety == ast::Unsafety::Unsafe,
_ => false,
}
}

View File

@ -656,19 +656,6 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
ty::ty_bare_fn(..) => {
self.consume_expr(callee);
}
ty::ty_closure(ref f) => {
match f.onceness {
ast::Many => {
self.borrow_expr(callee,
ty::ReScope(call_scope),
ty::UniqueImmBorrow,
ClosureInvocation);
}
ast::Once => {
self.consume_expr(callee);
}
}
}
ty::ty_err => { }
_ => {
let overloaded_call_type =
@ -836,7 +823,6 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
None => { }
Some(adjustment) => {
match *adjustment {
ty::AdjustAddEnv(..) |
ty::AdjustReifyFnPointer(..) => {
// Creating a closure/fn-pointer consumes the
// input and stores it into the resulting

View File

@ -80,9 +80,6 @@ pub fn simplify_type(tcx: &ty::ctxt,
ty::ty_tup(ref tys) => {
Some(TupleSimplifiedType(tys.len()))
}
ty::ty_closure(ref f) => {
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
}
ty::ty_bare_fn(_, ref f) => {
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
}

View File

@ -71,7 +71,6 @@ use middle::ty::{self, Ty};
use util::ppaux;
use util::ppaux::Repr;
use syntax::abi;
use syntax::ast;
// Note: Coerce is not actually a combiner, in that it does not
@ -160,15 +159,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
};
}
ty::ty_closure(box ty::ClosureTy {
store: ty::RegionTraitStore(..),
..
}) => {
return self.unpack_actual_value(a, |a| {
self.coerce_borrowed_fn(a, b)
});
}
_ => {}
}
@ -511,21 +501,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
a.repr(self.tcx()), b.repr(self.tcx()));
match b.sty {
ty::ty_closure(ref f) => {
if fn_ty_a.abi != abi::Rust || fn_ty_a.unsafety != ast::Unsafety::Normal {
return self.subtype(a, b);
}
let fn_ty_b = (*f).clone();
let adj = ty::AdjustAddEnv(fn_def_id_a, fn_ty_b.store);
let a_closure = ty::mk_closure(self.tcx(),
ty::ClosureTy {
sig: fn_ty_a.sig.clone(),
.. *fn_ty_b
});
try!(self.subtype(a_closure, b));
Ok(Some(adj))
}
ty::ty_bare_fn(None, _) => {
let a_fn_pointer = ty::mk_bare_fn(self.tcx(), None, fn_ty_a);
try!(self.subtype(a_fn_pointer, b));

View File

@ -644,12 +644,6 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
Ok(ty::mk_bare_fn(tcx, a_opt_def_id, tcx.mk_bare_fn(fty)))
}
(&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
this.closure_tys(&**a_fty, &**b_fty).and_then(|fty| {
Ok(ty::mk_closure(tcx, fty))
})
}
(&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => {
let projection_ty = try!(this.projection_tys(a_data, b_data));
Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name))

View File

@ -152,7 +152,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
ty::ty_ptr(..) |
ty::ty_rptr(..) |
ty::ty_bare_fn(..) |
ty::ty_closure(..) |
ty::ty_trait(..) |
ty::ty_struct(..) |
ty::ty_unboxed_closure(..) |

View File

@ -197,8 +197,7 @@ pub enum deref_kind {
// pointer adjustment).
pub fn deref_kind(t: Ty) -> McResult<deref_kind> {
match t.sty {
ty::ty_uniq(_) |
ty::ty_closure(box ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
ty::ty_uniq(_) => {
Ok(deref_ptr(Unique))
}
@ -207,13 +206,6 @@ pub fn deref_kind(t: Ty) -> McResult<deref_kind> {
Ok(deref_ptr(BorrowedPtr(kind, *r)))
}
ty::ty_closure(box ty::ClosureTy {
store: ty::RegionTraitStore(r, _),
..
}) => {
Ok(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
}
ty::ty_ptr(ref mt) => {
Ok(deref_ptr(UnsafePtr(mt.mutbl)))
}
@ -421,8 +413,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
Some(adjustment) => {
match *adjustment {
ty::AdjustAddEnv(..) | ty::AdjustReifyFnPointer(..) => {
debug!("cat_expr(AdjustAddEnv|AdjustReifyFnPointer): {}",
ty::AdjustReifyFnPointer(..) => {
debug!("cat_expr(AdjustReifyFnPointer): {}",
expr.repr(self.tcx()));
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
@ -592,25 +584,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
def::DefUpvar(var_id, fn_node_id, _) => {
let ty = try!(self.node_ty(fn_node_id));
match ty.sty {
ty::ty_closure(ref closure_ty) => {
// Translate old closure type info into unboxed
// closure kind/capture mode
let (mode, kind) = match (closure_ty.store, closure_ty.onceness) {
// stack closure
(ty::RegionTraitStore(..), ast::Many) => {
(ast::CaptureByRef, ty::FnMutUnboxedClosureKind)
}
// proc or once closure
(_, ast::Once) => {
(ast::CaptureByValue, ty::FnOnceUnboxedClosureKind)
}
// There should be no such old closure type
(ty::UniqTraitStore, ast::Many) => {
self.tcx().sess.span_bug(span, "Impossible closure type");
}
};
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, false)
}
ty::ty_unboxed_closure(closure_id, _, _) => {
let kind = self.typer.unboxed_closure_kind(closure_id);
let mode = self.typer.capture_mode(fn_node_id);

View File

@ -750,7 +750,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
debug!("privacy - path {}", self.nodestr(path_id));
let orig_def = self.tcx.def_map.borrow()[path_id].clone();
let ck = |&: tyname: &str| {
let ck_public = |def: ast::DefId| {
let ck_public = |&: def: ast::DefId| {
let name = token::get_ident(path.segments.last().unwrap().identifier);
let origdid = orig_def.def_id();
self.ensure_public(span,

View File

@ -136,18 +136,6 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyClosure(ref c) => {
// Careful, the bounds on a closure/proc are *not* within its binder.
visit::walk_ty_param_bounds_helper(self, &c.bounds);
visit::walk_lifetime_decls_helper(self, &c.lifetimes);
self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| {
this.check_lifetime_defs(old_scope, &c.lifetimes);
for argument in c.decl.inputs.iter() {
this.visit_ty(&*argument.ty)
}
visit::walk_fn_ret_ty(this, &c.decl.output);
});
}
ast::TyBareFn(ref c) => {
visit::walk_lifetime_decls_helper(self, &c.lifetimes);
self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| {

View File

@ -118,7 +118,6 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
ty::ty_float(..) |
ty::ty_str(..) |
ty::ty_bare_fn(..) |
ty::ty_closure(..) |
ty::ty_vec(..) |
ty::ty_ptr(..) |
ty::ty_rptr(..) |

View File

@ -1273,62 +1273,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::ty_closure(ref c) => {
match c.store {
ty::UniqTraitStore => {
// proc: Equivalent to `Box<FnOnce>`
match bound {
ty::BoundCopy => {
Err(Unimplemented)
}
ty::BoundSized => {
Ok(If(Vec::new()))
}
ty::BoundSync |
ty::BoundSend => {
if c.bounds.builtin_bounds.contains(&bound) {
Ok(If(Vec::new()))
} else {
Err(Unimplemented)
}
}
}
}
ty::RegionTraitStore(_, mutbl) => {
// ||: Equivalent to `&FnMut` or `&mut FnMut` or something like that.
match bound {
ty::BoundCopy => {
match mutbl {
ast::MutMutable => {
// &mut T is affine
Err(Unimplemented)
}
ast::MutImmutable => {
// &T is copyable, no matter what T is
Ok(If(Vec::new()))
}
}
}
ty::BoundSized => {
Ok(If(Vec::new()))
}
ty::BoundSync |
ty::BoundSend => {
if c.bounds.builtin_bounds.contains(&bound) {
Ok(If(Vec::new()))
} else {
Err(Unimplemented)
}
}
}
}
}
}
ty::ty_trait(ref data) => {
match bound {
ty::BoundSized => {

View File

@ -293,7 +293,6 @@ pub enum Variance {
#[derive(Clone, Show)]
pub enum AutoAdjustment<'tcx> {
AdjustAddEnv(ast::DefId, ty::TraitStore),
AdjustReifyFnPointer(ast::DefId), // go from a fn-item type to a fn-pointer type
AdjustDerefRef(AutoDerefRef<'tcx>)
}
@ -916,7 +915,7 @@ impl<'tcx> ctxt<'tcx> {
pub fn print_debug_stats(&self) {
sty_debug_print!(
self,
ty_enum, ty_uniq, ty_vec, ty_ptr, ty_rptr, ty_bare_fn, ty_closure, ty_trait,
ty_enum, ty_uniq, ty_vec, ty_ptr, ty_rptr, ty_bare_fn, ty_trait,
ty_struct, ty_unboxed_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
println!("Substs interner: #{}", self.substs_interner.borrow().len());
@ -1353,7 +1352,6 @@ pub enum sty<'tcx> {
// fn item. Otherwise, if None(_), it a fn pointer type.
ty_bare_fn(Option<DefId>, &'tcx BareFnTy<'tcx>),
ty_closure(Box<ClosureTy<'tcx>>),
ty_trait(Box<TyTrait<'tcx>>),
ty_struct(DefId, &'tcx Substs<'tcx>),
@ -2594,14 +2592,6 @@ impl FlagComputation {
&ty_bare_fn(_, ref f) => {
self.add_fn_sig(&f.sig);
}
&ty_closure(ref f) => {
if let RegionTraitStore(r, _) = f.store {
self.add_region(r);
}
self.add_fn_sig(&f.sig);
self.add_bounds(&f.bounds);
}
}
}
@ -2748,10 +2738,6 @@ pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
mk_tup(cx, Vec::new())
}
pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, fty: ClosureTy<'tcx>) -> Ty<'tcx> {
mk_t(cx, ty_closure(box fty))
}
pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
opt_def_id: Option<ast::DefId>,
fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
@ -3028,7 +3014,7 @@ pub fn type_is_vec(ty: Ty) -> bool {
pub fn type_is_structural(ty: Ty) -> bool {
match ty.sty {
ty_struct(..) | ty_tup(_) | ty_enum(..) | ty_closure(_) |
ty_struct(..) | ty_tup(_) | ty_enum(..) |
ty_vec(_, Some(_)) | ty_unboxed_closure(..) => true,
_ => type_is_slice(ty) | type_is_trait(ty)
}
@ -3345,10 +3331,6 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
TC::None
}
ty_closure(ref c) => {
closure_contents(&**c) | TC::ReachesFfiUnsafe
}
ty_uniq(typ) => {
TC::ReachesFfiUnsafe | match typ.sty {
ty_str => TC::OwnsOwned,
@ -3519,23 +3501,6 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
}
fn closure_contents(cty: &ClosureTy) -> TypeContents {
// Closure contents are just like trait contents, but with potentially
// even more stuff.
let st = object_contents(&cty.bounds);
let st = match cty.store {
UniqTraitStore => {
st.owned_pointer()
}
RegionTraitStore(r, mutbl) => {
st.reference(borrowed_contents(r, mutbl))
}
};
st
}
fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
// These are the type contents of the (opaque) interior. We
// make no assumptions (other than that it cannot have an
@ -3649,7 +3614,6 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
ty_float(_) |
ty_str |
ty_bare_fn(..) |
ty_closure(_) |
ty_param(_) |
ty_projection(_) |
ty_vec(_, None) => {
@ -4153,7 +4117,6 @@ pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts
pub fn fn_is_variadic(fty: Ty) -> bool {
match fty.sty {
ty_bare_fn(_, ref f) => f.sig.0.variadic,
ty_closure(ref f) => f.sig.0.variadic,
ref s => {
panic!("fn_is_variadic() called on non-fn type: {}", s)
}
@ -4163,7 +4126,6 @@ pub fn fn_is_variadic(fty: Ty) -> bool {
pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
match fty.sty {
ty_bare_fn(_, ref f) => &f.sig,
ty_closure(ref f) => &f.sig,
ref s => {
panic!("ty_fn_sig() called on non-fn type: {}", s)
}
@ -4174,7 +4136,6 @@ pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
pub fn ty_fn_abi(fty: Ty) -> abi::Abi {
match fty.sty {
ty_bare_fn(_, ref f) => f.abi,
ty_closure(ref f) => f.abi,
_ => panic!("ty_fn_abi() called on non-fn type"),
}
}
@ -4186,7 +4147,6 @@ pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> &'tcx [Ty<'tcx>] {
pub fn ty_closure_store(fty: Ty) -> TraitStore {
match fty.sty {
ty_closure(ref f) => f.store,
ty_unboxed_closure(..) => {
// Close enough for the purposes of all the callers of this
// function (which is soon to be deprecated anyhow).
@ -4201,7 +4161,6 @@ pub fn ty_closure_store(fty: Ty) -> TraitStore {
pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> FnOutput<'tcx> {
match fty.sty {
ty_bare_fn(_, ref f) => f.sig.0.output,
ty_closure(ref f) => f.sig.0.output,
ref s => {
panic!("ty_fn_ret() called on non-fn type: {}", s)
}
@ -4211,7 +4170,6 @@ pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> FnOutput<'tcx> {
pub fn is_fn_ty(fty: Ty) -> bool {
match fty.sty {
ty_bare_fn(..) => true,
ty_closure(_) => true,
_ => false
}
}
@ -4335,33 +4293,6 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
return match adjustment {
Some(adjustment) => {
match *adjustment {
AdjustAddEnv(_, store) => {
match unadjusted_ty.sty {
ty::ty_bare_fn(Some(_), ref b) => {
let bounds = ty::ExistentialBounds {
region_bound: ReStatic,
builtin_bounds: all_builtin_bounds(),
projection_bounds: vec!(),
};
ty::mk_closure(
cx,
ty::ClosureTy {unsafety: b.unsafety,
onceness: ast::Many,
store: store,
bounds: bounds,
sig: b.sig.clone(),
abi: b.abi})
}
ref b => {
cx.sess.bug(
format!("add_env adjustment on non-fn-item: \
{}",
b).as_slice());
}
}
}
AdjustReifyFnPointer(_) => {
match unadjusted_ty.sty {
ty::ty_bare_fn(Some(_), b) => {
@ -4731,7 +4662,6 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
ty_rptr(_, _) => "&-ptr".to_string(),
ty_bare_fn(Some(_), _) => format!("fn item"),
ty_bare_fn(None, _) => "fn pointer".to_string(),
ty_closure(_) => "fn".to_string(),
ty_trait(ref inner) => {
format!("trait {}", item_path_str(cx, inner.principal_def_id()))
}
@ -6326,24 +6256,6 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
fn_sig(state, &b.sig);
return false;
}
ty_closure(ref c) => {
byte!(15);
hash!(c.unsafety);
hash!(c.onceness);
hash!(c.bounds);
match c.store {
UniqTraitStore => byte!(0),
RegionTraitStore(r, m) => {
byte!(1);
region(state, r);
assert_eq!(m, ast::MutMutable);
}
}
fn_sig(state, &c.sig);
return false;
}
ty_trait(ref data) => {
byte!(17);
did(state, data.principal_def_id());
@ -6666,12 +6578,6 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
ty_struct(_, substs) => {
accum_substs(accumulator, substs);
}
ty_closure(ref closure_ty) => {
match closure_ty.store {
RegionTraitStore(region, _) => accumulator.push(region),
UniqTraitStore => {}
}
}
ty_unboxed_closure(_, region, substs) => {
accumulator.push(*region);
accum_substs(accumulator, substs);
@ -6741,7 +6647,6 @@ pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where
impl<'tcx> AutoAdjustment<'tcx> {
pub fn is_identity(&self) -> bool {
match *self {
AdjustAddEnv(..) => false,
AdjustReifyFnPointer(..) => false,
AdjustDerefRef(ref r) => r.is_identity(),
}
@ -6865,11 +6770,8 @@ impl DebruijnIndex {
impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
match *self {
AdjustAddEnv(def_id, ref trait_store) => {
format!("AdjustAddEnv({},{})", def_id.repr(tcx), trait_store)
}
AdjustReifyFnPointer(def_id) => {
format!("AdjustAddEnv({})", def_id.repr(tcx))
format!("AdjustReifyFnPointer({})", def_id.repr(tcx))
}
AdjustDerefRef(ref data) => {
data.repr(tcx)

View File

@ -604,9 +604,6 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
let bfn = f.fold_with(this);
ty::ty_bare_fn(opt_def_id, this.tcx().mk_bare_fn(bfn))
}
ty::ty_closure(ref f) => {
ty::ty_closure(f.fold_with(this))
}
ty::ty_rptr(r, ref tm) => {
let r = r.fold_with(this);
ty::ty_rptr(this.tcx().mk_region(r), tm.fold_with(this))

View File

@ -51,9 +51,6 @@ impl<'tcx> TypeWalker<'tcx> {
ty::ty_bare_fn(_, ref ft) => {
self.push_sig_subtypes(&ft.sig);
}
ty::ty_closure(ref ft) => {
self.push_sig_subtypes(&ft.sig);
}
}
}

View File

@ -18,7 +18,7 @@ use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
use middle::ty::{ReSkolemized, ReVar, BrEnv};
use middle::ty::{mt, Ty, ParamTy};
use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
use middle::ty::{ty_unboxed_closure};
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
@ -417,9 +417,6 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
strs => format!("({})", strs.connect(", "))
}
}
ty_closure(ref f) => {
closure_to_string(cx, &**f)
}
ty_bare_fn(opt_def_id, ref f) => {
bare_fn_to_string(cx, opt_def_id, f.unsafety, f.abi, None, &f.sig)
}

View File

@ -662,13 +662,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
default_msgs: (&'static str, &'static str))
-> (&'static str, &'static str) {
match ty.sty {
ty::ty_closure(box ty::ClosureTy {
store: ty::RegionTraitStore(..),
..
}) => {
("a non-copyable stack closure",
"capture it in a new closure, e.g. `|x| f(x)`, to override")
}
_ => {
if ty::type_moves_by_default(param_env, span, ty) {
("non-copyable",

View File

@ -638,7 +638,7 @@ fn write_out_deps(sess: &Session,
_ => return,
};
let result = (|| -> io::IoResult<()> {
let result = (|&:| -> io::IoResult<()> {
// Build a list of files used to compile the output and
// write Makefile-compatible dependency rules
let files: Vec<String> = sess.codemap().files.borrow()

View File

@ -277,26 +277,6 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
ty::mk_tup(self.infcx.tcx, vec![ty1, ty2])
}
pub fn t_closure(&self,
input_tys: &[Ty<'tcx>],
output_ty: Ty<'tcx>,
region_bound: ty::Region)
-> Ty<'tcx>
{
ty::mk_closure(self.infcx.tcx, ty::ClosureTy {
unsafety: ast::Unsafety::Normal,
onceness: ast::Many,
store: ty::RegionTraitStore(region_bound, ast::MutMutable),
bounds: ty::region_existential_bound(region_bound),
sig: ty::Binder(ty::FnSig {
inputs: input_tys.to_vec(),
output: ty::FnConverging(output_ty),
variadic: false,
}),
abi: abi::Rust,
})
}
pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> {
let name = format!("T{}", index);
ty::mk_param(self.infcx.tcx, space, index, token::intern(name[]))
@ -780,19 +760,6 @@ fn escaping() {
assert!(!ty::type_has_escaping_regions(t_param));
let t_fn = env.t_fn(&[t_param], env.t_nil());
assert!(!ty::type_has_escaping_regions(t_fn));
// t_fn = |&int|+'a
let t_fn = env.t_closure(&[t_rptr_bound1], env.t_nil(), env.re_free(0, 1));
assert!(!ty::type_has_escaping_regions(t_fn));
// t_fn = |&int|+'a (where &int has depth 2)
let t_fn = env.t_closure(&[t_rptr_bound2], env.t_nil(), env.re_free(0, 1));
assert!(ty::type_has_escaping_regions(t_fn));
// t_fn = |&int|+&int
let t_fn = env.t_closure(&[t_rptr_bound1], env.t_nil(),
env.re_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1)));
assert!(ty::type_has_escaping_regions(t_fn));
})
}

View File

@ -71,7 +71,7 @@ use syntax::ast::{PatRange, PatStruct, Path};
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
use syntax::ast::{RegionTyParamBound, StructField};
use syntax::ast::{TraitRef, TraitTyParamBound};
use syntax::ast::{Ty, TyBool, TyChar, TyClosure, TyF32};
use syntax::ast::{Ty, TyBool, TyChar, TyF32};
use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
@ -3606,14 +3606,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
}
TyClosure(ref c) => {
self.resolve_type_parameter_bounds(
ty.id,
&c.bounds,
TraitBoundingTypeParameter);
visit::walk_ty(self, ty);
}
TyPolyTraitRef(ref bounds) => {
self.resolve_type_parameter_bounds(
ty.id,

View File

@ -355,12 +355,6 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
// Functions are just pointers
ty::ty_bare_fn(..) => Some(path),
// Closures are a pair of pointers: the code and environment
ty::ty_closure(..) => {
path.push(FAT_PTR_ADDR);
Some(path)
},
// Is this the NonZero lang item wrapping a pointer or integer type?
ty::ty_struct(did, substs) if Some(did) == tcx.lang_items.non_zero() => {
let nonzero_fields = ty::lookup_struct_fields(tcx, did);

View File

@ -287,9 +287,6 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ty::ty_bare_fn(_, ref f) => {
(f.sig.0.inputs.clone(), f.sig.0.output, f.abi, None)
}
ty::ty_closure(ref f) => {
(f.sig.0.inputs.clone(), f.sig.0.output, f.abi, Some(Type::i8p(ccx)))
}
ty::ty_unboxed_closure(closure_did, _, substs) => {
let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
let function_type = typer.unboxed_closure_type(closure_did, substs);
@ -669,30 +666,31 @@ pub fn compare_simd_types<'blk, 'tcx>(
}
}
pub type val_and_ty_fn<'a, 'blk, 'tcx> =
|Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|: 'a -> Block<'blk, 'tcx>;
// Iterates through the elements of a structural type.
pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
av: ValueRef,
t: Ty<'tcx>,
f: val_and_ty_fn<'a, 'blk, 'tcx>)
-> Block<'blk, 'tcx> {
pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
av: ValueRef,
t: Ty<'tcx>,
mut f: F)
-> Block<'blk, 'tcx> where
F: FnMut(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
{
let _icx = push_ctxt("iter_structural_ty");
fn iter_variant<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
repr: &adt::Repr<'tcx>,
av: ValueRef,
variant: &ty::VariantInfo<'tcx>,
substs: &subst::Substs<'tcx>,
f: val_and_ty_fn<'a, 'blk, 'tcx>)
-> Block<'blk, 'tcx> {
fn iter_variant<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
repr: &adt::Repr<'tcx>,
av: ValueRef,
variant: &ty::VariantInfo<'tcx>,
substs: &subst::Substs<'tcx>,
f: &mut F)
-> Block<'blk, 'tcx> where
F: FnMut(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
{
let _icx = push_ctxt("iter_variant");
let tcx = cx.tcx();
let mut cx = cx;
for (i, &arg) in variant.args.iter().enumerate() {
cx = f(cx,
cx = (*f)(cx,
adt::trans_field_ptr(cx, repr, av, variant.disr_val, i),
arg.subst(tcx, substs));
}
@ -764,7 +762,7 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
match adt::trans_switch(cx, &*repr, av) {
(_match::Single, None) => {
cx = iter_variant(cx, &*repr, av, &*(*variants)[0],
substs, f);
substs, &mut f);
}
(_match::Switch, Some(lldiscrim_a)) => {
cx = f(cx, lldiscrim_a, cx.tcx().types.int);
@ -793,7 +791,7 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
data_ptr,
&**variant,
substs,
|x,y,z| f(x,y,z));
&mut f);
Br(variant_cx, next_cx.llbb);
}
cx = next_cx;
@ -951,9 +949,6 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
}
ty::ty_closure(_) => {
get_extern_rust_fn(ccx, t, name[], did)
}
_ => {
get_extern_const(ccx, did, t)
}
@ -2437,7 +2432,6 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
use middle::ty::{BrAnon, ReLateBound};
let (fn_sig, abi, has_env) = match fn_ty.sty {
ty::ty_closure(ref f) => (f.sig.clone(), f.abi, true),
ty::ty_bare_fn(_, ref f) => (f.sig.clone(), f.abi, false),
ty::ty_unboxed_closure(closure_did, _, substs) => {
let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
@ -2978,7 +2972,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
}
let encode_inlined_item: encoder::EncodeInlinedItem =
|ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii);
box |ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii);
let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
let metadata = encoder::encode_metadata(encode_parms, krate);

View File

@ -19,7 +19,7 @@ pub use self::CalleeData::*;
pub use self::CallArgs::*;
use arena::TypedArena;
use back::{abi,link};
use back::link;
use session;
use llvm::{ValueRef};
use llvm::get_param;
@ -66,8 +66,6 @@ pub struct MethodData {
}
pub enum CalleeData<'tcx> {
Closure(Datum<'tcx, Lvalue>),
// Constructor for enum variant/tuple-like-struct
// i.e. Some, Ok
NamedTupleConstructor(subst::Substs<'tcx>, ty::Disr),
@ -102,7 +100,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
fn datum_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
-> Callee<'blk, 'tcx> {
let DatumBlock {mut bcx, datum} = expr::trans(bcx, expr);
let DatumBlock { bcx, datum, .. } = expr::trans(bcx, expr);
match datum.ty.sty {
ty::ty_bare_fn(..) => {
let llval = datum.to_llscalarish(bcx);
@ -111,14 +109,6 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
data: Fn(llval),
};
}
ty::ty_closure(..) => {
let datum = unpack_datum!(
bcx, datum.to_lvalue_datum(bcx, "callee", expr.id));
return Callee {
bcx: bcx,
data: Closure(datum),
};
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,
@ -679,7 +669,6 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
let (abi, ret_ty) = match callee_ty.sty {
ty::ty_bare_fn(_, ref f) => (f.abi, f.sig.0.output),
ty::ty_closure(ref f) => (f.abi, f.sig.0.output),
_ => panic!("expected bare rust fn or closure in trans_call_inner")
};
@ -690,16 +679,6 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
TraitItem(d) => {
(d.llfn, None, Some(d.llself))
}
Closure(d) => {
// Closures are represented as (llfn, llclosure) pair:
// load the requisite values out.
let pair = d.to_llref();
let llfn = GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR]);
let llfn = Load(bcx, llfn);
let llenv = GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA]);
let llenv = Load(bcx, llenv);
(llfn, Some(llenv), None)
}
Intrinsic(node, substs) => {
assert!(abi == synabi::RustIntrinsic);
assert!(dest.is_some());

View File

@ -19,7 +19,7 @@ use trans::base::*;
use trans::build::*;
use trans::cleanup::{CleanupMethods, ScopeId};
use trans::common::*;
use trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
use trans::datum::{Datum, Lvalue, rvalue_scratch_datum};
use trans::datum::{Rvalue, ByValue};
use trans::debuginfo;
use trans::expr;
@ -29,10 +29,8 @@ use trans::type_::Type;
use middle::ty::{self, Ty, UnboxedClosureTyper};
use middle::subst::{Substs};
use session::config::FullDebugInfo;
use util::ppaux::Repr;
use util::ppaux::ty_to_string;
use arena::TypedArena;
use syntax::ast;
use syntax::ast_util;
@ -530,7 +528,6 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
// of the closure expression.
let typer = NormalizingUnboxedClosureTyper::new(bcx.tcx());
let function_type = typer.unboxed_closure_type(closure_id, bcx.fcx.param_substs);
let function_type = ty::mk_closure(bcx.tcx(), function_type);
let freevars: Vec<ty::Freevar> =
ty::with_freevars(bcx.tcx(), id, |fv| fv.iter().map(|&fv| fv).collect());
@ -543,8 +540,8 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
bcx.fcx.param_substs,
id,
&[],
ty::ty_fn_ret(function_type),
ty::ty_fn_abi(function_type),
function_type.sig.0.output,
function_type.abi,
ClosureEnv::new(freevars[],
UnboxedClosure(freevar_mode)));
@ -582,98 +579,3 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
bcx
}
pub fn get_wrapper_for_bare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
closure_ty: Ty<'tcx>,
def_id: ast::DefId,
fn_ptr: ValueRef,
is_local: bool) -> ValueRef {
match ccx.closure_bare_wrapper_cache().borrow().get(&fn_ptr) {
Some(&llval) => return llval,
None => {}
}
let tcx = ccx.tcx();
debug!("get_wrapper_for_bare_fn(closure_ty={})", closure_ty.repr(tcx));
let f = match closure_ty.sty {
ty::ty_closure(ref f) => f,
_ => {
ccx.sess().bug(format!("get_wrapper_for_bare_fn: \
expected a closure ty, got {}",
closure_ty.repr(tcx))[]);
}
};
let name = ty::with_path(tcx, def_id, |path| {
mangle_internal_name_by_path_and_seq(path, "as_closure")
});
let llfn = if is_local {
decl_internal_rust_fn(ccx, closure_ty, name[])
} else {
decl_rust_fn(ccx, closure_ty, name[])
};
ccx.closure_bare_wrapper_cache().borrow_mut().insert(fn_ptr, llfn);
// This is only used by statics inlined from a different crate.
if !is_local {
// Don't regenerate the wrapper, just reuse the original one.
return llfn;
}
let _icx = push_ctxt("closure::get_wrapper_for_bare_fn");
let arena = TypedArena::new();
let empty_param_substs = Substs::trans_empty();
let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, true, f.sig.0.output,
&empty_param_substs, None, &arena);
let bcx = init_function(&fcx, true, f.sig.0.output);
let args = create_datums_for_fn_args(&fcx,
ty::ty_fn_args(closure_ty)
[]);
let mut llargs = Vec::new();
match fcx.llretslotptr.get() {
Some(llretptr) => {
assert!(!fcx.needs_ret_allocas);
llargs.push(llretptr);
}
None => {}
}
llargs.extend(args.iter().map(|arg| arg.val));
let retval = Call(bcx, fn_ptr, llargs.as_slice(), None);
match f.sig.0.output {
ty::FnConverging(output_type) => {
if return_type_is_void(ccx, output_type) || fcx.llretslotptr.get().is_some() {
RetVoid(bcx);
} else {
Ret(bcx, retval);
}
}
ty::FnDiverging => {
RetVoid(bcx);
}
}
// HACK(eddyb) finish_fn cannot be used here, we returned directly.
debuginfo::clear_source_location(&fcx);
fcx.cleanup();
llfn
}
pub fn make_closure_from_bare_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
closure_ty: Ty<'tcx>,
def_id: ast::DefId,
fn_ptr: ValueRef)
-> DatumBlock<'blk, 'tcx, Expr> {
let scratch = rvalue_scratch_datum(bcx, closure_ty, "__adjust");
let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def_id, fn_ptr, true);
fill_fn_pair(bcx, scratch.val, wrapper, C_null(Type::i8p(bcx.ccx())));
DatumBlock::new(bcx, scratch.to_expr_datum())
}

View File

@ -15,7 +15,7 @@ use llvm::{ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, Tru
use llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};
use middle::{const_eval, def};
use trans::{adt, closure, consts, debuginfo, expr, inline, machine};
use trans::{adt, consts, debuginfo, expr, inline, machine};
use trans::base::{self, push_ctxt};
use trans::common::*;
use trans::type_::Type;
@ -189,20 +189,6 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, e: &ast::Expr)
None => { }
Some(adj) => {
match adj {
ty::AdjustAddEnv(def_id, ty::RegionTraitStore(ty::ReStatic, _)) => {
let wrapper = closure::get_wrapper_for_bare_fn(cx,
ety_adjusted,
def_id,
llconst,
true);
llconst = C_struct(cx, &[wrapper, C_null(Type::i8p(cx))], false)
}
ty::AdjustAddEnv(_, store) => {
cx.sess()
.span_bug(e.span,
format!("unexpected static function: {}",
store)[])
}
ty::AdjustReifyFnPointer(_def_id) => {
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here

View File

@ -465,11 +465,6 @@ impl<'tcx> TypeMap<'tcx> {
}
}
},
ty::ty_closure(box ref closure_ty) => {
self.get_unique_type_id_of_closure_type(cx,
closure_ty.clone(),
&mut unique_type_id);
},
ty::ty_unboxed_closure(def_id, _, substs) => {
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
let closure_ty = typer.unboxed_closure_type(def_id, substs);
@ -3017,9 +3012,6 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ty::ty_bare_fn(_, ref barefnty) => {
subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
}
ty::ty_closure(ref closurety) => {
subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
}
ty::ty_unboxed_closure(def_id, _, substs) => {
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
let sig = typer.unboxed_closure_type(def_id, substs).sig;
@ -3870,66 +3862,6 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
}
},
ty::ty_closure(box ty::ClosureTy { unsafety,
onceness,
store,
ref sig,
.. // omitting bounds ...
}) => {
if unsafety == ast::Unsafety::Unsafe {
output.push_str("unsafe ");
}
if onceness == ast::Once {
output.push_str("once ");
}
let param_list_closing_char;
match store {
ty::UniqTraitStore => {
output.push_str("proc(");
param_list_closing_char = ')';
}
ty::RegionTraitStore(_, ast::MutMutable) => {
output.push_str("&mut|");
param_list_closing_char = '|';
}
ty::RegionTraitStore(_, ast::MutImmutable) => {
output.push_str("&|");
param_list_closing_char = '|';
}
};
if sig.0.inputs.len() > 0 {
for &parameter_type in sig.0.inputs.iter() {
push_debuginfo_type_name(cx, parameter_type, true, output);
output.push_str(", ");
}
output.pop();
output.pop();
}
if sig.0.variadic {
if sig.0.inputs.len() > 0 {
output.push_str(", ...");
} else {
output.push_str("...");
}
}
output.push(param_list_closing_char);
match sig.0.output {
ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
ty::FnConverging(result_type) => {
output.push_str(" -> ");
push_debuginfo_type_name(cx, result_type, true, output);
}
ty::FnDiverging => {
output.push_str(" -> !");
}
}
},
ty::ty_unboxed_closure(..) => {
output.push_str("closure");
}

View File

@ -54,7 +54,7 @@ use trans::inline;
use trans::tvec;
use trans::type_of;
use middle::ty::{struct_fields, tup_fields};
use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AdjustAddEnv, AutoUnsafe};
use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AutoUnsafe};
use middle::ty::{AutoPtr};
use middle::ty::{self, Ty};
use middle::ty::MethodCall;
@ -179,9 +179,6 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
datum.to_string(bcx.ccx()),
adjustment.repr(bcx.tcx()));
match adjustment {
AdjustAddEnv(def_id, _) => {
datum = unpack_datum!(bcx, add_env(bcx, def_id, expr, datum));
}
AdjustReifyFnPointer(_def_id) => {
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
@ -476,22 +473,6 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
DatumBlock::new(bcx, scratch.to_expr_datum())
}
fn add_env<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
def_id: ast::DefId,
expr: &ast::Expr,
datum: Datum<'tcx, Expr>)
-> DatumBlock<'blk, 'tcx, Expr> {
// This is not the most efficient thing possible; since closures
// are two words it'd be better if this were compiled in
// 'dest' mode, but I can't find a nice way to structure the
// code and keep it DRY that accommodates that use case at the
// moment.
let closure_ty = expr_ty_adjusted(bcx, expr);
let fn_ptr = datum.to_llscalarish(bcx);
closure::make_closure_from_bare_fn(bcx, closure_ty, def_id, fn_ptr)
}
}
/// Translates an expression in "lvalue" mode -- meaning that it returns a reference to the memory

View File

@ -441,18 +441,6 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
v0,
t,
|bb, vv, tt| drop_ty(bb, vv, tt, None)),
ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => {
let box_cell_v = GEPi(bcx, v0, &[0u, abi::FAT_PTR_EXTRA]);
let env = Load(bcx, box_cell_v);
let env_ptr_ty = Type::at_box(bcx.ccx(), Type::i8(bcx.ccx())).ptr_to();
let env = PointerCast(bcx, env, env_ptr_ty);
with_cond(bcx, IsNotNull(bcx, env), |bcx| {
let dtor_ptr = GEPi(bcx, env, &[0u, abi::BOX_FIELD_DROP_GLUE]);
let dtor = Load(bcx, dtor_ptr);
Call(bcx, dtor, &[PointerCast(bcx, box_cell_v, Type::i8p(bcx.ccx()))], None);
bcx
})
}
ty::ty_trait(..) => {
// No need to do a null check here (as opposed to the Box<trait case
// above), because this happens for a trait field in an unsized
@ -531,13 +519,14 @@ fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
return (fn_nm, llfn);
}
fn make_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
t: Ty<'tcx>,
llfn: ValueRef,
helper: for<'blk> |Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|
-> Block<'blk, 'tcx>,
name: &str)
-> ValueRef {
fn make_generic_glue<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
t: Ty<'tcx>,
llfn: ValueRef,
helper: F,
name: &str)
-> ValueRef where
F: for<'blk> FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
{
let _icx = push_ctxt("make_generic_glue");
let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx(), t));
let _s = StatRecorder::new(ccx, glue_name);

View File

@ -40,7 +40,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
let csearch_result =
csearch::maybe_get_item_ast(
ccx.tcx(), fn_id,
|a,b,c,d| astencode::decode_inlined_item(a, b, c, d));
box |a,b,c,d| astencode::decode_inlined_item(a, b, c, d));
let inline_def = match csearch_result {
csearch::not_found => {

View File

@ -599,8 +599,27 @@ pub fn trans_object_shim<'a, 'tcx>(
bcx.val_to_string(llobject));
// the remaining arguments will be, well, whatever they are
let input_tys =
match fty.abi {
RustCall => {
// unpack the tuple to extract the input type arguments:
match fty.sig.0.inputs[1].sty {
ty::ty_tup(ref tys) => tys.as_slice(),
_ => {
bcx.sess().bug(
format!("rust-call expects a tuple not {}",
fty.sig.0.inputs[1].repr(tcx)).as_slice());
}
}
}
_ => {
// skip the self parameter:
fty.sig.0.inputs.slice_from(1)
}
};
let llargs: Vec<_> =
fty.sig.0.inputs[1..].iter()
input_tys.iter()
.enumerate()
.map(|(i, _)| {
let llarg = get_param(fcx.llfn, fcx.arg_pos(i+1) as u32);
@ -609,6 +628,7 @@ pub fn trans_object_shim<'a, 'tcx>(
llarg
})
.collect();
assert!(!fcx.needs_ret_allocas);
let dest =

View File

@ -416,15 +416,14 @@ pub fn get_base_and_len(bcx: Block,
}
}
pub type iter_vec_block<'a, 'blk, 'tcx> =
|Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|: 'a -> Block<'blk, 'tcx>;
pub fn iter_vec_loop<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
data_ptr: ValueRef,
vt: &VecTypes<'tcx>,
count: ValueRef,
f: iter_vec_block<'a, 'blk, 'tcx>)
-> Block<'blk, 'tcx> {
f: F)
-> Block<'blk, 'tcx> where
F: FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
{
let _icx = push_ctxt("tvec::iter_vec_loop");
let fcx = bcx.fcx;
@ -475,12 +474,14 @@ pub fn iter_vec_loop<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
next_bcx
}
pub fn iter_vec_raw<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
data_ptr: ValueRef,
unit_ty: Ty<'tcx>,
len: ValueRef,
f: iter_vec_block<'a, 'blk, 'tcx>)
-> Block<'blk, 'tcx> {
pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
data_ptr: ValueRef,
unit_ty: Ty<'tcx>,
len: ValueRef,
f: F)
-> Block<'blk, 'tcx> where
F: FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
{
let _icx = push_ctxt("tvec::iter_vec_raw");
let fcx = bcx.fcx;

View File

@ -143,13 +143,6 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// Given a function type and a count of ty params, construct an llvm type
pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>) -> Type {
match fty.sty {
ty::ty_closure(ref f) => {
type_of_rust_fn(cx,
Some(Type::i8p(cx)),
f.sig.0.inputs.as_slice(),
f.sig.0.output,
f.abi)
}
ty::ty_bare_fn(_, ref f) => {
// FIXME(#19925) once fn item types are
// zero-sized, we'll need to do something here
@ -207,7 +200,6 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
}
ty::ty_bare_fn(..) => Type::i8p(cx),
ty::ty_closure(..) => Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false),
ty::ty_vec(ty, Some(size)) => {
let llty = sizing_type_of(cx, ty);
@ -369,10 +361,6 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
ty::ty_bare_fn(..) => {
type_of_fn_from_ty(cx, t).ptr_to()
}
ty::ty_closure(_) => {
let fn_ty = type_of_fn_from_ty(cx, t).ptr_to();
Type::struct_(cx, &[fn_ty, Type::i8p(cx)], false)
}
ty::ty_tup(ref tys) if tys.is_empty() => Type::nil(cx),
ty::ty_tup(..) => {
let repr = adt::represent_type(cx, t);

View File

@ -1112,28 +1112,6 @@ pub fn ast_ty_to_ty<'tcx>(
let bare_fn = ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl);
ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn))
}
ast::TyClosure(ref f) => {
// Use corresponding trait store to figure out default bounds
// if none were specified.
let bounds = conv_existential_bounds(this,
rscope,
ast_ty.span,
None,
Vec::new(),
f.bounds.as_slice());
let region_bound = bounds.region_bound;
let fn_decl = ty_of_closure(this,
f.unsafety,
f.onceness,
bounds,
ty::RegionTraitStore(
region_bound,
ast::MutMutable),
&*f.decl,
abi::Rust,
None);
ty::mk_closure(tcx, fn_decl)
}
ast::TyPolyTraitRef(ref bounds) => {
conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds[])
}

View File

@ -111,7 +111,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
{
// If the callee is a bare function or a closure, then we're all set.
match structurally_resolved_type(fcx, callee_expr.span, adjusted_ty).sty {
ty::ty_bare_fn(..) | ty::ty_closure(_) => {
ty::ty_bare_fn(..) => {
fcx.write_adjustment(callee_expr.id,
callee_expr.span,
ty::AdjustDerefRef(autoderefref));
@ -158,8 +158,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
let error_fn_sig;
let fn_sig = match callee_ty.sty {
ty::ty_bare_fn(_, &ty::BareFnTy {ref sig, ..}) |
ty::ty_closure(box ty::ClosureTy {ref sig, ..}) => {
ty::ty_bare_fn(_, &ty::BareFnTy {ref sig, ..}) => {
sig
}
_ => {

View File

@ -13,20 +13,18 @@
use super::{check_fn, Expectation, FnCtxt};
use astconv;
use middle::infer;
use middle::region::CodeExtent;
use middle::subst;
use middle::ty::{self, ToPolyTraitRef, Ty};
use rscope::RegionScope;
use syntax::abi;
use syntax::ast;
use syntax::ast::CaptureClause::*;
use syntax::ast_util;
use util::ppaux::Repr;
pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
expr: &ast::Expr,
capture: ast::CaptureClause,
_capture: ast::CaptureClause,
opt_kind: Option<ast::UnboxedClosureKind>,
decl: &ast::FnDecl,
body: &ast::Block,
@ -46,30 +44,17 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
// evidence than an unboxed closure is desired, we'll use
// that, otherwise we'll fall back to boxed closures.
match expected_sig_and_kind {
None => { // doesn't look like an unboxed closure
let region = astconv::opt_ast_region_to_region(fcx,
fcx,
expr.span,
&None);
None => { // don't have information about the kind, request explicit annotation
// NB We still need to typeck the body, so assume `FnMut` kind just for that
let kind = ty::FnMutUnboxedClosureKind;
check_boxed_closure(fcx,
expr,
ty::RegionTraitStore(region, ast::MutMutable),
decl,
body,
expected);
check_unboxed_closure(fcx, expr, kind, decl, body, None);
match capture {
CaptureByValue => {
fcx.ccx.tcx.sess.span_err(
expr.span,
"boxed closures can't capture by value, \
if you want to use an unboxed closure, \
explicitly annotate its kind: e.g. `move |:|`");
},
CaptureByRef => {}
}
}
fcx.ccx.tcx.sess.span_err(
expr.span,
"can't infer the \"kind\" of the closure, explicitly annotate it. e.g. \
`|&:| {}`");
},
Some((sig, kind)) => {
check_unboxed_closure(fcx, expr, kind, decl, body, Some(sig));
}
@ -254,92 +239,3 @@ fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(
None
}
fn check_boxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
expr: &ast::Expr,
store: ty::TraitStore,
decl: &ast::FnDecl,
body: &ast::Block,
expected: Expectation<'tcx>) {
let tcx = fcx.ccx.tcx;
// Find the expected input/output types (if any). Substitute
// fresh bound regions for any bound regions we find in the
// expected types so as to avoid capture.
let expected_cenv = expected.map_to_option(fcx, |ty| match ty.sty {
ty::ty_closure(ref cenv) => Some(cenv),
_ => None
});
let (expected_sig, expected_onceness, expected_bounds) = match expected_cenv {
Some(cenv) => {
let (sig, _) =
ty::replace_late_bound_regions(
tcx,
&cenv.sig,
|_, debruijn| fcx.inh.infcx.fresh_bound_region(debruijn));
let onceness = match (&store, &cenv.store) {
// As the closure type and onceness go, only three
// combinations are legit:
// once closure
// many closure
// once proc
// If the actual and expected closure type disagree with
// each other, set expected onceness to be always Once or
// Many according to the actual type. Otherwise, it will
// yield either an illegal "many proc" or a less known
// "once closure" in the error message.
(&ty::UniqTraitStore, &ty::UniqTraitStore) |
(&ty::RegionTraitStore(..), &ty::RegionTraitStore(..)) =>
cenv.onceness,
(&ty::UniqTraitStore, _) => ast::Once,
(&ty::RegionTraitStore(..), _) => ast::Many,
};
(Some(sig), onceness, cenv.bounds.clone())
}
_ => {
// Not an error! Means we're inferring the closure type
let region = fcx.infcx().next_region_var(
infer::AddrOfRegion(expr.span));
let bounds = ty::region_existential_bound(region);
let onceness = ast::Many;
(None, onceness, bounds)
}
};
// construct the function type
let fn_ty = astconv::ty_of_closure(fcx,
ast::Unsafety::Normal,
expected_onceness,
expected_bounds,
store,
decl,
abi::Rust,
expected_sig);
let fn_sig = fn_ty.sig.clone();
let fty = ty::mk_closure(tcx, fn_ty);
debug!("check_expr_fn fty={}", fcx.infcx().ty_to_string(fty));
fcx.write_ty(expr.id, fty);
// If the closure is a stack closure and hasn't had some non-standard
// style inferred for it, then check it under its parent's style.
// Otherwise, use its own
let (inherited_style, inherited_style_id) = match store {
ty::RegionTraitStore(..) => (fcx.ps.borrow().unsafety,
fcx.ps.borrow().def),
ty::UniqTraitStore => (ast::Unsafety::Normal, expr.id)
};
let fn_sig =
ty::liberate_late_bound_regions(tcx, CodeExtent::from_node_id(body.id), &fn_sig);
check_fn(fcx.ccx,
inherited_style,
inherited_style_id,
&fn_sig,
&*decl,
expr.id,
&*body,
fcx.inh);
}

View File

@ -462,7 +462,6 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
method_callee: &MethodCallee) {
let sig = match method_callee.ty.sty {
ty::ty_bare_fn(_, ref f) => f.sig.clone(),
ty::ty_closure(ref f) => f.sig.clone(),
_ => return,
};

View File

@ -387,14 +387,18 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
// Do a search through a list of bounds, using a callback to actually
// create the candidates.
fn elaborate_bounds(
fn elaborate_bounds<F>(
&mut self,
bounds: &[ty::PolyTraitRef<'tcx>],
num_includes_types: bool,
mk_cand: for<'b> |this: &mut ProbeContext<'b, 'tcx>,
tr: ty::PolyTraitRef<'tcx>,
m: Rc<ty::Method<'tcx>>,
method_num: uint|)
mut mk_cand: F,
) where
F: for<'b> FnMut(
&mut ProbeContext<'b, 'tcx>,
ty::PolyTraitRef<'tcx>,
Rc<ty::Method<'tcx>>,
uint,
),
{
debug!("elaborate_bounds(bounds={})", bounds.repr(self.tcx()));

View File

@ -1850,7 +1850,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
adj: &ty::AutoAdjustment<'tcx>) {
match *adj {
ty::AdjustAddEnv(..) |
ty::AdjustReifyFnPointer(..) => {
}
ty::AdjustDerefRef(ref d_r) => {

View File

@ -735,29 +735,6 @@ fn check_expr_fn_block(rcx: &mut Rcx,
let function_type = rcx.resolve_node_type(expr.id);
match function_type.sty {
ty::ty_closure(box ty::ClosureTy{store: ty::RegionTraitStore(..),
ref bounds,
..}) => {
// For closure, ensure that the variables outlive region
// bound, since they are captured by reference.
ty::with_freevars(tcx, expr.id, |freevars| {
if freevars.is_empty() {
// No free variables means that the environment
// will be NULL at runtime and hence the closure
// has static lifetime.
} else {
// Variables being referenced must outlive closure.
constrain_free_variables_in_by_ref_closure(
rcx, bounds.region_bound, expr, freevars);
// Closure is stack allocated and hence cannot
// outlive the appropriate temporary scope.
let s = rcx.repeating_scope;
rcx.fcx.mk_subr(infer::InfStackClosure(expr.span),
bounds.region_bound, ty::ReScope(CodeExtent::from_node_id(s)));
}
});
}
ty::ty_unboxed_closure(_, region, _) => {
if tcx.capture_modes.borrow()[expr.id].clone() == ast::CaptureByRef {
ty::with_freevars(tcx, expr.id, |freevars| {
@ -778,11 +755,6 @@ fn check_expr_fn_block(rcx: &mut Rcx,
rcx.set_repeating_scope(repeating_scope);
match function_type.sty {
ty::ty_closure(box ty::ClosureTy {ref bounds, ..}) => {
ty::with_freevars(tcx, expr.id, |freevars| {
ensure_free_variable_types_outlive_closure_bound(rcx, bounds, expr, freevars);
})
}
ty::ty_unboxed_closure(_, region, _) => {
ty::with_freevars(tcx, expr.id, |freevars| {
let bounds = ty::region_existential_bound(*region);
@ -884,33 +856,11 @@ fn check_expr_fn_block(rcx: &mut Rcx,
fn constrain_callee(rcx: &mut Rcx,
callee_id: ast::NodeId,
call_expr: &ast::Expr,
callee_expr: &ast::Expr) {
let call_region = ty::ReScope(CodeExtent::from_node_id(call_expr.id));
_call_expr: &ast::Expr,
_callee_expr: &ast::Expr) {
let callee_ty = rcx.resolve_node_type(callee_id);
match callee_ty.sty {
ty::ty_bare_fn(..) => { }
ty::ty_closure(ref closure_ty) => {
let region = match closure_ty.store {
ty::RegionTraitStore(r, _) => {
// While we're here, link the closure's region with a unique
// immutable borrow (gathered later in borrowck)
let mc = mc::MemCategorizationContext::new(rcx.fcx);
let expr_cmt = ignore_err!(mc.cat_expr(callee_expr));
link_region(rcx, callee_expr.span, call_region,
ty::UniqueImmBorrow, expr_cmt);
r
}
ty::UniqTraitStore => ty::ReStatic
};
rcx.fcx.mk_subr(infer::InvokeClosure(callee_expr.span),
call_region, region);
let region = closure_ty.bounds.region_bound;
rcx.fcx.mk_subr(infer::InvokeClosure(callee_expr.span),
call_region, region);
}
_ => {
// this should not happen, but it does if the program is
// erroneous

View File

@ -67,10 +67,6 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
// No borrowed content reachable here.
}
ty::ty_closure(box ref c) => {
self.accumulate_from_closure_ty(ty, c);
}
ty::ty_unboxed_closure(_, region, _) => {
// An "unboxed closure type" is basically
// modeled here as equivalent to a struct like
@ -323,22 +319,6 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
}
}
fn accumulate_from_closure_ty(&mut self,
ty: Ty<'tcx>,
c: &ty::ClosureTy<'tcx>)
{
match c.store {
ty::RegionTraitStore(r_b, _) => {
self.push_region_constraint_from_top(r_b);
}
ty::UniqTraitStore => { }
}
let required_region_bounds =
ty::object_region_bounds(self.tcx, None, c.bounds.builtin_bounds);
self.accumulate_from_object_ty(ty, c.bounds.region_bound, required_region_bounds);
}
fn accumulate_from_object_ty(&mut self,
ty: Ty<'tcx>,
region_bound: ty::Region,

View File

@ -122,7 +122,6 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> {
_body: &ast::Block)
{
let is_old_skool_closure = match self.fcx.expr_ty(expr).sty {
ty::ty_closure(..) => true,
_ => false,
};

View File

@ -81,10 +81,9 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
}
}
fn with_fcx(&mut self,
item: &ast::Item,
f: for<'fcx> |&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>,
&FnCtxt<'fcx, 'tcx>|) {
fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>),
{
let ccx = self.ccx;
let item_def_id = local_def(item.id);
let polytype = ty::lookup_item_type(ccx.tcx, item_def_id);
@ -100,10 +99,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
}
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
fn check_type_defn(&mut self,
item: &ast::Item,
lookup_fields: for<'fcx> |&FnCtxt<'fcx, 'tcx>|
-> Vec<AdtVariant<'tcx>>)
fn check_type_defn<F>(&mut self, item: &ast::Item, mut lookup_fields: F) where
F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec<AdtVariant<'tcx>>,
{
self.with_fcx(item, |this, fcx| {
let variants = lookup_fields(fcx);

View File

@ -266,10 +266,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
Some(adjustment) => {
let adj_object = ty::adjust_is_object(&adjustment);
let resolved_adjustment = match adjustment {
ty::AdjustAddEnv(def_id, store) => {
ty::AdjustAddEnv(def_id, self.resolve(&store, reason))
}
ty::AdjustReifyFnPointer(def_id) => {
ty::AdjustReifyFnPointer(def_id)
}

View File

@ -22,7 +22,7 @@ use middle::subst::{self, Subst};
use middle::ty::RegionEscape;
use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
use middle::ty::{Ty, ty_bool, ty_char, ty_closure, ty_enum, ty_err};
use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
use middle::ty::{ty_param, TypeScheme, ty_ptr};
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
@ -69,7 +69,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
}
ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) |
ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_tup(..) |
ty_param(..) | ty_err | ty_open(..) | ty_uniq(_) |
ty_ptr(_) | ty_rptr(_, _) | ty_projection(..) => {
None

View File

@ -831,20 +831,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}
ty::ty_bare_fn(_, &ty::BareFnTy { ref sig, .. }) |
ty::ty_closure(box ty::ClosureTy {
ref sig,
store: ty::UniqTraitStore,
..
}) =>
{
self.add_constraints_from_sig(generics, sig, variance);
}
ty::ty_closure(box ty::ClosureTy { ref sig,
store: ty::RegionTraitStore(region, _), .. }) => {
let contra = self.contravariant(variance);
self.add_constraints_from_region(generics, region, contra);
ty::ty_bare_fn(_, &ty::BareFnTy { ref sig, .. }) => {
self.add_constraints_from_sig(generics, sig, variance);
}

View File

@ -1366,7 +1366,6 @@ impl Clean<Type> for ast::Ty {
}
}
}
TyClosure(ref c) => Closure(box c.clean(cx)),
TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
TyParen(ref ty) => ty.clean(cx),
TyQPath(ref qp) => qp.clean(cx),
@ -1426,19 +1425,6 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
decl: (ast_util::local_def(0), &fty.sig).clean(cx),
abi: fty.abi.to_string(),
}),
ty::ty_closure(ref fty) => {
let decl = box ClosureDecl {
lifetimes: Vec::new(), // FIXME: this looks wrong...
decl: (ast_util::local_def(0), &fty.sig).clean(cx),
onceness: fty.onceness,
unsafety: fty.unsafety,
bounds: fty.bounds.clean(cx),
};
match fty.store {
ty::UniqTraitStore => Proc(decl),
ty::RegionTraitStore(..) => Closure(decl),
}
}
ty::ty_struct(did, substs) |
ty::ty_enum(did, substs) => {
let fqn = csearch::get_item_path(cx.tcx(), did);

View File

@ -1125,15 +1125,6 @@ impl Json {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<'a> ops::Index<&'a str, Json> for Json {
fn index(&self, idx: & &str) -> &Json {
self.find(*idx).unwrap()
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<'a> ops::Index<&'a str> for Json {
type Output = Json;
@ -1142,18 +1133,6 @@ impl<'a> ops::Index<&'a str> for Json {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl ops::Index<uint, Json> for Json {
fn index<'a>(&'a self, idx: &uint) -> &'a Json {
match self {
&Json::Array(ref v) => v.index(idx),
_ => panic!("can only index Json with uint if it is an array")
}
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl ops::Index<uint> for Json {
type Output = Json;

View File

@ -1123,15 +1123,6 @@ impl Json {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<'a> ops::Index<&'a str, Json> for Json {
fn index(&self, idx: & &str) -> &Json {
self.find(*idx).unwrap()
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<'a> ops::Index<&'a str> for Json {
type Output = Json;
@ -1140,18 +1131,6 @@ impl<'a> ops::Index<&'a str> for Json {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl ops::Index<uint, Json> for Json {
fn index<'a>(&'a self, idx: &uint) -> &'a Json {
match self {
&Json::Array(ref v) => v.index(idx),
_ => panic!("can only index Json with uint if it is an array")
}
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl ops::Index<uint> for Json {
type Output = Json;

View File

@ -1226,19 +1226,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H>
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> Index<Q, V> for HashMap<K, V, H>
where Q: BorrowFrom<K> + Hash<S> + Eq
{
#[inline]
fn index<'a>(&'a self, index: &Q) -> &'a V {
self.get(index).expect("no entry found for key")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, H>
where Q: BorrowFrom<K> + Hash<S> + Eq
@ -1251,19 +1238,6 @@ impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, H
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> IndexMut<Q, V> for HashMap<K, V, H>
where Q: BorrowFrom<K> + Hash<S> + Eq
{
#[inline]
fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
self.get_mut(index).expect("no entry found for key")
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> IndexMut<Q> for HashMap<K, V, H>
where Q: BorrowFrom<K> + Hash<S> + Eq

View File

@ -518,14 +518,16 @@ pub fn rmdir(path: &Path) -> IoResult<()> {
/// use std::io;
///
/// // one possible implementation of fs::walk_dir only visiting files
/// fn visit_dirs(dir: &Path, cb: |&Path|) -> io::IoResult<()> {
/// fn visit_dirs<F>(dir: &Path, cb: &mut F) -> io::IoResult<()> where
/// F: FnMut(&Path),
/// {
/// if dir.is_dir() {
/// let contents = try!(fs::readdir(dir));
/// for entry in contents.iter() {
/// if entry.is_dir() {
/// try!(visit_dirs(entry, |p| cb(p)));
/// try!(visit_dirs(entry, cb));
/// } else {
/// cb(entry);
/// (*cb)(entry);
/// }
/// }
/// Ok(())

View File

@ -17,11 +17,12 @@
pub use self::IpAddr::*;
use boxed::Box;
use fmt;
use io::{self, IoResult, IoError};
use io::net;
use iter::{Iterator, IteratorExt};
use ops::FnOnce;
use ops::{FnOnce, FnMut};
use option::Option;
use option::Option::{None, Some};
use result::Result::{Ok, Err};
@ -120,10 +121,10 @@ impl<'a> Parser<'a> {
}
// Return result of first successful parser
fn read_or<T>(&mut self, parsers: &mut [|&mut Parser| -> Option<T>])
fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T>>])
-> Option<T> {
for pf in parsers.iter_mut() {
match self.read_atomically(|p: &mut Parser| (*pf)(p)) {
match self.read_atomically(|p: &mut Parser| pf.call_mut((p,))) {
Some(r) => return Some(r),
None => {}
}
@ -320,22 +321,22 @@ impl<'a> Parser<'a> {
}
fn read_ip_addr(&mut self) -> Option<IpAddr> {
let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
self.read_or(&mut [ipv4_addr, ipv6_addr])
let ipv4_addr = |&mut: p: &mut Parser| p.read_ipv4_addr();
let ipv6_addr = |&mut: p: &mut Parser| p.read_ipv6_addr();
self.read_or(&mut [box ipv4_addr, box ipv6_addr])
}
fn read_socket_addr(&mut self) -> Option<SocketAddr> {
let ip_addr = |&: p: &mut Parser| {
let ipv4_p = |p: &mut Parser| p.read_ip_addr();
let ipv6_p = |p: &mut Parser| {
let ipv4_p = |&mut: p: &mut Parser| p.read_ip_addr();
let ipv6_p = |&mut: p: &mut Parser| {
let open_br = |&: p: &mut Parser| p.read_given_char('[');
let ip_addr = |&: p: &mut Parser| p.read_ipv6_addr();
let clos_br = |&: p: &mut Parser| p.read_given_char(']');
p.read_seq_3::<char, IpAddr, char, _, _, _>(open_br, ip_addr, clos_br)
.map(|t| match t { (_, ip, _) => ip })
};
p.read_or(&mut [ipv4_p, ipv6_p])
p.read_or(&mut [box ipv4_p, box ipv6_p])
};
let colon = |&: p: &mut Parser| p.read_given_char(':');
let port = |&: p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);

View File

@ -1220,8 +1220,6 @@ pub enum Ty_ {
TyPtr(MutTy),
/// A reference (`&'a T` or `&'a mut T`)
TyRptr(Option<Lifetime>, MutTy),
/// A closure (e.g. `|uint| -> bool`)
TyClosure(P<ClosureTy>),
/// A bare function (e.g. `fn(uint) -> bool`)
TyBareFn(P<BareFnTy>),
/// A tuple (`(A, B, C, D,...)`)

View File

@ -859,9 +859,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
fn visit_ty(&mut self, ty: &'ast Ty) {
match ty.node {
TyClosure(ref fd) => {
self.visit_fn_decl(&*fd.decl);
}
TyBareFn(ref fd) => {
self.visit_fn_decl(&*fd.decl);
}

View File

@ -40,7 +40,7 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
args: Vec::new(),
ret_ty: Self,
attributes: attrs,
combine_substructure: combine_substructure(|c, s, sub| {
combine_substructure: combine_substructure(box |c, s, sub| {
cs_clone("Clone", c, s, sub)
}),
}

View File

@ -40,7 +40,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
cx.expr_binary(span, ast::BiAnd, subexpr, eq)
},
cx.expr_bool(span, true),
|cx, span, _, _| cx.expr_bool(span, false),
box |cx, span, _, _| cx.expr_bool(span, false),
cx, span, substr)
}
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
@ -57,7 +57,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
cx.expr_binary(span, ast::BiOr, subexpr, eq)
},
cx.expr_bool(span, false),
|cx, span, _, _| cx.expr_bool(span, true),
box |cx, span, _, _| cx.expr_bool(span, true),
cx, span, substr)
}
@ -72,7 +72,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
attributes: attrs,
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
$f(a, b, c)
})
}

View File

@ -38,7 +38,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
attributes: attrs,
combine_substructure: combine_substructure(|cx, span, substr| {
combine_substructure: combine_substructure(box |cx, span, substr| {
cs_op($op, $equal, cx, span, substr)
})
}
@ -61,7 +61,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
args: vec![borrowed_self()],
ret_ty: ret_ty,
attributes: attrs,
combine_substructure: combine_substructure(|cx, span, substr| {
combine_substructure: combine_substructure(box |cx, span, substr| {
cs_partial_cmp(cx, span, substr)
})
};
@ -174,7 +174,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
equals_expr.clone(),
|cx, span, (self_args, tag_tuple), _non_self_args| {
box |cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `deriving(PartialOrd)`")
} else {
@ -222,7 +222,7 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
cx.expr_binary(span, ast::BiOr, cmp, and)
},
cx.expr_bool(span, equal),
|cx, span, (self_args, tag_tuple), _non_self_args| {
box |cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `deriving(PartialOrd)`")
} else {

View File

@ -32,7 +32,7 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
let block = cx.block(span, stmts, None);
cx.expr_block(block)
},
|cx, sp, _, _| cx.span_bug(sp, "non matching enums in deriving(Eq)?"),
box |cx, sp, _, _| cx.span_bug(sp, "non matching enums in deriving(Eq)?"),
cx,
span,
substr)
@ -57,7 +57,7 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
args: vec!(),
ret_ty: nil_ty(),
attributes: attrs,
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
cs_total_eq_assert(a, b, c)
})
}

View File

@ -41,7 +41,7 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
attributes: attrs,
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
cs_cmp(a, b, c)
}),
}
@ -130,7 +130,7 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
cx.expr_path(equals_path.clone()),
|cx, span, (self_args, tag_tuple), _non_self_args| {
box |cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
} else {

View File

@ -76,7 +76,7 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
true
)),
attributes: Vec::new(),
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
decodable_substructure(a, b, c, krate)
}),
})

View File

@ -40,7 +40,7 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
args: Vec::new(),
ret_ty: Self,
attributes: attrs,
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
default_substructure(a, b, c)
})
})

View File

@ -152,7 +152,7 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
true
)),
attributes: Vec::new(),
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
encodable_substructure(a, b, c)
}),
})

View File

@ -312,7 +312,7 @@ pub enum SubstructureFields<'a> {
/// Combine the values of all the fields together. The last argument is
/// all the fields of all the structures.
pub type CombineSubstructureFunc<'a> =
|&mut ExtCtxt, Span, &Substructure|: 'a -> P<Expr>;
Box<FnMut(&mut ExtCtxt, Span, &Substructure) -> P<Expr> + 'a>;
/// Deal with non-matching enum variants. The tuple is a list of
/// identifiers (one for each `Self` argument, which could be any of the
@ -320,11 +320,7 @@ pub type CombineSubstructureFunc<'a> =
/// holding the variant index value for each of the `Self` arguments. The
/// last argument is all the non-`Self` args of the method being derived.
pub type EnumNonMatchCollapsedFunc<'a> =
|&mut ExtCtxt,
Span,
(&[Ident], &[Ident]),
&[P<Expr>]|: 'a
-> P<Expr>;
Box<FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
-> RefCell<CombineSubstructureFunc<'a>> {
@ -606,7 +602,7 @@ impl<'a> MethodDef<'a> {
};
let mut f = self.combine_substructure.borrow_mut();
let f: &mut CombineSubstructureFunc = &mut *f;
(*f)(cx, trait_.span, &substructure)
f.call_mut((cx, trait_.span, &substructure))
}
fn get_ret_ty(&self,
@ -1341,7 +1337,7 @@ impl<'a> TraitDef<'a> {
pub fn cs_fold<F>(use_foldl: bool,
mut f: F,
base: P<Expr>,
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
mut enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
@ -1369,8 +1365,8 @@ pub fn cs_fold<F>(use_foldl: bool,
}
},
EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
enum_nonmatch_f(cx, trait_span, (all_args[], tuple),
substructure.nonself_args),
enum_nonmatch_f.call_mut((cx, trait_span, (all_args[], tuple),
substructure.nonself_args)),
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, "static function in `derive`")
}
@ -1387,7 +1383,7 @@ pub fn cs_fold<F>(use_foldl: bool,
/// ```
#[inline]
pub fn cs_same_method<F>(f: F,
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
mut enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
@ -1409,8 +1405,8 @@ pub fn cs_same_method<F>(f: F,
f(cx, trait_span, called)
},
EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
enum_nonmatch_f(cx, trait_span, (all_self_args[], tuple),
substructure.nonself_args),
enum_nonmatch_f.call_mut((cx, trait_span, (all_self_args[], tuple),
substructure.nonself_args)),
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, "static function in `derive`")
}

View File

@ -55,7 +55,7 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
ret_ty: nil_ty(),
attributes: attrs,
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
hash_substructure(a, b, c)
})
}

View File

@ -46,7 +46,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
true)),
// #[inline] liable to cause code-bloat
attributes: attrs.clone(),
combine_substructure: combine_substructure(|c, s, sub| {
combine_substructure: combine_substructure(box |c, s, sub| {
cs_from("i64", c, s, sub)
}),
},
@ -62,7 +62,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
true)),
// #[inline] liable to cause code-bloat
attributes: attrs,
combine_substructure: combine_substructure(|c, s, sub| {
combine_substructure: combine_substructure(box |c, s, sub| {
cs_from("u64", c, s, sub)
}),
})

View File

@ -45,7 +45,7 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
),
ret_ty: Self,
attributes: Vec::new(),
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
rand_substructure(a, b, c)
})
}

View File

@ -46,7 +46,7 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
args: vec!(fmtr),
ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
attributes: Vec::new(),
combine_substructure: combine_substructure(|a, b, c| {
combine_substructure: combine_substructure(box |a, b, c| {
show_substructure(a, b, c)
})
}

View File

@ -364,12 +364,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
fn visit_ty(&mut self, t: &ast::Ty) {
if let ast::TyClosure(ref closure) = t.node {
// this used to be blocked by a feature gate, but it should just
// be plain impossible right now
assert!(closure.onceness != ast::Once);
}
visit::walk_ty(self, t);
}

View File

@ -414,17 +414,6 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyRptr(region, mt) => {
TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt))
}
TyClosure(f) => {
TyClosure(f.map(|ClosureTy {unsafety, onceness, bounds, decl, lifetimes}| {
ClosureTy {
unsafety: unsafety,
onceness: onceness,
bounds: fld.fold_bounds(bounds),
decl: fld.fold_fn_decl(decl),
lifetimes: fld.fold_lifetime_defs(lifetimes)
}
}))
}
TyBareFn(f) => {
TyBareFn(f.map(|BareFnTy {lifetimes, unsafety, abi, decl}| BareFnTy {
lifetimes: fld.fold_lifetime_defs(lifetimes),

View File

@ -34,6 +34,7 @@ pub enum ObsoleteSyntax {
ObsoleteExternCrateRenaming,
ObsoleteProcType,
ObsoleteProcExpr,
ObsoleteClosureType,
}
pub trait ParserObsoleteMethods {
@ -94,6 +95,10 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
ObsoleteExternCrateRenaming => (
"`extern crate foo = bar` syntax",
"write `extern crate bar as foo` instead"
),
ObsoleteClosureType => (
"`|uint| -> bool` closure type syntax",
"use unboxed closures instead, no type annotation needed"
)
};

View File

@ -14,7 +14,7 @@ pub use self::PathParsingMode::*;
use self::ItemOrViewItem::*;
use abi;
use ast::{AssociatedType, BareFnTy, ClosureTy};
use ast::{AssociatedType, BareFnTy};
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
use ast::{ProvidedMethod, Public, Unsafety};
use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
@ -30,7 +30,6 @@ use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
use ast::{ExprMethodCall, ExprParen, ExprPath};
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
use ast::{Many};
use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
use ast::{FnOnceUnboxedClosureKind};
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
@ -55,7 +54,7 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
use ast::{TtDelimited, TtSequence, TtToken};
use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
use ast::{TypeField, TyFixedLengthVec, TyClosure, TyBareFn};
use ast::{TypeField, TyFixedLengthVec, TyBareFn};
use ast::{TyTypeof, TyInfer, TypeMethod};
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
@ -1227,38 +1226,29 @@ impl<'a> Parser<'a> {
*/
let unsafety = self.parse_unsafety();
let ty_closure_span = self.last_span;
let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs);
// To be helpful, parse the closure type as ever
let _ = self.parse_unsafety();
let inputs = if self.eat(&token::OrOr) {
Vec::new()
} else {
let _ = self.parse_legacy_lifetime_defs(lifetime_defs);
if !self.eat(&token::OrOr) {
self.expect_or();
let inputs = self.parse_seq_to_before_or(
let _ = self.parse_seq_to_before_or(
&token::Comma,
|p| p.parse_arg_general(false));
self.expect_or();
inputs
};
}
let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
let _ = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
let output = self.parse_ret_ty();
let decl = P(FnDecl {
inputs: inputs,
output: output,
variadic: false
});
let _ = self.parse_ret_ty();
TyClosure(P(ClosureTy {
unsafety: unsafety,
onceness: Many,
bounds: bounds,
decl: decl,
lifetimes: lifetime_defs,
}))
self.obsolete(ty_closure_span, ObsoleteClosureType);
TyInfer
}
pub fn parse_unsafety(&mut self) -> Unsafety {

View File

@ -714,25 +714,6 @@ impl<'a> State<'a> {
Some(&generics),
None));
}
ast::TyClosure(ref f) => {
let generics = ast::Generics {
lifetimes: f.lifetimes.clone(),
ty_params: OwnedSlice::empty(),
where_clause: ast::WhereClause {
id: ast::DUMMY_NODE_ID,
predicates: Vec::new(),
},
};
try!(self.print_ty_fn(None,
Some('&'),
f.unsafety,
f.onceness,
&*f.decl,
None,
&f.bounds,
Some(&generics),
None));
}
ast::TyPath(ref path, _) => {
try!(self.print_path(path, false));
}

View File

@ -404,14 +404,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
visitor.visit_ty(&**tuple_element_type)
}
}
TyClosure(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(&*argument.ty)
}
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
}
TyBareFn(ref function_declaration) => {
for argument in function_declaration.decl.inputs.iter() {
visitor.visit_ty(&*argument.ty)

View File

@ -1,3 +1,12 @@
S 2015-01-04 b2085d9
freebsd-x86_64 50ccb6bf9c0645d0746a5167493a39b2be40c2d4
linux-i386 b880b98d832c9a049b8ef6a50df50061e363de5a
linux-x86_64 82a09c162474b69d2d1e4e8399086f3f0f4e31c3
macos-i386 569055bb10d96ab25f78ecf2c80ffbccd5e69b8d
macos-x86_64 cff1f9ebd63dae6890359b7d353bd9486d8ecdfc
winnt-i386 553790fe493413287a19d17a42bf7225d3e2272d
winnt-x86_64 bab0d13960afb7ccdd6bf11452de1b9c457cc3e9
S 2015-01-02 c894171
freebsd-x86_64 ea8bcf75eada3539f5cbab51708eecf40d436b77
linux-i386 646ae265721e3cbe19404aae4fea4ffa1f1d90cf

View File

@ -11,12 +11,12 @@
#![crate_name="cci_impl_lib"]
pub trait uint_helpers {
fn to(&self, v: uint, f: |uint|);
fn to<F>(&self, v: uint, f: F) where F: FnMut(uint);
}
impl uint_helpers for uint {
#[inline]
fn to(&self, v: uint, f: |uint|) {
fn to<F>(&self, v: uint, mut f: F) where F: FnMut(uint) {
let mut i = *self;
while i < v {
f(i);

View File

@ -11,7 +11,7 @@
#![crate_name="cci_iter_lib"]
#[inline]
pub fn iter<T>(v: &[T], f: |&T|) {
pub fn iter<T, F>(v: &[T], mut f: F) where F: FnMut(&T) {
let mut i = 0u;
let n = v.len();
while i < n {

View File

@ -12,7 +12,7 @@
// same as cci_iter_lib, more-or-less, but not marked inline
pub fn iter(v: Vec<uint> , f: |uint|) {
pub fn iter<F>(v: Vec<uint> , mut f: F) where F: FnMut(uint) {
let mut i = 0u;
let n = v.len();
while i < n {

View File

@ -12,12 +12,12 @@
// part of issue-6919.rs
pub struct C<'a> {
pub k: ||: 'a,
pub struct C<K> where K: FnOnce() {
pub k: K,
}
fn no_op() { }
pub const D : C<'static> = C {
k: no_op
pub const D : C<fn()> = C {
k: no_op as fn()
};

Some files were not shown because too many files have changed in this diff Show More