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 4 pull requests #124222

Merged
merged 10 commits into from
Apr 21, 2024
6 changes: 5 additions & 1 deletion compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ hir_analysis_param_in_ty_of_assoc_const_binding =
*[normal] the {$param_def_kind} `{$param_name}` is defined here
}

hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope
hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope in `use<...>`
.label = {$kind} parameter is implicitly captured by this `impl Trait`
.note = currently, all {$kind} parameters are required to be mentioned in the precise captures list

Expand Down Expand Up @@ -405,6 +405,10 @@ hir_analysis_self_in_impl_self =
`Self` is not valid in the self type of an impl block
.note = replace `Self` with a different type

hir_analysis_self_ty_not_captured = `impl Trait` must mention the `Self` type of the trait in `use<...>`
.label = `Self` type parameter is implicitly captured by this `impl Trait`
.note = currently, all type parameters are required to be mentioned in the precise captures list

hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code
.help = add `#![feature(simd_ffi)]` to the crate attributes to enable

Expand Down
49 changes: 32 additions & 17 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,37 +580,52 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe

match param.kind {
ty::GenericParamDefKind::Lifetime => {
let use_span = tcx.def_span(param.def_id);
let opaque_span = tcx.def_span(opaque_def_id);
// Check if the lifetime param was captured but isn't named in the precise captures list.
if variances[param.index as usize] == ty::Invariant {
let param_span = if let DefKind::OpaqueTy =
tcx.def_kind(tcx.parent(param.def_id))
if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
&& let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
| ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
..
}) = *tcx
.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
{
Some(tcx.def_span(def_id))
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
opaque_span,
use_span,
param_span: tcx.def_span(def_id),
});
} else {
None
};
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
use_span: tcx.def_span(param.def_id),
param_span,
opaque_span: tcx.def_span(opaque_def_id),
});
// If the `use_span` is actually just the param itself, then we must
// have not duplicated the lifetime but captured the original.
// The "effective" `use_span` will be the span of the opaque itself,
// and the param span will be the def span of the param.
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
opaque_span,
use_span: opaque_span,
param_span: use_span,
});
}
continue;
}
}
ty::GenericParamDefKind::Type { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
kind: "type",
});
if matches!(tcx.def_kind(param.def_id), DefKind::Trait | DefKind::TraitAlias) {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::SelfTyNotCaptured {
trait_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
});
} else {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
kind: "type",
});
}
}
ty::GenericParamDefKind::Const { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_hir_analysis/src/errors/precise_captures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@ use rustc_span::{Span, Symbol};
#[note]
pub struct ParamNotCaptured {
#[primary_span]
pub param_span: Span,
#[label]
pub opaque_span: Span,
#[label]
pub param_span: Span,
pub kind: &'static str,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_self_ty_not_captured)]
#[note]
pub struct SelfTyNotCaptured {
#[primary_span]
pub opaque_span: Span,
#[label]
pub trait_span: Span,
}

#[derive(Diagnostic)]
#[diag(hir_analysis_lifetime_not_captured)]
pub struct LifetimeNotCaptured {
#[primary_span]
pub use_span: Span,
#[label(hir_analysis_param_label)]
pub param_span: Option<Span>,
pub param_span: Span,
#[label]
pub opaque_span: Span,
}
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3199,7 +3199,8 @@ macro_rules! int_impl {
/// that code in debug mode will trigger a panic on this case and
/// optimized code will return
#[doc = concat!("`", stringify!($SelfT), "::MIN`")]
/// without a panic.
/// without a panic. If you do not want this behavior consider
/// using [`unsigned_abs`](Self::unsigned_abs) instead.
///
/// # Examples
///
Expand Down
100 changes: 64 additions & 36 deletions library/std/src/sys/pal/unix/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,9 @@ const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "tvos",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "watchos",
target_os = "visionos",
target_vendor = "apple",
))]
const fn max_iov() -> usize {
libc::IOV_MAX as usize
Expand All @@ -72,17 +68,13 @@ const fn max_iov() -> usize {
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
target_os = "ios",
target_os = "tvos",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "nto",
target_os = "openbsd",
target_os = "horizon",
target_os = "vita",
target_os = "watchos",
target_os = "visionos",
target_vendor = "apple",
)))]
const fn max_iov() -> usize {
16 // The minimum value required by POSIX.
Expand Down Expand Up @@ -201,13 +193,10 @@ impl FileDesc {
target_os = "fuchsia",
target_os = "hurd",
target_os = "illumos",
target_os = "ios",
target_os = "tvos",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "watchos",
target_vendor = "apple",
)))]
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
io::default_read_vectored(|b| self.read_at(b, offset), bufs)
Expand Down Expand Up @@ -241,15 +230,7 @@ impl FileDesc {
Ok(ret as usize)
}

// We support old MacOS and iOS versions that do not have `preadv`. There is
// no `syscall` possible in these platform.
#[cfg(any(
all(target_os = "android", target_pointer_width = "32"),
target_os = "ios", // ios 14.0
target_os = "tvos", // tvos 14.0
target_os = "macos", // macos 11.0
target_os = "watchos", // watchos 7.0
))]
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);

Expand All @@ -269,6 +250,35 @@ impl FileDesc {
}
}

// We support old MacOS, iOS, watchOS, tvOS and visionOS. `preadv` was added in the following
// Apple OS versions:
// ios 14.0
// tvos 14.0
// macos 11.0
// watchos 7.0
//
// These versions may be newer than the minimum supported versions of OS's we support so we must
// use "weak" linking.
#[cfg(target_vendor = "apple")]
pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
super::weak::weak!(fn preadv(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);

match preadv.get() {
Some(preadv) => {
let ret = cvt(unsafe {
preadv(
self.as_raw_fd(),
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
cmp::min(bufs.len(), max_iov()) as libc::c_int,
offset as _,
)
})?;
Ok(ret as usize)
}
None => io::default_read_vectored(|b| self.read_at(b, offset), bufs),
}
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let ret = cvt(unsafe {
libc::write(
Expand Down Expand Up @@ -360,13 +370,10 @@ impl FileDesc {
target_os = "fuchsia",
target_os = "hurd",
target_os = "illumos",
target_os = "ios",
target_os = "tvos",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "watchos",
target_vendor = "apple",
)))]
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
io::default_write_vectored(|b| self.write_at(b, offset), bufs)
Expand Down Expand Up @@ -400,15 +407,7 @@ impl FileDesc {
Ok(ret as usize)
}

// We support old MacOS and iOS versions that do not have `pwritev`. There is
// no `syscall` possible in these platform.
#[cfg(any(
all(target_os = "android", target_pointer_width = "32"),
target_os = "ios", // ios 14.0
target_os = "tvos", // tvos 14.0
target_os = "macos", // macos 11.0
target_os = "watchos", // watchos 7.0
))]
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);

Expand All @@ -428,6 +427,35 @@ impl FileDesc {
}
}

// We support old MacOS, iOS, watchOS, tvOS and visionOS. `pwritev` was added in the following
// Apple OS versions:
// ios 14.0
// tvos 14.0
// macos 11.0
// watchos 7.0
//
// These versions may be newer than the minimum supported versions of OS's we support so we must
// use "weak" linking.
#[cfg(target_vendor = "apple")]
pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
super::weak::weak!(fn pwritev(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);

match pwritev.get() {
Some(pwritev) => {
let ret = cvt(unsafe {
pwritev(
self.as_raw_fd(),
bufs.as_ptr() as *const libc::iovec,
cmp::min(bufs.len(), max_iov()) as libc::c_int,
offset as _,
)
})?;
Ok(ret as usize)
}
None => io::default_write_vectored(|b| self.write_at(b, offset), bufs),
}
}

#[cfg(not(any(
target_env = "newlib",
target_os = "solaris",
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/pal/unix/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::ptr;
use crate::sync::atomic::{self, AtomicPtr, Ordering};

// We can use true weak linkage on ELF targets.
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "tvos")))]
#[cfg(all(unix, not(target_vendor = "apple")))]
pub(crate) macro weak {
(fn $name:ident($($t:ty),*) -> $ret:ty) => (
let ref $name: ExternWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
Expand All @@ -43,7 +43,7 @@ pub(crate) macro weak {
}

// On non-ELF targets, use the dlsym approximation of weak linkage.
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))]
#[cfg(target_vendor = "apple")]
pub(crate) use self::dlsym as weak;

pub(crate) struct ExternWeak<F: Copy> {
Expand Down
5 changes: 3 additions & 2 deletions src/bootstrap/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fn main() {

build_lock = fd_lock::RwLock::new(t!(fs::OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(&lock_path)));
_build_lock_guard = match build_lock.try_write() {
Expand Down Expand Up @@ -143,8 +144,8 @@ fn check_version(config: &Config) -> Option<String> {
// then use the one from the config.toml. This way we never show the same warnings
// more than once.
if let Ok(t) = fs::read_to_string(&warned_id_path) {
let last_warned_id =
usize::from_str(&t).expect(&format!("{} is corrupted.", warned_id_path.display()));
let last_warned_id = usize::from_str(&t)
.unwrap_or_else(|_| panic!("{} is corrupted.", warned_id_path.display()));

// We only use the last_warned_id if it exists in `CONFIG_CHANGE_HISTORY`.
// Otherwise, we may retrieve all the changes if it's not the highest value.
Expand Down
Loading
Loading