diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 2a0175043b6f3..259ee25407a53 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -214,7 +214,7 @@ mod llvm_enzyme { // first get information about the annotable item: visibility, signature, name and generic // parameters. // these will be used to generate the differentiated version of the function - let Some((vis, sig, primal, generics, impl_of_trait)) = (match &item { + let Some((vis, sig, primal, generics, is_impl)) = (match &item { Annotatable::Item(iitem) => { extract_item_info(iitem).map(|(v, s, p, g)| (v, s, p, g, false)) } @@ -224,13 +224,13 @@ mod llvm_enzyme { } _ => None, }, - Annotatable::AssocItem(assoc_item, Impl { of_trait }) => match &assoc_item.kind { + Annotatable::AssocItem(assoc_item, Impl { of_trait: _ }) => match &assoc_item.kind { ast::AssocItemKind::Fn(box ast::Fn { sig, ident, generics, .. }) => Some(( assoc_item.vis.clone(), sig.clone(), ident.clone(), generics.clone(), - *of_trait, + true, )), _ => None, }, @@ -328,7 +328,7 @@ mod llvm_enzyme { span, &d_sig, &generics, - impl_of_trait, + is_impl, )], ); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 2c47c91d5192b..61e6133306066 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -133,7 +133,12 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option } fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - tcx.calculate_async_dtor(def_id, always_applicable::check_drop_impl) + let result = tcx.calculate_async_dtor(def_id, always_applicable::check_drop_impl); + // Async drop in libstd/libcore would become insta-stable — catch that mistake. + if result.is_some() && tcx.features().staged_api() { + span_bug!(tcx.def_span(def_id), "don't use async drop in libstd, it becomes insta-stable"); + } + result } /// Given a `DefId` for an opaque type in return position, find its parent item's return diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 7b8772eda2b38..e17629215b796 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -422,11 +422,8 @@ where fn build_drop(&mut self, bb: BasicBlock) { let drop_ty = self.place_ty(self.place); - if self.tcx().features().async_drop() - && self.elaborator.body().coroutine.is_some() - && self.elaborator.allow_async_drops() - && !self.elaborator.patch_ref().block(self.elaborator.body(), bb).is_cleanup - && drop_ty.needs_async_drop(self.tcx(), self.elaborator.typing_env()) + if !self.elaborator.patch_ref().block(self.elaborator.body(), bb).is_cleanup + && self.check_if_can_async_drop(drop_ty, false) { self.build_async_drop( self.place, @@ -452,6 +449,46 @@ where } } + /// Function to check if we can generate an async drop here + fn check_if_can_async_drop(&mut self, drop_ty: Ty<'tcx>, call_destructor_only: bool) -> bool { + let is_async_drop_feature_enabled = if self.tcx().features().async_drop() { + true + } else { + // Check if the type needing async drop comes from a dependency crate. + if let ty::Adt(adt_def, _) = drop_ty.kind() { + !adt_def.did().is_local() && adt_def.async_destructor(self.tcx()).is_some() + } else { + false + } + }; + + // Short-circuit before calling needs_async_drop/is_async_drop, as those + // require the `async_drop` lang item to exist (which may not be present + // in minimal/custom core environments like cranelift's mini_core). + if !is_async_drop_feature_enabled + || !self.elaborator.body().coroutine.is_some() + || !self.elaborator.allow_async_drops() + { + return false; + } + + let needs_async_drop = if call_destructor_only { + drop_ty.is_async_drop(self.tcx(), self.elaborator.typing_env()) + } else { + drop_ty.needs_async_drop(self.tcx(), self.elaborator.typing_env()) + }; + + // Async drop in libstd/libcore would become insta-stable — catch that mistake. + if needs_async_drop && self.tcx().features().staged_api() { + span_bug!( + self.source_info.span, + "don't use async drop in libstd, it becomes insta-stable" + ); + } + + needs_async_drop + } + /// This elaborates a single drop instruction, located at `bb`, and /// patches over it. /// @@ -1003,12 +1040,7 @@ where ) -> BasicBlock { debug!("destructor_call_block({:?}, {:?})", self, succ); let ty = self.place_ty(self.place); - if self.tcx().features().async_drop() - && self.elaborator.body().coroutine.is_some() - && self.elaborator.allow_async_drops() - && !unwind.is_cleanup() - && ty.is_async_drop(self.tcx(), self.elaborator.typing_env()) - { + if !unwind.is_cleanup() && self.check_if_can_async_drop(ty, true) { self.build_async_drop(self.place, ty, None, succ, unwind, dropline, true) } else { self.destructor_call_block_sync((succ, unwind)) @@ -1078,12 +1110,7 @@ where let loop_block = self.elaborator.patch().new_block(loop_block); let place = tcx.mk_place_deref(ptr); - if self.tcx().features().async_drop() - && self.elaborator.body().coroutine.is_some() - && self.elaborator.allow_async_drops() - && !unwind.is_cleanup() - && ety.needs_async_drop(self.tcx(), self.elaborator.typing_env()) - { + if !unwind.is_cleanup() && self.check_if_can_async_drop(ety, false) { self.build_async_drop( place, ety, @@ -1368,12 +1395,7 @@ where fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let drop_ty = self.place_ty(self.place); - if self.tcx().features().async_drop() - && self.elaborator.body().coroutine.is_some() - && self.elaborator.allow_async_drops() - && !unwind.is_cleanup() - && drop_ty.needs_async_drop(self.tcx(), self.elaborator.typing_env()) - { + if !unwind.is_cleanup() && self.check_if_can_async_drop(drop_ty, false) { self.build_async_drop( self.place, drop_ty, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 2b58a65051e1a..812e087a0cf69 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -92,7 +92,40 @@ where let value = infcx.commit_if_ok(|_| { let ocx = ObligationCtxt::new(infcx); let value = op(&ocx).map_err(|_| { - infcx.dcx().span_delayed_bug(span, format!("error performing operation: {name}")) + infcx.tcx.check_potentially_region_dependent_goals(root_def_id).err().unwrap_or_else( + // FIXME: In this region-dependent context, `type_op` should only fail due to + // region-dependent goals. Any other kind of failure indicates a bug and we + // should ICE. + // + // In principle, all non-region errors are expected to be emitted before + // borrowck. Such errors should taint the body and prevent borrowck from + // running at all. However, this invariant does not currently hold. + // + // Consider: + // + // ```ignore (illustrative) + // struct Foo(T) + // where + // T: Iterator, + // ::Item: Default; + // + // fn foo() -> Foo { + // loop {} + // } + // ``` + // + // Here, `fn foo` ought to error and taint the body before MIR build, since + // `Foo` is not well-formed. However, we currently avoid checking this + // during HIR typeck to prevent duplicate diagnostics. + // + // If we ICE here on any non-region-dependent failure, we would trigger ICEs + // too often for such cases. For now, we emit a delayed bug instead. + || { + infcx + .dcx() + .span_delayed_bug(span, format!("error performing operation: {name}")) + }, + ) })?; let errors = ocx.evaluate_obligations_error_on_ambiguity(); if errors.is_empty() { diff --git a/library/std/src/sys/args/xous.rs b/library/std/src/sys/args/xous.rs index 2010bad14d1fb..9025ed4f1354c 100644 --- a/library/std/src/sys/args/xous.rs +++ b/library/std/src/sys/args/xous.rs @@ -1,9 +1,8 @@ pub use super::common::Args; -use crate::sys::pal::os::get_application_parameters; -use crate::sys::pal::os::params::ArgumentList; +use crate::sys::pal::params::{self, ArgumentList}; pub fn args() -> Args { - let Some(params) = get_application_parameters() else { + let Some(params) = params::get() else { return Args::new(vec![]); }; diff --git a/library/std/src/sys/env/xous.rs b/library/std/src/sys/env/xous.rs index 8f65f30d35fcc..5a8a875984692 100644 --- a/library/std/src/sys/env/xous.rs +++ b/library/std/src/sys/env/xous.rs @@ -4,7 +4,7 @@ use crate::ffi::{OsStr, OsString}; use crate::io; use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; use crate::sync::{Mutex, Once}; -use crate::sys::pal::os::{get_application_parameters, params}; +use crate::sys::pal::params; static ENV: Atomic = AtomicUsize::new(0); static ENV_INIT: Once = Once::new(); @@ -13,7 +13,7 @@ type EnvStore = Mutex>; fn get_env_store() -> &'static EnvStore { ENV_INIT.call_once(|| { let env_store = EnvStore::default(); - if let Some(params) = get_application_parameters() { + if let Some(params) = params::get() { for param in params { if let Ok(envs) = params::EnvironmentBlock::try_from(¶m) { let mut env_store = env_store.lock().unwrap(); diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 87c99068929c3..9b22fb88c998d 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -1,7 +1,55 @@ #![forbid(unsafe_op_in_unsafe_fn)] pub mod os; +pub mod params; #[path = "../unsupported/common.rs"] mod common; pub use common::*; + +#[cfg(not(test))] +#[cfg(feature = "panic-unwind")] +mod eh_unwinding { + pub(crate) struct EhFrameFinder; + pub(crate) static mut EH_FRAME_ADDRESS: usize = 0; + pub(crate) static EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder; + + unsafe impl unwind::EhFrameFinder for EhFrameFinder { + fn find(&self, _pc: usize) -> Option { + if unsafe { EH_FRAME_ADDRESS == 0 } { + None + } else { + Some(unwind::FrameInfo { + text_base: None, + kind: unwind::FrameInfoKind::EhFrame(unsafe { EH_FRAME_ADDRESS }), + }) + } + } + } +} + +#[cfg(not(test))] +mod c_compat { + use crate::os::xous::ffi::exit; + + unsafe extern "C" { + fn main() -> u32; + } + + #[unsafe(no_mangle)] + pub extern "C" fn abort() { + exit(1); + } + + #[unsafe(no_mangle)] + pub extern "C" fn _start(eh_frame: usize, params: *mut u8) { + #[cfg(feature = "panic-unwind")] + { + unsafe { super::eh_unwinding::EH_FRAME_ADDRESS = eh_frame }; + unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok(); + } + + unsafe { super::params::set(params) }; + exit(unsafe { main() }); + } +} diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs index 0f5a708863f72..fe8addeafd2bc 100644 --- a/library/std/src/sys/pal/xous/os.rs +++ b/library/std/src/sys/pal/xous/os.rs @@ -2,66 +2,8 @@ use super::unsupported; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::path::{self, PathBuf}; -use crate::sync::atomic::{Atomic, AtomicPtr, Ordering}; use crate::{fmt, io}; -pub(crate) mod params; - -static PARAMS_ADDRESS: Atomic<*mut u8> = AtomicPtr::new(core::ptr::null_mut()); - -#[cfg(not(test))] -#[cfg(feature = "panic-unwind")] -mod eh_unwinding { - pub(crate) struct EhFrameFinder; - pub(crate) static mut EH_FRAME_ADDRESS: usize = 0; - pub(crate) static EH_FRAME_SETTINGS: EhFrameFinder = EhFrameFinder; - - unsafe impl unwind::EhFrameFinder for EhFrameFinder { - fn find(&self, _pc: usize) -> Option { - if unsafe { EH_FRAME_ADDRESS == 0 } { - None - } else { - Some(unwind::FrameInfo { - text_base: None, - kind: unwind::FrameInfoKind::EhFrame(unsafe { EH_FRAME_ADDRESS }), - }) - } - } - } -} - -#[cfg(not(test))] -mod c_compat { - use crate::os::xous::ffi::exit; - unsafe extern "C" { - fn main() -> u32; - } - - #[unsafe(no_mangle)] - pub extern "C" fn abort() { - exit(1); - } - - #[unsafe(no_mangle)] - pub extern "C" fn _start(eh_frame: usize, params_address: usize) { - #[cfg(feature = "panic-unwind")] - { - unsafe { super::eh_unwinding::EH_FRAME_ADDRESS = eh_frame }; - unwind::set_custom_eh_frame_finder(&super::eh_unwinding::EH_FRAME_SETTINGS).ok(); - } - - if params_address != 0 { - let params_address = crate::ptr::with_exposed_provenance_mut::(params_address); - if unsafe { - super::params::ApplicationParameters::new_from_ptr(params_address).is_some() - } { - super::PARAMS_ADDRESS.store(params_address, core::sync::atomic::Ordering::Relaxed); - } - } - exit(unsafe { main() }); - } -} - pub fn getcwd() -> io::Result { unsupported() } @@ -106,11 +48,6 @@ pub fn current_exe() -> io::Result { unsupported() } -pub(crate) fn get_application_parameters() -> Option { - let params_address = PARAMS_ADDRESS.load(Ordering::Relaxed); - unsafe { params::ApplicationParameters::new_from_ptr(params_address) } -} - pub fn temp_dir() -> PathBuf { panic!("no filesystem on this platform") } diff --git a/library/std/src/sys/pal/xous/os/params.rs b/library/std/src/sys/pal/xous/params.rs similarity index 67% rename from library/std/src/sys/pal/xous/os/params.rs rename to library/std/src/sys/pal/xous/params.rs index 0d02cf35477f9..d6f671e9a6b68 100644 --- a/library/std/src/sys/pal/xous/os/params.rs +++ b/library/std/src/sys/pal/xous/params.rs @@ -1,75 +1,100 @@ -/// Xous passes a pointer to the parameter block as the second argument. -/// This is used for passing flags such as environment variables. The -/// format of the argument block is: -/// -/// #[repr(C)] -/// struct BlockHeader { -/// /// Magic number that identifies this block. Must be printable ASCII. -/// magic: [u8; 4], -/// -/// /// The size of the data block. Does not include this header. May be 0. -/// size: u32, -/// -/// /// The contents of this block. Varies depending on the block type. -/// data: [u8; 0], -/// } -/// -/// There is a BlockHeader at the start that has magic `AppP`, and the data -/// that follows is the number of blocks present: -/// -/// #[repr(C)] -/// struct ApplicationParameters { -/// magic: b"AppP", -/// size: 4u32, -/// -/// /// The size of the entire application slice, in bytes, including all headers -/// length: u32, -/// -/// /// Number of application parameters present. Must be at least 1 (this block) -/// entries: (parameter_count as u32).to_bytes_le(), -/// } -/// -/// #[repr(C)] -/// struct EnvironmentBlock { -/// magic: b"EnvB", -/// -/// /// Total number of bytes, excluding this header -/// size: 2+data.len(), -/// -/// /// The number of environment variables -/// count: u16, -/// -/// /// Environment variable iteration -/// data: [u8; 0], -/// } -/// -/// Environment variables are present in an `EnvB` block. The `data` section is -/// a sequence of bytes of the form: -/// -/// (u16 /* key_len */; [0u8; key_len as usize] /* key */, -/// u16 /* val_len */ [0u8; val_len as usize]) -/// -/// #[repr(C)] -/// struct ArgumentList { -/// magic: b"ArgL", -/// -/// /// Total number of bytes, excluding this header -/// size: 2+data.len(), -/// -/// /// The number of arguments variables -/// count: u16, -/// -/// /// Argument variable iteration -/// data: [u8; 0], -/// } -/// -/// Args are just an array of strings that represent command line arguments. -/// They are a sequence of the form: -/// -/// (u16 /* val_len */ [0u8; val_len as usize]) -use core::slice; +//! Xous passes a pointer to the parameter block as the second argument. +//! This is used for passing flags such as environment variables. The +//! format of the argument block is: +//! +//! #[repr(C)] +//! struct BlockHeader { +//! /// Magic number that identifies this block. Must be printable ASCII. +//! magic: [u8; 4], +//! +//! /// The size of the data block. Does not include this header. May be 0. +//! size: u32, +//! +//! /// The contents of this block. Varies depending on the block type. +//! data: [u8; 0], +//! } +//! +//! There is a BlockHeader at the start that has magic `AppP`, and the data +//! that follows is the number of blocks present: +//! +//! #[repr(C)] +//! struct ApplicationParameters { +//! magic: b"AppP", +//! size: 4u32, +//! +//! /// The size of the entire application slice, in bytes, including all headers +//! length: u32, +//! +//! /// Number of application parameters present. Must be at least 1 (this block) +//! entries: (parameter_count as u32).to_bytes_le(), +//! } +//! +//! #[repr(C)] +//! struct EnvironmentBlock { +//! magic: b"EnvB", +//! +//! /// Total number of bytes, excluding this header +//! size: 2+data.len(), +//! +//! /// The number of environment variables +//! count: u16, +//! +//! /// Environment variable iteration +//! data: [u8; 0], +//! } +//! +//! Environment variables are present in an `EnvB` block. The `data` section is +//! a sequence of bytes of the form: +//! +//! (u16 /* key_len */; [0u8; key_len as usize] /* key */, +//! u16 /* val_len */ [0u8; val_len as usize]) +//! +//! #[repr(C)] +//! struct ArgumentList { +//! magic: b"ArgL", +//! +//! /// Total number of bytes, excluding this header +//! size: 2+data.len(), +//! +//! /// The number of arguments variables +//! count: u16, +//! +//! /// Argument variable iteration +//! data: [u8; 0], +//! } +//! +//! Args are just an array of strings that represent command line arguments. +//! They are a sequence of the form: +//! +//! (u16 /* val_len */ [0u8; val_len as usize]) use crate::ffi::OsString; +use crate::slice; + +#[cfg(test)] +mod tests; + +static mut PARAMS: *mut u8 = crate::ptr::null_mut(); + +/// Remember the location of the parameter block. +/// +/// # Safety +/// * This function may only be called before `main`. +/// * `data` must either be `null` or point to a valid parameter block. +pub(super) unsafe fn set(data: *mut u8) { + // SAFETY: + // Since this function is called before `main`, there cannot be any threads + // already running. Thus this write cannot race, and all threads will observe + // this write and the parameter block initialization since it happens-before + // their creation. + unsafe { PARAMS = data }; +} + +pub(crate) fn get() -> Option { + // SAFETY: See above. + let data = unsafe { PARAMS }; + unsafe { ApplicationParameters::new_from_ptr(data) } +} /// Magic number indicating we have an environment block const ENV_MAGIC: [u8; 4] = *b"EnvB"; @@ -80,9 +105,6 @@ const ARGS_MAGIC: [u8; 4] = *b"ArgL"; /// Magic number indicating the loader has passed application parameters const PARAMS_MAGIC: [u8; 4] = *b"AppP"; -#[cfg(test)] -mod tests; - pub(crate) struct ApplicationParameters { data: &'static [u8], offset: usize, @@ -90,7 +112,7 @@ pub(crate) struct ApplicationParameters { } impl ApplicationParameters { - pub(crate) unsafe fn new_from_ptr(data: *const u8) -> Option { + unsafe fn new_from_ptr(data: *const u8) -> Option { if data.is_null() { return None; } diff --git a/library/std/src/sys/pal/xous/os/params/tests.rs b/library/std/src/sys/pal/xous/params/tests.rs similarity index 100% rename from library/std/src/sys/pal/xous/os/params/tests.rs rename to library/std/src/sys/pal/xous/params/tests.rs diff --git a/src/ci/docker/host-x86_64/disabled/dist-aarch64-android/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-aarch64-android/Dockerfile index dea445c295c99..b3c46d5590f09 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-aarch64-android/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-aarch64-android/Dockerfile @@ -13,13 +13,12 @@ ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/ ENV HOSTS=aarch64-linux-android -ENV RUST_CONFIGURE_ARGS \ - --aarch64-linux-android-ndk=/android/ndk/arm64-21 \ +ENV RUST_CONFIGURE_ARGS="--aarch64-linux-android-ndk=/android/ndk/arm64-21 \ --disable-rpath \ --enable-extended \ - --enable-cargo-openssl-static + --enable-cargo-openssl-static" -ENV SCRIPT python3 ../x.py dist --target $HOSTS --host $HOSTS +ENV SCRIPT="python3 ../x.py dist --target $HOSTS --host $HOSTS" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile index f986c38ea02da..4403611f2f047 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-armv7-android/Dockerfile @@ -19,11 +19,10 @@ ENV DEP_Z_ROOT=/android/ndk/arm-14/sysroot/usr/ ENV HOSTS=armv7-linux-androideabi -ENV RUST_CONFIGURE_ARGS \ - --armv7-linux-androideabi-ndk=/android/ndk/arm \ +ENV RUST_CONFIGURE_ARGS="--armv7-linux-androideabi-ndk=/android/ndk/arm \ --disable-rpath \ --enable-extended \ - --enable-cargo-openssl-static + --enable-cargo-openssl-static" # We support api level 14, but api level 21 is required to build llvm. To # overcome this problem we use a ndk with api level 21 to build llvm and then @@ -32,12 +31,11 @@ ENV RUST_CONFIGURE_ARGS \ # level 14), the default linker behavior is to generate an error, to allow the # build to finish we use --warn-unresolved-symbols. Note that the missing # symbols does not affect std, only the compiler (llvm) and cargo (openssl). -ENV SCRIPT \ - python3 ../x.py --stage 2 build src/llvm --host $HOSTS --target $HOSTS && \ - (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ +ENV SCRIPT="python3 ../x.py --stage 2 build src/llvm --host $HOSTS --target $HOSTS && \ + (export RUSTFLAGS=\"-C link-arg=-Wl,--warn-unresolved-symbols\"; \ rm /android/ndk/arm && \ ln -s /android/ndk/arm-14 /android/ndk/arm && \ - python3 ../x.py dist --host $HOSTS --target $HOSTS) + python3 ../x.py dist --host $HOSTS --target $HOSTS)" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile index 4dfbc72560783..f36901794b9cd 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-i686-android/Dockerfile @@ -19,11 +19,10 @@ ENV DEP_Z_ROOT=/android/ndk/x86-14/sysroot/usr/ ENV HOSTS=i686-linux-android -ENV RUST_CONFIGURE_ARGS \ - --i686-linux-android-ndk=/android/ndk/x86 \ +ENV RUST_CONFIGURE_ARGS="--i686-linux-android-ndk=/android/ndk/x86 \ --disable-rpath \ --enable-extended \ - --enable-cargo-openssl-static + --enable-cargo-openssl-static" # We support api level 14, but api level 21 is required to build llvm. To # overcome this problem we use a ndk with api level 21 to build llvm and then @@ -32,12 +31,11 @@ ENV RUST_CONFIGURE_ARGS \ # level 14), the default linker behavior is to generate an error, to allow the # build to finish we use --warn-unresolved-symbols. Note that the missing # symbols does not affect std, only the compiler (llvm) and cargo (openssl). -ENV SCRIPT \ - python3 ../x.py --stage 2 build src/llvm --host $HOSTS --target $HOSTS && \ - (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ +ENV SCRIPT="python3 ../x.py --stage 2 build src/llvm --host $HOSTS --target $HOSTS && \ + (export RUSTFLAGS=\"-C link-arg=-Wl,--warn-unresolved-symbols\"; \ rm /android/ndk/x86 && \ ln -s /android/ndk/x86-14 /android/ndk/x86 && \ - python3 ../x.py dist --host $HOSTS --target $HOSTS) + python3 ../x.py dist --host $HOSTS --target $HOSTS)" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/disabled/dist-m68k-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-m68k-linux/Dockerfile index cbac2310d0dfd..8444e94b2a286 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-m68k-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-m68k-linux/Dockerfile @@ -24,5 +24,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=m68k-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--host=$HOSTS --enable-extended" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/disabled/dist-powerpcspe-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-powerpcspe-linux/Dockerfile index 34c487412145b..2dd10d30a070f 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-powerpcspe-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-powerpcspe-linux/Dockerfile @@ -23,5 +23,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=powerpc-unknown-linux-gnuspe -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/disabled/dist-sparc64-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-sparc64-linux/Dockerfile index a8e7583ccb017..e61251cbe047c 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-sparc64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-sparc64-linux/Dockerfile @@ -23,5 +23,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=sparc64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-android/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-android/Dockerfile index d44779763e544..b92d5729cbb88 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-android/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-android/Dockerfile @@ -13,13 +13,12 @@ ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/ ENV HOSTS=x86_64-linux-android -ENV RUST_CONFIGURE_ARGS \ - --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \ +ENV RUST_CONFIGURE_ARGS="--x86_64-linux-android-ndk=/android/ndk/x86_64-21 \ --disable-rpath \ --enable-extended \ - --enable-cargo-openssl-static + --enable-cargo-openssl-static" -ENV SCRIPT python3 ../x.py dist --target $HOSTS --host $HOSTS +ENV SCRIPT="python3 ../x.py dist --target $HOSTS --host $HOSTS" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/Dockerfile index 5d594a80581bb..7839c8d9494f7 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-dragonfly/Dockerfile @@ -33,5 +33,5 @@ ENV \ ENV HOSTS=x86_64-unknown-dragonfly -ENV RUST_CONFIGURE_ARGS --enable-extended -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile index 637b5fa22f974..6692e82847c32 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile @@ -43,10 +43,10 @@ RUN sh /scripts/sccache.sh ENV HOST=x86_64-unknown-haiku ENV TARGET=target.$HOST -ENV RUST_CONFIGURE_ARGS --disable-jemalloc \ +ENV RUST_CONFIGURE_ARGS="--disable-jemalloc \ --set=$TARGET.cc=x86_64-unknown-haiku-gcc \ --set=$TARGET.cxx=x86_64-unknown-haiku-g++ \ - --set=$TARGET.llvm-config=/bin/llvm-config-haiku -ENV EXTERNAL_LLVM 1 + --set=$TARGET.llvm-config=/bin/llvm-config-haiku" +ENV EXTERNAL_LLVM="1" -ENV SCRIPT python3 ../x.py dist --host=$HOST --target=$HOST +ENV SCRIPT="python3 ../x.py dist --host=$HOST --target=$HOST" diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-redox/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-redox/Dockerfile index e9188b42f5d75..6a647ac162e4e 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-redox/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-redox/Dockerfile @@ -18,5 +18,5 @@ ENV \ CC_x86_64_unknown_redox=x86_64-unknown-redox-gcc \ CXX_x86_64_unknown_redox=x86_64-unknown-redox-g++ -ENV RUST_CONFIGURE_ARGS --enable-extended -ENV SCRIPT python3 ../x.py dist --host='' --target x86_64-unknown-redox +ENV RUST_CONFIGURE_ARGS="--enable-extended" +ENV SCRIPT="python3 ../x.py dist --host= --target x86_64-unknown-redox" diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile index a52c3839196f7..fb647dedbc217 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile @@ -91,9 +91,8 @@ RUN sh /scripts/sccache.sh # Avoid "fatal: detected dubious ownership in repository at '/checkout'" error RUN git config --global --add safe.directory /checkout -ENV RUST_CONFIGURE_ARGS \ - --qemu-riscv64-rootfs=/tmp/rootfs \ - --set target.riscv64gc-unknown-linux-gnu.linker=riscv64-linux-gnu-gcc -ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target riscv64gc-unknown-linux-gnu +ENV RUST_CONFIGURE_ARGS="--qemu-riscv64-rootfs=/tmp/rootfs \ + --set target.riscv64gc-unknown-linux-gnu.linker=riscv64-linux-gnu-gcc" +ENV SCRIPT="python3 ../x.py --stage 2 test --host= --target riscv64gc-unknown-linux-gnu" ENV NO_CHANGE_USER=1 diff --git a/tests/codegen-llvm/autodiff/impl.rs b/tests/codegen-llvm/autodiff/impl.rs new file mode 100644 index 0000000000000..185ea6af52e0f --- /dev/null +++ b/tests/codegen-llvm/autodiff/impl.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -Zautodiff=Enable -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// Just check it does not crash for now +// CHECK: ; +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[derive(Clone)] +struct OptProblem { + a: f64, + b: f64, +} + +impl OptProblem { + #[autodiff_reverse(d_objective, Duplicated, Duplicated, Duplicated)] + fn objective(&self, x: &[f64], out: &mut f64) { + *out = self.a + x[0].sqrt() * self.b + } +} + +fn main() { + let p = OptProblem { a: 1., b: 2. }; + let x = [2.0]; + + let mut p_shadow = OptProblem { a: 0., b: 0. }; + let mut dx = [0.0]; + let mut out = 0.0; + let mut dout = 1.0; + + p.d_objective(&mut p_shadow, &x, &mut dx, &mut out, &mut dout); + + dbg!(dx); +} diff --git a/tests/ui/async-await/async-drop/async-drop-run-without-feature/async-drop-run-without-feature.rs b/tests/ui/async-await/async-drop/async-drop-run-without-feature/async-drop-run-without-feature.rs new file mode 100644 index 0000000000000..815a99ea712ff --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-run-without-feature/async-drop-run-without-feature.rs @@ -0,0 +1,18 @@ +//@ edition: 2024 +//@ run-pass +//@ compile-flags: -Z mir-opt-level=0 +//@ aux-crate: async_drop_crate_dep=async-drop-crate-dep.rs + +use std::{ //~ WARN found async drop types in dependency + pin::pin, + task::{Context, Waker}, +}; + +extern crate async_drop_crate_dep; + +fn main() { + let mut context = Context::from_waker(Waker::noop()); + let future = pin!(async { async_drop_crate_dep::run().await }); + // For some reason, putting this value into a variable is load-bearing. + let _x = future.poll(&mut context); +} diff --git a/tests/ui/async-await/async-drop/async-drop-run-without-feature/async-drop-run-without-feature.stderr b/tests/ui/async-await/async-drop/async-drop-run-without-feature/async-drop-run-without-feature.stderr new file mode 100644 index 0000000000000..70eca25edcbc0 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-run-without-feature/async-drop-run-without-feature.stderr @@ -0,0 +1,10 @@ +warning: found async drop types in dependency `async_drop_crate_dep`, but async_drop feature is disabled for `async_drop_run_without_feature` + --> $DIR/async-drop-run-without-feature.rs:6:1 + | +LL | use std::{ + | ^ + | + = help: if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/async-drop/async-drop-run-without-feature/auxiliary/async-drop-crate-dep.rs b/tests/ui/async-await/async-drop/async-drop-run-without-feature/auxiliary/async-drop-crate-dep.rs new file mode 100644 index 0000000000000..9e10b2d39bcd5 --- /dev/null +++ b/tests/ui/async-await/async-drop/async-drop-run-without-feature/auxiliary/async-drop-crate-dep.rs @@ -0,0 +1,23 @@ +//@ edition: 2024 +#![feature(async_drop)] +use std::future::AsyncDrop; +use std::pin::Pin; + +pub async fn run() { + let _st = St; +} + +struct St; + +impl Drop for St { + fn drop(&mut self) {} +} + +impl AsyncDrop for St { + async fn drop(self: Pin<&mut Self>) { + // Removing this line makes the program panic "normally" (not abort). + nothing().await; + } +} + +async fn nothing() {} diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.current.stderr b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.current.stderr new file mode 100644 index 0000000000000..779f143b64f92 --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.current.stderr @@ -0,0 +1,20 @@ +error[E0284]: type annotations needed + --> $DIR/ambiguity-due-to-uniquification-4.rs:17:47 + | +LL | pub fn f<'a, 'b, T: Trait<'a> + Trait<'b>>(v: >::Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: cannot satisfy `>::Type == _` + +error[E0284]: type annotations needed + --> $DIR/ambiguity-due-to-uniquification-4.rs:17:47 + | +LL | pub fn f<'a, 'b, T: Trait<'a> + Trait<'b>>(v: >::Type) {} + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: cannot satisfy `>::Type == _` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.next.stderr b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.next.stderr new file mode 100644 index 0000000000000..c7d774644c2ba --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot normalize `>::Type` + --> $DIR/ambiguity-due-to-uniquification-4.rs:17:44 + | +LL | pub fn f<'a, 'b, T: Trait<'a> + Trait<'b>>(v: >::Type) {} + | ^ cannot normalize `>::Type` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.rs b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.rs new file mode 100644 index 0000000000000..c40b472678d4b --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.rs @@ -0,0 +1,21 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +// A regression test for https://github.com/rust-lang/rust/issues/151318. +// +// Unlike in the previous other tests, this fails to compile with the old solver as well. +// Although we were already stashing goals which depend on inference variables and then +// reproving them at the end of HIR typeck to avoid causing an ICE during MIR borrowck, +// it wasn't enough because the type op itself can result in an error due to uniquification, +// e.g. while normalizing a projection type. + +pub trait Trait<'a> { + type Type; +} + +pub fn f<'a, 'b, T: Trait<'a> + Trait<'b>>(v: >::Type) {} +//~^ ERROR type annotations needed +//[current]~| ERROR type annotations needed + +fn main() {} diff --git a/tests/ui/wf/return-type-non-wf-no-ice.current.stderr b/tests/ui/wf/return-type-non-wf-no-ice.current.stderr new file mode 100644 index 0000000000000..888f0893ec7c4 --- /dev/null +++ b/tests/ui/wf/return-type-non-wf-no-ice.current.stderr @@ -0,0 +1,22 @@ +error[E0277]: `T` is not an iterator + --> $DIR/return-type-non-wf-no-ice.rs:13:16 + | +LL | fn foo() -> Foo { + | ^^^^^^ `T` is not an iterator + | +note: required by a bound in `Foo` + --> $DIR/return-type-non-wf-no-ice.rs:10:8 + | +LL | pub struct Foo(T) + | --- required by a bound in this struct +LL | where +LL | T: Iterator, + | ^^^^^^^^ required by this bound in `Foo` +help: consider restricting type parameter `T` with trait `Iterator` + | +LL | fn foo() -> Foo { + | +++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/return-type-non-wf-no-ice.next.stderr b/tests/ui/wf/return-type-non-wf-no-ice.next.stderr new file mode 100644 index 0000000000000..888f0893ec7c4 --- /dev/null +++ b/tests/ui/wf/return-type-non-wf-no-ice.next.stderr @@ -0,0 +1,22 @@ +error[E0277]: `T` is not an iterator + --> $DIR/return-type-non-wf-no-ice.rs:13:16 + | +LL | fn foo() -> Foo { + | ^^^^^^ `T` is not an iterator + | +note: required by a bound in `Foo` + --> $DIR/return-type-non-wf-no-ice.rs:10:8 + | +LL | pub struct Foo(T) + | --- required by a bound in this struct +LL | where +LL | T: Iterator, + | ^^^^^^^^ required by this bound in `Foo` +help: consider restricting type parameter `T` with trait `Iterator` + | +LL | fn foo() -> Foo { + | +++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/return-type-non-wf-no-ice.rs b/tests/ui/wf/return-type-non-wf-no-ice.rs new file mode 100644 index 0000000000000..915e33418d7c0 --- /dev/null +++ b/tests/ui/wf/return-type-non-wf-no-ice.rs @@ -0,0 +1,18 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver + +// Ensure we do not ICE if a non-well-formed return type manages to slip past HIR typeck. +// See for details. + +pub struct Foo(T) +where + T: Iterator, + ::Item: Default; + +fn foo() -> Foo { + //~^ ERROR: `T` is not an iterator + loop {} +} + +fn main() {}