diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md
index dd8dcb7ff9bd..020ffe4e1df8 100644
--- a/src/doc/rustdoc/src/documentation-tests.md
+++ b/src/doc/rustdoc/src/documentation-tests.md
@@ -236,6 +236,23 @@ appears to the reader as the initial idea but works with doc tests:
 /// ```
 ```
 
+As of version 1.34.0, one can also omit the `fn main()`, but you will have to
+disambiguate the error type:
+
+```ignore
+/// ```
+/// use std::io;
+/// let mut input = String::new();
+/// io::stdin().read_line(&mut input)?;
+/// # Ok::<(), io:Error>(())
+/// ```
+```
+
+This is an unfortunate consequence of the `?` operator adding an implicit
+conversion, so type inference fails because the type is not unique. Please note
+that you must write the `(())` in one sequence without intermediate whitespace
+so that rustdoc understands you want an implicit `Result`-returning function.
+
 ## Documenting macros
 
 Here’s an example of documenting a macro:
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 4d870daac4d0..133edb77051a 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -470,13 +470,19 @@ pub fn make_test(s: &str,
         }
     }
 
-    if dont_insert_main || already_has_main {
+    // FIXME: This code cannot yet handle no_std test cases yet
+    if dont_insert_main || already_has_main || prog.contains("![no_std]") {
         prog.push_str(everything_else);
     } else {
-        prog.push_str("fn main() {\n");
+        let returns_result = everything_else.trim_end().ends_with("(())");
+        let (main_pre, main_post) = if returns_result {
+            ("fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {",
+             "}\n_inner().unwrap() }")
+        } else {
+            ("fn main() {\n", "\n}")
+        };
+        prog.extend([main_pre, everything_else, main_post].iter().cloned());
         line_offset += 1;
-        prog.push_str(everything_else);
-        prog.push_str("\n}");
     }
 
     debug!("final doctest:\n{}", prog);
diff --git a/src/test/rustdoc/process-termination.rs b/src/test/rustdoc/process-termination.rs
new file mode 100644
index 000000000000..32258792b6e8
--- /dev/null
+++ b/src/test/rustdoc/process-termination.rs
@@ -0,0 +1,24 @@
+// compile-flags:--test
+
+/// A check of using various process termination strategies
+///
+/// # Examples
+///
+/// ```rust
+/// assert!(true); // this returns `()`, all is well
+/// ```
+///
+/// You can also simply return `Ok(())`, but you'll need to disambiguate the
+/// type using turbofish, because we cannot infer the type:
+///
+/// ```rust
+/// Ok::<(), &'static str>(())
+/// ```
+///
+/// You can err with anything that implements `Debug`:
+///
+/// ```rust,should_panic
+/// Err("This is returned from `main`, leading to panic")?;
+/// Ok::<(), &'static str>(())
+/// ```
+pub fn check_process_termination() {}