Skip to content

Add safe methods to handles/rootedguard and simplify NoGC#700

Merged
sagudev merged 7 commits intoservo:mainfrom
sagudev:more-safe-handles
Jan 17, 2026
Merged

Add safe methods to handles/rootedguard and simplify NoGC#700
sagudev merged 7 commits intoservo:mainfrom
sagudev:more-safe-handles

Conversation

@sagudev
Copy link
Copy Markdown
Member

@sagudev sagudev commented Jan 16, 2026

Firstly we simplify NoGC to be proper ZST without any inner lifetime. One should now use no_gc: &NoGC (this gives us compiler reborrow support, instead of manual reborrows we need to do for handles). This allows us to impl deref from &JSContext so &JSContext and &NoGC can be used interchangeably.

Then we add as_ref and as_mut_ref as the safe way (as they require &NoGC, aliasing rules are uphold by &/&mut of handles/root) of obtaining reference to rooted value. This should eventually replace unsound derefs and unsafe as_mut, but until then documentation notice will suffice.

Testing: compile doc tests
Servo PR: servo/servo#41971

This is not reviewable per commit.

@sagudev

This comment was marked as resolved.

Copy link
Copy Markdown
Member

@jdm jdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! Thanks for the doctests, too.

Signed-off-by: sagudev <[email protected]>
Signed-off-by: sagudev <[email protected]>
f
Signed-off-by: sagudev <[email protected]>
f
Signed-off-by: sagudev <[email protected]>
@sagudev sagudev added this pull request to the merge queue Jan 17, 2026
Merged via the queue into servo:main with commit e2361d9 Jan 17, 2026
36 checks passed
github-merge-queue bot pushed a commit to servo/servo that referenced this pull request Jan 18, 2026
…s artifacts (#41971)

This bump includes
some new safe wrappers: servo/mozjs#699
servo/mozjs#700
debugmozjs artifacts: servo/mozjs#544
rooted macros with vectors: servo/mozjs#697

Testing: Done in mozjs repo.

Signed-off-by: sagudev <[email protected]>
@sagudev
Copy link
Copy Markdown
Member Author

sagudev commented Jan 19, 2026

For servo dom objects, I think it is safe for & to be alive across GC (because they are alloc by Box and thus unmovable by SM). Some does not hold for &mut, because tracing will visit it, thus breaking aliasing rules.

/// It's ok to return ref to dom object as they are allocated via Box, thus
/// unmoovable by GC.
pub trait ServoRef {
    type Inner;
    fn as_servo_ref(&self) -> &Self::Inner;
}

impl<T: DomObject> ServoRef for Handle<'_, T> {
    type Inner = T;
    fn as_servo_ref(&self) -> &T {
        self.deref()
    }
}

impl<T: DomObject> ServoRef for MutableHandle<'_, T> {
    type Inner = T;
    fn as_servo_ref(&self) -> &T {
        self.deref()
    }
}

Huh, that's effectively what Dom(Root) is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants