Auto merge of #21019 - nikomatsakis:issue-20871-ret-as-assoc-type, r=nrc

Fixes https://github.com/rust-lang/rust/issues/20871

r? @aturon (at least until we decide definitively if this is a good idea)
This commit is contained in:
bors 2015-01-28 11:01:36 +00:00
commit a45e117733
76 changed files with 1103 additions and 487 deletions

View file

@ -17,7 +17,9 @@ struct SFn {
y: isize,
}
impl Fn<(isize,),isize> for SFn {
impl Fn<(isize,)> for SFn {
type Output = isize;
extern "rust-call" fn call(&self, (z,): (isize,)) -> isize {
self.x * self.y * z
}
@ -28,7 +30,9 @@ struct SFnMut {
y: isize,
}
impl FnMut<(isize,),isize> for SFnMut {
impl FnMut<(isize,)> for SFnMut {
type Output = isize;
extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
self.x * self.y * z
}
@ -38,7 +42,9 @@ struct SFnOnce {
x: String,
}
impl FnOnce<(String,),usize> for SFnOnce {
impl FnOnce<(String,)> for SFnOnce {
type Output = usize;
extern "rust-call" fn call_once(self, (z,): (String,)) -> usize {
self.x.len() + z.len()
}

View file

@ -16,5 +16,7 @@ fn is_fn<F>(_: F) where F: Fn() {}
fn main() {
// extern functions are extern "C" fn
let _x: extern "C" fn() = f; // OK
is_fn(f); //~ ERROR the trait `core::ops::Fn()` is not implemented for the type `extern "C" fn()
is_fn(f);
//~^ ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
//~| ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
}

View file

@ -8,18 +8,38 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that manual impls of the `Fn` traits are not possible without
// a feature gate. In fact, the specialized check for these cases
// never triggers (yet), because they encounter other problems around
// angle bracket vs parentheses notation.
#![allow(dead_code)]
struct Foo;
impl Fn() for Foo { //~ ERROR manual implementations of `Fn` are experimental
impl Fn<()> for Foo {
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
type Output = ();
extern "rust-call" fn call(&self, args: ()) -> () {}
}
struct Foo1;
impl Fn() for Foo1 {
//~^ ERROR associated type bindings are not allowed here
extern "rust-call" fn call(&self, args: ()) -> () {}
}
struct Bar;
impl FnMut() for Bar { //~ ERROR manual implementations of `FnMut` are experimental
impl FnMut<()> for Bar {
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
type Output = ();
extern "rust-call" fn call_mut(&self, args: ()) -> () {}
}
struct Baz;
impl FnOnce() for Baz { //~ ERROR manual implementations of `FnOnce` are experimental
impl FnOnce<()> for Baz {
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
type Output = ();
extern "rust-call" fn call_once(&self, args: ()) -> () {}
}

View file

@ -34,5 +34,7 @@ fn main() {
//~| expected ()
//~| found box
needs_fn(1is); //~ ERROR `core::ops::Fn(isize) -> isize`
needs_fn(1is);
//~^ ERROR `core::ops::Fn<(isize,)>`
//~| ERROR `core::ops::Fn<(isize,)>`
}

View file

@ -16,7 +16,9 @@ struct Debuger<T> {
x: T
}
impl<T: fmt::Debug> ops::Fn<(), ()> for Debuger<T> {
impl<T: fmt::Debug> ops::Fn<(),> for Debuger<T> {
type Output = ();
fn call(&self, _args: ()) {
//~^ ERROR `call` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
println!("{:?}", self.x);

View file

@ -10,7 +10,7 @@
#![feature(unboxed_closures)]
pub fn foo<'a, F: Fn<(&'a (),), ()>>(bar: F) {
pub fn foo<'a, F: Fn(&'a ())>(bar: F) {
bar.call((
&(), //~ ERROR borrowed value does not live long enough
));

View file

@ -17,7 +17,9 @@ struct S {
y: isize,
}
impl FnMut<(isize,),isize> for S {
impl FnMut<(isize,)> for S {
type Output = isize;
extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
self.x * self.y * z
}

View file

@ -17,7 +17,8 @@ struct S {
y: isize,
}
impl FnMut<isize,isize> for S {
impl FnMut<isize> for S {
type Output = isize;
extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
self.x + self.y + z
}

View file

@ -9,15 +9,15 @@
// except according to those terms.
struct invariant<'a> {
struct Invariant<'a> {
f: Box<for<'b> FnOnce() -> &'b mut &'a isize + 'static>,
}
fn to_same_lifetime<'r>(bi: invariant<'r>) {
let bj: invariant<'r> = bi;
fn to_same_lifetime<'r>(bi: Invariant<'r>) {
let bj: Invariant<'r> = bi;
}
fn to_longer_lifetime<'r>(bi: invariant<'r>) -> invariant<'static> {
fn to_longer_lifetime<'r>(bi: Invariant<'r>) -> Invariant<'static> {
bi //~ ERROR mismatched types
}

View file

@ -11,7 +11,8 @@
// Check that parenthetical notation is feature-gated except with the
// `Fn` traits.
trait Foo<A,R> {
trait Foo<A> {
type Output;
}
fn main() {

View file

@ -14,8 +14,9 @@
#![feature(unboxed_closures)]
#![allow(dead_code)]
trait Foo<T,U,V=T> {
fn dummy(&self, t: T, u: U, v: V);
trait Foo<T,V=T> {
type Output;
fn dummy(&self, t: T, v: V);
}
trait Eq<X: ?Sized> { }
@ -24,14 +25,14 @@ fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
fn test<'a,'b>() {
// Parens are equivalent to omitting default in angle.
eq::< Foo<(isize,),()>, Foo(isize) >();
eq::< Foo<(isize,),Output=()>, Foo(isize) >();
// In angle version, we supply something other than the default
eq::< Foo<(isize,),(),isize>, Foo(isize) >();
eq::< Foo<(isize,),isize,Output=()>, Foo(isize) >();
//~^ ERROR not implemented
// Supply default explicitly.
eq::< Foo<(isize,),(),(isize,)>, Foo(isize) >();
eq::< Foo<(isize,),(isize,),Output=()>, Foo(isize) >();
}
fn main() { }

View file

@ -16,8 +16,9 @@
#![feature(unboxed_closures)]
#![allow(dead_code)]
trait Foo<T,U> {
fn dummy(&self, t: T, u: U);
trait Foo<T> {
type Output;
fn dummy(&self, t: T, u: Self::Output);
}
trait Eq<X: ?Sized> { }
@ -26,31 +27,32 @@ fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
fn test<'a,'b>() {
// No errors expected:
eq::< Foo<(),()>, Foo() >();
eq::< Foo<(isize,),()>, Foo(isize) >();
eq::< Foo<(isize,usize),()>, Foo(isize,usize) >();
eq::< Foo<(isize,usize),usize>, Foo(isize,usize) -> usize >();
eq::< Foo<(&'a isize,&'b usize),usize>, Foo(&'a isize,&'b usize) -> usize >();
eq::< Foo<(),Output=()>, Foo() >();
eq::< Foo<(isize,),Output=()>, Foo(isize) >();
eq::< Foo<(isize,usize),Output=()>, Foo(isize,usize) >();
eq::< Foo<(isize,usize),Output=usize>, Foo(isize,usize) -> usize >();
eq::< Foo<(&'a isize,&'b usize),Output=usize>, Foo(&'a isize,&'b usize) -> usize >();
// Test that anonymous regions in `()` form are equivalent
// to fresh bound regions, and that we can intermingle
// named and anonymous as we choose:
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),usize>,
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>,
for<'x,'y> Foo(&'x isize,&'y usize) -> usize >();
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),usize>,
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>,
for<'x> Foo(&'x isize,&usize) -> usize >();
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),usize>,
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>,
for<'y> Foo(&isize,&'y usize) -> usize >();
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),usize>,
eq::< for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>,
Foo(&isize,&usize) -> usize >();
// lifetime elision
eq::< for<'x> Foo<(&'x isize,), &'x isize>,
eq::< for<'x> Foo<(&'x isize,), Output=&'x isize>,
Foo(&isize) -> &isize >();
// Errors expected:
eq::< Foo<(),()>, Foo(char) >();
//~^ ERROR not implemented
eq::< Foo<(),Output=()>,
Foo(char) >();
//~^^ ERROR not implemented
}
fn main() { }

View file

@ -16,8 +16,9 @@
#![feature(unboxed_closures)]
#![allow(dead_code)]
trait Foo<T,U> {
fn dummy(&self, t: T, u: U);
trait Foo<T> {
type Output;
fn dummy(&self, t: T);
}
trait Eq<X: ?Sized> { }
@ -25,9 +26,9 @@ impl<X: ?Sized> Eq<X> for X { }
fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
fn main() {
eq::< for<'a> Foo<(&'a isize,), &'a isize>,
eq::< for<'a> Foo<(&'a isize,), Output=&'a isize>,
Foo(&isize) -> &isize >();
eq::< for<'a> Foo<(&'a isize,), (&'a isize, &'a isize)>,
eq::< for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>,
Foo(&isize) -> (&isize, &isize) >();
let _: Foo(&isize, &usize) -> &usize; //~ ERROR missing lifetime specifier

View file

@ -11,11 +11,11 @@
// Test that the `Fn` traits require `()` form without a feature gate.
fn bar1(x: &Fn<(),()>) {
fn bar1(x: &Fn<()>) {
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family
}
fn bar2<T>(x: &T) where T: Fn<(),()> {
fn bar2<T>(x: &T) where T: Fn<()> {
//~^ ERROR angle-bracket notation is not stable when used with the `Fn` family
}

View file

@ -17,8 +17,9 @@
use std::marker;
trait Foo<'a,T,U> {
fn dummy(&'a self) -> &'a (T,U);
trait Foo<'a,T> {
type Output;
fn dummy(&'a self) -> &'a (T,Self::Output);
}
trait Eq<X: ?Sized> { }
@ -29,16 +30,17 @@ fn same_type<A,B:Eq<A>>(a: A, b: B) { }
fn test<'a,'b>() {
// Parens are equivalent to omitting default in angle.
eq::< Foo<(isize,),()>, Foo(isize) >();
eq::< Foo<(isize,),Output=()>, Foo(isize) >();
// Here we specify 'static explicitly in angle-bracket version.
// Parenthesized winds up getting inferred.
eq::< Foo<'static, (isize,),()>, Foo(isize) >();
eq::< Foo<'static, (isize,),Output=()>, Foo(isize) >();
}
fn test2(x: &Foo<(isize,),()>, y: &Foo(isize)) {
fn test2(x: &Foo<(isize,),Output=()>, y: &Foo(isize)) {
// Here, the omitted lifetimes are expanded to distinct things.
same_type(x, y) //~ ERROR cannot infer
//~^ ERROR cannot infer
}
fn main() { }

View file

@ -11,13 +11,14 @@
// Test that parentheses form doesn't work with struct types appearing in local variables.
struct Bar<A,R> {
f: A, r: R
struct Bar<A> {
f: A
}
fn bar() {
let x: Box<Bar()> = panic!();
//~^ ERROR parenthesized parameters may only be used with a trait
//~^^ ERROR associated type bindings are not allowed here
}
fn main() { }

View file

@ -10,12 +10,13 @@
// Test that parentheses form doesn't work with struct types appearing in argument types.
struct Bar<A,R> {
f: A, r: R
struct Bar<A> {
f: A
}
fn foo(b: Box<Bar()>) {
//~^ ERROR parenthesized parameters may only be used with a trait
//~^^ ERROR associated type bindings are not allowed here
}
fn main() { }

View file

@ -12,7 +12,7 @@
trait One<A> { fn foo(&self) -> A; }
fn foo(_: &One()) //~ ERROR wrong number of type arguments
fn foo(_: &One()) //~ ERROR no associated type `Output` defined in `One<()>`
{}
fn main() { }

View file

@ -13,7 +13,7 @@
trait Trait {}
fn f<F:Trait(isize) -> isize>(x: F) {}
//~^ ERROR wrong number of type arguments: expected 0, found 2
//~^ ERROR wrong number of type arguments: expected 0, found 1
fn main() {}

View file

@ -18,7 +18,9 @@ use std::ops::{Fn,FnMut,FnOnce};
struct S;
impl FnMut<(isize,),isize> for S {
impl FnMut<(isize,)> for S {
type Output = isize;
extern "rust-call" fn call_mut(&mut self, (x,): (isize,)) -> isize {
x * x
}
@ -29,6 +31,8 @@ fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
}
fn main() {
let x = call_it(&S, 22); //~ ERROR not implemented
let x = call_it(&S, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}

View file

@ -21,7 +21,9 @@ fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
fn a() {
let x = call_it(&square, 22); //~ ERROR not implemented
let x = call_it(&square, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}
fn b() {

View file

@ -12,13 +12,15 @@
use std::ops::FnMut;
fn call_it<F:FnMut<(isize,isize),isize>>(y: isize, mut f: F) -> isize {
fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
f(2, y)
}
pub fn main() {
let f = |&mut: x: usize, y: isize| -> isize { (x as isize) + y };
let z = call_it(3, f); //~ ERROR type mismatch
let z = call_it(3, f);
//~^ ERROR type mismatch
//~| ERROR type mismatch
println!("{}", z);
}

View file

@ -21,7 +21,9 @@ fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
fn a() {
let x = call_it(&square, 22); //~ ERROR not implemented
let x = call_it(&square, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}
fn b() {

View file

@ -22,7 +22,9 @@ fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
fn a() {
let x = call_it(&square, 22); //~ ERROR not implemented
let x = call_it(&square, 22);
//~^ ERROR not implemented
//~| ERROR not implemented
}
fn b() {

View file

@ -18,5 +18,6 @@ fn main() {
let z: isize = 7;
assert_eq!(c(|&mut: x: isize, y| x + y + z), 10);
//~^ ERROR not implemented
//~| ERROR not implemented
}

View file

@ -0,0 +1,24 @@
// Copyright 2012 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.
// Test that Cell is considered invariant with respect to its
// type.
use std::cell::Cell;
// For better or worse, associated types are invariant, and hence we
// get an invariant result for `'a`.
#[rustc_variance]
struct Foo<'a> { //~ ERROR regions=[[o];[];[]]
x: Box<Fn(i32) -> &'a i32 + 'static>
}
fn main() {
}

View file

@ -0,0 +1,28 @@
// Copyright 2015 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.
// Regression test for #21212: an overflow occurred during trait
// checking where normalizing `Self::Input` led to normalizing the
// where clauses in the environment which in turn required normalizing
// `Self::Input`.
pub trait Parser {
type Input;
fn parse(input: <Self as Parser>::Input) {
panic!()
}
}
impl <P> Parser for P {
type Input = ();
}
fn main() {
}

View file

@ -0,0 +1,42 @@
// Copyright 2015 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.
// Test that we normalize associated types that appear in a bound that
// contains a binding. Issue #21664.
#![allow(dead_code)]
pub trait Integral {
type Opposite;
}
impl Integral for i32 {
type Opposite = u32;
}
impl Integral for u32 {
type Opposite = i32;
}
pub trait FnLike<A> {
type R;
}
fn foo<T>()
where T : FnLike<<i32 as Integral>::Opposite, R=bool>
{
bar::<T>();
}
fn bar<T>()
where T : FnLike<u32, R=bool>
{}
fn main() { }

View file

@ -12,7 +12,7 @@
use std::ops::FnMut;
fn call_f<F:FnMut<(),()>>(mut f: F) {
fn call_f<F:FnMut()>(mut f: F) {
f();
}
@ -20,7 +20,7 @@ fn f() {
println!("hello");
}
fn call_g<G:FnMut<(String,String),String>>(mut g: G, x: String, y: String)
fn call_g<G:FnMut(String,String) -> String>(mut g: G, x: String, y: String)
-> String {
g(x, y)
}

View file

@ -22,23 +22,23 @@ trait Get<A,R> {
// Parse HRTB with explicit `for` in a where-clause:
fn foo00<T>(t: T)
where T : for<'a> Get<&'a int, &'a int>
where T : for<'a> Get<&'a i32, &'a i32>
{
}
fn foo01<T: for<'a> Get<&'a int, &'a int>>(t: T)
fn foo01<T: for<'a> Get<&'a i32, &'a i32>>(t: T)
{
}
// Parse HRTB with explicit `for` in various sorts of types:
fn foo10(t: Box<for<'a> Get<int, int>>) { }
fn foo11(t: Box<for<'a> Get(int) -> int>) { }
fn foo10(t: Box<for<'a> Get<i32, i32>>) { }
fn foo11(t: Box<for<'a> Fn(i32) -> i32>) { }
fn foo20(t: for<'a> fn(int) -> int) { }
fn foo21(t: for<'a> unsafe fn(int) -> int) { }
fn foo22(t: for<'a> extern "C" fn(int) -> int) { }
fn foo23(t: for<'a> unsafe extern "C" fn(int) -> int) { }
fn foo20(t: for<'a> fn(i32) -> i32) { }
fn foo21(t: for<'a> unsafe fn(i32) -> i32) { }
fn foo22(t: for<'a> extern "C" fn(i32) -> i32) { }
fn foo23(t: for<'a> unsafe extern "C" fn(i32) -> i32) { }
fn main() {
}

View file

@ -16,7 +16,7 @@ trait FnLike<A,R> {
fn call(&self, arg: A) -> R;
}
type FnObject<'b> = for<'a> FnLike(&'a int) -> (&'a int) + 'b;
type FnObject<'b> = for<'a> FnLike<(&'a i32,), &'a i32> + 'b;
struct Identity;

View file

@ -13,7 +13,8 @@ use std::ops::Fn;
struct Foo<T>(T);
impl<T: Copy> Fn<(), T> for Foo<T> {
impl<T: Copy> Fn<()> for Foo<T> {
type Output = T;
extern "rust-call" fn call(&self, _: ()) -> T {
match *self {
Foo(t) => t

View file

@ -14,7 +14,8 @@ trait Foo {}
struct Bar;
impl<'a> std::ops::Fn<(&'a (Foo+'a),), ()> for Bar {
impl<'a> std::ops::Fn<(&'a (Foo+'a),)> for Bar {
type Output = ();
extern "rust-call" fn call(&self, _: (&'a Foo,)) {}
}

View file

@ -33,7 +33,9 @@ impl Alloy {
}
}
impl<'a, 'b> Fn<(&'b mut (Response+'b),),()> for SendFile<'a> {
impl<'a, 'b> Fn<(&'b mut (Response+'b),)> for SendFile<'a> {
type Output = ();
extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
}

View file

@ -15,7 +15,7 @@
#![feature(unboxed_closures)]
struct Parser<'a, I, O> {
parse: Box<FnMut<(I,), Result<O, String>> + 'a>
parse: Box<FnMut(I) -> Result<O, String> + 'a>
}
impl<'a, I, O: 'a> Parser<'a, I, O> {

View file

@ -15,27 +15,30 @@
// Test that unboxing shim for calling rust-call ABI methods through a
// trait box works and does not cause an ICE.
struct Foo { foo: uint }
struct Foo { foo: u32 }
impl FnMut<(), uint> for Foo {
extern "rust-call" fn call_mut(&mut self, _: ()) -> uint { self.foo }
impl FnMut<()> for Foo {
type Output = u32;
extern "rust-call" fn call_mut(&mut self, _: ()) -> u32 { self.foo }
}
impl FnMut<(uint,), uint> for Foo {
extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> uint { self.foo + x }
impl FnMut<(u32,)> for Foo {
type Output = u32;
extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x }
}
impl FnMut<(uint, uint), uint> for Foo {
extern "rust-call" fn call_mut(&mut self, (x, y): (uint, uint)) -> uint { self.foo + x + y }
impl FnMut<(u32,u32)> for Foo {
type Output = u32;
extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y }
}
fn main() {
let mut f = box Foo { foo: 42 } as Box<FnMut<(), uint>>;
let mut f = box Foo { foo: 42 } as Box<FnMut() -> u32>;
assert_eq!(f.call_mut(()), 42);
let mut f = box Foo { foo: 40 } as Box<FnMut<(uint,), uint>>;
let mut f = box Foo { foo: 40 } as Box<FnMut(u32) -> u32>;
assert_eq!(f.call_mut((2,)), 42);
let mut f = box Foo { foo: 40 } as Box<FnMut<(uint, uint), uint>>;
let mut f = box Foo { foo: 40 } as Box<FnMut(u32, u32) -> u32>;
assert_eq!(f.call_mut((1, 1)), 42);
}

View file

@ -0,0 +1,36 @@
// Copyright 2015 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.
// Test for using an object with an associated type binding as the
// instantiation for a generic type with a bound.
trait SomeTrait {
type SomeType;
fn get(&self) -> Self::SomeType;
}
fn get_int<T:SomeTrait<SomeType=i32>+?Sized>(x: &T) -> i32 {
x.get()
}
impl SomeTrait for i32 {
type SomeType = i32;
fn get(&self) -> i32 {
*self
}
}
fn main() {
let x = 22_i32;
let x1: &SomeTrait<SomeType=i32> = &x;
let y = get_int(x1);
assert_eq!(x, y);
}

View file

@ -17,13 +17,15 @@ use std::ops::Add;
struct G<A>;
impl<'a, A: Add<int, Output=int>> Fn<(A,), int> for G<A> {
extern "rust-call" fn call(&self, (arg,): (A,)) -> int {
impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
type Output = i32;
extern "rust-call" fn call(&self, (arg,): (A,)) -> i32 {
arg.add(1)
}
}
fn main() {
// ICE trigger
G(1i);
G(1_i32);
}

View file

@ -13,34 +13,37 @@
use std::ops::{Fn, FnMut, FnOnce};
struct S1 {
x: int,
y: int,
x: i32,
y: i32,
}
impl FnMut<(int,),int> for S1 {
extern "rust-call" fn call_mut(&mut self, (z,): (int,)) -> int {
impl FnMut<(i32,)> for S1 {
type Output = i32;
extern "rust-call" fn call_mut(&mut self, (z,): (i32,)) -> i32 {
self.x * self.y * z
}
}
struct S2 {
x: int,
y: int,
x: i32,
y: i32,
}
impl Fn<(int,),int> for S2 {
extern "rust-call" fn call(&self, (z,): (int,)) -> int {
impl Fn<(i32,)> for S2 {
type Output = i32;
extern "rust-call" fn call(&self, (z,): (i32,)) -> i32 {
self.x * self.y * z
}
}
struct S3 {
x: int,
y: int,
x: i32,
y: i32,
}
impl FnOnce<(int,int),int> for S3 {
extern "rust-call" fn call_once(self, (z,zz): (int,int)) -> int {
impl FnOnce<(i32,i32)> for S3 {
type Output = i32;
extern "rust-call" fn call_once(self, (z,zz): (i32,i32)) -> i32 {
self.x * self.y * z * zz
}
}

View file

@ -13,12 +13,13 @@
use std::ops::{FnMut};
struct S {
x: int,
y: int,
x: i32,
y: i32,
}
impl FnMut<(),int> for S {
extern "rust-call" fn call_mut(&mut self, (): ()) -> int {
impl FnMut<()> for S {
type Output = i32;
extern "rust-call" fn call_mut(&mut self, (): ()) -> i32 {
self.x * self.y
}
}

View file

@ -14,9 +14,9 @@
use std::ops::FnMut;
fn make_adder(x: int) -> Box<FnMut<(int,),int>+'static> {
(box move |&mut: y: int| -> int { x + y }) as
Box<FnMut<(int,),int>+'static>
fn make_adder(x: i32) -> Box<FnMut(i32)->i32+'static> {
(box move |&mut: y: i32| -> i32 { x + y }) as
Box<FnMut(i32)->i32+'static>
}
pub fn main() {

View file

@ -18,21 +18,22 @@ use std::ops::{Fn,FnMut,FnOnce};
struct S;
impl Fn<(int,),int> for S {
extern "rust-call" fn call(&self, (x,): (int,)) -> int {
impl Fn<(i32,)> for S {
type Output = i32;
extern "rust-call" fn call(&self, (x,): (i32,)) -> i32 {
x * x
}
}
fn call_it<F:Fn(int)->int>(f: &F, x: int) -> int {
fn call_it<F:Fn(i32)->i32>(f: &F, x: i32) -> i32 {
f(x)
}
fn call_it_mut<F:FnMut(int)->int>(f: &mut F, x: int) -> int {
fn call_it_mut<F:FnMut(i32)->i32>(f: &mut F, x: i32) -> i32 {
f(x)
}
fn call_it_once<F:FnOnce(int)->int>(f: F, x: int) -> int {
fn call_it_once<F:FnOnce(i32)->i32>(f: F, x: i32) -> i32 {
f(x)
}

View file

@ -18,17 +18,19 @@ use std::ops::{FnMut,FnOnce};
struct S;
impl FnMut<(int,),int> for S {
extern "rust-call" fn call_mut(&mut self, (x,): (int,)) -> int {
impl FnMut<(i32,)> for S {
type Output = i32;
extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
x * x
}
}
fn call_it_mut<F:FnMut(int)->int>(f: &mut F, x: int) -> int {
fn call_it_mut<F:FnMut(i32)->i32>(f: &mut F, x: i32) -> i32 {
f(x)
}
fn call_it_once<F:FnOnce(int)->int>(f: F, x: int) -> int {
fn call_it_once<F:FnOnce(i32)->i32>(f: F, x: i32) -> i32 {
f(x)
}

View file

@ -12,12 +12,12 @@
use std::ops::FnMut;
fn call_it<F:FnMut<(int,int),int>>(y: int, mut f: F) -> int {
fn call_it<F:FnMut(i32,i32)->i32>(y: i32, mut f: F) -> i32 {
f(2, y)
}
pub fn main() {
let f = |&mut: x: int, y: int| -> int { x + y };
let f = |&mut: x: i32, y: i32| -> i32 { x + y };
let z = call_it(3, f);
println!("{}", z);
assert_eq!(z, 5);

View file

@ -15,17 +15,19 @@ use std::ops::FnMut;
struct S;
impl FnMut<(int,),int> for S {
extern "rust-call" fn call_mut(&mut self, (x,): (int,)) -> int {
impl FnMut<(i32,)> for S {
type Output = i32;
extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
x * x
}
}
fn call_it<F:FnMut(int)->int>(mut f: F, x: int) -> int {
fn call_it<F:FnMut(i32)->i32>(mut f: F, x: i32) -> i32 {
f(x) + 3
}
fn call_box(f: &mut FnMut(int) -> int, x: int) -> int {
fn call_box(f: &mut FnMut(i32) -> i32, x: i32) -> i32 {
f(x) + 3
}

View file

@ -16,17 +16,17 @@
#![feature(unboxed_closures)]
fn main(){
fn bar<'a, T:Clone+'a> (t: T) -> Box<FnMut<(),T> + 'a> {
fn bar<'a, T:Clone+'a> (t: T) -> Box<FnMut()->T + 'a> {
box move |&mut:| t.clone()
}
let mut f = bar(42u);
let mut f = bar(42_u32);
assert_eq!(f.call_mut(()), 42);
let mut f = bar("forty-two");
assert_eq!(f.call_mut(()), "forty-two");
let x = 42u;
let x = 42_u32;
let mut f = bar(&x);
assert_eq!(f.call_mut(()), &x);

View file

@ -29,7 +29,7 @@ impl<X> Getter<X,X> for Identity {
}
fn main() {
let x: &Getter(int) -> (int,) = &Identity;
let x: &Getter<(i32,), (i32,)> = &Identity;
let (y,) = x.get((22,));
assert_eq!(y, 22);
}