diff --git a/Cargo.lock b/Cargo.lock index be704e84a508c..60daa453c60dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3757,7 +3757,6 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", - "rustc_target", "rustc_trait_selection", "smallvec", "tracing", @@ -3796,6 +3795,7 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", + "rustc_target", "rustc_trait_selection", "smallvec", "tracing", diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 79cefb05de322..5561a01f35a19 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -65,7 +65,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, let ty = tcx.typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => Instance::expect_resolve( + tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + expr.span, + ), _ => span_bug!(op_sp, "asm sym is not a function"), }; let symbol = tcx.symbol_name(instance); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index d3f47ad726334..e866b8962551a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1282,7 +1282,7 @@ fn codegen_regular_intrinsic_call<'tcx>( intrinsic.name, ); } - return Err(Instance::new(instance.def_id(), instance.args)); + return Err(Instance::new_raw(instance.def_id(), instance.args)); } } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 9d9e790289cf6..ab09a6f8b38e1 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -41,8 +41,8 @@ use std::sync::Arc; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::{self, Configurable}; -use rustc_codegen_ssa::CodegenResults; use rustc_codegen_ssa::traits::CodegenBackend; +use rustc_codegen_ssa::{CodegenResults, TargetConfig}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; @@ -178,7 +178,7 @@ impl CodegenBackend for CraneliftCodegenBackend { } } - fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { + fn target_config(&self, sess: &Session) -> TargetConfig { // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" { // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled @@ -197,7 +197,16 @@ impl CodegenBackend for CraneliftCodegenBackend { }; // FIXME do `unstable_target_features` properly let unstable_target_features = target_features.clone(); - (target_features, unstable_target_features) + + TargetConfig { + target_features, + unstable_target_features, + // Cranelift does not yet support f16 or f128 + has_reliable_f16: false, + has_reliable_f16_math: false, + has_reliable_f128: false, + has_reliable_f128_math: false, + } } fn print_version(&self) { diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 955f902023573..2b053abdd190a 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -55,7 +55,7 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec. all_rust_features.push((false, feature)); } else if !feature.is_empty() && diagnostics { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index d22f4229e2374..2ed5ec4381edf 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -399,7 +399,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } // Fall back to default body - _ => return Err(Instance::new(instance.def_id(), instance.args)), + _ => return Err(Instance::new_raw(instance.def_id(), instance.args)), }; if !fn_abi.ret.is_ignore() { diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 555f164e53fd6..2c5a787168381 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -102,7 +102,7 @@ use rustc_codegen_ssa::back::write::{ }; use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::DiagCtxtHandle; @@ -260,8 +260,8 @@ impl CodegenBackend for GccCodegenBackend { .join(sess) } - fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { - target_features_cfg(sess, &self.target_info) + fn target_config(&self, sess: &Session) -> TargetConfig { + target_config(sess, &self.target_info) } } @@ -485,10 +485,7 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { } /// Returns the features that should be set in `cfg(target_feature)`. -fn target_features_cfg( - sess: &Session, - target_info: &LockedTargetInfo, -) -> (Vec, Vec) { +fn target_config(sess: &Session, target_info: &LockedTargetInfo) -> TargetConfig { // TODO(antoyo): use global_gcc_features. let f = |allow_unstable| { sess.target @@ -523,5 +520,14 @@ fn target_features_cfg( let target_features = f(false); let unstable_target_features = f(true); - (target_features, unstable_target_features) + + TargetConfig { + target_features, + unstable_target_features, + // There are no known bugs with GCC support for f16 or f128 + has_reliable_f16: true, + has_reliable_f16_math: true, + has_reliable_f128: true, + has_reliable_f128_math: true, + } } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index e8c42d16733ec..176fb72dfdc5e 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,5 +1,4 @@ //! Set and unset common attributes on LLVM values. - use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; @@ -28,6 +27,22 @@ pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[ } } +pub(crate) fn has_attr(llfn: &Value, idx: AttributePlace, attr: AttributeKind) -> bool { + llvm::HasAttributeAtIndex(llfn, idx, attr) +} + +pub(crate) fn has_string_attr(llfn: &Value, name: &str) -> bool { + llvm::HasStringAttribute(llfn, name) +} + +pub(crate) fn remove_from_llfn(llfn: &Value, place: AttributePlace, kind: AttributeKind) { + llvm::RemoveRustEnumAttributeAtIndex(llfn, place, kind); +} + +pub(crate) fn remove_string_attr_from_llfn(llfn: &Value, name: &str) { + llvm::RemoveStringAttrFromFn(llfn, name); +} + /// Get LLVM attribute for the provided inline heuristic. #[inline] fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll Attribute> { diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 925898d817371..39b3a23e0b1b0 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -28,8 +28,9 @@ use crate::back::write::{ use crate::errors::{ DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib, LtoProcMacro, }; +use crate::llvm::AttributePlace::Function; use crate::llvm::{self, build_string}; -use crate::{LlvmCodegenBackend, ModuleLlvm}; +use crate::{LlvmCodegenBackend, ModuleLlvm, SimpleCx, attributes}; /// We keep track of the computed LTO cache keys from the previous /// session to determine which CGUs we can reuse. @@ -666,6 +667,31 @@ pub(crate) fn run_pass_manager( } if cfg!(llvm_enzyme) && enable_ad && !thin { + let cx = + SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size); + + for function in cx.get_functions() { + let enzyme_marker = "enzyme_marker"; + if attributes::has_string_attr(function, enzyme_marker) { + // Sanity check: Ensure 'noinline' is present before replacing it. + assert!( + !attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), + "Expected __enzyme function to have 'noinline' before adding 'alwaysinline'" + ); + + attributes::remove_from_llfn(function, Function, llvm::AttributeKind::NoInline); + attributes::remove_string_attr_from_llfn(function, enzyme_marker); + + assert!( + !attributes::has_string_attr(function, enzyme_marker), + "Expected function to not have 'enzyme_marker'" + ); + + let always_inline = llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx); + attributes::apply_to_llfn(function, Function, &[always_inline]); + } + } + let opt_stage = llvm::OptStage::FatLTO; let stage = write::AutodiffStage::PostAD; if !config.autodiff.contains(&config::AutoDiff::NoPostopt) { diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 0147bd5a66581..c5c13ac097a27 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -361,6 +361,11 @@ fn generate_enzyme_call<'ll>( let attr = llvm::AttributeKind::NoInline.create_attr(cx.llcx); attributes::apply_to_llfn(ad_fn, Function, &[attr]); + // We add a made-up attribute just such that we can recognize it after AD to update + // (no)-inline attributes. We'll then also remove this attribute. + let enzyme_marker_attr = llvm::CreateAttrString(cx.llcx, "enzyme_marker"); + attributes::apply_to_llfn(outer_fn, Function, &[enzyme_marker_attr]); + // first, remove all calls from fnc let entry = llvm::LLVMGetFirstBasicBlock(outer_fn); let br = llvm::LLVMRustGetTerminator(entry); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 4ec6999551898..ed50515b70716 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -698,6 +698,16 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { llvm::LLVMMDStringInContext2(self.llcx(), name.as_ptr() as *const c_char, name.len()) }) } + + pub(crate) fn get_functions(&self) -> Vec<&'ll Value> { + let mut functions = vec![]; + let mut func = unsafe { llvm::LLVMGetFirstFunction(self.llmod()) }; + while let Some(f) = func { + functions.push(f); + func = unsafe { llvm::LLVMGetNextFunction(f) } + } + functions + } } impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs index 68f60f169b5b5..fe3a7a1580b53 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/unused.rs @@ -157,7 +157,7 @@ fn make_dummy_instance<'tcx>(tcx: TyCtxt<'tcx>, local_def_id: LocalDefId) -> ty: let def_id = local_def_id.to_def_id(); // Make a dummy instance that fills in all generics with placeholders. - ty::Instance::new( + ty::Instance::new_raw( def_id, ty::GenericArgs::for_item(tcx, def_id, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index ffeab59b05c32..bfaad8f2f1ef0 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -613,7 +613,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { _ => { debug!("unknown intrinsic '{}' -- falling back to default body", name); // Call the fallback body instead of generating the intrinsic code - return Err(ty::Instance::new(instance.def_id(), instance.args)); + return Err(ty::Instance::new_raw(instance.def_id(), instance.args)); } }; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index b2feeacdb4664..e8010ec9fc495 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -29,7 +29,7 @@ use back::owned_target_machine::OwnedTargetMachine; use back::write::{create_informational_target_machine, create_target_machine}; use context::SimpleCx; use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig}; -use llvm_util::target_features_cfg; +use llvm_util::target_config; use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; @@ -37,7 +37,7 @@ use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{DiagCtxtHandle, FatalError}; use rustc_metadata::EncodedMetadata; @@ -338,8 +338,8 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::print_version(); } - fn target_features_cfg(&self, sess: &Session) -> (Vec, Vec) { - target_features_cfg(sess) + fn target_config(&self, sess: &Session) -> TargetConfig { + target_config(sess) } fn codegen_crate<'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index a9b3bdf7344be..2ad39fc853819 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -19,6 +19,19 @@ unsafe extern "C" { pub(crate) fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool; pub(crate) fn LLVMRustHasAttributeAtIndex(V: &Value, i: c_uint, Kind: AttributeKind) -> bool; pub(crate) fn LLVMRustGetArrayNumElements(Ty: &Type) -> u64; + pub(crate) fn LLVMRustHasFnAttribute( + F: &Value, + Name: *const c_char, + NameLen: libc::size_t, + ) -> bool; + pub(crate) fn LLVMRustRemoveFnAttribute(F: &Value, Name: *const c_char, NameLen: libc::size_t); + pub(crate) fn LLVMGetFirstFunction(M: &Module) -> Option<&Value>; + pub(crate) fn LLVMGetNextFunction(Fn: &Value) -> Option<&Value>; + pub(crate) fn LLVMRustRemoveEnumAttributeAtIndex( + Fn: &Value, + index: c_uint, + kind: AttributeKind, + ); } unsafe extern "C" { diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 6ca81c651ed42..d14aab060731a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -41,6 +41,32 @@ pub(crate) fn AddFunctionAttributes<'ll>( } } +pub(crate) fn HasAttributeAtIndex<'ll>( + llfn: &'ll Value, + idx: AttributePlace, + kind: AttributeKind, +) -> bool { + unsafe { LLVMRustHasAttributeAtIndex(llfn, idx.as_uint(), kind) } +} + +pub(crate) fn HasStringAttribute<'ll>(llfn: &'ll Value, name: &str) -> bool { + unsafe { LLVMRustHasFnAttribute(llfn, name.as_c_char_ptr(), name.len()) } +} + +pub(crate) fn RemoveStringAttrFromFn<'ll>(llfn: &'ll Value, name: &str) { + unsafe { LLVMRustRemoveFnAttribute(llfn, name.as_c_char_ptr(), name.len()) } +} + +pub(crate) fn RemoveRustEnumAttributeAtIndex( + llfn: &Value, + place: AttributePlace, + kind: AttributeKind, +) { + unsafe { + LLVMRustRemoveEnumAttributeAtIndex(llfn, place.as_uint(), kind); + } +} + pub(crate) fn AddCallSiteAttributes<'ll>( callsite: &'ll Value, idx: AttributePlace, diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 36e35f81392bc..ae1bdac1655d3 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -6,6 +6,7 @@ use std::sync::Once; use std::{ptr, slice, str}; use libc::c_int; +use rustc_codegen_ssa::TargetConfig; use rustc_codegen_ssa::base::wants_wasm_eh; use rustc_codegen_ssa::codegen_attrs::check_tied_features; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -302,7 +303,7 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option (Vec, Vec) { +pub(crate) fn target_config(sess: &Session) -> TargetConfig { // Add base features for the target. // We do *not* add the -Ctarget-features there, and instead duplicate the logic for that below. // The reason is that if LLVM considers a feature implied but we do not, we don't want that to @@ -402,7 +403,89 @@ pub(crate) fn target_features_cfg(sess: &Session) -> (Vec, Vec) let target_features = f(false); let unstable_target_features = f(true); - (target_features, unstable_target_features) + let mut cfg = TargetConfig { + target_features, + unstable_target_features, + has_reliable_f16: true, + has_reliable_f16_math: true, + has_reliable_f128: true, + has_reliable_f128_math: true, + }; + + update_target_reliable_float_cfg(sess, &mut cfg); + cfg +} + +/// Determine whether or not experimental float types are reliable based on known bugs. +fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { + let target_arch = sess.target.arch.as_ref(); + let target_os = sess.target.options.os.as_ref(); + let target_env = sess.target.options.env.as_ref(); + let target_abi = sess.target.options.abi.as_ref(); + let target_pointer_width = sess.target.pointer_width; + + cfg.has_reliable_f16 = match (target_arch, target_os) { + // Selection failure + ("s390x", _) => false, + // Unsupported + ("arm64ec", _) => false, + // MinGW ABI bugs + ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, + // Infinite recursion + ("csky", _) => false, + ("hexagon", _) => false, + ("powerpc" | "powerpc64", _) => false, + ("sparc" | "sparc64", _) => false, + ("wasm32" | "wasm64", _) => false, + // `f16` support only requires that symbols converting to and from `f32` are available. We + // provide these in `compiler-builtins`, so `f16` should be available on all platforms that + // do not have other ABI issues or LLVM crashes. + _ => true, + }; + + cfg.has_reliable_f128 = match (target_arch, target_os) { + // Unsupported + ("arm64ec", _) => false, + // Selection bug + ("mips64" | "mips64r6", _) => false, + // Selection bug + ("nvptx64", _) => false, + // ABI bugs et al. (full + // list at ) + ("powerpc" | "powerpc64", _) => false, + // ABI unsupported + ("sparc", _) => false, + // Stack alignment bug . NB: tests may + // not fail if our compiler-builtins is linked. + ("x86", _) => false, + // MinGW ABI bugs + ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, + // There are no known problems on other platforms, so the only requirement is that symbols + // are available. `compiler-builtins` provides all symbols required for core `f128` + // support, so this should work for everything else. + _ => true, + }; + + cfg.has_reliable_f16_math = match (target_arch, target_os) { + // x86 has a crash for `powi`: + ("x86" | "x86_64", _) => false, + // Assume that working `f16` means working `f16` math for most platforms, since + // operations just go through `f32`. + _ => true, + } && cfg.has_reliable_f16; + + cfg.has_reliable_f128_math = match (target_arch, target_os) { + // LLVM lowers `fp128` math to `long double` symbols even on platforms where + // `long double` is not IEEE binary128. See + // . + // + // This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits + // (ld is `f64`), anything other than Linux (Windows and MacOS use `f64`), and `x86` + // (ld is 80-bit extended precision). + ("x86_64", _) => false, + (_, "linux") if target_pointer_width == 64 => true, + _ => false, + } && cfg.has_reliable_f128; } pub(crate) fn print_version() { @@ -686,7 +769,7 @@ pub(crate) fn global_llvm_features( ) } else if let Some(feature) = feature.strip_prefix('-') { // FIXME: Why do we not remove implied features on "-" here? - // We do the equivalent above in `target_features_cfg`. + // We do the equivalent above in `target_config`. // See . all_rust_features.push((false, feature)); } else if !feature.is_empty() { diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index b89ce90d1a1dc..169036f515298 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -128,6 +128,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { (**self).borrow().llcx } + pub(crate) fn llmod(&self) -> &'ll llvm::Module { + (**self).borrow().llmod + } + pub(crate) fn isize_ty(&self) -> &'ll Type { (**self).borrow().isize_ty } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 2bfab1f43bce3..175474186ea1b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -565,7 +565,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>( ExportedSymbol::Generic(def_id, args) => { rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, - Instance::new(def_id, args), + Instance::new_raw(def_id, args), instantiating_crate, ) } @@ -613,7 +613,7 @@ fn calling_convention_for_symbol<'tcx>( None } ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)), - ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)), + ExportedSymbol::Generic(def_id, args) => Some(Instance::new_raw(def_id, args)), // DropGlue always use the Rust calling convention and thus follow the target's default // symbol decoration scheme. ExportedSymbol::DropGlue(..) => None, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index c927aae2c4c2b..b67c871cac9fe 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -235,6 +235,24 @@ pub struct CrateInfo { pub lint_levels: CodegenLintLevels, } +/// Target-specific options that get set in `cfg(...)`. +/// +/// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen. +pub struct TargetConfig { + /// Options to be set in `cfg(target_features)`. + pub target_features: Vec, + /// Options to be set in `cfg(target_features)`, but including unstable features. + pub unstable_target_features: Vec, + /// Option for `cfg(target_has_reliable_f16)`, true if `f16` basic arithmetic works. + pub has_reliable_f16: bool, + /// Option for `cfg(target_has_reliable_f16_math)`, true if `f16` math calls work. + pub has_reliable_f16_math: bool, + /// Option for `cfg(target_has_reliable_f128)`, true if `f128` basic arithmetic works. + pub has_reliable_f128: bool, + /// Option for `cfg(target_has_reliable_f128_math)`, true if `f128` math calls work. + pub has_reliable_f128_math: bool, +} + #[derive(Encodable, Decodable)] pub struct CodegenResults { pub modules: Vec, diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 3a6b1f8d4efc9..c061795c913aa 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -86,7 +86,9 @@ fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ); let instance = match mono_type.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => { + Instance::expect_resolve(cx.tcx(), cx.typing_env(), def_id, args, value.span) + } _ => bug!("asm sym is not a function"), }; diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index f6af889fd6ecb..11e7b202a47c9 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -74,7 +74,13 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { hir::InlineAsmOperand::SymFn { expr } => { let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { - &ty::FnDef(def_id, args) => Instance::new(def_id, args), + &ty::FnDef(def_id, args) => Instance::expect_resolve( + cx.tcx(), + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + expr.span, + ), _ => span_bug!(*op_sp, "asm sym is not a function"), }; diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 65fd843e7a59e..e6b50cc7c0cbf 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -18,7 +18,7 @@ use super::write::WriteBackendMethods; use crate::back::archive::ArArchiveBuilderBuilder; use crate::back::link::link_binary; use crate::back::write::TargetMachineFactoryFn; -use crate::{CodegenResults, ModuleCodegen}; +use crate::{CodegenResults, ModuleCodegen, TargetConfig}; pub trait BackendTypes { type Value: CodegenObject; @@ -50,8 +50,15 @@ pub trait CodegenBackend { /// - The second is like the first, but also includes unstable features. /// /// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen. - fn target_features_cfg(&self, _sess: &Session) -> (Vec, Vec) { - (vec![], vec![]) + fn target_config(&self, _sess: &Session) -> TargetConfig { + TargetConfig { + target_features: vec![], + unstable_target_features: vec![], + has_reliable_f16: true, + has_reliable_f16_math: true, + has_reliable_f128: true, + has_reliable_f128_math: true, + } } fn print_passes(&self) {} diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 43ba67e7dc63b..a5e6b1c00d693 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -40,6 +40,26 @@ const GATED_CFGS: &[GatedCfg] = &[ // this is consistent with naming of the compiler flag it's for (sym::fmt_debug, sym::fmt_debug, Features::fmt_debug), (sym::emscripten_wasm_eh, sym::cfg_emscripten_wasm_eh, Features::cfg_emscripten_wasm_eh), + ( + sym::target_has_reliable_f16, + sym::cfg_target_has_reliable_f16_f128, + Features::cfg_target_has_reliable_f16_f128, + ), + ( + sym::target_has_reliable_f16_math, + sym::cfg_target_has_reliable_f16_f128, + Features::cfg_target_has_reliable_f16_f128, + ), + ( + sym::target_has_reliable_f128, + sym::cfg_target_has_reliable_f16_f128, + Features::cfg_target_has_reliable_f16_f128, + ), + ( + sym::target_has_reliable_f128_math, + sym::cfg_target_has_reliable_f16_f128, + Features::cfg_target_has_reliable_f16_f128, + ), ]; /// Find a gated cfg determined by the `pred`icate which is given the cfg's name. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8a31a03db7297..75e09cacb1f1e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -205,6 +205,8 @@ declare_features! ( (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None), /// Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind (internal, cfg_emscripten_wasm_eh, "1.86.0", None), + /// Allows checking whether or not the backend correctly supports unstable float types. + (internal, cfg_target_has_reliable_f16_f128, "CURRENT_RUSTC_VERSION", None), /// Allows identifying the `compiler_builtins` crate. (internal, compiler_builtins, "1.13.0", None), /// Allows writing custom MIR diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index e5017794d8f29..58213c4f4e462 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -26,7 +26,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 92701e3328e92..277bb7bd3e15c 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -450,9 +450,6 @@ hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` -hir_analysis_register_type_unstable = - type `{$ty}` cannot be used with this register class in stable - hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}` hir_analysis_return_type_notation_equality_bound = diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 5fbd771976bbb..fad8abf5fae85 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -67,7 +67,6 @@ mod check; mod compare_impl_item; mod entry; pub mod intrinsic; -pub mod intrinsicck; mod region; pub mod wfcheck; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 508970cf2554d..2b1661aaac8f0 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1675,14 +1675,6 @@ pub(crate) struct CmseEntryGeneric { pub span: Span, } -#[derive(Diagnostic)] -#[diag(hir_analysis_register_type_unstable)] -pub(crate) struct RegisterTypeUnstable<'a> { - #[primary_span] - pub span: Span, - pub ty: Ty<'a>, -} - #[derive(LintDiagnostic)] #[diag(hir_analysis_supertrait_item_shadowing)] pub(crate) struct SupertraitItemShadowing { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 309b8f2c76138..91dde13be550e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -216,7 +216,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { check::maybe_check_static_with_link_section(tcx, item_def_id); } DefKind::Const if tcx.generics_of(item_def_id).is_empty() => { - let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); + let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty()); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::fully_monomorphized(); tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid)); diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index b2b90cb29e36f..f00125c3e090a 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -22,6 +22,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 9e1b70f5767b4..23309102c4da5 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -179,6 +179,9 @@ hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> .help = use `transmute` if you're sure this is sound .label = unsupported cast +hir_typeck_register_type_unstable = + type `{$ty}` cannot be used with this register class in stable + hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this return type diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 9e7305430e5f5..732795535087e 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -963,3 +963,11 @@ pub(crate) enum SupertraitItemShadowee { traits: DiagSymbolList, }, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_register_type_unstable)] +pub(crate) struct RegisterTypeUnstable<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8b2d9ab297905..e70aa1a70645e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -8,7 +8,6 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::{ExprKind, HirId, Node, QPath}; -use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_index::IndexVec; @@ -33,6 +32,7 @@ use crate::errors::SuggestPtrNullMut; use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx}; use crate::fn_ctxt::infer::FnCall; use crate::gather_locals::Declaration; +use crate::inline_asm::InlineAsmCtxt; use crate::method::MethodCallee; use crate::method::probe::IsSuggestion; use crate::method::probe::Mode::MethodCall; @@ -98,13 +98,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id); - InlineAsmCtxt::new( - enclosing_id, - &self.infcx, - self.typing_env(self.param_env), - &*self.typeck_results.borrow(), - ) - .check_asm(asm); + InlineAsmCtxt::new(self, enclosing_id).check_asm(asm); } } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs similarity index 89% rename from compiler/rustc_hir_analysis/src/check/intrinsicck.rs rename to compiler/rustc_hir_typeck/src/inline_asm.rs index 32a582aadc1ca..6399f0a78ae2f 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -3,25 +3,22 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; -use rustc_infer::infer::InferCtxt; use rustc_middle::bug; -use rustc_middle::ty::{ - self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, TypeckResults, UintTy, -}; +use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; use rustc_target::asm::{ InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo, }; +use rustc_trait_selection::infer::InferCtxtExt; +use crate::FnCtxt; use crate::errors::RegisterTypeUnstable; -pub struct InlineAsmCtxt<'a, 'tcx> { - typing_env: ty::TypingEnv<'tcx>, +pub(crate) struct InlineAsmCtxt<'a, 'tcx> { target_features: &'tcx FxIndexSet, - infcx: &'a InferCtxt<'tcx>, - typeck_results: &'a TypeckResults<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, } enum NonAsmTypeReason<'tcx> { @@ -33,27 +30,17 @@ enum NonAsmTypeReason<'tcx> { } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { - pub fn new( - def_id: LocalDefId, - infcx: &'a InferCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - typeck_results: &'a TypeckResults<'tcx>, - ) -> Self { - InlineAsmCtxt { - typing_env, - target_features: infcx.tcx.asm_target_features(def_id), - infcx, - typeck_results, - } + pub(crate) fn new(fcx: &'a FnCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self { + InlineAsmCtxt { target_features: fcx.tcx.asm_target_features(def_id), fcx } } fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx + self.fcx.tcx } fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { - let ty = self.typeck_results.expr_ty_adjusted(expr); - let ty = self.infcx.resolve_vars_if_possible(ty); + let ty = self.fcx.typeck_results.borrow().expr_ty_adjusted(expr); + let ty = self.fcx.try_structurally_resolve_type(expr.span, ty); if ty.has_non_region_infer() { Ty::new_misc_error(self.tcx()) } else { @@ -62,19 +49,23 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` - fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool { + fn is_thin_ptr_ty(&self, span: Span, ty: Ty<'tcx>) -> bool { // Type still may have region variables, but `Sized` does not depend // on those, so just erase them before querying. - if ty.is_sized(self.tcx(), self.typing_env) { + if self.fcx.type_is_sized_modulo_regions(self.fcx.param_env, ty) { return true; } - if let ty::Foreign(..) = ty.kind() { + if let ty::Foreign(..) = self.fcx.try_structurally_resolve_type(span, ty).kind() { return true; } false } - fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result> { + fn get_asm_ty( + &self, + span: Span, + ty: Ty<'tcx>, + ) -> Result> { let asm_ty_isize = match self.tcx().sess.target.pointer_width { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, @@ -95,7 +86,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128), ty::FnPtr(..) => Ok(asm_ty_isize), ty::RawPtr(elem_ty, _) => { - if self.is_thin_ptr_ty(elem_ty) { + if self.is_thin_ptr_ty(span, elem_ty) { Ok(asm_ty_isize) } else { Err(NonAsmTypeReason::NotSizedPtr(ty)) @@ -109,11 +100,20 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let field = &fields[FieldIdx::ZERO]; let elem_ty = field.ty(self.tcx(), args); - let (size, ty) = match elem_ty.kind() { + let (size, ty) = match *elem_ty.kind() { ty::Array(ty, len) => { - let len = self.tcx().normalize_erasing_regions(self.typing_env, *len); + // FIXME: `try_structurally_resolve_const` doesn't eval consts + // in the old solver. + let len = if self.fcx.next_trait_solver() { + self.fcx.try_structurally_resolve_const(span, len) + } else { + self.fcx.tcx.normalize_erasing_regions( + self.fcx.typing_env(self.fcx.param_env), + len, + ) + }; if let Some(len) = len.try_to_target_usize(self.tcx()) { - (len, *ty) + (len, ty) } else { return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength( field.did, len, @@ -183,9 +183,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); let fields = &ty.non_enum_variant().fields; let ty = fields[FieldIdx::ZERO].ty(self.tcx(), args); - self.get_asm_ty(ty) + self.get_asm_ty(expr.span, ty) } - _ => self.get_asm_ty(ty), + _ => self.get_asm_ty(expr.span, ty), }; let asm_ty = match asm_ty { Ok(asm_ty) => asm_ty, @@ -193,7 +193,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { match reason { NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => { let msg = format!("cannot evaluate SIMD vector length `{len}`"); - self.infcx + self.fcx .dcx() .struct_span_err(self.tcx().def_span(did), msg) .with_span_note( @@ -204,7 +204,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } NonAsmTypeReason::Invalid(ty) => { let msg = format!("cannot use value of type `{ty}` for inline assembly"); - self.infcx.dcx().struct_span_err(expr.span, msg).with_note( + self.fcx.dcx().struct_span_err(expr.span, msg).with_note( "only integers, floats, SIMD vectors, pointers and function pointers \ can be used as arguments for inline assembly", ).emit(); @@ -213,7 +213,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = format!( "cannot use value of unsized pointer type `{ty}` for inline assembly" ); - self.infcx + self.fcx .dcx() .struct_span_err(expr.span, msg) .with_note("only sized pointers can be used in inline assembly") @@ -223,7 +223,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = format!( "cannot use SIMD vector with element type `{ty}` for inline assembly" ); - self.infcx.dcx() + self.fcx.dcx() .struct_span_err(self.tcx().def_span(did), msg).with_span_note( expr.span, "only integers, floats, SIMD vectors, pointers and function pointers \ @@ -232,7 +232,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } NonAsmTypeReason::EmptySIMDArray(ty) => { let msg = format!("use of empty SIMD vector `{ty}`"); - self.infcx.dcx().struct_span_err(expr.span, msg).emit(); + self.fcx.dcx().struct_span_err(expr.span, msg).emit(); } } return None; @@ -241,9 +241,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that the type implements Copy. The only case where this can // possibly fail is for SIMD types which don't #[derive(Copy)]. - if !self.tcx().type_is_copy_modulo_regions(self.typing_env, ty) { + if !self.fcx.type_is_copy_modulo_regions(self.fcx.param_env, ty) { let msg = "arguments for inline assembly must be copyable"; - self.infcx + self.fcx .dcx() .struct_span_err(expr.span, msg) .with_note(format!("`{ty}` does not implement the Copy trait")) @@ -263,7 +263,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; let in_expr_ty = self.expr_ty(in_expr); - self.infcx + self.fcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) .with_span_label(in_expr.span, format!("type `{in_expr_ty}`")) @@ -296,7 +296,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ) } else { let msg = format!("type `{ty}` cannot be used with this register class"); - let mut err = self.infcx.dcx().struct_span_err(expr.span, msg); + let mut err = self.fcx.dcx().struct_span_err(expr.span, msg); let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect(); err.note(format!( @@ -326,7 +326,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some(feature) = feature { if !self.target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); - self.infcx + self.fcx .dcx() .struct_span_err(expr.span, msg) .with_note(format!( @@ -384,9 +384,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { Some(asm_ty) } - pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { + pub(crate) fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { let Some(asm_arch) = self.tcx().sess.asm_arch else { - self.infcx.dcx().delayed_bug("target architecture does not support asm"); + self.fcx.dcx().delayed_bug("target architecture does not support asm"); return; }; let allow_experimental_reg = self.tcx().features().asm_experimental_reg(); @@ -418,7 +418,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.infcx.dcx().span_err(op_sp, msg); + self.fcx.dcx().span_err(op_sp, msg); continue; } } @@ -458,7 +458,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.infcx.dcx().span_err(op_sp, msg); + self.fcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -472,7 +472,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::(), ); - self.infcx.dcx().span_err(op_sp, msg); + self.fcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -512,7 +512,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Error(_) => {} _ if ty.is_integral() => {} _ => { - self.infcx + self.fcx .dcx() .struct_span_err(op_sp, "invalid type for `const` operand") .with_span_label( @@ -531,7 +531,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::FnDef(..) => {} ty::Error(_) => {} _ => { - self.infcx + self.fcx .dcx() .struct_span_err(op_sp, "invalid `sym` operand") .with_span_label( diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index c3717b4efa47f..d861a4f81b0e0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -23,6 +23,7 @@ mod diverges; mod errors; mod expectation; mod expr; +mod inline_asm; // Used by clippy; pub mod expr_use_visitor; mod fallback; diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index c3a939f1ab086..4d346b50c8080 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -38,14 +38,25 @@ pub(crate) fn add_configuration( codegen_backend: &dyn CodegenBackend, ) { let tf = sym::target_feature; + let tf_cfg = codegen_backend.target_config(sess); - let (target_features, unstable_target_features) = codegen_backend.target_features_cfg(sess); + sess.unstable_target_features.extend(tf_cfg.unstable_target_features.iter().copied()); + sess.target_features.extend(tf_cfg.target_features.iter().copied()); - sess.unstable_target_features.extend(unstable_target_features.iter().copied()); + cfg.extend(tf_cfg.target_features.into_iter().map(|feat| (tf, Some(feat)))); - sess.target_features.extend(target_features.iter().copied()); - - cfg.extend(target_features.into_iter().map(|feat| (tf, Some(feat)))); + if tf_cfg.has_reliable_f16 { + cfg.insert((sym::target_has_reliable_f16, None)); + } + if tf_cfg.has_reliable_f16_math { + cfg.insert((sym::target_has_reliable_f16_math, None)); + } + if tf_cfg.has_reliable_f128 { + cfg.insert((sym::target_has_reliable_f128, None)); + } + if tf_cfg.has_reliable_f128_math { + cfg.insert((sym::target_has_reliable_f128_math, None)); + } if sess.crt_static(None) { cfg.insert((tf, Some(sym::crt_dash_static))); diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 0494c78a7a97c..d0668794198ac 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -104,7 +104,7 @@ impl ClashingExternDeclarations { /// for the item, return its HirId without updating the set. fn insert(&mut self, tcx: TyCtxt<'_>, fi: hir::ForeignItemId) -> Option { let did = fi.owner_id.to_def_id(); - let instance = Instance::new(did, ty::List::identity_for_item(tcx, did)); + let instance = Instance::new_raw(did, ty::List::identity_for_item(tcx, did)); let name = Symbol::intern(tcx.symbol_name(instance).name); if let Some(&existing_id) = self.seen_decls.get(&name) { // Avoid updating the map with the new entry when we do find a collision. We want to diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 5f0e4d745e833..72369ab7b692a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -973,6 +973,27 @@ extern "C" LLVMMetadataRef LLVMRustDIGetInstMetadata(LLVMValueRef x) { return nullptr; } +extern "C" void +LLVMRustRemoveEnumAttributeAtIndex(LLVMValueRef F, size_t index, + LLVMRustAttributeKind RustAttr) { + LLVMRemoveEnumAttributeAtIndex(F, index, fromRust(RustAttr)); +} + +extern "C" bool LLVMRustHasFnAttribute(LLVMValueRef F, const char *Name, + size_t NameLen) { + if (auto *Fn = dyn_cast(unwrap(F))) { + return Fn->hasFnAttribute(StringRef(Name, NameLen)); + } + return false; +} + +extern "C" void LLVMRustRemoveFnAttribute(LLVMValueRef Fn, const char *Name, + size_t NameLen) { + if (auto *F = dyn_cast(unwrap(Fn))) { + F->removeFnAttr(StringRef(Name, NameLen)); + } +} + extern "C" void LLVMRustGlobalAddMetadata(LLVMValueRef Global, unsigned Kind, LLVMMetadataRef MD) { unwrap(Global)->addMetadata(Kind, *unwrap(MD)); diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 3c62017072e41..1d67d0fe3bbf4 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -56,7 +56,7 @@ impl<'tcx> ExportedSymbol<'tcx> { match *self { ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)), ExportedSymbol::Generic(def_id, args) => { - tcx.symbol_name(ty::Instance::new(def_id, args)) + tcx.symbol_name(ty::Instance::new_raw(def_id, args)) } ExportedSymbol::DropGlue(ty) => { tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty)) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 4222a68e5447d..c7159ed8167ae 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -23,7 +23,7 @@ impl<'tcx> TyCtxt<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); self.const_eval_global_id(typing_env, cid, DUMMY_SP) @@ -39,7 +39,7 @@ impl<'tcx> TyCtxt<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); let inputs = self.erase_regions(typing_env.as_query_input(cid)); @@ -208,7 +208,7 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> { // into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are // encountered. let args = GenericArgs::identity_for_item(self.tcx, def_id); - let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args)); + let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args)); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 6b413a7383a5e..7243f87ee6380 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -318,7 +318,7 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> { match *self { MonoItem::Fn(instance) => write!(f, "fn {instance}"), MonoItem::Static(def_id) => { - write!(f, "static {}", Instance::new(def_id, GenericArgs::empty())) + write!(f, "static {}", Instance::new_raw(def_id, GenericArgs::empty())) } MonoItem::GlobalAsm(..) => write!(f, "global_asm"), } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 293b1552beb58..09038008513d4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2471,7 +2471,7 @@ rustc_queries! { query resolve_instance_raw( key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { - desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } + desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) } } query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index d660e7d0d6022..0d99a1b51499a 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -491,7 +491,15 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> { } impl<'tcx> Instance<'tcx> { - pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { + /// Creates a new [`InstanceKind::Item`] from the `def_id` and `args`. + /// + /// Note that this item corresponds to the body of `def_id` directly, which + /// likely does not make sense for trait items which need to be resolved to an + /// implementation, and which may not even have a body themselves. Usages of + /// this function should probably use [`Instance::expect_resolve`], or if run + /// in a polymorphic environment or within a lint (that may encounter ambiguity) + /// [`Instance::try_resolve`] instead. + pub fn new_raw(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> { assert!( !args.has_escaping_bound_vars(), "args of instance {def_id:?} has escaping bound vars: {args:?}" @@ -510,7 +518,7 @@ impl<'tcx> Instance<'tcx> { } }); - Instance::new(def_id, args) + Instance::new_raw(def_id, args) } #[inline] @@ -603,7 +611,7 @@ impl<'tcx> Instance<'tcx> { let type_length = type_length(args); if !tcx.type_length_limit().value_within_limit(type_length) { let (shrunk, written_to_path) = - shrunk_instance_name(tcx, Instance::new(def_id, args)); + shrunk_instance_name(tcx, Instance::new_raw(def_id, args)); let mut path = PathBuf::new(); let was_written = if let Some(path2) = written_to_path { path = path2; @@ -773,7 +781,7 @@ impl<'tcx> Instance<'tcx> { match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args), - _ => Instance::new(def_id, args), + _ => Instance::new_raw(def_id, args), } } @@ -899,7 +907,7 @@ impl<'tcx> Instance<'tcx> { // This is important for `Iterator`'s combinators, but also useful for // adding future default methods to `Future`, for instance. debug_assert!(tcx.defaultness(trait_item_id).has_value()); - Some(Instance::new(trait_item_id, rcvr_args)) + Some(Instance::new_raw(trait_item_id, rcvr_args)) } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 76dad6b35714a..549f54d3c5496 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -913,7 +913,7 @@ fn visit_instance_use<'tcx>( // We explicitly skip this otherwise to ensure we get a linker error // if anyone tries to call this intrinsic and the codegen backend did not // override the implementation. - let instance = ty::Instance::new(instance.def_id(), instance.args); + let instance = ty::Instance::new_raw(instance.def_id(), instance.args); if tcx.should_codegen_locally(instance) { output.push(create_fn_mono_item(tcx, instance, source)); } @@ -1502,7 +1502,7 @@ impl<'v> RootCollector<'_, 'v> { ty::Closure(def_id, args) | ty::Coroutine(def_id, args) | ty::CoroutineClosure(def_id, args) => { - Instance::new(def_id, self.tcx.erase_regions(args)) + Instance::new_raw(def_id, self.tcx.erase_regions(args)) } _ => unreachable!(), }; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 04f80a056f94d..dded84f67686b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -81,12 +81,19 @@ where /// the values inferred while solving the instantiated goal. /// - `external_constraints`: additional constraints which aren't expressible /// using simple unification of inference variables. + /// + /// This takes the `shallow_certainty` which represents whether we're confident + /// that the final result of the current goal only depends on the nested goals. + /// + /// In case this is `Certainy::Maybe`, there may still be additional nested goals + /// or inference constraints required for this candidate to be hold. The candidate + /// always requires all already added constraints and nested goals. #[instrument(level = "trace", skip(self), ret)] pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response( &mut self, - certainty: Certainty, + shallow_certainty: Certainty, ) -> QueryResult { - self.inspect.make_canonical_response(certainty); + self.inspect.make_canonical_response(shallow_certainty); let goals_certainty = self.try_evaluate_added_goals()?; assert_eq!( @@ -103,26 +110,29 @@ where NoSolution })?; - // 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 - // to the caller, where they are then handled. - // - // As we return all ambiguous nested goals, we can ignore the certainty returned - // by `try_evaluate_added_goals()`. - let (certainty, normalization_nested_goals) = match self.current_goal_kind { - CurrentGoalKind::NormalizesTo => { - let goals = std::mem::take(&mut self.nested_goals); - if goals.is_empty() { - assert!(matches!(goals_certainty, Certainty::Yes)); + let (certainty, normalization_nested_goals) = + match (self.current_goal_kind, shallow_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 + // to the caller, where they are then handled. We only do so if we do not + // need to recompute the `NormalizesTo` goal afterwards to avoid repeatedly + // uplifting its nested goals. This is the case if the `shallow_certainty` is + // `Certainty::Yes`. + (CurrentGoalKind::NormalizesTo, Certainty::Yes) => { + let goals = std::mem::take(&mut self.nested_goals); + // As we return all ambiguous nested goals, we can ignore the certainty + // returned by `self.try_evaluate_added_goals()`. + if goals.is_empty() { + assert!(matches!(goals_certainty, Certainty::Yes)); + } + (Certainty::Yes, NestedNormalizationGoals(goals)) } - (certainty, NestedNormalizationGoals(goals)) - } - CurrentGoalKind::Misc | CurrentGoalKind::CoinductiveTrait => { - let certainty = certainty.unify_with(goals_certainty); - (certainty, NestedNormalizationGoals::empty()) - } - }; + _ => { + let certainty = shallow_certainty.unify_with(goals_certainty); + (certainty, NestedNormalizationGoals::empty()) + } + }; if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty { // If we have overflow, it's probable that we're substituting a type diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 1625da81b857a..8f85ff1c8b028 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -6,7 +6,7 @@ mod weak_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::{self as ty, Interner, NormalizesTo, Upcast as _}; +use rustc_type_ir::{self as ty, Interner, NormalizesTo, PredicateKind, Upcast as _}; use tracing::instrument; use crate::delegate::SolverDelegate; @@ -194,6 +194,12 @@ where .map(|pred| goal.with(cx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); + // Bail if the nested goals don't hold here. This is to avoid unnecessarily + // computing the `type_of` query for associated types that never apply, as + // this may result in query cycles in the case of RPITITs. + // See . + ecx.try_evaluate_added_goals()?; + // Add GAT where clauses from the trait's definition. // FIXME: We don't need these, since these are the type's own WF obligations. ecx.add_goals( @@ -221,13 +227,21 @@ where Ok(Some(target_item_def_id)) => target_item_def_id, Ok(None) => { match ecx.typing_mode() { - // In case the associated item is hidden due to specialization, we have to - // return ambiguity this would otherwise be incomplete, resulting in - // unsoundness during coherence (#105782). + // In case the associated item is hidden due to specialization, + // normalizing this associated item is always ambiguous. Treating + // the associated item as rigid would be incomplete and allow for + // overlapping impls, see #105782. + // + // As this ambiguity is unavoidable we emit a nested ambiguous + // goal instead of using `Certainty::AMBIGUOUS`. This allows us to + // return the nested goals to the parent `AliasRelate` goal. This + // would be relevant if any of the nested goals refer to the `term`. + // This is not the case here and we only prefer adding an ambiguous + // nested goal for consistency. ty::TypingMode::Coherence => { - return ecx.evaluate_added_goals_and_make_canonical_response( - Certainty::AMBIGUOUS, - ); + ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous)); + return ecx + .evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } // Outside of coherence, we treat the associated item as rigid instead. ty::TypingMode::Analysis { .. } @@ -254,10 +268,20 @@ where // treat it as rigid. if cx.impl_self_is_guaranteed_unsized(impl_def_id) { match ecx.typing_mode() { + // Trying to normalize such associated items is always ambiguous + // during coherence to avoid cyclic reasoning. See the example in + // tests/ui/traits/trivial-unsized-projection-in-coherence.rs. + // + // As this ambiguity is unavoidable we emit a nested ambiguous + // goal instead of using `Certainty::AMBIGUOUS`. This allows us to + // return the nested goals to the parent `AliasRelate` goal. This + // would be relevant if any of the nested goals refer to the `term`. + // This is not the case here and we only prefer adding an ambiguous + // nested goal for consistency. ty::TypingMode::Coherence => { - return ecx.evaluate_added_goals_and_make_canonical_response( - Certainty::AMBIGUOUS, - ); + ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous)); + return ecx + .evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } ty::TypingMode::Analysis { .. } | ty::TypingMode::Borrowck { .. } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index ee439f1b3d0d5..df3ad1e468bb8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -3,6 +3,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_type_ir::inherent::*; +use rustc_type_ir::solve::GoalSource; use rustc_type_ir::{self as ty, Interner, TypingMode, fold_regions}; use crate::delegate::SolverDelegate; @@ -31,7 +32,12 @@ where goal.param_env, expected, ); - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + // Trying to normalize an opaque type during coherence is always ambiguous. + // We add a nested ambiguous goal here instead of using `Certainty::AMBIGUOUS`. + // This allows us to return the nested goals to the parent `AliasRelate` goal. + // This can then allow nested goals to fail after we've constrained the `term`. + self.add_goal(GoalSource::Misc, goal.with(cx, ty::PredicateKind::Ambiguous)); + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } TypingMode::Analysis { defining_opaque_types_and_generators } => { let Some(def_id) = opaque_ty diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 231ca434962e6..cbfe9e0da6adf 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -142,6 +142,10 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) { | (sym::target_has_atomic, Some(_)) | (sym::target_has_atomic_equal_alignment, Some(_)) | (sym::target_has_atomic_load_store, Some(_)) + | (sym::target_has_reliable_f16, None | Some(_)) + | (sym::target_has_reliable_f16_math, None | Some(_)) + | (sym::target_has_reliable_f128, None | Some(_)) + | (sym::target_has_reliable_f128_math, None | Some(_)) | (sym::target_thread_local, None) => disallow(cfg, "--target"), (sym::fmt_debug, None | Some(_)) => disallow(cfg, "-Z fmt-debug"), (sym::emscripten_wasm_eh, None | Some(_)) => disallow(cfg, "-Z emscripten_wasm_eh"), diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index 64763b71d303d..40e6d21c06378 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -22,7 +22,7 @@ impl<'tcx> BodyBuilder<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self { let instance = match instance.def { // To get the fallback body of an intrinsic, we need to convert it to an item. - ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args), + ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args), _ => instance, }; BodyBuilder { tcx, instance } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 040ea7d8bc219..ba3e6d7ca826c 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -614,6 +614,7 @@ symbols! { cfg_target_feature, cfg_target_has_atomic, cfg_target_has_atomic_equal_alignment, + cfg_target_has_reliable_f16_f128, cfg_target_thread_local, cfg_target_vendor, cfg_trace: "", // must not be a valid identifier @@ -2068,6 +2069,10 @@ symbols! { target_has_atomic, target_has_atomic_equal_alignment, target_has_atomic_load_store, + target_has_reliable_f128, + target_has_reliable_f128_math, + target_has_reliable_f16, + target_has_reliable_f16_math, target_os, target_pointer_width, target_thread_local, diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index ddeeadff13d17..0c6d1495e39cf 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -56,7 +56,7 @@ impl SymbolNamesTest<'_> { // some subset. for attr in tcx.get_attrs(def_id, SYMBOL_NAME) { let def_id = def_id.to_def_id(); - let instance = Instance::new( + let instance = Instance::new_raw( def_id, tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)), ); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index da83566dad024..166e8f1934299 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -235,7 +235,7 @@ fn resolve_associated_item<'tcx>( tcx.ensure_ok().compare_impl_item(leaf_def_item)?; } - Some(ty::Instance::new(leaf_def.item.def_id, args)) + Some(ty::Instance::new_raw(leaf_def.item.def_id, args)) } traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => { let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args); @@ -280,7 +280,7 @@ fn resolve_associated_item<'tcx>( // Use the default `fn clone_from` from `trait Clone`. let args = tcx.erase_regions(rcvr_args); - Some(ty::Instance::new(trait_item_id, args)) + Some(ty::Instance::new_raw(trait_item_id, args)) } } else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) { if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) { @@ -329,7 +329,7 @@ fn resolve_associated_item<'tcx>( // sync with the built-in trait implementations (since all of the // implementations return `FnOnce::Output`). if ty::ClosureKind::FnOnce == args.as_coroutine_closure().kind() { - Some(Instance::new(coroutine_closure_def_id, args)) + Some(Instance::new_raw(coroutine_closure_def_id, args)) } else { Some(Instance { def: ty::InstanceKind::ConstructCoroutineInClosureShim { @@ -362,7 +362,7 @@ fn resolve_associated_item<'tcx>( args, }) } else { - Some(Instance::new(coroutine_closure_def_id, args)) + Some(Instance::new_raw(coroutine_closure_def_id, args)) } } ty::Closure(closure_def_id, args) => { @@ -381,7 +381,7 @@ fn resolve_associated_item<'tcx>( let name = tcx.item_name(trait_item_id); assert_eq!(name, sym::transmute); let args = tcx.erase_regions(rcvr_args); - Some(ty::Instance::new(trait_item_id, args)) + Some(ty::Instance::new_raw(trait_item_id, args)) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) } diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 3eee988b6c9d1..1af110691ba64 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -168,7 +168,7 @@ impl IntoIter { // SAFETY: This allocation originally came from a `Vec`, so it passes // all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`, - // so the `sub_ptr`s below cannot wrap, and will produce a well-formed + // so the `offset_from_unsigned`s below cannot wrap, and will produce a well-formed // range. `end` ≤ `buf + cap`, so the range will be in-bounds. // Taking `alloc` is ok because nothing else is going to look at it, // since our `Drop` impl isn't going to run so there's no more code. diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index ca5cb17f8bfda..ed1a0dda76d29 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -59,7 +59,7 @@ impl Drop for Splice<'_, I, A> { // and moving things into the final place. // Which means we can replace the slice::Iter with pointers that won't point to deallocated // memory, so that Drain::drop is still allowed to call iter.len(), otherwise it would break - // the ptr.sub_ptr contract. + // the ptr.offset_from_unsigned contract. self.drain.iter = (&[]).iter(); unsafe { diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index a7563f918a241..c5d5bc000f1c7 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2996,7 +2996,7 @@ pub unsafe fn nontemporal_store(ptr: *mut T, val: T); #[rustc_intrinsic] pub const unsafe fn ptr_offset_from(ptr: *const T, base: *const T) -> isize; -/// See documentation of `<*const T>::sub_ptr` for details. +/// See documentation of `<*const T>::offset_from_unsigned` for details. #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_const_stable_indirect] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 2d869958b85cc..bcf34781c8acd 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -804,8 +804,8 @@ impl *const T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for - /// documentation and safety requirements. + /// using [`offset_from_unsigned`][pointer::offset_from_unsigned] on it. + /// See that method for documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. @@ -814,7 +814,7 @@ impl *const T { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset_from_unsigned(self, origin: *const U) -> usize { - // SAFETY: the caller must uphold the safety contract for `sub_ptr`. + // SAFETY: the caller must uphold the safety contract for `offset_from_unsigned`. unsafe { self.cast::().offset_from_unsigned(origin.cast::()) } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index df49eedb35096..6d1a50d84366e 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -937,6 +937,7 @@ impl *mut T { /// /// // This would be incorrect, as the pointers are not correctly ordered: /// // ptr1.offset_from(ptr2) + /// ``` #[stable(feature = "ptr_sub_ptr", since = "1.87.0")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")] #[inline] @@ -945,7 +946,7 @@ impl *mut T { where T: Sized, { - // SAFETY: the caller must uphold the safety contract for `sub_ptr`. + // SAFETY: the caller must uphold the safety contract for `offset_from_unsigned`. unsafe { (self as *const T).offset_from_unsigned(origin) } } @@ -954,8 +955,8 @@ impl *mut T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for - /// documentation and safety requirements. + /// using [`offset_from_unsigned`][pointer::offset_from_unsigned] on it. + /// See that method for documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. @@ -964,7 +965,7 @@ impl *mut T { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn byte_offset_from_unsigned(self, origin: *mut U) -> usize { - // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. + // SAFETY: the caller must uphold the safety contract for `byte_offset_from_unsigned`. unsafe { (self as *const T).byte_offset_from_unsigned(origin) } } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 68b8f0c3e4e1d..0864cc457b658 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -906,7 +906,7 @@ impl NonNull { where T: Sized, { - // SAFETY: the caller must uphold the safety contract for `sub_ptr`. + // SAFETY: the caller must uphold the safety contract for `offset_from_unsigned`. unsafe { self.as_ptr().offset_from_unsigned(subtracted.as_ptr()) } } @@ -915,8 +915,8 @@ impl NonNull { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][NonNull::offset_from_unsigned] on it. See that method for - /// documentation and safety requirements. + /// using [`offset_from_unsigned`][NonNull::offset_from_unsigned] on it. + /// See that method for documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. @@ -925,7 +925,7 @@ impl NonNull { #[stable(feature = "ptr_sub_ptr", since = "1.87.0")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")] pub const unsafe fn byte_offset_from_unsigned(self, origin: NonNull) -> usize { - // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. + // SAFETY: the caller must uphold the safety contract for `byte_offset_from_unsigned`. unsafe { self.as_ptr().byte_offset_from_unsigned(origin.as_ptr()) } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 602af4a0447ee..940b671c51461 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -163,4 +163,10 @@ check-cfg = [ # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg 'cfg(feature, values(any()))', + # Internal features aren't marked known config by default, we use these to + # gate tests. + 'cfg(target_has_reliable_f16)', + 'cfg(target_has_reliable_f16_math)', + 'cfg(target_has_reliable_f128)', + 'cfg(target_has_reliable_f128_math)', ] diff --git a/library/std/build.rs b/library/std/build.rs index 40a56d4930d35..ef695601a448a 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -7,12 +7,6 @@ fn main() { let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set"); let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set"); - let target_abi = env::var("CARGO_CFG_TARGET_ABI").expect("CARGO_CFG_TARGET_ABI was not set"); - let target_pointer_width: u32 = env::var("CARGO_CFG_TARGET_POINTER_WIDTH") - .expect("CARGO_CFG_TARGET_POINTER_WIDTH was not set") - .parse() - .unwrap(); - let is_miri = env::var_os("CARGO_CFG_MIRI").is_some(); println!("cargo:rustc-check-cfg=cfg(netbsd10)"); if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() { @@ -80,108 +74,4 @@ fn main() { println!("cargo:rustc-cfg=backtrace_in_libstd"); println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap()); - - // Emit these on platforms that have no known ABI bugs, LLVM selection bugs, lowering bugs, - // missing symbols, or other problems, to determine when tests get run. - // If more broken platforms are found, please update the tracking issue at - // - // - // Some of these match arms are redundant; the goal is to separate reasons that the type is - // unreliable, even when multiple reasons might fail the same platform. - println!("cargo:rustc-check-cfg=cfg(reliable_f16)"); - println!("cargo:rustc-check-cfg=cfg(reliable_f128)"); - - // This is a step beyond only having the types and basic functions available. Math functions - // aren't consistently available or correct. - println!("cargo:rustc-check-cfg=cfg(reliable_f16_math)"); - println!("cargo:rustc-check-cfg=cfg(reliable_f128_math)"); - - let has_reliable_f16 = match (target_arch.as_str(), target_os.as_str()) { - // We can always enable these in Miri as that is not affected by codegen bugs. - _ if is_miri => true, - // Selection failure - ("s390x", _) => false, - // Unsupported - ("arm64ec", _) => false, - // MinGW ABI bugs - ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, - // Infinite recursion - ("csky", _) => false, - ("hexagon", _) => false, - ("powerpc" | "powerpc64", _) => false, - ("sparc" | "sparc64", _) => false, - ("wasm32" | "wasm64", _) => false, - // `f16` support only requires that symbols converting to and from `f32` are available. We - // provide these in `compiler-builtins`, so `f16` should be available on all platforms that - // do not have other ABI issues or LLVM crashes. - _ => true, - }; - - let has_reliable_f128 = match (target_arch.as_str(), target_os.as_str()) { - // We can always enable these in Miri as that is not affected by codegen bugs. - _ if is_miri => true, - // Unsupported - ("arm64ec", _) => false, - // Selection bug - ("mips64" | "mips64r6", _) => false, - // Selection bug - ("nvptx64", _) => false, - // ABI bugs et al. (full - // list at ) - ("powerpc" | "powerpc64", _) => false, - // ABI unsupported - ("sparc", _) => false, - // Stack alignment bug . NB: tests may - // not fail if our compiler-builtins is linked. - ("x86", _) => false, - // MinGW ABI bugs - ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false, - // There are no known problems on other platforms, so the only requirement is that symbols - // are available. `compiler-builtins` provides all symbols required for core `f128` - // support, so this should work for everything else. - _ => true, - }; - - // Configure platforms that have reliable basics but may have unreliable math. - - // LLVM is currently adding missing routines, - let has_reliable_f16_math = has_reliable_f16 - && match (target_arch.as_str(), target_os.as_str()) { - // FIXME: Disabled on Miri as the intrinsics are not implemented yet. - _ if is_miri => false, - // x86 has a crash for `powi`: - ("x86" | "x86_64", _) => false, - // Assume that working `f16` means working `f16` math for most platforms, since - // operations just go through `f32`. - _ => true, - }; - - let has_reliable_f128_math = has_reliable_f128 - && match (target_arch.as_str(), target_os.as_str()) { - // FIXME: Disabled on Miri as the intrinsics are not implemented yet. - _ if is_miri => false, - // LLVM lowers `fp128` math to `long double` symbols even on platforms where - // `long double` is not IEEE binary128. See - // . - // - // This rules out anything that doesn't have `long double` = `binary128`; <= 32 bits - // (ld is `f64`), anything other than Linux (Windows and MacOS use `f64`), and `x86` - // (ld is 80-bit extended precision). - ("x86_64", _) => false, - (_, "linux") if target_pointer_width == 64 => true, - _ => false, - }; - - if has_reliable_f16 { - println!("cargo:rustc-cfg=reliable_f16"); - } - if has_reliable_f128 { - println!("cargo:rustc-cfg=reliable_f128"); - } - if has_reliable_f16_math { - println!("cargo:rustc-cfg=reliable_f16_math"); - } - if has_reliable_f128_math { - println!("cargo:rustc-cfg=reliable_f128_math"); - } } diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index 217528fdf1c10..2b416b13fa59c 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -22,7 +22,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 3.7_f128; /// let g = 3.0_f128; @@ -49,7 +53,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 3.01_f128; /// let g = 4.0_f128; @@ -76,7 +84,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 3.3_f128; /// let g = -3.3_f128; @@ -108,7 +120,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 3.3_f128; /// let g = -3.3_f128; @@ -138,7 +154,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 3.7_f128; /// let g = 3.0_f128; @@ -166,7 +186,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 3.6_f128; /// let y = -3.6_f128; @@ -203,7 +227,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let m = 10.0_f128; /// let x = 4.0_f128; @@ -247,7 +275,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let a: f128 = 7.0; /// let b = 4.0; @@ -289,7 +321,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let a: f128 = 7.0; /// let b = 4.0; @@ -326,7 +362,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 2.0_f128; /// let abs_difference = (x.powi(2) - (x * x)).abs(); @@ -354,7 +394,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 2.0_f128; /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); @@ -386,7 +430,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let positive = 4.0_f128; /// let negative = -4.0_f128; @@ -417,7 +465,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let one = 1.0f128; /// // e^1 @@ -448,7 +500,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 2.0f128; /// @@ -479,7 +535,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let one = 1.0f128; /// // e^1 @@ -495,7 +555,11 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY); /// assert!((-42_f128).ln().is_nan()); @@ -526,7 +590,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let five = 5.0f128; /// @@ -540,7 +608,11 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY); /// assert!((-42_f128).log(10.0).is_nan()); @@ -567,7 +639,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let two = 2.0f128; /// @@ -581,7 +657,11 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY); /// assert!((-42_f128).log2().is_nan()); @@ -608,7 +688,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let ten = 10.0f128; /// @@ -622,7 +706,11 @@ impl f128 { /// Non-positive values: /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY); /// assert!((-42_f128).log10().is_nan()); @@ -651,7 +739,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 8.0f128; /// @@ -687,7 +779,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 2.0f128; /// let y = 3.0f128; @@ -717,7 +813,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = std::f128::consts::FRAC_PI_2; /// @@ -745,7 +845,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 2.0 * std::f128::consts::PI; /// @@ -776,7 +880,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = std::f128::consts::FRAC_PI_4; /// let abs_difference = (x.tan() - 1.0).abs(); @@ -808,7 +916,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = std::f128::consts::FRAC_PI_2; /// @@ -843,7 +955,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = std::f128::consts::FRAC_PI_4; /// @@ -877,7 +993,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let f = 1.0f128; /// @@ -915,7 +1035,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// // Positive angles measured counter-clockwise /// // from positive x axis @@ -957,7 +1081,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = std::f128::consts::FRAC_PI_4; /// let f = x.sin_cos(); @@ -992,7 +1120,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 1e-8_f128; /// @@ -1028,7 +1160,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 1e-8_f128; /// @@ -1043,7 +1179,11 @@ impl f128 { /// Out-of-range values: /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY); /// assert!((-2.0_f128).ln_1p().is_nan()); @@ -1072,7 +1212,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let e = std::f128::consts::E; /// let x = 1.0f128; @@ -1107,7 +1251,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let e = std::f128::consts::E; /// let x = 1.0f128; @@ -1142,7 +1290,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let e = std::f128::consts::E; /// let x = 1.0f128; @@ -1174,7 +1326,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 1.0f128; /// let f = x.sinh().asinh(); @@ -1206,7 +1362,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 1.0f128; /// let f = x.cosh().acosh(); @@ -1240,7 +1400,11 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let e = std::f128::consts::E; /// let f = e.tanh().atanh(); @@ -1274,7 +1438,11 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_gamma)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 5.0f128; /// @@ -1309,7 +1477,11 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_gamma)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// let x = 2.0f128; /// @@ -1344,7 +1516,11 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_erf)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// /// The error function relates what percent of a normal distribution lies /// /// within `x` standard deviations (scaled by `1/sqrt(2)`). /// fn within_standard_deviations(x: f128) -> f128 { @@ -1383,7 +1559,11 @@ impl f128 { /// ``` /// #![feature(f128)] /// #![feature(float_erf)] - /// # #[cfg(reliable_f128_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f128_math)] { /// let x: f128 = 0.123; /// /// let one = x.erf() + x.erfc(); diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index 4dadcbb518556..3f88ab2d400e9 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -22,7 +22,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 3.7_f16; /// let g = 3.0_f16; @@ -49,7 +53,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 3.01_f16; /// let g = 4.0_f16; @@ -76,7 +84,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 3.3_f16; /// let g = -3.3_f16; @@ -108,7 +120,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 3.3_f16; /// let g = -3.3_f16; @@ -138,7 +154,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 3.7_f16; /// let g = 3.0_f16; @@ -166,7 +186,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 3.6_f16; /// let y = -3.6_f16; @@ -203,7 +227,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let m = 10.0_f16; /// let x = 4.0_f16; @@ -247,7 +275,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let a: f16 = 7.0; /// let b = 4.0; @@ -289,7 +321,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let a: f16 = 7.0; /// let b = 4.0; @@ -326,7 +362,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 2.0_f16; /// let abs_difference = (x.powi(2) - (x * x)).abs(); @@ -354,7 +394,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 2.0_f16; /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); @@ -386,7 +430,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let positive = 4.0_f16; /// let negative = -4.0_f16; @@ -417,7 +465,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let one = 1.0f16; /// // e^1 @@ -448,7 +500,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 2.0f16; /// @@ -479,7 +535,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let one = 1.0f16; /// // e^1 @@ -495,7 +555,11 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// assert_eq!(0_f16.ln(), f16::NEG_INFINITY); /// assert!((-42_f16).ln().is_nan()); @@ -526,7 +590,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let five = 5.0f16; /// @@ -540,7 +608,11 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// assert_eq!(0_f16.log(10.0), f16::NEG_INFINITY); /// assert!((-42_f16).log(10.0).is_nan()); @@ -567,7 +639,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let two = 2.0f16; /// @@ -581,7 +657,11 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// assert_eq!(0_f16.log2(), f16::NEG_INFINITY); /// assert!((-42_f16).log2().is_nan()); @@ -608,7 +688,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let ten = 10.0f16; /// @@ -622,7 +706,11 @@ impl f16 { /// Non-positive values: /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// assert_eq!(0_f16.log10(), f16::NEG_INFINITY); /// assert!((-42_f16).log10().is_nan()); @@ -650,7 +738,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 8.0f16; /// @@ -685,7 +777,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 2.0f16; /// let y = 3.0f16; @@ -715,7 +811,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = std::f16::consts::FRAC_PI_2; /// @@ -743,7 +843,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 2.0 * std::f16::consts::PI; /// @@ -774,7 +878,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = std::f16::consts::FRAC_PI_4; /// let abs_difference = (x.tan() - 1.0).abs(); @@ -806,7 +914,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = std::f16::consts::FRAC_PI_2; /// @@ -841,7 +953,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = std::f16::consts::FRAC_PI_4; /// @@ -875,7 +991,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let f = 1.0f16; /// @@ -913,7 +1033,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// // Positive angles measured counter-clockwise /// // from positive x axis @@ -955,7 +1079,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = std::f16::consts::FRAC_PI_4; /// let f = x.sin_cos(); @@ -990,7 +1118,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 1e-4_f16; /// @@ -1026,7 +1158,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 1e-4_f16; /// @@ -1041,7 +1177,11 @@ impl f16 { /// Out-of-range values: /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// assert_eq!((-1.0_f16).ln_1p(), f16::NEG_INFINITY); /// assert!((-2.0_f16).ln_1p().is_nan()); @@ -1070,7 +1210,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let e = std::f16::consts::E; /// let x = 1.0f16; @@ -1105,7 +1249,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let e = std::f16::consts::E; /// let x = 1.0f16; @@ -1140,7 +1288,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let e = std::f16::consts::E; /// let x = 1.0f16; @@ -1172,7 +1324,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 1.0f16; /// let f = x.sinh().asinh(); @@ -1204,7 +1360,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 1.0f16; /// let f = x.cosh().acosh(); @@ -1238,7 +1398,11 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let e = std::f16::consts::E; /// let f = e.tanh().atanh(); @@ -1272,7 +1436,11 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_gamma)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 5.0f16; /// @@ -1307,7 +1475,11 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_gamma)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// let x = 2.0f16; /// @@ -1342,7 +1514,11 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_erf)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// /// The error function relates what percent of a normal distribution lies /// /// within `x` standard deviations (scaled by `1/sqrt(2)`). /// fn within_standard_deviations(x: f16) -> f16 { @@ -1381,7 +1557,11 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_erf)] - /// # #[cfg(reliable_f16_math)] { + /// # #![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] + /// # #![cfg_attr(not(bootstrap), expect(internal_features))] + /// # #[cfg(not(miri))] + /// # #[cfg(not(bootstrap))] + /// # #[cfg(target_has_reliable_f16_math)] { /// let x: f16 = 0.123; /// /// let one = x.erf() + x.erfc(); diff --git a/library/std/tests/floats/f128.rs b/library/std/tests/floats/f128.rs index 677738bac8f98..8b13d6e65587a 100644 --- a/library/std/tests/floats/f128.rs +++ b/library/std/tests/floats/f128.rs @@ -1,9 +1,12 @@ // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy -#![cfg(reliable_f128)] +#![cfg(not(bootstrap))] +#![cfg(target_has_reliable_f128)] use std::f128::consts; use std::num::FpCategory as Fp; -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] use std::ops::Rem; use std::ops::{Add, Div, Mul, Sub}; @@ -19,7 +22,9 @@ const TOL: f128 = 1e-12; /// Tolerances for math that is allowed to be imprecise, usually due to multiple chained /// operations. -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] const TOL_IMPR: f128 = 1e-10; /// Smallest number @@ -66,8 +71,13 @@ fn test_num_f128() { assert_eq!(ten.div(two), ten / two); } +// FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support +// the intrinsics. + #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_num_f128_rem() { let ten = 10f128; let two = 2f128; @@ -75,28 +85,36 @@ fn test_num_f128_rem() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_min_nan() { assert_eq!(f128::NAN.min(2.0), 2.0); assert_eq!(2.0f128.min(f128::NAN), 2.0); } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_max_nan() { assert_eq!(f128::NAN.max(2.0), 2.0); assert_eq!(2.0f128.max(f128::NAN), 2.0); } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_minimum() { assert!(f128::NAN.minimum(2.0).is_nan()); assert!(2.0f128.minimum(f128::NAN).is_nan()); } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_maximum() { assert!(f128::NAN.maximum(2.0).is_nan()); assert!(2.0f128.maximum(f128::NAN).is_nan()); @@ -253,7 +271,9 @@ fn test_classify() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_floor() { assert_approx_eq!(1.0f128.floor(), 1.0f128, TOL_PRECISE); assert_approx_eq!(1.3f128.floor(), 1.0f128, TOL_PRECISE); @@ -268,7 +288,9 @@ fn test_floor() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_ceil() { assert_approx_eq!(1.0f128.ceil(), 1.0f128, TOL_PRECISE); assert_approx_eq!(1.3f128.ceil(), 2.0f128, TOL_PRECISE); @@ -283,7 +305,9 @@ fn test_ceil() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_round() { assert_approx_eq!(2.5f128.round(), 3.0f128, TOL_PRECISE); assert_approx_eq!(1.0f128.round(), 1.0f128, TOL_PRECISE); @@ -299,7 +323,9 @@ fn test_round() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_round_ties_even() { assert_approx_eq!(2.5f128.round_ties_even(), 2.0f128, TOL_PRECISE); assert_approx_eq!(1.0f128.round_ties_even(), 1.0f128, TOL_PRECISE); @@ -315,7 +341,9 @@ fn test_round_ties_even() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_trunc() { assert_approx_eq!(1.0f128.trunc(), 1.0f128, TOL_PRECISE); assert_approx_eq!(1.3f128.trunc(), 1.0f128, TOL_PRECISE); @@ -330,7 +358,9 @@ fn test_trunc() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_fract() { assert_approx_eq!(1.0f128.fract(), 0.0f128, TOL_PRECISE); assert_approx_eq!(1.3f128.fract(), 0.3f128, TOL_PRECISE); @@ -345,7 +375,9 @@ fn test_fract() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_abs() { assert_eq!(f128::INFINITY.abs(), f128::INFINITY); assert_eq!(1f128.abs(), 1f128); @@ -445,7 +477,9 @@ fn test_next_down() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_mul_add() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -462,7 +496,9 @@ fn test_mul_add() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_recip() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -484,7 +520,9 @@ fn test_recip() { // Many math functions allow for less accurate results, so the next tolerance up is used #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_powi() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -499,7 +537,9 @@ fn test_powi() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_powf() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -516,7 +556,9 @@ fn test_powf() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_sqrt_domain() { assert!(f128::NAN.sqrt().is_nan()); assert!(f128::NEG_INFINITY.sqrt().is_nan()); @@ -528,7 +570,9 @@ fn test_sqrt_domain() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_exp() { assert_eq!(1.0, 0.0f128.exp()); assert_approx_eq!(consts::E, 1.0f128.exp(), TOL); @@ -543,7 +587,9 @@ fn test_exp() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_exp2() { assert_eq!(32.0, 5.0f128.exp2()); assert_eq!(1.0, 0.0f128.exp2()); @@ -557,7 +603,9 @@ fn test_exp2() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_ln() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -573,7 +621,9 @@ fn test_ln() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_log() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -592,7 +642,9 @@ fn test_log() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_log2() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -609,7 +661,9 @@ fn test_log2() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_log10() { let nan: f128 = f128::NAN; let inf: f128 = f128::INFINITY; @@ -659,7 +713,9 @@ fn test_to_radians() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_asinh() { // Lower accuracy results are allowed, use increased tolerances assert_eq!(0.0f128.asinh(), 0.0f128); @@ -690,7 +746,9 @@ fn test_asinh() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_acosh() { assert_eq!(1.0f128.acosh(), 0.0f128); assert!(0.999f128.acosh().is_nan()); @@ -709,7 +767,9 @@ fn test_acosh() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_atanh() { assert_eq!(0.0f128.atanh(), 0.0f128); assert_eq!((-0.0f128).atanh(), -0.0f128); @@ -729,7 +789,9 @@ fn test_atanh() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_gamma() { // precision can differ among platforms assert_approx_eq!(1.0f128.gamma(), 1.0f128, TOL_IMPR); @@ -750,7 +812,9 @@ fn test_gamma() { } #[test] -#[cfg(reliable_f128_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f128_math)] fn test_ln_gamma() { assert_approx_eq!(1.0f128.ln_gamma().0, 0.0f128, TOL_IMPR); assert_eq!(1.0f128.ln_gamma().1, 1); @@ -781,7 +845,9 @@ fn test_real_consts() { assert_approx_eq!(frac_1_pi, 1f128 / pi, TOL_PRECISE); assert_approx_eq!(frac_2_pi, 2f128 / pi, TOL_PRECISE); - #[cfg(reliable_f128_math)] + #[cfg(not(miri))] + #[cfg(not(bootstrap))] + #[cfg(target_has_reliable_f128_math)] { let frac_2_sqrtpi: f128 = consts::FRAC_2_SQRT_PI; let sqrt2: f128 = consts::SQRT_2; diff --git a/library/std/tests/floats/f16.rs b/library/std/tests/floats/f16.rs index 0fc4df8115a24..8b3b344dd467b 100644 --- a/library/std/tests/floats/f16.rs +++ b/library/std/tests/floats/f16.rs @@ -1,5 +1,6 @@ // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy -#![cfg(reliable_f16)] +#![cfg(not(bootstrap))] +#![cfg(target_has_reliable_f16)] use std::f16::consts; use std::num::FpCategory as Fp; @@ -57,29 +58,40 @@ fn test_num_f16() { crate::test_num(10f16, 2f16); } +// FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support +// the intrinsics. + #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_min_nan() { assert_eq!(f16::NAN.min(2.0), 2.0); assert_eq!(2.0f16.min(f16::NAN), 2.0); } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_max_nan() { assert_eq!(f16::NAN.max(2.0), 2.0); assert_eq!(2.0f16.max(f16::NAN), 2.0); } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_minimum() { assert!(f16::NAN.minimum(2.0).is_nan()); assert!(2.0f16.minimum(f16::NAN).is_nan()); } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_maximum() { assert!(f16::NAN.maximum(2.0).is_nan()); assert!(2.0f16.maximum(f16::NAN).is_nan()); @@ -236,7 +248,9 @@ fn test_classify() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_floor() { assert_approx_eq!(1.0f16.floor(), 1.0f16, TOL_0); assert_approx_eq!(1.3f16.floor(), 1.0f16, TOL_0); @@ -251,7 +265,9 @@ fn test_floor() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_ceil() { assert_approx_eq!(1.0f16.ceil(), 1.0f16, TOL_0); assert_approx_eq!(1.3f16.ceil(), 2.0f16, TOL_0); @@ -266,7 +282,9 @@ fn test_ceil() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_round() { assert_approx_eq!(2.5f16.round(), 3.0f16, TOL_0); assert_approx_eq!(1.0f16.round(), 1.0f16, TOL_0); @@ -282,7 +300,9 @@ fn test_round() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_round_ties_even() { assert_approx_eq!(2.5f16.round_ties_even(), 2.0f16, TOL_0); assert_approx_eq!(1.0f16.round_ties_even(), 1.0f16, TOL_0); @@ -298,7 +318,9 @@ fn test_round_ties_even() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_trunc() { assert_approx_eq!(1.0f16.trunc(), 1.0f16, TOL_0); assert_approx_eq!(1.3f16.trunc(), 1.0f16, TOL_0); @@ -313,7 +335,9 @@ fn test_trunc() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_fract() { assert_approx_eq!(1.0f16.fract(), 0.0f16, TOL_0); assert_approx_eq!(1.3f16.fract(), 0.3f16, TOL_0); @@ -328,7 +352,9 @@ fn test_fract() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_abs() { assert_eq!(f16::INFINITY.abs(), f16::INFINITY); assert_eq!(1f16.abs(), 1f16); @@ -428,7 +454,9 @@ fn test_next_down() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_mul_add() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -445,7 +473,9 @@ fn test_mul_add() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_recip() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -461,7 +491,9 @@ fn test_recip() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_powi() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -476,7 +508,9 @@ fn test_powi() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_powf() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -493,7 +527,9 @@ fn test_powf() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_sqrt_domain() { assert!(f16::NAN.sqrt().is_nan()); assert!(f16::NEG_INFINITY.sqrt().is_nan()); @@ -505,7 +541,9 @@ fn test_sqrt_domain() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_exp() { assert_eq!(1.0, 0.0f16.exp()); assert_approx_eq!(2.718282, 1.0f16.exp(), TOL_0); @@ -520,7 +558,9 @@ fn test_exp() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_exp2() { assert_eq!(32.0, 5.0f16.exp2()); assert_eq!(1.0, 0.0f16.exp2()); @@ -534,7 +574,9 @@ fn test_exp2() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_ln() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -550,7 +592,9 @@ fn test_ln() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_log() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -569,7 +613,9 @@ fn test_log() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_log2() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -586,7 +632,9 @@ fn test_log2() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_log10() { let nan: f16 = f16::NAN; let inf: f16 = f16::INFINITY; @@ -634,7 +682,9 @@ fn test_to_radians() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_asinh() { assert_eq!(0.0f16.asinh(), 0.0f16); assert_eq!((-0.0f16).asinh(), -0.0f16); @@ -659,7 +709,9 @@ fn test_asinh() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_acosh() { assert_eq!(1.0f16.acosh(), 0.0f16); assert!(0.999f16.acosh().is_nan()); @@ -678,7 +730,9 @@ fn test_acosh() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_atanh() { assert_eq!(0.0f16.atanh(), 0.0f16); assert_eq!((-0.0f16).atanh(), -0.0f16); @@ -698,7 +752,9 @@ fn test_atanh() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_gamma() { // precision can differ among platforms assert_approx_eq!(1.0f16.gamma(), 1.0f16, TOL_0); @@ -719,7 +775,9 @@ fn test_gamma() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_ln_gamma() { assert_approx_eq!(1.0f16.ln_gamma().0, 0.0f16, TOL_0); assert_eq!(1.0f16.ln_gamma().1, 1); @@ -752,7 +810,9 @@ fn test_real_consts() { assert_approx_eq!(frac_1_pi, 1f16 / pi, TOL_0); assert_approx_eq!(frac_2_pi, 2f16 / pi, TOL_0); - #[cfg(reliable_f16_math)] + #[cfg(not(miri))] + #[cfg(not(bootstrap))] + #[cfg(target_has_reliable_f16_math)] { let frac_2_sqrtpi: f16 = consts::FRAC_2_SQRT_PI; let sqrt2: f16 = consts::SQRT_2; @@ -813,7 +873,9 @@ fn test_clamp_max_is_nan() { } #[test] -#[cfg(reliable_f16_math)] +#[cfg(not(miri))] +#[cfg(not(bootstrap))] +#[cfg(target_has_reliable_f16_math)] fn test_total_cmp() { use core::cmp::Ordering; diff --git a/library/std/tests/floats/lib.rs b/library/std/tests/floats/lib.rs index de5a3cdbd0f93..7884fc9239e20 100644 --- a/library/std/tests/floats/lib.rs +++ b/library/std/tests/floats/lib.rs @@ -1,4 +1,6 @@ #![feature(f16, f128, float_algebraic, float_gamma, float_minimum_maximum)] +#![cfg_attr(not(bootstrap), feature(cfg_target_has_reliable_f16_f128))] +#![cfg_attr(not(bootstrap), expect(internal_features))] // for reliable_f16_f128 use std::fmt; use std::ops::{Add, Div, Mul, Rem, Sub}; diff --git a/src/bootstrap/src/utils/tests/git.rs b/src/bootstrap/src/utils/tests/git.rs index bd40f398c7b10..d9dd9ab980088 100644 --- a/src/bootstrap/src/utils/tests/git.rs +++ b/src/bootstrap/src/utils/tests/git.rs @@ -129,6 +129,9 @@ impl GitCtx { fn git_cmd(&self) -> Command { let mut cmd = Command::new("git"); + cmd.env("GIT_CONFIG_NOSYSTEM", "1"); + cmd.env("GIT_CONFIG_SYSTEM", "/tmp/nonexistent"); + cmd.env("GIT_CONFIG_GLOBAL", "/tmp/nonexistent"); cmd.current_dir(&self.dir); cmd } diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 63859c0396e48..6d3e77b6b6e97 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -263,7 +263,7 @@ impl<'tcx> NonCopyConst<'tcx> { fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { let def_id = body_id.hir_id.owner.to_def_id(); let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); - let instance = ty::Instance::new(def_id, args); + let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None, diff --git a/tests/codegen/autodiff/inline.rs b/tests/codegen/autodiff/inline.rs new file mode 100644 index 0000000000000..e90faa4aa3802 --- /dev/null +++ b/tests/codegen/autodiff/inline.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat -Zautodiff=NoPostopt +//@ no-prefer-dynamic +//@ needs-enzyme + +#![feature(autodiff)] + +use std::autodiff::autodiff; + +#[autodiff(d_square, Reverse, Duplicated, Active)] +fn square(x: &f64) -> f64 { + x * x +} + +// CHECK: ; inline::d_square +// CHECK-NEXT: ; Function Attrs: alwaysinline +// CHECK-NOT: noinline +// CHECK-NEXT: define internal fastcc void @_ZN6inline8d_square17h021c74e92c259cdeE +fn main() { + let x = std::hint::black_box(3.0); + let mut dx1 = std::hint::black_box(1.0); + let _ = d_square(&x, &mut dx1, 1.0); + assert_eq!(dx1, 6.0); +} diff --git a/tests/run-make/amdgpu-kd/rmake.rs b/tests/run-make/amdgpu-kd/rmake.rs index a787fa1da93aa..ee0df966e0cf3 100644 --- a/tests/run-make/amdgpu-kd/rmake.rs +++ b/tests/run-make/amdgpu-kd/rmake.rs @@ -6,13 +6,19 @@ //@ needs-llvm-components: amdgpu //@ needs-rust-lld +use run_make_support::targets::is_windows_gnu; use run_make_support::{llvm_readobj, rustc}; fn main() { + // FIXME(#115985): rust-lld on gnu targets may spuriously fail with + // STATUS_HEAP_CORRUPTION (0xc0000374). + // To try to mitigate this we pass --threads=1 to the linker. + let extra_args = if is_windows_gnu() { ["-C", "link-arg=--threads=1"] } else { [] }; rustc() .crate_name("foo") .target("amdgcn-amd-amdhsa") .arg("-Ctarget-cpu=gfx900") + .args(&extra_args) .crate_type("cdylib") .input("foo.rs") .run(); diff --git a/tests/ui/asm/global-asm-mono-sym-fn.rs b/tests/ui/asm/global-asm-mono-sym-fn.rs new file mode 100644 index 0000000000000..0491e1e6ce1ea --- /dev/null +++ b/tests/ui/asm/global-asm-mono-sym-fn.rs @@ -0,0 +1,27 @@ +// Test that we're properly monomorphizing sym args in global asm blocks +// that point to associated items. + +//@ edition: 2021 +//@ needs-asm-support +//@ only-x86_64 +//@ build-pass + +#![no_main] + +use std::arch::global_asm; + +fn foo() { + loop {} +} + +trait Foo { + fn bar(); +} + +impl Foo for i32 { + fn bar() { + loop {} + } +} + +global_asm!(".global main", "main:", "call {}", sym ::bar); diff --git a/tests/ui/asm/naked-asm-mono-sym-fn.rs b/tests/ui/asm/naked-asm-mono-sym-fn.rs new file mode 100644 index 0000000000000..948c290c0b4fb --- /dev/null +++ b/tests/ui/asm/naked-asm-mono-sym-fn.rs @@ -0,0 +1,35 @@ +// Regression test for . +// Test that we're properly monomorphizing sym args in naked asm blocks +// that point to associated items. + +//@ edition: 2021 +//@ needs-asm-support +//@ only-x86_64 +//@ build-pass + +trait Tr { + extern "C" fn t(); +} + +enum E {} + +impl Tr for E { + extern "C" fn t() { + println!("Const generic: {}", C); + } +} + +#[unsafe(naked)] +extern "C" fn foo() { + core::arch::naked_asm!( + "push rax", + "call {fn}", + "pop rax", + "ret", + fn = sym ::t, + ); +} + +fn main() { + foo::>(); +} diff --git a/tests/ui/asm/named_const_simd_vec_len.rs b/tests/ui/asm/named_const_simd_vec_len.rs index 7df4d922d5c91..7fedeb7d4d122 100644 --- a/tests/ui/asm/named_const_simd_vec_len.rs +++ b/tests/ui/asm/named_const_simd_vec_len.rs @@ -3,6 +3,9 @@ //@ only-x86_64 //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![feature(repr_simd)] diff --git a/tests/ui/asm/normalizable-asm-ty.rs b/tests/ui/asm/normalizable-asm-ty.rs new file mode 100644 index 0000000000000..c1f3f3ecd6168 --- /dev/null +++ b/tests/ui/asm/normalizable-asm-ty.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ needs-asm-support +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +fn invoke(pc_section: &[usize]) { + unsafe { + std::arch::asm!( + "/* {} */", + in(reg) pc_section[0] + ); + } +} + +fn main() {} diff --git a/tests/ui/async-await/in-trait/cycle-if-impl-doesnt-apply.rs b/tests/ui/async-await/in-trait/cycle-if-impl-doesnt-apply.rs new file mode 100644 index 0000000000000..54992c986558c --- /dev/null +++ b/tests/ui/async-await/in-trait/cycle-if-impl-doesnt-apply.rs @@ -0,0 +1,39 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ edition: 2024 + +// Regression test for . +// Avoid unnecessarily computing the RPITIT type of the first impl when checking the WF of the +// second impl, since the first impl relies on the hidden type of the second impl. + +use std::future::Future; + +trait Handler {} + +struct W(T); + +trait SendTarget { + fn call(self) -> impl Future + Send; +} + +impl SendTarget for W +where + T: Handler + Send, +{ + async fn call(self) { + todo!() + } +} + +impl SendTarget for T +where + T: Handler + Send, +{ + async fn call(self) { + W(self).call().await + } +} + +fn main() {} diff --git a/tests/ui/cfg/disallowed-cli-cfgs.reliable_f128_.stderr b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f128_.stderr new file mode 100644 index 0000000000000..1b6e05060017e --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f128_.stderr @@ -0,0 +1,8 @@ +error: unexpected `--cfg target_has_reliable_f128` flag + | + = note: config `target_has_reliable_f128` is only supposed to be controlled by `--target` + = note: manually setting a built-in cfg can and does create incoherent behaviors + = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.reliable_f128_math_.stderr b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f128_math_.stderr new file mode 100644 index 0000000000000..86e7342b8fc1e --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f128_math_.stderr @@ -0,0 +1,8 @@ +error: unexpected `--cfg target_has_reliable_f128_math` flag + | + = note: config `target_has_reliable_f128_math` is only supposed to be controlled by `--target` + = note: manually setting a built-in cfg can and does create incoherent behaviors + = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.reliable_f16_.stderr b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f16_.stderr new file mode 100644 index 0000000000000..cf5000ecf2741 --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f16_.stderr @@ -0,0 +1,8 @@ +error: unexpected `--cfg target_has_reliable_f16` flag + | + = note: config `target_has_reliable_f16` is only supposed to be controlled by `--target` + = note: manually setting a built-in cfg can and does create incoherent behaviors + = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.reliable_f16_math_.stderr b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f16_math_.stderr new file mode 100644 index 0000000000000..079e5627e4c2b --- /dev/null +++ b/tests/ui/cfg/disallowed-cli-cfgs.reliable_f16_math_.stderr @@ -0,0 +1,8 @@ +error: unexpected `--cfg target_has_reliable_f16_math` flag + | + = note: config `target_has_reliable_f16_math` is only supposed to be controlled by `--target` + = note: manually setting a built-in cfg can and does create incoherent behaviors + = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/cfg/disallowed-cli-cfgs.rs b/tests/ui/cfg/disallowed-cli-cfgs.rs index e9661abf3abea..f7f9d2b5cd7f9 100644 --- a/tests/ui/cfg/disallowed-cli-cfgs.rs +++ b/tests/ui/cfg/disallowed-cli-cfgs.rs @@ -8,6 +8,7 @@ //@ revisions: target_thread_local_ relocation_model_ //@ revisions: fmt_debug_ //@ revisions: emscripten_wasm_eh_ +//@ revisions: reliable_f16_ reliable_f16_math_ reliable_f128_ reliable_f128_math_ //@ [overflow_checks_]compile-flags: --cfg overflow_checks //@ [debug_assertions_]compile-flags: --cfg debug_assertions @@ -35,6 +36,10 @@ //@ [relocation_model_]compile-flags: --cfg relocation_model="a" //@ [fmt_debug_]compile-flags: --cfg fmt_debug="shallow" //@ [emscripten_wasm_eh_]compile-flags: --cfg emscripten_wasm_eh +//@ [reliable_f16_]compile-flags: --cfg target_has_reliable_f16 +//@ [reliable_f16_math_]compile-flags: --cfg target_has_reliable_f16_math +//@ [reliable_f128_]compile-flags: --cfg target_has_reliable_f128 +//@ [reliable_f128_math_]compile-flags: --cfg target_has_reliable_f128_math fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-has-reliable-f16-f128.rs b/tests/ui/feature-gates/feature-gate-cfg-target-has-reliable-f16-f128.rs new file mode 100644 index 0000000000000..f1b0e3b01a423 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg-target-has-reliable-f16-f128.rs @@ -0,0 +1,12 @@ +//@ compile-flags: --check-cfg=cfg(target_has_reliable_f16,target_has_reliable_f16_math,target_has_reliable_f128,target_has_reliable_f128_math) + +fn main() { + cfg!(target_has_reliable_f16); + //~^ ERROR `cfg(target_has_reliable_f16)` is experimental and subject to change + cfg!(target_has_reliable_f16_math); + //~^ ERROR `cfg(target_has_reliable_f16_math)` is experimental and subject to change + cfg!(target_has_reliable_f128); + //~^ ERROR `cfg(target_has_reliable_f128)` is experimental and subject to change + cfg!(target_has_reliable_f128_math); + //~^ ERROR `cfg(target_has_reliable_f128_math)` is experimental and subject to change +} diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-has-reliable-f16-f128.stderr b/tests/ui/feature-gates/feature-gate-cfg-target-has-reliable-f16-f128.stderr new file mode 100644 index 0000000000000..9b90d18699e6f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg-target-has-reliable-f16-f128.stderr @@ -0,0 +1,39 @@ +error[E0658]: `cfg(target_has_reliable_f16)` is experimental and subject to change + --> $DIR/feature-gate-cfg-target-has-reliable-f16-f128.rs:4:10 + | +LL | cfg!(target_has_reliable_f16); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(cfg_target_has_reliable_f16_f128)]` 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[E0658]: `cfg(target_has_reliable_f16_math)` is experimental and subject to change + --> $DIR/feature-gate-cfg-target-has-reliable-f16-f128.rs:6:10 + | +LL | cfg!(target_has_reliable_f16_math); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(cfg_target_has_reliable_f16_f128)]` 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[E0658]: `cfg(target_has_reliable_f128)` is experimental and subject to change + --> $DIR/feature-gate-cfg-target-has-reliable-f16-f128.rs:8:10 + | +LL | cfg!(target_has_reliable_f128); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(cfg_target_has_reliable_f16_f128)]` 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[E0658]: `cfg(target_has_reliable_f128_math)` is experimental and subject to change + --> $DIR/feature-gate-cfg-target-has-reliable-f16-f128.rs:10:10 + | +LL | cfg!(target_has_reliable_f128_math); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(cfg_target_has_reliable_f16_f128)]` 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 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/float/target-has-reliable-nightly-float.rs b/tests/ui/float/target-has-reliable-nightly-float.rs new file mode 100644 index 0000000000000..ad8600fc63593 --- /dev/null +++ b/tests/ui/float/target-has-reliable-nightly-float.rs @@ -0,0 +1,31 @@ +//@ run-pass +//@ compile-flags: --check-cfg=cfg(target_has_reliable_f16,target_has_reliable_f16_math,target_has_reliable_f128,target_has_reliable_f128_math) +// Verify that the feature gates and config work and are registered as known config +// options. + +#![deny(unexpected_cfgs)] +#![feature(cfg_target_has_reliable_f16_f128)] + +#[cfg(target_has_reliable_f16)] +pub fn has_f16() {} + +#[cfg(target_has_reliable_f16_math)] +pub fn has_f16_math() {} + +#[cfg(target_has_reliable_f128 )] +pub fn has_f128() {} + +#[cfg(target_has_reliable_f128_math)] +pub fn has_f128_math() {} + +fn main() { + if cfg!(target_arch = "aarch64") && cfg!(target_os = "linux") { + // Aarch64+Linux is one target that has support for all features, so use it to spot + // check that the compiler does indeed enable these gates. + + assert!(cfg!(target_has_reliable_f16)); + assert!(cfg!(target_has_reliable_f16_math)); + assert!(cfg!(target_has_reliable_f128)); + assert!(cfg!(target_has_reliable_f128_math)); + } +} diff --git a/tests/ui/impl-trait/in-trait/cycle-if-impl-doesnt-apply.rs b/tests/ui/impl-trait/in-trait/cycle-if-impl-doesnt-apply.rs new file mode 100644 index 0000000000000..72e08ed350426 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/cycle-if-impl-doesnt-apply.rs @@ -0,0 +1,32 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ edition: 2024 + +// Regression test for . +// Avoid unnecessarily computing the RPITIT type of the first impl when checking the WF of the +// second impl, since the first impl relies on the hidden type of the second impl. + +trait Foo { + fn call(self) -> impl Send; +} + +trait Nested {} +impl Foo for T +where + T: Nested, +{ + fn call(self) -> impl Sized { + NotSatisfied.call() + } +} + +struct NotSatisfied; +impl Foo for NotSatisfied { + fn call(self) -> impl Sized { + todo!() + } +} + +fn main() {}