From 837817c0534aca5ef414663dc2d6cdd1bd350273 Mon Sep 17 00:00:00 2001
From: Cengiz Can <cengizc@gmail.com>
Date: Thu, 27 Apr 2017 22:41:18 +0300
Subject: [PATCH] use diff crate for compile-fail test diagnostics #41474

---
 src/Cargo.lock                       |  7 +++
 src/tools/compiletest/Cargo.toml     |  1 +
 src/tools/compiletest/src/main.rs    |  2 +-
 src/tools/compiletest/src/runtest.rs | 11 +++--
 src/tools/compiletest/src/uidiff.rs  | 73 ----------------------------
 5 files changed, 17 insertions(+), 77 deletions(-)
 delete mode 100644 src/tools/compiletest/src/uidiff.rs

diff --git a/src/Cargo.lock b/src/Cargo.lock
index f4c35719f3631..9ff558a8398e3 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -147,6 +147,7 @@ dependencies = [
 name = "compiletest"
 version = "0.0.0"
 dependencies = [
+ "diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -157,6 +158,11 @@ dependencies = [
 name = "core"
 version = "0.0.0"
 
+[[package]]
+name = "diff"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "dtoa"
 version = "0.4.1"
@@ -990,6 +996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e17a4a72ffea176f77d6e2db609c6c919ef221f23862c9915e687fb54d833485"
 "checksum cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "d18d68987ed4c516dcc3e7913659bfa4076f5182eea4a7e0038bb060953e76ac"
+"checksum diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0a515461b6c8c08419850ced27bc29e86166dcdcde8fbe76f8b1f0589bb49472"
 "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
 "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83"
 "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 7530b65a9b7c4..59d83de5787c4 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -8,3 +8,4 @@ log = "0.3"
 env_logger = { version = "0.4", default-features = false }
 rustc-serialize = "0.3"
 filetime = "0.1"
+diff = "0.1.10"
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 09d21221a8395..1506581a4b40f 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -25,6 +25,7 @@ extern crate rustc_serialize;
 extern crate log;
 extern crate env_logger;
 extern crate filetime;
+extern crate diff;
 
 use std::env;
 use std::ffi::OsString;
@@ -49,7 +50,6 @@ pub mod runtest;
 pub mod common;
 pub mod errors;
 mod raise_fd_limit;
-mod uidiff;
 
 fn main() {
     env_logger::init().unwrap();
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 7fb296c19f6ed..0bab518fccb8b 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -12,6 +12,7 @@ use common::Config;
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
 use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
 use common::{Incremental, RunMake, Ui, MirOpt};
+use diff;
 use errors::{self, ErrorKind, Error};
 use filetime::FileTime;
 use json;
@@ -19,7 +20,6 @@ use header::TestProps;
 use header;
 use procsrv;
 use test::TestPaths;
-use uidiff;
 use util::logv;
 
 use std::collections::HashSet;
@@ -2569,8 +2569,13 @@ actual:\n\
         println!("normalized {}:\n{}\n", kind, actual);
         println!("expected {}:\n{}\n", kind, expected);
         println!("diff of {}:\n", kind);
-        for line in uidiff::diff_lines(actual, expected) {
-            println!("{}", line);
+
+        for diff in diff::lines(actual, expected) {
+            match diff {
+                diff::Result::Left(l)    => println!("+{}", l),
+                diff::Result::Both(l, _) => println!(" {}", l),
+                diff::Result::Right(r)   => println!("-{}", r),
+            }
         }
 
         let output_file = self.output_base_name().with_extension(kind);
diff --git a/src/tools/compiletest/src/uidiff.rs b/src/tools/compiletest/src/uidiff.rs
deleted file mode 100644
index fca01029c4465..0000000000000
--- a/src/tools/compiletest/src/uidiff.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Code for checking whether the output of the compiler matches what is
-//! expected.
-
-pub fn diff_lines(actual: &str, expected: &str) -> Vec<String> {
-    // mega simplistic diff algorithm that just prints the things added/removed
-    zip_all(actual.lines(), expected.lines())
-        .enumerate()
-        .filter_map(|(i, (a, e))| {
-            match (a, e) {
-                (Some(a), Some(e)) => {
-                    if lines_match(e, a) {
-                        None
-                    } else {
-                        Some(format!("{:3} - |{}|\n    + |{}|\n", i, e, a))
-                    }
-                }
-                (Some(a), None) => Some(format!("{:3} -\n    + |{}|\n", i, a)),
-                (None, Some(e)) => Some(format!("{:3} - |{}|\n    +\n", i, e)),
-                (None, None) => panic!("Cannot get here"),
-            }
-        })
-        .collect()
-}
-
-fn lines_match(expected: &str, mut actual: &str) -> bool {
-    for (i, part) in expected.split("[..]").enumerate() {
-        match actual.find(part) {
-            Some(j) => {
-                if i == 0 && j != 0 {
-                    return false;
-                }
-                actual = &actual[j + part.len()..];
-            }
-            None => return false,
-        }
-    }
-    actual.is_empty() || expected.ends_with("[..]")
-}
-
-struct ZipAll<I1: Iterator, I2: Iterator> {
-    first: I1,
-    second: I2,
-}
-
-impl<T, I1: Iterator<Item = T>, I2: Iterator<Item = T>> Iterator for ZipAll<I1, I2> {
-    type Item = (Option<T>, Option<T>);
-    fn next(&mut self) -> Option<(Option<T>, Option<T>)> {
-        let first = self.first.next();
-        let second = self.second.next();
-
-        match (first, second) {
-            (None, None) => None,
-            (a, b) => Some((a, b)),
-        }
-    }
-}
-
-fn zip_all<T, I1: Iterator<Item = T>, I2: Iterator<Item = T>>(a: I1, b: I2) -> ZipAll<I1, I2> {
-    ZipAll {
-        first: a,
-        second: b,
-    }
-}