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:
commit
a45e117733
76 changed files with 1103 additions and 487 deletions
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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: ()) -> () {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,)>`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
24
src/test/compile-fail/variance-object-types.rs
Normal file
24
src/test/compile-fail/variance-object-types.rs
Normal 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() {
|
||||
}
|
||||
28
src/test/run-pass/associated-types-issue-21212.rs
Normal file
28
src/test/run-pass/associated-types-issue-21212.rs
Normal 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() {
|
||||
}
|
||||
|
|
@ -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() { }
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,)) {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),)) {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
36
src/test/run-pass/object-method-numbering.rs
Normal file
36
src/test/run-pass/object-method-numbering.rs
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue