From cf77cabcb480c9eeedde3df8806b47bd8658208f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 21 Oct 2019 11:14:31 -0700 Subject: [PATCH] Work around bad diagnostic when missing Context import Previously the compiler would say: error[E0599]: no method named `context` found for type `std::result::Result<(), anyhow::error::Error>` in the current scope --> src/main.rs:83:13 | 83 | context(...)?; | ^^^^^^^ method not found in `std::result::Result<(), anyhow::error::Error>` | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: | 19 | use anyhow::context::Context; where the `anyhow::context::Context` in the suggestion is not a path that is accessible to the user. --- src/context.rs | 63 ++------------------------------------------------ src/lib.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/context.rs b/src/context.rs index 2483f34..357b066 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,4 +1,4 @@ -use crate::Error; +use crate::{Context, Error}; use std::convert::Infallible; use std::error::Error as StdError; use std::fmt::{self, Debug, Display}; @@ -6,65 +6,6 @@ use std::fmt::{self, Debug, Display}; #[cfg(backtrace)] use std::backtrace::Backtrace; -/// Provides the `context` method for `Result`. -/// -/// This trait is sealed and cannot be implemented for types outside of -/// `anyhow`. -/// -/// # Example -/// -/// ``` -/// use anyhow::{Context, Result}; -/// use std::fs; -/// use std::path::PathBuf; -/// -/// pub struct ImportantThing { -/// path: PathBuf, -/// } -/// -/// impl ImportantThing { -/// # const IGNORE: &'static str = stringify! { -/// pub fn detach(&mut self) -> Result<()> {...} -/// # }; -/// # fn detach(&mut self) -> Result<()> { -/// # unimplemented!() -/// # } -/// } -/// -/// pub fn do_it(mut it: ImportantThing) -> Result> { -/// it.detach().context("failed to detach the important thing")?; -/// -/// let path = &it.path; -/// let content = fs::read(path) -/// .with_context(|| format!("failed to read instrs from {}", path.display()))?; -/// -/// Ok(content) -/// } -/// ``` -/// -/// When printed, the outermost context would be printed first and the lower -/// level underlying causes would be enumerated below. -/// -/// ```console -/// Error: failed to read instrs from ./path/to/instrs.jsox -/// -/// caused by: -/// No such file or directory (os error 2) -/// ``` -pub trait Context: private::Sealed { - /// Wrap the error value with additional context. - fn context(self, context: C) -> Result - where - C: Display + Send + Sync + 'static; - - /// Wrap the error value with additional context that is evaluated lazily - /// only once an error does occur. - fn with_context(self, f: F) -> Result - where - C: Display + Send + Sync + 'static, - F: FnOnce() -> C; -} - mod ext { use super::*; @@ -209,7 +150,7 @@ where } } -mod private { +pub(crate) mod private { use super::*; pub trait Sealed {} diff --git a/src/lib.rs b/src/lib.rs index dd137ba..b65e9cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -183,7 +183,8 @@ mod kind; #[cfg(not(feature = "std"))] compile_error!("no_std support is not implemented yet"); -pub use crate::context::Context; +use std::fmt::Display; + pub use crate::error::{Chain, Error}; /// `Result` @@ -426,6 +427,65 @@ macro_rules! anyhow { }; } +/// Provides the `context` method for `Result`. +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `anyhow`. +/// +/// # Example +/// +/// ``` +/// use anyhow::{Context, Result}; +/// use std::fs; +/// use std::path::PathBuf; +/// +/// pub struct ImportantThing { +/// path: PathBuf, +/// } +/// +/// impl ImportantThing { +/// # const IGNORE: &'static str = stringify! { +/// pub fn detach(&mut self) -> Result<()> {...} +/// # }; +/// # fn detach(&mut self) -> Result<()> { +/// # unimplemented!() +/// # } +/// } +/// +/// pub fn do_it(mut it: ImportantThing) -> Result> { +/// it.detach().context("failed to detach the important thing")?; +/// +/// let path = &it.path; +/// let content = fs::read(path) +/// .with_context(|| format!("failed to read instrs from {}", path.display()))?; +/// +/// Ok(content) +/// } +/// ``` +/// +/// When printed, the outermost context would be printed first and the lower +/// level underlying causes would be enumerated below. +/// +/// ```console +/// Error: failed to read instrs from ./path/to/instrs.jsox +/// +/// caused by: +/// No such file or directory (os error 2) +/// ``` +pub trait Context: context::private::Sealed { + /// Wrap the error value with additional context. + fn context(self, context: C) -> Result + where + C: Display + Send + Sync + 'static; + + /// Wrap the error value with additional context that is evaluated lazily + /// only once an error does occur. + fn with_context(self, f: F) -> Result + where + C: Display + Send + Sync + 'static, + F: FnOnce() -> C; +} + // Not public API. #[doc(hidden)] pub mod private {