Skip to content

Commit

Permalink
Auto merge of rust-lang#121904 - matthiaskrgr:rollup-qcq0d3h, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#121666 (Use the OS thread name by default if `THREAD_INFO` has not been initialized)
 - rust-lang#121758 (Move thread local implementation to `sys`)
 - rust-lang#121759 (attempt to further clarify addr_of docs)
 - rust-lang#121855 (Correctly generate item info of trait items)
 - rust-lang#121888 (style library/core/src/error.rs)
 - rust-lang#121892 (The ordinary lowering of `thir::ExprKind::Let` is unreachable)
 - rust-lang#121895 (avoid collecting into vecs in some places)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 2, 2024
2 parents 5257aee + fcf5805 commit d25ab9c
Show file tree
Hide file tree
Showing 33 changed files with 269 additions and 107 deletions.
36 changes: 16 additions & 20 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Expand Up @@ -357,31 +357,27 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {

let ignore_unused_generics = tcx.sess.instrument_coverage_except_unused_generics();

let eligible_def_ids: Vec<DefId> = tcx
.mir_keys(())
.iter()
.filter_map(|local_def_id| {
let def_id = local_def_id.to_def_id();
let kind = tcx.def_kind(def_id);
// `mir_keys` will give us `DefId`s for all kinds of things, not
// just "functions", like consts, statics, etc. Filter those out.
// If `ignore_unused_generics` was specified, filter out any
// generic functions from consideration as well.
if !matches!(kind, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) {
return None;
}
if ignore_unused_generics && tcx.generics_of(def_id).requires_monomorphization(tcx) {
return None;
}
Some(local_def_id.to_def_id())
})
.collect();
let eligible_def_ids = tcx.mir_keys(()).iter().filter_map(|local_def_id| {
let def_id = local_def_id.to_def_id();
let kind = tcx.def_kind(def_id);
// `mir_keys` will give us `DefId`s for all kinds of things, not
// just "functions", like consts, statics, etc. Filter those out.
// If `ignore_unused_generics` was specified, filter out any
// generic functions from consideration as well.
if !matches!(kind, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) {
return None;
}
if ignore_unused_generics && tcx.generics_of(def_id).requires_monomorphization(tcx) {
return None;
}
Some(local_def_id.to_def_id())
});

let codegenned_def_ids = codegenned_and_inlined_items(tcx);

// For each `DefId` that should have coverage instrumentation but wasn't
// codegenned, add it to the function coverage map as an unused function.
for def_id in eligible_def_ids.into_iter().filter(|id| !codegenned_def_ids.contains(id)) {
for def_id in eligible_def_ids.filter(|id| !codegenned_def_ids.contains(id)) {
// Skip any function that didn't have coverage data added to it by the
// coverage instrumentor.
let body = tcx.instance_mir(ty::InstanceDef::Item(def_id));
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Expand Up @@ -860,10 +860,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
traits with associated type `{name}`, you could use the \
fully-qualified path",
),
traits
.iter()
.map(|trait_str| format!("<Example as {trait_str}>::{name}"))
.collect::<Vec<_>>(),
traits.iter().map(|trait_str| format!("<Example as {trait_str}>::{name}")),
Applicability::HasPlaceholders,
);
}
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_hir_typeck/src/expr.rs
Expand Up @@ -2156,10 +2156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.span_suggestions(
span.shrink_to_hi().with_hi(expr_span.hi()),
"you might have meant to use an associated function to build this type",
items
.iter()
.map(|(_, name, args)| suggestion(name, *args))
.collect::<Vec<String>>(),
items.iter().map(|(_, name, args)| suggestion(name, *args)),
Applicability::MaybeIncorrect,
);
}
Expand Down
38 changes: 6 additions & 32 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Expand Up @@ -109,38 +109,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.cfg.goto(else_blk, source_info, join_block);
join_block.unit()
}
ExprKind::Let { expr, ref pat } => {
let scope = this.local_scope();
let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
this.lower_let_expr(block, expr, pat, scope, None, expr_span, true)
});

this.cfg.push_assign_constant(
true_block,
source_info,
destination,
ConstOperand {
span: expr_span,
user_ty: None,
const_: Const::from_bool(this.tcx, true),
},
);

this.cfg.push_assign_constant(
false_block,
source_info,
destination,
ConstOperand {
span: expr_span,
user_ty: None,
const_: Const::from_bool(this.tcx, false),
},
);

let join_block = this.cfg.start_new_block();
this.cfg.goto(true_block, source_info, join_block);
this.cfg.goto(false_block, source_info, join_block);
join_block.unit()
ExprKind::Let { .. } => {
// After desugaring, `let` expressions should only appear inside `if`
// expressions or `match` guards, possibly nested within a let-chain.
// In both cases they are specifically handled by the lowerings of
// those expressions, so this case is currently unreachable.
span_bug!(expr_span, "unexpected let expression outside of if or match-guard");
}
ExprKind::NeverToAny { source } => {
let source_expr = &this.thir[source];
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Expand Up @@ -1884,10 +1884,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
err.span_suggestions_with_style(
path_span.shrink_to_hi().with_hi(call_span.hi()),
"you might have meant to use an associated function to build this type",
items
.iter()
.map(|(_, name, len)| suggestion(name, *len))
.collect::<Vec<String>>(),
items.iter().map(|(_, name, len)| suggestion(name, *len)),
Applicability::MaybeIncorrect,
SuggestionStyle::ShowAlways,
);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/fulfill.rs
Expand Up @@ -57,7 +57,7 @@ impl<'tcx> ObligationStorage<'tcx> {

fn take_pending(&mut self) -> Vec<PredicateObligation<'tcx>> {
let mut obligations = mem::take(&mut self.pending);
obligations.extend(self.overflowed.drain(..));
obligations.append(&mut self.overflowed);
obligations
}

Expand Down
1 change: 1 addition & 0 deletions library/core/src/error.rs
Expand Up @@ -183,6 +183,7 @@ pub trait Error: Debug + Display {
#[allow(unused_variables)]
fn provide<'a>(&'a self, request: &mut Request<'a>) {}
}

mod private {
// This is a hack to prevent `type_id` from being overridden by `Error`
// implementations, since that can enable unsound downcasting.
Expand Down
78 changes: 63 additions & 15 deletions library/core/src/ptr/mod.rs
Expand Up @@ -2071,11 +2071,16 @@ impl<F: FnPtr> fmt::Debug for F {
/// as all other references. This macro can create a raw pointer *without* creating
/// a reference first.
///
/// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads
/// from the place or requires the place to be dereferenceable. This means that
/// `addr_of!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
/// Note however that `addr_of!((*ptr).field)` still requires the projection to
/// `field` to be in-bounds, using the same rules as [`offset`].
/// See [`addr_of_mut`] for how to create a pointer to uninitialized data.
/// Doing that with `addr_of` would not make much sense since one could only
/// read the data, and that would be Undefined Behavior.
///
/// # Safety
///
/// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads from the
/// place or requires the place to be dereferenceable. This means that `addr_of!((*ptr).field)`
/// still requires the projection to `field` to be in-bounds, using the same rules as [`offset`].
/// However, `addr_of!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
///
/// Note that `Deref`/`Index` coercions (and their mutable counterparts) are applied inside
/// `addr_of!` like everywhere else, in which case a reference is created to call `Deref::deref` or
Expand All @@ -2086,6 +2091,8 @@ impl<F: FnPtr> fmt::Debug for F {
///
/// # Example
///
/// **Correct usage: Creating a pointer to unaligned data**
///
/// ```
/// use std::ptr;
///
Expand All @@ -2101,9 +2108,27 @@ impl<F: FnPtr> fmt::Debug for F {
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
/// ```
///
/// See [`addr_of_mut`] for how to create a pointer to uninitialized data.
/// Doing that with `addr_of` would not make much sense since one could only
/// read the data, and that would be Undefined Behavior.
/// **Incorrect usage: Out-of-bounds fields projection**
///
/// ```rust,no_run
/// use std::ptr;
///
/// #[repr(C)]
/// struct MyStruct {
/// field1: i32,
/// field2: i32,
/// }
///
/// let ptr: *const MyStruct = ptr::null();
/// let fieldptr = unsafe { ptr::addr_of!((*ptr).field2) }; // Undefined Behavior ⚠️
/// ```
///
/// The field projection `.field2` would offset the pointer by 4 bytes,
/// but the pointer is not in-bounds of an allocation for 4 bytes,
/// so this offset is Undefined Behavior.
/// See the [`offset`] docs for a full list of requirements for inbounds pointer arithmetic; the
/// same requirements apply to field projections, even inside `addr_of!`. (In particular, it makes
/// no difference whether the pointer is null or dangling.)
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(raw_ref_op)]
Expand All @@ -2120,11 +2145,12 @@ pub macro addr_of($place:expr) {
/// as all other references. This macro can create a raw pointer *without* creating
/// a reference first.
///
/// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads
/// from the place or requires the place to be dereferenceable. This means that
/// `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
/// Note however that `addr_of_mut!((*ptr).field)` still requires the projection to
/// `field` to be in-bounds, using the same rules as [`offset`].
/// # Safety
///
/// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads from the
/// place or requires the place to be dereferenceable. This means that `addr_of_mut!((*ptr).field)`
/// still requires the projection to `field` to be in-bounds, using the same rules as [`offset`].
/// However, `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
///
/// Note that `Deref`/`Index` coercions (and their mutable counterparts) are applied inside
/// `addr_of_mut!` like everywhere else, in which case a reference is created to call `Deref::deref`
Expand All @@ -2135,7 +2161,7 @@ pub macro addr_of($place:expr) {
///
/// # Examples
///
/// **Creating a pointer to unaligned data:**
/// **Correct usage: Creating a pointer to unaligned data**
///
/// ```
/// use std::ptr;
Expand All @@ -2153,7 +2179,7 @@ pub macro addr_of($place:expr) {
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
/// ```
///
/// **Creating a pointer to uninitialized data:**
/// **Correct usage: Creating a pointer to uninitialized data**
///
/// ```rust
/// use std::{ptr, mem::MaybeUninit};
Expand All @@ -2169,6 +2195,28 @@ pub macro addr_of($place:expr) {
/// unsafe { f1_ptr.write(true); }
/// let init = unsafe { uninit.assume_init() };
/// ```
///
/// **Incorrect usage: Out-of-bounds fields projection**
///
/// ```rust,no_run
/// use std::ptr;
///
/// #[repr(C)]
/// struct MyStruct {
/// field1: i32,
/// field2: i32,
/// }
///
/// let ptr: *mut MyStruct = ptr::null_mut();
/// let fieldptr = unsafe { ptr::addr_of_mut!((*ptr).field2) }; // Undefined Behavior ⚠️
/// ```
///
/// The field projection `.field2` would offset the pointer by 4 bytes,
/// but the pointer is not in-bounds of an allocation for 4 bytes,
/// so this offset is Undefined Behavior.
/// See the [`offset`] docs for a full list of requirements for inbounds pointer arithmetic; the
/// same requirements apply to field projections, even inside `addr_of_mut!`. (In particular, it
/// makes no difference whether the pointer is null or dangling.)
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(raw_ref_op)]
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/mod.rs
Expand Up @@ -9,6 +9,9 @@ pub mod cmath;
pub mod locks;
pub mod os_str;
pub mod path;
#[allow(dead_code)]
#[allow(unused_imports)]
pub mod thread_local;

// FIXME(117276): remove this, move feature implementations into individual
// submodules.
Expand Down
2 changes: 0 additions & 2 deletions library/std/src/sys/pal/common/mod.rs
Expand Up @@ -12,8 +12,6 @@

pub mod alloc;
pub mod small_c_string;
#[allow(unused_imports)]
pub mod thread_local;

#[cfg(test)]
mod tests;
6 changes: 5 additions & 1 deletion library/std/src/sys/pal/hermit/thread.rs
Expand Up @@ -2,7 +2,7 @@

use super::abi;
use super::thread_local_dtor::run_dtors;
use crate::ffi::CStr;
use crate::ffi::{CStr, CString};
use crate::io;
use crate::mem;
use crate::num::NonZero;
Expand Down Expand Up @@ -71,6 +71,10 @@ impl Thread {
// nope
}

pub fn get_name() -> Option<CString> {
None
}

#[inline]
pub fn sleep(dur: Duration) {
unsafe {
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/pal/itron/thread.rs
Expand Up @@ -8,7 +8,7 @@ use super::{
};
use crate::{
cell::UnsafeCell,
ffi::CStr,
ffi::{CStr, CString},
hint, io,
mem::ManuallyDrop,
num::NonZero,
Expand Down Expand Up @@ -204,6 +204,10 @@ impl Thread {
// nope
}

pub fn get_name() -> Option<CString> {
None
}

pub fn sleep(dur: Duration) {
for timeout in dur2reltims(dur) {
expect_success(unsafe { abi::dly_tsk(timeout) }, &"dly_tsk");
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/pal/sgx/thread.rs
@@ -1,6 +1,6 @@
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
use super::unsupported;
use crate::ffi::CStr;
use crate::ffi::{CStr, CString};
use crate::io;
use crate::num::NonZero;
use crate::time::Duration;
Expand Down Expand Up @@ -133,6 +133,10 @@ impl Thread {
// which succeeds as-is with the SGX target.
}

pub fn get_name() -> Option<CString> {
None
}

pub fn sleep(dur: Duration) {
usercalls::wait_timeout(0, dur, || true);
}
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/pal/teeos/thread.rs
@@ -1,7 +1,7 @@
use core::convert::TryInto;

use crate::cmp;
use crate::ffi::CStr;
use crate::ffi::{CStr, CString};
use crate::io;
use crate::mem;
use crate::num::NonZero;
Expand Down Expand Up @@ -101,6 +101,10 @@ impl Thread {
// contact the teeos rustzone team.
}

pub fn get_name() -> Option<CString> {
None
}

/// only main thread could wait for sometime in teeos
pub fn sleep(dur: Duration) {
let sleep_millis = dur.as_millis();
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/pal/uefi/thread.rs
@@ -1,5 +1,5 @@
use super::unsupported;
use crate::ffi::CStr;
use crate::ffi::{CStr, CString};
use crate::io;
use crate::num::NonZero;
use crate::ptr::NonNull;
Expand All @@ -23,6 +23,10 @@ impl Thread {
// nope
}

pub fn get_name() -> Option<CString> {
None
}

pub fn sleep(dur: Duration) {
let boot_services: NonNull<r_efi::efi::BootServices> =
crate::os::uefi::env::boot_services().expect("can't sleep").cast();
Expand Down

0 comments on commit d25ab9c

Please sign in to comment.