]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/compiletest/src/runtest.rs
Auto merge of #45080 - clippered:issue-44986/fix-windows-ui-path, r=estebank
[rust.git] / src / tools / compiletest / src / runtest.rs
index 0ffc8b563bbb8e89203332d0e4efc561fcb83b49..0473c2a5405b02f12b5c5f4e4464c0d7a49df5c2 100644 (file)
@@ -25,6 +25,7 @@
 use std::env;
 use std::ffi::OsString;
 use std::fs::{self, File, create_dir_all};
+use std::fmt;
 use std::io::prelude::*;
 use std::io::{self, BufReader};
 use std::path::{Path, PathBuf};
@@ -1040,7 +1041,7 @@ fn check_expected_errors(&self,
                 None => {
                     if self.is_unexpected_compiler_message(actual_error, expect_help, expect_note) {
                         self.error(
-                            &format!("{}:{}: unexpected {:?}: '{}'",
+                            &format!("{}:{}: unexpected {}: '{}'",
                                      file_name,
                                      actual_error.line_num,
                                      actual_error.kind.as_ref()
@@ -1154,6 +1155,9 @@ fn document(&self, out_dir: &Path) -> ProcRes {
             .arg("-o").arg(out_dir)
             .arg(&self.testpaths.file)
             .args(&self.props.compile_flags);
+        if let Some(ref linker) = self.config.linker {
+            rustdoc.arg("--linker").arg(linker).arg("-Z").arg("unstable-options");
+        }
 
         self.compose_and_run_compiler(rustdoc, None)
     }
@@ -1440,6 +1444,9 @@ fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> C
         } else {
             rustc.args(self.split_maybe_args(&self.config.target_rustcflags));
         }
+        if let Some(ref linker) = self.config.linker {
+            rustc.arg(format!("-Clinker={}", linker));
+        }
 
         rustc.args(&self.props.compile_flags);
 
@@ -2028,7 +2035,6 @@ fn run_incremental_test(&self) {
         // Add an extra flag pointing at the incremental directory.
         let mut revision_props = self.props.clone();
         revision_props.incremental_dir = Some(incremental_dir);
-        revision_props.compile_flags.push(String::from("-Zincremental-info"));
 
         let revision_cx = TestCx {
             config: self.config,
@@ -2101,6 +2107,10 @@ fn run_rmake_test(&self) {
            .env("LLVM_COMPONENTS", &self.config.llvm_components)
            .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags);
 
+        if let Some(ref linker) = self.config.linker {
+            cmd.env("RUSTC_LINKER", linker);
+        }
+
         // We don't want RUSTFLAGS set from the outside to interfere with
         // compiler flags set in the test cases:
         cmd.env_remove("RUSTFLAGS");
@@ -2123,7 +2133,8 @@ fn run_rmake_test(&self) {
                .env("CXX", &self.config.cxx);
         } else {
             cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
-               .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags));
+               .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
+               .env("AR", &self.config.ar);
 
             if self.config.target.contains("windows") {
                 cmd.env("IS_WINDOWS", "1");
@@ -2229,7 +2240,7 @@ fn check_mir_dump(&self) {
             let (_, tests_text) = test_file_contents.split_at(idx + "// END_RUST SOURCE".len());
             let tests_text_str = String::from(tests_text);
             let mut curr_test : Option<&str> = None;
-            let mut curr_test_contents = Vec::new();
+            let mut curr_test_contents = vec![ExpectedLine::Elision];
             for l in tests_text_str.lines() {
                 debug!("line: {:?}", l);
                 if l.starts_with("// START ") {
@@ -2243,11 +2254,14 @@ fn check_mir_dump(&self) {
                     self.compare_mir_test_output(curr_test.unwrap(), &curr_test_contents);
                     curr_test = None;
                     curr_test_contents.clear();
+                    curr_test_contents.push(ExpectedLine::Elision);
                 } else if l.is_empty() {
                     // ignore
+                } else if l.starts_with("//") && l.split_at("//".len()).1.trim() == "..." {
+                    curr_test_contents.push(ExpectedLine::Elision)
                 } else if l.starts_with("// ") {
                     let (_, test_content) = l.split_at("// ".len());
-                    curr_test_contents.push(test_content);
+                    curr_test_contents.push(ExpectedLine::Text(test_content));
                 }
             }
         }
@@ -2265,7 +2279,7 @@ fn check_mir_test_timestamp(&self, test_name: &str, output_file: &Path) {
         }
     }
 
-    fn compare_mir_test_output(&self, test_name: &str, expected_content: &[&str]) {
+    fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedLine<&str>]) {
         let mut output_file = PathBuf::new();
         output_file.push(self.get_mir_dump_dir());
         output_file.push(test_name);
@@ -2277,38 +2291,77 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[&str]) {
         let mut dumped_string = String::new();
         dumped_file.read_to_string(&mut dumped_string).unwrap();
         let mut dumped_lines = dumped_string.lines().filter(|l| !l.is_empty());
-        let mut expected_lines = expected_content.iter().filter(|l| !l.is_empty());
+        let mut expected_lines = expected_content.iter().filter(|&l| {
+            if let &ExpectedLine::Text(l) = l {
+                !l.is_empty()
+            } else {
+                true
+            }
+        }).peekable();
 
-        // We expect each non-empty line from expected_content to appear
-        // in the dump in order, but there may be extra lines interleaved
-        while let Some(expected_line) = expected_lines.next() {
+        let compare = |expected_line, dumped_line| {
             let e_norm = normalize_mir_line(expected_line);
-            if e_norm.is_empty() {
-                continue;
+            let d_norm = normalize_mir_line(dumped_line);
+            debug!("found: {:?}", d_norm);
+            debug!("expected: {:?}", e_norm);
+            e_norm == d_norm
+        };
+
+        let error = |expected_line, extra_msg| {
+            let normalize_all = dumped_string.lines()
+                                             .map(nocomment_mir_line)
+                                             .filter(|l| !l.is_empty())
+                                             .collect::<Vec<_>>()
+                                             .join("\n");
+            let f = |l: &ExpectedLine<_>| match l {
+                &ExpectedLine::Elision => "... (elided)".into(),
+                &ExpectedLine::Text(t) => t
             };
-            let mut found = false;
-            while let Some(dumped_line) = dumped_lines.next() {
-                let d_norm = normalize_mir_line(dumped_line);
-                debug!("found: {:?}", d_norm);
-                debug!("expected: {:?}", e_norm);
-                if e_norm == d_norm {
-                    found = true;
-                    break;
-                };
-            }
-            if !found {
-                let normalize_all = dumped_string.lines()
-                                                 .map(nocomment_mir_line)
-                                                 .filter(|l| !l.is_empty())
-                                                 .collect::<Vec<_>>()
-                                                 .join("\n");
-                panic!("ran out of mir dump output to match against.\n\
-                        Did not find expected line: {:?}\n\
-                        Expected:\n{}\n\
-                        Actual:\n{}",
-                        expected_line,
-                        expected_content.join("\n"),
-                        normalize_all);
+            let expected_content = expected_content.iter()
+                                                   .map(|l| f(l))
+                                                   .collect::<Vec<_>>()
+                                                   .join("\n");
+            panic!("Did not find expected line, error: {}\n\
+                   Actual Line: {:?}\n\
+                   Expected:\n{}\n\
+                   Actual:\n{}",
+                   extra_msg,
+                   expected_line,
+                   expected_content,
+                   normalize_all);
+        };
+
+        // We expect each non-empty line to appear consecutively, non-consecutive lines
+        // must be separated by at least one Elision
+        while let Some(dumped_line) = dumped_lines.next() {
+            match expected_lines.next() {
+                Some(&ExpectedLine::Text(expected_line)) =>
+                    if !compare(expected_line, dumped_line) {
+                        error(expected_line,
+                              format!("Mismatch in lines\nExpected Line: {:?}", dumped_line));
+                    },
+                Some(&ExpectedLine::Elision) => {
+                    // skip any number of elisions in a row.
+                    while let Some(&&ExpectedLine::Elision) = expected_lines.peek() {
+                        expected_lines.next();
+                    }
+                    if let Some(&ExpectedLine::Text(expected_line)) = expected_lines.next() {
+                        let mut found = compare(expected_line, dumped_line);
+                        if found {
+                            continue;
+                        }
+                        while let Some(dumped_line) = dumped_lines.next() {
+                            found = compare(expected_line, dumped_line);
+                            if found {
+                                break;
+                            }
+                        }
+                        if !found {
+                            error(expected_line, "ran out of mir dump to match against".into());
+                        }
+                    }
+                },
+                None => {},
             }
         }
     }
@@ -2438,6 +2491,25 @@ enum TargetLocation {
     ThisDirectory(PathBuf),
 }
 
+#[derive(Clone, PartialEq, Eq)]
+enum ExpectedLine<T: AsRef<str>> {
+    Elision,
+    Text(T)
+}
+
+impl<T> fmt::Debug for ExpectedLine<T>
+where
+    T: AsRef<str> + fmt::Debug
+{
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        if let &ExpectedLine::Text(ref t) = self {
+            write!(formatter, "{:?}", t)
+        } else {
+            write!(formatter, "\"...\" (Elision)")
+        }
+    }
+}
+
 fn normalize_mir_line(line: &str) -> String {
     nocomment_mir_line(line).replace(char::is_whitespace, "")
 }