From 3f8487a0996de85b611b7c10fd5a3f60b10473a6 Mon Sep 17 00:00:00 2001
From: l00846161 <liuxinyi27@huawei.com>
Date: Thu, 16 Nov 2023 14:17:54 +0800
Subject: [PATCH 1/5] Add safe compilation options

Add two options when building rust: strip and stack protector.
If set `strip = true`, symbols will be stripped using `-Cstrip=symbols`.
Also can set `stack-protector` and stack protectors will be used.
---
 config.example.toml                     | 10 ++++++++++
 src/bootstrap/src/core/builder.rs       |  6 ++++++
 src/bootstrap/src/core/config/config.rs |  7 +++++++
 3 files changed, 23 insertions(+)

diff --git a/config.example.toml b/config.example.toml
index c91222169d982..49c4ad4c958ed 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -600,6 +600,16 @@ change-id = 117813
 # desired in distributions, for example.
 #rpath = true
 
+# Indicates whether symbols should be stripped using `-Cstrip=symbols`.
+#strip = false
+
+# Indicates whether stack protectors should be used
+# via the unstable option `-Zstack-protector`.
+#
+# Valid options are : `none`(default),`basic`,`strong`, or `all`.
+# `strong` and `basic` options may be buggy and are not recommended, see rust-lang/rust#114903.
+#stack-protector = "none"
+
 # Prints each test name as it is executed, to help debug issues in the test harness itself.
 #verbose-tests = false
 
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 65af2aed6de37..8c73a2ad5c19e 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1667,6 +1667,12 @@ impl<'a> Builder<'a> {
             }
         }
 
+        cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
+
+        if let Some(stack_protector) = &self.config.rust_stack_protector {
+            rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
+        }
+
         if let Some(host_linker) = self.linker(compiler.host) {
             hostflags.arg(format!("-Clinker={}", host_linker.display()));
         }
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 22e8ce8365b1f..1527cc3e46a3a 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -222,6 +222,8 @@ pub struct Config {
     pub rust_debuginfo_level_tests: DebuginfoLevel,
     pub rust_split_debuginfo: SplitDebuginfo,
     pub rust_rpath: bool,
+    pub rust_strip: bool,
+    pub rust_stack_protector: Option<String>,
     pub rustc_parallel: bool,
     pub rustc_default_linker: Option<String>,
     pub rust_optimize_tests: bool,
@@ -1001,6 +1003,8 @@ define_config! {
         description: Option<String> = "description",
         musl_root: Option<String> = "musl-root",
         rpath: Option<bool> = "rpath",
+        strip: Option<bool> = "strip",
+        stack_protector: Option<String> = "stack-protector",
         verbose_tests: Option<bool> = "verbose-tests",
         optimize_tests: Option<bool> = "optimize-tests",
         codegen_tests: Option<bool> = "codegen-tests",
@@ -1069,6 +1073,7 @@ impl Config {
         config.docs = true;
         config.docs_minification = true;
         config.rust_rpath = true;
+        config.rust_strip = false;
         config.channel = "dev".to_string();
         config.codegen_tests = true;
         config.rust_dist_src = true;
@@ -1422,6 +1427,8 @@ impl Config {
             set(&mut config.rust_optimize_tests, rust.optimize_tests);
             set(&mut config.codegen_tests, rust.codegen_tests);
             set(&mut config.rust_rpath, rust.rpath);
+            set(&mut config.rust_strip, rust.strip);
+            config.rust_stack_protector = rust.stack_protector;
             set(&mut config.jemalloc, rust.jemalloc);
             set(&mut config.test_compare_mode, rust.test_compare_mode);
             set(&mut config.backtrace, rust.backtrace);

From 0f40b6545dc5acf1a3bfd5bcd97a9a9015e36a97 Mon Sep 17 00:00:00 2001
From: Urgau <urgau@numericable.fr>
Date: Fri, 8 Dec 2023 15:51:18 +0100
Subject: [PATCH 2/5] Remove extra check-cfg handled by libc directly

---
 src/bootstrap/src/lib.rs | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 60a89e9bf0709..13391b1faa193 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -83,8 +83,6 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (Some(Mode::Std), "no_global_oom_handling", None),
     (Some(Mode::Std), "no_rc", None),
     (Some(Mode::Std), "no_sync", None),
-    (Some(Mode::Std), "freebsd12", None),
-    (Some(Mode::Std), "freebsd13", None),
     (Some(Mode::Std), "backtrace_in_libstd", None),
     /* Extra values not defined in the built-in targets yet, but used in std */
     (Some(Mode::Std), "target_env", Some(&["libnx"])),

From cb6984217f12acd1da6eb7f244effe2c9f9f11f8 Mon Sep 17 00:00:00 2001
From: Young-Flash <871946895@qq.com>
Date: Sat, 9 Dec 2023 17:49:40 +0800
Subject: [PATCH 3/5] chore: add test case for type with generic

---
 ...ggest-assoc-fn-call-without-receiver.fixed | 14 ++++++
 .../suggest-assoc-fn-call-without-receiver.rs | 14 ++++++
 ...gest-assoc-fn-call-without-receiver.stderr | 44 +++++++++++++++++--
 3 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed
index 6e679134d636c..61f06d802b68f 100644
--- a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.fixed
@@ -7,10 +7,24 @@ impl A {
     fn test(_a: Self, _b: i32) {}
 }
 
+struct B<T> {
+    _b: T
+}
+impl<T> B<T> {
+    fn hello(_a: i32) {}
+    fn test(_a: Self, _b: i32) {}
+}
+
 fn main() {
     let _a = A {};
     A::hello(1);
     //~^ ERROR no method named `hello` found
     A::test(_a, 1);
     //~^ ERROR no method named `test` found
+
+    let _b = B {_b: ""};
+    B::<&str>::hello(1);
+    //~^ ERROR no method named `hello` found
+    B::<&str>::test(_b, 1);
+    //~^ ERROR no method named `test` found
 }
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs
index 67c2cc1bed561..07e614f0c15e5 100644
--- a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.rs
@@ -7,10 +7,24 @@ impl A {
     fn test(_a: Self, _b: i32) {}
 }
 
+struct B<T> {
+    _b: T
+}
+impl<T> B<T> {
+    fn hello(_a: i32) {}
+    fn test(_a: Self, _b: i32) {}
+}
+
 fn main() {
     let _a = A {};
     _a.hello(1);
     //~^ ERROR no method named `hello` found
     _a.test(1);
     //~^ ERROR no method named `test` found
+
+    let _b = B {_b: ""};
+    _b.hello(1);
+    //~^ ERROR no method named `hello` found
+    _b.test(1);
+    //~^ ERROR no method named `test` found
 }
diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr
index ed227cbab3967..793595784d937 100644
--- a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr
+++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `hello` found for struct `A` in the current scope
-  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:12:8
+  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:20:8
    |
 LL | struct A {}
    | -------- method `hello` not found for this struct
@@ -18,7 +18,7 @@ LL |     fn hello(_a: i32) {}
    |     ^^^^^^^^^^^^^^^^^
 
 error[E0599]: no method named `test` found for struct `A` in the current scope
-  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:14:8
+  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:22:8
    |
 LL | struct A {}
    | -------- method `test` not found for this struct
@@ -36,6 +36,44 @@ note: the candidate is defined in an impl for the type `A`
 LL |     fn test(_a: Self, _b: i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0599]: no method named `hello` found for struct `B<&str>` in the current scope
+  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:26:8
+   |
+LL | struct B<T> {
+   | ----------- method `hello` not found for this struct
+...
+LL |     _b.hello(1);
+   |     ---^^^^^---
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `B::<&str>::hello(1)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `B<T>`
+  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:14:5
+   |
+LL |     fn hello(_a: i32) {}
+   |     ^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `test` found for struct `B<&str>` in the current scope
+  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:28:8
+   |
+LL | struct B<T> {
+   | ----------- method `test` not found for this struct
+...
+LL |     _b.test(1);
+   |     ---^^^^---
+   |     |  |
+   |     |  this is an associated function, not a method
+   |     help: use associated function syntax instead: `B::<&str>::test(_b, 1)`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `B<T>`
+  --> $DIR/suggest-assoc-fn-call-without-receiver.rs:15:5
+   |
+LL |     fn test(_a: Self, _b: i32) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0599`.

From ef796db5f0d4eecce0dd2ae9fff224542fb88f5b Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Sat, 9 Dec 2023 09:47:14 +0000
Subject: [PATCH 4/5] add test for inductive cycle hangs

---
 .../fixpoint-exponential-growth.rs            |  8 +++--
 .../fixpoint-exponential-growth.stderr        |  4 +--
 .../cycles/inductive-fixpoint-hang.rs         | 33 +++++++++++++++++++
 .../cycles/inductive-fixpoint-hang.stderr     | 16 +++++++++
 4 files changed, 57 insertions(+), 4 deletions(-)
 create mode 100644 tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs
 create mode 100644 tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr

diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs
index 44e763ef9907d..07c7d4fb29c70 100644
--- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs
+++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.rs
@@ -3,8 +3,12 @@
 // Proving `W<?0>: Trait` instantiates `?0` with `(W<?1>, W<?2>)` and then
 // proves `W<?1>: Trait` and `W<?2>: Trait`, resulting in a coinductive cycle.
 //
-// Proving coinductive cycles runs until we reach a fixpoint. This fixpoint is
-// never reached here and each step doubles the amount of nested obligations.
+// Proving coinductive cycles runs until we reach a fixpoint. However, after
+// computing `try_evaluate_added_goals` in the second fixpoint iteration, the
+// self type already has a depth equal to the number of steps. This results
+// in enormous constraints, causing the canonicalizer to hang without ever
+// reaching the recursion limit. We currently avoid that by erasing the constraints
+// from overflow.
 //
 // This previously caused a hang in the trait solver, see
 // https://github.com/rust-lang/trait-system-refactor-initiative/issues/13.
diff --git a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
index 05aaf6108f1da..150100f2c531c 100644
--- a/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
+++ b/tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
@@ -1,12 +1,12 @@
 error[E0275]: overflow evaluating the requirement `W<_>: Trait`
-  --> $DIR/fixpoint-exponential-growth.rs:29:13
+  --> $DIR/fixpoint-exponential-growth.rs:33:13
    |
 LL |     impls::<W<_>>();
    |             ^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
 note: required by a bound in `impls`
-  --> $DIR/fixpoint-exponential-growth.rs:26:13
+  --> $DIR/fixpoint-exponential-growth.rs:30:13
    |
 LL | fn impls<T: Trait>() {}
    |             ^^^^^ required by this bound in `impls`
diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs
new file mode 100644
index 0000000000000..062c6ae98d56b
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.rs
@@ -0,0 +1,33 @@
+// compile-flags: -Ztrait-solver=next
+
+// This currently hangs if we do not erase constraints from
+// overflow.
+//
+// We set the provisional result of `W<?0>` to `?0 := W<_>`.
+// The next iteration does not simply result in a `?0 := W<W<_>` constraint as
+// one might expect, but instead each time we evaluate the nested `W<T>` goal we
+// apply the previously returned constraints: the first fixpoint iteration goes
+// as follows: `W<?1>: Trait` constrains `?1` to `W<?2>`, we then evaluate
+// `W<W<?2>>: Trait` the next time we try to prove the nested goal. This results
+// inn `W<W<W<?3>>>` and so on. This goes on until we reach overflow in
+// `try_evaluate_added_goals`.  This means the provisional result after the
+// second fixpoint iteration is already `W<W<W<...>>>` with a size proportional
+// to the number of steps in `try_evaluate_added_goals`. The size then continues
+// to grow. The exponential blowup from having 2 nested goals per impl causes
+// the solver to hang without hitting the recursion limit.
+trait Trait {}
+
+struct W<T: ?Sized>(*const T);
+
+impl<T: ?Sized> Trait for W<W<T>>
+where
+    W<T>: Trait,
+    W<T>: Trait,
+{}
+
+fn impls_trait<T: Trait>() {}
+
+fn main() {
+    impls_trait::<W<_>>();
+    //~^ ERROR overflow evaluating the requirement
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr
new file mode 100644
index 0000000000000..42451920744b0
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-fixpoint-hang.stderr
@@ -0,0 +1,16 @@
+error[E0275]: overflow evaluating the requirement `W<_>: Trait`
+  --> $DIR/inductive-fixpoint-hang.rs:31:19
+   |
+LL |     impls_trait::<W<_>>();
+   |                   ^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_fixpoint_hang`)
+note: required by a bound in `impls_trait`
+  --> $DIR/inductive-fixpoint-hang.rs:28:19
+   |
+LL | fn impls_trait<T: Trait>() {}
+   |                   ^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0275`.

From 2cf54e9f99f83e314256808b1e0753779d49e652 Mon Sep 17 00:00:00 2001
From: jyn <github@jyn.dev>
Date: Sat, 9 Dec 2023 09:43:27 -0500
Subject: [PATCH 5/5] use `&` instead of start-process in x.ps1

start-process has weird parsing rules and buggy behavior. we've already had to work around them several times, and the workarounds were not complete.
i wonder who could have added it HMMMMMM
```
PS C:\Users\jyn\src\rust> git log --reverse -S Start-Process x.ps1
commit 775c3c0493e9a383a7f1c521b06d36f2e3d0d886
Author: Jynn Nelson <github@jyn.dev>
Date:   Sun Jul 31 14:02:31 2022 -0500

    Add `x.sh` and `x.ps1` shell scripts
```

the latest broken thing is trailing backslashes:
```
$ x.ps1 t .\tests\ui\error-emitter\
```
would be transformed into
```
['t', '.\\tests\\ui\\error-emitter"']
```

rather than trying to hack around that too, abandon start-process altogether and just use `&`.
---
 x.ps1 | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/x.ps1 b/x.ps1
index eae1a2cb3996e..afd988e67e4cd 100755
--- a/x.ps1
+++ b/x.ps1
@@ -8,12 +8,7 @@ $ErrorActionPreference = "Stop"
 Get-Command -syntax ${PSCommandPath} >$null
 
 $xpy = Join-Path $PSScriptRoot x.py
-# Start-Process for some reason splits arguments on spaces. (Isn't powershell supposed to be simpler than bash?)
-# Double-quote all the arguments so it doesn't do that.
-$xpy_args = @("""$xpy""")
-foreach ($arg in $args) {
-    $xpy_args += """$arg"""
-}
+$xpy_args = @($xpy) + $args
 
 function Get-Application($app) {
     $cmd = Get-Command $app -ErrorAction SilentlyContinue -CommandType Application | Select-Object -First 1
@@ -21,16 +16,8 @@ function Get-Application($app) {
 }
 
 function Invoke-Application($application, $arguments) {
-    $process = Start-Process -NoNewWindow -PassThru $application $arguments
-    # WORKAROUND: Caching the handle is necessary to make ExitCode work.
-    # See https://stackoverflow.com/a/23797762
-    $handle = $process.Handle
-    $process.WaitForExit()
-    if ($null -eq $process.ExitCode) {
-        Write-Error "Unable to read the exit code"
-        Exit 1
-    }
-    Exit $process.ExitCode
+    & $application $arguments
+    Exit $LASTEXITCODE
 }
 
 foreach ($python in "py", "python3", "python", "python2") {