Skip to content

Commit 6c3fce9

Browse files
authored
Rollup merge of #124954 - kpreid:fmterr, r=Nilstrieb
Document proper usage of `fmt::Error` and `fmt()`'s `Result`. I've seen several newcomers wonder why `fmt::Error` doesn't have any error detail information, or propose to return it in response to an error condition found inside a `impl fmt::Display for MyType`. That is incorrect, per [a lone paragraph of the `fmt` module's documentation](https://doc.rust-lang.org/1.78.0/std/fmt/index.html#formatting-traits). However, users looking to implement a formatting trait won't necessarily look there. Therefore, let's add the critical information (that formatting per se is infallible) to all the involved items: every `fmt()` method, and `fmt::Error`. This PR is not intended to make any novel claims about `fmt`; only to repeat an existing one in places where it will be more visible.
2 parents 03ff775 + c21c5ba commit 6c3fce9

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

library/alloc/src/fmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@
403403
//! is, a formatting implementation must and may only return an error if the
404404
//! passed-in [`Formatter`] returns an error. This is because, contrary to what
405405
//! the function signature might suggest, string formatting is an infallible
406-
//! operation. This function only returns a result because writing to the
406+
//! operation. This function only returns a [`Result`] because writing to the
407407
//! underlying stream might fail and it must provide a way to propagate the fact
408408
//! that an error has occurred back up the stack.
409409
//!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Formats the value using the given formatter.
2+
3+
# Errors
4+
5+
This function should return [`Err`] if, and only if, the provided [`Formatter`] returns [`Err`].
6+
String formatting is considered an infallible operation; this function only
7+
returns a [`Result`] because writing to the underlying stream might fail and it must
8+
provide a way to propagate the fact that an error has occurred back up the stack.

library/core/src/fmt/mod.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,24 @@ pub type Result = result::Result<(), Error>;
7272
/// The error type which is returned from formatting a message into a stream.
7373
///
7474
/// This type does not support transmission of an error other than that an error
75-
/// occurred. Any extra information must be arranged to be transmitted through
76-
/// some other means.
77-
///
78-
/// An important thing to remember is that the type `fmt::Error` should not be
75+
/// occurred. This is because, despite the existence of this error,
76+
/// string formatting is considered an infallible operation.
77+
/// `fmt()` implementors should not return this `Error` unless they received it from their
78+
/// [`Formatter`]. The only time your code should create a new instance of this
79+
/// error is when implementing `fmt::Write`, in order to cancel the formatting operation when
80+
/// writing to the underlying stream fails.
81+
///
82+
/// Any extra information must be arranged to be transmitted through some other means,
83+
/// such as storing it in a field to be consulted after the formatting operation has been
84+
/// cancelled. (For example, this is how [`std::io::Write::write_fmt()`] propagates IO errors
85+
/// during writing.)
86+
///
87+
/// This type, `fmt::Error`, should not be
7988
/// confused with [`std::io::Error`] or [`std::error::Error`], which you may also
8089
/// have in scope.
8190
///
8291
/// [`std::io::Error`]: ../../std/io/struct.Error.html
92+
/// [`std::io::Write::write_fmt()`]: ../../std/io/trait.Write.html#method.write_fmt
8393
/// [`std::error::Error`]: ../../std/error/trait.Error.html
8494
///
8595
/// # Examples
@@ -118,8 +128,10 @@ pub trait Write {
118128
/// This function will return an instance of [`std::fmt::Error`][Error] on error.
119129
///
120130
/// The purpose of that error is to abort the formatting operation when the underlying
121-
/// destination encounters some error preventing it from accepting more text; it should
122-
/// generally be propagated rather than handled, at least when implementing formatting traits.
131+
/// destination encounters some error preventing it from accepting more text;
132+
/// in particular, it does not communicate any information about *what* error occurred.
133+
/// It should generally be propagated rather than handled, at least when implementing
134+
/// formatting traits.
123135
///
124136
/// # Examples
125137
///
@@ -586,7 +598,7 @@ impl Display for Arguments<'_> {
586598
#[rustc_diagnostic_item = "Debug"]
587599
#[rustc_trivial_field_reads]
588600
pub trait Debug {
589-
/// Formats the value using the given formatter.
601+
#[doc = include_str!("fmt_trait_method_doc.md")]
590602
///
591603
/// # Examples
592604
///
@@ -703,7 +715,7 @@ pub use macros::Debug;
703715
#[rustc_diagnostic_item = "Display"]
704716
#[stable(feature = "rust1", since = "1.0.0")]
705717
pub trait Display {
706-
/// Formats the value using the given formatter.
718+
#[doc = include_str!("fmt_trait_method_doc.md")]
707719
///
708720
/// # Examples
709721
///
@@ -777,7 +789,7 @@ pub trait Display {
777789
/// ```
778790
#[stable(feature = "rust1", since = "1.0.0")]
779791
pub trait Octal {
780-
/// Formats the value using the given formatter.
792+
#[doc = include_str!("fmt_trait_method_doc.md")]
781793
#[stable(feature = "rust1", since = "1.0.0")]
782794
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
783795
}
@@ -836,7 +848,7 @@ pub trait Octal {
836848
/// ```
837849
#[stable(feature = "rust1", since = "1.0.0")]
838850
pub trait Binary {
839-
/// Formats the value using the given formatter.
851+
#[doc = include_str!("fmt_trait_method_doc.md")]
840852
#[stable(feature = "rust1", since = "1.0.0")]
841853
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
842854
}
@@ -891,7 +903,7 @@ pub trait Binary {
891903
/// ```
892904
#[stable(feature = "rust1", since = "1.0.0")]
893905
pub trait LowerHex {
894-
/// Formats the value using the given formatter.
906+
#[doc = include_str!("fmt_trait_method_doc.md")]
895907
#[stable(feature = "rust1", since = "1.0.0")]
896908
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
897909
}
@@ -946,7 +958,7 @@ pub trait LowerHex {
946958
/// ```
947959
#[stable(feature = "rust1", since = "1.0.0")]
948960
pub trait UpperHex {
949-
/// Formats the value using the given formatter.
961+
#[doc = include_str!("fmt_trait_method_doc.md")]
950962
#[stable(feature = "rust1", since = "1.0.0")]
951963
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
952964
}
@@ -997,7 +1009,7 @@ pub trait UpperHex {
9971009
#[stable(feature = "rust1", since = "1.0.0")]
9981010
#[rustc_diagnostic_item = "Pointer"]
9991011
pub trait Pointer {
1000-
/// Formats the value using the given formatter.
1012+
#[doc = include_str!("fmt_trait_method_doc.md")]
10011013
#[stable(feature = "rust1", since = "1.0.0")]
10021014
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
10031015
}
@@ -1048,7 +1060,7 @@ pub trait Pointer {
10481060
/// ```
10491061
#[stable(feature = "rust1", since = "1.0.0")]
10501062
pub trait LowerExp {
1051-
/// Formats the value using the given formatter.
1063+
#[doc = include_str!("fmt_trait_method_doc.md")]
10521064
#[stable(feature = "rust1", since = "1.0.0")]
10531065
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
10541066
}
@@ -1099,7 +1111,7 @@ pub trait LowerExp {
10991111
/// ```
11001112
#[stable(feature = "rust1", since = "1.0.0")]
11011113
pub trait UpperExp {
1102-
/// Formats the value using the given formatter.
1114+
#[doc = include_str!("fmt_trait_method_doc.md")]
11031115
#[stable(feature = "rust1", since = "1.0.0")]
11041116
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
11051117
}

0 commit comments

Comments
 (0)