Remove the Option and bool impls for carrier and add a dummy impl
The dummy impl should ensure the same type checking behaviour as having other (real) Carrier impls.
This commit is contained in:
parent
683bcc0295
commit
5aa89d8bf6
@ -76,7 +76,6 @@ use cmp::PartialOrd;
|
|||||||
use fmt;
|
use fmt;
|
||||||
use marker::{Sized, Unsize};
|
use marker::{Sized, Unsize};
|
||||||
use result::Result::{self, Ok, Err};
|
use result::Result::{self, Ok, Err};
|
||||||
use option::Option::{self, Some, None};
|
|
||||||
|
|
||||||
/// The `Drop` trait is used to run some code when a value goes out of scope.
|
/// The `Drop` trait is used to run some code when a value goes out of scope.
|
||||||
/// This is sometimes called a 'destructor'.
|
/// This is sometimes called a 'destructor'.
|
||||||
@ -2203,75 +2202,23 @@ impl<U, V> Carrier for Result<U, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "question_mark_carrier", issue = "31436")]
|
struct _DummyErrorType;
|
||||||
impl<U> Carrier for Option<U> {
|
|
||||||
type Success = U;
|
|
||||||
type Error = ();
|
|
||||||
|
|
||||||
fn from_success(u: U) -> Option<U> {
|
impl Carrier for _DummyErrorType {
|
||||||
Some(u)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_error(_: ()) -> Option<U> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn translate<T>(self) -> T
|
|
||||||
where T: Carrier<Success=U, Error=()>
|
|
||||||
{
|
|
||||||
match self {
|
|
||||||
Some(u) => T::from_success(u),
|
|
||||||
None => T::from_error(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementing Carrier for bools means it's easy to write short-circuiting
|
|
||||||
// functions. E.g.,
|
|
||||||
// ```
|
|
||||||
// fn foo() -> bool {
|
|
||||||
// if !(f() || g()) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// some_computation();
|
|
||||||
// if h() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// more_computation();
|
|
||||||
// i()
|
|
||||||
// }
|
|
||||||
// ```
|
|
||||||
// becomes
|
|
||||||
// ```
|
|
||||||
// fn foo() -> bool {
|
|
||||||
// (f() || g())?;
|
|
||||||
// some_computation();
|
|
||||||
// (!h())?;
|
|
||||||
// more_computation();
|
|
||||||
// i()
|
|
||||||
// }
|
|
||||||
// ```
|
|
||||||
#[unstable(feature = "question_mark_carrier", issue = "31436")]
|
|
||||||
impl Carrier for bool {
|
|
||||||
type Success = ();
|
type Success = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_success(_: ()) -> bool {
|
fn from_success(_: ()) -> _DummyErrorType {
|
||||||
true
|
_DummyErrorType
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_error(_: ()) -> bool {
|
fn from_error(_: ()) -> _DummyErrorType {
|
||||||
false
|
_DummyErrorType
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate<T>(self) -> T
|
fn translate<T>(self) -> T
|
||||||
where T: Carrier<Success=(), Error=()>
|
where T: Carrier<Success=(), Error=()>
|
||||||
{
|
{
|
||||||
match self {
|
T::from_success(())
|
||||||
true => T::from_success(()),
|
|
||||||
false => T::from_error(()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
src/test/compile-fail/question-mark-type-infer.rs
Normal file
27
src/test/compile-fail/question-mark-type-infer.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#![feature(question_mark, question_mark_carrier)]
|
||||||
|
|
||||||
|
// Test that type inference fails where there are multiple possible return types
|
||||||
|
// for the `?` operator.
|
||||||
|
|
||||||
|
fn f(x: &i32) -> Result<i32, ()> {
|
||||||
|
Ok(*x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn g() -> Result<Vec<i32>, ()> {
|
||||||
|
let l = [1, 2, 3, 4];
|
||||||
|
l.iter().map(f).collect()? //~ ERROR type annotations required: cannot resolve
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
g();
|
||||||
|
}
|
@ -144,23 +144,6 @@ fn merge_error() -> Result<i32, Error> {
|
|||||||
Ok(s.parse::<i32>()? + 1)
|
Ok(s.parse::<i32>()? + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn option() -> Option<i32> {
|
|
||||||
let x = Some(42);
|
|
||||||
let y = x?;
|
|
||||||
Some(y + 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bool() -> bool {
|
|
||||||
let x = true;
|
|
||||||
let y = false;
|
|
||||||
let z = true;
|
|
||||||
|
|
||||||
(x || y)?;
|
|
||||||
let a: () = z?;
|
|
||||||
x?;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(Ok(3), on_method());
|
assert_eq!(Ok(3), on_method());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user