From 9dee59071a405b137442ac13f5304e52595d2f32 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Wed, 15 Jul 2020 22:39:39 +0800 Subject: [PATCH 01/23] Rearrange the pipeline of `pow` to gain efficiency The check of the `exp` parameter seems useless if we execute the while-loop more than once. The original implementation of `pow` function using one more comparison if the `exp==0` and may break the pipeline of the cpu, which may generate a slower code. The performance gap between the old and the new implementation may be small, but IMO, at least the newer one looks more beautiful. --- bench prog: ``` #![feature(test)] extern crate test; #[macro_export]macro_rules! timing{ ($a:expr)=>{let time=std::time::Instant::now();{$a;}print!("{:?} ",time.elapsed())}; ($a:expr,$b:literal)=>{let time=std::time::Instant::now();let mut a=0;for _ in 0..$b{a^=$a;}print!("{:?} {} ",time.elapsed(),a)} } #[inline] pub fn pow_rust(x:i64, mut exp: u32) -> i64 { let mut base = x; let mut acc = 1; while exp > 1 { if (exp & 1) == 1 { acc = acc * base; } exp /= 2; base = base * base; } if exp == 1 { acc = acc * base; } acc } #[inline] pub fn pow_new(x:i64, mut exp: u32) -> i64 { if exp==0{ 1 }else{ let mut base = x; let mut acc = 1; while exp > 1 { if (exp & 1) == 1 { acc = acc * base; } exp >>= 1; base = base * base; } acc * base } } fn main(){ let a=2i64; let b=1_u32; println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); timing!(test::black_box(a).pow(test::black_box(b)),100000000); timing!(pow_new(test::black_box(a),test::black_box(b)),100000000); timing!(pow_rust(test::black_box(a),test::black_box(b)),100000000); println!(); } ``` bench in my laptop: ``` neutron@Neutron:/me/rust$ rc commit.rs rustc commit.rs && ./commit 3.978419716s 0 4.079765171s 0 3.964630622s 0 3.997127013s 0 4.260304804s 0 3.997638211s 0 3.963195544s 0 4.11657718s 0 4.176054164s 0 3.830128579s 0 3.980396122s 0 3.937258567s 0 3.986055948s 0 4.127804162s 0 4.018943411s 0 4.185568857s 0 4.217512517s 0 3.98313603s 0 3.863018225s 0 4.030447988s 0 3.694878237s 0 4.206987927s 0 4.137608047s 0 4.115564664s 0 neutron@Neutron:/me/rust$ rc commit.rs -O rustc commit.rs -O && ./commit 162.111993ms 0 165.107125ms 0 166.26924ms 0 175.20479ms 0 205.062565ms 0 176.278791ms 0 174.408975ms 0 166.526899ms 0 201.857604ms 0 146.190062ms 0 168.592821ms 0 154.61411ms 0 199.678912ms 0 168.411598ms 0 162.129996ms 0 147.420765ms 0 209.759326ms 0 154.807907ms 0 165.507134ms 0 188.476239ms 0 157.351524ms 0 121.320123ms 0 126.401229ms 0 114.86428ms 0 ``` --- src/libcore/num/mod.rs | 88 +++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f4a1afd436adb..dd9fd04d41294 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1103,6 +1103,9 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn checked_pow(self, mut exp: u32) -> Option { + if exp == 0 { + return Some(1); + } let mut base = self; let mut acc: Self = 1; @@ -1113,15 +1116,11 @@ $EndFeature, " exp /= 2; base = try_opt!(base.checked_mul(base)); } - + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - acc = try_opt!(acc.checked_mul(base)); - } - - Some(acc) + Some(try_opt!(acc.checked_mul(base))) } } @@ -1631,6 +1630,9 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_pow(self, mut exp: u32) -> Self { + if exp == 0 { + return 1; + } let mut base = self; let mut acc: Self = 1; @@ -1641,15 +1643,12 @@ $EndFeature, " exp /= 2; base = base.wrapping_mul(base); } - + + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - acc = acc.wrapping_mul(base); - } - - acc + acc.wrapping_mul(base); } } @@ -1999,6 +1998,9 @@ $EndFeature, " without modifying the original"] #[inline] pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { + if exp == 0 { + return (1,false); + } let mut base = self; let mut acc: Self = 1; let mut overflown = false; @@ -2016,17 +2018,14 @@ $EndFeature, " base = r.0; overflown |= r.1; } - + + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - r = acc.overflowing_mul(base); - acc = r.0; - overflown |= r.1; - } - - (acc, overflown) + r = acc.overflowing_mul(base); + r.1 |= overflown; + r } } @@ -2050,6 +2049,9 @@ $EndFeature, " #[inline] #[rustc_inherit_overflow_checks] pub const fn pow(self, mut exp: u32) -> Self { + if exp == 0 { + return 1; + } let mut base = self; let mut acc = 1; @@ -2061,14 +2063,11 @@ $EndFeature, " base = base * base; } + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - acc = acc * base; - } - - acc + acc * base } } @@ -3306,6 +3305,9 @@ assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);", $EndFeature, " without modifying the original"] #[inline] pub const fn checked_pow(self, mut exp: u32) -> Option { + if exp == 0 { + return Some(1); + } let mut base = self; let mut acc: Self = 1; @@ -3317,14 +3319,12 @@ assert_eq!(", stringify!($SelfT), "::MAX.checked_pow(2), None);", $EndFeature, " base = try_opt!(base.checked_mul(base)); } + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - acc = try_opt!(acc.checked_mul(base)); - } - Some(acc) + Some(try_opt!(acc.checked_mul(base))) } } @@ -3715,6 +3715,9 @@ assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, " without modifying the original"] #[inline] pub const fn wrapping_pow(self, mut exp: u32) -> Self { + if exp == 0 { + return 1; + } let mut base = self; let mut acc: Self = 1; @@ -3726,14 +3729,11 @@ assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, " base = base.wrapping_mul(base); } + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - acc = acc.wrapping_mul(base); - } - - acc + acc.wrapping_mul(base) } } @@ -4058,16 +4058,14 @@ assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, " overflown |= r.1; } + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - r = acc.overflowing_mul(base); - acc = r.0; - overflown |= r.1; - } + r = acc.overflowing_mul(base); + r.1 |= overflown; - (acc, overflown) + r } } @@ -4088,6 +4086,9 @@ Basic usage: #[inline] #[rustc_inherit_overflow_checks] pub const fn pow(self, mut exp: u32) -> Self { + if exp == 0 { + return 1; + } let mut base = self; let mut acc = 1; @@ -4099,14 +4100,11 @@ Basic usage: base = base * base; } + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - if exp == 1 { - acc = acc * base; - } - - acc + acc * base } } From ebafab96fce602b45b81a3c5e5acc5af9b7dec3f Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 09:25:01 +0800 Subject: [PATCH 02/23] delete an unnecessary semicolon... Sorry for the typo. --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index dd9fd04d41294..7f89af944ddd1 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1648,7 +1648,7 @@ $EndFeature, " // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a // needless overflow. - acc.wrapping_mul(base); + acc.wrapping_mul(base) } } From 020c0b5cb3e92b232adaf60cd130a443e0f12f43 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 09:54:48 +0800 Subject: [PATCH 03/23] delete trailing whitespace Sorry, too.. --- src/libcore/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7f89af944ddd1..7408b2c31b18f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1643,7 +1643,7 @@ $EndFeature, " exp /= 2; base = base.wrapping_mul(base); } - + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a @@ -2018,7 +2018,7 @@ $EndFeature, " base = r.0; overflown |= r.1; } - + // since exp!=0, finally the exp must be 1. // Deal with the final bit of the exponent separately, since // squaring the base afterwards is not necessary and may cause a From 8f58ce41f1c33089c3746ff3941994042dfb51d5 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 14:30:07 +0800 Subject: [PATCH 04/23] Sorry for the missing... I checked all the implementations, and finally found that there is one function that does not check whether `exp == 0` --- src/libcore/num/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7408b2c31b18f..c576465c622fe 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4040,6 +4040,9 @@ assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, " without modifying the original"] #[inline] pub const fn overflowing_pow(self, mut exp: u32) -> (Self, bool) { + if exp == 0{ + return (1,false); + } let mut base = self; let mut acc: Self = 1; let mut overflown = false; From f3d476b16a9ec9c1471b0eded0bba4ece458d118 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 14:58:20 +0800 Subject: [PATCH 05/23] add extra tests --- src/libcore/tests/num/int_macros.rs | 31 +++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 8396a0dd62db9..7bdaf8364dd4e 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -252,15 +252,42 @@ macro_rules! int_module { assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>); } + #[test] fn test_pow() { let mut r = 2 as $T; - assert_eq!(r.pow(2), 4 as $T); assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(2), 4 as $T); + assert_eq!(r.wrapping_pow(0), 1 as $T); + assert_eq!(r.checked_pow(2), Some(4 as $T)); + assert_eq!(r.checked_pow(0), Some(1 as $T)); + assert_eq!(r.overflowing_pow(2), (4 as $T,false)); + assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.saturating_pow(2), 4 as $T); + assert_eq!(r.saturating_pow(0), 1 as $T); + + r = MAX; + // use `^` to represent .pow() with no overflow. + // if itest::MAX == 2^j-1, then itest is a `j` bit int, + // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`, + // thussaturating_pow the overflowing result is exactly 1. + assert_eq!(r.wrapping_pow(2), 1 as $T); + assert_eq!(r.checked_pow(2), None); + assert_eq!(r.overflowing_pow(2), (1 as $T,true)); + assert_eq!(r.saturating_pow(2), MAX); + //test for negative exponent. r = -2 as $T; - assert_eq!(r.pow(2), 4 as $T); assert_eq!(r.pow(3), -8 as $T); + assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(3), -8 as $T); + assert_eq!(r.wrapping_pow(0), 1 as $T); + assert_eq!(r.checked_pow(3), Some(-8) as $T); + assert_eq!(r.checked_pow(0), Some(1) as $T); + assert_eq!(r.overflowing_pow(3), (-8 as $T,false)); + assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.saturating_pow(3), -8 as $T); + assert_eq!(r.saturating_pow(0), 1 as $T); } } }; From 87958456a14fdacb2f4027522b0d6c06ca6da284 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 14:59:38 +0800 Subject: [PATCH 06/23] add extra tests. finished adding the extra tests to prevent further typo --- src/libcore/tests/num/uint_macros.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs index 8f1ca8e6fac2c..530a94f5723d7 100644 --- a/src/libcore/tests/num/uint_macros.rs +++ b/src/libcore/tests/num/uint_macros.rs @@ -184,6 +184,31 @@ macro_rules! uint_module { assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>); assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>); } + + #[test] + fn test_pow() { + let mut r = 2 as $T; + assert_eq!(r.pow(2), 4 as $T); + assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(2), 4 as $T); + assert_eq!(r.wrapping_pow(0), 1 as $T); + assert_eq!(r.checked_pow(2), Some(4 as $T)); + assert_eq!(r.checked_pow(0), Some(1 as $T)); + assert_eq!(r.overflowing_pow(2), (4 as $T,false)); + assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.saturating_pow(2), 4 as $T); + assert_eq!(r.saturating_pow(0), 1 as $T); + + r = MAX; + // use `^` to represent .pow() with no overflow. + // if itest::MAX == 2^j-1, then itest is a `j` bit int, + // so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`, + // thussaturating_pow the overflowing result is exactly 1. + assert_eq!(r.wrapping_pow(2), 1 as $T); + assert_eq!(r.checked_pow(2), None); + assert_eq!(r.overflowing_pow(2), (1 as $T,true)); + assert_eq!(r.saturating_pow(2), MAX); + } } }; } From 319db3089b45ba0fef385d78252082f2d0f8d105 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 15:06:30 +0800 Subject: [PATCH 07/23] add pow(2) to negative exp --- src/libcore/tests/num/int_macros.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 7bdaf8364dd4e..3293a6a8ef894 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -278,14 +278,19 @@ macro_rules! int_module { assert_eq!(r.saturating_pow(2), MAX); //test for negative exponent. r = -2 as $T; + assert_eq!(r.pow(2), 4 as $T); assert_eq!(r.pow(3), -8 as $T); assert_eq!(r.pow(0), 1 as $T); + assert_eq!(r.wrapping_pow(2), 4 as $T); assert_eq!(r.wrapping_pow(3), -8 as $T); assert_eq!(r.wrapping_pow(0), 1 as $T); - assert_eq!(r.checked_pow(3), Some(-8) as $T); - assert_eq!(r.checked_pow(0), Some(1) as $T); + assert_eq!(r.checked_pow(2), Some(4 as $T)); + assert_eq!(r.checked_pow(3), Some(-8 as $T)); + assert_eq!(r.checked_pow(0), Some(1 as $T)); + assert_eq!(r.overflowing_pow(2), (4 as $T,false)); assert_eq!(r.overflowing_pow(3), (-8 as $T,false)); assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.saturating_pow(2), 4 as $T); assert_eq!(r.saturating_pow(3), -8 as $T); assert_eq!(r.saturating_pow(0), 1 as $T); } From e2f3e3c8072c69db566eca24c04233886d4c2a02 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 15:19:48 +0800 Subject: [PATCH 08/23] add whitespace. --- src/libcore/tests/num/uint_macros.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs index 530a94f5723d7..b84a8a7d9f88b 100644 --- a/src/libcore/tests/num/uint_macros.rs +++ b/src/libcore/tests/num/uint_macros.rs @@ -194,8 +194,8 @@ macro_rules! uint_module { assert_eq!(r.wrapping_pow(0), 1 as $T); assert_eq!(r.checked_pow(2), Some(4 as $T)); assert_eq!(r.checked_pow(0), Some(1 as $T)); - assert_eq!(r.overflowing_pow(2), (4 as $T,false)); - assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.overflowing_pow(2), (4 as $T, false)); + assert_eq!(r.overflowing_pow(0), (1 as $T, false)); assert_eq!(r.saturating_pow(2), 4 as $T); assert_eq!(r.saturating_pow(0), 1 as $T); @@ -206,7 +206,7 @@ macro_rules! uint_module { // thussaturating_pow the overflowing result is exactly 1. assert_eq!(r.wrapping_pow(2), 1 as $T); assert_eq!(r.checked_pow(2), None); - assert_eq!(r.overflowing_pow(2), (1 as $T,true)); + assert_eq!(r.overflowing_pow(2), (1 as $T, true)); assert_eq!(r.saturating_pow(2), MAX); } } From d5d7ca29958dd13b8543fa471d7d20ec723daf1c Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 15:20:16 +0800 Subject: [PATCH 09/23] add whitespace --- src/libcore/tests/num/int_macros.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 3293a6a8ef894..2eb7146da2716 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -274,7 +274,7 @@ macro_rules! int_module { // thussaturating_pow the overflowing result is exactly 1. assert_eq!(r.wrapping_pow(2), 1 as $T); assert_eq!(r.checked_pow(2), None); - assert_eq!(r.overflowing_pow(2), (1 as $T,true)); + assert_eq!(r.overflowing_pow(2), (1 as $T, true)); assert_eq!(r.saturating_pow(2), MAX); //test for negative exponent. r = -2 as $T; @@ -287,9 +287,9 @@ macro_rules! int_module { assert_eq!(r.checked_pow(2), Some(4 as $T)); assert_eq!(r.checked_pow(3), Some(-8 as $T)); assert_eq!(r.checked_pow(0), Some(1 as $T)); - assert_eq!(r.overflowing_pow(2), (4 as $T,false)); - assert_eq!(r.overflowing_pow(3), (-8 as $T,false)); - assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.overflowing_pow(2), (4 as $T, false)); + assert_eq!(r.overflowing_pow(3), (-8 as $T, false)); + assert_eq!(r.overflowing_pow(0), (1 as $T, false)); assert_eq!(r.saturating_pow(2), 4 as $T); assert_eq!(r.saturating_pow(3), -8 as $T); assert_eq!(r.saturating_pow(0), 1 as $T); From 7599e01e92ec585e35726b1ea28f13c0c6f69682 Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 15:20:44 +0800 Subject: [PATCH 10/23] add whitespace --- src/libcore/tests/num/int_macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 2eb7146da2716..e9046f6d26af0 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -262,8 +262,8 @@ macro_rules! int_module { assert_eq!(r.wrapping_pow(0), 1 as $T); assert_eq!(r.checked_pow(2), Some(4 as $T)); assert_eq!(r.checked_pow(0), Some(1 as $T)); - assert_eq!(r.overflowing_pow(2), (4 as $T,false)); - assert_eq!(r.overflowing_pow(0), (1 as $T,false)); + assert_eq!(r.overflowing_pow(2), (4 as $T, false)); + assert_eq!(r.overflowing_pow(0), (1 as $T, false)); assert_eq!(r.saturating_pow(2), 4 as $T); assert_eq!(r.saturating_pow(0), 1 as $T); From 364cacb5840c1d96a8b4c1f4d62652200c57470d Mon Sep 17 00:00:00 2001 From: Neutron3529 Date: Thu, 16 Jul 2020 15:53:18 +0800 Subject: [PATCH 11/23] delete extra line --- src/libcore/tests/num/int_macros.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index e9046f6d26af0..58a585669122c 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -252,7 +252,6 @@ macro_rules! int_module { assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>); } - #[test] fn test_pow() { let mut r = 2 as $T; From 6100b74fbcf8da2122bd5ee4a9361965d8bf3429 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 29 Jun 2020 11:14:31 -0700 Subject: [PATCH 12/23] Advertise correct stable version for const control flow --- src/librustc_feature/accepted.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs index d93c17b05b498..d16f023c00a62 100644 --- a/src/librustc_feature/accepted.rs +++ b/src/librustc_feature/accepted.rs @@ -262,9 +262,9 @@ declare_features! ( /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. (accepted, slice_patterns, "1.42.0", Some(62254), None), /// Allows the use of `if` and `match` in constants. - (accepted, const_if_match, "1.45.0", Some(49146), None), + (accepted, const_if_match, "1.46.0", Some(49146), None), /// Allows the use of `loop` and `while` in constants. - (accepted, const_loop, "1.45.0", Some(52000), None), + (accepted, const_loop, "1.46.0", Some(52000), None), /// Allows `#[track_caller]` to be used which provides /// accurate caller location reporting during panic (RFC 2091). (accepted, track_caller, "1.46.0", Some(47809), None), From 4fb260bb32a2da7d7ea63b759eef77072a95614b Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 4 Jul 2020 18:41:30 +0100 Subject: [PATCH 13/23] Guard against non-monomorphized type_id intrinsic call --- src/librustc_mir/interpret/intrinsics.rs | 12 +++++++++-- src/test/ui/consts/issue-73976.rs | 26 ++++++++++++++++++++++++ src/test/ui/consts/issue-73976.stderr | 14 +++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/consts/issue-73976.rs create mode 100644 src/test/ui/consts/issue-73976.stderr diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 5836fc9c95a80..29549041d258c 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable}; use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size}; @@ -54,6 +54,9 @@ crate fn eval_nullary_intrinsic<'tcx>( let name = tcx.item_name(def_id); Ok(match name { sym::type_name => { + if tp_ty.needs_subst() { + throw_inval!(TooGeneric); + } let alloc = type_name::alloc_type_name(tcx, tp_ty); ConstValue::Slice { data: alloc, start: 0, end: alloc.len() } } @@ -68,7 +71,12 @@ crate fn eval_nullary_intrinsic<'tcx>( }; ConstValue::from_machine_usize(n, &tcx) } - sym::type_id => ConstValue::from_u64(tcx.type_id_hash(tp_ty)), + sym::type_id => { + if tp_ty.needs_subst() { + throw_inval!(TooGeneric); + } + ConstValue::from_u64(tcx.type_id_hash(tp_ty)) + } sym::variant_count => { if let ty::Adt(ref adt, _) = tp_ty.kind { ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx) diff --git a/src/test/ui/consts/issue-73976.rs b/src/test/ui/consts/issue-73976.rs new file mode 100644 index 0000000000000..ef141791c2cc8 --- /dev/null +++ b/src/test/ui/consts/issue-73976.rs @@ -0,0 +1,26 @@ +// This test is from #73976. We previously did not check if a type is monomorphized +// before calculating its type id, which leads to the bizzare behaviour below that +// TypeId of a generic type does not match itself. +// +// This test case should either run-pass or be rejected at compile time. +// Currently we just disallow this usage and require pattern is monomorphic. + +#![feature(const_type_id)] + +use std::any::TypeId; + +pub struct GetTypeId(T); + +impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); +} + +const fn check_type_id() -> bool { + matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) + //~^ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern +} + +fn main() { + assert!(check_type_id::()); +} diff --git a/src/test/ui/consts/issue-73976.stderr b/src/test/ui/consts/issue-73976.stderr new file mode 100644 index 0000000000000..dbb7690b849c8 --- /dev/null +++ b/src/test/ui/consts/issue-73976.stderr @@ -0,0 +1,14 @@ +error: could not evaluate constant pattern + --> $DIR/issue-73976.rs:19:37 + | +LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) + | ^^^^^^^^^^^^^^^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/issue-73976.rs:19:37 + | +LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 4c69d4bc05f43d801390c8498eea6e317e9d4b12 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sat, 11 Jul 2020 14:50:03 -0400 Subject: [PATCH 14/23] Add the aarch64-apple-darwin target This is a basic copy-paste-modify from the existing x86_64-apple-darwin target. --- .../spec/aarch64_apple_darwin.rs | 30 +++++++++++++++++++ src/librustc_target/spec/mod.rs | 1 + .../spec/x86_64_apple_darwin.rs | 5 +++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/librustc_target/spec/aarch64_apple_darwin.rs diff --git a/src/librustc_target/spec/aarch64_apple_darwin.rs b/src/librustc_target/spec/aarch64_apple_darwin.rs new file mode 100644 index 0000000000000..60daf10b36afe --- /dev/null +++ b/src/librustc_target/spec/aarch64_apple_darwin.rs @@ -0,0 +1,30 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::apple_base::opts(); + base.cpu = "apple-a12".to_string(); + base.max_atomic_width = Some(128); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]); + + base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); + + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + let arch = "aarch64"; + let llvm_target = super::apple_base::macos_llvm_target(&arch); + + Ok(Target { + llvm_target, + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), + arch: arch.to_string(), + target_os: "macos".to_string(), + target_env: String::new(), + target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { target_mcount: "\u{1}mcount".to_string(), ..base }, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index d53033ba3ba20..5a97ef441c203 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -574,6 +574,7 @@ supported_targets! { ("i686-unknown-haiku", i686_unknown_haiku), ("x86_64-unknown-haiku", x86_64_unknown_haiku), + ("aarch64-apple-darwin", aarch64_apple_darwin), ("x86_64-apple-darwin", x86_64_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs index 31011e8474958..909aebec70b58 100644 --- a/src/librustc_target/spec/x86_64_apple_darwin.rs +++ b/src/librustc_target/spec/x86_64_apple_darwin.rs @@ -5,7 +5,10 @@ pub fn target() -> TargetResult { base.cpu = "core2".to_string(); base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.eliminate_frame_pointer = false; - base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); + base.pre_link_args.insert( + LinkerFlavor::Gcc, + vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()], + ); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); base.stack_probes = true; From 804241ea06f20acc9bfd83c229507e726609f927 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Sat, 11 Jul 2020 14:52:30 -0400 Subject: [PATCH 15/23] Update dependencies that have knowledge about aarch64-apple-darwin --- Cargo.lock | 8 ++++---- src/librustc_llvm/Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34a33eca3f40b..8391cba278631 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,9 +412,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe" +checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" dependencies = [ "jobserver", ] @@ -1576,9 +1576,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.71" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" +checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" dependencies = [ "rustc-std-workspace-core", ] diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 4fc02e348f646..1a034294cd8eb 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -14,8 +14,8 @@ static-libstdcpp = [] emscripten = [] [dependencies] -libc = "0.2" +libc = "0.2.73" [build-dependencies] build_helper = { path = "../build_helper" } -cc = "1.0.1" +cc = "1.0.58" From b3340b5cea5fdaefa4cbc7eec8ceb0592ebe2255 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Tue, 21 Jul 2020 02:28:51 +0100 Subject: [PATCH 16/23] Expand test to cover type_name and monomorphic use --- src/test/ui/consts/issue-73976-monomorphic.rs | 36 +++++++++++++++++++ ...ue-73976.rs => issue-73976-polymorphic.rs} | 16 ++++++++- .../ui/consts/issue-73976-polymorphic.stderr | 26 ++++++++++++++ src/test/ui/consts/issue-73976.stderr | 14 -------- 4 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/consts/issue-73976-monomorphic.rs rename src/test/ui/consts/{issue-73976.rs => issue-73976-polymorphic.rs} (62%) create mode 100644 src/test/ui/consts/issue-73976-polymorphic.stderr delete mode 100644 src/test/ui/consts/issue-73976.stderr diff --git a/src/test/ui/consts/issue-73976-monomorphic.rs b/src/test/ui/consts/issue-73976-monomorphic.rs new file mode 100644 index 0000000000000..7706a97f23b48 --- /dev/null +++ b/src/test/ui/consts/issue-73976-monomorphic.rs @@ -0,0 +1,36 @@ +// check-pass +// +// This test is complement to the test in issue-73976-polymorphic.rs. +// In that test we ensure that polymorphic use of type_id and type_name in patterns +// will be properly rejected. This test will ensure that monomorphic use of these +// would not be wrongly rejected in patterns. + +#![feature(const_type_id)] +#![feature(const_type_name)] + +use std::any::{self, TypeId}; + +pub struct GetTypeId(T); + +impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); +} + +const fn check_type_id() -> bool { + matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) +} + +pub struct GetTypeNameLen(T); + +impl GetTypeNameLen { + pub const VALUE: usize = any::type_name::().len(); +} + +const fn check_type_name_len() -> bool { + matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) +} + +fn main() { + assert!(check_type_id::()); + assert!(check_type_name_len::()); +} diff --git a/src/test/ui/consts/issue-73976.rs b/src/test/ui/consts/issue-73976-polymorphic.rs similarity index 62% rename from src/test/ui/consts/issue-73976.rs rename to src/test/ui/consts/issue-73976-polymorphic.rs index ef141791c2cc8..28b84518719a1 100644 --- a/src/test/ui/consts/issue-73976.rs +++ b/src/test/ui/consts/issue-73976-polymorphic.rs @@ -6,8 +6,9 @@ // Currently we just disallow this usage and require pattern is monomorphic. #![feature(const_type_id)] +#![feature(const_type_name)] -use std::any::TypeId; +use std::any::{self, TypeId}; pub struct GetTypeId(T); @@ -21,6 +22,19 @@ const fn check_type_id() -> bool { //~| ERROR could not evaluate constant pattern } +pub struct GetTypeNameLen(T); + +impl GetTypeNameLen { + pub const VALUE: usize = any::type_name::().len(); +} + +const fn check_type_name_len() -> bool { + matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) + //~^ ERROR could not evaluate constant pattern + //~| ERROR could not evaluate constant pattern +} + fn main() { assert!(check_type_id::()); + assert!(check_type_name_len::()); } diff --git a/src/test/ui/consts/issue-73976-polymorphic.stderr b/src/test/ui/consts/issue-73976-polymorphic.stderr new file mode 100644 index 0000000000000..c90ce2bd06a67 --- /dev/null +++ b/src/test/ui/consts/issue-73976-polymorphic.stderr @@ -0,0 +1,26 @@ +error: could not evaluate constant pattern + --> $DIR/issue-73976-polymorphic.rs:20:37 + | +LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) + | ^^^^^^^^^^^^^^^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/issue-73976-polymorphic.rs:32:42 + | +LL | matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/issue-73976-polymorphic.rs:20:37 + | +LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) + | ^^^^^^^^^^^^^^^^^^^^^ + +error: could not evaluate constant pattern + --> $DIR/issue-73976-polymorphic.rs:32:42 + | +LL | matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/consts/issue-73976.stderr b/src/test/ui/consts/issue-73976.stderr deleted file mode 100644 index dbb7690b849c8..0000000000000 --- a/src/test/ui/consts/issue-73976.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: could not evaluate constant pattern - --> $DIR/issue-73976.rs:19:37 - | -LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^ - -error: could not evaluate constant pattern - --> $DIR/issue-73976.rs:19:37 - | -LL | matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) - | ^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - From 430bd39a0da2b17e5c7ca4842e25b7f523c51522 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 22 Jul 2020 14:42:45 +0900 Subject: [PATCH 17/23] Do not ICE on assoc type with bad placeholder --- src/librustc_typeck/collect.rs | 8 +++++++- .../ui/typeck/typeck_type_placeholder_item.rs | 2 ++ .../typeck/typeck_type_placeholder_item.stderr | 18 ++++++++++++------ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index c3b54f1461426..cb9348a9521bc 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -730,7 +730,13 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) { placeholder_type_error(tcx, None, &[], visitor.0, false); } - hir::TraitItemKind::Type(_, None) => {} + hir::TraitItemKind::Type(_, None) => { + // #74612: Visit and try to find bad placeholders + // even if there is no concrete type. + let mut visitor = PlaceholderHirTyCollector::default(); + visitor.visit_trait_item(trait_item); + placeholder_type_error(tcx, None, &[], visitor.0, false); + } }; tcx.ensure().predicates_of(def_id); diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 133c5231031fd..2c8b1e76b1b82 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -194,6 +194,8 @@ trait Qux { const D: _ = 42; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures // type E: _; // FIXME: make the parser propagate the existence of `B` + type F: std::ops::Fn(_); + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } impl Qux for Struct { type A = _; diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index a1945f2b9cf4e..782ff4948cda4 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -29,7 +29,7 @@ LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:203:5 + --> $DIR/typeck_type_placeholder_item.rs:205:5 | LL | const C: _; | ^^^^^^^^^^- @@ -545,6 +545,12 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace `_` with the correct type: `i32` +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:197:26 + | +LL | type F: std::ops::Fn(_); + | ^ not allowed in type signatures + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:40:24 | @@ -582,25 +588,25 @@ LL | fn clone(&self) -> _ { FnTest9 } | help: replace with the correct return type: `main::FnTest9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:199:14 + --> $DIR/typeck_type_placeholder_item.rs:201:14 | LL | type A = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:201:14 + --> $DIR/typeck_type_placeholder_item.rs:203:14 | LL | type B = _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:203:14 + --> $DIR/typeck_type_placeholder_item.rs:205:14 | LL | const C: _; | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:206:14 + --> $DIR/typeck_type_placeholder_item.rs:208:14 | LL | const D: _ = 42; | ^ @@ -608,7 +614,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace `_` with the correct type: `i32` -error: aborting due to 66 previous errors +error: aborting due to 67 previous errors Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. From 747bc8ec88b94ddfbd665d21bb87732411bcd1f7 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 21 Jul 2020 14:53:39 -0400 Subject: [PATCH 18/23] Enable perf try builder This adds a dedicated branch for perf to use for CI, intended to allow perf to enqueue builds without needing to use bors. bors is great, but bors requires an open PR to work, and we want to invoke perf on closed PRs sometimes (in particular, rollups). --- .github/workflows/ci.yml | 7 ++++--- src/ci/github-actions/ci.yml | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e0808c0d5896..d83971b70bedc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,7 @@ name: CI branches: - auto - try + - try-perf - master pull_request: branches: @@ -146,7 +147,7 @@ jobs: CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 CACHE_DOMAIN: ci-caches.rust-lang.org - if: "github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'" + if: "github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" strategy: matrix: include: @@ -717,7 +718,7 @@ jobs: try-success: needs: - try - if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'" + if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" steps: - name: mark the job as a success run: exit 0 @@ -727,7 +728,7 @@ jobs: try-failure: needs: - try - if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'" + if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" steps: - name: mark the job as a failure run: exit 1 diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 425e34f1af624..0aeb6a04e5f77 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -247,6 +247,7 @@ on: branches: - auto - try + - try-perf - master pull_request: branches: @@ -285,7 +286,7 @@ jobs: name: try env: <<: [*shared-ci-variables, *prod-variables] - if: github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust' + if: github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust' strategy: matrix: include: @@ -645,11 +646,11 @@ jobs: # successful listening to webhooks only. try-success: needs: [try] - if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'" + if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" <<: *base-success-job try-failure: needs: [try] - if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/try' && github.repository == 'rust-lang-ci/rust'" + if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" <<: *base-failure-job auto-success: needs: [auto] From 49b9a6486ab0814f4c7d57c22c75216fdc1ebf14 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 22 Jul 2020 15:49:04 +0300 Subject: [PATCH 19/23] rustc_target: Add a target spec option for disabling `--eh-frame-hdr` --- src/librustc_codegen_ssa/back/link.rs | 4 +++- src/librustc_codegen_ssa/back/linker.rs | 8 +------- src/librustc_target/spec/apple_base.rs | 1 + src/librustc_target/spec/freestanding_base.rs | 1 + src/librustc_target/spec/illumos_base.rs | 1 + src/librustc_target/spec/mod.rs | 8 ++++++++ src/librustc_target/spec/msp430_none_elf.rs | 2 ++ src/librustc_target/spec/riscv32i_unknown_none_elf.rs | 1 + src/librustc_target/spec/riscv32imac_unknown_none_elf.rs | 1 + src/librustc_target/spec/riscv32imc_unknown_none_elf.rs | 1 + src/librustc_target/spec/riscv64gc_unknown_none_elf.rs | 1 + src/librustc_target/spec/riscv64imac_unknown_none_elf.rs | 1 + src/librustc_target/spec/solaris_base.rs | 1 + src/librustc_target/spec/windows_gnu_base.rs | 1 + 14 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 2d65282ce7798..b53b82a1e62fc 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1598,7 +1598,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( } // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER - cmd.add_eh_frame_header(); + if sess.target.target.options.eh_frame_header { + cmd.add_eh_frame_header(); + } // NO-OPT-OUT, OBJECT-FILES-NO if crt_objects_fallback { diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index e64aafa599fd8..d1ae9e372695f 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -619,13 +619,7 @@ impl<'a> Linker for GccLinker<'a> { // Some versions of `gcc` add it implicitly, some (e.g. `musl-gcc`) don't, // so we just always add it. fn add_eh_frame_header(&mut self) { - if !self.sess.target.target.options.is_like_osx - && !self.sess.target.target.options.is_like_windows - && !self.sess.target.target.options.is_like_solaris - && self.sess.target.target.target_os != "uefi" - { - self.linker_arg("--eh-frame-hdr"); - } + self.linker_arg("--eh-frame-hdr"); } } diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs index bdd5a893d34e2..e7b565ae9cad9 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -31,6 +31,7 @@ pub fn opts() -> TargetOptions { has_elf_tls: version >= (10, 7), abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, + eh_frame_header: false, // This environment variable is pretty magical but is intended for // producing deterministic builds. This was first discovered to be used diff --git a/src/librustc_target/spec/freestanding_base.rs b/src/librustc_target/spec/freestanding_base.rs index 5402ea074fae1..c338856228dc6 100644 --- a/src/librustc_target/spec/freestanding_base.rs +++ b/src/librustc_target/spec/freestanding_base.rs @@ -25,6 +25,7 @@ pub fn opts() -> TargetOptions { has_rpath: false, pre_link_args: args, position_independent_executables: false, + eh_frame_header: false, ..Default::default() } } diff --git a/src/librustc_target/spec/illumos_base.rs b/src/librustc_target/spec/illumos_base.rs index 35ac346fb3f6f..214142b88fc2c 100644 --- a/src/librustc_target/spec/illumos_base.rs +++ b/src/librustc_target/spec/illumos_base.rs @@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions { is_like_solaris: true, limit_rdylib_exports: false, // Linker doesn't support this eliminate_frame_pointer: false, + eh_frame_header: false, late_link_args, // While we support ELF TLS, rust requires a way to register diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index d53033ba3ba20..61dba6c72bd4f 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -987,6 +987,11 @@ pub struct TargetOptions { /// Whether to use legacy .ctors initialization hooks rather than .init_array. Defaults /// to false (uses .init_array). pub use_ctors_section: bool, + + /// Whether the linker is instructed to add a `GNU_EH_FRAME` ELF header + /// used to locate unwinding information is passed + /// (only has effect if the linker is `ld`-like). + pub eh_frame_header: bool, } impl Default for TargetOptions { @@ -1078,6 +1083,7 @@ impl Default for TargetOptions { relax_elf_relocations: false, llvm_args: vec![], use_ctors_section: false, + eh_frame_header: true, } } } @@ -1470,6 +1476,7 @@ impl Target { key!(relax_elf_relocations, bool); key!(llvm_args, list); key!(use_ctors_section, bool); + key!(eh_frame_header, bool); // NB: The old name is deprecated, but support for it is retained for // compatibility. @@ -1707,6 +1714,7 @@ impl ToJson for Target { target_option_val!(relax_elf_relocations); target_option_val!(llvm_args); target_option_val!(use_ctors_section); + target_option_val!(eh_frame_header); if default.unsupported_abis != self.options.unsupported_abis { d.insert( diff --git a/src/librustc_target/spec/msp430_none_elf.rs b/src/librustc_target/spec/msp430_none_elf.rs index c6d0308f8f82f..f75697996ac78 100644 --- a/src/librustc_target/spec/msp430_none_elf.rs +++ b/src/librustc_target/spec/msp430_none_elf.rs @@ -56,6 +56,8 @@ pub fn target() -> TargetResult { // See the thumb_base.rs file for an explanation of this value emit_debug_gdb_scripts: false, + eh_frame_header: false, + ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs index 977aa896f2520..5b5e342000b55 100644 --- a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs @@ -25,6 +25,7 @@ pub fn target() -> TargetResult { relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false, unsupported_abis: super::riscv_base::unsupported_abis(), + eh_frame_header: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs index 1a85cdff1315c..4cef5c42d8ddf 100644 --- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs @@ -25,6 +25,7 @@ pub fn target() -> TargetResult { relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false, unsupported_abis: super::riscv_base::unsupported_abis(), + eh_frame_header: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs index e3c1c6908a23a..8ad563e441de3 100644 --- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs @@ -25,6 +25,7 @@ pub fn target() -> TargetResult { relocation_model: RelocModel::Static, emit_debug_gdb_scripts: false, unsupported_abis: super::riscv_base::unsupported_abis(), + eh_frame_header: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs index 857af4ceb0d9f..3aeb3f3ca72b2 100644 --- a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs @@ -26,6 +26,7 @@ pub fn target() -> TargetResult { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, unsupported_abis: super::riscv_base::unsupported_abis(), + eh_frame_header: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs index 36fe7730f95bf..d8144964dc913 100644 --- a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs +++ b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs @@ -26,6 +26,7 @@ pub fn target() -> TargetResult { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, unsupported_abis: super::riscv_base::unsupported_abis(), + eh_frame_header: false, ..Default::default() }, }) diff --git a/src/librustc_target/spec/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs index 8d3a3563f4164..3d7f0034b8b10 100644 --- a/src/librustc_target/spec/solaris_base.rs +++ b/src/librustc_target/spec/solaris_base.rs @@ -8,6 +8,7 @@ pub fn opts() -> TargetOptions { target_family: Some("unix".to_string()), is_like_solaris: true, limit_rdylib_exports: false, // Linker doesn't support this + eh_frame_header: false, ..Default::default() } diff --git a/src/librustc_target/spec/windows_gnu_base.rs b/src/librustc_target/spec/windows_gnu_base.rs index 680dbbad4b0a0..69236e98e58d7 100644 --- a/src/librustc_target/spec/windows_gnu_base.rs +++ b/src/librustc_target/spec/windows_gnu_base.rs @@ -91,6 +91,7 @@ pub fn opts() -> TargetOptions { abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, requires_uwtable: true, + eh_frame_header: false, ..Default::default() } From 4b052024a05d529e2c51cf40a525340f20310466 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 22 Jul 2020 18:44:15 +0300 Subject: [PATCH 20/23] build: Remove unnecessary `cargo:rerun-if-env-changed` annotations --- src/librustc_ast/build.rs | 5 ----- src/librustc_attr/build.rs | 5 ----- src/librustc_codegen_llvm/build.rs | 6 ------ src/librustc_codegen_ssa/build.rs | 4 ---- src/librustc_driver/build.rs | 7 ------- src/librustc_incremental/build.rs | 4 ---- src/librustc_interface/build.rs | 4 ---- src/librustc_llvm/build.rs | 2 +- src/librustc_metadata/build.rs | 5 ----- src/librustc_middle/build.rs | 12 ------------ src/librustc_session/session.rs | 2 +- src/librustc_target/build.rs | 4 ---- 12 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 src/librustc_ast/build.rs delete mode 100644 src/librustc_attr/build.rs delete mode 100644 src/librustc_codegen_llvm/build.rs delete mode 100644 src/librustc_codegen_ssa/build.rs delete mode 100644 src/librustc_driver/build.rs delete mode 100644 src/librustc_incremental/build.rs delete mode 100644 src/librustc_interface/build.rs delete mode 100644 src/librustc_metadata/build.rs delete mode 100644 src/librustc_middle/build.rs delete mode 100644 src/librustc_target/build.rs diff --git a/src/librustc_ast/build.rs b/src/librustc_ast/build.rs deleted file mode 100644 index 9b861f9640904..0000000000000 --- a/src/librustc_ast/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL"); - println!("cargo:rerun-if-env-changed=CFG_DISABLE_UNSTABLE_FEATURES"); -} diff --git a/src/librustc_attr/build.rs b/src/librustc_attr/build.rs deleted file mode 100644 index 863f2b7337b25..0000000000000 --- a/src/librustc_attr/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_RELEASE"); - println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL"); -} diff --git a/src/librustc_codegen_llvm/build.rs b/src/librustc_codegen_llvm/build.rs deleted file mode 100644 index d1fc624c68927..0000000000000 --- a/src/librustc_codegen_llvm/build.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_VERSION"); - println!("cargo:rerun-if-env-changed=CFG_PREFIX"); - println!("cargo:rerun-if-env-changed=CFG_LLVM_ROOT"); -} diff --git a/src/librustc_codegen_ssa/build.rs b/src/librustc_codegen_ssa/build.rs deleted file mode 100644 index ea2af6e192e7c..0000000000000 --- a/src/librustc_codegen_ssa/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL"); -} diff --git a/src/librustc_driver/build.rs b/src/librustc_driver/build.rs deleted file mode 100644 index 414d13445f01e..0000000000000 --- a/src/librustc_driver/build.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_RELEASE"); - println!("cargo:rerun-if-env-changed=CFG_VERSION"); - println!("cargo:rerun-if-env-changed=CFG_VER_DATE"); - println!("cargo:rerun-if-env-changed=CFG_VER_HASH"); -} diff --git a/src/librustc_incremental/build.rs b/src/librustc_incremental/build.rs deleted file mode 100644 index d230ba91039ad..0000000000000 --- a/src/librustc_incremental/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_VERSION"); -} diff --git a/src/librustc_interface/build.rs b/src/librustc_interface/build.rs deleted file mode 100644 index 79a343e0fee0b..0000000000000 --- a/src/librustc_interface/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=RUSTC_INSTALL_BINDIR"); -} diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 78e27b10ec657..f00bd7d47f035 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -163,7 +163,7 @@ fn main() { cfg.define(&flag, None); } - println!("cargo:rerun-if-changed-env=LLVM_RUSTLLVM"); + println!("cargo:rerun-if-env-changed=LLVM_RUSTLLVM"); if env::var_os("LLVM_RUSTLLVM").is_some() { cfg.define("LLVM_RUSTLLVM", None); } diff --git a/src/librustc_metadata/build.rs b/src/librustc_metadata/build.rs deleted file mode 100644 index 7d5c58ecea2a1..0000000000000 --- a/src/librustc_metadata/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_VERSION"); - println!("cargo:rerun-if-env-changed=CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"); -} diff --git a/src/librustc_middle/build.rs b/src/librustc_middle/build.rs deleted file mode 100644 index af7723aea34e4..0000000000000 --- a/src/librustc_middle/build.rs +++ /dev/null @@ -1,12 +0,0 @@ -use std::env; - -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_LIBDIR_RELATIVE"); - println!("cargo:rerun-if-env-changed=CFG_COMPILER_HOST_TRIPLE"); - println!("cargo:rerun-if-env-changed=RUSTC_VERIFY_LLVM_IR"); - - if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() { - println!("cargo:rustc-cfg=always_verify_llvm_ir"); - } -} diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 4ad95e95e9a86..1b8f6cdd8bebc 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -548,7 +548,7 @@ impl Session { self.opts.debugging_opts.asm_comments } pub fn verify_llvm_ir(&self) -> bool { - self.opts.debugging_opts.verify_llvm_ir || cfg!(always_verify_llvm_ir) + self.opts.debugging_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some() } pub fn borrowck_stats(&self) -> bool { self.opts.debugging_opts.borrowck_stats diff --git a/src/librustc_target/build.rs b/src/librustc_target/build.rs deleted file mode 100644 index 368200b776d74..0000000000000 --- a/src/librustc_target/build.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-env-changed=CFG_DEFAULT_LINKER"); -} From 0b662c23580420c3d6a9e457df54c17a934ebdc9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 22 Jul 2020 19:13:02 +0300 Subject: [PATCH 21/23] build: Remove unnecessary `build = "build.rs"` annotations --- src/libprofiler_builtins/Cargo.toml | 1 - src/librustc_attr/Cargo.toml | 1 - src/librustc_llvm/Cargo.toml | 1 - src/libstd/Cargo.toml | 1 - src/libunwind/Cargo.toml | 1 - src/tools/error_index_generator/Cargo.toml | 1 - 6 files changed, 6 deletions(-) diff --git a/src/libprofiler_builtins/Cargo.toml b/src/libprofiler_builtins/Cargo.toml index 0d36bd0b39d76..899f923b957fe 100644 --- a/src/libprofiler_builtins/Cargo.toml +++ b/src/libprofiler_builtins/Cargo.toml @@ -1,6 +1,5 @@ [package] authors = ["The Rust Project Developers"] -build = "build.rs" name = "profiler_builtins" version = "0.0.0" edition = "2018" diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml index 677796a8df0b3..496becb8f1b59 100644 --- a/src/librustc_attr/Cargo.toml +++ b/src/librustc_attr/Cargo.toml @@ -3,7 +3,6 @@ authors = ["The Rust Project Developers"] name = "rustc_attr" version = "0.0.0" edition = "2018" -build = "build.rs" [lib] name = "rustc_attr" diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 4fc02e348f646..ccc417c166429 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -2,7 +2,6 @@ authors = ["The Rust Project Developers"] name = "rustc_llvm" version = "0.0.0" -build = "build.rs" edition = "2018" [lib] diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 42403bdb1bcea..f5d8119f711cb 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -2,7 +2,6 @@ authors = ["The Rust Project Developers"] name = "std" version = "0.0.0" -build = "build.rs" license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust.git" description = "The Rust Standard Library" diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index 77bcfffd506c9..b6baa9a8c6bcc 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -2,7 +2,6 @@ authors = ["The Rust Project Developers"] name = "unwind" version = "0.0.0" -build = "build.rs" edition = "2018" include = [ '/libunwind/*', diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index 992af261b8352..787e08404e1c6 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -3,7 +3,6 @@ authors = ["The Rust Project Developers"] name = "error_index_generator" version = "0.0.0" edition = "2018" -build = "build.rs" [dependencies] rustdoc = { path = "../../librustdoc" } From 461c5764577414d0232508177f8099a27b96b303 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 22 Jul 2020 19:51:19 +0300 Subject: [PATCH 22/23] build: Harden env var tracking in build scripts --- src/build_helper/lib.rs | 16 ++++++++++++---- src/librustc_llvm/build.rs | 24 ++++++++++-------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 43c3c5773ce5b..e30da8d56e10f 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,3 +1,5 @@ +use std::ffi::{OsStr, OsString}; +use std::fmt::Display; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::time::{SystemTime, UNIX_EPOCH}; @@ -28,6 +30,14 @@ macro_rules! t { }; } +/// Reads an environment variable and adds it to dependencies. +/// Supposed to be used for all variables except those set for build scripts by cargo +/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts +pub fn tracked_env_var_os + Display>(key: K) -> Option { + println!("cargo:rerun-if-env-changed={}", key); + env::var_os(key) +} + // Because Cargo adds the compiler's dylib path to our library search path, llvm-config may // break: the dylib path for the compiler, as of this writing, contains a copy of the LLVM // shared library, which means that when our freshly built llvm-config goes to load it's @@ -37,10 +47,8 @@ macro_rules! t { // perfect -- we might actually want to see something from Cargo's added library paths -- but // for now it works. pub fn restore_library_path() { - println!("cargo:rerun-if-env-changed=REAL_LIBRARY_PATH_VAR"); - println!("cargo:rerun-if-env-changed=REAL_LIBRARY_PATH"); - let key = env::var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); - if let Some(env) = env::var_os("REAL_LIBRARY_PATH") { + let key = tracked_env_var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); + if let Some(env) = tracked_env_var_os("REAL_LIBRARY_PATH") { env::set_var(&key, &env); } else { env::remove_var(&key); diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index f00bd7d47f035..21b8080714c17 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -2,12 +2,12 @@ use std::env; use std::path::{Path, PathBuf}; use std::process::Command; -use build_helper::output; +use build_helper::{output, tracked_env_var_os}; fn detect_llvm_link() -> (&'static str, &'static str) { // Force the link mode we want, preferring static by default, but // possibly overridden by `configure --enable-llvm-link-shared`. - if env::var_os("LLVM_LINK_SHARED").is_some() { + if tracked_env_var_os("LLVM_LINK_SHARED").is_some() { ("dylib", "--link-shared") } else { ("static", "--link-static") @@ -15,8 +15,7 @@ fn detect_llvm_link() -> (&'static str, &'static str) { } fn main() { - println!("cargo:rerun-if-env-changed=RUST_CHECK"); - if env::var_os("RUST_CHECK").is_some() { + if tracked_env_var_os("RUST_CHECK").is_some() { // If we're just running `check`, there's no need for LLVM to be built. return; } @@ -25,8 +24,8 @@ fn main() { let target = env::var("TARGET").expect("TARGET was not set"); let llvm_config = - env::var_os("LLVM_CONFIG").map(|x| Some(PathBuf::from(x))).unwrap_or_else(|| { - if let Some(dir) = env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) { + tracked_env_var_os("LLVM_CONFIG").map(|x| Some(PathBuf::from(x))).unwrap_or_else(|| { + if let Some(dir) = tracked_env_var_os("CARGO_TARGET_DIR").map(PathBuf::from) { let to_test = dir .parent() .unwrap() @@ -46,8 +45,6 @@ fn main() { } let llvm_config = llvm_config.unwrap_or_else(|| PathBuf::from("llvm-config")); - println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); - // Test whether we're cross-compiling LLVM. This is a pretty rare case // currently where we're producing an LLVM for a different platform than // what this build script is currently running on. @@ -163,12 +160,11 @@ fn main() { cfg.define(&flag, None); } - println!("cargo:rerun-if-env-changed=LLVM_RUSTLLVM"); - if env::var_os("LLVM_RUSTLLVM").is_some() { + if tracked_env_var_os("LLVM_RUSTLLVM").is_some() { cfg.define("LLVM_RUSTLLVM", None); } - if env::var_os("LLVM_NDEBUG").is_some() { + if tracked_env_var_os("LLVM_NDEBUG").is_some() { cfg.define("NDEBUG", None); cfg.debug(false); } @@ -255,7 +251,7 @@ fn main() { // librustc_llvm, for example when using static libc++, we may need to // manually specify the library search path and -ldl -lpthread as link // dependencies. - let llvm_linker_flags = env::var_os("LLVM_LINKER_FLAGS"); + let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS"); if let Some(s) = llvm_linker_flags { for lib in s.into_string().unwrap().split_whitespace() { if lib.starts_with("-l") { @@ -266,8 +262,8 @@ fn main() { } } - let llvm_static_stdcpp = env::var_os("LLVM_STATIC_STDCPP"); - let llvm_use_libcxx = env::var_os("LLVM_USE_LIBCXX"); + let llvm_static_stdcpp = tracked_env_var_os("LLVM_STATIC_STDCPP"); + let llvm_use_libcxx = tracked_env_var_os("LLVM_USE_LIBCXX"); let stdcppname = if target.contains("openbsd") { if target.contains("sparc64") { "estdc++" } else { "c++" } From 7be36a86f7b7798e662d844b33bd744a136b4f60 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 22 Jul 2020 20:06:37 +0300 Subject: [PATCH 23/23] build: Avoid unnecessary build script reruns in libstd Add a FIXME to build scripts in profiler_builtins --- src/libprofiler_builtins/build.rs | 2 ++ src/libstd/build.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index bb7d59e113c08..d2cb873058c28 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -9,6 +9,8 @@ fn main() { let target = env::var("TARGET").expect("TARGET was not set"); let cfg = &mut cc::Build::new(); + // FIXME: `rerun-if-changed` directives are not currently emitted and the build script + // will not rerun on changes in these source files or headers included into them. let mut profile_sources = vec![ "GCDAProfiling.c", "InstrProfiling.c", diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 58fb6fda19aab..83073cc77dd1a 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -1,6 +1,7 @@ use std::env; fn main() { + println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); if target.contains("linux") { if target.contains("android") {