diff --git a/Cargo.lock b/Cargo.lock
index 7e4db4fdd53..c034cbae991 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3824,7 +3824,6 @@ dependencies = [
"rustc_session",
"rustc_smir",
"rustc_span",
- "rustc_symbol_mangling",
"rustc_target",
"rustc_trait_selection",
"rustc_ty_utils",
@@ -4008,7 +4007,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
- "rustc_graphviz",
"rustc_hir",
"rustc_hir_analysis",
"rustc_hir_pretty",
@@ -4468,7 +4466,6 @@ dependencies = [
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
- "rustc_hir_analysis",
"rustc_macros",
"rustc_middle",
"rustc_session",
@@ -4515,7 +4512,6 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
- "rustc_type_ir",
"smallvec",
"thin-vec",
"tracing",
diff --git a/RELEASES.md b/RELEASES.md
index 104ea497ba4..3080f03c721 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -102,6 +102,10 @@ Compatibility Notes
- [Change equality of higher ranked types to not rely on subtyping](https://github.com/rust-lang/rust/pull/118247)
- [When called, additionally check bounds on normalized function return type](https://github.com/rust-lang/rust/pull/118882)
- [Expand coverage for `arithmetic_overflow` lint](https://github.com/rust-lang/rust/pull/119432/)
+- [Fix detection of potential interior mutability in `const` initializers](https://github.com/rust-lang/rust/issues/121250)
+ This code was accidentally accepted. The fix can break generic code that borrows a value of unknown type,
+ as there is currently no way to declare "this type has no interior mutability". In the future, stabilizing
+ the [`Freeze` trait](https://github.com/rust-lang/rust/issues/121675) will allow proper support for such code.
diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs
index 434b978ae31..7ba58406ef1 100644
--- a/compiler/rustc/src/main.rs
+++ b/compiler/rustc/src/main.rs
@@ -1,5 +1,3 @@
-#![feature(unix_sigpipe)]
-
// A note about jemalloc: rustc uses jemalloc when built for CI and
// distribution. The obvious way to do this is with the `#[global_allocator]`
// mechanism. However, for complicated reasons (see
@@ -34,7 +32,6 @@
// https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef
// for an example of how to do so.
-#[unix_sigpipe = "sig_dfl"]
fn main() {
// See the comment at the top of this file for an explanation of this.
#[cfg(feature = "jemalloc-sys")]
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 2c717661a1c..2450ac8f4b3 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -307,7 +307,7 @@ fn make_format_args(
return ExpandResult::Ready(Err(guar));
}
- let to_span = |inner_span: rustc_parse_format::InnerSpan| {
+ let to_span = |inner_span: parse::InnerSpan| {
is_source_literal.then(|| {
fmt_span.from_inner(InnerSpan { start: inner_span.start, end: inner_span.end })
})
@@ -577,7 +577,7 @@ enum ArgRef<'a> {
fn invalid_placeholder_type_error(
ecx: &ExtCtxt<'_>,
ty: &str,
- ty_span: Option,
+ ty_span: Option,
fmt_span: Span,
) {
let sp = ty_span.map(|sp| fmt_span.from_inner(InnerSpan::new(sp.start, sp.end)));
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index a8bba3afb7e..cb37644d570 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -42,9 +42,8 @@ rustc_privacy = { path = "../rustc_privacy" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }
-rustc_smir ={ path = "../rustc_smir" }
+rustc_smir = { path = "../rustc_smir" }
rustc_span = { path = "../rustc_span" }
-rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index b3a1e29f8e2..4696917554f 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -13,7 +13,7 @@
use rustc_span::Span;
use rustc_target::abi::TargetDataLayoutErrors;
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
-use rustc_type_ir as type_ir;
+use rustc_type_ir::{ClosureKind, FloatTy};
use std::backtrace::Backtrace;
use std::borrow::Cow;
use std::fmt;
@@ -196,7 +196,7 @@ fn into_diag_arg(self) -> DiagArgValue {
}
}
-impl IntoDiagArg for type_ir::FloatTy {
+impl IntoDiagArg for FloatTy {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(Cow::Borrowed(self.name_str()))
}
@@ -252,7 +252,7 @@ fn into_diag_arg(self) -> DiagArgValue {
}
}
-impl IntoDiagArg for type_ir::ClosureKind {
+impl IntoDiagArg for ClosureKind {
fn into_diag_arg(self) -> DiagArgValue {
DiagArgValue::Str(self.as_str().into())
}
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 9d3aac66c41..9c33cc8ed0b 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -396,10 +396,6 @@ pub struct BuiltinAttribute {
),
// Entry point:
- gated!(
- unix_sigpipe, Normal, template!(NameValueStr: "inherit|sig_ign|sig_dfl"), ErrorFollowing,
- EncodeCrossCrate::Yes, experimental!(unix_sigpipe)
- ),
ungated!(start, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_start, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(no_main, CrateLevel, template!(Word), WarnFollowing, EncodeCrossCrate::No),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index e7d7a9f380b..fe50499db76 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -619,8 +619,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows creation of instances of a struct by moving fields that have
/// not changed from prior instances of the same struct (RFC #2528)
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
- /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
- (unstable, unix_sigpipe, "1.65.0", Some(97889)),
/// Allows unnamed fields of struct and union type
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
/// Allows unsized fn parameters.
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index aafb5c1c0b4..5562b81871f 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -23,7 +23,7 @@
/// include the self type (e.g., `trait_bounds`) but in others we do not
#[derive(Default, PartialEq, Eq, Clone, Debug)]
pub struct Bounds<'tcx> {
- pub clauses: Vec<(ty::Clause<'tcx>, Span)>,
+ clauses: Vec<(ty::Clause<'tcx>, Span)>,
}
impl<'tcx> Bounds<'tcx> {
diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml
index 9e7f0776b60..73a775690d6 100644
--- a/compiler/rustc_hir_typeck/Cargo.toml
+++ b/compiler/rustc_hir_typeck/Cargo.toml
@@ -12,7 +12,6 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
-rustc_graphviz = { path = "../rustc_graphviz" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_analysis = { path = "../rustc_hir_analysis" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 382dba5f95f..8c7ae7f8e98 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -10,7 +10,6 @@
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind};
use rustc_infer::infer;
use rustc_infer::infer::type_variable::TypeVariableOrigin;
-use rustc_lint as lint;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
@@ -684,7 +683,7 @@ fn check_pat_ident(
{
// `mut x` resets the binding mode in edition <= 2021.
self.tcx.emit_node_span_lint(
- lint::builtin::DEREFERENCING_MUT_BINDING,
+ rustc_lint::builtin::DEREFERENCING_MUT_BINDING,
pat.hir_id,
pat.span,
errors::DereferencingMutBinding { span: pat.span },
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index b593c41a8ea..76d5d7a3ac2 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -4,7 +4,6 @@
use crate::util;
use rustc_ast::{self as ast, visit};
-use rustc_borrowck as mir_borrowck;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::parallel;
use rustc_data_structures::steal::Steal;
@@ -20,7 +19,6 @@
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
use rustc_middle::util::Providers;
-use rustc_mir_build as mir_build;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
use rustc_passes::{abi_test, hir_stats, layout_test};
use rustc_resolve::Resolver;
@@ -616,8 +614,8 @@ pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) {
proc_macro_decls::provide(providers);
rustc_const_eval::provide(providers);
rustc_middle::hir::provide(providers);
- mir_borrowck::provide(providers);
- mir_build::provide(providers);
+ rustc_borrowck::provide(providers);
+ rustc_mir_build::provide(providers);
rustc_mir_transform::provide(providers);
rustc_monomorphize::provide(providers);
rustc_privacy::provide(providers);
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index db150cc1f87..36f9dda7250 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -20,7 +20,7 @@
use rustc_span::symbol::sym;
use rustc_span::{FileName, SourceFileHashAlgorithm};
use rustc_target::spec::{
- CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi,
+ CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
};
use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel};
use std::collections::{BTreeMap, BTreeSet};
@@ -809,6 +809,7 @@ macro_rules! tracked {
tracked!(no_profiler_runtime, true);
tracked!(no_trait_vptr, true);
tracked!(no_unique_section_names, true);
+ tracked!(on_broken_pipe, OnBrokenPipe::Kill);
tracked!(oom, OomStrategy::Panic);
tracked!(osx_rpath_install_name, true);
tracked!(packed_bundled_libs, true);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 02dcfe9c8df..ce4d3825015 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -7,18 +7,16 @@
use rustc_metadata::{load_symbol_from_dylib, DylibError};
use rustc_middle::ty::CurrentGcx;
use rustc_parse::validate_attr;
-use rustc_session as session;
-use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes};
+use rustc_session::config::{host_triple, Cfg, OutFileName, OutputFilenames, OutputTypes};
use rustc_session::filesearch::sysroot_candidates;
use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
-use rustc_session::{filesearch, Session};
+use rustc_session::output::{categorize_crate_type, CRATE_TYPES};
+use rustc_session::{filesearch, EarlyDiagCtxt, Session};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::source_map::SourceMapInputs;
use rustc_span::symbol::sym;
use rustc_target::spec::Target;
-use session::output::{categorize_crate_type, CRATE_TYPES};
-use session::EarlyDiagCtxt;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
@@ -286,7 +284,7 @@ fn get_codegen_sysroot(
"cannot load the default codegen backend twice"
);
- let target = session::config::host_triple();
+ let target = host_triple();
let sysroot_candidates = sysroot_candidates();
let sysroot = iter::once(sysroot)
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index 4c34bf88c7f..3ad6b68d129 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -273,6 +273,8 @@ pub enum GoalSource {
/// they are from an impl where-clause. This is necessary due to
/// backwards compatability, cc trait-system-refactor-initiatitive#70.
ImplWhereBound,
+ /// Instantiating a higher-ranked goal and re-proving it.
+ InstantiateHigherRanked,
}
/// Possible ways the given goal can be proven.
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index 2d73be387fd..11aa0e10931 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -127,6 +127,7 @@ pub(super) fn format_probe(&mut self, probe: &Probe<'_>) -> std::fmt::Result {
let source = match source {
GoalSource::Misc => "misc",
GoalSource::ImplWhereBound => "impl where-bound",
+ GoalSource::InstantiateHigherRanked => "higher-ranked goal",
};
writeln!(this.f, "ADDED GOAL ({source}): {goal:?}")?
}
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index a545c170297..8878310d6e9 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -695,9 +695,6 @@ passes_transparent_incompatible =
passes_undefined_naked_function_abi =
Rust ABI is unsupported in naked functions
-passes_unix_sigpipe_values =
- valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl`
-
passes_unknown_external_lang_item =
unknown external lang item: `{$lang_item}`
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index c403e9196fa..e60aa27dba2 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2523,7 +2523,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
sym::automatically_derived,
sym::start,
sym::rustc_main,
- sym::unix_sigpipe,
sym::derive,
sym::test,
sym::test_case,
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 438c583db49..d52092f2aa9 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -12,8 +12,7 @@
use rustc_span::{Span, Symbol};
use crate::errors::{
- AttrOnlyInFunctions, AttrOnlyOnMain, AttrOnlyOnRootMain, ExternMain, MultipleRustcMain,
- MultipleStartFunctions, NoMainErr, UnixSigpipeValues,
+ AttrOnlyInFunctions, ExternMain, MultipleRustcMain, MultipleStartFunctions, NoMainErr,
};
struct EntryContext<'tcx> {
@@ -67,11 +66,7 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
ctxt.tcx.opt_item_name(id.owner_id.to_def_id()),
);
match entry_point_type {
- EntryPointType::None => {
- if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
- ctxt.tcx.dcx().emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
- }
- }
+ EntryPointType::None => (),
_ if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) => {
for attr in [sym::start, sym::rustc_main] {
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
@@ -81,9 +76,6 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
}
EntryPointType::MainNamed => (),
EntryPointType::OtherMain => {
- if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
- ctxt.tcx.dcx().emit_err(AttrOnlyOnRootMain { span, attr: sym::unix_sigpipe });
- }
ctxt.non_main_fns.push(ctxt.tcx.def_span(id.owner_id));
}
EntryPointType::RustcMainAttr => {
@@ -98,9 +90,6 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
}
}
EntryPointType::Start => {
- if let Some(span) = attr_span_by_symbol(ctxt, id, sym::unix_sigpipe) {
- ctxt.tcx.dcx().emit_err(AttrOnlyOnMain { span, attr: sym::unix_sigpipe });
- }
if ctxt.start_fn.is_none() {
ctxt.start_fn = Some((id.owner_id.def_id, ctxt.tcx.def_span(id.owner_id)));
} else {
@@ -120,7 +109,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
Some((def_id.to_def_id(), EntryFnType::Start))
} else if let Some((local_def_id, _)) = visitor.attr_main_fn {
let def_id = local_def_id.to_def_id();
- Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }))
+ Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }))
} else {
if let Some(main_def) = tcx.resolutions(()).main_def
&& let Some(def_id) = main_def.opt_fn_def_id()
@@ -133,31 +122,19 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId,
return None;
}
- return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx, def_id) }));
+ return Some((def_id, EntryFnType::Main { sigpipe: sigpipe(tcx) }));
}
no_main_err(tcx, visitor);
None
}
}
-fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
- if let Some(attr) = tcx.get_attr(def_id, sym::unix_sigpipe) {
- match (attr.value_str(), attr.meta_item_list()) {
- (Some(sym::inherit), None) => sigpipe::INHERIT,
- (Some(sym::sig_ign), None) => sigpipe::SIG_IGN,
- (Some(sym::sig_dfl), None) => sigpipe::SIG_DFL,
- (Some(_), None) => {
- tcx.dcx().emit_err(UnixSigpipeValues { span: attr.span });
- sigpipe::DEFAULT
- }
- _ => {
- // Keep going so that `fn emit_malformed_attribute()` can print
- // an excellent error message
- sigpipe::DEFAULT
- }
- }
- } else {
- sigpipe::DEFAULT
+fn sigpipe(tcx: TyCtxt<'_>) -> u8 {
+ match tcx.sess.opts.unstable_opts.on_broken_pipe {
+ rustc_target::spec::OnBrokenPipe::Default => sigpipe::DEFAULT,
+ rustc_target::spec::OnBrokenPipe::Kill => sigpipe::SIG_DFL,
+ rustc_target::spec::OnBrokenPipe::Error => sigpipe::SIG_IGN,
+ rustc_target::spec::OnBrokenPipe::Inherit => sigpipe::INHERIT,
}
}
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 03a607348e8..743faf54560 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1259,13 +1259,6 @@ pub struct ExternMain {
pub span: Span,
}
-#[derive(Diagnostic)]
-#[diag(passes_unix_sigpipe_values)]
-pub struct UnixSigpipeValues {
- #[primary_span]
- pub span: Span,
-}
-
pub struct NoMainErr {
pub sp: Span,
pub crate_name: Symbol,
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
index e7a32771f35..f998e0ff154 100644
--- a/compiler/rustc_privacy/Cargo.toml
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -11,7 +11,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
-rustc_hir_analysis = { path = "../rustc_hir_analysis" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 6ea87a4a633..4d845ab0d07 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -19,7 +19,6 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
-rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
thin-vec = "0.2.12"
tracing = "0.1"
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index ad66e5e1c2b..f2bdabbf394 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2909,7 +2909,9 @@ pub(crate) mod dep_tracking {
use rustc_feature::UnstableFeatures;
use rustc_span::edition::Edition;
use rustc_span::RealFileName;
- use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel, WasmCAbi};
+ use rustc_target::spec::{
+ CodeModel, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel, WasmCAbi,
+ };
use rustc_target::spec::{
RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
};
@@ -2973,6 +2975,7 @@ fn hash(
InstrumentXRay,
CrateType,
MergeFunctions,
+ OnBrokenPipe,
PanicStrategy,
RelroLevel,
OptLevel,
diff --git a/compiler/rustc_session/src/config/sigpipe.rs b/compiler/rustc_session/src/config/sigpipe.rs
index 1fadc75cfd0..1830ee03485 100644
--- a/compiler/rustc_session/src/config/sigpipe.rs
+++ b/compiler/rustc_session/src/config/sigpipe.rs
@@ -1,6 +1,6 @@
//! NOTE: Keep these constants in sync with `library/std/src/sys/pal/unix/mod.rs`!
-/// The default value if `#[unix_sigpipe]` is not specified. This resolves
+/// The default value if `-Zon-broken-pipe=...` is not specified. This resolves
/// to `SIG_IGN` in `library/std/src/sys/pal/unix/mod.rs`.
///
/// Note that `SIG_IGN` has been the Rust default since 2014. See
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 7355e5b6953..65660286dd7 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -12,7 +12,7 @@
use rustc_span::RealFileName;
use rustc_span::SourceFileHashAlgorithm;
use rustc_target::spec::{
- CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, SanitizerSet, WasmCAbi,
+ CodeModel, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy, SanitizerSet, WasmCAbi,
};
use rustc_target::spec::{
RelocModel, RelroLevel, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
@@ -378,6 +378,7 @@ mod desc {
pub const parse_time_passes_format: &str = "`text` (default) or `json`";
pub const parse_passes: &str = "a space-separated list of passes, or `all`";
pub const parse_panic_strategy: &str = "either `unwind` or `abort`";
+ pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
@@ -708,6 +709,17 @@ pub(crate) fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) ->
true
}
+ pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool {
+ match v {
+ // OnBrokenPipe::Default can't be explicitly specified
+ Some("kill") => *slot = OnBrokenPipe::Kill,
+ Some("error") => *slot = OnBrokenPipe::Error,
+ Some("inherit") => *slot = OnBrokenPipe::Inherit,
+ _ => return false,
+ }
+ true
+ }
+
pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool {
match v {
Some("panic") => *slot = OomStrategy::Panic,
@@ -1833,6 +1845,8 @@ pub(crate) fn parse_wasm_c_abi(slot: &mut WasmCAbi, v: Option<&str>) -> bool {
"do not use unique names for text and data sections when -Z function-sections is used"),
normalize_docs: bool = (false, parse_bool, [TRACKED],
"normalize associated items in rustdoc when generating documentation"),
+ on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED],
+ "behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"),
oom: OomStrategy = (OomStrategy::Abort, parse_oom_strategy, [TRACKED],
"panic strategy for out-of-memory handling"),
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7fe94c2e82b..9c556f1152a 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1936,7 +1936,6 @@
unit,
universal_impl_trait,
unix,
- unix_sigpipe,
unlikely,
unmarked_api,
unnamed_fields,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index bd347c1b4b3..cbb248a0fc2 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -778,6 +778,14 @@ pub enum PanicStrategy {
Abort,
}
+#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
+pub enum OnBrokenPipe {
+ Default,
+ Kill,
+ Error,
+ Inherit,
+}
+
impl PanicStrategy {
pub fn desc(&self) -> &str {
match *self {
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 280975f63bd..f2ca42a0be9 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -58,15 +58,15 @@ fn probe_and_match_goal_against_assumption(
/// goal by equating it with the assumption.
fn probe_and_consider_implied_clause(
ecx: &mut EvalCtxt<'_, 'tcx>,
- source: CandidateSource,
+ parent_source: CandidateSource,
goal: Goal<'tcx, Self>,
assumption: ty::Clause<'tcx>,
- requirements: impl IntoIterator- >>,
+ requirements: impl IntoIterator
- >)>,
) -> Result, NoSolution> {
- Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
- // FIXME(-Znext-solver=coinductive): check whether this should be
- // `GoalSource::ImplWhereBound` for any caller.
- ecx.add_goals(GoalSource::Misc, requirements);
+ Self::probe_and_match_goal_against_assumption(ecx, parent_source, goal, assumption, |ecx| {
+ for (nested_source, goal) in requirements {
+ ecx.add_goal(nested_source, goal);
+ }
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
@@ -85,9 +85,8 @@ fn probe_and_consider_object_bound_candidate(
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
bug!("expected object type in `probe_and_consider_object_bound_candidate`");
};
- // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
ecx.add_goals(
- GoalSource::Misc,
+ GoalSource::ImplWhereBound,
structural_traits::predicates_for_object_candidate(
ecx,
goal.param_env,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 6722abd709c..d6bf2b596ef 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -90,6 +90,8 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
&mut self,
certainty: Certainty,
) -> QueryResult<'tcx> {
+ self.inspect.make_canonical_response(certainty);
+
let goals_certainty = self.try_evaluate_added_goals()?;
assert_eq!(
self.tainted,
@@ -98,8 +100,6 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
previous call to `try_evaluate_added_goals!`"
);
- self.inspect.make_canonical_response(certainty);
-
// When normalizing, we've replaced the expected term with an unconstrained
// inference variable. This means that we dropped information which could
// have been important. We handle this by instead returning the nested goals
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 1710746ae50..bae1c6b6011 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -454,7 +454,7 @@ fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult
} else {
self.infcx.enter_forall(kind, |kind| {
let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
- self.add_goal(GoalSource::Misc, goal);
+ self.add_goal(GoalSource::InstantiateHigherRanked, goal);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 3fa409eefff..796222129f1 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -1,15 +1,19 @@
use std::mem;
+use std::ops::ControlFlow;
use rustc_infer::infer::InferCtxt;
-use rustc_infer::traits::solve::MaybeCause;
+use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::solve::inspect::ProbeKind;
+use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause};
use rustc_infer::traits::{
- query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
- PredicateObligation, SelectionError, TraitEngine,
+ self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation,
+ ObligationCause, PredicateObligation, SelectionError, TraitEngine,
};
-use rustc_middle::ty;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::{self, TyCtxt};
use super::eval_ctxt::GenerateProofTree;
+use super::inspect::{ProofTreeInferCtxtExt, ProofTreeVisitor};
use super::{Certainty, InferCtxtEvalExt};
/// A trait engine using the new trait solver.
@@ -133,9 +137,9 @@ fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec(
infcx: &InferCtxt<'tcx>,
- obligation: PredicateObligation<'tcx>,
+ root_obligation: PredicateObligation<'tcx>,
) -> FulfillmentError<'tcx> {
+ let obligation = find_best_leaf_obligation(infcx, &root_obligation);
+
let code = match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
FulfillmentErrorCode::ProjectionError(
@@ -234,7 +240,8 @@ fn fulfillment_error_for_no_solution<'tcx>(
bug!("unexpected goal: {obligation:?}")
}
};
- FulfillmentError { root_obligation: obligation.clone(), code, obligation }
+
+ FulfillmentError { obligation, code, root_obligation }
}
fn fulfillment_error_for_stalled<'tcx>(
@@ -258,5 +265,136 @@ fn fulfillment_error_for_stalled<'tcx>(
}
});
- FulfillmentError { obligation: obligation.clone(), code, root_obligation: obligation }
+ FulfillmentError {
+ obligation: find_best_leaf_obligation(infcx, &obligation),
+ code,
+ root_obligation: obligation,
+ }
+}
+
+fn find_best_leaf_obligation<'tcx>(
+ infcx: &InferCtxt<'tcx>,
+ obligation: &PredicateObligation<'tcx>,
+) -> PredicateObligation<'tcx> {
+ let obligation = infcx.resolve_vars_if_possible(obligation.clone());
+ infcx
+ .visit_proof_tree(
+ obligation.clone().into(),
+ &mut BestObligation { obligation: obligation.clone() },
+ )
+ .break_value()
+ .unwrap_or(obligation)
+}
+
+struct BestObligation<'tcx> {
+ obligation: PredicateObligation<'tcx>,
+}
+
+impl<'tcx> BestObligation<'tcx> {
+ fn with_derived_obligation(
+ &mut self,
+ derived_obligation: PredicateObligation<'tcx>,
+ and_then: impl FnOnce(&mut Self) -> >::Result,
+ ) -> >::Result {
+ let old_obligation = std::mem::replace(&mut self.obligation, derived_obligation);
+ let res = and_then(self);
+ self.obligation = old_obligation;
+ res
+ }
+}
+
+impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
+ type Result = ControlFlow>;
+
+ fn span(&self) -> rustc_span::Span {
+ self.obligation.cause.span
+ }
+
+ fn visit_goal(&mut self, goal: &super::inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
+ // FIXME: Throw out candidates that have no failing WC and >0 failing misc goal.
+ // This most likely means that the goal just didn't unify at all, e.g. a param
+ // candidate with an alias in it.
+ let candidates = goal.candidates();
+
+ let [candidate] = candidates.as_slice() else {
+ return ControlFlow::Break(self.obligation.clone());
+ };
+
+ // FIXME: Could we extract a trait ref from a projection here too?
+ // FIXME: Also, what about considering >1 layer up the stack? May be necessary
+ // for normalizes-to.
+ let Some(parent_trait_pred) = goal.goal().predicate.to_opt_poly_trait_pred() else {
+ return ControlFlow::Break(self.obligation.clone());
+ };
+
+ let tcx = goal.infcx().tcx;
+ let mut impl_where_bound_count = 0;
+ for nested_goal in candidate.instantiate_nested_goals(self.span()) {
+ let obligation;
+ match nested_goal.source() {
+ GoalSource::Misc => {
+ continue;
+ }
+ GoalSource::ImplWhereBound => {
+ obligation = Obligation {
+ cause: derive_cause(
+ tcx,
+ candidate.kind(),
+ self.obligation.cause.clone(),
+ impl_where_bound_count,
+ parent_trait_pred,
+ ),
+ param_env: nested_goal.goal().param_env,
+ predicate: nested_goal.goal().predicate,
+ recursion_depth: self.obligation.recursion_depth + 1,
+ };
+ impl_where_bound_count += 1;
+ }
+ GoalSource::InstantiateHigherRanked => {
+ obligation = self.obligation.clone();
+ }
+ }
+
+ // Skip nested goals that hold.
+ //FIXME: We should change the max allowed certainty based on if we're
+ // visiting an ambiguity or error obligation.
+ if matches!(nested_goal.result(), Ok(Certainty::Yes)) {
+ continue;
+ }
+
+ self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
+ }
+
+ ControlFlow::Break(self.obligation.clone())
+ }
+}
+
+fn derive_cause<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ candidate_kind: ProbeKind<'tcx>,
+ mut cause: ObligationCause<'tcx>,
+ idx: usize,
+ parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
+) -> ObligationCause<'tcx> {
+ match candidate_kind {
+ ProbeKind::TraitCandidate { source: CandidateSource::Impl(impl_def_id), result: _ } => {
+ if let Some((_, span)) =
+ tcx.predicates_of(impl_def_id).instantiate_identity(tcx).iter().nth(idx)
+ {
+ cause = cause.derived_cause(parent_trait_pred, |derived| {
+ traits::ImplDerivedObligation(Box::new(traits::ImplDerivedObligationCause {
+ derived,
+ impl_or_alias_def_id: impl_def_id,
+ impl_def_predicate_index: Some(idx),
+ span,
+ }))
+ })
+ }
+ }
+ ProbeKind::TraitCandidate { source: CandidateSource::BuiltinImpl(..), result: _ } => {
+ cause = cause.derived_cause(parent_trait_pred, traits::BuiltinDerivedObligation);
+ }
+ _ => {}
+ };
+ cause
}
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 97de25295b8..4f79f1b2aaf 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -41,6 +41,7 @@ pub struct InspectGoal<'a, 'tcx> {
result: Result,
evaluation_kind: inspect::CanonicalGoalEvaluationKind<'tcx>,
normalizes_to_term_hack: Option>,
+ source: GoalSource,
}
/// The expected term of a `NormalizesTo` goal gets replaced
@@ -90,7 +91,7 @@ fn constrain(
pub struct InspectCandidate<'a, 'tcx> {
goal: &'a InspectGoal<'a, 'tcx>,
kind: inspect::ProbeKind<'tcx>,
- nested_goals: Vec>>>,
+ nested_goals: Vec<(GoalSource, inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>)>,
final_state: inspect::CanonicalState<'tcx, ()>,
result: QueryResult<'tcx>,
shallow_certainty: Certainty,
@@ -125,10 +126,8 @@ pub fn shallow_certainty(&self) -> Certainty {
/// back their inference constraints. This function modifies
/// the state of the `infcx`.
pub fn visit_nested_no_probe>(&self, visitor: &mut V) -> V::Result {
- if self.goal.depth < visitor.config().max_depth {
- for goal in self.instantiate_nested_goals(visitor.span()) {
- try_visit!(visitor.visit_goal(&goal));
- }
+ for goal in self.instantiate_nested_goals(visitor.span()) {
+ try_visit!(goal.visit_with(visitor));
}
V::Result::output()
@@ -143,13 +142,16 @@ pub fn instantiate_nested_goals(&self, span: Span) -> Vec>
let instantiated_goals: Vec<_> = self
.nested_goals
.iter()
- .map(|goal| {
- canonical::instantiate_canonical_state(
- infcx,
- span,
- param_env,
- &mut orig_values,
- *goal,
+ .map(|(source, goal)| {
+ (
+ *source,
+ canonical::instantiate_canonical_state(
+ infcx,
+ span,
+ param_env,
+ &mut orig_values,
+ *goal,
+ ),
)
})
.collect();
@@ -171,7 +173,7 @@ pub fn instantiate_nested_goals(&self, span: Span) -> Vec>
instantiated_goals
.into_iter()
- .map(|goal| match goal.predicate.kind().no_bound_vars() {
+ .map(|(source, goal)| match goal.predicate.kind().no_bound_vars() {
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
let unconstrained_term = match term.unpack() {
ty::TermKind::Ty(_) => infcx
@@ -195,6 +197,7 @@ pub fn instantiate_nested_goals(&self, span: Span) -> Vec>
self.goal.depth + 1,
proof_tree.unwrap(),
Some(NormalizesToTermHack { term, unconstrained_term }),
+ source,
)
}
_ => InspectGoal::new(
@@ -202,6 +205,7 @@ pub fn instantiate_nested_goals(&self, span: Span) -> Vec>
self.goal.depth + 1,
infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(),
None,
+ source,
),
})
.collect()
@@ -227,16 +231,23 @@ pub fn result(&self) -> Result {
self.result
}
+ pub fn source(&self) -> GoalSource {
+ self.source
+ }
+
fn candidates_recur(
&'a self,
candidates: &mut Vec>,
- nested_goals: &mut Vec>>>,
+ nested_goals: &mut Vec<(
+ GoalSource,
+ inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>,
+ )>,
probe: &inspect::Probe<'tcx>,
) {
let mut shallow_certainty = None;
for step in &probe.steps {
match step {
- &inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
+ &inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
inspect::ProbeStep::NestedProbe(ref probe) => {
// Nested probes have to prove goals added in their parent
// but do not leak them, so we truncate the added goals
@@ -319,6 +330,7 @@ fn new(
depth: usize,
root: inspect::GoalEvaluation<'tcx>,
normalizes_to_term_hack: Option>,
+ source: GoalSource,
) -> Self {
let inspect::GoalEvaluation { uncanonicalized_goal, kind, evaluation } = root;
let inspect::GoalEvaluationKind::Root { orig_values } = kind else { unreachable!() };
@@ -341,8 +353,17 @@ fn new(
result,
evaluation_kind: evaluation.kind,
normalizes_to_term_hack,
+ source,
}
}
+
+ pub(crate) fn visit_with>(&self, visitor: &mut V) -> V::Result {
+ if self.depth < visitor.config().max_depth {
+ try_visit!(visitor.visit_goal(self));
+ }
+
+ V::Result::output()
+ }
}
/// The public API to interact with proof trees.
@@ -367,6 +388,6 @@ fn visit_proof_tree>(
) -> V::Result {
let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
let proof_tree = proof_tree.unwrap();
- visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None))
+ visitor.visit_goal(&InspectGoal::new(self, 0, proof_tree, None, GoalSource::Misc))
}
}
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index dab87fffe46..f886c588650 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -389,7 +389,7 @@ fn consider_builtin_fn_trait_candidates(
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
goal,
pred,
- [goal.with(tcx, output_is_sized_pred)],
+ [(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))],
)
}
@@ -473,7 +473,8 @@ fn consider_builtin_async_fn_trait_candidates(
pred,
[goal.with(tcx, output_is_sized_pred)]
.into_iter()
- .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))),
+ .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred)))
+ .map(|goal| (GoalSource::ImplWhereBound, goal)),
)
}
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index c8cb14abb55..d2b893d6383 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -321,7 +321,7 @@ fn consider_builtin_fn_trait_candidates(
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
goal,
pred,
- [goal.with(tcx, output_is_sized_pred)],
+ [(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))],
)
}
@@ -367,7 +367,8 @@ fn consider_builtin_async_fn_trait_candidates(
pred,
[goal.with(tcx, output_is_sized_pred)]
.into_iter()
- .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))),
+ .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred)))
+ .map(|goal| (GoalSource::ImplWhereBound, goal)),
)
}
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 5dcef638954..dcf68b36c7a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -186,7 +186,6 @@
#![feature(ptr_metadata)]
#![feature(set_ptr_value)]
#![feature(slice_ptr_get)]
-#![feature(split_at_checked)]
#![feature(str_internals)]
#![feature(str_split_inclusive_remainder)]
#![feature(str_split_remainder)]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 9c523fd6295..de766a4b977 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -2051,8 +2051,6 @@ pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
/// # Examples
///
/// ```
- /// #![feature(split_at_checked)]
- ///
/// let v = [1, -2, 3, -4, 5, -6];
///
/// {
@@ -2075,8 +2073,8 @@ pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
///
/// assert_eq!(None, v.split_at_checked(7));
/// ```
- #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
- #[rustc_const_unstable(feature = "split_at_checked", issue = "119128")]
+ #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
#[inline]
#[must_use]
pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> {
@@ -2102,8 +2100,6 @@ pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> {
/// # Examples
///
/// ```
- /// #![feature(split_at_checked)]
- ///
/// let mut v = [1, 0, 3, 0, 5, 6];
///
/// if let Some((left, right)) = v.split_at_mut_checked(2) {
@@ -2116,8 +2112,8 @@ pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> {
///
/// assert_eq!(None, v.split_at_mut_checked(7));
/// ```
- #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
- #[rustc_const_unstable(feature = "split_at_checked", issue = "119128")]
+ #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")]
#[inline]
#[must_use]
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut [T], &mut [T])> {
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index adccbe02d46..b6f65907d3c 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -721,8 +721,6 @@ pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
/// # Examples
///
/// ```
- /// #![feature(split_at_checked)]
- ///
/// let s = "Per Martin-Löf";
///
/// let (first, last) = s.split_at_checked(3).unwrap();
@@ -734,7 +732,7 @@ pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
/// ```
#[inline]
#[must_use]
- #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
+ #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
@@ -761,8 +759,6 @@ pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
/// # Examples
///
/// ```
- /// #![feature(split_at_checked)]
- ///
/// let mut s = "Per Martin-Löf".to_string();
/// if let Some((first, last)) = s.split_at_mut_checked(3) {
/// first.make_ascii_uppercase();
@@ -776,7 +772,7 @@ pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
/// ```
#[inline]
#[must_use]
- #[unstable(feature = "split_at_checked", reason = "new API", issue = "119128")]
+ #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")]
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 59e118f81ab..46f691d7b75 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -74,7 +74,7 @@ macro_rules! rtunwrap {
//
// Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to
// `SIG_IGN`. Applications have good reasons to want a different behavior
-// though, so there is a `#[unix_sigpipe = "..."]` attribute on `fn main()` that
+// though, so there is a `-Zon-broken-pipe` compiler flag that
// can be used to select how `SIGPIPE` shall be setup (if changed at all) before
// `fn main()` is called. See
// for more info.
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 01d7fb31d7d..1ac5729c02f 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -55,8 +55,8 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
// want!
//
// Hence, we set SIGPIPE to ignore when the program starts up in order
- // to prevent this problem. Add `#[unix_sigpipe = "..."]` above `fn main()` to
- // alter this behavior.
+ // to prevent this problem. Use `-Zon-broken-pipe=...` to alter this
+ // behavior.
reset_sigpipe(sigpipe);
stack_overflow::init();
@@ -190,7 +190,7 @@ mod sigpipe {
_ => unreachable!(),
};
if sigpipe_attr_specified {
- UNIX_SIGPIPE_ATTR_SPECIFIED.store(true, crate::sync::atomic::Ordering::Relaxed);
+ ON_BROKEN_PIPE_FLAG_USED.store(true, crate::sync::atomic::Ordering::Relaxed);
}
if let Some(handler) = handler {
rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR);
@@ -210,7 +210,7 @@ mod sigpipe {
target_os = "fuchsia",
target_os = "horizon",
)))]
-static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool =
+static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
crate::sync::atomic::AtomicBool::new(false);
#[cfg(not(any(
@@ -219,8 +219,8 @@ mod sigpipe {
target_os = "fuchsia",
target_os = "horizon",
)))]
-pub(crate) fn unix_sigpipe_attr_specified() -> bool {
- UNIX_SIGPIPE_ATTR_SPECIFIED.load(crate::sync::atomic::Ordering::Relaxed)
+pub(crate) fn on_broken_pipe_flag_used() -> bool {
+ ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
}
// SAFETY: must be called only once during runtime cleanup.
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index f2947161cd5..e2fca8c7e63 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -353,11 +353,11 @@ unsafe fn do_exec(
// Inherit the signal mask from the parent rather than resetting it (i.e. do not call
// pthread_sigmask).
- // If #[unix_sigpipe] is specified, don't reset SIGPIPE to SIG_DFL.
- // If #[unix_sigpipe] is not specified, reset SIGPIPE to SIG_DFL for backward compatibility.
+ // If -Zon-broken-pipe is used, don't reset SIGPIPE to SIG_DFL.
+ // If -Zon-broken-pipe is not used, reset SIGPIPE to SIG_DFL for backward compatibility.
//
- // #[unix_sigpipe] is an opportunity to change the default here.
- if !crate::sys::pal::unix_sigpipe_attr_specified() {
+ // -Zon-broken-pipe is an opportunity to change the default here.
+ if !crate::sys::pal::on_broken_pipe_flag_used() {
#[cfg(target_os = "android")] // see issue #88585
{
let mut action: libc::sigaction = mem::zeroed();
@@ -450,7 +450,7 @@ fn posix_spawn(
) -> io::Result