about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/bootstrap.py6
-rwxr-xr-xsrc/bootstrap/configure.py5
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs4
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs6
-rw-r--r--src/bootstrap/src/core/config/config.rs5
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs2
-rw-r--r--src/bootstrap/src/lib.rs6
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/display.rs6
-rw-r--r--src/librustdoc/html/format.rs107
-rw-r--r--src/librustdoc/html/render/mod.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs4
14 files changed, 99 insertions, 71 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 19e87f9c293..effd33d288f 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1193,8 +1193,6 @@ class RustBuild(object):
             return "<commit>"
         cmd = [
             "git",
-            "-C",
-            repo_path,
             "rev-list",
             "--author",
             author_email,
@@ -1202,7 +1200,9 @@ class RustBuild(object):
             "HEAD",
         ]
         try:
-            commit = subprocess.check_output(cmd, universal_newlines=True).strip()
+            commit = subprocess.check_output(
+                cmd, universal_newlines=True, cwd=repo_path
+            ).strip()
             return commit or "<commit>"
         except subprocess.CalledProcessError:
             return "<commit>"
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index b05a5cc8b81..1915986be28 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -340,6 +340,11 @@ o(
     "don't truncate options when printing them in this configure script",
 )
 v("set", None, "set arbitrary key/value pairs in TOML configuration")
+v(
+    "parallel-frontend-threads",
+    "rust.parallel-frontend-threads",
+    "number of parallel threads for rustc compilation",
+)
 
 
 def p(msg):
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 1458b0beefa..14104d7d1d7 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1357,10 +1357,6 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
         cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
     }
 
-    if builder.config.llvm_enzyme {
-        cargo.rustflag("--cfg=llvm_enzyme");
-    }
-
     // These conditionals represent a tension between three forces:
     // - For non-check builds, we need to define some LLVM-related environment
     //   variables, requiring LLVM to have been built.
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 8e65ec7ce50..6121bf7d9cd 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -679,6 +679,12 @@ impl Builder<'_> {
         // cargo would implicitly add it, it was discover that sometimes bootstrap only use
         // `rustflags` without `cargo` making it required.
         rustflags.arg("-Zunstable-options");
+
+        // Add parallel frontend threads configuration
+        if let Some(threads) = self.config.rust_parallel_frontend_threads {
+            rustflags.arg(&format!("-Zthreads={threads}"));
+        }
+
         for (restricted_mode, name, values) in EXTRA_CHECK_CFGS {
             if restricted_mode.is_none() || *restricted_mode == Some(mode) {
                 rustflags.arg(&check_cfg_arg(name, *values));
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 0213047f3a1..efb7ad91699 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -191,7 +191,6 @@ pub struct Config {
     pub rust_optimize: RustOptimize,
     pub rust_codegen_units: Option<u32>,
     pub rust_codegen_units_std: Option<u32>,
-
     pub rustc_debug_assertions: bool,
     pub std_debug_assertions: bool,
     pub tools_debug_assertions: bool,
@@ -222,6 +221,8 @@ pub struct Config {
     pub rust_validate_mir_opts: Option<u32>,
     pub rust_std_features: BTreeSet<String>,
     pub rust_break_on_ice: bool,
+    pub rust_parallel_frontend_threads: Option<u32>,
+
     pub llvm_profile_use: Option<String>,
     pub llvm_profile_generate: bool,
     pub llvm_libunwind_default: Option<LlvmLibunwind>,
@@ -534,6 +535,7 @@ impl Config {
             backtrace_on_ice: rust_backtrace_on_ice,
             verify_llvm_ir: rust_verify_llvm_ir,
             thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit,
+            parallel_frontend_threads: rust_parallel_frontend_threads,
             remap_debuginfo: rust_remap_debuginfo,
             jemalloc: rust_jemalloc,
             test_compare_mode: rust_test_compare_mode,
@@ -1298,6 +1300,7 @@ impl Config {
             rust_overflow_checks_std: rust_overflow_checks_std
                 .or(rust_overflow_checks)
                 .unwrap_or(rust_debug == Some(true)),
+            rust_parallel_frontend_threads: rust_parallel_frontend_threads.map(threads_from_config),
             rust_profile_generate: flags_rust_profile_generate.or(rust_profile_generate),
             rust_profile_use: flags_rust_profile_use.or(rust_profile_use),
             rust_randomize_layout: rust_randomize_layout.unwrap_or(false),
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index 4832a1d37b7..e5987d7040a 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -66,6 +66,7 @@ define_config! {
         validate_mir_opts: Option<u32> = "validate-mir-opts",
         std_features: Option<BTreeSet<String>> = "std-features",
         break_on_ice: Option<bool> = "break-on-ice",
+        parallel_frontend_threads: Option<u32> = "parallel-frontend-threads",
     }
 }
 
@@ -357,6 +358,7 @@ pub fn check_incompatible_options_for_ci_rustc(
         validate_mir_opts: _,
         frame_pointers: _,
         break_on_ice: _,
+        parallel_frontend_threads: _,
     } = ci_rust_config;
 
     // There are two kinds of checks for CI rustc incompatible options:
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index a2aeed20948..e953fe2945e 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -87,9 +87,6 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (Some(Mode::Codegen), "bootstrap", None),
     (Some(Mode::ToolRustcPrivate), "bootstrap", None),
     (Some(Mode::ToolStd), "bootstrap", None),
-    (Some(Mode::Rustc), "llvm_enzyme", None),
-    (Some(Mode::Codegen), "llvm_enzyme", None),
-    (Some(Mode::ToolRustcPrivate), "llvm_enzyme", None),
     (Some(Mode::ToolRustcPrivate), "rust_analyzer", None),
     (Some(Mode::ToolStd), "rust_analyzer", None),
     // Any library specific cfgs like `target_os`, `target_arch` should be put in
@@ -869,6 +866,9 @@ impl Build {
         if (self.config.llvm_enabled(target) || kind == Kind::Check) && check("llvm") {
             features.push("llvm");
         }
+        if self.config.llvm_enzyme {
+            features.push("llvm_enzyme");
+        }
         // keep in sync with `bootstrap/compile.rs:rustc_cargo_env`
         if self.config.rust_randomize_layout && check("rustc_randomized_layouts") {
             features.push("rustc_randomized_layouts");
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 03b39882e30..2c48cebd2df 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -546,4 +546,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "The default value of the `gcc.download-ci-gcc` option has been changed to `true`.",
     },
+    ChangeInfo {
+        change_id: 146458,
+        severity: ChangeSeverity::Info,
+        summary: "There is now a bootstrap option called `rust.parallel-frontend-threads`, which can be used to set the number of threads for the compiler frontend used during compilation of Rust code.",
+    },
 ];
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5ccacafea01..0afb969d5c8 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2093,7 +2093,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
             );
             Type::Path { path }
         }
-        ty::Dynamic(obj, reg, _) => {
+        ty::Dynamic(obj, reg) => {
             // HACK: pick the first `did` as the `did` of the trait object. Someone
             // might want to implement "native" support for marker-trait-only
             // trait objects.
diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs
index aa0fad26520..db868c5c9a8 100644
--- a/src/librustdoc/display.rs
+++ b/src/librustdoc/display.rs
@@ -10,7 +10,7 @@ pub(crate) trait Joined: IntoIterator {
     ///
     /// The performance of `joined` is slightly better than `format`, since it doesn't need to use a `Cell` to keep track of whether [`fmt`](Display::fmt)
     /// was already called (`joined`'s API doesn't allow it be called more than once).
-    fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result;
+    fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result;
 }
 
 impl<I, T> Joined for I
@@ -18,12 +18,12 @@ where
     I: IntoIterator<Item = T>,
     T: Display,
 {
-    fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result {
+    fn joined(self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result {
         let mut iter = self.into_iter();
         let Some(first) = iter.next() else { return Ok(()) };
         first.fmt(f)?;
         for item in iter {
-            f.write_str(sep)?;
+            sep.fmt(f)?;
             item.fmt(f)?;
         }
         Ok(())
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 493fdc6fb1b..8c75f301841 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1264,6 +1264,7 @@ impl std::fmt::Write for WriteCounter {
 }
 
 // Implements Display by emitting the given number of spaces.
+#[derive(Clone, Copy)]
 struct Indent(usize);
 
 impl Display for Indent {
@@ -1275,6 +1276,37 @@ impl Display for Indent {
     }
 }
 
+impl clean::Parameter {
+    fn print(&self, cx: &Context<'_>) -> impl fmt::Display {
+        fmt::from_fn(move |f| {
+            if let Some(self_ty) = self.to_receiver() {
+                match self_ty {
+                    clean::SelfTy => f.write_str("self"),
+                    clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
+                        f.write_str(if f.alternate() { "&" } else { "&amp;" })?;
+                        if let Some(lt) = lifetime {
+                            write!(f, "{lt} ", lt = lt.print())?;
+                        }
+                        write!(f, "{mutability}self", mutability = mutability.print_with_space())
+                    }
+                    _ => {
+                        f.write_str("self: ")?;
+                        self_ty.print(cx).fmt(f)
+                    }
+                }
+            } else {
+                if self.is_const {
+                    write!(f, "const ")?;
+                }
+                if let Some(name) = self.name {
+                    write!(f, "{name}: ")?;
+                }
+                self.type_.print(cx).fmt(f)
+            }
+        })
+    }
+}
+
 impl clean::FnDecl {
     pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
@@ -1333,63 +1365,42 @@ impl clean::FnDecl {
         f: &mut fmt::Formatter<'_>,
         cx: &Context<'_>,
     ) -> fmt::Result {
-        let amp = if f.alternate() { "&" } else { "&amp;" };
+        f.write_char('(')?;
 
-        write!(f, "(")?;
-        if let Some(n) = line_wrapping_indent
-            && !self.inputs.is_empty()
-        {
-            write!(f, "\n{}", Indent(n + 4))?;
-        }
+        if !self.inputs.is_empty() {
+            let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));
 
-        let last_input_index = self.inputs.len().checked_sub(1);
-        for (i, param) in self.inputs.iter().enumerate() {
-            if let Some(selfty) = param.to_receiver() {
-                match selfty {
-                    clean::SelfTy => {
-                        write!(f, "self")?;
-                    }
-                    clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
-                        write!(f, "{amp}")?;
-                        if let Some(lt) = lifetime {
-                            write!(f, "{lt} ", lt = lt.print())?;
-                        }
-                        write!(f, "{mutability}self", mutability = mutability.print_with_space())?;
-                    }
-                    _ => {
-                        write!(f, "self: ")?;
-                        selfty.print(cx).fmt(f)?;
-                    }
-                }
-            } else {
-                if param.is_const {
-                    write!(f, "const ")?;
-                }
-                if let Some(name) = param.name {
-                    write!(f, "{name}: ")?;
+            if let Some(indent) = line_wrapping_indent {
+                write!(f, "\n{indent}")?;
+            }
+
+            let sep = fmt::from_fn(|f| {
+                if let Some(indent) = line_wrapping_indent {
+                    write!(f, ",\n{indent}")
+                } else {
+                    f.write_str(", ")
                 }
-                param.type_.print(cx).fmt(f)?;
+            });
+
+            self.inputs.iter().map(|param| param.print(cx)).joined(sep, f)?;
+
+            if line_wrapping_indent.is_some() {
+                writeln!(f, ",")?
             }
-            match (line_wrapping_indent, last_input_index) {
-                (_, None) => (),
-                (None, Some(last_i)) if i != last_i => write!(f, ", ")?,
-                (None, Some(_)) => (),
-                (Some(n), Some(last_i)) if i != last_i => write!(f, ",\n{}", Indent(n + 4))?,
-                (Some(_), Some(_)) => writeln!(f, ",")?,
+
+            if self.c_variadic {
+                match line_wrapping_indent {
+                    None => write!(f, ", ...")?,
+                    Some(indent) => writeln!(f, "{indent}...")?,
+                };
             }
         }
 
-        if self.c_variadic {
-            match line_wrapping_indent {
-                None => write!(f, ", ...")?,
-                Some(n) => writeln!(f, "{}...", Indent(n + 4))?,
-            };
+        if let Some(n) = line_wrapping_indent {
+            write!(f, "{}", Indent(n))?
         }
 
-        match line_wrapping_indent {
-            None => write!(f, ")")?,
-            Some(n) => write!(f, "{})", Indent(n))?,
-        };
+        f.write_char(')')?;
 
         self.print_output(cx).fmt(f)
     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index b4ef47d1e26..6d684449b6d 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2454,11 +2454,11 @@ fn get_id_for_impl(tcx: TyCtxt<'_>, impl_id: ItemId) -> String {
             (ty, Some(ty::TraitRef::new(tcx, trait_, [ty])))
         }
         ItemId::Blanket { impl_id, .. } | ItemId::DefId(impl_id) => {
-            match tcx.impl_subject(impl_id).skip_binder() {
-                ty::ImplSubject::Trait(trait_ref) => {
-                    (trait_ref.args[0].expect_ty(), Some(trait_ref))
-                }
-                ty::ImplSubject::Inherent(ty) => (ty, None),
+            if let Some(trait_ref) = tcx.impl_trait_ref(impl_id) {
+                let trait_ref = trait_ref.skip_binder();
+                (trait_ref.self_ty(), Some(trait_ref))
+            } else {
+                (tcx.type_of(impl_id).skip_binder(), None)
             }
         }
     };
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 40fd2cdeb86..2bda6d50373 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -86,7 +86,7 @@ fn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, msrv: Msrv)
             ty::FnPtr(..) => {
                 return Err((span, "function pointers in const fn are unstable".into()));
             },
-            ty::Dynamic(preds, _, _) => {
+            ty::Dynamic(preds, _) => {
                 for pred in *preds {
                     match pred.skip_binder() {
                         ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index 9f77a1c4d9b..3e41bce1dc4 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -349,7 +349,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
             }
             false
         },
-        ty::Dynamic(binder, _, _) => {
+        ty::Dynamic(binder, _) => {
             for predicate in *binder {
                 if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()
                     && find_attr!(cx.tcx.get_all_attrs(trait_ref.def_id), AttributeKind::MustUse { .. })
@@ -673,7 +673,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
             cx.tcx.opt_parent(def_id),
         ),
         ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)),
-        ty::Dynamic(bounds, _, _) => {
+        ty::Dynamic(bounds, _) => {
             let lang_items = cx.tcx.lang_items();
             match bounds.principal() {
                 Some(bound)