Added support for type placeholders (explicit requested type

inference in a type with `_` ). This enables partial type inference.
This commit is contained in:
Marvin Löbel 2014-03-11 00:17:46 +01:00
parent 6c895d1d58
commit eb69eb36f8
10 changed files with 236 additions and 11 deletions

View file

@ -0,0 +1,119 @@
// 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.
// This test checks that it is not possible to enable global type
// inference by using the `_` type placeholder.
fn test() -> _ { 5 }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn test2() -> (_, _) { (5u, 5u) }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures.
static TEST3: _ = "test";
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
static TEST4: _ = 145u16;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
static TEST5: (_, _) = (1, 2);
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn test6(_: _) { }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn test7(x: _) { let _x: uint = x; }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn test8(_f: fn() -> _) { }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
struct Test9;
impl Test9 {
fn test9(&self) -> _ { () }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn test10(&self, _x : _) { }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
}
impl Clone for Test9 {
fn clone(&self) -> _ { Test9 }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn clone_from(&mut self, other: _) { *self = Test9; }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
}
struct Test10 {
a: _,
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
b: (_, _),
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures.
}
pub fn main() {
fn fn_test() -> _ { 5 }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn fn_test2() -> (_, _) { (5u, 5u) }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures.
static FN_TEST3: _ = "test";
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
static FN_TEST4: _ = 145u16;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
static FN_TEST5: (_, _) = (1, 2);
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn fn_test6(_: _) { }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn fn_test7(x: _) { let _x: uint = x; }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn fn_test8(_f: fn() -> _) { }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
struct FnTest9;
impl FnTest9 {
fn fn_test9(&self) -> _ { () }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn fn_test10(&self, _x : _) { }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
}
impl Clone for FnTest9 {
fn clone(&self) -> _ { FnTest9 }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
fn clone_from(&mut self, other: _) { *self = FnTest9; }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
}
struct FnTest10 {
a: _,
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
b: (_, _),
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures.
//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures.
}
}

View file

@ -0,0 +1,21 @@
// 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.
// This test checks that the `_` type placeholder does not react
// badly if put as a lifetime parameter.
struct Foo<'a, T> {
r: &'a T
}
pub fn main() {
let c: Foo<_, _> = Foo { r: &5u };
//~^ ERROR wrong number of type arguments: expected 1 but found 2
}

View file

@ -0,0 +1,21 @@
// 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.
// This test checks that the `_` type placeholder does not react
// badly if put as a lifetime parameter.
struct Foo<'a, T> {
r: &'a T
}
pub fn main() {
let c: Foo<_, uint> = Foo { r: &5 };
//~^ ERROR wrong number of type arguments: expected 1 but found 2
}

View file

@ -0,0 +1,30 @@
// 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.
// This test checks that genuine type errors with partial
// type hints are understandable.
struct Foo<T>;
struct Bar<U>;
pub fn main() {
}
fn test1() {
let x: Foo<_> = Bar::<uint>;
//~^ ERROR mismatched types: expected `Foo<<generic #0>>` but found `Bar<uint>`
let y: Foo<uint> = x;
}
fn test2() {
let x: Foo<_> = Bar::<uint>;
//~^ ERROR mismatched types: expected `Foo<<generic #0>>` but found `Bar<uint>`
//~^^ ERROR cannot determine a type for this local variable: unconstrained type
}

View file

@ -0,0 +1,32 @@
// 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.
// This test checks that the `_` type placeholder works
// correctly for enabling type inference.
static CONSTEXPR: *int = &'static 413 as *_;
pub fn main() {
use std::vec_ng::Vec;
let x: Vec<_> = range(0u, 5).collect();
assert_eq!(x.as_slice(), &[0u,1,2,3,4]);
let x = range(0u, 5).collect::<Vec<_>>();
assert_eq!(x.as_slice(), &[0u,1,2,3,4]);
let y: _ = "hello";
assert_eq!(y.len(), 5);
let ptr = &5u;
let ptr2 = ptr as *_;
assert_eq!(ptr as *uint as uint, ptr2 as uint);
}