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:
commit
c7dd3c4d69
|
@ -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),
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ mod num;
|
|||
mod ops;
|
||||
mod option;
|
||||
mod ptr;
|
||||
mod raw;
|
||||
mod result;
|
||||
mod slice;
|
||||
mod str;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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(..) |
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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(..) |
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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));
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ¶meter_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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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[])
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,...)`)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}),
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}),
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
}),
|
||||
})
|
||||
|
|
|
@ -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`")
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}),
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue