2015-12-13 07:48:43 -06:00
|
|
|
// 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.
|
|
|
|
|
2016-02-11 10:30:34 -06:00
|
|
|
#![feature(rustc_attrs, unboxed_closures, fn_traits)]
|
2015-12-13 07:48:43 -06:00
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
|
|
|
|
// Test passing a number of arguments including a fat pointer.
|
|
|
|
// Also returning via an out pointer
|
|
|
|
fn callee(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
|
|
|
|
(a, b, c)
|
|
|
|
}
|
|
|
|
callee(a, b, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test2(a: isize) -> isize {
|
|
|
|
// Test passing a single argument.
|
|
|
|
// Not using out pointer.
|
|
|
|
fn callee(a: isize) -> isize {
|
|
|
|
a
|
|
|
|
}
|
|
|
|
callee(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Foo;
|
|
|
|
impl Foo {
|
|
|
|
fn inherent_method(&self, a: isize) -> isize { a }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test3(x: &Foo, a: isize) -> isize {
|
|
|
|
// Test calling inherent method
|
|
|
|
x.inherent_method(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
trait Bar {
|
|
|
|
fn extension_method(&self, a: isize) -> isize { a }
|
|
|
|
}
|
|
|
|
impl Bar for Foo {}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test4(x: &Foo, a: isize) -> isize {
|
|
|
|
// Test calling extension method
|
|
|
|
x.extension_method(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test5(x: &Bar, a: isize) -> isize {
|
|
|
|
// Test calling method on trait object
|
|
|
|
x.extension_method(a)
|
|
|
|
}
|
|
|
|
|
2016-01-06 15:50:54 -06:00
|
|
|
#[rustc_mir]
|
|
|
|
fn test6<T: Bar>(x: &T, a: isize) -> isize {
|
|
|
|
// Test calling extension method on generic callee
|
|
|
|
x.extension_method(a)
|
|
|
|
}
|
2015-12-13 07:48:43 -06:00
|
|
|
|
|
|
|
trait One<T = Self> {
|
|
|
|
fn one() -> T;
|
|
|
|
}
|
|
|
|
impl One for isize {
|
|
|
|
fn one() -> isize { 1 }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test7() -> isize {
|
|
|
|
// Test calling trait static method
|
|
|
|
<isize as One>::one()
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Two;
|
|
|
|
impl Two {
|
|
|
|
fn two() -> isize { 2 }
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test8() -> isize {
|
|
|
|
// Test calling impl static method
|
|
|
|
Two::two()
|
|
|
|
}
|
|
|
|
|
2016-01-12 07:20:18 -06:00
|
|
|
extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
|
|
|
|
x + y.0 * y.1
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test9() -> u32 {
|
|
|
|
simple_extern(41, (42, 43))
|
|
|
|
}
|
|
|
|
|
2016-01-04 05:08:11 -06:00
|
|
|
#[rustc_mir]
|
2016-01-05 11:32:49 -06:00
|
|
|
fn test_closure<F>(f: &F, x: i32, y: i32) -> i32
|
|
|
|
where F: Fn(i32, i32) -> i32
|
|
|
|
{
|
2016-01-04 05:08:11 -06:00
|
|
|
f(x, y)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_object(f: &Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
|
|
|
|
f(x, y)
|
|
|
|
}
|
|
|
|
|
2016-01-05 11:32:49 -06:00
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_impl(f: &&Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
|
|
|
|
// This call goes through the Fn implementation for &Fn provided in
|
|
|
|
// core::ops::impls. It expands to a static Fn::call() that calls the
|
2016-02-09 10:52:39 -06:00
|
|
|
// Fn::call() implementation of the object shim underneath.
|
2016-01-05 11:32:49 -06:00
|
|
|
f(x, y)
|
|
|
|
}
|
|
|
|
|
2016-02-11 10:30:34 -06:00
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_direct_call<F>(f: &F, x: i32, y: i32) -> i32
|
|
|
|
where F: Fn(i32, i32) -> i32
|
|
|
|
{
|
|
|
|
f.call((x, y))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_const_call<F>(f: &F) -> i32
|
|
|
|
where F: Fn(i32, i32) -> i32
|
|
|
|
{
|
|
|
|
f.call((100, -1))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_nil_call<F>(f: &F) -> i32
|
|
|
|
where F: Fn() -> i32
|
|
|
|
{
|
|
|
|
f()
|
|
|
|
}
|
|
|
|
|
2016-05-07 14:59:03 -05:00
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_transmute_zst(x: ()) -> [(); 1] {
|
|
|
|
fn id<T>(x: T) -> T {x}
|
|
|
|
|
|
|
|
id(unsafe {
|
|
|
|
std::mem::transmute(x)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-06-06 16:24:21 -05:00
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_ignored_pair() -> ((), ()) {
|
|
|
|
((), ())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustc_mir]
|
|
|
|
fn test_fn_ignored_pair_0() {
|
|
|
|
test_fn_ignored_pair().0
|
|
|
|
}
|
|
|
|
|
2015-12-13 07:48:43 -06:00
|
|
|
fn main() {
|
|
|
|
assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..]));
|
|
|
|
assert_eq!(test2(98), 98);
|
|
|
|
assert_eq!(test3(&Foo, 42), 42);
|
|
|
|
assert_eq!(test4(&Foo, 970), 970);
|
|
|
|
assert_eq!(test5(&Foo, 8576), 8576);
|
2016-01-06 15:50:54 -06:00
|
|
|
assert_eq!(test6(&Foo, 12367), 12367);
|
2015-12-13 07:48:43 -06:00
|
|
|
assert_eq!(test7(), 1);
|
|
|
|
assert_eq!(test8(), 2);
|
2016-01-12 07:20:18 -06:00
|
|
|
assert_eq!(test9(), 41 + 42 * 43);
|
2016-01-04 05:08:11 -06:00
|
|
|
|
2016-02-11 10:30:34 -06:00
|
|
|
let r = 3;
|
|
|
|
let closure = |x: i32, y: i32| { r*(x + (y*2)) };
|
|
|
|
assert_eq!(test_fn_const_call(&closure), 294);
|
|
|
|
assert_eq!(test_closure(&closure, 100, 1), 306);
|
2016-01-05 11:32:49 -06:00
|
|
|
let function_object = &closure as &Fn(i32, i32) -> i32;
|
2016-02-11 10:30:34 -06:00
|
|
|
assert_eq!(test_fn_object(function_object, 100, 2), 312);
|
|
|
|
assert_eq!(test_fn_impl(&function_object, 100, 3), 318);
|
|
|
|
assert_eq!(test_fn_direct_call(&closure, 100, 4), 324);
|
|
|
|
|
|
|
|
assert_eq!(test_fn_nil_call(&(|| 42)), 42);
|
2016-05-07 14:59:03 -05:00
|
|
|
assert_eq!(test_fn_transmute_zst(()), [()]);
|
2016-06-06 16:24:21 -05:00
|
|
|
|
|
|
|
assert_eq!(test_fn_ignored_pair_0(), ());
|
2015-12-13 07:48:43 -06:00
|
|
|
}
|