Skip to content

Commit

Permalink
Auto merge of rust-lang#126300 - workingjubilee:rollup-0v2ypgt, r=wor…
Browse files Browse the repository at this point in the history
…kingjubilee

Rollup of 8 pull requests

Successful merges:

 - rust-lang#123374 (DOC: Add FFI example for slice::from_raw_parts())
 - rust-lang#126210 (docs(core): make more const_ptr doctests assert instead of printing)
 - rust-lang#126228 (Provide correct parent for nested anon const)
 - rust-lang#126242 (Simplify provider api to improve llvm ir)
 - rust-lang#126249 (Simplify `[T; N]::try_map` signature)
 - rust-lang#126256 (Add {{target}} substitution to compiletest)
 - rust-lang#126263 (Make issue-122805.rs big endian compatible)
 - rust-lang#126286 (Make `storage-live.rs` robust against rustc internal changes.)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 12, 2024
2 parents 76c7382 + 8e25298 commit aea0c94
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 67 deletions.
26 changes: 21 additions & 5 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_session::lint;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span;

#[instrument(level = "debug", skip(tcx))]
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
use rustc_hir::*;

Expand Down Expand Up @@ -66,7 +67,22 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
// FIXME(#43408) always enable this once `lazy_normalization` is
// stable enough and does not need a feature gate anymore.
Node::AnonConst(_) => {
let parent_def_id = tcx.hir().get_parent_item(hir_id);
let parent_did = tcx.parent(def_id.to_def_id());

// We don't do this unconditionally because the `DefId` parent of an anon const
// might be an implicitly created closure during `async fn` desugaring. This would
// have the wrong generics.
//
// i.e. `async fn foo<'a>() { let a = [(); { 1 + 2 }]; bar().await() }`
// would implicitly have a closure in its body that would be the parent of
// the `{ 1 + 2 }` anon const. This closure's generics is simply a witness
// instead of `['a]`.
let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) {
parent_did
} else {
tcx.hir().get_parent_item(hir_id).to_def_id()
};
debug!(?parent_did);

let mut in_param_ty = false;
for (_parent, node) in tcx.hir().parent_iter(hir_id) {
Expand Down Expand Up @@ -121,7 +137,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
//
// This has some implications for how we get the predicates available to the anon const
// see `explicit_predicates_of` for more information on this
let generics = tcx.generics_of(parent_def_id.to_def_id());
let generics = tcx.generics_of(parent_did);
let param_def_idx = generics.param_def_id_to_index[&param_id.to_def_id()];
// In the above example this would be .params[..N#0]
let own_params = generics.params_to(param_def_idx as usize, tcx).to_owned();
Expand All @@ -147,7 +163,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
//
// Note that we do not supply the parent generics when using
// `min_const_generics`.
Some(parent_def_id.to_def_id())
Some(parent_did)
}
} else {
let parent_node = tcx.parent_hir_node(hir_id);
Expand All @@ -159,7 +175,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
if constant.hir_id() == hir_id =>
{
Some(parent_def_id.to_def_id())
Some(parent_did)
}
// Exclude `GlobalAsm` here which cannot have generics.
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
Expand All @@ -171,7 +187,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
_ => false,
}) =>
{
Some(parent_def_id.to_def_id())
Some(parent_did)
}
_ => None,
}
Expand Down
6 changes: 2 additions & 4 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,11 +533,9 @@ impl<T, const N: usize> [T; N] {
/// assert_eq!(c, Some(a));
/// ```
#[unstable(feature = "array_try_map", issue = "79711")]
pub fn try_map<F, R>(self, f: F) -> ChangeOutputType<R, [R::Output; N]>
pub fn try_map<R>(self, f: impl FnMut(T) -> R) -> ChangeOutputType<R, [R::Output; N]>
where
F: FnMut(T) -> R,
R: Try,
R::Residual: Residual<[R::Output; N]>,
R: Try<Residual: Residual<[R::Output; N]>>,
{
drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f)))
}
Expand Down
49 changes: 23 additions & 26 deletions library/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,9 @@ fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reifi
where
I: tags::Type<'a>,
{
let mut tagged = TaggedOption::<'a, I>(None);
let mut tagged = Tagged { tag_id: TypeId::of::<I>(), value: TaggedOption::<'a, I>(None) };
err.provide(tagged.as_request());
tagged.0
tagged.value.0
}

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -507,16 +507,9 @@ where
///
#[unstable(feature = "error_generic_member_access", issue = "99301")]
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
pub struct Request<'a>(dyn Erased<'a> + 'a);
pub struct Request<'a>(Tagged<dyn Erased<'a> + 'a>);

impl<'a> Request<'a> {
/// Create a new `&mut Request` from a `&mut dyn Erased` trait object.
fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Request<'a> {
// SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Request<'a>` is safe since
// `Request` is repr(transparent).
unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Request<'a>) }
}

/// Provide a value or other type with only static lifetimes.
///
/// # Examples
Expand Down Expand Up @@ -940,37 +933,38 @@ pub(crate) mod tags {
#[repr(transparent)]
pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option<I::Reified>);

impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> {
impl<'a, I: tags::Type<'a>> Tagged<TaggedOption<'a, I>> {
pub(crate) fn as_request(&mut self) -> &mut Request<'a> {
Request::new(self as &mut (dyn Erased<'a> + 'a))
let erased = self as &mut Tagged<dyn Erased<'a> + 'a>;
// SAFETY: transmuting `&mut Tagged<dyn Erased<'a> + 'a>` to `&mut Request<'a>` is safe since
// `Request` is repr(transparent).
unsafe { &mut *(erased as *mut Tagged<dyn Erased<'a>> as *mut Request<'a>) }
}
}

