mrustc does not implement the ptr_mask intrinsic which was added in newer Rust versions. Replace all .mask() calls with equivalent pointer arithmetic using casts to usize and back. This affects the sync primitives in: - library/std/src/sys/sync/once/queue.rs - library/std/src/sys/sync/rwlock/queue.rs The replacement ((ptr as usize) & mask) as *T is equivalent to ptr.mask(mask) but uses only basic operations. --- library/std/src/sys/sync/once/queue.rs | 4 ++-- library/std/src/sys/sync/rwlock/queue.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs --- a/library/std/src/sys/sync/once/queue.rs +++ b/library/std/src/sys/sync/once/queue.rs @@ -108,7 +108,7 @@ } fn to_queue(current: StateAndQueue) -> *const Waiter { - current.mask(QUEUE_MASK).cast() + ((current as usize) & QUEUE_MASK) as *const Waiter } fn to_state(current: StateAndQueue) -> usize { @@ -195,7 +195,7 @@ // Try to register this thread as the one RUNNING. if let Err(new) = self.state_and_queue.compare_exchange_weak( current, - current.mask(QUEUE_MASK).wrapping_byte_add(RUNNING), + (((current as usize) & QUEUE_MASK) as StateAndQueue).wrapping_byte_add(RUNNING), Acquire, Acquire, ) { diff --git a/library/std/src/sys/sync/rwlock/queue.rs b/library/std/src/sys/sync/rwlock/queue.rs --- a/library/std/src/sys/sync/rwlock/queue.rs +++ b/library/std/src/sys/sync/rwlock/queue.rs @@ -164,7 +164,7 @@ /// The state must contain a valid pointer to a queue node. #[inline] unsafe fn to_node(state: State) -> NonNull { - unsafe { NonNull::new_unchecked(state.mask(NODE_MASK)).cast() } + unsafe { NonNull::new_unchecked(((state as usize) & NODE_MASK) as *mut ()).cast() } } /// The representation of a thread waiting on the lock queue. @@ -390,7 +390,7 @@ // first node in the queue. // If the state is read-locked, this will set `next` to the lock count. // If it is write-locked, it will set `next` to zero. - node.next.0 = AtomicPtr::new(state.mask(NODE_MASK).cast()); + node.next.0 = AtomicPtr::new(((state as usize) & NODE_MASK) as *mut Node); node.prev = AtomicLink::new(None); // Set the `QUEUED` bit and preserve the `LOCKED` and `DOWNGRADED` bit. @@ -463,7 +463,7 @@ // not been completed yet, so we still have exclusive access. // Retract the downgrade request and unlock, but leave waking up new threads to the // thread that already holds the queue lock. - Some(state.mask(!(DOWNGRADED | LOCKED))) + Some(((state as usize) & !(DOWNGRADED | LOCKED)) as State) } else { None } @@ -532,7 +532,7 @@ // First check if the queue lock is already held. if current.addr() & QUEUE_LOCKED != 0 { // Another thread holds the queue lock, so let them wake up waiters for us. - let next = current.mask(!LOCKED); + let next = ((current as usize) & !LOCKED) as State; match self.state.compare_exchange_weak(current, next, Release, Relaxed) { Ok(_) => return, Err(new) => { @@ -648,7 +648,7 @@ // Leave waking up waiters to them by releasing the queue lock. match self.state.compare_exchange_weak( state, - state.mask(!QUEUE_LOCKED), + ((state as usize) & !QUEUE_LOCKED) as State, Release, Acquire, ) { @@ -684,7 +684,7 @@ // Try to release the queue lock. We need to check the state again since another // thread might have acquired the lock and requested a downgrade. - let next = state.mask(!QUEUE_LOCKED); + let next = ((state as usize) & !QUEUE_LOCKED) as State; if let Err(new) = self.state.compare_exchange_weak(state, next, Release, Acquire) { // Undo the tail modification above, so that we can find the tail again above. // As mentioned above, we have exclusive control over the queue, so no other