@@ -1911,6 +1911,7 @@ fn run_rustdoc_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
1911
1911
}
1912
1912
1913
1913
fn run_codegen_units_test ( config : & Config , props : & TestProps , testpaths : & TestPaths ) {
1914
+
1914
1915
assert ! ( props. revisions. is_empty( ) , "revisions not relevant here" ) ;
1915
1916
1916
1917
let proc_res = compile_test ( config, props, testpaths) ;
@@ -1921,36 +1922,148 @@ fn run_codegen_units_test(config: &Config, props: &TestProps, testpaths: &TestPa
1921
1922
1922
1923
check_no_compiler_crash ( None , & proc_res) ;
1923
1924
1924
- let prefix = "TRANS_ITEM " ;
1925
+ const PREFIX : & ' static str = "TRANS_ITEM " ;
1926
+ const CGU_MARKER : & ' static str = "@@" ;
1925
1927
1926
- let actual: HashSet < String > = proc_res
1928
+ let actual: Vec < TransItem > = proc_res
1927
1929
. stdout
1928
1930
. lines ( )
1929
- . filter ( |line| line. starts_with ( prefix ) )
1930
- . map ( |s| ( & s [ prefix . len ( ) .. ] ) . to_string ( ) )
1931
+ . filter ( |line| line. starts_with ( PREFIX ) )
1932
+ . map ( str_to_trans_item )
1931
1933
. collect ( ) ;
1932
1934
1933
- let expected: HashSet < String > = errors:: load_errors ( & testpaths. file , None )
1935
+ let expected: Vec < TransItem > = errors:: load_errors ( & testpaths. file , None )
1934
1936
. iter ( )
1935
- . map ( |e| e. msg . trim ( ) . to_string ( ) )
1937
+ . map ( |e| str_to_trans_item ( & e. msg [ .. ] ) )
1936
1938
. collect ( ) ;
1937
1939
1938
- if actual != expected {
1939
- let mut missing: Vec < _ > = expected. difference ( & actual) . collect ( ) ;
1940
+ let mut missing = Vec :: new ( ) ;
1941
+ let mut wrong_cgus = Vec :: new ( ) ;
1942
+
1943
+ for expected_item in & expected {
1944
+ let actual_item_with_same_name = actual. iter ( )
1945
+ . find ( |ti| ti. name == expected_item. name ) ;
1946
+
1947
+ if let Some ( actual_item) = actual_item_with_same_name {
1948
+ if !expected_item. codegen_units . is_empty ( ) {
1949
+ // Also check for codegen units
1950
+ if expected_item. codegen_units != actual_item. codegen_units {
1951
+ wrong_cgus. push ( ( expected_item. clone ( ) , actual_item. clone ( ) ) ) ;
1952
+ }
1953
+ }
1954
+ } else {
1955
+ missing. push ( expected_item. string . clone ( ) ) ;
1956
+ }
1957
+ }
1958
+
1959
+ let unexpected: Vec < _ > =
1960
+ actual. iter ( )
1961
+ . filter ( |acgu| !expected. iter ( ) . any ( |ecgu| acgu. name == ecgu. name ) )
1962
+ . map ( |acgu| acgu. string . clone ( ) )
1963
+ . collect ( ) ;
1964
+
1965
+ if !missing. is_empty ( ) {
1940
1966
missing. sort ( ) ;
1941
1967
1942
- let mut too_much: Vec < _ > = actual. difference ( & expected) . collect ( ) ;
1943
- too_much. sort ( ) ;
1968
+ println ! ( "\n These items should have been contained but were not:\n " ) ;
1969
+
1970
+ for item in & missing {
1971
+ println ! ( "{}" , item) ;
1972
+ }
1944
1973
1945
- println ! ( "Expected and actual sets of codegen-items differ.\n \
1946
- These items should have been contained but were not:\n \n \
1947
- {}\n \n \
1948
- These items were contained but should not have been:\n \n \
1949
- {}\n \n ",
1950
- missing. iter( ) . fold( "" . to_string( ) , |s1, s2| s1 + "\n " + s2) ,
1951
- too_much. iter( ) . fold( "" . to_string( ) , |s1, s2| s1 + "\n " + s2) ) ;
1974
+ println ! ( "\n " ) ;
1975
+ }
1976
+
1977
+ if !unexpected. is_empty ( ) {
1978
+ let sorted = {
1979
+ let mut sorted = unexpected. clone ( ) ;
1980
+ sorted. sort ( ) ;
1981
+ sorted
1982
+ } ;
1983
+
1984
+ println ! ( "\n These items were contained but should not have been:\n " ) ;
1985
+
1986
+ for item in sorted {
1987
+ println ! ( "{}" , item) ;
1988
+ }
1989
+
1990
+ println ! ( "\n " ) ;
1991
+ }
1992
+
1993
+ if !wrong_cgus. is_empty ( ) {
1994
+ wrong_cgus. sort_by_key ( |pair| pair. 0 . name . clone ( ) ) ;
1995
+ println ! ( "\n The following items were assigned to wrong codegen units:\n " ) ;
1996
+
1997
+ for & ( ref expected_item, ref actual_item) in & wrong_cgus {
1998
+ println ! ( "{}" , expected_item. name) ;
1999
+ println ! ( " expected: {}" , codegen_units_to_str( & expected_item. codegen_units) ) ;
2000
+ println ! ( " actual: {}" , codegen_units_to_str( & actual_item. codegen_units) ) ;
2001
+ println ! ( "" ) ;
2002
+ }
2003
+ }
2004
+
2005
+ if !( missing. is_empty ( ) && unexpected. is_empty ( ) && wrong_cgus. is_empty ( ) )
2006
+ {
1952
2007
panic ! ( ) ;
1953
2008
}
2009
+
2010
+ #[ derive( Clone , Eq , PartialEq ) ]
2011
+ struct TransItem {
2012
+ name : String ,
2013
+ codegen_units : HashSet < String > ,
2014
+ string : String ,
2015
+ }
2016
+
2017
+ // [TRANS_ITEM] name [@@ (cgu)+]
2018
+ fn str_to_trans_item ( s : & str ) -> TransItem {
2019
+ let s = if s. starts_with ( PREFIX ) {
2020
+ ( & s[ PREFIX . len ( ) ..] ) . trim ( )
2021
+ } else {
2022
+ s. trim ( )
2023
+ } ;
2024
+
2025
+ let full_string = format ! ( "{}{}" , PREFIX , s. trim( ) . to_owned( ) ) ;
2026
+
2027
+ let parts: Vec < & str > = s. split ( CGU_MARKER )
2028
+ . map ( str:: trim)
2029
+ . filter ( |s| !s. is_empty ( ) )
2030
+ . collect ( ) ;
2031
+
2032
+ let name = parts[ 0 ] . trim ( ) ;
2033
+
2034
+ let cgus = if parts. len ( ) > 1 {
2035
+ let cgus_str = parts[ 1 ] ;
2036
+
2037
+ cgus_str. split ( " " )
2038
+ . map ( str:: trim)
2039
+ . filter ( |s| !s. is_empty ( ) )
2040
+ . map ( str:: to_owned)
2041
+ . collect ( )
2042
+ }
2043
+ else {
2044
+ HashSet :: new ( )
2045
+ } ;
2046
+
2047
+ TransItem {
2048
+ name : name. to_owned ( ) ,
2049
+ codegen_units : cgus,
2050
+ string : full_string,
2051
+ }
2052
+ }
2053
+
2054
+ fn codegen_units_to_str ( cgus : & HashSet < String > ) -> String
2055
+ {
2056
+ let mut cgus: Vec < _ > = cgus. iter ( ) . collect ( ) ;
2057
+ cgus. sort ( ) ;
2058
+
2059
+ let mut string = String :: new ( ) ;
2060
+ for cgu in cgus {
2061
+ string. push_str ( & cgu[ ..] ) ;
2062
+ string. push_str ( " " ) ;
2063
+ }
2064
+
2065
+ string
2066
+ }
1954
2067
}
1955
2068
1956
2069
fn run_incremental_test ( config : & Config , props : & TestProps , testpaths : & TestPaths ) {
0 commit comments