Skip to content

Commit

Permalink
Auto merge of #123801 - cuviper:beta-next, r=cuviper
Browse files Browse the repository at this point in the history
[beta] backports

- fix attribute validation on associated items in traits #121545
- Only inspect user-written predicates for privacy concerns #123377
- Check def id before calling `match_projection_projections` #123471
- Restore `pred_known_to_hold_modulo_regions` #123578
- Beta revert "Use OS thread name by default" #123533

r? cuviper
  • Loading branch information
bors committed Apr 12, 2024
2 parents 27011d5 + 3e37631 commit 6fd1912
Show file tree
Hide file tree
Showing 22 changed files with 402 additions and 138 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Expand Up @@ -1527,6 +1527,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
generics,
body.as_deref(),
);
walk_list!(self, visit_attribute, &item.attrs);
self.visit_fn(kind, item.span, item.id);
}
AssocItemKind::Type(_) => {
Expand Down
50 changes: 47 additions & 3 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Expand Up @@ -119,16 +119,60 @@ pub fn predicates_for_generics<'tcx>(

/// Determines whether the type `ty` is known to meet `bound` and
/// returns true if so. Returns false if `ty` either does not meet
/// `bound` or is not known to meet bound.
/// `bound` or is not known to meet bound (note that this is
/// conservative towards *no impl*, which is the opposite of the
/// `evaluate` methods).
pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
def_id: DefId,
) -> bool {
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, trait_ref);
infcx.predicate_must_hold_modulo_regions(&obligation)
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref)
}

/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist?
///
/// Ping me on zulip if you want to use this method and need help with finding
/// an appropriate replacement.
#[instrument(level = "debug", skip(infcx, param_env, pred), ret)]
fn pred_known_to_hold_modulo_regions<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
pred: impl ToPredicate<'tcx>,
) -> bool {
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, pred);

let result = infcx.evaluate_obligation_no_overflow(&obligation);
debug!(?result);

if result.must_apply_modulo_regions() {
true
} else if result.may_apply() {
// Sometimes obligations are ambiguous because the recursive evaluator
// is not smart enough, so we fall back to fulfillment when we're not certain
// that an obligation holds or not. Even still, we must make sure that
// the we do no inference in the process of checking this obligation.
let goal = infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
infcx.probe(|_| {
let ocx = ObligationCtxt::new(infcx);
ocx.register_obligation(obligation);

let errors = ocx.select_all_or_error();
match errors.as_slice() {
// Only known to hold if we did no inference.
[] => infcx.shallow_resolve(goal) == goal,

errors => {
debug!(?errors);
false
}
}
})
} else {
false
}
}

#[instrument(level = "debug", skip(tcx, elaborated_env))]
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_trait_selection/src/traits/project.rs
Expand Up @@ -794,6 +794,9 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
let Some(clause) = clause.as_projection_clause() else {
return ControlFlow::Continue(());
};
if clause.projection_def_id() != obligation.predicate.def_id {
return ControlFlow::Continue(());
}

let is_match =
selcx.infcx.probe(|_| selcx.match_projection_projections(obligation, clause, true));
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_ty_utils/src/sig_types.rs
Expand Up @@ -13,6 +13,7 @@ pub trait SpannedTypeVisitor<'tcx> {
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
}

#[instrument(level = "trace", skip(tcx, visitor))]
pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
tcx: TyCtxt<'tcx>,
item: LocalDefId,
Expand All @@ -36,7 +37,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
}
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand All @@ -54,7 +55,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
// Associated types in traits don't necessarily have a type that we can visit
try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
}
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand All @@ -76,7 +77,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
let ty = field.ty(tcx, args);
try_visit!(visitor.visit(span, ty));
}
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand All @@ -95,12 +96,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
_ => tcx.def_span(item),
};
try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
DefKind::TraitAlias | DefKind::Trait => {
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
try_visit!(visitor.visit(span, pred));
}
}
Expand Down
6 changes: 1 addition & 5 deletions 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, CString};
use crate::ffi::CStr;
use crate::io;
use crate::mem;
use crate::num::NonZero;
Expand Down Expand Up @@ -71,10 +71,6 @@ impl Thread {
// nope
}

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

