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 https://github.com/rust-lang/rust/issues/99301#issuecomment-3661904330
This commit is contained in:
Matthias Krüger 2026-01-08 16:25:27 +01:00 committed by GitHub
commit b3f95da910
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -205,6 +205,56 @@ pub trait Error: Debug + Display {
/// assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
/// }
/// ```
///
/// # Delegating Impls
///
/// <div class="warning">
///
/// **Warning**: We recommend implementors avoid delegating implementations of `provide` to
/// source error implementations.
///
/// </div>
///
/// This method should expose context from the current piece of the source chain only, not from
/// sources that are exposed in the chain of sources. Delegating `provide` implementations cause
/// the same context to be provided by multiple errors in the chain of sources which can cause
/// unintended duplication of information in error reports or require heuristics to deduplicate.
///
/// In other words, the following implementation pattern for `provide` is discouraged and should
/// not be used for [`Error`] types exposed in public APIs to third parties.
///
/// ```rust
/// # #![feature(error_generic_member_access)]
/// # use core::fmt;
/// # use core::error::Request;
/// # #[derive(Debug)]
/// struct MyError {
/// source: Error,
/// }
/// # #[derive(Debug)]
/// # struct Error;
/// # impl fmt::Display for Error {
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// # write!(f, "Example Source Error")
/// # }
/// # }
/// # impl fmt::Display for MyError {
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// # write!(f, "Example Error")
/// # }
/// # }
/// # impl std::error::Error for Error { }
///
/// impl std::error::Error for MyError {
/// fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
/// Some(&self.source)
/// }
///
/// fn provide<'a>(&'a self, request: &mut Request<'a>) {
/// self.source.provide(request) // <--- Discouraged
/// }
/// }
/// ```
#[unstable(feature = "error_generic_member_access", issue = "99301")]
#[allow(unused_variables)]
fn provide<'a>(&'a self, request: &mut Request<'a>) {}