mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #148462 - Zalathar:rollup-6gckwu6, r=Zalathar
Rollup of 8 pull requests Successful merges: - rust-lang/rust#133149 (Provide more context on `Fn` closure modifying binding) - rust-lang/rust#145915 (Stabilize `fmt::from_fn`) - rust-lang/rust#145974 (Stabilize -Zno-jump-tables into -Cjump-tables=bool) - rust-lang/rust#146057 (feat: add `from_fn_ptr` to `Waker` and `LocalWaker`) - rust-lang/rust#146301 (library: std: sys: net: uefi: tcp: Implement write_vectored) - rust-lang/rust#148437 (Regression test for undefined `__chkstk` on `aarch64-unknown-uefi`) - rust-lang/rust#148448 (Update books) - rust-lang/rust#148451 (tidy: Fix false positives with absolute repo paths in `pal.rs` `check()`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -150,8 +150,8 @@ pub(crate) fn report_mutability_error(
|
||||
}
|
||||
}
|
||||
}
|
||||
PlaceRef { local: _, projection: [proj_base @ .., ProjectionElem::Deref] } => {
|
||||
if the_place_err.local == ty::CAPTURE_STRUCT_LOCAL
|
||||
PlaceRef { local, projection: [proj_base @ .., ProjectionElem::Deref] } => {
|
||||
if local == ty::CAPTURE_STRUCT_LOCAL
|
||||
&& proj_base.is_empty()
|
||||
&& !self.upvars.is_empty()
|
||||
{
|
||||
@@ -165,10 +165,8 @@ pub(crate) fn report_mutability_error(
|
||||
", as `Fn` closures cannot mutate their captured variables".to_string()
|
||||
}
|
||||
} else {
|
||||
let source = self.borrowed_content_source(PlaceRef {
|
||||
local: the_place_err.local,
|
||||
projection: proj_base,
|
||||
});
|
||||
let source =
|
||||
self.borrowed_content_source(PlaceRef { local, projection: proj_base });
|
||||
let pointer_type = source.describe_for_immutable_place(self.infcx.tcx);
|
||||
opt_source = Some(source);
|
||||
if let Some(desc) = self.describe_place(access_place.as_ref()) {
|
||||
@@ -540,6 +538,7 @@ pub(crate) fn report_mutability_error(
|
||||
PlaceRef { local, projection: [ProjectionElem::Deref] }
|
||||
if local == ty::CAPTURE_STRUCT_LOCAL && !self.upvars.is_empty() =>
|
||||
{
|
||||
self.point_at_binding_outside_closure(&mut err, local, access_place);
|
||||
self.expected_fn_found_fn_mut_call(&mut err, span, act);
|
||||
}
|
||||
|
||||
@@ -958,6 +957,50 @@ fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) -> Self::Result {
|
||||
}
|
||||
}
|
||||
|
||||
/// When modifying a binding from inside of an `Fn` closure, point at the binding definition.
|
||||
fn point_at_binding_outside_closure(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
local: Local,
|
||||
access_place: Place<'tcx>,
|
||||
) {
|
||||
let place = access_place.as_ref();
|
||||
for (index, elem) in place.projection.into_iter().enumerate() {
|
||||
if let ProjectionElem::Deref = elem {
|
||||
if index == 0 {
|
||||
if self.body.local_decls[local].is_ref_for_guard() {
|
||||
continue;
|
||||
}
|
||||
if let LocalInfo::StaticRef { .. } = *self.body.local_decls[local].local_info()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(field) = self.is_upvar_field_projection(PlaceRef {
|
||||
local,
|
||||
projection: place.projection.split_at(index + 1).0,
|
||||
}) {
|
||||
let var_index = field.index();
|
||||
let upvar = self.upvars[var_index];
|
||||
if let Some(hir_id) = upvar.info.capture_kind_expr_id {
|
||||
let node = self.infcx.tcx.hir_node(hir_id);
|
||||
if let hir::Node::Expr(expr) = node
|
||||
&& let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
|
||||
&& let hir::def::Res::Local(hir_id) = path.res
|
||||
&& let hir::Node::Pat(pat) = self.infcx.tcx.hir_node(hir_id)
|
||||
{
|
||||
let name = upvar.to_string(self.infcx.tcx);
|
||||
err.span_label(
|
||||
pat.span,
|
||||
format!("`{name}` declared here, outside the closure"),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected.
|
||||
fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str) {
|
||||
err.span_label(sp, format!("cannot {act}"));
|
||||
@@ -970,6 +1013,7 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
|
||||
let def_id = tcx.hir_enclosing_body_owner(fn_call_id);
|
||||
let mut look_at_return = true;
|
||||
|
||||
err.span_label(closure_span, "in this closure");
|
||||
// If the HIR node is a function or method call, get the DefId
|
||||
// of the callee function or method, the span, and args of the call expr
|
||||
let get_call_details = || {
|
||||
@@ -1040,7 +1084,6 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
|
||||
if let Some(span) = arg {
|
||||
err.span_label(span, "change this to accept `FnMut` instead of `Fn`");
|
||||
err.span_label(call_span, "expects `Fn` instead of `FnMut`");
|
||||
err.span_label(closure_span, "in this closure");
|
||||
look_at_return = false;
|
||||
}
|
||||
}
|
||||
@@ -1067,7 +1110,6 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
|
||||
sig.decl.output.span(),
|
||||
"change this to return `FnMut` instead of `Fn`",
|
||||
);
|
||||
err.span_label(closure_span, "in this closure");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ fn instrument_function_attr<'ll>(
|
||||
}
|
||||
|
||||
fn nojumptables_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> {
|
||||
if !sess.opts.unstable_opts.no_jump_tables {
|
||||
if sess.opts.cg.jump_tables {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(closure_track_caller)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
#![feature(variant_count)]
|
||||
|
||||
@@ -59,10 +59,10 @@
|
||||
#![allow(internal_features)]
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(gen_blocks)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
|
||||
@@ -620,6 +620,7 @@ macro_rules! tracked {
|
||||
tracked!(force_frame_pointers, FramePointer::Always);
|
||||
tracked!(force_unwind_tables, Some(true));
|
||||
tracked!(instrument_coverage, InstrumentCoverage::Yes);
|
||||
tracked!(jump_tables, false);
|
||||
tracked!(link_dead_code, Some(true));
|
||||
tracked!(linker_plugin_lto, LinkerPluginLto::LinkerPluginAuto);
|
||||
tracked!(llvm_args, vec![String::from("1"), String::from("2")]);
|
||||
@@ -831,7 +832,6 @@ macro_rules! tracked {
|
||||
tracked!(mutable_noalias, false);
|
||||
tracked!(next_solver, NextSolverConfig { coherence: true, globally: true });
|
||||
tracked!(no_generate_arange_section, true);
|
||||
tracked!(no_jump_tables, true);
|
||||
tracked!(no_link, true);
|
||||
tracked!(no_profiler_runtime, true);
|
||||
tracked!(no_trait_vptr, true);
|
||||
|
||||
@@ -2093,6 +2093,8 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool {
|
||||
"instrument the generated code to support LLVM source-based code coverage reports \
|
||||
(note, the compiler build config must include `profiler = true`); \
|
||||
implies `-C symbol-mangling-version=v0`"),
|
||||
jump_tables: bool = (true, parse_bool, [TRACKED],
|
||||
"allow jump table and lookup table generation from switch case lowering (default: yes)"),
|
||||
link_arg: (/* redirected to link_args */) = ((), parse_string_push, [UNTRACKED],
|
||||
"a single extra argument to append to the linker invocation (can be used several times)"),
|
||||
link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
|
||||
@@ -2475,8 +2477,6 @@ pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool {
|
||||
"omit DWARF address ranges that give faster lookups"),
|
||||
no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED],
|
||||
"disable the compatibility version of the `implied_bounds_ty` query"),
|
||||
no_jump_tables: bool = (false, parse_no_value, [TRACKED],
|
||||
"disable the jump tables and lookup tables that can be generated from a switch case lowering"),
|
||||
no_leak_check: bool = (false, parse_no_value, [UNTRACKED],
|
||||
"disable the 'leak check' for subtyping; unsound, but useful for tests"),
|
||||
no_link: bool = (false, parse_no_value, [TRACKED],
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(rustdoc_internals)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
@@ -602,7 +602,7 @@
|
||||
pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::fmt::{Formatter, Result, Write};
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub use core::fmt::{FromFn, from_fn};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::fmt::{LowerExp, UpperExp};
|
||||
|
||||
@@ -1210,13 +1210,12 @@ fn is_pretty(&self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are provided with the function
|
||||
/// `f`.
|
||||
/// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are
|
||||
/// forwarded to the provided closure.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(debug_closure_helpers)]
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// let value = 'a';
|
||||
@@ -1227,21 +1226,19 @@ fn is_pretty(&self) -> bool {
|
||||
/// assert_eq!(format!("{}", wrapped), "'a'");
|
||||
/// assert_eq!(format!("{:?}", wrapped), "'a'");
|
||||
/// ```
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used"]
|
||||
pub fn from_fn<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result>(f: F) -> FromFn<F> {
|
||||
FromFn(f)
|
||||
}
|
||||
|
||||
/// Implements [`fmt::Debug`] and [`fmt::Display`] using a function.
|
||||
/// Implements [`fmt::Debug`] and [`fmt::Display`] via the provided closure.
|
||||
///
|
||||
/// Created with [`from_fn`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub struct FromFn<F>(F)
|
||||
where
|
||||
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result;
|
||||
#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub struct FromFn<F>(F);
|
||||
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl<F> fmt::Debug for FromFn<F>
|
||||
where
|
||||
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
@@ -1251,7 +1248,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl<F> fmt::Display for FromFn<F>
|
||||
where
|
||||
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
|
||||
@@ -39,7 +39,7 @@ pub enum Alignment {
|
||||
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
#[stable(feature = "fmt_from_fn", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub use self::builders::{FromFn, from_fn};
|
||||
|
||||
/// The type returned by formatter methods.
|
||||
|
||||
@@ -584,6 +584,28 @@ pub fn data(&self) -> *const () {
|
||||
pub fn vtable(&self) -> &'static RawWakerVTable {
|
||||
self.waker.vtable
|
||||
}
|
||||
|
||||
/// Constructs a `Waker` from a function pointer.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "waker_from_fn_ptr", issue = "148457")]
|
||||
pub const fn from_fn_ptr(f: fn()) -> Self {
|
||||
// SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it
|
||||
// is sound to transmute it back to `fn()`.
|
||||
static VTABLE: RawWakerVTable = unsafe {
|
||||
RawWakerVTable::new(
|
||||
|this| RawWaker::new(this, &VTABLE),
|
||||
|this| transmute::<*const (), fn()>(this)(),
|
||||
|this| transmute::<*const (), fn()>(this)(),
|
||||
|_| {},
|
||||
)
|
||||
};
|
||||
let raw = RawWaker::new(f as *const (), &VTABLE);
|
||||
|
||||
// SAFETY: `clone` is just a copy, `drop` is a no-op while `wake` and
|
||||
// `wake_by_ref` just call the function pointer.
|
||||
unsafe { Self::from_raw(raw) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
@@ -879,6 +901,28 @@ pub fn data(&self) -> *const () {
|
||||
pub fn vtable(&self) -> &'static RawWakerVTable {
|
||||
self.waker.vtable
|
||||
}
|
||||
|
||||
/// Constructs a `LocalWaker` from a function pointer.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "waker_from_fn_ptr", issue = "148457")]
|
||||
pub const fn from_fn_ptr(f: fn()) -> Self {
|
||||
// SAFETY: Unsafe is used for transmutes, pointer came from `fn()` so it
|
||||
// is sound to transmute it back to `fn()`.
|
||||
static VTABLE: RawWakerVTable = unsafe {
|
||||
RawWakerVTable::new(
|
||||
|this| RawWaker::new(this, &VTABLE),
|
||||
|this| transmute::<*const (), fn()>(this)(),
|
||||
|this| transmute::<*const (), fn()>(this)(),
|
||||
|_| {},
|
||||
)
|
||||
};
|
||||
let raw = RawWaker::new(f as *const (), &VTABLE);
|
||||
|
||||
// SAFETY: `clone` is just a copy, `drop` is a no-op while `wake` and
|
||||
// `wake_by_ref` just call the function pointer.
|
||||
unsafe { Self::from_raw(raw) }
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "local_waker", issue = "118959")]
|
||||
impl Clone for LocalWaker {
|
||||
|
||||
@@ -82,12 +82,11 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
// FIXME: UEFI does support vectored write, so implement that.
|
||||
crate::io::default_write_vectored(|b| self.write(b), buf)
|
||||
self.inner.write_vectored(buf, self.write_timeout()?)
|
||||
}
|
||||
|
||||
pub fn is_write_vectored(&self) -> bool {
|
||||
false
|
||||
true
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::tcp4;
|
||||
use crate::io;
|
||||
use crate::io::{self, IoSlice};
|
||||
use crate::net::SocketAddr;
|
||||
use crate::ptr::NonNull;
|
||||
use crate::sys::{helpers, unsupported};
|
||||
@@ -28,6 +28,16 @@ pub(crate) fn write(&self, buf: &[u8], timeout: Option<Duration>) -> io::Result<
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_vectored(
|
||||
&self,
|
||||
buf: &[IoSlice<'_>],
|
||||
timeout: Option<Duration>,
|
||||
) -> io::Result<usize> {
|
||||
match self {
|
||||
Self::V4(client) => client.write_vectored(buf, timeout),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read(&self, buf: &mut [u8], timeout: Option<Duration>) -> io::Result<usize> {
|
||||
match self {
|
||||
Self::V4(client) => client.read(buf, timeout),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use r_efi::efi::{self, Status};
|
||||
use r_efi::protocols::tcp4;
|
||||
|
||||
use crate::io;
|
||||
use crate::io::{self, IoSlice};
|
||||
use crate::net::SocketAddrV4;
|
||||
use crate::ptr::NonNull;
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
@@ -108,11 +108,7 @@ pub(crate) fn connect(&self, timeout: Option<Duration>) -> io::Result<()> {
|
||||
}
|
||||
|
||||
pub(crate) fn write(&self, buf: &[u8], timeout: Option<Duration>) -> io::Result<usize> {
|
||||
let evt = unsafe { self.create_evt() }?;
|
||||
let completion_token =
|
||||
tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS };
|
||||
let data_len = u32::try_from(buf.len()).unwrap_or(u32::MAX);
|
||||
|
||||
let fragment = tcp4::FragmentData {
|
||||
fragment_length: data_len,
|
||||
fragment_buffer: buf.as_ptr().cast::<crate::ffi::c_void>().cast_mut(),
|
||||
@@ -125,14 +121,63 @@ pub(crate) fn write(&self, buf: &[u8], timeout: Option<Duration>) -> io::Result<
|
||||
fragment_table: [fragment],
|
||||
};
|
||||
|
||||
let protocol = self.protocol.as_ptr();
|
||||
let mut token = tcp4::IoToken {
|
||||
completion_token,
|
||||
packet: tcp4::IoTokenPacket {
|
||||
tx_data: (&raw mut tx_data).cast::<tcp4::TransmitData<0>>(),
|
||||
},
|
||||
self.write_inner((&raw mut tx_data).cast(), timeout).map(|_| data_len as usize)
|
||||
}
|
||||
|
||||
pub(crate) fn write_vectored(
|
||||
&self,
|
||||
buf: &[IoSlice<'_>],
|
||||
timeout: Option<Duration>,
|
||||
) -> io::Result<usize> {
|
||||
let mut data_length = 0u32;
|
||||
let mut fragment_count = 0u32;
|
||||
|
||||
// Calculate how many IoSlice in buf can be transmitted.
|
||||
for i in buf {
|
||||
// IoSlice length is always <= u32::MAX in UEFI.
|
||||
match data_length
|
||||
.checked_add(u32::try_from(i.as_slice().len()).expect("value is stored as a u32"))
|
||||
{
|
||||
Some(x) => data_length = x,
|
||||
None => break,
|
||||
}
|
||||
fragment_count += 1;
|
||||
}
|
||||
|
||||
let tx_data_size = size_of::<tcp4::TransmitData<0>>()
|
||||
+ size_of::<tcp4::FragmentData>() * (fragment_count as usize);
|
||||
let mut tx_data = helpers::UefiBox::<tcp4::TransmitData>::new(tx_data_size)?;
|
||||
tx_data.write(tcp4::TransmitData {
|
||||
push: r_efi::efi::Boolean::FALSE,
|
||||
urgent: r_efi::efi::Boolean::FALSE,
|
||||
data_length,
|
||||
fragment_count,
|
||||
fragment_table: [],
|
||||
});
|
||||
unsafe {
|
||||
// SAFETY: IoSlice and FragmentData are guaranteed to have same layout.
|
||||
crate::ptr::copy_nonoverlapping(
|
||||
buf.as_ptr().cast(),
|
||||
(*tx_data.as_mut_ptr()).fragment_table.as_mut_ptr(),
|
||||
fragment_count as usize,
|
||||
);
|
||||
};
|
||||
|
||||
self.write_inner(tx_data.as_mut_ptr(), timeout).map(|_| data_length as usize)
|
||||
}
|
||||
|
||||
fn write_inner(
|
||||
&self,
|
||||
tx_data: *mut tcp4::TransmitData,
|
||||
timeout: Option<Duration>,
|
||||
) -> io::Result<()> {
|
||||
let evt = unsafe { self.create_evt() }?;
|
||||
let completion_token =
|
||||
tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS };
|
||||
|
||||
let protocol = self.protocol.as_ptr();
|
||||
let mut token = tcp4::IoToken { completion_token, packet: tcp4::IoTokenPacket { tx_data } };
|
||||
|
||||
let r = unsafe { ((*protocol).transmit)(protocol, &mut token) };
|
||||
if r.is_error() {
|
||||
return Err(io::Error::from_raw_os_error(r.as_usize()));
|
||||
@@ -143,7 +188,7 @@ pub(crate) fn write(&self, buf: &[u8], timeout: Option<Duration>) -> io::Result<
|
||||
if completion_token.status.is_error() {
|
||||
Err(io::Error::from_raw_os_error(completion_token.status.as_usize()))
|
||||
} else {
|
||||
Ok(data_len as usize)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
use r_efi::efi::{self, Guid};
|
||||
use r_efi::protocols::{device_path, device_path_to_text, service_binding, shell};
|
||||
|
||||
use crate::alloc::Layout;
|
||||
use crate::ffi::{OsStr, OsString};
|
||||
use crate::io::{self, const_error};
|
||||
use crate::marker::PhantomData;
|
||||
@@ -769,3 +770,39 @@ pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Addres
|
||||
pub(crate) const fn ipv4_from_r_efi(ip: efi::Ipv4Address) -> crate::net::Ipv4Addr {
|
||||
crate::net::Ipv4Addr::new(ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3])
|
||||
}
|
||||
|
||||
/// This type is intended for use with ZSTs. Since such types are unsized, a reference to such types
|
||||
/// is not valid in Rust. Thus, only pointers should be used when interacting with such types.
|
||||
pub(crate) struct UefiBox<T> {
|
||||
inner: NonNull<T>,
|
||||
size: usize,
|
||||
}
|
||||
|
||||
impl<T> UefiBox<T> {
|
||||
pub(crate) fn new(len: usize) -> io::Result<Self> {
|
||||
assert!(len >= size_of::<T>());
|
||||
// UEFI always expects types to be 8 byte aligned.
|
||||
let layout = Layout::from_size_align(len, 8).unwrap();
|
||||
let ptr = unsafe { crate::alloc::alloc(layout) };
|
||||
|
||||
match NonNull::new(ptr.cast()) {
|
||||
Some(inner) => Ok(Self { inner, size: len }),
|
||||
None => Err(io::Error::new(io::ErrorKind::OutOfMemory, "Allocation failed")),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write(&mut self, data: T) {
|
||||
unsafe { self.inner.write(data) }
|
||||
}
|
||||
|
||||
pub(crate) fn as_mut_ptr(&mut self) -> *mut T {
|
||||
self.inner.as_ptr().cast()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for UefiBox<T> {
|
||||
fn drop(&mut self) {
|
||||
let layout = Layout::from_size_align(self.size, 8).unwrap();
|
||||
unsafe { crate::alloc::dealloc(self.inner.as_ptr().cast(), layout) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
LINUX_VERSION=v6.17-rc5
|
||||
# https://github.com/rust-lang/rust/pull/145974
|
||||
LINUX_VERSION=842cfd8e5aff3157cb25481b2900b49c188d628a
|
||||
|
||||
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
|
||||
../x.py build --stage 2 library rustdoc clippy rustfmt
|
||||
|
||||
+1
-1
Submodule src/doc/book updated: af415fc6c8...f660f34188
+1
-1
Submodule src/doc/edition-guide updated: e2ed891f00...5c621253d8
+1
-1
Submodule src/doc/reference updated: 752eab01ce...e122eefff3
+1
-1
Submodule src/doc/rust-by-example updated: 2c9b490d70...160e6bbca7
@@ -209,6 +209,27 @@ Note that while the `-C instrument-coverage` option is stable, the profile data
|
||||
format produced by the resulting instrumentation may change, and may not work
|
||||
with coverage tools other than those built and shipped with the compiler.
|
||||
|
||||
## jump-tables
|
||||
|
||||
This option is used to allow or prevent the LLVM codegen backend from creating
|
||||
jump tables when lowering switches from Rust code.
|
||||
|
||||
* `y`, `yes`, `on`, `true` or no value: allow jump tables (the default).
|
||||
* `n`, `no`, `off` or `false`: disable jump tables.
|
||||
|
||||
To prevent jump tables being created from Rust code, a target must ensure
|
||||
all crates are compiled with jump tables disabled.
|
||||
|
||||
Note, in many cases the Rust toolchain is distributed with precompiled
|
||||
crates, such as the core and std crates, which could possibly include
|
||||
jump tables. Furthermore, this option does not guarantee a target will
|
||||
be free of jump tables. They could arise from external dependencies,
|
||||
inline asm, or other complicated interactions when using crates which
|
||||
are compiled with jump table support.
|
||||
|
||||
Disabling jump tables can be used to help provide protection against
|
||||
jump-oriented-programming (JOP) attacks.
|
||||
|
||||
## link-arg
|
||||
|
||||
This flag lets you append a single extra argument to the linker invocation.
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# `no-jump-tables`
|
||||
|
||||
The tracking issue for this feature is [#116592](https://github.com/rust-lang/rust/issues/116592)
|
||||
|
||||
---
|
||||
|
||||
This option enables the `-fno-jump-tables` flag for LLVM, which makes the
|
||||
codegen backend avoid generating jump tables when lowering switches.
|
||||
|
||||
This option adds the LLVM `no-jump-tables=true` attribute to every function.
|
||||
|
||||
The option can be used to help provide protection against
|
||||
jump-oriented-programming (JOP) attacks, such as with the linux kernel's [IBT].
|
||||
|
||||
```sh
|
||||
RUSTFLAGS="-Zno-jump-tables" cargo +nightly build -Z build-std
|
||||
```
|
||||
|
||||
[IBT]: https://www.phoronix.com/news/Linux-IBT-By-Default-Tip
|
||||
@@ -1,4 +1,5 @@
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
|
||||
#![doc(
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/",
|
||||
html_playground_url = "https://play.rust-lang.org/"
|
||||
@@ -8,7 +9,6 @@
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_into_inner)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(file_buffered)]
|
||||
#![feature(formatting_options)]
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
"only-aarch64",
|
||||
"only-aarch64-apple-darwin",
|
||||
"only-aarch64-unknown-linux-gnu",
|
||||
"only-aarch64-unknown-uefi",
|
||||
"only-apple",
|
||||
"only-arm",
|
||||
"only-arm64ec",
|
||||
|
||||
@@ -68,14 +68,20 @@
|
||||
"library/std/src/io/error.rs", // Repr unpacked needed for UEFI
|
||||
];
|
||||
|
||||
pub fn check(path: &Path, tidy_ctx: TidyCtx) {
|
||||
let mut check = tidy_ctx.start_check(CheckId::new("pal").path(path));
|
||||
pub fn check(library_path: &Path, tidy_ctx: TidyCtx) {
|
||||
let mut check = tidy_ctx.start_check(CheckId::new("pal").path(library_path));
|
||||
|
||||
let root_path = library_path.parent().unwrap();
|
||||
// Let's double-check that this is the root path by making sure it has `x.py`.
|
||||
assert!(root_path.join("x.py").is_file());
|
||||
|
||||
// Sanity check that the complex parsing here works.
|
||||
let mut saw_target_arch = false;
|
||||
let mut saw_cfg_bang = false;
|
||||
walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| {
|
||||
walk(library_path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| {
|
||||
let file = entry.path();
|
||||
// We don't want the absolute path to matter, so make it relative.
|
||||
let file = file.strip_prefix(root_path).unwrap();
|
||||
let filestr = file.to_string_lossy().replace("\\", "/");
|
||||
if !filestr.ends_with(".rs") {
|
||||
return;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Test that jump tables are (not) emitted when the `-Zno-jump-tables`
|
||||
// Test that jump tables are (not) emitted when the `-Cjump-tables=no`
|
||||
// flag is (not) set.
|
||||
|
||||
//@ revisions: unset set
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: -Copt-level=3
|
||||
//@ [set] compile-flags: -Zno-jump-tables
|
||||
//@ [set] compile-flags: -Cjump-tables=no
|
||||
//@ only-x86_64
|
||||
//@ ignore-sgx
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Test that the `no-jump-tables` function attribute are (not) emitted when
|
||||
// the `-Zno-jump-tables` flag is (not) set.
|
||||
// the `-Cjump-tables=no` flag is (not) set.
|
||||
|
||||
//@ add-minicore
|
||||
//@ revisions: unset set
|
||||
//@ revisions: unset set_no set_yes
|
||||
//@ needs-llvm-components: x86
|
||||
//@ compile-flags: --target x86_64-unknown-linux-gnu
|
||||
//@ [set] compile-flags: -Zno-jump-tables
|
||||
//@ [set_no] compile-flags: -Cjump-tables=no
|
||||
//@ [set_yes] compile-flags: -Cjump-tables=yes
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, lang_items)]
|
||||
@@ -19,5 +20,6 @@ pub fn foo() {
|
||||
// CHECK: @foo() unnamed_addr #0
|
||||
|
||||
// unset-NOT: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
|
||||
// set: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
|
||||
// set_yes-NOT: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
|
||||
// set_no: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
LL | fn needs_async_fn(_: impl AsyncFn()) {}
|
||||
| -------------- change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = 1;
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | needs_async_fn(async || {
|
||||
| -------------- ^^^^^^^^
|
||||
| | |
|
||||
|
||||
@@ -4,6 +4,8 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu
|
||||
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = 0;
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | let _f = to_fn(|| x = 42);
|
||||
| ----- -- ^^^^^^ cannot assign
|
||||
| | |
|
||||
@@ -16,6 +18,8 @@ error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `F
|
||||
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut y = 0;
|
||||
| ----- `y` declared here, outside the closure
|
||||
LL | let _g = to_fn(|| set(&mut y));
|
||||
| ----- -- ^^^^^^ cannot borrow as mutable
|
||||
| | |
|
||||
@@ -28,6 +32,9 @@ error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closu
|
||||
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut z = 0;
|
||||
| ----- `z` declared here, outside the closure
|
||||
...
|
||||
LL | to_fn(|| z = 42);
|
||||
| ----- -- ^^^^^^ cannot assign
|
||||
| | |
|
||||
|
||||
@@ -40,6 +40,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
LL | fn make_fn<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = 0;
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | let f = make_fn(|| {
|
||||
| ------- -- in this closure
|
||||
| |
|
||||
|
||||
@@ -139,7 +139,9 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu
|
||||
|
|
||||
LL | fn fn_ref<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL |
|
||||
LL | fn ref_closure(mut x: (i32,)) {
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | fn_ref(|| {
|
||||
| ------ -- in this closure
|
||||
| |
|
||||
@@ -152,7 +154,9 @@ error[E0594]: cannot assign to `x.0`, as `Fn` closures cannot mutate their captu
|
||||
|
|
||||
LL | fn fn_ref<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL |
|
||||
LL | fn ref_closure(mut x: (i32,)) {
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | fn_ref(|| {
|
||||
| ------ -- in this closure
|
||||
| |
|
||||
@@ -166,7 +170,9 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
|
|
||||
LL | fn fn_ref<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL |
|
||||
LL | fn ref_closure(mut x: (i32,)) {
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | fn_ref(|| {
|
||||
| ------ -- in this closure
|
||||
| |
|
||||
@@ -180,7 +186,9 @@ error[E0596]: cannot borrow `x.0` as mutable, as `Fn` closures cannot mutate the
|
||||
|
|
||||
LL | fn fn_ref<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL |
|
||||
LL | fn ref_closure(mut x: (i32,)) {
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | fn_ref(|| {
|
||||
| ------ -- in this closure
|
||||
| |
|
||||
|
||||
@@ -4,6 +4,9 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
LL | fn call_it<F>(f: F) where F: Fn() { f(); }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = A;
|
||||
| ----- `x` declared here, outside the closure
|
||||
...
|
||||
LL | call_it(|| x.gen_mut());
|
||||
| ------- -- ^ cannot borrow as mutable
|
||||
| | |
|
||||
@@ -16,6 +19,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
LL | fn call_it<F>(f: F) where F: Fn() { f(); }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = A;
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | call_it(|| {
|
||||
| ------- -- in this closure
|
||||
| |
|
||||
|
||||
@@ -4,6 +4,8 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu
|
||||
LL | fn assoc_func(&self, _f: impl Fn()) -> usize {
|
||||
| --------- change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = ();
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | s.assoc_func(|| x = ());
|
||||
| --------------^^^^^^-
|
||||
| | | |
|
||||
@@ -17,6 +19,9 @@ error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closu
|
||||
LL | fn func(_f: impl Fn()) -> usize {
|
||||
| --------- change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut x = ();
|
||||
| ----- `x` declared here, outside the closure
|
||||
...
|
||||
LL | func(|| x = ())
|
||||
| ---- -- ^^^^^^ cannot assign
|
||||
| | |
|
||||
|
||||
@@ -47,7 +47,9 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
|
|
||||
LL | fn fn_ref<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL |
|
||||
LL | fn two_closures_ref_mut(mut x: i32) {
|
||||
| ----- `x` declared here, outside the closure
|
||||
LL | fn_ref(|| {
|
||||
| ------ -- in this closure
|
||||
| |
|
||||
@@ -89,6 +91,8 @@ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `F
|
||||
LL | fn fn_ref<F: Fn()>(f: F) -> F { f }
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | fn two_closures_ref(x: i32) {
|
||||
| - `x` declared here, outside the closure
|
||||
LL | fn_ref(|| {
|
||||
| ------ -- in this closure
|
||||
| |
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//! Regression test for #98254, missing `__chkstk` symbol on `aarch64-unknown-uefi`.
|
||||
//@ build-pass
|
||||
//@ only-aarch64-unknown-uefi
|
||||
//@ compile-flags: -Cpanic=abort
|
||||
//@ compile-flags: -Clinker=rust-lld
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#[panic_handler]
|
||||
fn panic_handler(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[export_name = "efi_main"]
|
||||
fn main() {
|
||||
let b = [0; 1024];
|
||||
}
|
||||
@@ -4,6 +4,8 @@ error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn`
|
||||
LL | fn call<F>(f: F) where F : Fn() {
|
||||
| - change this to accept `FnMut` instead of `Fn`
|
||||
...
|
||||
LL | let mut counter = 0;
|
||||
| ----------- `counter` declared here, outside the closure
|
||||
LL | call(|| {
|
||||
| ---- -- in this closure
|
||||
| |
|
||||
|
||||
Reference in New Issue
Block a user