diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8f1ae594a9247..5f99d86b4eaff 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -7,7 +7,7 @@ use rustc_errors::{ }; use rustc_hir as hir; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; -use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; +use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_middle::mir::tcx::PlaceTy; @@ -601,7 +601,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` let infcx = tcx.infer_ctxt().build(); - let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); + let copy_did = infcx.tcx.require_lang_item(LangItem::Copy, Some(span)); let cause = ObligationCause::new( span, self.mir_hir_id(), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 2d4afd0dc356b..c62c665158779 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -1,7 +1,7 @@ //! Concrete error types for all operations which may be invalid in a certain const context. use hir::def_id::LocalDefId; -use hir::ConstContext; +use hir::{ConstContext, LangItem}; use rustc_errors::{ error_code, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, }; @@ -304,7 +304,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { err.span_note(deref_target, "deref defined here"); } - diag_trait(&mut err, self_ty, tcx.lang_items().deref_trait().unwrap()); + diag_trait(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, Some(span))); err } _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => { diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs index 5446ccb1a4730..b38a6c551388e 100644 --- a/compiler/rustc_const_eval/src/util/call_kind.rs +++ b/compiler/rustc_const_eval/src/util/call_kind.rs @@ -3,7 +3,7 @@ //! context. use rustc_hir::def_id::DefId; -use rustc_hir::lang_items; +use rustc_hir::{lang_items, LangItem}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AssocItemContainer, DefIdTree, Instance, ParamEnv, Ty, TyCtxt}; use rustc_span::symbol::Ident; @@ -26,7 +26,7 @@ impl CallDesugaringKind { match self { Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), Self::QuestionBranch | Self::TryBlockFromOutput => { - tcx.lang_items().try_trait().unwrap() + tcx.require_lang_item(LangItem::Try, None) } Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(), } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index b2c9e7389b047..11661215ae1cc 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -114,7 +114,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { traits::ObligationCause::dummy_with_span(field_ty_span), param_env, ty, - tcx.lang_items().copy_trait().unwrap(), + tcx.require_lang_item(LangItem::Copy, Some(span)), ) { let error_predicate = error.obligation.predicate; // Only note if it's not the root obligation, otherwise it's trivial and diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 886a3ad755df9..91f65b8c0f21f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1118,7 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let lhs_deref_ty_is_sized = self .infcx .type_implements_trait( - self.tcx.lang_items().sized_trait().unwrap(), + self.tcx.require_lang_item(LangItem::Sized, None), [lhs_deref_ty], self.param_env, ) diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 0d6c26a582246..273a61c966c72 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -5,6 +5,7 @@ use crate::{mir, ty}; use std::fmt::Write; +use hir::LangItem; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -130,11 +131,14 @@ impl<'tcx> ClosureKind { } pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId { - match self { - ClosureKind::Fn => tcx.lang_items().fn_once_trait().unwrap(), - ClosureKind::FnMut => tcx.lang_items().fn_mut_trait().unwrap(), - ClosureKind::FnOnce => tcx.lang_items().fn_trait().unwrap(), - } + tcx.require_lang_item( + match self { + ClosureKind::Fn => LangItem::Fn, + ClosureKind::FnMut => LangItem::FnMut, + ClosureKind::FnOnce => LangItem::FnOnce, + }, + None, + ) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8d6ae14231457..26d30308ed371 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2293,7 +2293,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given a `ty`, return whether it's an `impl Future<...>`. pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { let ty::Opaque(def_id, _) = ty.kind() else { return false }; - let future_trait = self.lang_items().future_trait().unwrap(); + let future_trait = self.require_lang_item(LangItem::Future, None); self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d828d08805ec3..9c7721bf49a8a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -11,6 +11,7 @@ use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; +use rustc_hir::LangItem; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_session::Limit; @@ -889,7 +890,7 @@ pub trait PrettyPrinter<'tcx>: // Group the return ty with its def id, if we had one. entry .return_ty - .map(|ty| (tcx.lang_items().fn_once_output().unwrap(), ty)), + .map(|ty| (tcx.require_lang_item(LangItem::FnOnce, None), ty)), ); } if let Some(trait_ref) = entry.fn_mut_trait_ref { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index db18558e947a3..e7a751fa0afca 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -17,6 +17,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; @@ -2108,7 +2109,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(..) => { - let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap(); + let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); (tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) }, diff --git a/compiler/rustc_target/src/spec/aix_base.rs b/compiler/rustc_target/src/spec/aix_base.rs new file mode 100644 index 0000000000000..c71c4ba2cc902 --- /dev/null +++ b/compiler/rustc_target/src/spec/aix_base.rs @@ -0,0 +1,32 @@ +use crate::abi::Endian; +use crate::spec::{crt_objects, cvs, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions}; + +pub fn opts() -> TargetOptions { + TargetOptions { + abi: "vec-extabi".into(), + code_model: Some(CodeModel::Small), + cpu: "pwr7".into(), + os: "aix".into(), + vendor: "ibm".into(), + dynamic_linking: true, + endian: Endian::Big, + executables: true, + archive_format: "aix_big".into(), + families: cvs!["unix"], + has_rpath: false, + has_thread_local: true, + crt_static_respected: true, + linker_flavor: LinkerFlavor::Unix(Cc::No), + linker: Some("ld".into()), + eh_frame_header: false, + is_like_aix: true, + default_dwarf_version: 3, + function_sections: true, + pre_link_objects: crt_objects::new(&[ + (LinkOutputKind::DynamicNoPicExe, &["/usr/lib/crt0_64.o", "/usr/lib/crti_64.o"]), + (LinkOutputKind::DynamicPicExe, &["/usr/lib/crt0_64.o", "/usr/lib/crti_64.o"]), + ]), + dll_suffix: ".a".into(), + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 6d936d2cb9ff0..c633ef1e76193 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -58,6 +58,7 @@ use rustc_macros::HashStable_Generic; pub mod abi; pub mod crt_objects; +mod aix_base; mod android_base; mod apple_base; mod avr_gnu_base; @@ -1027,6 +1028,7 @@ supported_targets! { ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), ("powerpc-unknown-linux-musl", powerpc_unknown_linux_musl), + ("powerpc64-ibm-aix", powerpc64_ibm_aix), ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu), ("powerpc64-unknown-linux-musl", powerpc64_unknown_linux_musl), ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), @@ -1454,6 +1456,9 @@ pub struct TargetOptions { pub families: StaticCow<[StaticCow]>, /// Whether the target toolchain's ABI supports returning small structs as an integer. pub abi_return_struct_as_int: bool, + /// Whether the target toolchain is like AIX's. Linker options on AIX are special and it uses + /// XCOFF as binary format. Defaults to false. + pub is_like_aix: bool, /// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS, /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false. /// Also indiates whether to use Apple-specific ABI changes, such as extending function @@ -1817,6 +1822,7 @@ impl Default for TargetOptions { staticlib_suffix: ".a".into(), families: cvs![], abi_return_struct_as_int: false, + is_like_aix: false, is_like_osx: false, is_like_solaris: false, is_like_windows: false, @@ -2488,6 +2494,7 @@ impl Target { key!(staticlib_suffix); key!(families, TargetFamilies); key!(abi_return_struct_as_int, bool); + key!(is_like_aix, bool); key!(is_like_osx, bool); key!(is_like_solaris, bool); key!(is_like_windows, bool); @@ -2741,6 +2748,7 @@ impl ToJson for Target { target_option_val!(staticlib_suffix); target_option_val!(families, "target-family"); target_option_val!(abi_return_struct_as_int); + target_option_val!(is_like_aix); target_option_val!(is_like_osx); target_option_val!(is_like_solaris); target_option_val!(is_like_windows); diff --git a/compiler/rustc_target/src/spec/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/powerpc64_ibm_aix.rs new file mode 100644 index 0000000000000..e3eb9bccd5ed7 --- /dev/null +++ b/compiler/rustc_target/src/spec/powerpc64_ibm_aix.rs @@ -0,0 +1,23 @@ +use crate::spec::{Cc, LinkerFlavor, Target}; + +pub fn target() -> Target { + let mut base = super::aix_base::opts(); + base.max_atomic_width = Some(64); + base.add_pre_link_args( + LinkerFlavor::Unix(Cc::No), + &[ + "-b64".into(), + "-bpT:0x100000000".into(), + "-bpD:0x110000000".into(), + "-bcdtors:all:0:s".into(), + ], + ); + + Target { + llvm_target: "powerpc64-ibm-aix".into(), + pointer_width: 64, + data_layout: "E-m:a-i64:64-n32:64-S128-v256:256:256-v512:512:512".into(), + arch: "powerpc64".into(), + options: base, + } +} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 8086cac0d551a..186109e7075f1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2625,7 +2625,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } }; - let from_generator = tcx.lang_items().from_generator_fn().unwrap(); + let from_generator = tcx.require_lang_item(LangItem::FromGenerator, None); // Don't print the tuple of capture types 'print: { diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 5d267891bb0ed..154b608c0dc5c 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -181,7 +181,8 @@ macro_rules! thread_local { macro_rules! __thread_local_inner { // used to generate the `LocalKey` value for const-initialized thread locals (@key $t:ty, const $init:expr) => {{ - #[cfg_attr(not(windows), inline)] // see comments below + #[cfg_attr(not(all(windows, target_thread_local)), inline)] // see comments below + #[cfg_attr(all(windows, target_thread_local), inline(never))] #[deny(unsafe_op_in_unsafe_fn)] unsafe fn __getit( _init: $crate::option::Option<&mut $crate::option::Option<$t>>, @@ -294,12 +295,17 @@ macro_rules! __thread_local_inner { fn __init() -> $t { $init } // When reading this function you might ask "why is this inlined - // everywhere other than Windows?", and that's a very reasonable - // question to ask. The short story is that it segfaults rustc if - // this function is inlined. The longer story is that Windows looks - // to not support `extern` references to thread locals across DLL - // boundaries. This appears to at least not be supported in the ABI - // that LLVM implements. + // everywhere other than Windows?", and "why must it not be inlined + // on Windows?" and these are very reasonable questions to ask. + // + // The short story is that Windows doesn't support referencing + // `#[thread_local]` across DLL boundaries. The slightly longer + // story is that each module (dll or exe) has its own separate set + // of static thread locals, so if you try and reference a + // `#[thread_local]` that comes from `crate1.dll` from within one of + // `crate2.dll`'s functions, then it might give you a completely + // different thread local than what you asked for (or it might just + // crash). // // Because of this we never inline on Windows, but we do inline on // other platforms (where external references to thread locals @@ -314,8 +320,9 @@ macro_rules! __thread_local_inner { // Cargo question kinda). This means that, unfortunately, Windows // gets the pessimistic path for now where it's never inlined. // - // The issue of "should enable on Windows sometimes" is #84933 - #[cfg_attr(not(windows), inline)] + // The issue of "should improve things on Windows" is #84933 + #[cfg_attr(not(all(windows, target_thread_local)), inline)] + #[cfg_attr(all(windows, target_thread_local), inline(never))] unsafe fn __getit( init: $crate::option::Option<&mut $crate::option::Option<$t>>, ) -> $crate::option::Option<&'static $t> { diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 28929acb9b48d..27e911c6be5a2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -283,6 +283,7 @@ target | std | host | notes `powerpc64-wrs-vxworks` | ? | | `powerpc64le-unknown-linux-musl` | ? | | [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 +`powerpc64-ibm-aix` | ? | | 64-bit AIX (7.2 and newer) `riscv32gc-unknown-linux-gnu` | | | RISC-V Linux (kernel 5.4, glibc 2.33) `riscv32gc-unknown-linux-musl` | | | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches) `riscv32im-unknown-none-elf` | * | | Bare RISC-V (RV32IM ISA) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 2335f3ff1ce96..d4e881ad832af 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -932,7 +932,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ right: var(--popover-arrow-offset); border: solid var(--border-color); border-width: 1px 1px 0 0; - display: inline-block; padding: 4px; transform: rotate(-45deg); top: -5px; @@ -1200,7 +1199,6 @@ pre.rust .doccomment { } a.test-arrow { - display: inline-block; visibility: hidden; position: absolute; padding: 5px 10px 5px 10px; diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr index 6c0dc05ba2330..29ececea5d394 100644 --- a/src/test/ui/check-cfg/well-known-values.stderr +++ b/src/test/ui/check-cfg/well-known-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")] | | | help: did you mean: `"linux"` | - = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous + = note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value diff --git a/src/test/ui/const-generics/projection-as-arg-const.rs b/src/test/ui/const-generics/projection-as-arg-const.rs new file mode 100644 index 0000000000000..903548c75db56 --- /dev/null +++ b/src/test/ui/const-generics/projection-as-arg-const.rs @@ -0,0 +1,20 @@ +// This is currently not possible to use projections as const generics. +// More information about this available here: +// https://github.com/rust-lang/rust/pull/104443#discussion_r1029375633 + +pub trait Identity { + type Identity; +} + +impl Identity for T { + type Identity = Self; +} + +pub fn foo::Identity>() { +//~^ ERROR + assert!(X == 12); +} + +fn main() { + foo::<12>(); +} diff --git a/src/test/ui/const-generics/projection-as-arg-const.stderr b/src/test/ui/const-generics/projection-as-arg-const.stderr new file mode 100644 index 0000000000000..803ed9c959752 --- /dev/null +++ b/src/test/ui/const-generics/projection-as-arg-const.stderr @@ -0,0 +1,11 @@ +error: `::Identity` is forbidden as the type of a const generic parameter + --> $DIR/projection-as-arg-const.rs:13:21 + | +LL | pub fn foo::Identity>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: more complex types are supported with `#![feature(adt_const_params)]` + +error: aborting due to previous error + diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs index 902a6ec81d60b..232cd2ba88cc2 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs @@ -20,14 +20,23 @@ impl FnOnce<(isize,)> for S { } } +struct F; + +impl FnOnce<(i32,)> for F { + type Output = (); + + extern "rust-call" fn call_once(self, args: (i32,)) -> Self::Output {} +} + fn main() { - let mut s = S { - x: 3, - y: 3, - }; - let ans = s("what"); //~ ERROR mismatched types + let mut s = S { x: 3, y: 3 }; + let ans = s("what"); + //~^ ERROR mismatched types let ans = s(); //~^ ERROR this function takes 1 argument but 0 arguments were supplied let ans = s("burma", "shave"); //~^ ERROR this function takes 1 argument but 2 arguments were supplied + + F(""); + //~^ ERROR mismatched types } diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr index fb3597aa85300..3a895acbdb5dd 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/overloaded-calls-bad.rs:28:17 + --> $DIR/overloaded-calls-bad.rs:33:17 | LL | let ans = s("what"); | - ^^^^^^ expected `isize`, found `&str` @@ -13,7 +13,7 @@ LL | impl FnMut<(isize,)> for S { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0057]: this function takes 1 argument but 0 arguments were supplied - --> $DIR/overloaded-calls-bad.rs:29:15 + --> $DIR/overloaded-calls-bad.rs:35:15 | LL | let ans = s(); | ^-- an argument of type `isize` is missing @@ -29,7 +29,7 @@ LL | let ans = s(/* isize */); | ~~~~~~~~~~~~~ error[E0057]: this function takes 1 argument but 2 arguments were supplied - --> $DIR/overloaded-calls-bad.rs:31:15 + --> $DIR/overloaded-calls-bad.rs:37:15 | LL | let ans = s("burma", "shave"); | ^ ------- ------- argument of type `&'static str` unexpected @@ -46,7 +46,21 @@ help: remove the extra argument LL | let ans = s(/* isize */); | ~~~~~~~~~~~~~ -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/overloaded-calls-bad.rs:40:7 + | +LL | F(""); + | - ^^ expected `i32`, found `&str` + | | + | arguments to this struct are incorrect + | +note: implementation defined here + --> $DIR/overloaded-calls-bad.rs:25:1 + | +LL | impl FnOnce<(i32,)> for F { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0057, E0308. For more information about an error, try `rustc --explain E0057`. diff --git a/src/test/ui/threads-sendsync/mpsc_stress.rs b/src/test/ui/threads-sendsync/mpsc_stress.rs index a889542fec0be..c2e1912deb7aa 100644 --- a/src/test/ui/threads-sendsync/mpsc_stress.rs +++ b/src/test/ui/threads-sendsync/mpsc_stress.rs @@ -64,9 +64,11 @@ fn shared_close_sender_does_not_lose_messages_iter() { #[test] fn shared_close_sender_does_not_lose_messages() { - for _ in 0..10000 { - shared_close_sender_does_not_lose_messages_iter(); - } + with_minimum_timer_resolution(|| { + for _ in 0..10000 { + shared_close_sender_does_not_lose_messages_iter(); + } + }); } @@ -96,17 +98,11 @@ fn concurrent_recv_timeout_and_upgrade_iter() { #[test] fn concurrent_recv_timeout_and_upgrade() { - // FIXME: fix and enable - if true { return } - - // at the moment of writing this test fails like this: - // thread '' panicked at 'assertion failed: `(left == right)` - // left: `4561387584`, - // right: `0`', libstd/sync/mpsc/shared.rs:253:13 - - for _ in 0..10000 { - concurrent_recv_timeout_and_upgrade_iter(); - } + with_minimum_timer_resolution(|| { + for _ in 0..10000 { + concurrent_recv_timeout_and_upgrade_iter(); + } + }); } @@ -159,7 +155,46 @@ fn concurrent_writes_iter() { #[test] fn concurrent_writes() { - for _ in 0..100 { - concurrent_writes_iter(); + with_minimum_timer_resolution(|| { + for _ in 0..100 { + concurrent_writes_iter(); + } + }); +} + +#[cfg(windows)] +pub mod timeapi { + #![allow(non_snake_case)] + use std::ffi::c_uint; + + pub const TIMERR_NOERROR: c_uint = 0; + + #[link(name = "winmm")] + extern "system" { + pub fn timeBeginPeriod(uPeriod: c_uint) -> c_uint; + pub fn timeEndPeriod(uPeriod: c_uint) -> c_uint; + } +} + +/// Window's minimum sleep time can be as much as 16ms. +// This function evaluates the closure with this resolution +// set as low as possible. +/// +/// This takes the above test's duration from 10000*16/1000/60=2.67 minutes to ~16 seconds. +fn with_minimum_timer_resolution(f: impl Fn()) { + #[cfg(windows)] + unsafe { + let ret = timeapi::timeBeginPeriod(1); + assert_eq!(ret, timeapi::TIMERR_NOERROR); + + f(); + + let ret = timeapi::timeEndPeriod(1); + assert_eq!(ret, timeapi::TIMERR_NOERROR); + } + + #[cfg(not(windows))] + { + f(); } }