Auto merge of #49371 - scottmcm:catch-wrapping, r=nikomatsakis
Add ok-wrapping to catch blocks, per RFC
Updates the `catch{}` lowering to wrap the result in `Try::from_ok`.
r? @nikomatsakis
Fixes #41414
Fixes #43818
This commit is contained in:
commit
252a459d37
14 changed files with 132 additions and 43 deletions
|
|
@ -21,7 +21,6 @@ pub fn main() {
|
|||
//~^ ERROR `my_string` does not live long enough
|
||||
Err(my_str) ?;
|
||||
Err("") ?;
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +31,6 @@ pub fn main() {
|
|||
let mut j: Result<(), &mut i32> = do catch {
|
||||
Err(k) ?;
|
||||
i = 10; //~ ERROR cannot assign to `i` because it is borrowed
|
||||
Ok(())
|
||||
};
|
||||
::std::mem::drop(k); //~ ERROR use of moved value: `k`
|
||||
i = 40; //~ ERROR cannot assign to `i` because it is borrowed
|
||||
|
|
|
|||
|
|
@ -11,11 +11,18 @@
|
|||
#![feature(catch_expr)]
|
||||
|
||||
pub fn main() {
|
||||
let res: Result<i32, i32> = do catch {
|
||||
let res: Result<u32, i32> = do catch {
|
||||
Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` is not satisfied
|
||||
Ok(5)
|
||||
5
|
||||
};
|
||||
|
||||
let res: Result<i32, i32> = do catch {
|
||||
Ok("") //~ mismatched types
|
||||
"" //~ ERROR type mismatch
|
||||
};
|
||||
|
||||
let res: Result<i32, i32> = do catch { }; //~ ERROR type mismatch
|
||||
|
||||
let res: () = do catch { }; //~ the trait bound `(): std::ops::Try` is not satisfied
|
||||
|
||||
let res: i32 = do catch { 5 }; //~ ERROR the trait bound `i32: std::ops::Try` is not satisfied
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub fn main() {
|
|||
let mut i = 222;
|
||||
let x: Result<&i32, ()> = do catch {
|
||||
Err(())?;
|
||||
Ok(&i)
|
||||
&i
|
||||
};
|
||||
x.ok().cloned();
|
||||
i = 0; //~ ERROR cannot assign to `i` because it is borrowed
|
||||
|
|
@ -29,7 +29,6 @@ pub fn main() {
|
|||
let _y: Result<(), ()> = do catch {
|
||||
Err(())?;
|
||||
::std::mem::drop(x);
|
||||
Ok(())
|
||||
};
|
||||
println!("{}", x); //~ ERROR use of moved value: `x`
|
||||
}
|
||||
|
|
@ -42,7 +41,6 @@ pub fn main() {
|
|||
let x: Result<(), ()> = do catch {
|
||||
Err(())?;
|
||||
j = &i;
|
||||
Ok(())
|
||||
};
|
||||
i = 0; //~ ERROR cannot assign to `i` because it is borrowed
|
||||
let _ = i;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ pub fn main() {
|
|||
cfg_res = 5;
|
||||
Ok::<(), ()>(())?;
|
||||
use_val(cfg_res);
|
||||
Ok(())
|
||||
};
|
||||
assert_eq!(cfg_res, 5); //~ ERROR use of possibly uninitialized variable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@
|
|||
struct catch {}
|
||||
|
||||
pub fn main() {
|
||||
let catch_result = do catch {
|
||||
let catch_result: Option<_> = do catch {
|
||||
let x = 5;
|
||||
x
|
||||
};
|
||||
assert_eq!(catch_result, 5);
|
||||
assert_eq!(catch_result, Some(5));
|
||||
|
||||
let mut catch = true;
|
||||
while catch { catch = false; }
|
||||
|
|
@ -30,16 +30,16 @@ pub fn main() {
|
|||
_ => {}
|
||||
};
|
||||
|
||||
let catch_err = do catch {
|
||||
let catch_err: Result<_, i32> = do catch {
|
||||
Err(22)?;
|
||||
Ok(1)
|
||||
1
|
||||
};
|
||||
assert_eq!(catch_err, Err(22));
|
||||
|
||||
let catch_okay: Result<i32, i32> = do catch {
|
||||
if false { Err(25)?; }
|
||||
Ok::<(), i32>(())?;
|
||||
Ok(28)
|
||||
28
|
||||
};
|
||||
assert_eq!(catch_okay, Ok(28));
|
||||
|
||||
|
|
@ -47,14 +47,13 @@ pub fn main() {
|
|||
for i in 0..10 {
|
||||
if i < 5 { Ok::<i32, i32>(i)?; } else { Err(i)?; }
|
||||
}
|
||||
Ok(22)
|
||||
22
|
||||
};
|
||||
assert_eq!(catch_from_loop, Err(5));
|
||||
|
||||
let cfg_init;
|
||||
let _res: Result<(), ()> = do catch {
|
||||
cfg_init = 5;
|
||||
Ok(())
|
||||
};
|
||||
assert_eq!(cfg_init, 5);
|
||||
|
||||
|
|
@ -62,19 +61,19 @@ pub fn main() {
|
|||
let _res: Result<(), ()> = do catch {
|
||||
cfg_init_2 = 6;
|
||||
Err(())?;
|
||||
Ok(())
|
||||
};
|
||||
assert_eq!(cfg_init_2, 6);
|
||||
|
||||
let my_string = "test".to_string();
|
||||
let res: Result<&str, ()> = do catch {
|
||||
Ok(&my_string)
|
||||
// Unfortunately, deref doesn't fire here (#49356)
|
||||
&my_string[..]
|
||||
};
|
||||
assert_eq!(res, Ok("test"));
|
||||
|
||||
do catch {
|
||||
()
|
||||
}
|
||||
let my_opt: Option<_> = do catch { () };
|
||||
assert_eq!(my_opt, Some(()));
|
||||
|
||||
();
|
||||
let my_opt: Option<_> = do catch { };
|
||||
assert_eq!(my_opt, Some(()));
|
||||
}
|
||||
|
|
|
|||
26
src/test/ui/catch-block-type-error.rs
Normal file
26
src/test/ui/catch-block-type-error.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
#![feature(catch_expr)]
|
||||
|
||||
fn foo() -> Option<()> { Some(()) }
|
||||
|
||||
fn main() {
|
||||
let _: Option<f32> = do catch {
|
||||
foo()?;
|
||||
42
|
||||
//~^ ERROR type mismatch
|
||||
};
|
||||
|
||||
let _: Option<i32> = do catch {
|
||||
foo()?;
|
||||
};
|
||||
//~^ ERROR type mismatch
|
||||
}
|
||||
21
src/test/ui/catch-block-type-error.stderr
Normal file
21
src/test/ui/catch-block-type-error.stderr
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
error[E0271]: type mismatch resolving `<std::option::Option<f32> as std::ops::Try>::Ok == {integer}`
|
||||
--> $DIR/catch-block-type-error.rs:18:9
|
||||
|
|
||||
LL | 42
|
||||
| ^^ expected f32, found integral variable
|
||||
|
|
||||
= note: expected type `f32`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0271]: type mismatch resolving `<std::option::Option<i32> as std::ops::Try>::Ok == ()`
|
||||
--> $DIR/catch-block-type-error.rs:24:5
|
||||
|
|
||||
LL | };
|
||||
| ^ expected i32, found ()
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `()`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue