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 10 pull requests #126307

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8e91a51
DOC: Add FFI example for slice::from_raw_parts()
mgeier Apr 2, 2024
22319bf
Add "safety" comment
mgeier Apr 26, 2024
4df1303
Extend the example code and assert the result
mgeier Apr 26, 2024
30b676c
Add missing .into_iter()
mgeier Apr 26, 2024
fe52b54
docs(core): make more const_ptr doctests assert instead of printing
lolbinarycat Jun 10, 2024
bfb7757
Correct parent for nested anon consts
BoxyUwU Jun 10, 2024
1462f3d
Add {{target}} substitution to compiletest
Veykril Jun 11, 2024
d695544
Simplify `[T; N]::try_map` signature
workingjubilee Jun 11, 2024
26fa5c2
Make issue-122805.rs big endian compatible
nikic Jun 11, 2024
751143e
set_env: State the conclusion upfront
ChrisDenton Jun 11, 2024
1a60597
Make `storage-live.rs` robust against rustc internal changes.
nnethercote Jun 11, 2024
7e7da49
Update a cranelift patch file for formatting changes.
nnethercote Jun 11, 2024
0b3fec9
For E0277 suggest adding `Result` return type for function which usin…
surechen Jun 9, 2024
50068e1
Rollup merge of #123374 - mgeier:doc-slice-from-raw-parts, r=scottmcm
workingjubilee Jun 12, 2024
fa0b4f0
Rollup merge of #126187 - surechen:fix_125997, r=oli-obk
workingjubilee Jun 12, 2024
343a659
Rollup merge of #126210 - lolbinarycat:ptr_doctest_assert, r=workingj…
workingjubilee Jun 12, 2024
4307c75
Rollup merge of #126228 - BoxyUwU:nested_repeat_expr_generics, r=comp…
workingjubilee Jun 12, 2024
a4429e9
Rollup merge of #126249 - workingjubilee:simplify-try-map-signature, …
workingjubilee Jun 12, 2024
d54e07c
Rollup merge of #126256 - ferrocene:lw-target-subst, r=albertlarsan68
workingjubilee Jun 12, 2024
bc2f677
Rollup merge of #126263 - nikic:s390x-codegen-test-fix, r=jieyouxu
workingjubilee Jun 12, 2024
2a6e8b6
Rollup merge of #126281 - ChrisDenton:env, r=jhpratt
workingjubilee Jun 12, 2024
57cbdba
Rollup merge of #126286 - nnethercote:fix-test-LL-CC, r=lqd
workingjubilee Jun 12, 2024
54f92f9
Rollup merge of #126287 - nnethercote:reformat-cranelift-patch, r=bjorn3
workingjubilee Jun 12, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/wind
index ad8e01bfa9b..9ca8e4c16ce 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -323,7 +323,7 @@ pub unsafe fn NtWriteFile(
@@ -312,7 +312,7 @@ pub unsafe fn NtWriteFile(

// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
cfg_if::cfg_if! {
Expand All @@ -26,8 +26,8 @@ index e427546222a..f2fe42a4d51 100644
--- a/library/std/src/sys/pal/windows/rand.rs
+++ b/library/std/src/sys/pal/windows/rand.rs
@@ -2,7 +2,7 @@
use core::mem;
use core::ptr;

use crate::sys::c;

-#[cfg(not(target_vendor = "win7"))]
+#[cfg(any())]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,7 @@ pub struct Block<'hir> {
pub hir_id: HirId,
/// Distinguishes between `unsafe { ... }` and `{ ... }`.
pub rules: BlockCheckMode,
/// The span includes the curly braces `{` and `}` around the block.
pub span: Span,
/// If true, then there may exist `break 'a` values that aim to
/// break out of this block early.
Expand Down
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
Original file line number Diff line number Diff line change
Expand Up @@ -4587,6 +4587,47 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
_ => "/* value */".to_string(),
})
}

fn suggest_add_result_as_return_type(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diag<'_>,
trait_ref: ty::PolyTraitRef<'tcx>,
) {
if ObligationCauseCode::QuestionMark != *obligation.cause.code().peel_derives() {
return;
}

let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
if let hir::Node::Item(item) = node
&& let hir::ItemKind::Fn(sig, _, body_id) = item.kind
&& let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_ref.def_id())
&& let ty::Tuple(l) = trait_ref.skip_binder().args.type_at(0).kind()
&& l.len() == 0
&& let ty::Adt(def, _) = trait_ref.skip_binder().args.type_at(1).kind()
&& self.tcx.is_diagnostic_item(sym::Result, def.did())
{
let body = self.tcx.hir().body(body_id);
let mut sugg_spans =
vec![(ret_span, " -> Result<(), Box<dyn std::error::Error>>".to_string())];

if let hir::ExprKind::Block(b, _) = body.value.kind
&& b.expr.is_none()
{
sugg_spans.push((
// The span will point to the closing curly brace `}` of the block.
b.span.shrink_to_hi().with_lo(b.span.hi() - BytePos(1)),
"\n Ok(())\n}".to_string(),
));
}
err.multipart_suggestion_verbose(
format!("consider adding return type"),
sugg_spans,
Applicability::MaybeIncorrect,
);
}
}
}

/// Add a hint to add a missing borrow or remove an unnecessary one.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&mut err,
trait_predicate,
);
self.suggest_add_result_as_return_type(&obligation,
&mut err,
trait_ref);

if self.suggest_add_reference_to_arg(
&obligation,
&mut err,
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
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
12 changes: 8 additions & 4 deletions library/std/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,10 @@ impl Error for VarError {
/// This function is also always safe to call on Windows, in single-threaded
/// and multi-threaded programs.
///
/// In multi-threaded programs on other operating systems, we strongly suggest
/// not using `set_var` or `remove_var` at all. The exact requirement is: you
/// In multi-threaded programs on other operating systems, the only safe option is
/// to not use `set_var` or `remove_var` at all.
///
/// The exact requirement is: you
/// must ensure that there are no other threads concurrently writing or
/// *reading*(!) the environment through functions or global variables other
/// than the ones in this module. The problem is that these operating systems
Expand Down Expand Up @@ -390,8 +392,10 @@ unsafe fn _set_var(key: &OsStr, value: &OsStr) {
/// This function is also always safe to call on Windows, in single-threaded
/// and multi-threaded programs.
///
/// In multi-threaded programs on other operating systems, we strongly suggest
/// not using `set_var` or `remove_var` at all. The exact requirement is: you
/// In multi-threaded programs on other operating systems, the only safe option is
/// to not use `set_var` or `remove_var` at all.
///
/// The exact requirement is: you
/// must ensure that there are no other threads concurrently writing or
/// *reading*(!) the environment through functions or global variables other
/// than the ones in this module. The problem is that these operating systems
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/pal/windows/rand.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::{mem, ptr};

use crate::sys::c;
use core::mem;
use core::ptr;

#[cfg(not(target_vendor = "win7"))]
#[inline]
Expand Down
Loading
Loading