pub struct Address(/* private fields */);Expand description
Memory address of an AST node in arena.
Implementations§
Source§impl Address
impl Address
Sourcepub unsafe fn from_ptr<T>(p: *const T) -> Self
pub unsafe fn from_ptr<T>(p: *const T) -> Self
Get the memory address of a pointer to an AST node in arena.
This method is an escape hatch only.
Prefer using GetAddress::address or UnstableAddress::unstable_address instead,
because they are more likely to produce a stable Address.
(Yes even unstable_address is more likely to produce a stable Address than this function!)
If the AST node is in a Box, the address is guaranteed to be a unique identifier
for the duration of the arena’s existence.
But if the node is in a Vec, then the Address may not remain accurate if the Vec
is resized or has elements added or removed before this node.
The pointer must point to an AST node in the arena (not on the stack),
or the returned Address will be meaningless.
If called with a reference, the reference must point to an AST node in the arena (not on the stack),
or the returned Address will be meaningless. Be careful not to pass a double-reference to from_ptr,
or the resulting Address will point to the reference itself, instead of the thing being referenced.
impl<'a> Visit<'a> for MyVisitor {
fn visit_identifier_reference(&mut self, ident: &IdentifierReference<'a>) {
// Correct - `address` is address of the `IdentifierReference`
let address = Address::from_ptr(ident);
// WRONG - `address` is address of `&IdentifierReference` reference itself, which is on the stack
let address = Address::from_ptr(&ident);
}
}§SAFETY
Pointer must be non-null.
§Example
Demonstration of the difference between Address::from_ptr and GetAddress::address:
use oxc_allocator::{Address, GetAddress, Vec};
use oxc_span::SPAN;
// Create a `Vec<Statement>` containing a single `BlockStatement`
let mut stmts = Vec::with_capacity_in(1, &allocator);
stmts.push(ast_builder.statement_block(SPAN, Vec::new_in(&allocator)));
let block_address = stmts[0].address();
let stmt_address = Address::from_ptr(&stmts[0]);
// Add another `Statement` to the `Vec`.
// This causes the `Vec` to grow and reallocate.
stmts.push(ast_builder.statement_empty(SPAN));
let block_address_after_push = stmts[0].address();
let stmt_address_after_push = Address::from_ptr(&stmts[0]);
// Address of the `BlockStatement` is unchanged
// (because the `Box`'s pointer still points to same memory location)
assert!(block_address_after_push == block_address);
// Address of the `Statement` has changed
// (because the `Vec` reallocated, so its contents have moved in memory)
assert!(stmt_address_after_push != stmt_address);
// Insert a new `Statement` at start of the `Vec`.
// The `BlockStatement` is now at index 1.
stmts.insert(0, ast_builder.statement_empty(SPAN));
let block_address_after_insert = stmts[1].address();
let stmt_address_after_insert = Address::from_ptr(&stmts[1]);
// Address of the `BlockStatement` is still unchanged
assert!(block_address_after_insert == block_address_after_push);
// Address of the `Statement` has changed again
assert!(stmt_address_after_insert != stmt_address_after_push);Trait Implementations§
Source§impl GetAddress for Address
impl GetAddress for Address
impl Copy for Address
impl Eq for Address
impl StructuralPartialEq for Address
Auto Trait Implementations§
impl Freeze for Address
impl RefUnwindSafe for Address
impl Send for Address
impl Sync for Address
impl Unpin for Address
impl UnwindSafe for Address
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)