more detailed tests around diverging type variables
This commit is contained in:
parent
52e524a357
commit
5cd99aa167
@ -22,16 +22,6 @@ fn deserialize() -> Result<(), String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn doit() -> Result<(), String> {
|
||||
let _ = match Deserialize::deserialize() {
|
||||
//~^ ERROR code relies on type
|
||||
//~| WARNING previously accepted
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
trait ImplementedForUnitButNotNever {}
|
||||
|
||||
impl ImplementedForUnitButNotNever for () {}
|
||||
@ -46,6 +36,6 @@ fn smeg() {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = doit();
|
||||
smeg();
|
||||
}
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
// 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 diverging types default to ! when feature(never_type) is enabled. This test is the
|
||||
// same as run-pass/unit-fallback.rs except that ! is enabled.
|
||||
|
||||
#![feature(never_type)]
|
||||
|
||||
trait Balls: Sized {
|
||||
fn smeg() -> Result<Self, ()>;
|
||||
}
|
||||
|
||||
impl Balls for () {
|
||||
fn smeg() -> Result<(), ()> { Ok(()) }
|
||||
}
|
||||
|
||||
struct Flah;
|
||||
|
||||
impl Flah {
|
||||
fn flah<T: Balls>(&self) -> Result<T, ()> {
|
||||
T::smeg()
|
||||
}
|
||||
}
|
||||
|
||||
fn doit() -> Result<(), ()> {
|
||||
// The type of _ is unconstrained here and should default to !
|
||||
let _ = try!(Flah.flah()); //~ ERROR the trait bound
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = doit();
|
||||
}
|
||||
|
106
src/test/run-pass/diverging-fallback-control-flow.rs
Normal file
106
src/test/run-pass/diverging-fallback-control-flow.rs
Normal file
@ -0,0 +1,106 @@
|
||||
// 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 various cases where we permit an unconstrained variable
|
||||
// to fallback based on control-flow.
|
||||
//
|
||||
// These represent current behavior, but are pretty dubious. I would
|
||||
// like to revisit these and potentially change them. --nmatsakis
|
||||
|
||||
#![feature(never_type)]
|
||||
#![feature(loop_break_value)]
|
||||
|
||||
trait BadDefault {
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
||||
impl BadDefault for u32 {
|
||||
fn default() -> Self {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl BadDefault for ! {
|
||||
fn default() -> ! {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
fn assignment() {
|
||||
let x;
|
||||
|
||||
if true {
|
||||
x = BadDefault::default();
|
||||
} else {
|
||||
x = return;
|
||||
}
|
||||
}
|
||||
|
||||
fn assignment_rev() {
|
||||
let x;
|
||||
|
||||
if true {
|
||||
x = return;
|
||||
} else {
|
||||
x = BadDefault::default();
|
||||
}
|
||||
}
|
||||
|
||||
fn if_then_else() {
|
||||
let _x = if true {
|
||||
BadDefault::default()
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
fn if_then_else_rev() {
|
||||
let _x = if true {
|
||||
return;
|
||||
} else {
|
||||
BadDefault::default()
|
||||
};
|
||||
}
|
||||
|
||||
fn match_arm() {
|
||||
let _x = match Ok(BadDefault::default()) {
|
||||
Ok(v) => v,
|
||||
Err(()) => return,
|
||||
};
|
||||
}
|
||||
|
||||
fn match_arm_rev() {
|
||||
let _x = match Ok(BadDefault::default()) {
|
||||
Err(()) => return,
|
||||
Ok(v) => v,
|
||||
};
|
||||
}
|
||||
|
||||
fn loop_break() {
|
||||
let _x = loop {
|
||||
if false {
|
||||
break return;
|
||||
} else {
|
||||
break BadDefault::default();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn loop_break_rev() {
|
||||
let _x = loop {
|
||||
if false {
|
||||
break return;
|
||||
} else {
|
||||
break BadDefault::default();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -8,31 +8,20 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that diverging types default to () (with feature(never_type) disabled).
|
||||
// Test a regression found when building compiler. The `produce()`
|
||||
// error type `T` winds up getting unified with result of `x.parse()`;
|
||||
// the type of the closure given to `unwrap_or_else` needs to be
|
||||
// inferred to `usize`.
|
||||
|
||||
trait Balls: Sized {
|
||||
fn smeg() -> Result<Self, ()>;
|
||||
}
|
||||
use std::num::ParseIntError;
|
||||
|
||||
impl Balls for () {
|
||||
fn smeg() -> Result<(), ()> { Ok(()) }
|
||||
}
|
||||
|
||||
struct Flah;
|
||||
|
||||
impl Flah {
|
||||
fn flah<T: Balls>(&self) -> Result<T, ()> {
|
||||
T::smeg()
|
||||
}
|
||||
}
|
||||
|
||||
fn doit() -> Result<(), ()> {
|
||||
// The type of _ is unconstrained here and should default to ()
|
||||
let _ = try!(Flah.flah());
|
||||
Ok(())
|
||||
fn produce<T>() -> Result<&'static str, T> {
|
||||
Ok("22")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = doit();
|
||||
let x: usize = produce()
|
||||
.and_then(|x| x.parse())
|
||||
.unwrap_or_else(|_| panic!());
|
||||
println!("{}", x);
|
||||
}
|
||||
|
22
src/test/run-pass/diverging-fallback-option.rs
Normal file
22
src/test/run-pass/diverging-fallback-option.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// 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.
|
||||
|
||||
#![allow(warnings)]
|
||||
|
||||
// Here the type of `c` is `Option<?T>`, where `?T` is unconstrained.
|
||||
// Because there is data-flow from the `{ return; }` block, which
|
||||
// diverges and hence has type `!`, into `c`, we will default `?T` to
|
||||
// `!`, and hence this code compiles rather than failing and requiring
|
||||
// a type annotation.
|
||||
|
||||
fn main() {
|
||||
let c = Some({ return; });
|
||||
c.unwrap();
|
||||
}
|
Loading…
Reference in New Issue
Block a user