Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_builtin_macros/src/autodiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand All @@ -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,
},
Expand Down Expand Up @@ -328,7 +328,7 @@ mod llvm_enzyme {
span,
&d_sig,
&generics,
impl_of_trait,
is_impl,
)],
);

Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,12 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor>
}

fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {
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
Expand Down
68 changes: 45 additions & 23 deletions compiler/rustc_mir_transform/src/elaborate_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.
///
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>(T)
// where
// T: Iterator,
// <T as Iterator>::Item: Default;
//
// fn foo<T>() -> Foo<T> {
// loop {}
// }
// ```
//
// Here, `fn foo` ought to error and taint the body before MIR build, since
// `Foo<T>` 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() {
Expand Down
5 changes: 2 additions & 3 deletions library/std/src/sys/args/xous.rs
Original file line number Diff line number Diff line change
@@ -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![]);
};

Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/env/xous.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<usize> = AtomicUsize::new(0);
static ENV_INIT: Once = Once::new();
Expand All @@ -13,7 +13,7 @@ type EnvStore = Mutex<HashMap<OsString, OsString>>;
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(&param) {
let mut env_store = env_store.lock().unwrap();
Expand Down
48 changes: 48 additions & 0 deletions library/std/src/sys/pal/xous/mod.rs
Original file line number Diff line number Diff line change
@@ -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<unwind::FrameInfo> {
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() });
}
}
63 changes: 0 additions & 63 deletions library/std/src/sys/pal/xous/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<unwind::FrameInfo> {
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::<u8>(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<PathBuf> {
unsupported()
}
Expand Down Expand Up @@ -106,11 +48,6 @@ pub fn current_exe() -> io::Result<PathBuf> {
unsupported()
}

pub(crate) fn get_application_parameters() -> Option<params::ApplicationParameters> {
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")
}
Expand Down
Loading
Loading