/// Represents a type-erased but identifiable object.
///
/// This trait is exclusively implemented by the `TaggedOption` type.
unsafe trait Erased<'a>: 'a {
/// The `TypeId` of the erased type.
fn tag_id(&self) -> TypeId;
}
unsafe trait Erased<'a>: 'a {}

unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {
fn tag_id(&self) -> TypeId {
TypeId::of::<I>()
}
unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {}

struct Tagged<E: ?Sized> {
tag_id: TypeId,
value: E,
}

impl<'a> dyn Erased<'a> + 'a {
impl<'a> Tagged<dyn Erased<'a> + 'a> {
/// Returns some reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
where
I: tags::Type<'a>,
{
if self.tag_id() == TypeId::of::<I>() {
if self.tag_id == TypeId::of::<I>() {
// SAFETY: Just checked whether we're pointing to an I.
Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
Some(&unsafe { &*(self as *const Self).cast::<Tagged<TaggedOption<'a, I>>>() }.value)
} else {
None
}
Expand All @@ -983,9 +977,12 @@ impl<'a> dyn Erased<'a> + 'a {
where
I: tags::Type<'a>,
{
if self.tag_id() == TypeId::of::<I>() {
// SAFETY: Just checked whether we're pointing to an I.
Some(unsafe { &mut *(self as *mut Self).cast::<TaggedOption<'a, I>>() })
if self.tag_id == TypeId::of::<I>() {
Some(
// SAFETY: Just checked whether we're pointing to an I.
&mut unsafe { &mut *(self as *mut Self).cast::<Tagged<TaggedOption<'a, I>>>() }
.value,
)
} else {
None
}
Expand Down
4 changes: 3 additions & 1 deletion library/core/src/ops/try_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,9 @@ pub trait Residual<O> {
}

#[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")]
pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::TryType;
#[allow(type_alias_bounds)]
pub(crate) type ChangeOutputType<T: Try<Residual: Residual<V>>, V> =
<T::Residual as Residual<V>>::TryType;

/// An adapter for implementing non-try methods via the `Try` implementation.
///
Expand Down
38 changes: 22 additions & 16 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ impl<T: ?Sized> *const T {
///
/// unsafe {
/// if let Some(val_back) = ptr.as_ref() {
/// println!("We got back the value: {val_back}!");
/// assert_eq!(val_back, &10);
/// }
/// }
/// ```
Expand All @@ -346,7 +346,7 @@ impl<T: ?Sized> *const T {
///
/// unsafe {
/// let val_back = &*ptr;
/// println!("We got back the value: {val_back}!");
/// assert_eq!(val_back, &10);
/// }
/// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
Expand Down Expand Up @@ -393,7 +393,7 @@ impl<T: ?Sized> *const T {
/// let ptr: *const u8 = &10u8 as *const u8;
///
/// unsafe {
/// println!("We got back the value: {}!", ptr.as_ref_unchecked());
/// assert_eq!(ptr.as_ref_unchecked(), &10);
/// }
/// ```
// FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
Expand Down Expand Up @@ -439,7 +439,7 @@ impl<T: ?Sized> *const T {
///
/// unsafe {
/// if let Some(val_back) = ptr.as_uninit_ref() {
/// println!("We got back the value: {}!", val_back.assume_init());
/// assert_eq!(val_back.assume_init(), 10);
/// }
/// }
/// ```
Expand Down Expand Up @@ -501,8 +501,8 @@ impl<T: ?Sized> *const T {
/// let ptr: *const u8 = s.as_ptr();
///
/// unsafe {
/// println!("{}", *ptr.offset(1) as char);
/// println!("{}", *ptr.offset(2) as char);
/// assert_eq!(*ptr.offset(1) as char, '2');
/// assert_eq!(*ptr.offset(2) as char, '3');
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -573,19 +573,21 @@ impl<T: ?Sized> *const T {
/// # Examples
///
/// ```
/// # use std::fmt::Write;
/// // Iterate using a raw pointer in increments of two elements
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// let step = 2;
/// let end_rounded_up = ptr.wrapping_offset(6);
///
/// // This loop prints "1, 3, 5, "
/// let mut out = String::new();
/// while ptr != end_rounded_up {
/// unsafe {
/// print!("{}, ", *ptr);
/// write!(&mut out, "{}, ", *ptr).unwrap();
/// }
/// ptr = ptr.wrapping_offset(step);
/// }
/// assert_eq!(out.as_str(), "1, 3, 5, ");
/// ```
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
Expand Down Expand Up @@ -988,8 +990,8 @@ impl<T: ?Sized> *const T {
/// let ptr: *const u8 = s.as_ptr();
///
/// unsafe {
/// println!("{}", *ptr.add(1) as char);
/// println!("{}", *ptr.add(2) as char);
/// assert_eq!(*ptr.add(1), b'2');
/// assert_eq!(*ptr.add(2), b'3');
/// }
/// ```
#[stable(feature = "pointer_methods", since = "1.26.0")]
Expand Down Expand Up @@ -1073,8 +1075,8 @@ impl<T: ?Sized> *const T {
///
/// unsafe {
/// let end: *const u8 = s.as_ptr().add(3);
/// println!("{}", *end.sub(1) as char);
/// println!("{}", *end.sub(2) as char);
/// assert_eq!(*end.sub(1), b'3');
/// assert_eq!(*end.sub(2), b'2');
/// }
/// ```
#[stable(feature = "pointer_methods", since = "1.26.0")]
Expand Down Expand Up @@ -1155,19 +1157,21 @@ impl<T: ?Sized> *const T {
/// # Examples
///
/// ```
/// # use std::fmt::Write;
/// // Iterate using a raw pointer in increments of two elements
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// let step = 2;
/// let end_rounded_up = ptr.wrapping_add(6);
///
/// // This loop prints "1, 3, 5, "
/// let mut out = String::new();
/// while ptr != end_rounded_up {
/// unsafe {
/// print!("{}, ", *ptr);
/// write!(&mut out, "{}, ", *ptr).unwrap();
/// }
/// ptr = ptr.wrapping_add(step);
/// }
/// assert_eq!(out, "1, 3, 5, ");
/// ```
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
Expand Down Expand Up @@ -1234,19 +1238,21 @@ impl<T: ?Sized> *const T {
/// # Examples
///
/// ```
/// # use std::fmt::Write;
/// // Iterate using a raw pointer in increments of two elements (backwards)
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
/// let start_rounded_down = ptr.wrapping_sub(2);
/// ptr = ptr.wrapping_add(4);
/// let step = 2;
/// // This loop prints "5, 3, 1, "
/// let mut out = String::new();
/// while ptr != start_rounded_down {
/// unsafe {
/// print!("{}, ", *ptr);
/// write!(&mut out, "{}, ", *ptr).unwrap();
/// }
/// ptr = ptr.wrapping_sub(step);
/// }
/// assert_eq!(out, "5, 3, 1, ");
/// ```
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
Expand Down
33 changes: 33 additions & 0 deletions library/core/src/slice/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,39 @@ use crate::ub_checks;
/// }
/// ```
///
/// ### FFI: Handling null pointers
///
/// In languages such as C++, pointers to empty collections are not guaranteed to be non-null.
/// When accepting such pointers, they have to be checked for null-ness to avoid undefined
/// behavior.
///
/// ```
/// use std::slice;
///
/// /// Sum the elements of an FFI slice.
/// ///
/// /// # Safety
/// ///
/// /// If ptr is not NULL, it must be correctly aligned and
/// /// point to `len` initialized items of type `f32`.
/// unsafe extern "C" fn sum_slice(ptr: *const f32, len: usize) -> f32 {
/// let data = if ptr.is_null() {
/// // `len` is assumed to be 0.
/// &[]
/// } else {
/// // SAFETY: see function docstring.
/// unsafe { slice::from_raw_parts(ptr, len) }
/// };
/// data.into_iter().sum()
/// }
///
/// // This could be the result of C++'s std::vector::data():
/// let ptr = std::ptr::null();
/// // And this could be std::vector::size():
/// let len = 0;
/// assert_eq!(unsafe { sum_slice(ptr, len) }, 0.0);
/// ```
///
/// [valid]: ptr#safety
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
#[inline]
Expand Down
5 changes: 5 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ fn expand_variables(mut value: String, config: &Config) -> String {
const BUILD_BASE: &str = "{{build-base}}";
const SYSROOT_BASE: &str = "{{sysroot-base}}";
const TARGET_LINKER: &str = "{{target-linker}}";
const TARGET: &str = "{{target}}";

if value.contains(CWD) {
let cwd = env::current_dir().unwrap();
Expand All @@ -1303,6 +1304,10 @@ fn expand_variables(mut value: String, config: &Config) -> String {
value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or(""));
}

if value.contains(TARGET) {
value = value.replace(TARGET, &config.target);
}

value
}

Expand Down
Loading

0 comments on commit aea0c94

Please sign in to comment.