about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2019-05-05 12:37:27 -0700
committerGitHub <noreply@github.com>2019-05-05 12:37:27 -0700
commita8ed6777eef5f7d7a6a2dba3bbf0093fdd6fa8f9 (patch)
treed00ea2d3a8ffacda4fa23288dde17adfb52e5fe1 /src
parent577b0b9c627377665b6ff0339f5f66436f9b5c70 (diff)
parent80f54ba8811901ae8de1cc9971f2eab418c76fdd (diff)
downloadrust-a8ed6777eef5f7d7a6a2dba3bbf0093fdd6fa8f9.tar.gz
rust-a8ed6777eef5f7d7a6a2dba3bbf0093fdd6fa8f9.zip
Rollup merge of #60426 - varkor:fix-duplicate-arg-handling, r=alexcrichton
Stop `-O`/`-C opt-level` and `-g`/`-C debuginfo` conflicting

Allow `-O` and `-C opt-level`, and `-g` and `-C debuginfo` to be specified simultaneously without conflict. In such cases, the rightmost provided option is chosen.

Fixes https://github.com/rust-lang/rust/issues/7493.
Fixes https://github.com/rust-lang/rust/issues/32352.

~Blocked on https://github.com/rust-lang-nursery/getopts/pull/79.~

r? @alexcrichton
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/librustc/session/config.rs31
-rw-r--r--src/libtest/Cargo.toml2
-rw-r--r--src/test/run-make-fulldeps/override-aliased-flags/Makefile22
-rw-r--r--src/test/run-make-fulldeps/override-aliased-flags/main.rs1
5 files changed, 50 insertions, 8 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 9a410c339bf..3151b56d8e8 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -39,7 +39,7 @@ build_helper = { path = "../build_helper" }
 cmake = "0.1.38"
 filetime = "0.2"
 num_cpus = "1.0"
-getopts = "0.2.18"
+getopts = "0.2.19"
 cc = "1.0.35"
 libc = "0.2"
 serde = "1.0.8"
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index ad80e5d74bd..084a5429f26 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -2181,10 +2181,21 @@ pub fn build_session_options_and_crate_config(
         TargetTriple::from_triple(host_triple())
     };
     let opt_level = {
-        if matches.opt_present("O") {
-            if cg.opt_level.is_some() {
-                early_error(error_format, "-O and -C opt-level both provided");
+        // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
+        // to use them interchangeably. However, because they're technically different flags,
+        // we need to work out manually which should take precedence if both are supplied (i.e.
+        // the rightmost flag). We do this by finding the (rightmost) position of both flags and
+        // comparing them. Note that if a flag is not found, its position will be `None`, which
+        // always compared less than `Some(_)`.
+        let max_o = matches.opt_positions("O").into_iter().max();
+        let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
+            if let Some("opt-level") = s.splitn(2, '=').next() {
+                Some(i)
+            } else {
+                None
             }
+        }).max();
+        if max_o > max_c {
             OptLevel::Default
         } else {
             match cg.opt_level.as_ref().map(String::as_ref) {
@@ -2208,11 +2219,19 @@ pub fn build_session_options_and_crate_config(
             }
         }
     };
+    // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
+    // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
+    // for more details.
     let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
-    let debuginfo = if matches.opt_present("g") {
-        if cg.debuginfo.is_some() {
-            early_error(error_format, "-g and -C debuginfo both provided");
+    let max_g = matches.opt_positions("g").into_iter().max();
+    let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
+        if let Some("debuginfo") = s.splitn(2, '=').next() {
+            Some(i)
+        } else {
+            None
         }
+    }).max();
+    let debuginfo = if max_g > max_c {
         DebugInfo::Full
     } else {
         match cg.debuginfo {
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index 2e836b6772f..a72e4c70502 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -10,7 +10,7 @@ path = "lib.rs"
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-getopts = "0.2.18"
+getopts = "0.2.19"
 term = { path = "../libterm" }
 
 # not actually used but needed to always have proc_macro in the sysroot
diff --git a/src/test/run-make-fulldeps/override-aliased-flags/Makefile b/src/test/run-make-fulldeps/override-aliased-flags/Makefile
new file mode 100644
index 00000000000..bea610eeb9f
--- /dev/null
+++ b/src/test/run-make-fulldeps/override-aliased-flags/Makefile
@@ -0,0 +1,22 @@
+-include ../tools.mk
+
+# FIXME: it would be good to check that it's actually the rightmost flags
+# that are used when multiple flags are specified, but I can't think of a
+# reliable way to check this.
+
+all:
+	# Test that `-O` and `-C opt-level` can be specified multiple times.
+	# The rightmost flag will be used over any previous flags.
+	$(RUSTC) -O -O main.rs
+	$(RUSTC) -O -C opt-level=0 main.rs
+	$(RUSTC) -C opt-level=0 -O main.rs
+	$(RUSTC) -C opt-level=0 -C opt-level=2 main.rs
+	$(RUSTC) -C opt-level=2 -C opt-level=0 main.rs
+
+	# Test that `-g` and `-C debuginfo` can be specified multiple times.
+	# The rightmost flag will be used over any previous flags.
+	$(RUSTC) -g -g main.rs
+	$(RUSTC) -g -C debuginfo=0 main.rs
+	$(RUSTC) -C debuginfo=0 -g main.rs
+	$(RUSTC) -C debuginfo=0 -C debuginfo=2 main.rs
+	$(RUSTC) -C debuginfo=2 -C debuginfo=0 main.rs
diff --git a/src/test/run-make-fulldeps/override-aliased-flags/main.rs b/src/test/run-make-fulldeps/override-aliased-flags/main.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/src/test/run-make-fulldeps/override-aliased-flags/main.rs
@@ -0,0 +1 @@
+fn main() {}