Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #94447

Merged
merged 10 commits into from
Feb 28, 2022
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
output_path.with_extension("lib")
};

let mingw_gnu_toolchain = self.config.sess.target.llvm_target.ends_with("pc-windows-gnu");
let target = &self.config.sess.target;
let mingw_gnu_toolchain =
target.vendor == "pc" && target.os == "windows" && target.env == "gnu";

let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
.iter()
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ pub use raw::{from_raw_parts, from_raw_parts_mut};
#[stable(feature = "from_ref", since = "1.28.0")]
pub use raw::{from_mut, from_ref};

#[unstable(feature = "slice_from_ptr_range", issue = "89792")]
pub use raw::{from_mut_ptr_range, from_ptr_range};

// This function is public only because there is no other way to unit test heapsort.
#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
pub use sort::heapsort;
Expand Down
111 changes: 111 additions & 0 deletions library/core/src/slice/raw.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Free functions to create `&[T]` and `&mut [T]`.

use crate::array;
use crate::ops::Range;
use crate::ptr;

/// Forms a slice from a pointer and a length.
Expand Down Expand Up @@ -177,3 +178,113 @@ pub const fn from_ref<T>(s: &T) -> &[T] {
pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
array::from_mut(s)
}

/// Forms a slice from a pointer range.
///
/// This function is useful for interacting with foreign interfaces which
/// use two pointers to refer to a range of elements in memory, as is
/// common in C++.
///
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * The `start` pointer of the range must be a [valid] and properly aligned pointer
/// to the first element of a slice.
///
/// * The `end` pointer must be a [valid] and properly aligned pointer to *one past*
/// the last element, such that the offset from the end to the start pointer is
/// the length of the slice.
///
/// * The range must contain `N` consecutive properly initialized values of type `T`:
///
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
///
/// * The memory referenced by the returned slice must not be mutated for the duration
/// of lifetime `'a`, except inside an `UnsafeCell`.
///
/// * The total length of the range must be no larger than `isize::MAX`.
/// See the safety documentation of [`pointer::offset`].
///
/// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements.
///
/// # Caveat
///
/// The lifetime for the returned slice is inferred from its usage. To
/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
/// source lifetime is safe in the context, such as by providing a helper
/// function taking the lifetime of a host value for the slice, or by explicit
/// annotation.
///
/// # Examples
///
/// ```
/// #![feature(slice_from_ptr_range)]
///
/// use core::slice;
///
/// let x = [1, 2, 3];
/// let range = x.as_ptr_range();
///
/// unsafe {
/// assert_eq!(slice::from_ptr_range(range), &x);
/// }
/// ```
///
/// [valid]: ptr#safety
#[unstable(feature = "slice_from_ptr_range", issue = "89792")]
pub unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
// SAFETY: the caller must uphold the safety contract for `from_ptr_range`.
unsafe { from_raw_parts(range.start, range.end.offset_from(range.start) as usize) }
}

/// Performs the same functionality as [`from_ptr_range`], except that a
/// mutable slice is returned.
///
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * The `start` pointer of the range must be a [valid] and properly aligned pointer
/// to the first element of a slice.
///
/// * The `end` pointer must be a [valid] and properly aligned pointer to *one past*
/// the last element, such that the offset from the end to the start pointer is
/// the length of the slice.
///
/// * The range must contain `N` consecutive properly initialized values of type `T`:
///
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
///
/// * The memory referenced by the returned slice must not be accessed through any other pointer
/// (not derived from the return value) for the duration of lifetime `'a`.
/// Both read and write accesses are forbidden.
///
/// * The total length of the range must be no larger than `isize::MAX`.
/// See the safety documentation of [`pointer::offset`].
///
/// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements.
///
/// # Examples
///
/// ```
/// #![feature(slice_from_ptr_range)]
///
/// use core::slice;
///
/// let mut x = [1, 2, 3];
/// let range = x.as_mut_ptr_range();
///
/// unsafe {
/// assert_eq!(slice::from_mut_ptr_range(range), &mut [1, 2, 3]);
/// }
/// ```
///
/// [valid]: ptr#safety
#[unstable(feature = "slice_from_ptr_range", issue = "89792")]
pub unsafe fn from_mut_ptr_range<'a, T>(range: Range<*mut T>) -> &'a mut [T] {
// SAFETY: the caller must uphold the safety contract for `from_mut_ptr_range`.
unsafe { from_raw_parts_mut(range.start, range.end.offset_from(range.start) as usize) }
}
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#![feature(pin_macro)]
#![feature(sort_internals)]
#![feature(slice_take)]
#![feature(slice_from_ptr_range)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_array_assume_init)]
#![feature(maybe_uninit_write_slice)]
Expand Down
22 changes: 22 additions & 0 deletions library/core/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use core::cell::Cell;
use core::cmp::Ordering;
use core::mem::MaybeUninit;
use core::result::Result::{Err, Ok};
use core::slice;

#[test]
fn test_position() {
Expand Down Expand Up @@ -2480,3 +2481,24 @@ take_tests! {
(take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
(take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
}

#[test]
fn test_slice_from_ptr_range() {
let arr = ["foo".to_owned(), "bar".to_owned()];
let range = arr.as_ptr_range();
unsafe {
assert_eq!(slice::from_ptr_range(range), &arr);
}

let mut arr = [1, 2, 3];
let range = arr.as_mut_ptr_range();
unsafe {
assert_eq!(slice::from_mut_ptr_range(range), &mut [1, 2, 3]);
}

let arr: [Vec<String>; 0] = [];
let range = arr.as_ptr_range();
unsafe {
assert_eq!(slice::from_ptr_range(range), &arr);
}
}
2 changes: 1 addition & 1 deletion src/doc/not_found.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function on_submit(event) {
if (form['from'].value === 'duckduckgo') {
document.location.href = form.action + '?q=' + encodeURIComponent(q + ' site:doc.rust-lang.org');
} else if (form['from'].value === 'library') {
document.location.href = 'std/index.html?search=' + encodeURIComponent(q);
document.location.href = '/std/index.html?search=' + encodeURIComponent(q);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustdoc/src/what-to-include.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ rustdoc --theme awesome.css src/lib.rs

Here is an example of a new theme, [Ayu].

[Ayu]: https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/themes/ayu.css
[Ayu]: https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/css/themes/ayu.css
[API Guidelines]: https://rust-lang.github.io/api-guidelines/documentation.html#rustdoc-does-not-show-unhelpful-implementation-details-c-hidden
[Documentation tests]: documentation-tests.md
[on this blog]: https://blog.guillaume-gomez.fr/articles/2016-09-16+Generating+doc+with+rustdoc+and+a+custom+theme
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/const-generics/generic_const_exprs/issue-90847.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// check-pass

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(adt_const_params)]

struct Foo<const A: [(); 0 + 0]> where [(); 0 + 0]: Sized;

fn main() {}