diff --git a/text/0000-ok-coercion.md b/text/0000-ok-coercion.md
new file mode 100644
index 00000000000..15bbc0040b7
--- /dev/null
+++ b/text/0000-ok-coercion.md
@@ -0,0 +1,604 @@
+- Feature Name: `ok_coercion`
+- Start Date: 2017-08-22
+- RFC PR: (leave this empty)
+- Rust Issue: (leave this empty)
+
+# Summary
+[summary]: #summary
+
+Implicitly coerce `()` to `Ok(())`.
+
+# Motivation
+[motivation]: #motivation
+
+Idiomatic Rust uses the `Result` type to signal fallible execution. When a function has nothing to return on success,
+one needs to append an `Ok(())` since a return value is required.
+
+```rust
+impl fmt::Display for EscapeUnicode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ for c in self.clone() {
+ f.write_char(c)?;
+ }
+ Ok(()) // <-- yuck.
+ }
+}
+```
+
+This is considered [strange][reddit-3bbi1l] and [unattractive][urlo-1578], since if the function is infallible, you
+don't need to insert the `Ok(())` at all.
+
+This RFC tries to address the issue by implicitly coerce `()` to `Ok(())`, achieving the parity with functions returning
+`()`.
+
+[reddit-3bbi1l]: https://www.reddit.com/r/rust/comments/3bbi1l/returning_a_resulterror/
+[urlo-1578]: https://users.rust-lang.org/t/error-handling-design-in-horrorshow/1578/2
+
+# Guide-level explanation
+[guide-level-explanation]: #guide-level-explanation
+
+## Examples
+
+We add a coercion rule from `()` to `Result<(), _>`, thus allowing the following code:
+
+
After this RFC | Before this RFC |
---|
+
+```rust
+fn foo_0() -> Result<(), E> {
+ println!("Hello!")
+}
+```
+
+ |
+
+```rust
+fn foo_0() -> Result<(), E> {
+ println!("Hello!");
+ Ok(())
+}
+```
+
+ |
+
+```rust
+fn foo_1() -> Result<(), E> {
+ bar_1()?;
+}
+```
+
+ |
+
+```rust
+fn foo_1() -> Result<(), E> {
+ bar_1()?;
+ Ok(())
+}
+```
+
+ |
+
+```rust
+fn foo_2() -> Result<(), E> {
+ if test_2() {
+ bar_2()?;
+ }
+}
+```
+
+ |
+
+```rust
+fn foo_2() -> Result<(), E> {
+ if test_2() {
+ bar_2()?;
+ }
+ Ok(())
+}
+```
+
+ |
+
+```rust
+fn foo_3() -> Result<(), E> {
+ for item in items()? {
+ if item.has_bar() {
+ return;
+ }
+ }
+ Err(E::NotFound)
+}
+```
+
+ |
+
+```rust
+fn foo_3() -> Result<(), E> {
+ for item in items()? {
+ if item.has_bar() {
+ return Ok(());
+ }
+ }
+ Err(E::NotFound)
+}
+```
+
+ |
+
+```rust
+fn foo_4() -> Result<(), E> {
+ let result = loop {
+ if bar_4() {
+ break Err(E::OhNo);
+ }
+ break;
+ };
+ println!("{:?}", result);
+ result
+}
+```
+
+ |
+
+```rust
+fn foo_4() -> Result<(), E> {
+ let result = loop {
+ if bar_4() {
+ break Err(E::OhNo);
+ }
+ break Ok(());
+ };
+ println!("{:?}", result);
+ result
+}
+```
+
+ |
+
+Although pointless, we would also insert `Some(())` for function returning `Option<()>`. In fact, this coercion is
+applied for all types implementing `Try`.
+
+