Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1e772f9
check for empty heads after adding parent
lcnr Oct 2, 2025
36283bc
fix `RebaseReason::Ambiguity`
lcnr Oct 2, 2025
1e6b444
library: fs: Factor out a `file_time_to_timespec` function in prepara…
joshtriplett Oct 7, 2025
1bf555c
library: fs: Factor out the Apple file time to attrlist code for reuse
joshtriplett Oct 7, 2025
0355358
run zero-size assertion in `const {}`
cyrgani Oct 8, 2025
e3d2016
inline constants in generated `enum` `Encode` impls
cyrgani Oct 8, 2025
7225454
Implement fs api set_times and set_times_nofollow
chenyukang Oct 8, 2025
3d40fa6
Update library/std/src/fs.rs
chenyukang Oct 9, 2025
6308e76
Update library/std/src/fs.rs
chenyukang Oct 9, 2025
1c5c8ca
use proper unsupported
chenyukang Oct 9, 2025
46c6f0a
rebase #147504
chenyukang Oct 9, 2025
2438df7
support fs::set_times for wasi
chenyukang Oct 9, 2025
1dd5641
add doc alias for set_times_nofollow
chenyukang Oct 9, 2025
6fd1c2b
add doc alias for set_times
chenyukang Oct 9, 2025
901366a
fix c_char error in Android
chenyukang Oct 9, 2025
f8118d8
unsupported: Use `unsupported()` for `set_times`
joshtriplett Oct 9, 2025
d2f590a
unsupported: Use `unsupported()` for `set_times_nofollow`
joshtriplett Oct 9, 2025
6a12470
rename `DecodeMut` to `Decode`
cyrgani Oct 10, 2025
04da682
vexos: implement `pal::os::exit`
tropicaaal Oct 11, 2025
4261352
Rollup merge of #147266 - lcnr:fix-search_graph, r=BoxyUwU
chenyukang Oct 14, 2025
35e64c4
Rollup merge of #147468 - chenyukang:yukang-api-set-times, r=joshtrip…
chenyukang Oct 14, 2025
8c04cf0
Rollup merge of #147497 - cyrgani:proc-macro-cleanups-3, r=petrochenkov
chenyukang Oct 14, 2025
e950a60
Rollup merge of #147594 - vexide:vexos-exit-impl, r=joboet
chenyukang Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions compiler/rustc_next_trait_solver/src/solve/search_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,23 @@ where
response_no_constraints(cx, input, Certainty::overflow(false))
}

