From 896cfcc67fb8d3e53a5dcf138f79909891bf940e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 2 Jun 2014 15:49:42 -0700 Subject: [PATCH] std: Remove generics from Option::expect This commit removes the type parameter from Option::expect in favor of just taking a hard-coded `&str` argument. This allows this function to move into libcore. Previous code using strings with `expect` will continue to work, but code using this implicitly to transmit task failure will need to unwrap manually with a `match` statement. [breaking-change] Closes #14008 --- src/compiletest/runtest.rs | 22 ++-- src/libcore/option.rs | 14 +++ src/librustc/metadata/tydecode.rs | 2 +- src/librustc/middle/trans/reflect.rs | 2 +- src/libstd/io/timer.rs | 1 - src/libstd/lib.rs | 5 +- src/libstd/option.rs | 170 --------------------------- src/libstd/os.rs | 4 +- src/libstd/prelude.rs | 1 - src/libstd/rt/env.rs | 2 +- src/libstd/slice.rs | 1 - src/libstd/vec.rs | 2 +- 12 files changed, 31 insertions(+), 195 deletions(-) delete mode 100644 src/libstd/option.rs diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 16149e9f277..10428244b71 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -361,7 +361,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { ], vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); procsrv::run("", config.adb_path.as_slice(), @@ -372,7 +372,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { ], vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); let adb_arg = format!("export LD_LIBRARY_PATH={}; \ gdbserver :5039 {}/{}", @@ -392,7 +392,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); loop { //waiting 1 second for gdbserver start timer::sleep(1000); @@ -428,7 +428,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { debugger_opts.as_slice(), vec!(("".to_string(), "".to_string())), None) - .expect(format!("failed to exec `{}`", gdb_path)); + .expect(format!("failed to exec `{}`", gdb_path).as_slice()); let cmdline = { let cmdline = make_cmdline("", "arm-linux-androideabi-gdb", @@ -1207,7 +1207,7 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String prog.as_slice(), args.as_slice(), env, - input).expect(format!("failed to exec `{}`", prog)); + input).expect(format!("failed to exec `{}`", prog).as_slice()); dump_output(config, testfile, out.as_slice(), err.as_slice()); return ProcRes { status: status, @@ -1333,7 +1333,7 @@ fn _arm_exec_compiled_test(config: &Config, ], vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); if config.verbose { println!("push ({}) {} {} {}", @@ -1363,7 +1363,7 @@ fn _arm_exec_compiled_test(config: &Config, config.adb_path.as_slice(), runargs.as_slice(), vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); // get exitcode of result runargs = Vec::new(); @@ -1377,7 +1377,7 @@ fn _arm_exec_compiled_test(config: &Config, runargs.as_slice(), vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); let mut exitcode: int = 0; for c in exitcode_out.as_slice().chars() { @@ -1400,7 +1400,7 @@ fn _arm_exec_compiled_test(config: &Config, runargs.as_slice(), vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); // get stderr of result runargs = Vec::new(); @@ -1414,7 +1414,7 @@ fn _arm_exec_compiled_test(config: &Config, runargs.as_slice(), vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); dump_output(config, testfile, @@ -1448,7 +1448,7 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) { vec!(("".to_string(), "".to_string())), Some("".to_string())) - .expect(format!("failed to exec `{}`", config.adb_path)); + .expect(format!("failed to exec `{}`", config.adb_path).as_slice()); if config.verbose { println!("push ({}) {} {} {}", diff --git a/src/libcore/option.rs b/src/libcore/option.rs index b91a8cebded..45ccf657dbd 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -233,6 +233,20 @@ pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] { // Getting to contained values ///////////////////////////////////////////////////////////////////////// + /// Unwraps an option, yielding the content of a `Some` + /// + /// # Failure + /// + /// Fails if the value is a `None` with a custom failure message provided by + /// `msg`. + #[inline] + pub fn expect(self, msg: &str) -> T { + match self { + Some(val) => val, + None => fail!(msg), + } + } + /// Moves a value out of an option type and returns it, consuming the `Option`. /// /// # Failure diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index b5fc3828623..f8d041bc923 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -451,7 +451,7 @@ fn parse_fn_style(c: char) -> FnStyle { fn parse_abi_set(st: &mut PState) -> abi::Abi { assert_eq!(next(st), '['); scan(st, |c| c == ']', |bytes| { - let abi_str = str::from_utf8(bytes).unwrap().to_string(); + let abi_str = str::from_utf8(bytes).unwrap(); abi::lookup(abi_str.as_slice()).expect(abi_str) }) } diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 4b81463ed79..a4f583cdb82 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -90,7 +90,7 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) { let mth_idx = ty::method_idx(token::str_to_ident(format!( "visit_{}", ty_name).as_slice()), self.visitor_methods.as_slice()).expect( - format!("couldn't find visit method for {}", ty_name)); + format!("couldn't find visit method for {}", ty_name).as_slice()); let mth_ty = ty::mk_bare_fn(tcx, self.visitor_methods[mth_idx].fty.clone()); diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs index 2df6062b7ac..d7476dd2de8 100644 --- a/src/libstd/io/timer.rs +++ b/src/libstd/io/timer.rs @@ -21,7 +21,6 @@ use io::IoResult; use kinds::Send; use owned::Box; -use option::Expect; use rt::rtio::{IoFactory, LocalIo, RtioTimer}; /// A synchronous timer object diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index a67ed1c0b79..7d1ca3d5782 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -155,6 +155,7 @@ pub use core::tuple; #[cfg(not(test))] pub use core::ty; pub use core::result; +pub use core::option; pub use alloc::owned; pub use alloc::rc; @@ -219,10 +220,6 @@ fn start(argc: int, argv: **u8) -> int { pub mod to_str; pub mod hash; -/* Common data structures */ - -pub mod option; - /* Tasks and communication */ pub mod task; diff --git a/src/libstd/option.rs b/src/libstd/option.rs deleted file mode 100644 index ad834f2b4d4..00000000000 --- a/src/libstd/option.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2014 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. - -//! Optional values -//! -//! Type `Option` represents an optional value: every `Option` -//! is either `Some` and contains a value, or `None`, and -//! does not. `Option` types are very common in Rust code, as -//! they have a number of uses: -//! -//! * Initial values -//! * Return values for functions that are not defined -//! over their entire input range (partial functions) -//! * Return value for otherwise reporting simple errors, where `None` is -//! returned on error -//! * Optional struct fields -//! * Struct fields that can be loaned or "taken" -//! * Optional function arguments -//! * Nullable pointers -//! * Swapping things out of difficult situations -//! -//! Options are commonly paired with pattern matching to query the presence -//! of a value and take action, always accounting for the `None` case. -//! -//! ``` -//! fn divide(numerator: f64, denominator: f64) -> Option { -//! if denominator == 0.0 { -//! None -//! } else { -//! Some(numerator / denominator) -//! } -//! } -//! -//! // The return value of the function is an option -//! let result = divide(2.0, 3.0); -//! -//! // Pattern match to retrieve the value -//! match result { -//! // The division was valid -//! Some(x) => println!("Result: {}", x), -//! // The division was invalid -//! None => println!("Cannot divide by 0") -//! } -//! ``` -//! -// -// FIXME: Show how `Option` is used in practice, with lots of methods -// -//! # Options and pointers ("nullable" pointers) -//! -//! Rust's pointer types must always point to a valid location; there are -//! no "null" pointers. Instead, Rust has *optional* pointers, like -//! the optional owned box, `Option>`. -//! -//! The following example uses `Option` to create an optional box of -//! `int`. Notice that in order to use the inner `int` value first the -//! `check_optional` function needs to use pattern matching to -//! determine whether the box has a value (i.e. it is `Some(...)`) or -//! not (`None`). -//! -//! ``` -//! let optional: Option> = None; -//! check_optional(&optional); -//! -//! let optional: Option> = Some(box 9000); -//! check_optional(&optional); -//! -//! fn check_optional(optional: &Option>) { -//! match *optional { -//! Some(ref p) => println!("have value {}", p), -//! None => println!("have no value") -//! } -//! } -//! ``` -//! -//! This usage of `Option` to create safe nullable pointers is so -//! common that Rust does special optimizations to make the -//! representation of `Option>` a single pointer. Optional pointers -//! in Rust are stored as efficiently as any other pointer type. -//! -//! # Examples -//! -//! Basic pattern matching on `Option`: -//! -//! ``` -//! let msg = Some("howdy"); -//! -//! // Take a reference to the contained string -//! match msg { -//! Some(ref m) => println!("{}", *m), -//! None => () -//! } -//! -//! // Remove the contained string, destroying the Option -//! let unwrapped_msg = match msg { -//! Some(m) => m, -//! None => "default message" -//! }; -//! ``` -//! -//! Initialize a result to `None` before a loop: -//! -//! ``` -//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) } -//! -//! // A list of data to search through. -//! let all_the_big_things = [ -//! Plant(250, "redwood"), -//! Plant(230, "noble fir"), -//! Plant(229, "sugar pine"), -//! Animal(25, "blue whale"), -//! Animal(19, "fin whale"), -//! Animal(15, "north pacific right whale"), -//! ]; -//! -//! // We're going to search for the name of the biggest animal, -//! // but to start with we've just got `None`. -//! let mut name_of_biggest_animal = None; -//! let mut size_of_biggest_animal = 0; -//! for big_thing in all_the_big_things.iter() { -//! match *big_thing { -//! Animal(size, name) if size > size_of_biggest_animal => { -//! // Now we've found the name of some big animal -//! size_of_biggest_animal = size; -//! name_of_biggest_animal = Some(name); -//! } -//! Animal(..) | Plant(..) => () -//! } -//! } -//! -//! match name_of_biggest_animal { -//! Some(name) => println!("the biggest animal is {}", name), -//! None => println!("there are no animals :(") -//! } -//! ``` - -use any::Any; -use kinds::Send; - -pub use core::option::{Option, Some, None, Item, collect}; - -/// Extension trait for the `Option` type to add an `expect` method - -// FIXME(#14008) should this trait even exist? -pub trait Expect { - /// Unwraps an option, yielding the content of a `Some` - /// - /// # Failure - /// - /// Fails if the value is a `None` with a custom failure message provided by - /// `msg`. - fn expect(self, m: M) -> T; -} - -impl Expect for Option { - #[inline] - fn expect(self, msg: M) -> T { - match self { - Some(val) => val, - None => fail!(msg), - } - } -} diff --git a/src/libstd/os.rs b/src/libstd/os.rs index fa0116b2482..486d98a5487 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -85,7 +85,6 @@ pub fn getcwd() -> Path { pub fn getcwd() -> Path { use libc::DWORD; use libc::GetCurrentDirectoryW; - use option::Expect; let mut buf = [0 as u16, ..BUF_BYTES]; unsafe { @@ -101,7 +100,7 @@ pub fn getcwd() -> Path { pub mod win32 { use libc::types::os::arch::extra::DWORD; use libc; - use option::{None, Option, Expect}; + use option::{None, Option}; use option; use os::TMPBUF_SZ; use slice::{MutableVector, ImmutableVector}; @@ -924,7 +923,6 @@ fn real_args() -> Vec { #[cfg(windows)] fn real_args() -> Vec { use slice; - use option::Expect; let mut nArgs: c_int = 0; let lpArgCount: *mut c_int = &mut nArgs; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index cce2cce0d6e..54dcbd1812f 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -69,7 +69,6 @@ #[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul}; #[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float}; #[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive}; -#[doc(no_inline)] pub use option::Expect; #[doc(no_inline)] pub use owned::Box; #[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath}; #[doc(no_inline)] pub use ptr::RawPtr; diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs index c9e5cae60e4..7271464d1e9 100644 --- a/src/libstd/rt/env.rs +++ b/src/libstd/rt/env.rs @@ -11,7 +11,7 @@ //! Runtime environment settings use from_str::from_str; -use option::{Some, None, Expect}; +use option::{Some, None}; use os; use str::Str; diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs index 5753663dd87..ea42b77fb55 100644 --- a/src/libstd/slice.rs +++ b/src/libstd/slice.rs @@ -296,7 +296,6 @@ impl<'a, T: Clone> CloneableVector for &'a [T] { fn to_owned(&self) -> ~[T] { use RawVec = core::raw::Vec; use num::{CheckedAdd, CheckedMul}; - use option::Expect; let len = self.len(); let data_size = len.checked_mul(&mem::size_of::()); diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 916ba083b3e..cdcee9464de 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -21,7 +21,7 @@ use num::{CheckedMul, CheckedAdd}; use num; use ops::{Add, Drop}; -use option::{None, Option, Some, Expect}; +use option::{None, Option, Some}; use ptr::RawPtr; use ptr; use raw::Slice; -- 2.44.0