about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-20 12:30:45 +0000
committerbors <bors@rust-lang.org>2020-04-20 12:30:45 +0000
commit8ce3f840ae9b735a66531996c32330f24b877cb0 (patch)
treebb5966a154805aef3cfc2148cbb32278af124078 /src
parent4ca5fd2d7b6b1d75b6cb8f679e8523fb3e7b19e2 (diff)
parent3e3fd73f85c8dd2a7ba6b2072bfb1158e7e6872f (diff)
downloadrust-8ce3f840ae9b735a66531996c32330f24b877cb0.tar.gz
rust-8ce3f840ae9b735a66531996c32330f24b877cb0.zip
Auto merge of #70729 - nnethercote:a-big-options-clean-up, r=petrochenkov
A big options clean-up

Lots of improvements here.

r? @Centril
Diffstat (limited to 'src')
-rw-r--r--src/doc/rustc/src/codegen-options/index.md172
-rw-r--r--src/librustc_codegen_llvm/back/write.rs2
-rw-r--r--src/librustc_codegen_ssa/back/link.rs21
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs2
-rw-r--r--src/librustc_codegen_ssa/back/write.rs2
-rw-r--r--src/librustc_driver/lib.rs25
-rw-r--r--src/librustc_interface/tests.rs6
-rw-r--r--src/librustc_middle/ty/layout.rs4
-rw-r--r--src/librustc_session/config.rs39
-rw-r--r--src/librustc_session/options.rs433
-rw-r--r--src/librustc_session/session.rs8
-rw-r--r--src/librustdoc/core.rs4
12 files changed, 339 insertions, 379 deletions
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 8dc6257ce2e..5dda5ec2cb8 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -9,10 +9,10 @@ This option is deprecated and does nothing.
 
 ## linker
 
-This flag lets you control which linker `rustc` invokes to link your code. It
-takes a path to the linker executable. If this flag is not specified, the
-linker will be inferred based on the target. See also the
-[linker-flavor](#linker-flavor) flag for another way to specify the linker.
+This flag controls which linker `rustc` invokes to link your code. It takes a
+path to the linker executable. If this flag is not specified, the linker will
+be inferred based on the target. See also the [linker-flavor](#linker-flavor)
+flag for another way to specify the linker.
 
 ## link-arg
 
@@ -27,49 +27,52 @@ options should be separated by spaces.
 
 ## linker-flavor
 
-This flag lets you control the linker flavor used by `rustc`. If a linker is given with the
-[`-C linker` flag](#linker), then the linker flavor is inferred from the value provided. If no
-linker is given then the linker flavor is used to determine the linker to use. Every `rustc` target
-defaults to some linker flavor. Valid options are:
-
-* `em`: Uses [Emscripten `emcc`](https://emscripten.org/docs/tools_reference/emcc.html).
-* `gcc`: Uses the `cc` executable, which is typically gcc or clang on many systems.
-* `ld`: Uses the `ld` executable.
-* `msvc`: Uses the `link.exe` executable from Microsoft Visual Studio MSVC.
-* `ptx-linker`: Uses
+This flag controls the linker flavor used by `rustc`. If a linker is given with
+the [`-C linker` flag](#linker), then the linker flavor is inferred from the
+value provided. If no linker is given then the linker flavor is used to
+determine the linker to use. Every `rustc` target defaults to some linker
+flavor. Valid options are:
+
+* `em`: use [Emscripten `emcc`](https://emscripten.org/docs/tools_reference/emcc.html).
+* `gcc`: use the `cc` executable, which is typically gcc or clang on many systems.
+* `ld`: use the `ld` executable.
+* `msvc`: use the `link.exe` executable from Microsoft Visual Studio MSVC.
+* `ptx-linker`: use
   [`rust-ptx-linker`](https://github.com/denzp/rust-ptx-linker) for Nvidia
   NVPTX GPGPU support.
-* `wasm-ld`: Uses the [`wasm-ld`](https://lld.llvm.org/WebAssembly.html)
+* `wasm-ld`: use the [`wasm-ld`](https://lld.llvm.org/WebAssembly.html)
   executable, a port of LLVM `lld` for WebAssembly.
-* `ld64.lld`: Uses the LLVM `lld` executable with the [`-flavor darwin`
+* `ld64.lld`: use the LLVM `lld` executable with the [`-flavor darwin`
   flag][lld-flavor] for Apple's `ld`.
-* `ld.lld`: Uses the LLVM `lld` executable with the [`-flavor gnu`
+* `ld.lld`: use the LLVM `lld` executable with the [`-flavor gnu`
   flag][lld-flavor] for GNU binutils' `ld`.
-* `lld-link`: Uses the LLVM `lld` executable with the [`-flavor link`
+* `lld-link`: use the LLVM `lld` executable with the [`-flavor link`
   flag][lld-flavor] for Microsoft's `link.exe`.
 
 [lld-flavor]: https://lld.llvm.org/Driver.html
 
 ## link-dead-code
 
-Normally, the linker will remove dead code. This flag disables this behavior.
+This flag controls whether the linker will keep dead code. It takes one of
+the following values:
+
+* `y`, `yes`, `on`, or no value: keep dead code.
+* `n`, `no`, or `off`: remove dead code (the default).
 
 An example of when this flag might be useful is when trying to construct code coverage
 metrics.
 
 ## lto
 
-This flag instructs LLVM to use [link time
+This flag controls whether LLVM uses [link time
 optimizations](https://llvm.org/docs/LinkTimeOptimization.html) to produce
 better optimized code, using whole-program analysis, at the cost of longer
-linking time.
+linking time. It takes one of the following values:
 
-This flag may take one of the following values:
-
-* `y`, `yes`, `on`, `fat`, or no value: Performs "fat" LTO which attempts to
+* `y`, `yes`, `on`, `fat`, or no value: perform "fat" LTO which attempts to
   perform optimizations across all crates within the dependency graph.
-* `n`, `no`, `off`: Disables LTO.
-* `thin`: Performs ["thin"
+* `n`, `no`, `off`: disables LTO.
+* `thin`: perform ["thin"
   LTO](http://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html).
   This is similar to "fat", but takes substantially less time to run while
   still achieving performance gains similar to "fat".
@@ -81,22 +84,22 @@ disabled if codegen units is 1 or optimizations are disabled ([`-C
 opt-level=0`](#opt-level)). That is:
 
 * When `-C lto` is not specified:
-  * `codegen-units=1`: Disables LTO.
-  * `opt-level=0`: Disables LTO.
+  * `codegen-units=1`: disable LTO.
+  * `opt-level=0`: disable LTO.
 * When `-C lto=true`:
-  * `lto=true`: 16 codegen units, performs fat LTO across crates.
+  * `lto=true`: 16 codegen units, perform fat LTO across crates.
   * `codegen-units=1` + `lto=true`: 1 codegen unit, fat LTO across crates.
 
 See also [linker-plugin-lto](#linker-plugin-lto) for cross-language LTO.
 
 ## linker-plugin-lto
 
-Defers LTO optimizations to the linker. See
-[linkger-plugin-LTO](../linker-plugin-lto.md) for more details. Takes one of
+This flag defers LTO optimizations to the linker. See
+[linker-plugin-LTO](../linker-plugin-lto.md) for more details. It takes one of
 the following values:
 
-* `y`, `yes`, `on`, or no value: Enabled.
-* `n`, `no`, or `off`: Disabled (default).
+* `y`, `yes`, `on`, or no value: enable linker plugin LTO.
+* `n`, `no`, or `off`: disable linker plugin LTO (the default).
 * A path to the linker plugin.
 
 ## target-cpu
@@ -148,14 +151,19 @@ Pass `--help` to see a list of options.
 
 ## save-temps
 
-`rustc` will generate temporary files during compilation; normally it will
-delete them after it's done with its work. This option will cause them to be
-preserved instead of removed.
+This flag controls whether temporary files generated during compilation are
+deleted once compilation finishes. It takes one of the following values:
+
+* `y`, `yes`, `on`, or no value: save temporary files.
+* `n`, `no`, or `off`: delete temporary files (the default).
 
 ## rpath
 
-This option allows you to enable
-[`rpath`](https://en.wikipedia.org/wiki/Rpath).
+This flag controls whether [`rpath`](https://en.wikipedia.org/wiki/Rpath) is
+enabled. It takes one of the following values:
+
+* `y`, `yes`, `on`, or no value: enable rpath.
+* `n`, `no`, or `off`: disable rpath (the default).
 
 ## overflow-checks
 
@@ -164,35 +172,35 @@ overflow](../../reference/expressions/operator-expr.md#overflow). When
 overflow-checks are enabled, a panic will occur on overflow. This flag takes
 one of the following values:
 
-* `y`, `yes`, `on`, or no value: Enable overflow checks.
-* `n`, `no`, or `off`: Disable overflow checks.
+* `y`, `yes`, `on`, or no value: enable overflow checks.
+* `n`, `no`, or `off`: disable overflow checks.
 
 If not specified, overflow checks are enabled if
 [debug-assertions](#debug-assertions) are enabled, disabled otherwise.
 
 ## no-prepopulate-passes
 
-The pass manager comes pre-populated with a list of passes; this flag
-ensures that list is empty.
+This flag tells the pass manager to use an empty list of passes, instead of the
+usual pre-populated list of passes.
 
 ## no-vectorize-loops
 
-By default, `rustc` will attempt to [vectorize
-loops](https://llvm.org/docs/Vectorizers.html#the-loop-vectorizer). This
-flag will turn that behavior off.
+This flag disables [loop
+vectorization](https://llvm.org/docs/Vectorizers.html#the-loop-vectorizer).
 
 ## no-vectorize-slp
 
-By default, `rustc` will attempt to vectorize code using [superword-level
-parallelism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer). This
-flag will turn that behavior off.
+This flag disables vectorization using
+[superword-level
+parallelism](https://llvm.org/docs/Vectorizers.html#the-slp-vectorizer).
 
 ## soft-float
 
-This option will make `rustc` generate code using "soft floats." By default,
-a lot of hardware supports floating point instructions, and so the code generated
-will take advantage of this. "soft floats" emulate floating point instructions
-in software.
+This option controls whether `rustc` generates code that emulates floating
+point instructions in software. It takes one of the following values:
+
+* `y`, `yes`, `on`, or no value: use soft floats.
+* `n`, `no`, or `off`: use hardware floats (the default).
 
 ## prefer-dynamic
 
@@ -201,24 +209,21 @@ indicate that dynamic linking should be used if possible if both a static and
 dynamic versions of a library are available. There is an internal algorithm
 for determining whether or not it is possible to statically or dynamically
 link with a dependency. For example, `cdylib` crate types may only use static
-linkage.
+linkage. This flag takes one of the following values:
 
-## no-integrated-as
-
-`rustc` normally uses the LLVM internal assembler to create object code. This
-flag will disable the internal assembler and emit assembly code to be
-translated using an external assembler, currently the linker such as `cc`.
+* `y`, `yes`, `on`, or no value: use dynamic linking.
+* `n`, `no`, or `off`: use static linking (the default).
 
 ## no-redzone
 
 This flag allows you to disable [the
-red zone](https://en.wikipedia.org/wiki/Red_zone_\(computing\)). This flag can
-be passed one of the following options:
+red zone](https://en.wikipedia.org/wiki/Red_zone_\(computing\)). It takes one
+of the following values:
 
-* `y`, `yes`, `on`, or no value: Disables the red zone.
-* `n`, `no`, or `off`: Enables the red zone.
+* `y`, `yes`, `on`, or no value: disable the red zone.
+* `n`, `no`, or `off`: enable the red zone.
 
-The default if not specified depends on the target.
+The default behaviour, if the flag is not specified, depends on the target.
 
 ## relocation-model
 
@@ -257,7 +262,7 @@ them in parallel. Increasing parallelism may speed up compile times, but may
 also produce slower code. Setting this to 1 may improve the performance of
 generated code, but may be slower to compile.
 
-The default, if not specified, is 16 for non-incremental builds. For
+The default value, if not specified, is 16 for non-incremental builds. For
 incremental builds the default is 256 which allows caching to be more granular.
 
 ## remark
@@ -274,23 +279,25 @@ This option is deprecated and does nothing.
 
 ## debuginfo
 
-This flag lets you control debug information:
+This flag controls the generation of debug information. It takes one of the
+following values:
 
-* `0`: no debug info at all (default)
-* `1`: line tables only
-* `2`: full debug info
+* `0`: no debug info at all (the default).
+* `1`: line tables only.
+* `2`: full debug info.
 
 Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`.
 
 ## opt-level
 
-This flag lets you control the optimization level.
+This flag controls the optimization level.
 
-* `0`: no optimizations, also turns on [`cfg(debug_assertions)`](#debug-assertions).
-* `1`: basic optimizations
-* `2`: some optimizations
-* `3`: all optimizations
-* `s`: optimize for binary size
+* `0`: no optimizations, also turns on
+  [`cfg(debug_assertions)`](#debug-assertions) (the default).
+* `1`: basic optimizations.
+* `2`: some optimizations.
+* `3`: all optimizations.
+* `s`: optimize for binary size.
 * `z`: optimize for binary size, but also turn off loop vectorization.
 
 Note: The [`-O` flag][option-o-optimize] is an alias for `-C opt-level=2`.
@@ -303,8 +310,8 @@ This flag lets you turn `cfg(debug_assertions)` [conditional
 compilation](../../reference/conditional-compilation.md#debug_assertions) on
 or off. It takes one of the following values:
 
-* `y`, `yes`, `on`, or no value: Enable debug-assertions.
-* `n`, `no`, or `off`: Disable debug-assertions.
+* `y`, `yes`, `on`, or no value: enable debug-assertions.
+* `n`, `no`, or `off`: disable debug-assertions.
 
 If not specified, debug assertions are automatically enabled only if the
 [opt-level](#opt-level) is 0.
@@ -362,25 +369,24 @@ to a valid `.profdata` file. See the chapter on
 This flag forces the use of frame pointers. It takes one of the following
 values:
 
-* `y`, `yes`, `on`, or no value: Frame pointers are forced to be enabled.
-* `n`, `no`, or `off`: Frame pointers are not forced to be enabled. This does
+* `y`, `yes`, `on`, or no value: force-enable frame pointers.
+* `n`, `no`, or `off`: do not force-enable frame pointers. This does
   not necessarily mean frame pointers will be removed.
 
-The default if not specified depends on the target.
+The default behaviour, if frame pointers are not force-enabled, depends on the
+target.
 
 ## default-linker-libraries
 
 This flag controls whether or not the linker includes its default libraries.
 It takes one of the following values:
 
-* `y`, `yes`, `on`, or no value: Default libraries are included.
-* `n`, `no`, or `off`: Default libraries are **not** included.
+* `y`, `yes`, `on`, or no value: include default libraries (the default).
+* `n`, `no`, or `off`: exclude default libraries.
 
 For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to
 the linker.
 
-The default is `yes` if not specified.
-
 [option-emit]: ../command-line-arguments.md#option-emit
 [option-o-optimize]: ../command-line-arguments.md#option-o-optimize
 [profile-guided optimization]: ../profile-guided-optimization.md
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 5708cb4e654..b57ad102d63 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -347,7 +347,7 @@ pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
     }
 
     // The new pass manager is disabled by default.
-    config.new_llvm_pass_manager.unwrap_or(false)
+    config.new_llvm_pass_manager
 }
 
 pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index cd7674935e7..8725bfaa025 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -858,18 +858,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
     // *not* running dsymutil then the object files are the only source of truth
     // for debug information, so we must preserve them.
     if sess.target.target.options.is_like_osx {
-        match sess.opts.debugging_opts.run_dsymutil {
-            // dsymutil is not being run, preserve objects
-            Some(false) => return true,
-
-            // dsymutil is being run, no need to preserve the objects
-            Some(true) => return false,
-
-            // The default historical behavior was to always run dsymutil, so
-            // we're preserving that temporarily, but we're likely to switch the
-            // default soon.
-            None => return false,
-        }
+        return !sess.opts.debugging_opts.run_dsymutil;
     }
 
     false
@@ -1324,11 +1313,11 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'
     // If -Zlink-native-libraries=false is set, then the assumption is that an
     // external build system already has the native dependencies defined, and it
     // will provide them to the linker itself.
-    if sess.opts.debugging_opts.link_native_libraries.unwrap_or(true) {
+    if sess.opts.debugging_opts.link_native_libraries {
         add_local_native_libraries(cmd, sess, codegen_results);
     }
     add_upstream_rust_crates::<B>(cmd, sess, codegen_results, crate_type, tmpdir);
-    if sess.opts.debugging_opts.link_native_libraries.unwrap_or(true) {
+    if sess.opts.debugging_opts.link_native_libraries {
         add_upstream_native_libraries(cmd, sess, codegen_results, crate_type);
     }
 }
@@ -1534,9 +1523,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     // OBJECT-FILES-NO, AUDIT-ORDER
     // We want to prevent the compiler from accidentally leaking in any system libraries,
     // so by default we tell linkers not to link to any default libraries.
-    if !sess.opts.cg.default_linker_libraries.unwrap_or(false)
-        && sess.target.target.options.no_default_libraries
-    {
+    if !sess.opts.cg.default_linker_libraries && sess.target.target.options.no_default_libraries {
         cmd.no_default_libraries();
     }
 
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index d8c5ddf586f..9ca8f743f65 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -384,7 +384,7 @@ impl<'a> Linker for GccLinker<'a> {
             // If we are building without debuginfo enabled and we were called with
             // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo
             // found when linking to get rid of symbols from libstd.
-            if let Some(true) = self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
+            if self.sess.opts.debugging_opts.strip_debuginfo_if_disabled {
                 self.linker_arg("-S");
             }
         };
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index b1fb1ef0e33..d81a767abd4 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -115,7 +115,7 @@ pub struct ModuleConfig {
     pub vectorize_slp: bool,
     pub merge_functions: bool,
     pub inline_threshold: Option<usize>,
-    pub new_llvm_pass_manager: Option<bool>,
+    pub new_llvm_pass_manager: bool,
 }
 
 impl ModuleConfig {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 0e3199975f9..fff86ba8194 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -955,32 +955,17 @@ fn describe_codegen_flags() {
 
 fn print_flag_list<T>(
     cmdline_opt: &str,
-    flag_list: &[(&'static str, T, Option<&'static str>, &'static str)],
+    flag_list: &[(&'static str, T, &'static str, &'static str)],
 ) {
-    let max_len = flag_list
-        .iter()
-        .map(|&(name, _, opt_type_desc, _)| {
-            let extra_len = match opt_type_desc {
-                Some(..) => 4,
-                None => 0,
-            };
-            name.chars().count() + extra_len
-        })
-        .max()
-        .unwrap_or(0);
+    let max_len = flag_list.iter().map(|&(name, _, _, _)| name.chars().count()).max().unwrap_or(0);
 
-    for &(name, _, opt_type_desc, desc) in flag_list {
-        let (width, extra) = match opt_type_desc {
-            Some(..) => (max_len - 4, "=val"),
-            None => (max_len, ""),
-        };
+    for &(name, _, _, desc) in flag_list {
         println!(
-            "    {} {:>width$}{} -- {}",
+            "    {} {:>width$}=val -- {}",
             cmdline_opt,
             name.replace("_", "-"),
-            extra,
             desc,
-            width = width
+            width = max_len
         );
     }
 }
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index c75f3b279a2..13c0c8f46b9 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -375,7 +375,7 @@ fn test_codegen_options_tracking_hash() {
     let mut opts = Options::default();
 
     // Make sure the changing an [UNTRACKED] option leaves the hash unchanged
-    opts.cg.ar = Some(String::from("abc"));
+    opts.cg.ar = String::from("abc");
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
     opts.cg.linker = Some(PathBuf::from("linker"));
@@ -479,11 +479,11 @@ fn test_codegen_options_tracking_hash() {
     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
     opts = reference.clone();
-    opts.cg.debuginfo = Some(0xdeadbeef);
+    opts.cg.debuginfo = 0xdeadbeef;
     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
     opts = reference.clone();
-    opts.cg.debuginfo = Some(0xba5eba11);
+    opts.cg.debuginfo = 0xba5eba11;
     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
     opts = reference.clone();
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 5a210547f13..6b7672a57f0 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -2182,9 +2182,7 @@ where
                         //
                         // For now, do not enable mutable_noalias by default at all, while the
                         // issue is being figured out.
-                        let mutable_noalias =
-                            tcx.sess.opts.debugging_opts.mutable_noalias.unwrap_or(false);
-                        if mutable_noalias {
+                        if tcx.sess.opts.debugging_opts.mutable_noalias {
                             PointerKind::UniqueBorrowed
                         } else {
                             PointerKind::Shared
diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs
index fa167dc2873..2513cfa73e5 100644
--- a/src/librustc_session/config.rs
+++ b/src/librustc_session/config.rs
@@ -617,10 +617,6 @@ impl Options {
 }
 
 impl DebuggingOptions {
-    pub fn ui_testing(&self) -> bool {
-        self.ui_testing.unwrap_or(false)
-    }
-
     pub fn diagnostic_handler_flags(&self, can_emit_warnings: bool) -> HandlerFlags {
         HandlerFlags {
             can_emit_warnings,
@@ -628,7 +624,7 @@ impl DebuggingOptions {
             dont_buffer_diagnostics: self.dont_buffer_diagnostics,
             report_delayed_bugs: self.report_delayed_bugs,
             macro_backtrace: self.macro_backtrace,
-            deduplicate_diagnostics: self.deduplicate_diagnostics.unwrap_or(true),
+            deduplicate_diagnostics: self.deduplicate_diagnostics,
         }
     }
 }
@@ -1395,15 +1391,14 @@ fn parse_opt_level(
     if max_o > max_c {
         OptLevel::Default
     } else {
-        match cg.opt_level.as_ref().map(String::as_ref) {
-            None => OptLevel::No,
-            Some("0") => OptLevel::No,
-            Some("1") => OptLevel::Less,
-            Some("2") => OptLevel::Default,
-            Some("3") => OptLevel::Aggressive,
-            Some("s") => OptLevel::Size,
-            Some("z") => OptLevel::SizeMin,
-            Some(arg) => {
+        match cg.opt_level.as_ref() {
+            "0" => OptLevel::No,
+            "1" => OptLevel::Less,
+            "2" => OptLevel::Default,
+            "3" => OptLevel::Aggressive,
+            "s" => OptLevel::Size,
+            "z" => OptLevel::SizeMin,
+            arg => {
                 early_error(
                     error_format,
                     &format!(
@@ -1436,10 +1431,10 @@ fn select_debuginfo(
         DebugInfo::Full
     } else {
         match cg.debuginfo {
-            None | Some(0) => DebugInfo::None,
-            Some(1) => DebugInfo::Limited,
-            Some(2) => DebugInfo::Full,
-            Some(arg) => {
+            0 => DebugInfo::None,
+            1 => DebugInfo::Limited,
+            2 => DebugInfo::Full,
+            arg => {
                 early_error(
                     error_format,
                     &format!(
@@ -1502,10 +1497,10 @@ fn parse_libs(
 }
 
 fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType) -> BorrowckMode {
-    match dopts.borrowck.as_ref().map(|s| &s[..]) {
-        None | Some("migrate") => BorrowckMode::Migrate,
-        Some("mir") => BorrowckMode::Mir,
-        Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
+    match dopts.borrowck.as_ref() {
+        "migrate" => BorrowckMode::Migrate,
+        "mir" => BorrowckMode::Mir,
+        m => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
     }
 }
 
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index 94e65093e71..5e17fc98985 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -181,27 +181,22 @@ macro_rules! options {
             let value = iter.next();
             let option_to_lookup = key.replace("-", "_");
             let mut found = false;
-            for &(candidate, setter, opt_type_desc, _) in $stat {
+            for &(candidate, setter, type_desc, _) in $stat {
                 if option_to_lookup != candidate { continue }
                 if !setter(&mut op, value) {
-                    match (value, opt_type_desc) {
-                        (Some(..), None) => {
-                            early_error(error_format, &format!("{} option `{}` takes no \
-                                                                value", $outputname, key))
-                        }
-                        (None, Some(type_desc)) => {
+                    match value {
+                        None => {
                             early_error(error_format, &format!("{0} option `{1}` requires \
                                                                 {2} ({3} {1}=<value>)",
                                                                $outputname, key,
                                                                type_desc, $prefix))
                         }
-                        (Some(value), Some(type_desc)) => {
+                        Some(value) => {
                             early_error(error_format, &format!("incorrect value `{}` for {} \
                                                                 option `{}` - {} was expected",
                                                                value, $outputname,
                                                                key, type_desc))
                         }
-                        (None, None) => panic!()
                     }
                 }
                 found = true;
@@ -231,61 +226,45 @@ macro_rules! options {
     }
 
     pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool;
-    pub const $stat: &[(&str, $setter_name, Option<&str>, &str)] =
+    pub const $stat: &[(&str, $setter_name, &str, &str)] =
         &[ $( (stringify!($opt), $mod_set::$opt, $mod_desc::$parse, $desc) ),* ];
 
     #[allow(non_upper_case_globals, dead_code)]
     mod $mod_desc {
-        pub const parse_bool: Option<&str> = None;
-        pub const parse_opt_bool: Option<&str> =
-            Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
-        pub const parse_string: Option<&str> = Some("a string");
-        pub const parse_string_push: Option<&str> = Some("a string");
-        pub const parse_pathbuf_push: Option<&str> = Some("a path");
-        pub const parse_opt_string: Option<&str> = Some("a string");
-        pub const parse_opt_pathbuf: Option<&str> = Some("a path");
-        pub const parse_list: Option<&str> = Some("a space-separated list of strings");
-        pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings");
-        pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings");
-        pub const parse_threads: Option<&str> = Some("a number");
-        pub const parse_uint: Option<&str> = Some("a number");
-        pub const parse_passes: Option<&str> =
-            Some("a space-separated list of passes, or `all`");
-        pub const parse_opt_uint: Option<&str> =
-            Some("a number");
-        pub const parse_panic_strategy: Option<&str> =
-            Some("either `unwind` or `abort`");
-        pub const parse_relro_level: Option<&str> =
-            Some("one of: `full`, `partial`, or `off`");
-        pub const parse_sanitizer: Option<&str> =
-            Some("one of: `address`, `leak`, `memory` or `thread`");
-        pub const parse_sanitizer_list: Option<&str> =
-            Some("comma separated list of sanitizers");
-        pub const parse_sanitizer_memory_track_origins: Option<&str> = None;
-        pub const parse_cfguard: Option<&str> =
-            Some("either `disabled`, `nochecks`, or `checks`");
-        pub const parse_linker_flavor: Option<&str> =
-            Some(::rustc_target::spec::LinkerFlavor::one_of());
-        pub const parse_optimization_fuel: Option<&str> =
-            Some("crate=integer");
-        pub const parse_unpretty: Option<&str> =
-            Some("`string` or `string=string`");
-        pub const parse_treat_err_as_bug: Option<&str> =
-            Some("either no value or a number bigger than 0");
-        pub const parse_lto: Option<&str> =
-            Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
-                  `fat`, or omitted");
-        pub const parse_linker_plugin_lto: Option<&str> =
-            Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
-                  or the path to the linker plugin");
-        pub const parse_switch_with_opt_path: Option<&str> =
-            Some("an optional path to the profiling data output directory");
-        pub const parse_merge_functions: Option<&str> =
-            Some("one of: `disabled`, `trampolines`, or `aliases`");
-        pub const parse_symbol_mangling_version: Option<&str> =
-            Some("either `legacy` or `v0` (RFC 2603)");
-        pub const parse_src_file_hash: Option<&str> =
-            Some("either `md5`, or `sha1`");
+        pub const parse_no_flag: &str = "no value";
+        pub const parse_bool: &str = "one of: `y`, `yes`, `on`, `n`, `no`, or `off`";
+        pub const parse_opt_bool: &str = parse_bool;
+        pub const parse_string: &str = "a string";
+        pub const parse_opt_string: &str = parse_string;
+        pub const parse_string_push: &str = parse_string;
+        pub const parse_opt_pathbuf: &str = "a path";
+        pub const parse_pathbuf_push: &str = parse_opt_pathbuf;
+        pub const parse_list: &str = "a space-separated list of strings";
+        pub const parse_opt_list: &str = parse_list;
+        pub const parse_opt_comma_list: &str = "a comma-separated list of strings";
+        pub const parse_uint: &str = "a number";
+        pub const parse_opt_uint: &str = parse_uint;
+        pub const parse_threads: &str = parse_uint;
+        pub const parse_passes: &str = "a space-separated list of passes, or `all`";
+        pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
+        pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
+        pub const parse_sanitizer: &str = "one of: `address`, `leak`, `memory` or `thread`";
+        pub const parse_sanitizer_list: &str = "comma separated list of sanitizers";
+        pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
+        pub const parse_cfguard: &str = "either `disabled`, `nochecks`, or `checks`";
+        pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of();
+        pub const parse_optimization_fuel: &str = "crate=integer";
+        pub const parse_unpretty: &str = "`string` or `string=string`";
+        pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0";
+        pub const parse_lto: &str =
+            "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
+        pub const parse_linker_plugin_lto: &str =
+            "either a boolean (`yes`, `no`, `on`, `off`, etc), or the path to the linker plugin";
+        pub const parse_switch_with_opt_path: &str =
+            "an optional path to the profiling data output directory";
+        pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
+        pub const parse_symbol_mangling_version: &str = "either `legacy` or `v0` (RFC 2603)";
+        pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
     }
 
     #[allow(dead_code)]
@@ -310,52 +289,54 @@ macro_rules! options {
             }
         )*
 
-        /// Set a flag to true. Note that it cannot set the flag to false, so
-        /// using this parser in combination with a flag that defaults to true
-        /// is useless; the flag will always be true.
-        fn parse_bool(slot: &mut bool, v: Option<&str>) -> bool {
+        /// This is for boolean options that don't take a value and start with
+        /// `no-`. This style of option is deprecated.
+        fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool {
             match v {
-                Some(..) => false,
                 None => { *slot = true; true }
+                Some(_) => false,
             }
         }
 
-        fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
+        /// Use this for any boolean option that has a static default.
+        fn parse_bool(slot: &mut bool, v: Option<&str>) -> bool {
             match v {
-                Some(s) => {
-                    match s {
-                        "n" | "no" | "off" => {
-                            *slot = Some(false);
-                        }
-                        "y" | "yes" | "on" => {
-                            *slot = Some(true);
-                        }
-                        _ => { return false; }
-                    }
+                Some("y") | Some("yes") | Some("on") | None => { *slot = true; true }
+                Some("n") | Some("no") | Some("off") => { *slot = false; true }
+                _ => false,
+            }
+        }
 
-                    true
-                },
-                None => { *slot = Some(true); true }
+        /// Use this for any boolean option that lacks a static default. (The
+        /// actions taken when such an option is not specified will depend on
+        /// other factors, such as other options, or target options.)
+        fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
+            match v {
+                Some("y") | Some("yes") | Some("on") | None => { *slot = Some(true); true }
+                Some("n") | Some("no") | Some("off") => { *slot = Some(false); true }
+                _ => false,
             }
         }
 
-        fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
+        /// Use this for any string option that has a static default.
+        fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
             match v {
-                Some(s) => { *slot = Some(s.to_string()); true },
+                Some(s) => { *slot = s.to_string(); true },
                 None => false,
             }
         }
 
-        fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool {
+        /// Use this for any string option that lacks a static default.
+        fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
             match v {
-                Some(s) => { *slot = Some(PathBuf::from(s)); true },
+                Some(s) => { *slot = Some(s.to_string()); true },
                 None => false,
             }
         }
 
-        fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
+        fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool {
             match v {
-                Some(s) => { *slot = s.to_string(); true },
+                Some(s) => { *slot = Some(PathBuf::from(s)); true },
                 None => false,
             }
         }
@@ -417,6 +398,7 @@ macro_rules! options {
             }
         }
 
+        /// Use this for any uint option that has a static default.
         fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool {
             match v.and_then(|s| s.parse().ok()) {
                 Some(i) => { *slot = i; true },
@@ -424,10 +406,11 @@ macro_rules! options {
             }
         }
 
+        /// Use this for any uint option that lacks a static default.
         fn parse_opt_uint(slot: &mut Option<usize>, v: Option<&str>) -> bool {
             match v {
                 Some(s) => { *slot = s.parse().ok(); slot.is_some() }
-                None => { *slot = None; false }
+                None => false
             }
         }
 
@@ -498,18 +481,11 @@ macro_rules! options {
         }
 
         fn parse_sanitizer_memory_track_origins(slot: &mut usize, v: Option<&str>) -> bool {
-            match v.map(|s| s.parse()) {
-                None => {
-                    *slot = 2;
-                    true
-                }
-                Some(Ok(i)) if i <= 2 => {
-                    *slot = i;
-                    true
-                }
-                _ => {
-                    false
-                }
+            match v {
+                Some("2") | None => { *slot = 2; true }
+                Some("1") => { *slot = 1; true }
+                Some("0") => { *slot = 0; true }
+                Some(_) => false,
             }
         }
 
@@ -647,7 +623,7 @@ macro_rules! options {
 options! {CodegenOptions, CodegenSetter, basic_codegen_options,
           build_codegen_options, "C", "codegen",
           CG_OPTIONS, cg_type_desc, cgsetters,
-    ar: Option<String> = (None, parse_opt_string, [UNTRACKED],
+    ar: String = (String::new(), parse_string, [UNTRACKED],
         "this option is deprecated and does nothing"),
     linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
         "system linker to link outputs with"),
@@ -656,7 +632,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
     link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
         "extra arguments to append to the linker invocation (space separated)"),
     link_dead_code: bool = (false, parse_bool, [UNTRACKED],
-        "don't let linker strip dead code (turning it on can be used for code coverage)"),
+        "keep dead code at link time (useful for code coverage) (default: no)"),
     lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED],
         "perform LLVM link-time optimizations"),
     target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
@@ -669,21 +645,21 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
     llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
         "a list of arguments to pass to LLVM (space separated)"),
     save_temps: bool = (false, parse_bool, [UNTRACKED],
-        "save all temporary output files during compilation"),
+        "save all temporary output files during compilation (default: no)"),
     rpath: bool = (false, parse_bool, [UNTRACKED],
-        "set rpath values in libs/exes"),
+        "set rpath values in libs/exes (default: no)"),
     overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use overflow checks for integer arithmetic"),
-    no_prepopulate_passes: bool = (false, parse_bool, [TRACKED],
-        "don't pre-populate the pass manager with a list of passes"),
-    no_vectorize_loops: bool = (false, parse_bool, [TRACKED],
-        "don't run the loop vectorization optimization passes"),
-    no_vectorize_slp: bool = (false, parse_bool, [TRACKED],
-        "don't run LLVM's SLP vectorization pass"),
+    no_prepopulate_passes: bool = (false, parse_no_flag, [TRACKED],
+        "give an empty list of passes to the pass manager"),
+    no_vectorize_loops: bool = (false, parse_no_flag, [TRACKED],
+        "disable loop vectorization optimization passes"),
+    no_vectorize_slp: bool = (false, parse_no_flag, [TRACKED],
+        "disable LLVM's SLP vectorization pass"),
     soft_float: bool = (false, parse_bool, [TRACKED],
-        "use soft float ABI (*eabihf targets only)"),
+        "use soft float ABI (*eabihf targets only) (default: no)"),
     prefer_dynamic: bool = (false, parse_bool, [TRACKED],
-        "prefer dynamic linking to static linking"),
+        "prefer dynamic linking to static linking (default: no)"),
     no_redzone: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "disable the use of the redzone"),
     relocation_model: Option<String> = (None, parse_opt_string, [TRACKED],
@@ -698,30 +674,30 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
         "divide crate into N units to optimize in parallel"),
     remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED],
         "print remarks for these optimization passes (space separated, or \"all\")"),
-    no_stack_check: bool = (false, parse_bool, [UNTRACKED],
-        "the `--no-stack-check` flag is deprecated and does nothing"),
-    debuginfo: Option<usize> = (None, parse_opt_uint, [TRACKED],
-        "debug info emission level, 0 = no debug info, 1 = line tables only, \
-         2 = full debug info with variable and type information"),
-    opt_level: Option<String> = (None, parse_opt_string, [TRACKED],
-        "optimize with possible levels 0-3, s, or z"),
+    no_stack_check: bool = (false, parse_no_flag, [UNTRACKED],
+        "this option is deprecated and does nothing"),
+    debuginfo: usize = (0, parse_uint, [TRACKED],
+        "debug info emission level (0 = no debug info, 1 = line tables only, \
+         2 = full debug info with variable and type information; default: 0)"),
+    opt_level: String = ("0".to_string(), parse_string, [TRACKED],
+        "optimization level (0-3, s, or z; default: 0)"),
     force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "force use of the frame pointers"),
     debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "explicitly enable the `cfg(debug_assertions)` directive"),
     inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
-        "set the threshold for inlining a function (default: 225)"),
+        "set the threshold for inlining a function"),
     panic: Option<PanicStrategy> = (None, parse_panic_strategy,
         [TRACKED], "panic strategy to compile crate with"),
     incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "enable incremental compilation"),
-    default_linker_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
-        "allow the linker to link its default libraries"),
+    default_linker_libraries: bool = (false, parse_bool, [UNTRACKED],
+        "allow the linker to link its default libraries (default: no)"),
     linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
                                            "linker flavor"),
     linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
         parse_linker_plugin_lto, [TRACKED],
-        "generate build artifacts that are compatible with linker-based LTO."),
+        "generate build artifacts that are compatible with linker-based LTO"),
     profile_generate: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
         parse_switch_with_opt_path, [TRACKED],
         "compile the program with profiling instrumentation"),
@@ -735,41 +711,43 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
         "the backend to use"),
     verbose: bool = (false, parse_bool, [UNTRACKED],
-        "in general, enable more debug printouts"),
+        "in general, enable more debug printouts (default: no)"),
+    // o/w tests have closure@path
     span_free_formats: bool = (false, parse_bool, [UNTRACKED],
-        "when debug-printing compiler state, do not include spans"), // o/w tests have closure@path
+        "exclude spans when debug-printing compiler state (default: no)"),
     identify_regions: bool = (false, parse_bool, [UNTRACKED],
-        "make unnamed regions display as '# (where # is some non-ident unique id)"),
-    borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED],
-        "select which borrowck is used (`mir` or `migrate`)"),
+        "display unnamed regions as `'<id>`, using a non-ident unique id (default: no)"),
+    borrowck: String = ("migrate".to_string(), parse_string, [UNTRACKED],
+        "select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"),
     time_passes: bool = (false, parse_bool, [UNTRACKED],
-        "measure time of each rustc pass"),
+        "measure time of each rustc pass (default: no)"),
     time: bool = (false, parse_bool, [UNTRACKED],
-        "measure time of rustc processes"),
+        "measure time of rustc processes (default: no)"),
     time_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
-        "measure time of each LLVM pass"),
+        "measure time of each LLVM pass (default: no)"),
     llvm_time_trace: bool = (false, parse_bool, [UNTRACKED],
-        "generate JSON tracing data file from LLVM data"),
+        "generate JSON tracing data file from LLVM data (default: no)"),
     input_stats: bool = (false, parse_bool, [UNTRACKED],
-        "gather statistics about the input"),
+        "gather statistics about the input (default: no)"),
     asm_comments: bool = (false, parse_bool, [TRACKED],
-        "generate comments into the assembly (may change behavior)"),
+        "generate comments into the assembly (may change behavior) (default: no)"),
     verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
-        "verify LLVM IR"),
+        "verify LLVM IR (default: no)"),
     borrowck_stats: bool = (false, parse_bool, [UNTRACKED],
-        "gather borrowck statistics"),
-    no_landing_pads: bool = (false, parse_bool, [TRACKED],
+        "gather borrowck statistics (default: no)"),
+    no_landing_pads: bool = (false, parse_no_flag, [TRACKED],
         "omit landing pads for unwinding"),
     fewer_names: bool = (false, parse_bool, [TRACKED],
-        "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR)"),
+        "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
+        (default: no)"),
     meta_stats: bool = (false, parse_bool, [UNTRACKED],
-        "gather metadata statistics"),
+        "gather metadata statistics (default: no)"),
     print_link_args: bool = (false, parse_bool, [UNTRACKED],
-        "print the arguments passed to the linker"),
+        "print the arguments passed to the linker (default: no)"),
     print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
-        "prints the LLVM optimization passes being run"),
+        "print the LLVM optimization passes being run (default: no)"),
     ast_json: bool = (false, parse_bool, [UNTRACKED],
-        "print the AST as JSON and halt"),
+        "print the AST as JSON and halt (default: no)"),
     // We default to 1 here since we want to behave like
     // a sequential compiler for now. This'll likely be adjusted
     // in the future. Note that -Zthreads=0 is the way to get
@@ -777,70 +755,73 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     threads: usize = (1, parse_threads, [UNTRACKED],
         "use a thread pool with N threads"),
     ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED],
-        "print the pre-expansion AST as JSON and halt"),
+        "print the pre-expansion AST as JSON and halt (default: no)"),
     ls: bool = (false, parse_bool, [UNTRACKED],
-        "list the symbols defined by a library crate"),
+        "list the symbols defined by a library crate (default: no)"),
     save_analysis: bool = (false, parse_bool, [UNTRACKED],
         "write syntax and type analysis (in JSON format) information, in \
-         addition to normal output"),
+         addition to normal output (default: no)"),
     print_region_graph: bool = (false, parse_bool, [UNTRACKED],
         "prints region inference graph. \
-         Use with RUST_REGION_GRAPH=help for more info"),
+         Use with RUST_REGION_GRAPH=help for more info (default: no)"),
     parse_only: bool = (false, parse_bool, [UNTRACKED],
-        "parse only; do not compile, assemble, or link"),
+        "parse only; do not compile, assemble, or link (default: no)"),
     dual_proc_macros: bool = (false, parse_bool, [TRACKED],
-        "load proc macros for both target and host, but only link to the target"),
-    no_codegen: bool = (false, parse_bool, [TRACKED],
+        "load proc macros for both target and host, but only link to the target (default: no)"),
+    no_codegen: bool = (false, parse_no_flag, [TRACKED],
         "run all passes except codegen; no output"),
     treat_err_as_bug: Option<usize> = (None, parse_treat_err_as_bug, [TRACKED],
         "treat error number `val` that occurs as bug"),
     report_delayed_bugs: bool = (false, parse_bool, [TRACKED],
-        "immediately print bugs registered with `delay_span_bug`"),
+        "immediately print bugs registered with `delay_span_bug` (default: no)"),
     macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
-        "show macro backtraces"),
+        "show macro backtraces (default: no)"),
     teach: bool = (false, parse_bool, [TRACKED],
-        "show extended diagnostic help"),
+        "show extended diagnostic help (default: no)"),
     terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
         "set the current terminal width"),
     panic_abort_tests: bool = (false, parse_bool, [TRACKED],
-        "support compiling tests with panic=abort"),
+        "support compiling tests with panic=abort (default: no)"),
     dep_tasks: bool = (false, parse_bool, [UNTRACKED],
-        "print tasks that execute and the color their dep node gets (requires debug build)"),
+        "print tasks that execute and the color their dep node gets (requires debug build) \
+        (default: no)"),
     incremental_info: bool = (false, parse_bool, [UNTRACKED],
-        "print high-level information about incremental reuse (or the lack thereof)"),
+        "print high-level information about incremental reuse (or the lack thereof) \
+        (default: no)"),
     incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
-        "verify incr. comp. hashes of green query instances"),
+        "verify incr. comp. hashes of green query instances (default: no)"),
     incremental_ignore_spans: bool = (false, parse_bool, [UNTRACKED],
-        "ignore spans during ICH computation -- used for testing"),
+        "ignore spans during ICH computation -- used for testing (default: no)"),
     instrument_mcount: bool = (false, parse_bool, [TRACKED],
-        "insert function instrument code for mcount-based tracing"),
+        "insert function instrument code for mcount-based tracing (default: no)"),
     dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
-        "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv)"),
+        "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \
+        (default: no)"),
     query_dep_graph: bool = (false, parse_bool, [UNTRACKED],
-        "enable queries of the dependency graph for regression testing"),
-    no_analysis: bool = (false, parse_bool, [UNTRACKED],
+        "enable queries of the dependency graph for regression testing (default: no)"),
+    no_analysis: bool = (false, parse_no_flag, [UNTRACKED],
         "parse and expand the source, but run no analysis"),
     unstable_options: bool = (false, parse_bool, [UNTRACKED],
-        "adds unstable command line options to rustc interface"),
+        "adds unstable command line options to rustc interface (default: no)"),
     force_overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "force overflow checks on or off"),
     trace_macros: bool = (false, parse_bool, [UNTRACKED],
-        "for every macro invocation, print its name and arguments"),
+        "for every macro invocation, print its name and arguments (default: no)"),
     debug_macros: bool = (false, parse_bool, [TRACKED],
-        "emit line numbers debug info inside macros"),
-    no_generate_arange_section: bool = (false, parse_bool, [TRACKED],
-        "don't generate DWARF address ranges that give faster lookups"),
+        "emit line numbers debug info inside macros (default: no)"),
+    no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
+        "omit DWARF address ranges that give faster lookups"),
     keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
-        "don't clear the hygiene data after analysis"),
+        "keep hygiene data after analysis (default: no)"),
     show_span: Option<String> = (None, parse_opt_string, [TRACKED],
         "show spans for compiler debugging (expr|pat|ty)"),
     print_type_sizes: bool = (false, parse_bool, [UNTRACKED],
-        "print layout information for each type encountered"),
+        "print layout information for each type encountered (default: no)"),
     print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "print the result of the monomorphization collection pass"),
     mir_opt_level: usize = (1, parse_uint, [TRACKED],
-        "set the MIR optimization level (0-3, default: 1)"),
-    mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "MIR optimization level (0-3; default: 1)"),
+    mutable_noalias: bool = (false, parse_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: no)"),
     dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "dump MIR state to file.
@@ -850,56 +831,58 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
         `foo | bar` all passes for function names containing 'foo' or 'bar'."),
 
-    dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED],
-        "the directory the MIR is dumped into"),
+    dump_mir_dir: String = ("mir_dump".to_string(), parse_string, [UNTRACKED],
+        "the directory the MIR is dumped into (default: `mir_dump`)"),
     dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
-        "in addition to `.mir` files, create graphviz `.dot` files"),
+        "in addition to `.mir` files, create graphviz `.dot` files (default: no)"),
     dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED],
-        "in addition to `.mir` files, create graphviz `.dot` files with dataflow results"),
+        "in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)"),
     dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
-        "if set, exclude the pass number when dumping MIR (used in tests)"),
+        "exclude the pass number when dumping MIR (used in tests) (default: no)"),
     mir_emit_retag: bool = (false, parse_bool, [TRACKED],
-        "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0"),
+        "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
+        (default: no)"),
     perf_stats: bool = (false, parse_bool, [UNTRACKED],
-        "print some performance-related statistics"),
+        "print some performance-related statistics (default: no)"),
     query_stats: bool = (false, parse_bool, [UNTRACKED],
-        "print some statistics about the query system"),
+        "print some statistics about the query system (default: no)"),
     hir_stats: bool = (false, parse_bool, [UNTRACKED],
-        "print some statistics about AST and HIR"),
+        "print some statistics about AST and HIR (default: no)"),
     always_encode_mir: bool = (false, parse_bool, [TRACKED],
-        "encode MIR of all functions into the crate metadata"),
+        "encode MIR of all functions into the crate metadata (default: no)"),
     unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED],
-        "take the breaks off const evaluation. NOTE: this is unsound"),
+        "take the brakes off const evaluation. NOTE: this is unsound (default: no)"),
     osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
-        "pass `-install_name @rpath/...` to the macOS linker"),
+        "pass `-install_name @rpath/...` to the macOS linker (default: no)"),
     sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [TRACKED],
-                                    "use a sanitizer"),
+        "use a sanitizer"),
     sanitizer_recover: Vec<Sanitizer> = (vec![], parse_sanitizer_list, [TRACKED],
-        "Enable recovery for selected sanitizers"),
+        "enable recovery for selected sanitizers"),
     sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED],
-        "Enable origins tracking in MemorySanitizer"),
+        "enable origins tracking in MemorySanitizer"),
     fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
         "set the optimization fuel quota for a crate"),
     print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
         "make rustc print the total optimization fuel used by a crate"),
     force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
-        "force all crates to be `rustc_private` unstable"),
+        "force all crates to be `rustc_private` unstable (default: no)"),
     pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED],
         "a single extra argument to prepend the linker invocation (can be used several times)"),
     pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
         "extra arguments to prepend to the linker invocation (space separated)"),
     profile: bool = (false, parse_bool, [TRACKED],
-                     "insert profiling code"),
-    no_profiler_runtime: bool = (false, parse_bool, [TRACKED],
-        "don't automatically inject the profiler_builtins crate"),
+        "insert profiling code (default: no)"),
+    no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED],
+        "prevent automatic injection of the profiler_builtins crate"),
     relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
         "choose which RELRO level to use"),
     nll_facts: bool = (false, parse_bool, [UNTRACKED],
-                       "dump facts from NLL analysis into side files"),
+        "dump facts from NLL analysis into side files (default: no)"),
     dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED],
-        "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting)."),
+        "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \
+        (default: no)"),
     polonius: bool = (false, parse_bool, [UNTRACKED],
-        "enable polonius-based borrow-checker"),
+        "enable polonius-based borrow-checker (default: no)"),
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable ThinLTO when possible"),
     inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
@@ -908,12 +891,12 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "choose the TLS model to use (`rustc --print tls-models` for details)"),
     saturating_float_casts: bool = (false, parse_bool, [TRACKED],
         "make float->int casts UB-free: numbers outside the integer type's range are clipped to \
-         the max/min integer respectively, and NaN is mapped to 0"),
+         the max/min integer respectively, and NaN is mapped to 0 (default: no)"),
     human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
-        "generate human-readable, predictable names for codegen units"),
+        "generate human-readable, predictable names for codegen units (default: no)"),
     dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
         "in dep-info output, omit targets for tracking dependencies of the dep-info files \
-         themselves"),
+         themselves (default: no)"),
     unpretty: Option<String> = (None, parse_unpretty, [UNTRACKED],
         "present the input source, unstable (and less-pretty) variants;
         valid types are any of the types for `--pretty`, as well as:
@@ -924,22 +907,26 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         `hir,typed` (HIR with types for each node),
         `hir-tree` (dump the raw HIR),
         `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"),
-    run_dsymutil: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "run `dsymutil` and delete intermediate object files"),
-    ui_testing: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
-        "format compiler diagnostics in a way that's better suitable for UI testing"),
+    // The default historical behavior was to always run dsymutil, so we're
+    // preserving that temporarily, but we're likely to switch the default
+    // soon.
+    run_dsymutil: bool = (true, parse_bool, [TRACKED],
+        "if on Mac, run `dsymutil` and delete intermediate object files (default: yes)"),
+    ui_testing: bool = (false, parse_bool, [UNTRACKED],
+        "emit compiler diagnostics in a form suitable for UI testing (default: no)"),
     embed_bitcode: bool = (false, parse_bool, [TRACKED],
-        "embed LLVM bitcode in object files"),
-    strip_debuginfo_if_disabled: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "tell the linker to strip debuginfo when building without debuginfo enabled."),
+        "embed LLVM bitcode in object files (default: no)"),
+    strip_debuginfo_if_disabled: bool = (false, parse_bool, [TRACKED],
+        "tell the linker to strip debuginfo when building without debuginfo enabled \
+        (default: no)"),
     share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "make the current crate share its generic instantiations"),
-    no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED],
-        "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
-    no_leak_check: bool = (false, parse_bool, [UNTRACKED],
-        "disables the 'leak check' for subtyping; unsound, but useful for tests"),
-    no_interleave_lints: bool = (false, parse_bool, [UNTRACKED],
-        "don't interleave execution of lints; allows benchmarking individual lints"),
+    no_parallel_llvm: bool = (false, parse_no_flag, [UNTRACKED],
+        "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
+    no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
+        "disable the 'leak check' for subtyping; unsound, but useful for tests"),
+    no_interleave_lints: bool = (false, parse_no_flag, [UNTRACKED],
+        "execute lints separately; allows benchmarking individual lints"),
     crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
         "inject the given attribute in the crate"),
     self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
@@ -947,18 +934,18 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "run the self profiler and output the raw event data"),
     // keep this in sync with the event filter names in librustc_data_structures/profiling.rs
     self_profile_events: Option<Vec<String>> = (None, parse_opt_comma_list, [UNTRACKED],
-        "specifies which kinds of events get recorded by the self profiler;
+        "specify the events recorded by the self profiler;
         for example: `-Z self-profile-events=default,query-keys`
         all options: none, all, default, generic-activity, query-provider, query-cache-hit
                      query-blocked, incr-cache-load, query-keys, function-args, args, llvm"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
-        "emits a section containing stack size metadata"),
+        "emit a section containing stack size metadata (default: no)"),
     plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
-          "whether to use the PLT when calling into shared libraries;
-          only has effect for PIC code on systems with ELF binaries
-          (default: PLT is disabled if full relro is enabled)"),
+        "whether to use the PLT when calling into shared libraries;
+        only has effect for PIC code on systems with ELF binaries
+        (default: PLT is disabled if full relro is enabled)"),
     merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
-        "control the operation of the MergeFunctions LLVM pass, taking
+        "control the operation of the MergeFunctions LLVM pass, taking \
          the same values as the target option of the same name"),
     allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
         "only allow the listed language features to be enabled in code (space separated)"),
@@ -966,22 +953,24 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         parse_symbol_mangling_version, [TRACKED],
         "which mangling version to use for symbol names"),
     binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
-        "include artifacts (sysroot, crate dependencies) used during compilation in dep-info"),
+        "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
+        (default: no)"),
     insert_sideeffect: bool = (false, parse_bool, [TRACKED],
         "fix undefined behavior when a thread doesn't eventually make progress \
-         (such as entering an empty infinite loop) by inserting llvm.sideeffect"),
-    deduplicate_diagnostics: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
-        "deduplicate identical diagnostics"),
+         (such as entering an empty infinite loop) by inserting llvm.sideeffect \
+         (default: no)"),
+    deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED],
+        "deduplicate identical diagnostics (default: yes)"),
     control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [UNTRACKED],
         "use Windows Control Flow Guard (`disabled`, `nochecks` or `checks`)"),
-    no_link: bool = (false, parse_bool, [TRACKED],
+    no_link: bool = (false, parse_no_flag, [TRACKED],
         "compile without linking"),
     link_only: bool = (false, parse_bool, [TRACKED],
-        "link the `.rlink` file generated by `-Z no-link`"),
-    new_llvm_pass_manager: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "use new LLVM pass manager"),
-    link_native_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
-        "Link native libraries in the linker invocation."),
+        "link the `.rlink` file generated by `-Z no-link` (default: no)"),
+    new_llvm_pass_manager: bool = (false, parse_bool, [TRACKED],
+        "use new LLVM pass manager (default: no)"),
+    link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
+        "link native libraries in the linker invocation (default: yes)"),
     src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED],
         "hash algorithm of source files in debug info (`md5`, or `sha1`)"),
 }
diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs
index 1c5d19db49c..f0bbe1d0a18 100644
--- a/src/librustc_session/session.rs
+++ b/src/librustc_session/session.rs
@@ -899,7 +899,7 @@ fn default_emitter(
                     short,
                     macro_backtrace,
                 );
-                Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing()))
+                Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing))
             } else {
                 let emitter = match dst {
                     None => EmitterWriter::stderr(
@@ -920,7 +920,7 @@ fn default_emitter(
                         macro_backtrace,
                     ),
                 };
-                Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing()))
+                Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing))
             }
         }
         (config::ErrorOutputType::Json { pretty, json_rendered }, None) => Box::new(
@@ -931,7 +931,7 @@ fn default_emitter(
                 json_rendered,
                 macro_backtrace,
             )
-            .ui_testing(sopts.debugging_opts.ui_testing()),
+            .ui_testing(sopts.debugging_opts.ui_testing),
         ),
         (config::ErrorOutputType::Json { pretty, json_rendered }, Some(dst)) => Box::new(
             JsonEmitter::new(
@@ -942,7 +942,7 @@ fn default_emitter(
                 json_rendered,
                 macro_backtrace,
             )
-            .ui_testing(sopts.debugging_opts.ui_testing()),
+            .ui_testing(sopts.debugging_opts.ui_testing),
         ),
     }
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 762ec7e9ac3..fe2727c962c 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -185,7 +185,7 @@ pub fn new_handler(
                     debugging_opts.terminal_width,
                     false,
                 )
-                .ui_testing(debugging_opts.ui_testing()),
+                .ui_testing(debugging_opts.ui_testing),
             )
         }
         ErrorOutputType::Json { pretty, json_rendered } => {
@@ -194,7 +194,7 @@ pub fn new_handler(
             });
             Box::new(
                 JsonEmitter::stderr(None, source_map, pretty, json_rendered, false)
-                    .ui_testing(debugging_opts.ui_testing()),
+                    .ui_testing(debugging_opts.ui_testing),
             )
         }
     };