typeck: Unify if-else blocks, match arms and array elements by coercing where possible.
This commit is contained in:
parent
d2c6bef493
commit
eb926dd4b7
11 changed files with 423 additions and 172 deletions
|
|
@ -20,13 +20,6 @@ trait Foo { fn foo() { /* this is a default fn */ } }
|
|||
impl<T> Foo for T { /* `foo` is still default here */ }
|
||||
|
||||
fn main() {
|
||||
let f = if true { foo::<u8> } else { bar::<u8> };
|
||||
//~^ ERROR if and else have incompatible types
|
||||
//~| expected `fn(isize) -> isize {foo::<u8>}`
|
||||
//~| found `fn(isize) -> isize {bar::<u8>}`
|
||||
//~| expected fn item,
|
||||
//~| found a different fn item
|
||||
|
||||
eq(foo::<u8>, bar::<u8>);
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `fn(isize) -> isize {foo::<u8>}`
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ fn main() {
|
|||
let y = match x {
|
||||
[] => None,
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected `[_#0i; 2]`
|
||||
//~| expected `[_#1i; 2]`
|
||||
//~| found `[_#7t; 0]`
|
||||
//~| expected an array with a fixed size of 2 elements
|
||||
//~| found one with 0 elements
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ impl Debug for Player {
|
|||
}
|
||||
|
||||
fn str_to_direction(to_parse: &str) -> RoomDirection {
|
||||
match to_parse {
|
||||
match to_parse { //~ ERROR match arms have incompatible types
|
||||
"w" | "west" => RoomDirection::West,
|
||||
"e" | "east" => RoomDirection::East,
|
||||
"n" | "north" => RoomDirection::North,
|
||||
|
|
@ -116,7 +116,7 @@ fn str_to_direction(to_parse: &str) -> RoomDirection {
|
|||
"out" => RoomDirection::Out,
|
||||
"up" => RoomDirection::Up,
|
||||
"down" => RoomDirection::Down,
|
||||
_ => None //~ ERROR mismatched types
|
||||
_ => None //~ NOTE match arm with an incompatible type
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,5 +21,5 @@ impl<A> vec_monad<A> for Vec<A> {
|
|||
}
|
||||
fn main() {
|
||||
["hi"].bind(|x| [x] );
|
||||
//~^ ERROR no method named `bind` found for type `[&str; 1]` in the current scope
|
||||
//~^ ERROR no method named `bind` found for type `[&'static str; 1]` in the current scope
|
||||
}
|
||||
|
|
|
|||
77
src/test/run-pass/coerce-unify.rs
Normal file
77
src/test/run-pass/coerce-unify.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
// Check that coercions can unify if-else, match arms and array elements.
|
||||
|
||||
// Try to construct if-else chains, matches and arrays out of given expressions.
|
||||
macro_rules! check {
|
||||
($last:expr $(, $rest:expr)+) => {
|
||||
// Last expression comes first because of whacky ifs and matches.
|
||||
let _ = $(if false { $rest })else+ else { $last };
|
||||
|
||||
let _ = match 0 { $(_ if false => $rest,)+ _ => $last };
|
||||
|
||||
let _ = [$($rest,)+ $last];
|
||||
}
|
||||
}
|
||||
|
||||
// Check all non-uniform cases of 2 and 3 expressions of 2 types.
|
||||
macro_rules! check2 {
|
||||
($a:expr, $b:expr) => {
|
||||
check!($a, $b);
|
||||
check!($b, $a);
|
||||
|
||||
check!($a, $a, $b);
|
||||
check!($a, $b, $a);
|
||||
check!($a, $b, $b);
|
||||
|
||||
check!($b, $a, $a);
|
||||
check!($b, $a, $b);
|
||||
check!($b, $b, $a);
|
||||
}
|
||||
}
|
||||
|
||||
// Check all non-uniform cases of 2 and 3 expressions of 3 types.
|
||||
macro_rules! check3 {
|
||||
($a:expr, $b:expr, $c:expr) => {
|
||||
// Delegate to check2 for cases where a type repeats.
|
||||
check2!($a, $b);
|
||||
check2!($b, $c);
|
||||
check2!($a, $c);
|
||||
|
||||
// Check the remaining cases, i.e. permutations of ($a, $b, $c).
|
||||
check!($a, $b, $c);
|
||||
check!($a, $c, $b);
|
||||
check!($b, $a, $c);
|
||||
check!($b, $c, $a);
|
||||
check!($c, $a, $b);
|
||||
check!($c, $b, $a);
|
||||
}
|
||||
}
|
||||
|
||||
use std::mem::size_of;
|
||||
|
||||
fn foo() {}
|
||||
fn bar() {}
|
||||
|
||||
pub fn main() {
|
||||
check3!(foo, bar, foo as fn());
|
||||
check3!(size_of::<u8>, size_of::<u16>, size_of::<usize> as fn() -> usize);
|
||||
|
||||
let s = String::from("bar");
|
||||
check2!("foo", &s);
|
||||
|
||||
let a = [1, 2, 3];
|
||||
let v = vec![1, 2, 3];
|
||||
check2!(&a[..], &v);
|
||||
|
||||
// Make sure in-array coercion still works.
|
||||
let _ = [("a", Default::default()), (Default::default(), "b"), (&s, &s)];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue