diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 3858bc80d4318..9bdbcf6ab9071 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -37,9 +37,10 @@ ast_passes_assoc_type_without_body = .suggestion = provide a definition for the type ast_passes_async_fn_in_const_trait_or_trait_impl = - async functions are not allowed in `const` {$in_impl -> - [true] trait impls - *[false] traits + async functions are not allowed in `const` {$context -> + [trait_impl] trait impls + [impl] impls + *[trait] traits } .label = associated functions of `const` cannot be declared `async` diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 425ba407fd61e..163dbc3350ba2 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -312,9 +312,15 @@ impl<'a> AstValidator<'a> { return; }; + let context = match parent { + TraitOrImpl::Trait { .. } => "trait", + TraitOrImpl::TraitImpl { .. } => "trait_impl", + TraitOrImpl::Impl { .. } => "impl", + }; + self.dcx().emit_err(errors::AsyncFnInConstTraitOrTraitImpl { async_keyword, - in_impl: matches!(parent, TraitOrImpl::TraitImpl { .. }), + context, const_keyword, }); } @@ -1714,9 +1720,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_async_fn_in_const_trait_or_impl(sig, parent); } } - Some(TraitOrImpl::Impl { constness }) => { + Some(parent @ TraitOrImpl::Impl { constness }) => { if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind { self.check_impl_fn_not_const(sig.header.constness, *constness); + self.check_async_fn_in_const_trait_or_impl(sig, parent); } } None => {} diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 48fd6a7cdd5d0..02e6ecfbaee74 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -76,7 +76,7 @@ pub(crate) struct TraitFnConst { pub(crate) struct AsyncFnInConstTraitOrTraitImpl { #[primary_span] pub async_keyword: Span, - pub in_impl: bool, + pub context: &'static str, #[label] pub const_keyword: Span, } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 84fc6ebbc3172..029c43e0ba82e 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -15,6 +15,7 @@ use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv}; use rustc_middle::{bug, span_bug}; +use rustc_session::config::CrateType; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate}; use rustc_target::callconv::PassMode; @@ -1136,8 +1137,17 @@ fn codegen_autodiff<'ll, 'tcx>( if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) { let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable); } - if tcx.sess.lto() != rustc_session::config::Lto::Fat { - let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto); + + let ct = tcx.crate_types(); + let lto = tcx.sess.lto(); + if ct.len() == 1 && ct.contains(&CrateType::Executable) { + if lto != rustc_session::config::Lto::Fat { + let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto); + } + } else { + if lto != rustc_session::config::Lto::Fat && !tcx.sess.opts.cg.linker_plugin_lto.enabled() { + let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto); + } } let fn_args = instance.args; diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 7fc9fb9cca2d7..69248cf91f241 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -34,6 +34,14 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return true; } + // FIXME(autodiff): replace this as per discussion in https://github.com/rust-lang/rust/pull/149033#discussion_r2535465880 + if tcx.has_attr(def_id, sym::autodiff_forward) + || tcx.has_attr(def_id, sym::autodiff_reverse) + || tcx.has_attr(def_id, sym::rustc_autodiff) + { + return true; + } + if tcx.has_attr(def_id, sym::rustc_intrinsic) { // Intrinsic fallback bodies are always cross-crate inlineable. // To ensure that the MIR inliner doesn't cluelessly try to inline fallback diff --git a/compiler/rustc_monomorphize/src/collector/autodiff.rs b/compiler/rustc_monomorphize/src/collector/autodiff.rs index 13868cca944a2..e3646596e75e6 100644 --- a/compiler/rustc_monomorphize/src/collector/autodiff.rs +++ b/compiler/rustc_monomorphize/src/collector/autodiff.rs @@ -7,6 +7,8 @@ use crate::collector::{MonoItems, create_fn_mono_item}; // mono so this does not interfere in `autodiff` intrinsics // codegen process. If they are unused, LLVM will remove them when // compiling with O3. +// FIXME(autodiff): Remove this whole file, as per discussion in +// https://github.com/rust-lang/rust/pull/149033#discussion_r2535465880 pub(crate) fn collect_autodiff_fn<'tcx>( tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs index 5f1ab6069ef00..eb0d328b51b7c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("ARM64 OpenHarmony".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index b548eb4939d42..8b3e943b4ccd0 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2918,7 +2918,7 @@ pub fn canonicalize>(path: P) -> io::Result { fs_imp::canonicalize(path.as_ref()) } -/// Creates a new, empty directory at the provided path +/// Creates a new, empty directory at the provided path. /// /// # Platform-specific behavior /// diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 9fd87e119906e..0a5d1153d860c 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1,24 +1,7 @@ use rand::RngCore; -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "illumos", - target_vendor = "apple", -))] use crate::assert_matches::assert_matches; -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "illumos", - target_vendor = "apple", -))] -use crate::fs::TryLockError; -use crate::fs::{self, File, FileTimes, OpenOptions}; +use crate::fs::{self, File, FileTimes, OpenOptions, TryLockError}; use crate::io::prelude::*; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; use crate::mem::MaybeUninit; @@ -222,15 +205,22 @@ fn file_test_io_seek_and_write() { } #[test] -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "solaris", - target_os = "illumos", - target_vendor = "apple", -))] +#[cfg_attr( + not(any( + windows, + target_os = "aix", + target_os = "cygwin", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_vendor = "apple", + )), + should_panic +)] fn file_lock_multiple_shared() { let tmpdir = tmpdir(); let filename = &tmpdir.join("file_lock_multiple_shared_test.txt"); @@ -247,15 +237,22 @@ fn file_lock_multiple_shared() { } #[test] -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "solaris", - target_os = "illumos", - target_vendor = "apple", -))] +#[cfg_attr( + not(any( + windows, + target_os = "aix", + target_os = "cygwin", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_vendor = "apple", + )), + should_panic +)] fn file_lock_blocking() { let tmpdir = tmpdir(); let filename = &tmpdir.join("file_lock_blocking_test.txt"); @@ -273,15 +270,22 @@ fn file_lock_blocking() { } #[test] -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "solaris", - target_os = "illumos", - target_vendor = "apple", -))] +#[cfg_attr( + not(any( + windows, + target_os = "aix", + target_os = "cygwin", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_vendor = "apple", + )), + should_panic +)] fn file_lock_drop() { let tmpdir = tmpdir(); let filename = &tmpdir.join("file_lock_dup_test.txt"); @@ -296,15 +300,22 @@ fn file_lock_drop() { } #[test] -#[cfg(any( - windows, - target_os = "freebsd", - target_os = "linux", - target_os = "netbsd", - target_os = "solaris", - target_os = "illumos", - target_vendor = "apple", -))] +#[cfg_attr( + not(any( + windows, + target_os = "aix", + target_os = "cygwin", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_vendor = "apple", + )), + should_panic +)] fn file_lock_dup() { let tmpdir = tmpdir(); let filename = &tmpdir.join("file_lock_dup_test.txt"); @@ -1252,7 +1263,7 @@ fn readlink_not_symlink() { } #[test] -#[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating hardlinks +#[cfg_attr(target_os = "android", ignore = "Android SELinux rules prevent creating hardlinks")] fn links_work() { let tmpdir = tmpdir(); let input = tmpdir.join("in.txt"); @@ -1748,7 +1759,7 @@ fn metadata_access_times() { /// Test creating hard links to symlinks. #[test] -#[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating hardlinks +#[cfg_attr(target_os = "android", ignore = "Android SELinux rules prevent creating hardlinks")] fn symlink_hard_link() { let tmpdir = tmpdir(); if !got_symlink_permission(&tmpdir) { diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 18c1501a655fe..7625409007a46 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -81,7 +81,7 @@ impl FileAttr { unsafe { Self { attr: (*info.as_ptr()).attribute, - size: (*info.as_ptr()).size, + size: (*info.as_ptr()).file_size, modified: uefi_fs::uefi_to_systemtime((*info.as_ptr()).modification_time), accessed: uefi_fs::uefi_to_systemtime((*info.as_ptr()).last_access_time), created: uefi_fs::uefi_to_systemtime((*info.as_ptr()).create_time), diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index a60b83213fd96..fb410c2851604 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -143,12 +143,6 @@ unsafe impl UserSafe for [T] { align_of::() } - /// # Safety - /// Behavior is undefined if any of these conditions are violated: - /// * `ptr` must be [valid] for writes of `size` many bytes, and it must be - /// properly aligned. - /// - /// [valid]: core::ptr#safety /// # Panics /// /// This function panics if: @@ -158,8 +152,7 @@ unsafe impl UserSafe for [T] { let elem_size = size_of::(); assert_eq!(size % elem_size, 0); let len = size / elem_size; - // SAFETY: The caller must uphold the safety contract for `from_raw_sized_unchecked` - unsafe { slice::from_raw_parts_mut(ptr as _, len) } + ptr::slice_from_raw_parts_mut(ptr as _, len) } } diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c0e9ed8aa4130..d772702df76e2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -182,7 +182,7 @@ target | std | notes [`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) -[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.5) +[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index 6cb0c2a040535..89e9f31688379 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -18,8 +18,6 @@ impl TestCx<'_> { self.fatal_proc_rec("rustdoc failed!", &proc_res); } - let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap()); - json_out.set_extension("json"); let res = self.run_command_to_procres( Command::new(self.config.jsondocck_path.as_ref().unwrap()) .arg("--doc-dir") diff --git a/tests/run-make/autodiff/rlib/dep.rs b/tests/run-make/autodiff/rlib/dep.rs new file mode 100644 index 0000000000000..6fc9b2c2473f4 --- /dev/null +++ b/tests/run-make/autodiff/rlib/dep.rs @@ -0,0 +1,7 @@ +pub fn f(x: f64, y: f64) -> f64 { + 2.0 * x + y +} + +pub fn g(x: f64) -> f64 { + 2.0 * x +} diff --git a/tests/run-make/autodiff/rlib/lib.rs b/tests/run-make/autodiff/rlib/lib.rs new file mode 100644 index 0000000000000..b459fed643a1c --- /dev/null +++ b/tests/run-make/autodiff/rlib/lib.rs @@ -0,0 +1,13 @@ +#![feature(autodiff)] +extern crate simple_dep; +use std::autodiff::*; + +#[inline(never)] +pub fn f2(x: f64) -> f64 { + x.sin() +} + +#[autodiff_forward(df1_lib, Dual, Dual)] +pub fn _f1(x: f64) -> f64 { + simple_dep::f(x, x) * f2(x) +} diff --git a/tests/run-make/autodiff/rlib/main.rs b/tests/run-make/autodiff/rlib/main.rs new file mode 100644 index 0000000000000..a3e5fcde0381b --- /dev/null +++ b/tests/run-make/autodiff/rlib/main.rs @@ -0,0 +1,8 @@ +extern crate foo; + +fn main() { + //dbg!("Running main.rs"); + let enzyme_y1_lib = foo::df1_lib(1.5, 1.0); + println!("output1: {:?}", enzyme_y1_lib.0); + println!("output2: {:?}", enzyme_y1_lib.1); +} diff --git a/tests/run-make/autodiff/rlib/rmake.rs b/tests/run-make/autodiff/rlib/rmake.rs new file mode 100644 index 0000000000000..59eaa836864c7 --- /dev/null +++ b/tests/run-make/autodiff/rlib/rmake.rs @@ -0,0 +1,66 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{cwd, run, rustc}; + +fn main() { + // Build the dependency crate. + rustc() + .input("dep.rs") + .arg("-Zautodiff=Enable") + .arg("--edition=2024") + .arg("-Copt-level=3") + .arg("--crate-name=simple_dep") + .arg("-Clinker-plugin-lto") + .arg("--crate-type=lib") + .emit("dep-info,metadata,link") + .run(); + + let cwd = cwd(); + let cwd_str = cwd.to_string_lossy(); + + let mydep = format!("-Ldependency={cwd_str}"); + + let simple_dep_rlib = + format!("--extern=simple_dep={}", cwd.join("libsimple_dep.rlib").to_string_lossy()); + + // Build the main library that depends on `simple_dep`. + rustc() + .input("lib.rs") + .arg("-Zautodiff=Enable") + .arg("--edition=2024") + .arg("-Copt-level=3") + .arg("--crate-name=foo") + .arg("-Clinker-plugin-lto") + .arg("--crate-type=lib") + .emit("dep-info,metadata,link") + .arg(&mydep) + .arg(&simple_dep_rlib) + .run(); + + let foo_rlib = format!("--extern=foo={}", cwd.join("libfoo.rlib").to_string_lossy()); + + // Build the final binary linking both rlibs. + rustc() + .input("main.rs") + .arg("-Zautodiff=Enable") + .arg("--edition=2024") + .arg("-Copt-level=3") + .arg("--crate-name=foo") + .arg("-Clto=fat") + .arg("--crate-type=bin") + .emit("dep-info,link") + .arg(&mydep) + .arg(&foo_rlib) + .arg(&simple_dep_rlib) + .run(); + + // Run the binary and check its output. + let binary = run("foo"); + assert!(binary.status().success(), "binary failed to run"); + + let binary_out = binary.stdout(); + let output = String::from_utf8_lossy(&binary_out); + assert!(output.contains("output1: 4.488727439718245")); + assert!(output.contains("output2: 3.3108023673168265")); +} diff --git a/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs new file mode 100644 index 0000000000000..0880ae509111a --- /dev/null +++ b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.rs @@ -0,0 +1,9 @@ +//@ edition:2024 + +#![feature(const_trait_impl)] +struct Foo; +const impl Foo { + async fn e() {} + //~^ ERROR async functions are not allowed in `const` impls +} +fn main() {} diff --git a/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr new file mode 100644 index 0000000000000..447222ea4abbd --- /dev/null +++ b/tests/ui/traits/const-traits/ice-149083-async-in-const-impl.stderr @@ -0,0 +1,10 @@ +error: async functions are not allowed in `const` impls + --> $DIR/ice-149083-async-in-const-impl.rs:6:5 + | +LL | const impl Foo { + | ----- associated functions of `const` cannot be declared `async` +LL | async fn e() {} + | ^^^^^ + +error: aborting due to 1 previous error +