fn is_ambiguous_result(result: QueryResult<I>) -> bool {
result.is_ok_and(|response| {
has_no_inference_or_external_constraints(response)
fn is_ambiguous_result(result: QueryResult<I>) -> Option<Certainty> {
result.ok().and_then(|response| {
if has_no_inference_or_external_constraints(response)
&& matches!(response.value.certainty, Certainty::Maybe { .. })
{
Some(response.value.certainty)
} else {
None
}
})
}

fn propagate_ambiguity(
cx: I,
for_input: CanonicalInput<I>,
from_result: QueryResult<I>,
certainty: Certainty,
) -> QueryResult<I> {
let certainty = from_result.unwrap().value.certainty;
response_no_constraints(cx, for_input, certainty)
}

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::inherent::*;
use crate::ir_print::IrPrint;
use crate::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
use crate::relate::Relate;
use crate::solve::{CanonicalInput, ExternalConstraintsData, QueryResult, inspect};
use crate::solve::{CanonicalInput, Certainty, ExternalConstraintsData, QueryResult, inspect};
use crate::visit::{Flags, TypeVisitable};
use crate::{self as ty, CanonicalParamEnvCacheEntry, search_graph};

Expand Down Expand Up @@ -550,6 +550,7 @@ impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
impl<I: Interner> search_graph::Cx for I {
type Input = CanonicalInput<I>;
type Result = QueryResult<I>;
type AmbiguityInfo = Certainty;

type DepNodeIndex = I::DepNodeIndex;
type Tracked<T: Debug + Clone> = I::Tracked<T>;
Expand Down
34 changes: 21 additions & 13 deletions compiler/rustc_type_ir/src/search_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub use global_cache::GlobalCache;
pub trait Cx: Copy {
type Input: Debug + Eq + Hash + Copy;
type Result: Debug + Eq + Hash + Copy;
type AmbiguityInfo: Debug + Eq + Hash + Copy;

type DepNodeIndex;
type Tracked<T: Debug + Clone>: Debug;
Expand Down Expand Up @@ -96,11 +97,13 @@ pub trait Delegate: Sized {
input: <Self::Cx as Cx>::Input,
) -> <Self::Cx as Cx>::Result;

fn is_ambiguous_result(result: <Self::Cx as Cx>::Result) -> bool;
fn is_ambiguous_result(
result: <Self::Cx as Cx>::Result,
) -> Option<<Self::Cx as Cx>::AmbiguityInfo>;
fn propagate_ambiguity(
cx: Self::Cx,
for_input: <Self::Cx as Cx>::Input,
from_result: <Self::Cx as Cx>::Result,
ambiguity_info: <Self::Cx as Cx>::AmbiguityInfo,
) -> <Self::Cx as Cx>::Result;

fn compute_goal(
Expand Down Expand Up @@ -913,9 +916,9 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D> {
/// heads from the stack. This may not necessarily mean that we've actually
/// reached a fixpoint for that cycle head, which impacts the way we rebase
/// provisional cache entries.
enum RebaseReason {
enum RebaseReason<X: Cx> {
NoCycleUsages,
Ambiguity,
Ambiguity(X::AmbiguityInfo),
Overflow,
/// We've actually reached a fixpoint.
///
Expand Down Expand Up @@ -951,7 +954,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
&mut self,
cx: X,
stack_entry: &StackEntry<X>,
rebase_reason: RebaseReason,
rebase_reason: RebaseReason<X>,
) {
let popped_head_index = self.stack.next_index();
#[allow(rustc::potential_query_instability)]
Expand All @@ -969,10 +972,6 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
return true;
};

let Some(new_highest_head_index) = heads.opt_highest_cycle_head_index() else {
return false;
};

// We're rebasing an entry `e` over a head `p`. This head
// has a number of own heads `h` it depends on.
//
Expand Down Expand Up @@ -1033,8 +1032,8 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
// is not actually equal to the final provisional result. We
// need to discard the provisional cache entry in this case.
RebaseReason::NoCycleUsages => return false,
RebaseReason::Ambiguity => {
*result = D::propagate_ambiguity(cx, input, *result);
RebaseReason::Ambiguity(info) => {
*result = D::propagate_ambiguity(cx, input, info);
}
RebaseReason::Overflow => *result = D::fixpoint_overflow_result(cx, input),
RebaseReason::ReachedFixpoint(None) => {}
Expand All @@ -1046,6 +1045,10 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
};
}

let Some(new_highest_head_index) = heads.opt_highest_cycle_head_index() else {
return false;
};

// We now care about the path from the next highest cycle head to the
// provisional cache entry.
*path_from_head = path_from_head.extend(Self::cycle_path_kind(
Expand Down Expand Up @@ -1268,6 +1271,7 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
}

/// Whether we've reached a fixpoint when evaluating a cycle head.
#[instrument(level = "trace", skip(self, stack_entry), ret)]
fn reached_fixpoint(
&mut self,
stack_entry: &StackEntry<X>,
Expand Down Expand Up @@ -1355,8 +1359,12 @@ impl<D: Delegate<Cx = X>, X: Cx> SearchGraph<D, X> {
// As we only get to this branch if we haven't yet reached a fixpoint,
// we also taint all provisional cache entries which depend on the
// current goal.
if D::is_ambiguous_result(result) {
self.rebase_provisional_cache_entries(cx, &stack_entry, RebaseReason::Ambiguity);
if let Some(info) = D::is_ambiguous_result(result) {
self.rebase_provisional_cache_entries(
cx,
&stack_entry,
RebaseReason::Ambiguity(info),
);
return EvaluationResult::finalize(stack_entry, encountered_overflow, result);
};

Expand Down
6 changes: 3 additions & 3 deletions library/proc_macro/src/bridge/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ macro_rules! define_client_handles {
}
}

impl<S> DecodeMut<'_, '_, S> for $oty {
impl<S> Decode<'_, '_, S> for $oty {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
$oty {
handle: handle::Handle::decode(r, s),
Expand All @@ -82,7 +82,7 @@ macro_rules! define_client_handles {
}
}

impl<S> DecodeMut<'_, '_, S> for $ity {
impl<S> Decode<'_, '_, S> for $ity {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
$ity {
handle: handle::Handle::decode(r, s),
Expand Down Expand Up @@ -276,7 +276,7 @@ fn maybe_install_panic_hook(force_show_panics: bool) {
/// Client-side helper for handling client panics, entering the bridge,
/// deserializing input and serializing output.
// FIXME(eddyb) maybe replace `Bridge::enter` with this?
fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
fn run_client<A: for<'a, 's> Decode<'a, 's, ()>, R: Encode<()>>(
config: BridgeConfig<'_>,
f: impl FnOnce(A) -> R,
) -> Buffer {
Expand Down
4 changes: 2 additions & 2 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ mod symbol;

use buffer::Buffer;
pub use rpc::PanicMessage;
use rpc::{DecodeMut, Encode, Reader, Writer};
use rpc::{Decode, Encode, Reader, Writer};

/// Configuration for establishing an active connection between a server and a
/// client. The server creates the bridge config (`run_server` in `server.rs`),
Expand All @@ -168,7 +168,7 @@ impl !Sync for BridgeConfig<'_> {}
#[forbid(unsafe_code)]
#[allow(non_camel_case_types)]
mod api_tags {
use super::rpc::{DecodeMut, Encode, Reader, Writer};
use super::rpc::{Decode, Encode, Reader, Writer};

macro_rules! declare_tags {
($($name:ident {
Expand Down
45 changes: 20 additions & 25 deletions library/proc_macro/src/bridge/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(super) trait Encode<S>: Sized {

pub(super) type Reader<'a> = &'a [u8];

pub(super) trait DecodeMut<'a, 's, S>: Sized {
pub(super) trait Decode<'a, 's, S>: Sized {
fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
}

Expand All @@ -24,7 +24,7 @@ macro_rules! rpc_encode_decode {
}
}

impl<S> DecodeMut<'_, '_, S> for $ty {
impl<S> Decode<'_, '_, S> for $ty {
fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
const N: usize = size_of::<$ty>();

Expand All @@ -43,12 +43,12 @@ macro_rules! rpc_encode_decode {
}
}

impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
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 {
$name {
$($field: DecodeMut::decode(r, s)),*
$($field: Decode::decode(r, s)),*
}
}
}
Expand All @@ -58,23 +58,18 @@ macro_rules! rpc_encode_decode {
fn encode(self, w: &mut Writer, s: &mut S) {
// HACK(eddyb): `Tag` enum duplicated between the
// two impls as there's no other place to stash it.
#[allow(non_upper_case_globals)]
mod tag {
#[repr(u8)] enum Tag { $($variant),* }

$(pub(crate) const $variant: u8 = Tag::$variant as u8;)*
}
#[repr(u8)] enum Tag { $($variant),* }

match self {
$($name::$variant $(($field))* => {
tag::$variant.encode(w, s);
(Tag::$variant as u8).encode(w, s);
$($field.encode(w, s);)*
})*
}
}
}

impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
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 {
Expand All @@ -89,7 +84,7 @@ macro_rules! rpc_encode_decode {

match u8::decode(r, s) {
$(tag::$variant => {
$(let $field = DecodeMut::decode(r, s);)*
$(let $field = Decode::decode(r, s);)*
$name::$variant $(($field))*
})*
_ => unreachable!(),
Expand All @@ -103,7 +98,7 @@ impl<S> Encode<S> for () {
fn encode(self, _: &mut Writer, _: &mut S) {}
}

impl<S> DecodeMut<'_, '_, S> for () {
impl<S> Decode<'_, '_, S> for () {
fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
}

Expand All @@ -113,7 +108,7 @@ impl<S> Encode<S> for u8 {
}
}

impl<S> DecodeMut<'_, '_, S> for u8 {
impl<S> Decode<'_, '_, S> for u8 {
fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
let x = r[0];
*r = &r[1..];
Expand All @@ -130,7 +125,7 @@ impl<S> Encode<S> for bool {
}
}

impl<S> DecodeMut<'_, '_, S> for bool {
impl<S> Decode<'_, '_, S> for bool {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
match u8::decode(r, s) {
0 => false,
Expand All @@ -146,7 +141,7 @@ impl<S> Encode<S> for char {
}
}

impl<S> DecodeMut<'_, '_, S> for char {
impl<S> Decode<'_, '_, S> for char {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
char::from_u32(u32::decode(r, s)).unwrap()
}
Expand All @@ -158,7 +153,7 @@ impl<S> Encode<S> for NonZero<u32> {
}
}

impl<S> DecodeMut<'_, '_, S> for NonZero<u32> {
impl<S> Decode<'_, '_, S> for NonZero<u32> {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
Self::new(u32::decode(r, s)).unwrap()
}
Expand All @@ -171,11 +166,11 @@ impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
}
}

impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
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 {
(DecodeMut::decode(r, s), DecodeMut::decode(r, s))
(Decode::decode(r, s), Decode::decode(r, s))
}
}

Expand All @@ -186,7 +181,7 @@ impl<S> Encode<S> for &[u8] {
}
}

impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
impl<'a, S> Decode<'a, '_, S> for &'a [u8] {
fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
let len = usize::decode(r, s);
let xs = &r[..len];
Expand All @@ -201,7 +196,7 @@ impl<S> Encode<S> for &str {
}
}

impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
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()
}
Expand All @@ -213,7 +208,7 @@ impl<S> Encode<S> for String {
}
}

impl<S> DecodeMut<'_, '_, S> for String {
impl<S> Decode<'_, '_, S> for String {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
<&str>::decode(r, s).to_string()
}
Expand All @@ -228,7 +223,7 @@ impl<S, T: Encode<S>> Encode<S> for Vec<T> {
}
}

impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
impl<'a, S, T: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> for Vec<T> {
fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
let len = usize::decode(r, s);
let mut vec = Vec::with_capacity(len);
Expand Down Expand Up @@ -288,7 +283,7 @@ impl<S> Encode<S> for PanicMessage {
}
}

impl<S> DecodeMut<'_, '_, S> for PanicMessage {
impl<S> Decode<'_, '_, S> for PanicMessage {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
match Option::<String>::decode(r, s) {
Some(s) => PanicMessage::String(s),
Expand Down
2 changes: 1 addition & 1 deletion library/proc_macro/src/bridge/selfless_reify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ macro_rules! define_reify_functions {
>(f: F) -> $(extern $abi)? fn($($arg_ty),*) -> $ret_ty {
// FIXME(eddyb) describe the `F` type (e.g. via `type_name::<F>`) once panic
// formatting becomes possible in `const fn`.
assert!(size_of::<F>() == 0, "selfless_reify: closure must be zero-sized");
const { assert!(size_of::<F>() == 0, "selfless_reify: closure must be zero-sized"); }

$(extern $abi)? fn wrapper<
$($($param,)*)?
Expand Down
Loading
Loading