diff --git a/Cargo.lock b/Cargo.lock index 7e4db4fdd53eb..c034cbae9912b 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 104ea497ba499..3080f03c7210b 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 434b978ae3151..7ba58406ef1ad 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 2c717661a1c43..2450ac8f4b338 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 @@ fn make_format_args( 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 a8bba3afb7e70..cb37644d570d0 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 b3a1e29f8e2cb..4696917554ffb 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -13,7 +13,7 @@ use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; 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 @@ impl IntoDiagArg for ast::token::TokenKind { } } -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 @@ impl IntoDiagArg for Level { } } -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 9d3aac66c4103..9c33cc8ed0b9c 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -396,10 +396,6 @@ pub const BUILTIN_ATTRIBUTES: &[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 e7d7a9f380b19..fe50499db767b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -619,8 +619,6 @@ declare_features! ( /// 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 aafb5c1c0b4bc..5562b81871fc7 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -23,7 +23,7 @@ use rustc_span::Span; /// 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 9e7f0776b6087..73a775690d66b 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 382dba5f95fb9..8c7ae7f8e980d 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -10,7 +10,6 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // `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 b593c41a8eafa..76d5d7a3ac2fd 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -4,7 +4,6 @@ use crate::proc_macro_decls; 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::arena::Arena; 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 static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { 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 db150cc1f875d..36f9dda7250ca 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -20,7 +20,7 @@ use rustc_span::source_map::{RealFileLoader, SourceMapInputs}; 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 @@ fn test_unstable_options_tracking_hash() { 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 02dcfe9c8dffb..ce4d382501522 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -7,18 +7,16 @@ use rustc_data_structures::sync; 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 4c34bf88c7f96..3ad6b68d1299b 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 2d73be387fdcd..11aa0e10931cb 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 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> { 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 a545c170297de..8878310d6e93f 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 c403e9196fab2..e60aa27dba2b9 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 438c583db49e5..d52092f2aa92a 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -12,8 +12,7 @@ use rustc_span::symbol::sym; 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 03a607348e88c..743faf5456078 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 e7a32771f350d..f998e0ff1547f 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 6ea87a4a633e5..4d845ab0d07b8 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 ad66e5e1c2b4d..f2bdabbf39428 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 @@ pub(crate) mod dep_tracking { 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 1fadc75cfd0d2..1830ee034855b 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 7355e5b695347..65660286dd73a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -12,7 +12,7 @@ use rustc_span::edition::Edition; 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 @@ mod parse { 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 @@ options! { "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 7fe94c2e82ba6..9c556f1152a5b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1936,7 +1936,6 @@ symbols! { 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 bd347c1b4b3fd..cbb248a0fc21c 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 280975f63bd3d..f2ca42a0be91e 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 @@ pub(super) trait GoalKind<'tcx>: /// 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 @@ pub(super) trait GoalKind<'tcx>: 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 6722abd709c31..d6bf2b596ef1e 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 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { &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 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { 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 1710746ae504e..bae1c6b60115e 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 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } 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 3fa409eefffcd..796222129f180 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 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { .collect(); errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError { - root_obligation: obligation.clone(), + obligation: find_best_leaf_obligation(infcx, &obligation), code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) }, - obligation, + root_obligation: obligation, })); errors @@ -192,8 +196,10 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { fn fulfillment_error_for_no_solution<'tcx>( 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 97de25295b813..4f79f1b2aafe0 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 @@ impl<'tcx> NormalizesToTermHack<'tcx> { 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 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { /// 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 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { 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 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { 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 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.goal.depth + 1, proof_tree.unwrap(), Some(NormalizesToTermHack { term, unconstrained_term }), + source, ) } _ => InspectGoal::new( @@ -202,6 +205,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { self.goal.depth + 1, infcx.evaluate_root_goal(goal, GenerateProofTree::Yes).1.unwrap(), None, + source, ), }) .collect() @@ -227,16 +231,23 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { 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 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { 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 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { 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 @@ impl<'tcx> InferCtxt<'tcx> { ) -> 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 dab87fffe461e..f886c5886504c 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { 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 c8cb14abb554d..d2b893d6383bd 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { 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 5dcef63895441..dcf68b36c7a2e 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 9c523fd6295d7..de766a4b9774f 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2051,8 +2051,6 @@ impl [T] { /// # Examples /// /// ``` - /// #![feature(split_at_checked)] - /// /// let v = [1, -2, 3, -4, 5, -6]; /// /// { @@ -2075,8 +2073,8 @@ impl [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 @@ impl [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 @@ impl [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 adccbe02d46d4..b6f65907d3c30 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -721,8 +721,6 @@ impl 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 @@ impl 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 @@ impl 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 @@ impl 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 59e118f81ab1b..46f691d7b7504 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 01d7fb31d7d6c..1ac5729c02fd4 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 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { _ => 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 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { 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 @@ static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool = 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 f2947161cd56d..e2fca8c7e63dc 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 @@ impl Command { // 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 @@ impl Command { ) -> io::Result> { use crate::mem::MaybeUninit; use crate::sys::weak::weak; - use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified}; + use crate::sys::{self, cvt_nz, on_broken_pipe_flag_used}; if self.get_gid().is_some() || self.get_uid().is_some() @@ -612,11 +612,11 @@ impl Command { // Inherit the signal mask from this process rather than resetting it (i.e. do not call // posix_spawnattr_setsigmask). - // 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 !unix_sigpipe_attr_specified() { + // -Zon-broken-pipe is an opportunity to change the default here. + if !on_broken_pipe_flag_used() { let mut default_set = MaybeUninit::::uninit(); cvt(sigemptyset(default_set.as_mut_ptr()))?; cvt(sigaddset(default_set.as_mut_ptr(), libc::SIGPIPE))?; diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index f3a26e2593831..7bd08a0605f83 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -589,7 +589,9 @@ pub fn run_test( // If the platform is single-threaded we're just going to run // the test synchronously, regardless of the concurrency // level. - let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm"); + let supports_threads = !cfg!(target_os = "emscripten") + && !cfg!(target_family = "wasm") + && !cfg!(target_os = "zkvm"); if supports_threads { let cfg = thread::Builder::new().name(name.as_slice().to_owned()); let mut runtest = Arc::new(Mutex::new(Some(runtest))); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 1d46a158f9ed2..48a6602e2df7e 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1006,6 +1006,13 @@ pub fn rustc_cargo( cargo.rustdocflag("-Zcrate-attr=warn(rust_2018_idioms)"); + // If the rustc output is piped to e.g. `head -n1` we want the process to be + // killed, rather than having an error bubble up and cause a panic. + // FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it. + if compiler.stage != 0 { + cargo.rustflag("-Zon-broken-pipe=kill"); + } + // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary // and may just be a time sink. if compiler.stage != 0 { diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 2e2c5e9e6f8b2..21344a4224e40 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -471,7 +471,7 @@ impl Step for Rustdoc { features.push("jemalloc".to_string()); } - let cargo = prepare_tool_cargo( + let mut cargo = prepare_tool_cargo( builder, build_compiler, Mode::ToolRustc, @@ -482,6 +482,14 @@ impl Step for Rustdoc { features.as_slice(), ); + // If the rustdoc output is piped to e.g. `head -n1` we want the process + // to be killed, rather than having an error bubble up and cause a + // panic. + // FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it. + if build_compiler.stage > 0 { + cargo.rustflag("-Zon-broken-pipe=kill"); + } + let _guard = builder.msg_tool( Kind::Build, Mode::ToolRustc, diff --git a/src/doc/unstable-book/src/compiler-flags/on-broken-pipe.md b/src/doc/unstable-book/src/compiler-flags/on-broken-pipe.md new file mode 100644 index 0000000000000..bdc175f3b0a32 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/on-broken-pipe.md @@ -0,0 +1,84 @@ +# `on-broken-pipe` + +-------------------- + +The tracking issue for this feature is: [#97889] + +Note: The ui for this feature was previously an attribute named `#[unix_sigpipe = "..."]`. + +[#97889]: https://github.com/rust-lang/rust/issues/97889 + +--- + + +## Overview + +The `-Zon-broken-pipe=...` compiler flag can be used to specify how libstd shall setup `SIGPIPE` on Unix platforms before invoking `fn main()`. This flag is ignored on non-Unix targets. The flag can be used with three different values or be omitted entirely. It affects `SIGPIPE` before `fn main()` and before children get `exec()`'ed: + +| Compiler flag | `SIGPIPE` before `fn main()` | `SIGPIPE` before child `exec()` | +|----------------------------|------------------------------|---------------------------------| +| not used | `SIG_IGN` | `SIG_DFL` | +| `-Zon-broken-pipe=kill` | `SIG_DFL` | not touched | +| `-Zon-broken-pipe=error` | `SIG_IGN` | not touched | +| `-Zon-broken-pipe=inherit` | not touched | not touched | + + +## `-Zon-broken-pipe` not used + +If `-Zon-broken-pipe` is not used, libstd will behave in the manner it has since 2014, before Rust 1.0. `SIGPIPE` will be set to `SIG_IGN` before `fn main()` and result in `EPIPE` errors which are converted to `std::io::ErrorKind::BrokenPipe`. + +When spawning child processes, `SIGPIPE` will be set to `SIG_DFL` before doing the underlying `exec()` syscall. + + +## `-Zon-broken-pipe=kill` + +Set the `SIGPIPE` handler to `SIG_DFL` before invoking `fn main()`. This will result in your program getting killed if it tries to write to a closed pipe. This is normally what you want if your program produces textual output. + +When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_DFL` for `SIGPIPE`. + +### Example + +```rust,no_run +fn main() { + loop { + println!("hello world"); + } +} +``` + +```console +$ rustc -Zon-broken-pipe=kill main.rs +$ ./main | head -n1 +hello world +``` + +## `-Zon-broken-pipe=error` + +Set the `SIGPIPE` handler to `SIG_IGN` before invoking `fn main()`. This will result in `ErrorKind::BrokenPipe` errors if you program tries to write to a closed pipe. This is normally what you want if you for example write socket servers, socket clients, or pipe peers. + +When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_IGN` for `SIGPIPE`. + +### Example + +```rust,no_run +fn main() { + loop { + println!("hello world"); + } +} +``` + +```console +$ rustc -Zon-broken-pipe=error main.rs +$ ./main | head -n1 +hello world +thread 'main' panicked at library/std/src/io/stdio.rs:1118:9: +failed printing to stdout: Broken pipe (os error 32) +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +``` + +## `-Zon-broken-pipe=inherit` + +Leave `SIGPIPE` untouched before entering `fn main()`. Unless the parent process has changed the default `SIGPIPE` handler from `SIG_DFL` to something else, this will behave the same as `-Zon-broken-pipe=kill`. + +When spawning child processes, `SIGPIPE` will not be touched. This normally means child processes inherit `SIG_DFL` for `SIGPIPE`. diff --git a/src/doc/unstable-book/src/language-features/unix-sigpipe.md b/src/doc/unstable-book/src/language-features/unix-sigpipe.md deleted file mode 100644 index 7ed6a7de895c1..0000000000000 --- a/src/doc/unstable-book/src/language-features/unix-sigpipe.md +++ /dev/null @@ -1,62 +0,0 @@ -# `unix_sigpipe` - -The tracking issue for this feature is: [#97889] - -[#97889]: https://github.com/rust-lang/rust/issues/97889 - ---- - -The `#[unix_sigpipe = "..."]` attribute on `fn main()` can be used to specify how libstd shall setup `SIGPIPE` on Unix platforms before invoking `fn main()`. This attribute is ignored on non-Unix targets. There are three variants: -* `#[unix_sigpipe = "inherit"]` -* `#[unix_sigpipe = "sig_dfl"]` -* `#[unix_sigpipe = "sig_ign"]` - -## `#[unix_sigpipe = "inherit"]` - -Leave `SIGPIPE` untouched before entering `fn main()`. Unless the parent process has changed the default `SIGPIPE` handler from `SIG_DFL` to something else, this will behave the same as `#[unix_sigpipe = "sig_dfl"]`. - -## `#[unix_sigpipe = "sig_dfl"]` - -Set the `SIGPIPE` handler to `SIG_DFL`. This will result in your program getting killed if it tries to write to a closed pipe. This is normally what you want if your program produces textual output. - -### Example - -```rust,no_run -#![feature(unix_sigpipe)] -#[unix_sigpipe = "sig_dfl"] -fn main() { loop { println!("hello world"); } } -``` - -```bash -% ./main | head -n 1 -hello world -``` - -## `#[unix_sigpipe = "sig_ign"]` - -Set the `SIGPIPE` handler to `SIG_IGN` before invoking `fn main()`. This will result in `ErrorKind::BrokenPipe` errors if you program tries to write to a closed pipe. This is normally what you want if you for example write socket servers, socket clients, or pipe peers. - -This is what libstd has done by default since 2014. (However, see the note on child processes below.) - -### Example - -```rust,no_run -#![feature(unix_sigpipe)] -#[unix_sigpipe = "sig_ign"] -fn main() { loop { println!("hello world"); } } -``` - -```bash -% ./main | head -n 1 -hello world -thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1016:9 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -``` - -### Note on child processes - -When spawning child processes, the legacy Rust behavior if `#[unix_sigpipe]` is not specified is to -reset `SIGPIPE` to `SIG_DFL`. - -If `#[unix_sigpipe = "..."]` is specified, no matter what its value is, the signal disposition of -`SIGPIPE` is no longer reset. This means that the child inherits the parent's `SIGPIPE` behavior. diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 2242768a56827..97c5e9a0eac97 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -387,7 +387,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( let main_ptr = ecx.fn_ptr(FnVal::Instance(entry_instance)); // Always using DEFAULT is okay since we don't support signals in Miri anyway. - // (This means we are effectively ignoring `#[unix_sigpipe]`.) + // (This means we are effectively ignoring `-Zon-broken-pipe`.) let sigpipe = rustc_session::config::sigpipe::DEFAULT; ecx.call_function( diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 239f90b23c981..d040b05f20e82 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -261,6 +261,12 @@ macro_rules! impl_common_helpers { } output } + + /// Set the path where the command will be run. + pub fn current_dir>(&mut self, path: P) -> &mut Self { + self.cmd.current_dir(path); + self + } } }; } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs index 55b9a1dfdcb91..1fba2e2e4d348 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs @@ -207,7 +207,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // Entry point: - gated!(unix_sigpipe, Normal, template!(Word, NameValueStr: "inherit|sig_ign|sig_dfl"), ErrorFollowing, experimental!(unix_sigpipe)), ungated!(start, Normal, template!(Word), WarnFollowing), ungated!(no_start, CrateLevel, template!(Word), WarnFollowing), ungated!(no_main, CrateLevel, template!(Word), WarnFollowing), diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs index b81f46d1211ce..5b499a1fa1fa8 100644 --- a/src/tools/rustdoc/main.rs +++ b/src/tools/rustdoc/main.rs @@ -1,6 +1,3 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "sig_dfl"] fn main() { rustdoc::main() } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 4b79b910ec39c..a56ea8df6ccb5 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -44,7 +44,6 @@ run-make/dep-graph/Makefile run-make/dep-info-doesnt-run-much/Makefile run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile -run-make/doctests-keep-binaries/Makefile run-make/doctests-runtool/Makefile run-make/dump-ice-to-disk/Makefile run-make/dump-mono-stats/Makefile diff --git a/tests/run-make/doctests-keep-binaries/Makefile b/tests/run-make/doctests-keep-binaries/Makefile deleted file mode 100644 index 2c647851ad0b7..0000000000000 --- a/tests/run-make/doctests-keep-binaries/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Check that valid binaries are persisted by running them, regardless of whether the --run or --no-run option is used. - -MY_SRC_DIR := ${CURDIR} - -all: run no_run test_run_directory - -run: - mkdir -p $(TMPDIR)/doctests - $(RUSTC) --crate-type rlib t.rs - $(RUSTDOC) -Zunstable-options --test --persist-doctests $(TMPDIR)/doctests --extern t=$(TMPDIR)/libt.rlib t.rs - $(TMPDIR)/doctests/t_rs_2_0/rust_out - $(TMPDIR)/doctests/t_rs_8_0/rust_out - rm -rf $(TMPDIR)/doctests - -no_run: - mkdir -p $(TMPDIR)/doctests - $(RUSTC) --crate-type rlib t.rs - $(RUSTDOC) -Zunstable-options --test --persist-doctests $(TMPDIR)/doctests --extern t=$(TMPDIR)/libt.rlib t.rs --no-run - $(TMPDIR)/doctests/t_rs_2_0/rust_out - $(TMPDIR)/doctests/t_rs_8_0/rust_out - rm -rf $(TMPDIR)/doctests - -# Behavior with --test-run-directory with relative paths. -test_run_directory: - mkdir -p $(TMPDIR)/doctests - mkdir -p $(TMPDIR)/rundir - $(RUSTC) --crate-type rlib t.rs - ( cd $(TMPDIR); \ - $(RUSTDOC) -Zunstable-options --test --persist-doctests doctests --test-run-directory rundir --extern t=libt.rlib $(MY_SRC_DIR)/t.rs ) - rm -rf $(TMPDIR)/doctests $(TMPDIR)/rundir diff --git a/tests/run-make/doctests-keep-binaries/rmake.rs b/tests/run-make/doctests-keep-binaries/rmake.rs new file mode 100644 index 0000000000000..ad0c2764df7aa --- /dev/null +++ b/tests/run-make/doctests-keep-binaries/rmake.rs @@ -0,0 +1,68 @@ +// Check that valid binaries are persisted by running them, regardless of whether the +// --run or --no-run option is used. + +use run_make_support::{run, rustc, rustdoc, tmp_dir}; +use std::fs::{create_dir, remove_dir_all}; +use std::path::Path; + +fn setup_test_env(callback: F) { + let out_dir = tmp_dir().join("doctests"); + create_dir(&out_dir).expect("failed to create doctests folder"); + rustc().input("t.rs").crate_type("rlib").run(); + callback(&out_dir, &tmp_dir().join("libt.rlib")); + remove_dir_all(out_dir); +} + +fn check_generated_binaries() { + run("doctests/t_rs_2_0/rust_out"); + run("doctests/t_rs_8_0/rust_out"); +} + +fn main() { + setup_test_env(|out_dir, extern_path| { + rustdoc() + .input("t.rs") + .arg("-Zunstable-options") + .arg("--test") + .arg("--persist-doctests") + .arg(out_dir) + .arg("--extern") + .arg(format!("t={}", extern_path.display())) + .run(); + check_generated_binaries(); + }); + setup_test_env(|out_dir, extern_path| { + rustdoc() + .input("t.rs") + .arg("-Zunstable-options") + .arg("--test") + .arg("--persist-doctests") + .arg(out_dir) + .arg("--extern") + .arg(format!("t={}", extern_path.display())) + .arg("--no-run") + .run(); + check_generated_binaries(); + }); + // Behavior with --test-run-directory with relative paths. + setup_test_env(|_out_dir, extern_path| { + let run_dir = "rundir"; + let run_dir_path = tmp_dir().join("rundir"); + create_dir(&run_dir_path).expect("failed to create rundir folder"); + + rustdoc() + .current_dir(tmp_dir()) + .input(std::env::current_dir().unwrap().join("t.rs")) + .arg("-Zunstable-options") + .arg("--test") + .arg("--persist-doctests") + .arg("doctests") + .arg("--test-run-directory") + .arg(run_dir) + .arg("--extern") + .arg("t=libt.rlib") + .run(); + + remove_dir_all(run_dir_path); + }); +} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.rs deleted file mode 100644 index 5d95fc70e78e9..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe] //~ error: malformed `unix_sigpipe` attribute input -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.stderr deleted file mode 100644 index c1b4470d54a4a..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-bare.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: malformed `unix_sigpipe` attribute input - --> $DIR/unix_sigpipe-bare.rs:3:1 - | -LL | #[unix_sigpipe] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[unix_sigpipe = "inherit|sig_ign|sig_dfl"]` - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs deleted file mode 100644 index f5fa177f29c18..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(unix_sigpipe)] -#![unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute cannot be used at crate level - -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr deleted file mode 100644 index fdfa30180863b..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: `unix_sigpipe` attribute cannot be used at crate level - --> $DIR/unix_sigpipe-crate.rs:2:1 - | -LL | #![unix_sigpipe = "sig_dfl"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | fn main() {} - | ---- the inner attribute doesn't annotate this function - | -help: perhaps you meant to use an outer attribute - | -LL - #![unix_sigpipe = "sig_dfl"] -LL + #[unix_sigpipe = "sig_dfl"] - | - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.rs deleted file mode 100644 index 294cb38526bd0..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "sig_ign"] -#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.stderr deleted file mode 100644 index c2a3b9f45f9ac..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-different-duplicates.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: multiple `unix_sigpipe` attributes - --> $DIR/unix_sigpipe-different-duplicates.rs:4:1 - | -LL | #[unix_sigpipe = "inherit"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unix_sigpipe-different-duplicates.rs:3:1 - | -LL | #[unix_sigpipe = "sig_ign"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs deleted file mode 100644 index eccb23021b6b8..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "inherit"] -#[unix_sigpipe = "inherit"] //~ error: multiple `unix_sigpipe` attributes -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr deleted file mode 100644 index c86e54a1e532f..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-duplicates.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: multiple `unix_sigpipe` attributes - --> $DIR/unix_sigpipe-duplicates.rs:4:1 - | -LL | #[unix_sigpipe = "inherit"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unix_sigpipe-duplicates.rs:3:1 - | -LL | #[unix_sigpipe = "inherit"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.rs deleted file mode 100644 index 462ae24a88425..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe(sig_dfl)] //~ error: malformed `unix_sigpipe` attribute input -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.stderr deleted file mode 100644 index a020f21e6ca77..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-ident-list.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: malformed `unix_sigpipe` attribute input - --> $DIR/unix_sigpipe-ident-list.rs:3:1 - | -LL | #[unix_sigpipe(sig_dfl)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unix_sigpipe = "inherit|sig_ign|sig_dfl"]` - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs deleted file mode 100644 index 16731a4ba2c6e..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()` -fn f() {} - -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr deleted file mode 100644 index fcdd5db8f294b..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-main-fn.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `unix_sigpipe` attribute can only be used on `fn main()` - --> $DIR/unix_sigpipe-non-main-fn.rs:3:1 - | -LL | #[unix_sigpipe = "sig_dfl"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs deleted file mode 100644 index a2435258620a0..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![feature(unix_sigpipe)] - -mod m { - #[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on root `fn main()` - fn main() {} -} - -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr deleted file mode 100644 index 98afb62fdb43b..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-non-root-main.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `unix_sigpipe` attribute can only be used on root `fn main()` - --> $DIR/unix_sigpipe-non-root-main.rs:4:5 - | -LL | #[unix_sigpipe = "sig_dfl"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs deleted file mode 100644 index 945b820f9e00a..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(start)] -#![feature(unix_sigpipe)] - -#[start] -#[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()` -fn custom_start(argc: isize, argv: *const *const u8) -> isize { 0 } diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr deleted file mode 100644 index 3d56b3655c957..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-start.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `unix_sigpipe` attribute can only be used on `fn main()` - --> $DIR/unix_sigpipe-start.rs:5:1 - | -LL | #[unix_sigpipe = "sig_dfl"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.rs deleted file mode 100644 index 22326835623bc..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe("sig_dfl")] //~ error: malformed `unix_sigpipe` attribute input -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.stderr deleted file mode 100644 index b62c086e36059..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-str-list.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: malformed `unix_sigpipe` attribute input - --> $DIR/unix_sigpipe-str-list.rs:3:1 - | -LL | #[unix_sigpipe("sig_dfl")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unix_sigpipe = "inherit|sig_ign|sig_dfl"]` - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs deleted file mode 100644 index 662779c082177..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "sig_dfl"] //~ error: `unix_sigpipe` attribute can only be used on `fn main()` -struct S; - -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr deleted file mode 100644 index a8fc51bdbc430..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-struct.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `unix_sigpipe` attribute can only be used on `fn main()` - --> $DIR/unix_sigpipe-struct.rs:3:1 - | -LL | #[unix_sigpipe = "sig_dfl"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs deleted file mode 100644 index 4ec25de00ec3b..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "wrong"] //~ error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl` -fn main() {} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr deleted file mode 100644 index d750443e4a984..0000000000000 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-wrong.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: valid values for `#[unix_sigpipe = "..."]` are `inherit`, `sig_ign`, or `sig_dfl` - --> $DIR/unix_sigpipe-wrong.rs:3:1 - | -LL | #[unix_sigpipe = "wrong"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index a5182eb5d9c32..f6c5255a18693 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -11,7 +11,7 @@ error[E0282]: type annotations needed --> $DIR/opaques.rs:13:20 | LL | pub fn cast(x: Container, T>) -> Container { - | ^ cannot infer type for struct `Container` + | ^ cannot infer type for associated type `>::Assoc` error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-unix_sigpipe.rs b/tests/ui/feature-gates/feature-gate-unix_sigpipe.rs deleted file mode 100644 index 46dc3f6cc17a5..0000000000000 --- a/tests/ui/feature-gates/feature-gate-unix_sigpipe.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![crate_type = "bin"] - -#[unix_sigpipe = "inherit"] //~ the `#[unix_sigpipe]` attribute is an experimental feature -fn main () {} diff --git a/tests/ui/feature-gates/feature-gate-unix_sigpipe.stderr b/tests/ui/feature-gates/feature-gate-unix_sigpipe.stderr deleted file mode 100644 index 88c18e726835e..0000000000000 --- a/tests/ui/feature-gates/feature-gate-unix_sigpipe.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: the `#[unix_sigpipe]` attribute is an experimental feature - --> $DIR/feature-gate-unix_sigpipe.rs:3:1 - | -LL | #[unix_sigpipe = "inherit"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #97889 for more information - = help: add `#![feature(unix_sigpipe)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 0669999cb82e1..6855e17df9aac 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -2,9 +2,14 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/issue-20605.rs:6:17 | LL | for item in *things { *item = 0 } - | ^^^^^^^ `dyn Iterator` is not an iterator + | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` | - = help: the trait `IntoIterator` is not implemented for `dyn Iterator` + = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: required for `dyn Iterator` to implement `IntoIterator` +help: consider mutably borrowing here + | +LL | for item in &mut *things { *item = 0 } + | ++++ error: the type ` as IntoIterator>::IntoIter` is not well-formed --> $DIR/issue-20605.rs:6:17 diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr index 8a8118dea859b..5be683cd3191b 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr @@ -23,7 +23,20 @@ error[E0283]: type annotations needed LL | impls_indirect_leak::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak` | - = note: cannot satisfy `for<'a> Box<_>: IndirectLeak<'a>` +note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found + --> $DIR/leak-check-in-selection-3.rs:9:1 + | +LL | impl Leak<'_> for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Leak<'static> for Box {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required for `Box<_>` to implement `for<'a> IndirectLeak<'a>` + --> $DIR/leak-check-in-selection-3.rs:23:23 + | +LL | impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {} + | -------- ^^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `impls_indirect_leak` --> $DIR/leak-check-in-selection-3.rs:25:27 | diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index 1df8c765cbdec..798db3c0f8ca4 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -6,16 +6,14 @@ //@ ignore-horizon //@ ignore-android //@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ compile-flags: -Zon-broken-pipe=error // Test what the error message looks like when `println!()` panics because of // `std::io::ErrorKind::BrokenPipe` -#![feature(unix_sigpipe)] - use std::env; use std::process::{Command, Stdio}; -#[unix_sigpipe = "sig_ign"] fn main() { let mut args = env::args(); let me = args.next().unwrap(); diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_dfl.rs similarity index 72% rename from tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs rename to tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_dfl.rs index 7f95fa7ebbece..b179e48452447 100644 --- a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs +++ b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_dfl.rs @@ -1,8 +1,6 @@ //@ aux-crate: sigpipe_utils=sigpipe-utils.rs +//@ compile-flags: -Zon-broken-pipe=inherit -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "inherit"] fn main() { sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); } diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_ign.rs similarity index 72% rename from tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs rename to tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_ign.rs index d96e8b8ef8436..5ea435521ec4e 100644 --- a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs +++ b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-inherit-sig_ign.rs @@ -1,8 +1,6 @@ //@ aux-crate: sigpipe_utils=sigpipe-utils.rs +//@ compile-flags: -Zon-broken-pipe=inherit -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "inherit"] fn main() { sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore); } diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs similarity index 100% rename from tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs rename to tests/ui/runtime/on-broken-pipe/auxiliary/assert-sigpipe-disposition.rs diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs b/tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs similarity index 100% rename from tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs rename to tests/ui/runtime/on-broken-pipe/auxiliary/sigpipe-utils.rs diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs b/tests/ui/runtime/on-broken-pipe/child-processes.rs similarity index 55% rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs rename to tests/ui/runtime/on-broken-pipe/child-processes.rs index 9d1bd9f9607ec..0da2347481b19 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs +++ b/tests/ui/runtime/on-broken-pipe/child-processes.rs @@ -1,25 +1,20 @@ -//@ revisions: default sig_dfl sig_ign inherit +//@ revisions: default error kill inherit //@ ignore-cross-compile because aux-bin does not yet support it //@ only-unix because SIGPIPE is a unix thing //@ run-pass //@ aux-bin:assert-sigpipe-disposition.rs //@ aux-crate:sigpipe_utils=sigpipe-utils.rs +//@ [kill] compile-flags: -Zunstable-options -Zon-broken-pipe=kill +//@ [error] compile-flags: -Zunstable-options -Zon-broken-pipe=error +//@ [inherit] compile-flags: -Zunstable-options -Zon-broken-pipe=inherit // Checks the signal disposition of `SIGPIPE` in child processes, and in our own -// process for robustness. Without any `unix_sigpipe` attribute, `SIG_IGN` is -// the default. But there is a difference in how `SIGPIPE` is treated in child -// processes with and without the attribute. Search for -// `unix_sigpipe_attr_specified()` in the code base to learn more. - -#![cfg_attr(any(sig_dfl, sig_ign, inherit), feature(unix_sigpipe))] +// process for robustness. extern crate sigpipe_utils; use sigpipe_utils::*; -#[cfg_attr(sig_dfl, unix_sigpipe = "sig_dfl")] -#[cfg_attr(sig_ign, unix_sigpipe = "sig_ign")] -#[cfg_attr(inherit, unix_sigpipe = "inherit")] fn main() { // By default we get SIG_IGN but the child gets SIG_DFL through an explicit // reset before exec: @@ -27,18 +22,18 @@ fn main() { #[cfg(default)] let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_DFL"); - // With #[unix_sigpipe = "sig_dfl"] we get SIG_DFL and the child does too - // without any special code running before exec. - #[cfg(sig_dfl)] + // We get SIG_DFL and the child does too without any special code running + // before exec. + #[cfg(kill)] let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL"); - // With #[unix_sigpipe = "sig_ign"] we get SIG_IGN and the child does too - // without any special code running before exec. - #[cfg(sig_ign)] + // We get SIG_IGN and the child does too without any special code running + // before exec. + #[cfg(error)] let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_IGN"); - // With #[unix_sigpipe = "inherit"] we get SIG_DFL and the child does too - // without any special code running before exec. + // We get SIG_DFL and the child does too without any special code running + // before exec. #[cfg(inherit)] let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL"); diff --git a/tests/ui/runtime/on-broken-pipe/default.rs b/tests/ui/runtime/on-broken-pipe/default.rs new file mode 100644 index 0000000000000..c10d1cfacc0c3 --- /dev/null +++ b/tests/ui/runtime/on-broken-pipe/default.rs @@ -0,0 +1,4 @@ +//@ compile-flags: -Zon-broken-pipe=default +//@ check-fail + +fn main() {} diff --git a/tests/ui/runtime/on-broken-pipe/default.stderr b/tests/ui/runtime/on-broken-pipe/default.stderr new file mode 100644 index 0000000000000..b90d7566cbb21 --- /dev/null +++ b/tests/ui/runtime/on-broken-pipe/default.stderr @@ -0,0 +1,2 @@ +error: incorrect value `default` for unstable option `on-broken-pipe` - either `kill`, `error`, or `inherit` was expected + diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs b/tests/ui/runtime/on-broken-pipe/error.rs similarity index 50% rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs rename to tests/ui/runtime/on-broken-pipe/error.rs index b0044f5e91999..ab2036c2f415e 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-not-used.rs +++ b/tests/ui/runtime/on-broken-pipe/error.rs @@ -1,12 +1,10 @@ -//@ revisions: with_feature without_feature //@ run-pass //@ aux-build:sigpipe-utils.rs - -#![cfg_attr(with_feature, feature(unix_sigpipe))] +//@ compile-flags: -Zon-broken-pipe=error fn main() { extern crate sigpipe_utils; - // SIGPIPE shall be ignored since #[unix_sigpipe = "..."] is not used + // `-Zon-broken-pipe=error` is active, so we expect SIGPIPE to be ignored. sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore); } diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/tests/ui/runtime/on-broken-pipe/inherit.rs similarity index 73% rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs rename to tests/ui/runtime/on-broken-pipe/inherit.rs index 3e63349edb747..64909b7352815 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs +++ b/tests/ui/runtime/on-broken-pipe/inherit.rs @@ -3,20 +3,20 @@ //@ aux-bin: assert-inherit-sig_dfl.rs //@ aux-bin: assert-inherit-sig_ign.rs //@ run-pass +//@ compile-flags: -Zon-broken-pipe=kill -#![feature(rustc_private, unix_sigpipe)] +#![feature(rustc_private)] extern crate libc; // By default the Rust runtime resets SIGPIPE to SIG_DFL before exec'ing child -// processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See +// processes so opt-out of that with `-Zon-broken-pipe=kill`. See // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384 -#[unix_sigpipe = "sig_dfl"] fn main() { - // First expect SIG_DFL in a child process with #[unix_sigpipe = "inherit"]. + // First expect SIG_DFL in a child process with -`Zon-broken-pipe=inherit`. assert_inherit_sigpipe_disposition("auxiliary/bin/assert-inherit-sig_dfl"); - // With SIG_IGN we expect #[unix_sigpipe = "inherit"] to also get SIG_IGN. + // With SIG_IGN we expect `-Zon-broken-pipe=inherit` to also get SIG_IGN. unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN); } diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs b/tests/ui/runtime/on-broken-pipe/kill.rs similarity index 60% rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs rename to tests/ui/runtime/on-broken-pipe/kill.rs index 30f2a9b143062..5dace6f1c6ffc 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_dfl.rs +++ b/tests/ui/runtime/on-broken-pipe/kill.rs @@ -1,13 +1,11 @@ //@ run-pass //@ aux-build:sigpipe-utils.rs +//@ compile-flags: -Zon-broken-pipe=kill -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "sig_dfl"] fn main() { extern crate sigpipe_utils; - // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE shall NOT be ignored, instead + // `-Zon-broken-pipe=kill` is active, so SIGPIPE shall NOT be ignored, instead // the default handler shall be installed sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); } diff --git a/tests/ui/runtime/on-broken-pipe/no-flag-arg.rs b/tests/ui/runtime/on-broken-pipe/no-flag-arg.rs new file mode 100644 index 0000000000000..2273291bfa778 --- /dev/null +++ b/tests/ui/runtime/on-broken-pipe/no-flag-arg.rs @@ -0,0 +1,4 @@ +//@ compile-flags: -Zon-broken-pipe +//@ check-fail + +fn main() {} diff --git a/tests/ui/runtime/on-broken-pipe/no-flag-arg.stderr b/tests/ui/runtime/on-broken-pipe/no-flag-arg.stderr new file mode 100644 index 0000000000000..3d3e12d303ca2 --- /dev/null +++ b/tests/ui/runtime/on-broken-pipe/no-flag-arg.stderr @@ -0,0 +1,2 @@ +error: unstable option `on-broken-pipe` requires either `kill`, `error`, or `inherit` (Z on-broken-pipe=) + diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_ign.rs b/tests/ui/runtime/on-broken-pipe/not-used.rs similarity index 50% rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_ign.rs rename to tests/ui/runtime/on-broken-pipe/not-used.rs index ccd6c67866018..e31236f2b3df8 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-sig_ign.rs +++ b/tests/ui/runtime/on-broken-pipe/not-used.rs @@ -1,13 +1,9 @@ //@ run-pass //@ aux-build:sigpipe-utils.rs -#![feature(unix_sigpipe)] - -#[unix_sigpipe = "sig_ign"] fn main() { extern crate sigpipe_utils; - // #[unix_sigpipe = "sig_ign"] is active, so the legacy behavior of ignoring - // SIGPIPE shall be in effect + // SIGPIPE shall be ignored since `-Zon-broken-pipe` is not used sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore); } diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs similarity index 69% rename from tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs rename to tests/ui/runtime/on-broken-pipe/with-rustc_main.rs index 02a3f48f3b395..c1731200038b4 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-rustc_main.rs +++ b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs @@ -1,15 +1,14 @@ //@ run-pass //@ aux-build:sigpipe-utils.rs +//@ compile-flags: -Zon-broken-pipe=kill -#![feature(unix_sigpipe)] #![feature(rustc_attrs)] -#[unix_sigpipe = "sig_dfl"] #[rustc_main] fn rustc_main() { extern crate sigpipe_utils; - // #[unix_sigpipe = "sig_dfl"] is active, so SIGPIPE handler shall be + // `-Zon-broken-pipe=kill` is active, so SIGPIPE handler shall be // SIG_DFL. Note that we have a #[rustc_main], but it should still work. sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); } diff --git a/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.rs b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.rs new file mode 100644 index 0000000000000..14d0ac56b5a3d --- /dev/null +++ b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.rs @@ -0,0 +1,4 @@ +//@ compile-flags: -Zon-broken-pipe=wrong +//@ check-fail + +fn main() {} diff --git a/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.stderr b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.stderr new file mode 100644 index 0000000000000..3635418c845c2 --- /dev/null +++ b/tests/ui/runtime/on-broken-pipe/wrong-flag-arg.stderr @@ -0,0 +1,2 @@ +error: incorrect value `wrong` for unstable option `on-broken-pipe` - either `kill`, `error`, or `inherit` was expected + diff --git a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr index ac05dfb2d46f2..562d7ccf9fec0 100644 --- a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr +++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.fail.stderr @@ -1,18 +1,26 @@ -error[E0277]: `impl Future` cannot be sent between threads safely +error: future cannot be sent between threads safely --> $DIR/auto-with-drop_tracking_mir.rs:25:13 | LL | is_send(foo()); - | ------- ^^^^^ `impl Future` cannot be sent between threads safely - | | - | required by a bound introduced by this call + | ^^^^^ future returned by `foo` is not `Send` | - = help: the trait `Send` is not implemented for `impl Future` + = help: the trait `Sync` is not implemented for `impl Future`, which is required by `impl Future: Send` +note: future is not `Send` as this value is used across an await + --> $DIR/auto-with-drop_tracking_mir.rs:16:11 + | +LL | let x = &NotSync; + | - has type `&NotSync` which is not `Send` +LL | bar().await; + | ^^^^^ await occurs here, with `x` maybe used later note: required by a bound in `is_send` --> $DIR/auto-with-drop_tracking_mir.rs:24:24 | LL | fn is_send(_: impl Send) {} | ^^^^ required by this bound in `is_send` +help: consider dereferencing here + | +LL | is_send(*foo()); + | + error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs index c82c17931194a..17741161b31bc 100644 --- a/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs +++ b/tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs @@ -23,5 +23,5 @@ async fn bar() {} fn main() { fn is_send(_: impl Send) {} is_send(foo()); - //[fail]~^ ERROR `impl Future` cannot be sent between threads safely + //[fail]~^ ERROR future cannot be sent between threads safely } diff --git a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs index ccb10bab6c1bc..f8926b24e3fab 100644 --- a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs +++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs @@ -13,5 +13,5 @@ fn foo, T: Tuple>(f: Option, t: T) { fn main() { foo:: str, _>(None, ()); - //~^ expected a `Fn<_>` closure, found `fn() -> str` + //~^ the size for values of type `str` cannot be known at compilation time } diff --git a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr index 08047852f203a..b487ceef1d42e 100644 --- a/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr +++ b/tests/ui/traits/next-solver/builtin-fn-must-return-sized.stderr @@ -1,10 +1,11 @@ -error[E0277]: expected a `Fn<_>` closure, found `fn() -> str` +error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/builtin-fn-must-return-sized.rs:15:11 | LL | foo:: str, _>(None, ()); - | ^^^^^^^^^^^ expected an `Fn<_>` closure, found `fn() -> str` + | ^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `Fn<_>` is not implemented for `fn() -> str` + = help: within `fn() -> str`, the trait `Sized` is not implemented for `str`, which is required by `fn() -> str: Fn<_>` + = note: required because it appears within the type `fn() -> str` note: required by a bound in `foo` --> $DIR/builtin-fn-must-return-sized.rs:10:11 | diff --git a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr index 57cba790b5537..6e68646fbe4f4 100644 --- a/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/coherence-fulfill-overflow.stderr @@ -1,12 +1,12 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>` +error[E0119]: conflicting implementations of trait `Trait` for type `W>>>>>>>>>>>>>>>>>>>>>` --> $DIR/coherence-fulfill-overflow.rs:12:1 | LL | impl Trait for W {} | ------------------------------------- first implementation here LL | impl Trait for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>>>>>>>>>>>>>>>>>>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W>>>>>>>>>>>>>>>>>>>>>` | - = note: overflow evaluating the requirement `W>>>>>>>>>>>>>>>>>>>>: TwoW` + = note: overflow evaluating the requirement `W>>>: TwoW` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`) error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr index 8d7d8cee08ae3..df25150c21f8b 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr @@ -1,9 +1,16 @@ -error[E0275]: overflow evaluating the requirement `W<_>: Trait` +error[E0275]: overflow evaluating the requirement `_: Sized` --> $DIR/fixpoint-exponential-growth.rs:33:13 | LL | impls::>(); | ^^^^ | +note: required for `W<(W<_>, W<_>)>` to implement `Trait` + --> $DIR/fixpoint-exponential-growth.rs:23:12 + | +LL | impl Trait for W<(W, W)> + | - ^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `impls` --> $DIR/fixpoint-exponential-growth.rs:30:13 | diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs index 7eea81ce03c66..bc9bb6ce2d79e 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -61,7 +61,7 @@ where // entering the cycle from `A` fails, but would work if we were to use the cache // result of `B`. impls_trait::, _, _, _>(); - //~^ ERROR the trait bound `A: Trait<_, _, _>` is not satisfied + //~^ ERROR the trait bound `X: IncompleteGuidance<_, _>` is not satisfied } fn main() { diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr index d4932191791fd..78116ebba8274 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.stderr @@ -1,10 +1,21 @@ -error[E0277]: the trait bound `A: Trait<_, _, _>` is not satisfied +error[E0277]: the trait bound `X: IncompleteGuidance<_, _>` is not satisfied --> $DIR/incompleteness-unstable-result.rs:63:19 | LL | impls_trait::, _, _, _>(); - | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A` + | ^^^^ the trait `IncompleteGuidance<_, _>` is not implemented for `X`, which is required by `A: Trait<_, _, _>` | - = help: the trait `Trait` is implemented for `A` + = help: the following other types implement trait `IncompleteGuidance`: + > + > + > +note: required for `A` to implement `Trait<_, _, u8>` + --> $DIR/incompleteness-unstable-result.rs:32:50 + | +LL | impl Trait for A + | ^^^^^^^^^^^^^^ ^^^^ +LL | where +LL | T: IncompleteGuidance, + | ------------------------ unsatisfied trait bound introduced here note: required by a bound in `impls_trait` --> $DIR/incompleteness-unstable-result.rs:51:28 | diff --git a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr index 7cedb4d36c98d..86c71ad92ff8a 100644 --- a/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr +++ b/tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.stderr @@ -1,21 +1,53 @@ -error[E0275]: overflow evaluating the requirement `(): Trait` +error[E0275]: overflow evaluating the requirement `(): Inductive` --> $DIR/double-cycle-inductive-coinductive.rs:32:19 | LL | impls_trait::<()>(); | ^^ | +note: required for `()` to implement `Trait` + --> $DIR/double-cycle-inductive-coinductive.rs:9:34 + | +LL | impl Trait for T {} + | --------- ^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `Inductive` + --> $DIR/double-cycle-inductive-coinductive.rs:12:16 + | +LL | impl Inductive for T {} + | ----- ^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 7 redundant requirements hidden + = note: required for `()` to implement `Trait` note: required by a bound in `impls_trait` --> $DIR/double-cycle-inductive-coinductive.rs:17:19 | LL | fn impls_trait() {} | ^^^^^ required by this bound in `impls_trait` -error[E0275]: overflow evaluating the requirement `(): TraitRev` +error[E0275]: overflow evaluating the requirement `(): CoinductiveRev` --> $DIR/double-cycle-inductive-coinductive.rs:35:23 | LL | impls_trait_rev::<()>(); | ^^ | +note: required for `()` to implement `TraitRev` + --> $DIR/double-cycle-inductive-coinductive.rs:21:40 + | +LL | impl TraitRev for T {} + | -------------- ^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `CoinductiveRev` + --> $DIR/double-cycle-inductive-coinductive.rs:27:19 + | +LL | impl CoinductiveRev for T {} + | -------- ^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 7 redundant requirements hidden + = note: required for `()` to implement `TraitRev` note: required by a bound in `impls_trait_rev` --> $DIR/double-cycle-inductive-coinductive.rs:29:23 | diff --git a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr index a2a5c028cf8d5..ea46c0fea97b8 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.stderr @@ -1,9 +1,19 @@ -error[E0275]: overflow evaluating the requirement `W<_>: Trait` +error[E0275]: overflow evaluating the requirement `W>: Trait` --> $DIR/inductive-fixpoint-hang.rs:31:19 | LL | impls_trait::>(); | ^^^^ | +note: required for `W>>` to implement `Trait` + --> $DIR/inductive-fixpoint-hang.rs:22:17 + | +LL | impl Trait for W> + | ^^^^^ ^^^^^^^ +LL | where +LL | W: Trait, + | ----- unsatisfied trait bound introduced here + = note: 8 redundant requirements hidden + = note: required for `W>>>>>>>>>>` to implement `Trait` note: required by a bound in `impls_trait` --> $DIR/inductive-fixpoint-hang.rs:28:19 | diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs index 78683372580be..9d0ea51b1b25e 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs @@ -39,7 +39,7 @@ fn impls_ar() {} fn main() { impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` + //~^ ERROR overflow evaluating the requirement `(): B` impls_ar::<()>(); //~^ ERROR overflow evaluating the requirement `(): AR` diff --git a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr index e9cc6bc6c81ad..fe02d3c407cab 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-not-on-stack.stderr @@ -1,9 +1,25 @@ -error[E0275]: overflow evaluating the requirement `(): A` +error[E0275]: overflow evaluating the requirement `(): B` --> $DIR/inductive-not-on-stack.rs:41:15 | LL | impls_a::<()>(); | ^^ | +note: required for `()` to implement `A` + --> $DIR/inductive-not-on-stack.rs:21:16 + | +LL | impl A for T {} + | - ^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `B` + --> $DIR/inductive-not-on-stack.rs:22:12 + | +LL | impl B for T {} + | - ^ ^ + | | + | unsatisfied trait bound introduced here + = note: 7 redundant requirements hidden + = note: required for `()` to implement `A` note: required by a bound in `impls_a` --> $DIR/inductive-not-on-stack.rs:25:15 | @@ -16,6 +32,29 @@ error[E0275]: overflow evaluating the requirement `(): AR` LL | impls_ar::<()>(); | ^^ | +note: required for `()` to implement `BR` + --> $DIR/inductive-not-on-stack.rs:35:13 + | +LL | impl BR for T {} + | -- ^^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `CR` + --> $DIR/inductive-not-on-stack.rs:36:13 + | +LL | impl CR for T {} + | -- ^^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `AR` + --> $DIR/inductive-not-on-stack.rs:34:18 + | +LL | impl AR for T {} + | -- ^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 6 redundant requirements hidden + = note: required for `()` to implement `AR` note: required by a bound in `impls_ar` --> $DIR/inductive-not-on-stack.rs:38:16 | diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs index 6d75d24186430..b90a354be1b61 100644 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs +++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs @@ -35,5 +35,5 @@ fn impls_a() {} fn main() { impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` + //~^ ERROR overflow evaluating the requirement `(): CInd` } diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr index 17544eb1da528..03e61dbf99c22 100644 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr +++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-1.stderr @@ -1,9 +1,46 @@ -error[E0275]: overflow evaluating the requirement `(): A` +error[E0275]: overflow evaluating the requirement `(): CInd` --> $DIR/mixed-cycles-1.rs:37:15 | LL | impls_a::<()>(); | ^^ | +note: required for `()` to implement `B` + --> $DIR/mixed-cycles-1.rs:31:28 + | +LL | impl B for T {} + | ---- ^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `C` + --> $DIR/mixed-cycles-1.rs:32:25 + | +LL | impl C for T {} + | - ^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `CInd` + --> $DIR/mixed-cycles-1.rs:28:21 + | +LL | impl CInd for T {} + | - ^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 4 redundant requirements hidden + = note: required for `()` to implement `B` +note: required for `()` to implement `BInd` + --> $DIR/mixed-cycles-1.rs:23:21 + | +LL | impl BInd for T {} + | - ^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `A` + --> $DIR/mixed-cycles-1.rs:30:28 + | +LL | impl A for T {} + | ---- ^ ^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `impls_a` --> $DIR/mixed-cycles-1.rs:34:15 | diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs index c939a6e5ef2f7..a3ffcaafb3758 100644 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs +++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs @@ -28,5 +28,5 @@ fn impls_a() {} fn main() { impls_a::<()>(); - //~^ ERROR overflow evaluating the requirement `(): A` + //~^ ERROR overflow evaluating the requirement `(): BInd` } diff --git a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr index a9be1016c7412..892426abe82e6 100644 --- a/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr +++ b/tests/ui/traits/next-solver/cycles/mixed-cycles-2.stderr @@ -1,9 +1,32 @@ -error[E0275]: overflow evaluating the requirement `(): A` +error[E0275]: overflow evaluating the requirement `(): BInd` --> $DIR/mixed-cycles-2.rs:30:15 | LL | impls_a::<()>(); | ^^ | +note: required for `()` to implement `B` + --> $DIR/mixed-cycles-2.rs:25:24 + | +LL | impl B for T {} + | ---- ^ ^ + | | + | unsatisfied trait bound introduced here +note: required for `()` to implement `BInd` + --> $DIR/mixed-cycles-2.rs:22:21 + | +LL | impl BInd for T {} + | - ^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 6 redundant requirements hidden + = note: required for `()` to implement `BInd` +note: required for `()` to implement `A` + --> $DIR/mixed-cycles-2.rs:24:28 + | +LL | impl A for T {} + | ---- ^ ^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `impls_a` --> $DIR/mixed-cycles-2.rs:27:15 | diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs index ce7a380f07a6b..d11150ca55ae8 100644 --- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs +++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs @@ -25,7 +25,7 @@ fn foo() { // // https://github.com/rust-lang/trait-system-refactor-initiative/issues/76 require_bar::(); - //~^ ERROR the trait bound `T: Bar` is not satisfied + //~^ ERROR type mismatch resolving `::Assoc == i32` } fn main() {} diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr index 2785357e792de..3ef0afa38bff4 100644 --- a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr +++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr @@ -1,19 +1,25 @@ -error[E0277]: the trait bound `T: Bar` is not satisfied +error[E0271]: type mismatch resolving `::Assoc == i32` --> $DIR/param-candidate-shadows-project.rs:27:19 | LL | require_bar::(); - | ^ the trait `Bar` is not implemented for `T` + | ^ type mismatch resolving `::Assoc == i32` | +note: types differ + --> $DIR/param-candidate-shadows-project.rs:10:18 + | +LL | type Assoc = i32; + | ^^^ +note: required for `T` to implement `Bar` + --> $DIR/param-candidate-shadows-project.rs:13:9 + | +LL | impl Bar for T where T: Foo {} + | ^^^ ^ ----------- unsatisfied trait bound introduced here note: required by a bound in `require_bar` --> $DIR/param-candidate-shadows-project.rs:15:19 | LL | fn require_bar() {} | ^^^ required by this bound in `require_bar` -help: consider further restricting this bound - | -LL | fn foo() { - | +++++ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/more-object-bound.rs b/tests/ui/traits/next-solver/more-object-bound.rs index 511111af83f3d..3d3fdc926f658 100644 --- a/tests/ui/traits/next-solver/more-object-bound.rs +++ b/tests/ui/traits/next-solver/more-object-bound.rs @@ -10,7 +10,7 @@ trait Trait: SuperTrait::B> {} fn transmute(x: A) -> B { foo::>(x) - //~^ ERROR the trait bound `dyn Trait: Trait` is not satisfied + //~^ ERROR type mismatch resolving ` as SuperTrait>::A == B` } fn foo(x: T::A) -> B diff --git a/tests/ui/traits/next-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr index 1b776d7198ea4..8cc2a51ee2b6c 100644 --- a/tests/ui/traits/next-solver/more-object-bound.stderr +++ b/tests/ui/traits/next-solver/more-object-bound.stderr @@ -1,9 +1,10 @@ -error[E0277]: the trait bound `dyn Trait: Trait` is not satisfied +error[E0271]: type mismatch resolving ` as SuperTrait>::A == B` --> $DIR/more-object-bound.rs:12:5 | LL | foo::>(x) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ | + = note: required because it appears within the type `dyn Trait` note: required by a bound in `foo` --> $DIR/more-object-bound.rs:18:8 | @@ -12,11 +13,7 @@ LL | fn foo(x: T::A) -> B LL | where LL | T: Trait, | ^^^^^^^^^^^^ required by this bound in `foo` -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | fn transmute(x: A) -> B where dyn Trait: Trait { - | ++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs index 40d68dbaffdf0..12ea1bf142ab8 100644 --- a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs +++ b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs @@ -24,7 +24,7 @@ fn needs_bar() {} fn foo + Foo>() { needs_bar::(); - //~^ ERROR type annotations needed: cannot satisfy `T: Bar` + //~^ ERROR type annotations needed: cannot satisfy `::Assoc == i32` } fn main() {} diff --git a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr index dfff9f11b8756..21f3fbfeb872e 100644 --- a/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr +++ b/tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.stderr @@ -1,11 +1,14 @@ -error[E0283]: type annotations needed: cannot satisfy `T: Bar` +error[E0284]: type annotations needed: cannot satisfy `::Assoc == i32` --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17 | LL | needs_bar::(); - | ^ + | ^ cannot satisfy `::Assoc == i32` | - = note: cannot satisfy `T: Bar` - = help: the trait `Bar` is implemented for `T` +note: required for `T` to implement `Bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:21:9 + | +LL | impl Bar for T where T: Foo {} + | ^^^ ^ ----------- unsatisfied trait bound introduced here note: required by a bound in `needs_bar` --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 | @@ -14,4 +17,4 @@ LL | fn needs_bar() {} error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/object-unsafety.rs b/tests/ui/traits/next-solver/object-unsafety.rs index 4222607b5bfe4..3aa1af4956e22 100644 --- a/tests/ui/traits/next-solver/object-unsafety.rs +++ b/tests/ui/traits/next-solver/object-unsafety.rs @@ -11,9 +11,9 @@ fn copy(from: &U::From) -> U::From { pub fn copy_any(t: &T) -> T { copy::>(t) //~^ ERROR the type `& as Setup>::From` is not well-formed - //~| ERROR the trait bound `dyn Setup: Setup` is not satisfied //~| ERROR mismatched types //~| ERROR the type ` as Setup>::From` is not well-formed + //~| ERROR the trait bound `T: Copy` is not satisfied // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. diff --git a/tests/ui/traits/next-solver/object-unsafety.stderr b/tests/ui/traits/next-solver/object-unsafety.stderr index a9cbb721511ca..7c9a6077fe7fd 100644 --- a/tests/ui/traits/next-solver/object-unsafety.stderr +++ b/tests/ui/traits/next-solver/object-unsafety.stderr @@ -1,18 +1,19 @@ -error[E0277]: the trait bound `dyn Setup: Setup` is not satisfied +error[E0277]: the trait bound `T: Copy` is not satisfied in `dyn Setup` --> $DIR/object-unsafety.rs:12:12 | LL | copy::>(t) - | ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup` + | ^^^^^^^^^^^^^^^^^ within `dyn Setup`, the trait `Copy` is not implemented for `T`, which is required by `dyn Setup: Setup` | + = note: required because it appears within the type `dyn Setup` note: required by a bound in `copy` --> $DIR/object-unsafety.rs:7:12 | LL | fn copy(from: &U::From) -> U::From { | ^^^^^ required by this bound in `copy` -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement +help: consider restricting type parameter `T` | -LL | pub fn copy_any(t: &T) -> T where dyn Setup: Setup { - | ++++++++++++++++++++++++++++++++ +LL | pub fn copy_any(t: &T) -> T { + | +++++++++++++++++++ error: the type `& as Setup>::From` is not well-formed --> $DIR/object-unsafety.rs:12:31 diff --git a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs index 186d0e8be56e8..052d803765d3c 100644 --- a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs +++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs @@ -15,5 +15,5 @@ fn impls() {} fn main() { impls::>(); - //~^ ERROR overflow evaluating the requirement `W<_>: Trait` + //~^ ERROR overflow evaluating the requirement `_: Sized` } diff --git a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr index b032ae3e740db..6583cae8bb9c1 100644 --- a/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr +++ b/tests/ui/traits/next-solver/overflow/exponential-trait-goals.stderr @@ -1,9 +1,16 @@ -error[E0275]: overflow evaluating the requirement `W<_>: Trait` +error[E0275]: overflow evaluating the requirement `_: Sized` --> $DIR/exponential-trait-goals.rs:17:13 | LL | impls::>(); | ^^^^ | +note: required for `W<(W<_>, W<_>)>` to implement `Trait` + --> $DIR/exponential-trait-goals.rs:7:12 + | +LL | impl Trait for W<(W, W)> + | - ^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here note: required by a bound in `impls` --> $DIR/exponential-trait-goals.rs:14:13 | diff --git a/tests/ui/traits/next-solver/overflow/global-cache.stderr b/tests/ui/traits/next-solver/overflow/global-cache.stderr index 67616619384c6..9e467721e83e3 100644 --- a/tests/ui/traits/next-solver/overflow/global-cache.stderr +++ b/tests/ui/traits/next-solver/overflow/global-cache.stderr @@ -5,6 +5,15 @@ LL | impls_trait::>>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`) +note: required for `Inc>>>>>>>>>>` to implement `Trait` + --> $DIR/global-cache.rs:12:16 + | +LL | impl Trait for Inc {} + | ----- ^^^^^ ^^^^^^ + | | + | unsatisfied trait bound introduced here + = note: 5 redundant requirements hidden + = note: required for `Inc>>>>>>>>>>>>>>>` to implement `Trait` note: required by a bound in `impls_trait` --> $DIR/global-cache.rs:15:19 |