Skip to content

Commit b16a855

Browse files
committed
more detailed tests around diverging type variables
1 parent 00a2f12 commit b16a855

5 files changed

+140
-74
lines changed

src/test/compile-fail/defaulted-unit-warning.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@ impl Deserialize for () {
2222
}
2323
}
2424

25-
fn doit() -> Result<(), String> {
26-
let _ = match Deserialize::deserialize() {
27-
//~^ ERROR code relies on type
28-
//~| WARNING previously accepted
29-
Ok(x) => x,
30-
Err(e) => return Err(e),
31-
};
32-
Ok(())
33-
}
34-
3525
trait ImplementedForUnitButNotNever {}
3626

3727
impl ImplementedForUnitButNotNever for () {}
@@ -46,6 +36,6 @@ fn smeg() {
4636
}
4737

4838
fn main() {
49-
let _ = doit();
39+
smeg();
5040
}
5141

src/test/compile-fail/never-fallback.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test various cases where we permit an unconstrained variable
12+
// to fallback based on control-flow.
13+
//
14+
// These represent current behavior, but are pretty dubious. I would
15+
// like to revisit these and potentially change them. --nmatsakis
16+
17+
#![feature(never_type)]
18+
#![feature(loop_break_value)]
19+
20+
trait BadDefault {
21+
fn default() -> Self;
22+
}
23+
24+
impl BadDefault for u32 {
25+
fn default() -> Self {
26+
0
27+
}
28+
}
29+
30+
impl BadDefault for ! {
31+
fn default() -> ! {
32+
panic!()
33+
}
34+
}
35+
36+
fn assignment() {
37+
let x;
38+
39+
if true {
40+
x = BadDefault::default();
41+
} else {
42+
x = return;
43+
}
44+
}
45+
46+
fn assignment_rev() {
47+
let x;
48+
49+
if true {
50+
x = return;
51+
} else {
52+
x = BadDefault::default();
53+
}
54+
}
55+
56+
fn if_then_else() {
57+
let _x = if true {
58+
BadDefault::default()
59+
} else {
60+
return;
61+
};
62+
}
63+
64+
fn if_then_else_rev() {
65+
let _x = if true {
66+
return;
67+
} else {
68+
BadDefault::default()
69+
};
70+
}
71+
72+
fn match_arm() {
73+
let _x = match Ok(BadDefault::default()) {
74+
Ok(v) => v,
75+
Err(()) => return,
76+
};
77+
}
78+
79+
fn match_arm_rev() {
80+
let _x = match Ok(BadDefault::default()) {
81+
Err(()) => return,
82+
Ok(v) => v,
83+
};
84+
}
85+
86+
fn loop_break() {
87+
let _x = loop {
88+
if false {
89+
break return;
90+
} else {
91+
break BadDefault::default();
92+
}
93+
};
94+
}
95+
96+
fn loop_break_rev() {
97+
let _x = loop {
98+
if false {
99+
break return;
100+
} else {
101+
break BadDefault::default();
102+
}
103+
};
104+
}
105+
106+
fn main() { }

src/test/run-pass/unit-fallback.rs renamed to src/test/run-pass/diverging-fallback-method-chain.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,20 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Test that diverging types default to () (with feature(never_type) disabled).
11+
// Test a regression found when building compiler. The `produce()`
12+
// error type `T` winds up getting unified with result of `x.parse()`;
13+
// the type of the closure given to `unwrap_or_else` needs to be
14+
// inferred to `usize`.
1215

13-
trait Balls: Sized {
14-
fn smeg() -> Result<Self, ()>;
15-
}
16-
17-
impl Balls for () {
18-
fn smeg() -> Result<(), ()> { Ok(()) }
19-
}
20-
21-
struct Flah;
16+
use std::num::ParseIntError;
2217

23-
impl Flah {
24-
fn flah<T: Balls>(&self) -> Result<T, ()> {
25-
T::smeg()
26-
}
27-
}
28-
29-
fn doit() -> Result<(), ()> {
30-
// The type of _ is unconstrained here and should default to ()
31-
let _ = try!(Flah.flah());
32-
Ok(())
18+
fn produce<T>() -> Result<&'static str, T> {
19+
Ok("22")
3320
}
3421

3522
fn main() {
36-
let _ = doit();
23+
let x: usize = produce()
24+
.and_then(|x| x.parse())
25+
.unwrap_or_else(|_| panic!());
26+
println!("{}", x);
3727
}
38-
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(warnings)]
12+
13+
// Here the type of `c` is `Option<?T>`, where `?T` is unconstrained.
14+
// Because there is data-flow from the `{ return; }` block, which
15+
// diverges and hence has type `!`, into `c`, we will default `?T` to
16+
// `!`, and hence this code compiles rather than failing and requiring
17+
// a type annotation.
18+
19+
fn main() {
20+
let c = Some({ return; });
21+
c.unwrap();
22+
}

0 commit comments

Comments
 (0)