Skip to content

Commit b3f95da

Browse files
authored
Rollup merge of #150074 - provider-doc-update, r=Mark-Simulacrum
Update provider API docs Adds guidance on a specific provider API implementation anti pattern that implementers of the error trait should avoid. resolves #99301 (comment)
2 parents 10ef358 + b007397 commit b3f95da

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

library/core/src/error.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,56 @@ pub trait Error: Debug + Display {
205205
/// assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
206206
/// }
207207
/// ```
208+
///
209+
/// # Delegating Impls
210+
///
211+
/// <div class="warning">
212+
///
213+
/// **Warning**: We recommend implementors avoid delegating implementations of `provide` to
214+
/// source error implementations.
215+
///
216+
/// </div>
217+
///
218+
/// This method should expose context from the current piece of the source chain only, not from
219+
/// sources that are exposed in the chain of sources. Delegating `provide` implementations cause
220+
/// the same context to be provided by multiple errors in the chain of sources which can cause
221+
/// unintended duplication of information in error reports or require heuristics to deduplicate.
222+
///
223+
/// In other words, the following implementation pattern for `provide` is discouraged and should
224+
/// not be used for [`Error`] types exposed in public APIs to third parties.
225+
///
226+
/// ```rust
227+
/// # #![feature(error_generic_member_access)]
228+
/// # use core::fmt;
229+
/// # use core::error::Request;
230+
/// # #[derive(Debug)]
231+
/// struct MyError {
232+
/// source: Error,
233+
/// }
234+
/// # #[derive(Debug)]
235+
/// # struct Error;
236+
/// # impl fmt::Display for Error {
237+
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238+
/// # write!(f, "Example Source Error")
239+
/// # }
240+
/// # }
241+
/// # impl fmt::Display for MyError {
242+
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243+
/// # write!(f, "Example Error")
244+
/// # }
245+
/// # }
246+
/// # impl std::error::Error for Error { }
247+
///
248+
/// impl std::error::Error for MyError {
249+
/// fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
250+
/// Some(&self.source)
251+
/// }
252+
///
253+
/// fn provide<'a>(&'a self, request: &mut Request<'a>) {
254+
/// self.source.provide(request) // <--- Discouraged
255+
/// }
256+
/// }
257+
/// ```
208258
#[unstable(feature = "error_generic_member_access", issue = "99301")]
209259
#[allow(unused_variables)]
210260
fn provide<'a>(&'a self, request: &mut Request<'a>) {}

0 commit comments

Comments
 (0)