diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index a869b3c4f98..0e32d71172b 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -76,7 +76,6 @@ use cmp::PartialOrd; use fmt; use marker::{Sized, Unsize}; 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. /// This is sometimes called a 'destructor'. @@ -2203,75 +2202,23 @@ impl Carrier for Result { } } -#[unstable(feature = "question_mark_carrier", issue = "31436")] -impl Carrier for Option { - type Success = U; - type Error = (); +struct _DummyErrorType; - fn from_success(u: U) -> Option { - Some(u) - } - - fn from_error(_: ()) -> Option { - None - } - - fn translate(self) -> T - where T: Carrier - { - 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 { +impl Carrier for _DummyErrorType { type Success = (); type Error = (); - fn from_success(_: ()) -> bool { - true + fn from_success(_: ()) -> _DummyErrorType { + _DummyErrorType } - fn from_error(_: ()) -> bool { - false + fn from_error(_: ()) -> _DummyErrorType { + _DummyErrorType } fn translate(self) -> T where T: Carrier { - match self { - true => T::from_success(()), - false => T::from_error(()), - } + T::from_success(()) } } diff --git a/src/test/compile-fail/question-mark-type-infer.rs b/src/test/compile-fail/question-mark-type-infer.rs new file mode 100644 index 00000000000..e15c9af41e0 --- /dev/null +++ b/src/test/compile-fail/question-mark-type-infer.rs @@ -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 or the MIT license +// , 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 { + Ok(*x) +} + +fn g() -> Result, ()> { + let l = [1, 2, 3, 4]; + l.iter().map(f).collect()? //~ ERROR type annotations required: cannot resolve +} + +fn main() { + g(); +} diff --git a/src/test/run-pass/try-operator.rs b/src/test/run-pass/try-operator.rs index 8076e00fd08..de5ccf09c59 100644 --- a/src/test/run-pass/try-operator.rs +++ b/src/test/run-pass/try-operator.rs @@ -144,23 +144,6 @@ fn merge_error() -> Result { Ok(s.parse::()? + 1) } -fn option() -> Option { - 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() { assert_eq!(Ok(3), on_method());