diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index a51aa90355bcd..12490880ab0eb 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -458,13 +458,11 @@ impl<'a, 'b> Rustc<'a, 'b> { } } -impl server::Types for Rustc<'_, '_> { +impl server::Server for Rustc<'_, '_> { type TokenStream = TokenStream; type Span = Span; type Symbol = Symbol; -} -impl server::Server for Rustc<'_, '_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { def_site: self.def_site, diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 2cc8e9d6739c8..6e7b93a5e719f 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -18,6 +18,7 @@ use rustc_const_eval::check_consts::{ConstCx, qualifs}; use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -329,6 +330,7 @@ impl<'tcx> Validator<'_, 'tcx> { if let TempState::Defined { location: loc, .. } = self.temps[local] && let Left(statement) = self.body.stmt_at(loc) && let Some((_, Rvalue::Use(Operand::Constant(c)))) = statement.kind.as_assign() + && self.should_evaluate_for_promotion_checks(c.const_) && let Some(idx) = c.const_.try_eval_target_usize(self.tcx, self.typing_env) // Determine the type of the thing we are indexing. && let ty::Array(_, len) = place_base.ty(self.body, self.tcx).ty.kind() @@ -484,7 +486,9 @@ impl<'tcx> Validator<'_, 'tcx> { let sz = lhs_ty.primitive_size(self.tcx); // Integer division: the RHS must be a non-zero const. let rhs_val = match rhs { - Operand::Constant(c) => { + Operand::Constant(c) + if self.should_evaluate_for_promotion_checks(c.const_) => + { c.const_.try_eval_scalar_int(self.tcx, self.typing_env) } _ => None, @@ -502,9 +506,14 @@ impl<'tcx> Validator<'_, 'tcx> { // The RHS is -1 or unknown, so we have to be careful. // But is the LHS int::MIN? let lhs_val = match lhs { - Operand::Constant(c) => c - .const_ - .try_eval_scalar_int(self.tcx, self.typing_env), + Operand::Constant(c) + if self.should_evaluate_for_promotion_checks( + c.const_, + ) => + { + c.const_ + .try_eval_scalar_int(self.tcx, self.typing_env) + } _ => None, }; let lhs_min = sz.signed_int_min(); @@ -683,6 +692,28 @@ impl<'tcx> Validator<'_, 'tcx> { // This passed all checks, so let's accept. Ok(()) } + + /// Can we try to evaluate a given constant at this point in compilation? Attempting to evaluate + /// a const block before borrow-checking will result in a query cycle (#150464). + fn should_evaluate_for_promotion_checks(&self, constant: Const<'tcx>) -> bool { + match constant { + // `Const::Ty` is always a `ConstKind::Param` right now and that can never be turned + // into a mir value for promotion + // FIXME(mgca): do we want uses of type_const to be normalized during promotion? + Const::Ty(..) => false, + Const::Val(..) => true, + // Evaluating a MIR constant requires borrow-checking it. For inline consts, as of + // #138499, this means borrow-checking its typeck root. Since borrow-checking the + // typeck root requires promoting its constants, trying to evaluate an inline const here + // will result in a query cycle. To avoid the cycle, we can't evaluate const blocks yet. + // Other kinds of unevaluated's can cause query cycles too when they arise from + // self-reference in user code; e.g. evaluating a constant can require evaluating a + // const function that uses that constant, again requiring evaluation of the constant. + // However, this form of cycle renders both the constant and function unusable in + // general, so we don't need to special-case it here. + Const::Unevaluated(uc, _) => self.tcx.def_kind(uc.def) != DefKind::InlineConst, + } + } } fn validate_candidates( diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c4d16ba633b81..e8c9d26fb3b51 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -182,6 +182,7 @@ #![feature(staged_api)] #![feature(stmt_expr_attributes)] #![feature(strict_provenance_lints)] +#![feature(target_feature_inline_always)] #![feature(trait_alias)] #![feature(transparent_unions)] #![feature(try_blocks)] diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 0d87a727ae40b..8f4a79b389f62 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -30,19 +30,19 @@ impl Drop for TokenStream { } impl Encode for TokenStream { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { mem::ManuallyDrop::new(self).handle.encode(w, s); } } impl Encode for &TokenStream { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.handle.encode(w, s); } } impl Decode<'_, '_, S> for TokenStream { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { TokenStream { handle: handle::Handle::decode(r, s) } } } @@ -56,23 +56,17 @@ impl !Send for Span {} impl !Sync for Span {} impl Encode for Span { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.handle.encode(w, s); } } impl Decode<'_, '_, S> for Span { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { Span { handle: handle::Handle::decode(r, s) } } } -// FIXME(eddyb) generate these impls by pattern-matching on the -// names of methods - also could use the presence of `fn drop` -// to distinguish between 'owned and 'interned, above. -// Alternatively, special "modes" could be listed of types in with_api -// instead of pattern matching on methods, here and in server decl. - impl Clone for TokenStream { fn clone(&self) -> Self { Methods::ts_clone(self) @@ -104,10 +98,7 @@ pub(crate) use super::symbol::Symbol; macro_rules! define_client_side { ( - Methods { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* - }, - $($name:ident),* $(,)? + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* ) => { impl Methods { $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)? { @@ -115,7 +106,7 @@ macro_rules! define_client_side { let mut buf = bridge.cached_buffer.take(); buf.clear(); - api_tags::Method::$method.encode(&mut buf, &mut ()); + ApiTags::$method.encode(&mut buf, &mut ()); $($arg.encode(&mut buf, &mut ());)* buf = bridge.dispatch.call(buf); @@ -130,7 +121,7 @@ macro_rules! define_client_side { } } } -with_api!(self, self, define_client_side); +with_api!(self, define_client_side); struct Bridge<'a> { /// Reusable buffer (only `clear`-ed, never shrunk), primarily diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 6f7c8726f9253..244ab7d81b022 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -13,92 +13,76 @@ use std::ops::{Bound, Range}; use std::sync::Once; use std::{fmt, marker, mem, panic, thread}; -use crate::{Delimiter, Level, Spacing}; +use crate::{Delimiter, Level}; /// Higher-order macro describing the server RPC API, allowing automatic /// generation of type-safe Rust APIs, both client-side and server-side. /// -/// `with_api!(MySelf, my_self, my_macro)` expands to: +/// `with_api!(MySelf, my_macro)` expands to: /// ```rust,ignore (pseudo-code) /// my_macro! { -/// Methods { -/// // ... -/// fn lit_character(ch: char) -> MySelf::Literal; -/// // ... -/// fn lit_span(my_self: &MySelf::Literal) -> MySelf::Span; -/// fn lit_set_span(my_self: &mut MySelf::Literal, span: MySelf::Span); -/// }, -/// Literal, -/// Span, +/// fn lit_character(ch: char) -> MySelf::Literal; +/// fn lit_span(lit: &MySelf::Literal) -> MySelf::Span; +/// fn lit_set_span(lit: &mut MySelf::Literal, span: MySelf::Span); /// // ... /// } /// ``` /// -/// The first two arguments serve to customize the arguments names -/// and argument/return types, to enable several different usecases: -/// -/// If `my_self` is just `self`, then each `fn` signature can be used -/// as-is for a method. If it's anything else (`self_` in practice), -/// then the signatures don't have a special `self` argument, and -/// can, therefore, have a different one introduced. +/// The first argument serves to customize the argument/return types, +/// to enable several different usecases: /// /// If `MySelf` is just `Self`, then the types are only valid inside /// a trait or a trait impl, where the trait has associated types /// for each of the API types. If non-associated types are desired, /// a module name (`self` in practice) can be used instead of `Self`. macro_rules! with_api { - ($S:ident, $self:ident, $m:ident) => { + ($S:ident, $m:ident) => { $m! { - Methods { - fn injected_env_var(var: &str) -> Option; - fn track_env_var(var: &str, value: Option<&str>); - fn track_path(path: &str); - fn literal_from_str(s: &str) -> Result, ()>; - fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>); - - fn ts_drop(stream: $S::TokenStream); - fn ts_clone(stream: &$S::TokenStream) -> $S::TokenStream; - fn ts_is_empty(stream: &$S::TokenStream) -> bool; - fn ts_expand_expr(stream: &$S::TokenStream) -> Result<$S::TokenStream, ()>; - fn ts_from_str(src: &str) -> $S::TokenStream; - fn ts_to_string(stream: &$S::TokenStream) -> String; - fn ts_from_token_tree( - tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>, - ) -> $S::TokenStream; - fn ts_concat_trees( - base: Option<$S::TokenStream>, - trees: Vec>, - ) -> $S::TokenStream; - fn ts_concat_streams( - base: Option<$S::TokenStream>, - streams: Vec<$S::TokenStream>, - ) -> $S::TokenStream; - fn ts_into_trees( - stream: $S::TokenStream - ) -> Vec>; - - fn span_debug(span: $S::Span) -> String; - fn span_parent(span: $S::Span) -> Option<$S::Span>; - fn span_source(span: $S::Span) -> $S::Span; - fn span_byte_range(span: $S::Span) -> Range; - fn span_start(span: $S::Span) -> $S::Span; - fn span_end(span: $S::Span) -> $S::Span; - fn span_line(span: $S::Span) -> usize; - fn span_column(span: $S::Span) -> usize; - fn span_file(span: $S::Span) -> String; - fn span_local_file(span: $S::Span) -> Option; - fn span_join(span: $S::Span, other: $S::Span) -> Option<$S::Span>; - fn span_subspan(span: $S::Span, start: Bound, end: Bound) -> Option<$S::Span>; - fn span_resolved_at(span: $S::Span, at: $S::Span) -> $S::Span; - fn span_source_text(span: $S::Span) -> Option; - fn span_save_span(span: $S::Span) -> usize; - fn span_recover_proc_macro_span(id: usize) -> $S::Span; - - fn symbol_normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>; - }, - TokenStream, - Span, - Symbol, + fn injected_env_var(var: &str) -> Option; + fn track_env_var(var: &str, value: Option<&str>); + fn track_path(path: &str); + fn literal_from_str(s: &str) -> Result, ()>; + fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>); + + fn ts_drop(stream: $S::TokenStream); + fn ts_clone(stream: &$S::TokenStream) -> $S::TokenStream; + fn ts_is_empty(stream: &$S::TokenStream) -> bool; + fn ts_expand_expr(stream: &$S::TokenStream) -> Result<$S::TokenStream, ()>; + fn ts_from_str(src: &str) -> $S::TokenStream; + fn ts_to_string(stream: &$S::TokenStream) -> String; + fn ts_from_token_tree( + tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>, + ) -> $S::TokenStream; + fn ts_concat_trees( + base: Option<$S::TokenStream>, + trees: Vec>, + ) -> $S::TokenStream; + fn ts_concat_streams( + base: Option<$S::TokenStream>, + streams: Vec<$S::TokenStream>, + ) -> $S::TokenStream; + fn ts_into_trees( + stream: $S::TokenStream + ) -> Vec>; + + fn span_debug(span: $S::Span) -> String; + fn span_parent(span: $S::Span) -> Option<$S::Span>; + fn span_source(span: $S::Span) -> $S::Span; + fn span_byte_range(span: $S::Span) -> Range; + fn span_start(span: $S::Span) -> $S::Span; + fn span_end(span: $S::Span) -> $S::Span; + fn span_line(span: $S::Span) -> usize; + fn span_column(span: $S::Span) -> usize; + fn span_file(span: $S::Span) -> String; + fn span_local_file(span: $S::Span) -> Option; + fn span_join(span: $S::Span, other: $S::Span) -> Option<$S::Span>; + fn span_subspan(span: $S::Span, start: Bound, end: Bound) -> Option<$S::Span>; + fn span_resolved_at(span: $S::Span, at: $S::Span) -> $S::Span; + fn span_source_text(span: $S::Span) -> Option; + fn span_save_span(span: $S::Span) -> usize; + fn span_recover_proc_macro_span(id: usize) -> $S::Span; + + fn symbol_normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>; } }; } @@ -129,7 +113,7 @@ mod symbol; use buffer::Buffer; pub use rpc::PanicMessage; -use rpc::{Decode, Encode, Reader, Writer}; +use rpc::{Decode, Encode}; /// Configuration for establishing an active connection between a server and a /// client. The server creates the bridge config (`run_server` in `server.rs`), @@ -151,26 +135,18 @@ pub struct BridgeConfig<'a> { impl !Send for BridgeConfig<'_> {} impl !Sync for BridgeConfig<'_> {} -#[forbid(unsafe_code)] -#[allow(non_camel_case_types)] -mod api_tags { - use super::rpc::{Decode, Encode, Reader, Writer}; - - macro_rules! declare_tags { - ( - Methods { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* - }, - $($name:ident),* $(,)? - ) => { - pub(super) enum Method { - $($method),* - } - rpc_encode_decode!(enum Method { $($method),* }); +macro_rules! declare_tags { + ( + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* + ) => { + #[allow(non_camel_case_types)] + pub(super) enum ApiTags { + $($method),* } + rpc_encode_decode!(enum ApiTags { $($method),* }); } - with_api!(self, self, declare_tags); } +with_api!(self, declare_tags); /// Helper to wrap associated types to allow trait impl dispatch. /// That is, normally a pair of impls for `T::Foo` and `T::Bar` @@ -179,11 +155,6 @@ mod api_tags { trait Mark { type Unmarked; fn mark(unmarked: Self::Unmarked) -> Self; -} - -/// Unwrap types wrapped by `Mark::mark` (see `Mark` for details). -trait Unmark { - type Unmarked; fn unmark(self) -> Self::Unmarked; } @@ -198,23 +169,17 @@ impl Mark for Marked { fn mark(unmarked: Self::Unmarked) -> Self { Marked { value: unmarked, _marker: marker::PhantomData } } -} -impl Unmark for Marked { - type Unmarked = T; fn unmark(self) -> Self::Unmarked { self.value } } -impl<'a, T, M> Unmark for &'a Marked { +impl<'a, T, M> Mark for &'a Marked { type Unmarked = &'a T; - fn unmark(self) -> Self::Unmarked { - &self.value + fn mark(_: Self::Unmarked) -> Self { + unreachable!() } -} -impl<'a, T, M> Unmark for &'a mut Marked { - type Unmarked = &'a mut T; fn unmark(self) -> Self::Unmarked { - &mut self.value + &self.value } } @@ -224,9 +189,6 @@ impl Mark for Vec { // Should be a no-op due to std's in-place collect optimizations. unmarked.into_iter().map(T::mark).collect() } -} -impl Unmark for Vec { - type Unmarked = Vec; fn unmark(self) -> Self::Unmarked { // Should be a no-op due to std's in-place collect optimizations. self.into_iter().map(T::unmark).collect() @@ -241,9 +203,6 @@ macro_rules! mark_noop { fn mark(unmarked: Self::Unmarked) -> Self { unmarked } - } - impl Unmark for $ty { - type Unmarked = Self; fn unmark(self) -> Self::Unmarked { self } @@ -254,8 +213,6 @@ macro_rules! mark_noop { mark_noop! { (), bool, - char, - &'_ [u8], &'_ str, String, u8, @@ -263,7 +220,6 @@ mark_noop! { Delimiter, LitKind, Level, - Spacing, } rpc_encode_decode!( @@ -282,12 +238,6 @@ rpc_encode_decode!( Help, } ); -rpc_encode_decode!( - enum Spacing { - Alone, - Joint, - } -); #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum LitKind { @@ -333,13 +283,9 @@ macro_rules! mark_compound { $($field: Mark::mark(unmarked.$field)),* } } - } - - impl<$($T: Unmark),+> Unmark for $name <$($T),+> { - type Unmarked = $name <$($T::Unmarked),+>; fn unmark(self) -> Self::Unmarked { $name { - $($field: Unmark::unmark(self.$field)),* + $($field: Mark::unmark(self.$field)),* } } } @@ -354,14 +300,10 @@ macro_rules! mark_compound { })* } } - } - - impl<$($T: Unmark),+> Unmark for $name <$($T),+> { - type Unmarked = $name <$($T::Unmarked),+>; fn unmark(self) -> Self::Unmarked { match self { $($name::$variant $(($field))? => { - $name::$variant $((Unmark::unmark($field)))? + $name::$variant $((Mark::unmark($field)))? })* } } diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs index ed67674a74ab7..63329c8c02601 100644 --- a/library/proc_macro/src/bridge/rpc.rs +++ b/library/proc_macro/src/bridge/rpc.rs @@ -4,28 +4,26 @@ use std::any::Any; use std::io::Write; use std::num::NonZero; -pub(super) type Writer = super::buffer::Buffer; +use super::buffer::Buffer; pub(super) trait Encode: Sized { - fn encode(self, w: &mut Writer, s: &mut S); + fn encode(self, w: &mut Buffer, s: &mut S); } -pub(super) type Reader<'a> = &'a [u8]; - pub(super) trait Decode<'a, 's, S>: Sized { - fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self; + fn decode(r: &mut &'a [u8], s: &'s mut S) -> Self; } macro_rules! rpc_encode_decode { (le $ty:ty) => { impl Encode for $ty { - fn encode(self, w: &mut Writer, _: &mut S) { + fn encode(self, w: &mut Buffer, _: &mut S) { w.extend_from_array(&self.to_le_bytes()); } } impl Decode<'_, '_, S> for $ty { - fn decode(r: &mut Reader<'_>, _: &mut S) -> Self { + fn decode(r: &mut &[u8], _: &mut S) -> Self { const N: usize = size_of::<$ty>(); let mut bytes = [0; N]; @@ -38,7 +36,7 @@ macro_rules! rpc_encode_decode { }; (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => { impl),+)?> Encode for $name $(<$($T),+>)? { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { $(self.$field.encode(w, s);)* } } @@ -46,7 +44,7 @@ macro_rules! rpc_encode_decode { impl<'a, S, $($($T: for<'s> Decode<'a, 's, S>),+)?> Decode<'a, '_, S> for $name $(<$($T),+>)? { - fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { + fn decode(r: &mut &'a [u8], s: &mut S) -> Self { $name { $($field: Decode::decode(r, s)),* } @@ -55,10 +53,12 @@ macro_rules! rpc_encode_decode { }; (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => { impl),+)?> Encode for $name $(<$($T),+>)? { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { // HACK(eddyb): `Tag` enum duplicated between the // two impls as there's no other place to stash it. - #[repr(u8)] enum Tag { $($variant),* } + #[allow(non_camel_case_types)] + #[repr(u8)] + enum Tag { $($variant),* } match self { $($name::$variant $(($field))* => { @@ -72,10 +72,10 @@ macro_rules! rpc_encode_decode { impl<'a, S, $($($T: for<'s> Decode<'a, 's, S>),+)?> Decode<'a, '_, S> for $name $(<$($T),+>)? { - fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { + fn decode(r: &mut &'a [u8], s: &mut S) -> Self { // HACK(eddyb): `Tag` enum duplicated between the // two impls as there's no other place to stash it. - #[allow(non_upper_case_globals)] + #[allow(non_upper_case_globals, non_camel_case_types)] mod tag { #[repr(u8)] enum Tag { $($variant),* } @@ -95,21 +95,21 @@ macro_rules! rpc_encode_decode { } impl Encode for () { - fn encode(self, _: &mut Writer, _: &mut S) {} + fn encode(self, _: &mut Buffer, _: &mut S) {} } impl Decode<'_, '_, S> for () { - fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {} + fn decode(_: &mut &[u8], _: &mut S) -> Self {} } impl Encode for u8 { - fn encode(self, w: &mut Writer, _: &mut S) { + fn encode(self, w: &mut Buffer, _: &mut S) { w.push(self); } } impl Decode<'_, '_, S> for u8 { - fn decode(r: &mut Reader<'_>, _: &mut S) -> Self { + fn decode(r: &mut &[u8], _: &mut S) -> Self { let x = r[0]; *r = &r[1..]; x @@ -120,13 +120,13 @@ rpc_encode_decode!(le u32); rpc_encode_decode!(le usize); impl Encode for bool { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { (self as u8).encode(w, s); } } impl Decode<'_, '_, S> for bool { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { match u8::decode(r, s) { 0 => false, 1 => true, @@ -135,32 +135,20 @@ impl Decode<'_, '_, S> for bool { } } -impl Encode for char { - fn encode(self, w: &mut Writer, s: &mut S) { - (self as u32).encode(w, s); - } -} - -impl Decode<'_, '_, S> for char { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { - char::from_u32(u32::decode(r, s)).unwrap() - } -} - impl Encode for NonZero { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.get().encode(w, s); } } impl Decode<'_, '_, S> for NonZero { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { Self::new(u32::decode(r, s)).unwrap() } } impl, B: Encode> Encode for (A, B) { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.0.encode(w, s); self.1.encode(w, s); } @@ -169,53 +157,42 @@ impl, B: Encode> Encode for (A, B) { impl<'a, S, A: for<'s> Decode<'a, 's, S>, B: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> for (A, B) { - fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { + fn decode(r: &mut &'a [u8], s: &mut S) -> Self { (Decode::decode(r, s), Decode::decode(r, s)) } } -impl Encode for &[u8] { - fn encode(self, w: &mut Writer, s: &mut S) { - self.len().encode(w, s); - w.write_all(self).unwrap(); +impl Encode for &str { + fn encode(self, w: &mut Buffer, s: &mut S) { + let bytes = self.as_bytes(); + bytes.len().encode(w, s); + w.write_all(bytes).unwrap(); } } -impl<'a, S> Decode<'a, '_, S> for &'a [u8] { - fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { +impl<'a, S> Decode<'a, '_, S> for &'a str { + fn decode(r: &mut &'a [u8], s: &mut S) -> Self { let len = usize::decode(r, s); let xs = &r[..len]; *r = &r[len..]; - xs - } -} - -impl Encode for &str { - fn encode(self, w: &mut Writer, s: &mut S) { - self.as_bytes().encode(w, s); - } -} - -impl<'a, S> Decode<'a, '_, S> for &'a str { - fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { - str::from_utf8(<&[u8]>::decode(r, s)).unwrap() + str::from_utf8(xs).unwrap() } } impl Encode for String { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self[..].encode(w, s); } } impl Decode<'_, '_, S> for String { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { <&str>::decode(r, s).to_string() } } impl> Encode for Vec { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.len().encode(w, s); for x in self { x.encode(w, s); @@ -224,7 +201,7 @@ impl> Encode for Vec { } impl<'a, S, T: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> for Vec { - fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { + fn decode(r: &mut &'a [u8], s: &mut S) -> Self { let len = usize::decode(r, s); let mut vec = Vec::with_capacity(len); for _ in 0..len { @@ -278,13 +255,13 @@ impl PanicMessage { } impl Encode for PanicMessage { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.as_str().encode(w, s); } } impl Decode<'_, '_, S> for PanicMessage { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { match Option::::decode(r, s) { Some(s) => PanicMessage::String(s), None => PanicMessage::Unknown, diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index b79de99844533..073ddb554994c 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -5,12 +5,12 @@ use std::marker::PhantomData; use super::*; -pub(super) struct HandleStore { - token_stream: handle::OwnedStore>, - span: handle::InternedStore>, +pub(super) struct HandleStore { + token_stream: handle::OwnedStore>, + span: handle::InternedStore>, } -impl HandleStore { +impl HandleStore { fn new(handle_counters: &'static client::HandleCounters) -> Self { HandleStore { token_stream: handle::OwnedStore::new(&handle_counters.token_stream), @@ -19,52 +19,54 @@ impl HandleStore { } } -impl Encode> for Marked { - fn encode(self, w: &mut Writer, s: &mut HandleStore) { +pub(super) type MarkedTokenStream = Marked<::TokenStream, client::TokenStream>; +pub(super) type MarkedSpan = Marked<::Span, client::Span>; +pub(super) type MarkedSymbol = Marked<::Symbol, client::Symbol>; + +impl Encode> for MarkedTokenStream { + fn encode(self, w: &mut Buffer, s: &mut HandleStore) { s.token_stream.alloc(self).encode(w, s); } } -impl Decode<'_, '_, HandleStore> for Marked { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore) -> Self { +impl Decode<'_, '_, HandleStore> for MarkedTokenStream { + fn decode(r: &mut &[u8], s: &mut HandleStore) -> Self { s.token_stream.take(handle::Handle::decode(r, &mut ())) } } -impl<'s, S: Types> Decode<'_, 's, HandleStore> - for &'s Marked -{ - fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore) -> Self { +impl<'s, S: Server> Decode<'_, 's, HandleStore> for &'s MarkedTokenStream { + fn decode(r: &mut &[u8], s: &'s mut HandleStore) -> Self { &s.token_stream[handle::Handle::decode(r, &mut ())] } } -impl Encode> for Marked { - fn encode(self, w: &mut Writer, s: &mut HandleStore) { +impl Encode> for MarkedSpan { + fn encode(self, w: &mut Buffer, s: &mut HandleStore) { s.span.alloc(self).encode(w, s); } } -impl Decode<'_, '_, HandleStore> for Marked { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore) -> Self { +impl Decode<'_, '_, HandleStore> for MarkedSpan { + fn decode(r: &mut &[u8], s: &mut HandleStore) -> Self { s.span.copy(handle::Handle::decode(r, &mut ())) } } -pub trait Types { - type TokenStream: 'static + Clone; - type Span: 'static + Copy + Eq + Hash; - type Symbol: 'static; +struct Dispatcher { + handle_store: HandleStore, + server: S, } -macro_rules! declare_server_traits { +macro_rules! define_server_dispatcher_impl { ( - Methods { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* - }, - $($name:ident),* $(,)? + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* ) => { - pub trait Server: Types { + pub trait Server { + type TokenStream: 'static + Clone; + type Span: 'static + Copy + Eq + Hash; + type Symbol: 'static; + fn globals(&mut self) -> ExpnGlobals; /// Intern a symbol received from RPC @@ -75,39 +77,28 @@ macro_rules! declare_server_traits { $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?;)* } - } -} -with_api!(Self, self_, declare_server_traits); -struct Dispatcher { - handle_store: HandleStore, - server: S, -} - -macro_rules! define_dispatcher_impl { - ( - Methods { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* - }, - $($name:ident),* $(,)? - ) => { // FIXME(eddyb) `pub` only for `ExecutionStrategy` below. pub trait DispatcherTrait { // HACK(eddyb) these are here to allow `Self::$name` to work below. - $(type $name;)* + type TokenStream; + type Span; + type Symbol; fn dispatch(&mut self, buf: Buffer) -> Buffer; } impl DispatcherTrait for Dispatcher { - $(type $name = Marked;)* + type TokenStream = MarkedTokenStream; + type Span = MarkedSpan; + type Symbol = MarkedSymbol; fn dispatch(&mut self, mut buf: Buffer) -> Buffer { let Dispatcher { handle_store, server } = self; let mut reader = &buf[..]; - match api_tags::Method::decode(&mut reader, &mut ()) { - $(api_tags::Method::$method => { + match ApiTags::decode(&mut reader, &mut ()) { + $(ApiTags::$method => { let mut call_method = || { $(let $arg = <$arg_ty>::decode(&mut reader, handle_store).unmark();)* let r = server.$method($($arg),*); @@ -136,7 +127,7 @@ macro_rules! define_dispatcher_impl { } } } -with_api!(Self, self_, define_dispatcher_impl); +with_api!(Self, define_server_dispatcher_impl); pub trait ExecutionStrategy { fn run_bridge_and_client( @@ -303,7 +294,7 @@ fn run_server< let globals = dispatcher.server.globals(); let mut buf = Buffer::new(); - (> as Mark>::mark(globals), input) + (> as Mark>::mark(globals), input) .encode(&mut buf, &mut dispatcher.handle_store); buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics); @@ -328,13 +319,11 @@ impl client::Client { strategy, handle_counters, server, - >::mark(input), + >::mark(input), run, force_show_panics, ) - .map(|s| { - >>::unmark(s).unwrap_or_default() - }) + .map(|s| >>::unmark(s).unwrap_or_default()) } } @@ -356,15 +345,10 @@ impl client::Client<(crate::TokenStream, crate::TokenStream), crate::TokenStream strategy, handle_counters, server, - ( - >::mark(input), - >::mark(input2), - ), + (>::mark(input), >::mark(input2)), run, force_show_panics, ) - .map(|s| { - >>::unmark(s).unwrap_or_default() - }) + .map(|s| >>::unmark(s).unwrap_or_default()) } } diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index edba142bad721..2a04f7d808bd5 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -94,25 +94,25 @@ impl fmt::Display for Symbol { } impl Encode for Symbol { - fn encode(self, w: &mut Writer, s: &mut S) { + fn encode(self, w: &mut Buffer, s: &mut S) { self.with(|sym| sym.encode(w, s)) } } -impl Decode<'_, '_, server::HandleStore> for Marked { - fn decode(r: &mut Reader<'_>, s: &mut server::HandleStore) -> Self { +impl Decode<'_, '_, server::HandleStore> for server::MarkedSymbol { + fn decode(r: &mut &[u8], s: &mut server::HandleStore) -> Self { Mark::mark(S::intern_symbol(<&str>::decode(r, s))) } } -impl Encode> for Marked { - fn encode(self, w: &mut Writer, s: &mut server::HandleStore) { +impl Encode> for server::MarkedSymbol { + fn encode(self, w: &mut Buffer, s: &mut server::HandleStore) { S::with_symbol_string(&self.unmark(), |sym| sym.encode(w, s)) } } impl Decode<'_, '_, S> for Symbol { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + fn decode(r: &mut &[u8], s: &mut S) -> Self { Symbol::new(<&str>::decode(r, s)) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 8bec157e4e6e6..b213fa7491775 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -309,6 +309,7 @@ #![feature(staged_api)] #![feature(stmt_expr_attributes)] #![feature(strict_provenance_lints)] +#![feature(target_feature_inline_always)] #![feature(thread_local)] #![feature(try_blocks)] #![feature(try_trait_v2)] diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index a1bb0c6e828bd..8135519317a02 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -580,7 +580,8 @@ mod uefi_fs { use crate::path::Path; use crate::ptr::NonNull; use crate::sys::pal::helpers::{self, UefiBox}; - use crate::sys::time::{self, SystemTime}; + use crate::sys::pal::system_time; + use crate::sys::time::SystemTime; pub(crate) struct File { protocol: NonNull, @@ -879,7 +880,7 @@ mod uefi_fs { /// conversion to SystemTime, we use the current time to get the timezone in such cases. pub(crate) fn uefi_to_systemtime(mut time: r_efi::efi::Time) -> Option { time.timezone = if time.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE { - time::system_time_internal::now().timezone + system_time::now().timezone } else { time.timezone }; @@ -888,7 +889,7 @@ mod uefi_fs { /// Convert to UEFI Time with the current timezone. pub(crate) fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time { - let now = time::system_time_internal::now(); + let now = system_time::now(); time.to_uefi_loose(now.timezone, now.daylight) } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index ca9d3fd592bf4..3ca84db0f47fc 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1822,7 +1822,7 @@ impl File { _ => { #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] { - use crate::sys::{time::__timespec64, weak::weak}; + use crate::sys::pal::{time::__timespec64, weak::weak}; // Added in glibc 2.34 weak!( @@ -2258,7 +2258,7 @@ fn set_times_impl(p: &CStr, times: FileTimes, follow_symlinks: bool) -> io::Resu let flags = if follow_symlinks { 0 } else { libc::AT_SYMLINK_NOFOLLOW }; #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] { - use crate::sys::{time::__timespec64, weak::weak}; + use crate::sys::pal::{time::__timespec64, weak::weak}; // Added in glibc 2.34 weak!( diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index c9035938cfdd3..5436c144d3330 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -26,6 +26,7 @@ pub mod stdio; pub mod sync; pub mod thread; pub mod thread_local; +pub mod time; // FIXME(117276): remove this, move feature implementations into individual // submodules. diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index d57a075eb42d5..59f515d31aff9 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -9,10 +9,9 @@ use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Shutdown, SocketAddr}; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd}; use crate::sys::fd::FileDesc; -use crate::sys::time::Instant; use crate::sys::{AsInner, FromInner, IntoInner}; pub use crate::sys::{cvt, cvt_r}; -use crate::time::Duration; +use crate::time::{Duration, Instant}; use crate::{cmp, mem}; #[expect(non_camel_case_types)] diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs index 734ad2540a180..b9851eb6754d6 100644 --- a/library/std/src/sys/pal/hermit/time.rs +++ b/library/std/src/sys/pal/hermit/time.rs @@ -1,35 +1,32 @@ -#![allow(dead_code)] +use hermit_abi::{self, timespec}; -use core::hash::{Hash, Hasher}; - -use super::hermit_abi::{self, CLOCK_MONOTONIC, CLOCK_REALTIME, timespec}; use crate::cmp::Ordering; -use crate::ops::{Add, AddAssign, Sub, SubAssign}; +use crate::hash::{Hash, Hasher}; use crate::time::Duration; const NSEC_PER_SEC: i32 = 1_000_000_000; #[derive(Copy, Clone, Debug)] -struct Timespec { - t: timespec, +pub struct Timespec { + pub t: timespec, } impl Timespec { - const MAX: Timespec = Self::new(i64::MAX, 1_000_000_000 - 1); + pub const MAX: Timespec = Self::new(i64::MAX, 1_000_000_000 - 1); - const MIN: Timespec = Self::new(i64::MIN, 0); + pub const MIN: Timespec = Self::new(i64::MIN, 0); - const fn zero() -> Timespec { + pub const fn zero() -> Timespec { Timespec { t: timespec { tv_sec: 0, tv_nsec: 0 } } } - const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec { + pub const fn new(tv_sec: i64, tv_nsec: i32) -> Timespec { assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC); // SAFETY: The assert above checks tv_nsec is within the valid range Timespec { t: timespec { tv_sec, tv_nsec } } } - fn sub_timespec(&self, other: &Timespec) -> Result { + pub fn sub_timespec(&self, other: &Timespec) -> Result { fn sub_ge_to_unsigned(a: i64, b: i64) -> u64 { debug_assert!(a >= b); a.wrapping_sub(b).cast_unsigned() @@ -57,7 +54,7 @@ impl Timespec { } } - fn checked_add_duration(&self, other: &Duration) -> Option { + pub fn checked_add_duration(&self, other: &Duration) -> Option { let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?; // Nano calculations can't overflow because nanos are <1B which fit @@ -70,7 +67,7 @@ impl Timespec { Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } }) } - fn checked_sub_duration(&self, other: &Duration) -> Option { + pub fn checked_sub_duration(&self, other: &Duration) -> Option { let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?; // Similar to above, nanos can't overflow. @@ -111,132 +108,3 @@ impl Hash for Timespec { self.t.tv_nsec.hash(state); } } - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Instant(Timespec); - -impl Instant { - pub fn now() -> Instant { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { hermit_abi::clock_gettime(CLOCK_MONOTONIC, &raw mut time.t) }; - - Instant(time) - } - - #[stable(feature = "time2", since = "1.8.0")] - pub fn elapsed(&self) -> Duration { - Instant::now() - *self - } - - pub fn duration_since(&self, earlier: Instant) -> Duration { - self.checked_duration_since(earlier).unwrap_or_default() - } - - pub fn checked_duration_since(&self, earlier: Instant) -> Option { - self.checked_sub_instant(&earlier) - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option { - self.0.sub_timespec(&other.0).ok() - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(Instant(self.0.checked_add_duration(other)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(Instant(self.0.checked_sub_duration(other)?)) - } - - pub fn checked_add(&self, duration: Duration) -> Option { - self.0.checked_add_duration(&duration).map(Instant) - } - - pub fn checked_sub(&self, duration: Duration) -> Option { - self.0.checked_sub_duration(&duration).map(Instant) - } -} - -impl Add for Instant { - type Output = Instant; - - /// # Panics - /// - /// This function may panic if the resulting point in time cannot be represented by the - /// underlying data structure. See [`Instant::checked_add`] for a version without panic. - fn add(self, other: Duration) -> Instant { - self.checked_add(other).expect("overflow when adding duration to instant") - } -} - -impl AddAssign for Instant { - fn add_assign(&mut self, other: Duration) { - *self = *self + other; - } -} - -impl Sub for Instant { - type Output = Instant; - - fn sub(self, other: Duration) -> Instant { - self.checked_sub(other).expect("overflow when subtracting duration from instant") - } -} - -impl SubAssign for Instant { - fn sub_assign(&mut self, other: Duration) { - *self = *self - other; - } -} - -impl Sub for Instant { - type Output = Duration; - - /// Returns the amount of time elapsed from another instant to this one, - /// or zero duration if that instant is later than this one. - /// - /// # Panics - /// - /// Previous Rust versions panicked when `other` was later than `self`. Currently this - /// method saturates. Future versions may reintroduce the panic in some circumstances. - /// See [Monotonicity]. - /// - /// [Monotonicity]: Instant#monotonicity - fn sub(self, other: Instant) -> Duration { - self.duration_since(other) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct SystemTime(Timespec); - -pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero()); - -impl SystemTime { - pub const MAX: SystemTime = SystemTime(Timespec::MAX); - - pub const MIN: SystemTime = SystemTime(Timespec::MIN); - - pub fn new(tv_sec: i64, tv_nsec: i32) -> SystemTime { - SystemTime(Timespec::new(tv_sec, tv_nsec)) - } - - pub fn now() -> SystemTime { - let mut time: Timespec = Timespec::zero(); - let _ = unsafe { hermit_abi::clock_gettime(CLOCK_REALTIME, &raw mut time.t) }; - - SystemTime(time) - } - - pub fn sub_time(&self, other: &SystemTime) -> Result { - self.0.sub_timespec(&other.0) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - Some(SystemTime(self.0.checked_add_duration(other)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - Some(SystemTime(self.0.checked_sub_duration(other)?)) - } -} diff --git a/library/std/src/sys/pal/itron/time.rs b/library/std/src/sys/pal/itron/time.rs index 7976c27f4952b..ff3cffd2069e9 100644 --- a/library/std/src/sys/pal/itron/time.rs +++ b/library/std/src/sys/pal/itron/time.rs @@ -3,38 +3,16 @@ use super::error::expect_success; use crate::mem::MaybeUninit; use crate::time::Duration; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Instant(abi::SYSTIM); - -impl Instant { - pub fn now() -> Instant { - // Safety: The provided pointer is valid - unsafe { - let mut out = MaybeUninit::uninit(); - expect_success(abi::get_tim(out.as_mut_ptr()), &"get_tim"); - Instant(out.assume_init()) - } - } - - pub fn checked_sub_instant(&self, other: &Instant) -> Option { - self.0.checked_sub(other.0).map(|ticks| { - // `SYSTIM` is measured in microseconds - Duration::from_micros(ticks) - }) - } - - pub fn checked_add_duration(&self, other: &Duration) -> Option { - // `SYSTIM` is measured in microseconds - let ticks = other.as_micros(); - - Some(Instant(self.0.checked_add(ticks.try_into().ok()?)?)) - } - - pub fn checked_sub_duration(&self, other: &Duration) -> Option { - // `SYSTIM` is measured in microseconds - let ticks = other.as_micros(); +#[cfg(test)] +mod tests; - Some(Instant(self.0.checked_sub(ticks.try_into().ok()?)?)) +#[inline] +pub fn get_tim() -> abi::SYSTIM { + // Safety: The provided pointer is valid + unsafe { + let mut out = MaybeUninit::uninit(); + expect_success(abi::get_tim(out.as_mut_ptr()), &"get_tim"); + out.assume_init() } } @@ -98,7 +76,7 @@ pub fn with_tmos_strong(dur: Duration, mut f: impl FnMut(abi::TMO) -> abi::ER) - // a problem in practice. (`u64::MAX` μs ≈ 584942 years) let ticks = dur.as_micros().min(abi::SYSTIM::MAX as u128) as abi::SYSTIM; - let start = Instant::now().0; + let start = get_tim(); let mut elapsed = 0; let mut er = abi::E_TMOUT; while elapsed <= ticks { @@ -106,11 +84,8 @@ pub fn with_tmos_strong(dur: Duration, mut f: impl FnMut(abi::TMO) -> abi::ER) - if er != abi::E_TMOUT { break; } - elapsed = Instant::now().0.wrapping_sub(start); + elapsed = get_tim().wrapping_sub(start); } er } - -#[cfg(test)] -mod tests; diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index e5b99cea01d55..a520375a4bbff 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -1,7 +1,6 @@ #![allow(unsafe_op_in_unsafe_fn)] pub mod os; -pub mod time; pub use moto_rt::futex; diff --git a/library/std/src/sys/pal/motor/time.rs b/library/std/src/sys/pal/motor/time.rs deleted file mode 100644 index e917fd466c2e4..0000000000000 --- a/library/std/src/sys/pal/motor/time.rs +++ /dev/null @@ -1 +0,0 @@ -pub use moto_rt::time::{Instant, SystemTime, UNIX_EPOCH}; diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 7f1c81a0ff7bf..1de3ca4a5d79c 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -12,7 +12,6 @@ pub mod abi; mod libunwind_integration; pub mod os; pub mod thread_parking; -pub mod time; pub mod waitqueue; // SAFETY: must be called only once during runtime initialization. diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 4eec12dacd7ca..1376af8304cf6 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -21,7 +21,6 @@ pub mod itron { pub(crate) mod error; pub mod os; pub use self::itron::thread_parking; -pub mod time; // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index d40c10663fd17..f76c26d3c966c 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -7,7 +7,6 @@ #![allow(dead_code)] pub mod os; -#[allow(non_upper_case_globals)] #[path = "../unix/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs index 76a3a75b10c1a..b785c2dbb7892 100644 --- a/library/std/src/sys/pal/trusty/mod.rs +++ b/library/std/src/sys/pal/trusty/mod.rs @@ -5,7 +5,5 @@ mod common; #[path = "../unsupported/os.rs"] pub mod os; -#[path = "../unsupported/time.rs"] -pub mod time; pub use common::*; diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index b181d78c2345a..e4a8f50e4274d 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -15,7 +15,7 @@ pub mod helpers; pub mod os; -pub mod time; +pub mod system_time; #[cfg(test)] mod tests; diff --git a/library/std/src/sys/pal/uefi/system_time.rs b/library/std/src/sys/pal/uefi/system_time.rs new file mode 100644 index 0000000000000..557a49b27c2d1 --- /dev/null +++ b/library/std/src/sys/pal/uefi/system_time.rs @@ -0,0 +1,151 @@ +use r_efi::efi::{RuntimeServices, Time}; + +use super::helpers; +use crate::mem::MaybeUninit; +use crate::ptr::NonNull; +use crate::time::Duration; + +const SECS_IN_MINUTE: u64 = 60; +const SECS_IN_HOUR: u64 = SECS_IN_MINUTE * 60; +const SECS_IN_DAY: u64 = SECS_IN_HOUR * 24; +const SYSTEMTIME_TIMEZONE: i64 = -1440 * SECS_IN_MINUTE as i64; + +pub(crate) fn now() -> Time { + let runtime_services: NonNull = + helpers::runtime_services().expect("Runtime services are not available"); + let mut t: MaybeUninit