#[inline]
pub fn sleep(dur: Duration) {
unsafe {
Expand Down
6 changes: 1 addition & 5 deletions library/std/src/sys/pal/itron/thread.rs
Expand Up @@ -8,7 +8,7 @@ use super::{
};
use crate::{
cell::UnsafeCell,
ffi::{CStr, CString},
ffi::CStr,
hint, io,
mem::ManuallyDrop,
num::NonZero,
Expand Down Expand Up @@ -204,10 +204,6 @@ 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: 1 addition & 5 deletions 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, CString};
use crate::ffi::CStr;
use crate::io;
use crate::num::NonZero;
use crate::time::Duration;
Expand Down Expand Up @@ -133,10 +133,6 @@ 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: 1 addition & 5 deletions library/std/src/sys/pal/teeos/thread.rs
@@ -1,7 +1,7 @@
use core::convert::TryInto;

use crate::cmp;
use crate::ffi::{CStr, CString};
use crate::ffi::CStr;
use crate::io;
use crate::mem;
use crate::num::NonZero;
Expand Down Expand Up @@ -101,10 +101,6 @@ 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: 1 addition & 5 deletions library/std/src/sys/pal/uefi/thread.rs
@@ -1,5 +1,5 @@
use super::unsupported;
use crate::ffi::{CStr, CString};
use crate::ffi::CStr;
use crate::io;
use crate::num::NonZero;
use crate::ptr::NonNull;
Expand All @@ -23,10 +23,6 @@ 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
40 changes: 1 addition & 39 deletions library/std/src/sys/pal/unix/thread.rs
@@ -1,5 +1,5 @@
use crate::cmp;
use crate::ffi::{CStr, CString};
use crate::ffi::CStr;
use crate::io;
use crate::mem;
use crate::num::NonZero;
Expand Down Expand Up @@ -225,44 +225,6 @@ impl Thread {
// Newlib, Emscripten, and VxWorks have no way to set a thread name.
}

#[cfg(target_os = "linux")]
pub fn get_name() -> Option<CString> {
const TASK_COMM_LEN: usize = 16;
let mut name = vec![0u8; TASK_COMM_LEN];
let res = unsafe {
libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
};
if res != 0 {
return None;
}
name.truncate(name.iter().position(|&c| c == 0)?);
CString::new(name).ok()
}

#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
pub fn get_name() -> Option<CString> {
let mut name = vec![0u8; libc::MAXTHREADNAMESIZE];
let res = unsafe {
libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
};
if res != 0 {
return None;
}
name.truncate(name.iter().position(|&c| c == 0)?);
CString::new(name).ok()
}

#[cfg(not(any(
target_os = "linux",
target_os = "macos",
target_os = "ios",
target_os = "tvos",
target_os = "watchos"
)))]
pub fn get_name() -> Option<CString> {
None
}

#[cfg(not(target_os = "espidf"))]
pub fn sleep(dur: Duration) {
let mut secs = dur.as_secs();
Expand Down
6 changes: 1 addition & 5 deletions library/std/src/sys/pal/unsupported/thread.rs
@@ -1,5 +1,5 @@
use super::unsupported;
use crate::ffi::{CStr, CString};
use crate::ffi::CStr;
use crate::io;
use crate::num::NonZero;
use crate::time::Duration;
Expand All @@ -22,10 +22,6 @@ impl Thread {
// nope
}

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

pub fn sleep(_dur: Duration) {
panic!("can't sleep");
}
Expand Down
6 changes: 1 addition & 5 deletions library/std/src/sys/pal/wasi/thread.rs
@@ -1,4 +1,4 @@
use crate::ffi::{CStr, CString};
use crate::ffi::CStr;
use crate::io;
use crate::mem;
use crate::num::NonZero;
Expand Down Expand Up @@ -134,10 +134,6 @@ impl Thread {
// nope
}

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

pub fn sleep(dur: Duration) {
let nanos = dur.as_nanos();
assert!(nanos <= u64::MAX as u128);
Expand Down
4 changes: 0 additions & 4 deletions library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -1,5 +1,4 @@
use crate::ffi::CStr;
use crate::ffi::CString;
use crate::io;
use crate::num::NonZero;
use crate::sys::unsupported;
Expand All @@ -18,9 +17,6 @@ impl Thread {
pub fn yield_now() {}

pub fn set_name(_name: &CStr) {}
pub fn get_name() -> Option<CString> {
None
}

pub fn sleep(dur: Duration) {
use crate::arch::wasm32;
Expand Down
24 changes: 0 additions & 24 deletions library/std/src/sys/pal/windows/thread.rs
Expand Up @@ -9,7 +9,6 @@ use crate::sys::handle::Handle;
use crate::sys::stack_overflow;
use crate::sys_common::FromInner;
use crate::time::Duration;
use alloc::ffi::CString;
use core::ffi::c_void;

use super::time::WaitableTimer;
Expand Down Expand Up @@ -68,29 +67,6 @@ impl Thread {
};
}

pub fn get_name() -> Option<CString> {
unsafe {
let mut ptr = core::ptr::null_mut();
let result = c::GetThreadDescription(c::GetCurrentThread(), &mut ptr);
if result < 0 {
return None;
}
let name = String::from_utf16_lossy({
let mut len = 0;
while *ptr.add(len) != 0 {
len += 1;
}
core::slice::from_raw_parts(ptr, len)
})
.into_bytes();
// Attempt to free the memory.
// This should never fail but if it does then there's not much we can do about it.
let result = c::LocalFree(ptr.cast::<c_void>());
debug_assert!(result.is_null());
if name.is_empty() { None } else { Some(CString::from_vec_unchecked(name)) }
}
}

pub fn join(self) {
let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
if rc == c::WAIT_FAILED {
Expand Down
6 changes: 1 addition & 5 deletions library/std/src/sys/pal/xous/thread.rs
@@ -1,4 +1,4 @@
use crate::ffi::{CStr, CString};
use crate::ffi::CStr;
use crate::io;
use crate::num::NonZero;
use crate::os::xous::ffi::{
Expand Down Expand Up @@ -113,10 +113,6 @@ impl Thread {
// nope
}

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

pub fn sleep(dur: Duration) {
// Because the sleep server works on units of `usized milliseconds`, split
// the messages up into these chunks. This means we may run into issues
Expand Down

0 comments on commit 6fd1912

Please sign in to comment.