aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock3
-rw-r--r--components/dom_struct/lib.rs2
-rw-r--r--components/script/canvas_state.rs6
-rw-r--r--components/script/document_loader.rs2
-rw-r--r--components/script/dom/bindings/callback.rs6
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py5
-rw-r--r--components/script/dom/bindings/refcounted.rs2
-rw-r--r--components/script/dom/bindings/reflector.rs2
-rw-r--r--components/script/dom/bindings/root.rs12
-rw-r--r--components/script/dom/bindings/trace.rs6
-rw-r--r--components/script/dom/bindings/weakref.rs8
-rw-r--r--components/script/dom/blob.rs2
-rw-r--r--components/script/dom/cssstyledeclaration.rs2
-rw-r--r--components/script/dom/customelementregistry.rs6
-rw-r--r--components/script/dom/document.rs4
-rw-r--r--components/script/dom/documentorshadowroot.rs4
-rw-r--r--components/script/dom/htmlcanvaselement.rs2
-rw-r--r--components/script/dom/htmlimageelement.rs2
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs2
-rw-r--r--components/script/dom/htmlmediaelement.rs2
-rw-r--r--components/script/dom/messageevent.rs2
-rw-r--r--components/script/dom/nodelist.rs4
-rw-r--r--components/script/dom/offscreencanvas.rs2
-rw-r--r--components/script/dom/paintworkletglobalscope.rs2
-rw-r--r--components/script/dom/promise.rs2
-rw-r--r--components/script/dom/range.rs2
-rw-r--r--components/script/dom/raredata.rs4
-rw-r--r--components/script/dom/servoparser/async_html.rs2
-rw-r--r--components/script/dom/servoparser/html.rs2
-rw-r--r--components/script/dom/servoparser/mod.rs4
-rw-r--r--components/script/dom/servoparser/prefetch.rs2
-rw-r--r--components/script/dom/servoparser/xml.rs2
-rw-r--r--components/script/dom/stylesheetlist.rs2
-rw-r--r--components/script/dom/trackevent.rs2
-rw-r--r--components/script/dom/webgl_extensions/extensions.rs2
-rw-r--r--components/script/dom/webgl_extensions/wrapper.rs2
-rw-r--r--components/script/dom/webglframebuffer.rs2
-rw-r--r--components/script/dom/webglrenderingcontext.rs4
-rw-r--r--components/script/dom/webglvertexarrayobjectoes.rs2
-rw-r--r--components/script/dom/worklet.rs2
-rw-r--r--components/script/lib.rs2
-rw-r--r--components/script/script_thread.rs2
-rw-r--r--components/script/serviceworkerjob.rs4
-rw-r--r--components/script_plugins/Cargo.toml3
-rw-r--r--components/script_plugins/lib.rs73
-rw-r--r--rust-toolchain2
-rw-r--r--tests/unit/script_plugins/lib.rs22
47 files changed, 130 insertions, 106 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 259316181fd..7a148e771b7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4228,6 +4228,9 @@ dependencies = [
[[package]]
name = "script_plugins"
version = "0.0.1"
+dependencies = [
+ "matches",
+]
[[package]]
name = "script_plugins_tests"
diff --git a/components/dom_struct/lib.rs b/components/dom_struct/lib.rs
index e7b2b290ce5..ff95e7d838a 100644
--- a/components/dom_struct/lib.rs
+++ b/components/dom_struct/lib.rs
@@ -17,7 +17,7 @@ pub fn dom_struct(args: TokenStream, input: TokenStream) -> TokenStream {
}
let attributes = quote! {
#[derive(DenyPublicFields, DomObject, JSTraceable, MallocSizeOf)]
- #[must_root]
+ #[unrooted_must_root_lint::must_root]
#[repr(C)]
};
diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs
index 4b47308fa46..76fd9d12caf 100644
--- a/components/script/canvas_state.rs
+++ b/components/script/canvas_state.rs
@@ -53,7 +53,7 @@ use std::fmt;
use std::str::FromStr;
use std::sync::Arc;
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(Clone, JSTraceable, MallocSizeOf)]
#[allow(dead_code)]
pub(crate) enum CanvasFillOrStrokeStyle {
@@ -62,7 +62,7 @@ pub(crate) enum CanvasFillOrStrokeStyle {
Pattern(Dom<CanvasPattern>),
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(Clone, JSTraceable, MallocSizeOf)]
pub(crate) struct CanvasContextState {
global_alpha: f64,
@@ -103,7 +103,7 @@ impl CanvasContextState {
}
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
pub(crate) struct CanvasState {
#[ignore_malloc_size_of = "Defined in ipc-channel"]
diff --git a/components/script/document_loader.rs b/components/script/document_loader.rs
index ef60cbc2a6c..9e103b91380 100644
--- a/components/script/document_loader.rs
+++ b/components/script/document_loader.rs
@@ -29,7 +29,7 @@ pub enum LoadType {
/// created via DocumentLoader::fetch_async) are always removed by the time
/// that the owner is destroyed.
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct LoadBlocker {
/// The document whose load event is blocked by this object existing.
doc: Dom<Document>,
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs
index 6059d75605a..fe6b8d36d39 100644
--- a/components/script/dom/bindings/callback.rs
+++ b/components/script/dom/bindings/callback.rs
@@ -40,7 +40,7 @@ pub enum ExceptionHandling {
/// A common base class for representing IDL callback function and
/// callback interface types.
#[derive(JSTraceable)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct CallbackObject {
/// The underlying `JSObject`.
callback: Heap<*mut JSObject>,
@@ -131,7 +131,7 @@ pub trait CallbackContainer {
/// A common base class for representing IDL callback function types.
#[derive(JSTraceable, PartialEq)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct CallbackFunction {
object: CallbackObject,
}
@@ -159,7 +159,7 @@ impl CallbackFunction {
/// A common base class for representing IDL callback interface types.
#[derive(JSTraceable, PartialEq)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct CallbackInterface {
object: CallbackObject,
}
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index e660471364e..0a1df6553fa 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -6406,7 +6406,7 @@ class CGDictionary(CGThing):
derive = ["JSTraceable"]
mustRoot = ""
if self.membersNeedTracing():
- mustRoot = "#[must_root]\n"
+ mustRoot = "#[unrooted_must_root_lint::must_root]\n"
derive += ["Default"]
return (string.Template(
@@ -6927,7 +6927,8 @@ class CGCallback(CGClass):
bases=[ClassBase(baseName)],
constructors=self.getConstructors(),
methods=realMethods,
- decorators="#[derive(JSTraceable, PartialEq)]\n#[allow_unrooted_interior]")
+ decorators="#[derive(JSTraceable, PartialEq)]\n"
+ "#[unrooted_must_root_lint::allow_unrooted_interior]")
def getConstructors(self):
return [ClassConstructor(
diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs
index 8636f910121..ad5be5bb0cf 100644
--- a/components/script/dom/bindings/refcounted.rs
+++ b/components/script/dom/bindings/refcounted.rs
@@ -151,7 +151,7 @@ impl TrustedPromise {
/// shared among threads for use in asynchronous operations. The underlying
/// DOM object is guaranteed to live at least as long as the last outstanding
/// `Trusted<T>` instance.
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct Trusted<T: DomObject> {
/// A pointer to the Rust DOM object of type T, but void to allow
/// sending `Trusted<T>` between threads, regardless of T's sendability.
diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs
index dc13fca77b0..2b5a4987eb5 100644
--- a/components/script/dom/bindings/reflector.rs
+++ b/components/script/dom/bindings/reflector.rs
@@ -30,7 +30,7 @@ where
/// A struct to store a reference to the reflector of a DOM object.
#[allow(unrooted_must_root)]
#[derive(MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
// If you're renaming or moving this field, update the path in plugins::reflector as well
pub struct Reflector {
#[ignore_malloc_size_of = "defined and measured in rust-mozjs"]
diff --git a/components/script/dom/bindings/root.rs b/components/script/dom/bindings/root.rs
index 6e2c883984c..19df89df53f 100644
--- a/components/script/dom/bindings/root.rs
+++ b/components/script/dom/bindings/root.rs
@@ -46,7 +46,7 @@ use style::thread_state;
/// A rooted value.
#[allow(unrooted_must_root)]
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct Root<T: StableTraceObject> {
/// The value to root.
value: T,
@@ -283,7 +283,7 @@ where
/// on the stack, the `Dom<T>` can point to freed memory.
///
/// This should only be used as a field in other DOM objects.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Dom<T> {
ptr: ptr::NonNull<T>,
}
@@ -343,7 +343,7 @@ unsafe impl<T: DomObject> JSTraceable for Dom<T> {
/// An unrooted reference to a DOM object for use in layout. `Layout*Helpers`
/// traits must be implemented on this.
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct LayoutDom<T> {
ptr: ptr::NonNull<T>,
}
@@ -463,7 +463,7 @@ impl LayoutDom<Node> {
///
/// This should only be used as a field in other DOM objects; see warning
/// on `Dom<T>`.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable)]
pub struct MutDom<T: DomObject> {
val: UnsafeCell<Dom<T>>,
@@ -518,7 +518,7 @@ impl<T: DomObject + PartialEq> PartialEq<T> for MutDom<T> {
///
/// This should only be used as a field in other DOM objects; see warning
/// on `Dom<T>`.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable)]
pub struct MutNullableDom<T: DomObject> {
ptr: UnsafeCell<Option<Dom<T>>>,
@@ -616,7 +616,7 @@ impl<T: DomObject> MallocSizeOf for MutNullableDom<T> {
///
/// This should only be used as a field in other DOM objects; see warning
/// on `Dom<T>`.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct DomOnceCell<T: DomObject> {
ptr: OnceCell<Dom<T>>,
}
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 7869d1499ac..65faac1bb95 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -883,7 +883,7 @@ impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> {
/// If you have GC things like *mut JSObject or JSVal, use rooted!.
/// If you have an arbitrary number of DomObjects to root, use rooted_vec!.
/// If you know what you're doing, use this.
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct RootedTraceableBox<T: 'static + JSTraceable> {
ptr: *mut T,
}
@@ -954,7 +954,7 @@ impl<T: JSTraceable + 'static> Drop for RootedTraceableBox<T> {
/// iterator of `DomRoot`s, `rooted_vec!(let v <- iterator);`.
#[allow(unrooted_must_root)]
#[derive(JSTraceable)]
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct RootableVec<T: JSTraceable> {
v: Vec<T>,
}
@@ -967,7 +967,7 @@ impl<T: JSTraceable> RootableVec<T> {
}
/// A vector of items that are rooted for the lifetime 'a.
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct RootedVec<'a, T: 'static + JSTraceable> {
root: &'a mut RootableVec<T>,
}
diff --git a/components/script/dom/bindings/weakref.rs b/components/script/dom/bindings/weakref.rs
index bea2141d142..5c74e111816 100644
--- a/components/script/dom/bindings/weakref.rs
+++ b/components/script/dom/bindings/weakref.rs
@@ -34,13 +34,13 @@ pub const DOM_WEAK_SLOT: u32 = 1;
/// A weak reference to a JS-managed DOM object.
#[allow(unrooted_must_root)]
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct WeakRef<T: WeakReferenceable> {
ptr: ptr::NonNull<WeakBox<T>>,
}
/// The inner box of weak references, public for the finalization in codegen.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct WeakBox<T: WeakReferenceable> {
/// The reference count. When it reaches zero, the `value` field should
/// have already been set to `None`. The pointee contributes one to the count.
@@ -218,7 +218,7 @@ unsafe impl<T: WeakReferenceable> JSTraceable for MutableWeakRef<T> {
/// A vector of weak references. On tracing, the vector retains
/// only references which still point to live objects.
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
#[derive(MallocSizeOf)]
pub struct WeakRefVec<T: WeakReferenceable> {
vec: Vec<WeakRef<T>>,
@@ -268,7 +268,7 @@ impl<T: WeakReferenceable> DerefMut for WeakRefVec<T> {
/// An entry of a vector of weak references. Passed to the closure
/// given to `WeakRefVec::update`.
-#[allow_unrooted_interior]
+#[unrooted_must_root_lint::allow_unrooted_interior]
pub struct WeakRefEntry<'a, T: WeakReferenceable> {
vec: &'a mut WeakRefVec<T>,
index: &'a mut usize,
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index fbf3e5819be..db90b2d2bda 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -31,7 +31,7 @@ pub struct FileBlob {
}
/// Different backends of Blob
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable)]
pub enum BlobImpl {
/// File-based blob, whose content lives in the net process
diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs
index d623f46005a..2ad565f9b45 100644
--- a/components/script/dom/cssstyledeclaration.rs
+++ b/components/script/dom/cssstyledeclaration.rs
@@ -39,7 +39,7 @@ pub struct CSSStyleDeclaration {
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub enum CSSStyleOwner {
Element(Dom<Element>),
CSSRule(
diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs
index 64117959500..7b4229835e2 100644
--- a/components/script/dom/customelementregistry.rs
+++ b/components/script/dom/customelementregistry.rs
@@ -706,7 +706,7 @@ pub fn try_upgrade_element(element: &Element) {
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub enum CustomElementReaction {
Upgrade(#[ignore_malloc_size_of = "Rc"] Rc<CustomElementDefinition>),
Callback(
@@ -752,7 +752,7 @@ enum BackupElementQueueFlag {
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct CustomElementReactionStack {
stack: DomRefCell<Vec<ElementQueue>>,
backup_queue: ElementQueue,
@@ -934,7 +934,7 @@ impl CustomElementReactionStack {
/// <https://html.spec.whatwg.org/multipage/#element-queue>
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
struct ElementQueue {
queue: DomRefCell<VecDeque<Dom<Element>>>,
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index b2a6468bd90..5a344879005 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -4749,7 +4749,7 @@ impl AnimationFrameCallback {
}
#[derive(Default, JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
struct PendingInOrderScriptVec {
scripts: DomRefCell<VecDeque<PendingScript>>,
}
@@ -4787,7 +4787,7 @@ impl PendingInOrderScriptVec {
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
struct PendingScript {
element: Dom<HTMLScriptElement>,
load: Option<ScriptResult>,
diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs
index 594801584c8..724ea11da8c 100644
--- a/components/script/dom/documentorshadowroot.rs
+++ b/components/script/dom/documentorshadowroot.rs
@@ -28,7 +28,7 @@ use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuar
use style::stylesheets::{CssRule, Origin, Stylesheet};
#[derive(Clone, JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct StyleSheetInDocument {
#[ignore_malloc_size_of = "Arc"]
pub sheet: Arc<Stylesheet>,
@@ -76,7 +76,7 @@ impl ::style::stylesheets::StylesheetInDocument for StyleSheetInDocument {
}
// https://w3c.github.io/webcomponents/spec/shadow/#extensions-to-the-documentorshadowroot-mixin
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
pub struct DocumentOrShadowRoot {
window: Dom<Window>,
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 8924f8ddd1c..89410a6b6b0 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -50,7 +50,7 @@ use style::attr::{AttrValue, LengthOrPercentageOrAuto};
const DEFAULT_WIDTH: u32 = 300;
const DEFAULT_HEIGHT: u32 = 150;
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(Clone, JSTraceable, MallocSizeOf)]
pub enum CanvasContext {
Context2d(Dom<CanvasRenderingContext2D>),
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index 698e21517a8..5b6bd321534 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -133,7 +133,7 @@ enum ImageRequestPhase {
Current,
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
struct ImageRequest {
state: State,
parsed_url: Option<ServoUrl>,
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 60b5cb9bcb1..5fdbad5c1bd 100755
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -237,7 +237,7 @@ pub struct HTMLInputElement {
}
#[derive(JSTraceable)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(MallocSizeOf)]
struct InputActivationState {
indeterminate: bool,
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index 13c5cd126c7..5afc2deb381 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -268,7 +268,7 @@ impl FrameRenderer for MediaFrameRenderer {
}
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
enum SrcObject {
MediaStream(Dom<MediaStream>),
diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs
index 3e9a7079605..9d9e5f88e35 100644
--- a/components/script/dom/messageevent.rs
+++ b/components/script/dom/messageevent.rs
@@ -26,7 +26,7 @@ use js::jsval::JSVal;
use js::rust::HandleValue;
use servo_atoms::Atom;
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
enum SrcObject {
WindowProxy(Dom<WindowProxy>),
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 82fd3be59d6..930fedbbec4 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -13,7 +13,7 @@ use dom_struct::dom_struct;
use std::cell::Cell;
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub enum NodeListType {
Simple(Vec<Dom<Node>>),
Children(ChildrenList),
@@ -119,7 +119,7 @@ impl NodeList {
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct ChildrenList {
node: Dom<Node>,
#[ignore_malloc_size_of = "Defined in rust-mozjs"]
diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs
index 69c1114768c..2186ba54bc8 100644
--- a/components/script/dom/offscreencanvas.rs
+++ b/components/script/dom/offscreencanvas.rs
@@ -23,7 +23,7 @@ use ref_filter_map;
use std::cell::Cell;
use std::cell::Ref;
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(Clone, JSTraceable, MallocSizeOf)]
pub enum OffscreenCanvasContext {
OffscreenContext2d(Dom<OffscreenCanvasRenderingContext2D>),
diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs
index bc04ab63440..ce3f955cc9c 100644
--- a/components/script/dom/paintworkletglobalscope.rs
+++ b/components/script/dom/paintworkletglobalscope.rs
@@ -473,7 +473,7 @@ pub enum PaintWorkletTask {
/// This type is dangerous, because it contains uboxed `Heap<JSVal>` values,
/// which can't be moved.
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
struct PaintDefinition {
#[ignore_malloc_size_of = "mozjs"]
class_constructor: Heap<JSVal>,
diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs
index b101c449348..d2e209b98dd 100644
--- a/components/script/dom/promise.rs
+++ b/components/script/dom/promise.rs
@@ -37,7 +37,7 @@ use std::ptr;
use std::rc::Rc;
#[dom_struct]
-#[allow_unrooted_in_rc]
+#[unrooted_must_root_lint::allow_unrooted_in_rc]
pub struct Promise {
reflector: Reflector,
/// Since Promise values are natively reference counted without the knowledge of
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index 64a26fa0ba9..819cc284d63 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -1011,7 +1011,7 @@ impl RangeMethods for Range {
}
#[derive(DenyPublicFields, JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct BoundaryPoint {
node: MutDom<Node>,
offset: Cell<u32>,
diff --git a/components/script/dom/raredata.rs b/components/script/dom/raredata.rs
index 8c481425982..e32f218ce89 100644
--- a/components/script/dom/raredata.rs
+++ b/components/script/dom/raredata.rs
@@ -15,7 +15,7 @@ use std::rc::Rc;
// storage.
#[derive(Default, JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct NodeRareData {
/// The shadow root the node belongs to.
/// This is None if the node is not in a shadow tree or
@@ -28,7 +28,7 @@ pub struct NodeRareData {
}
#[derive(Default, JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct ElementRareData {
/// https://dom.spec.whatwg.org/#dom-element-shadowroot
/// The ShadowRoot this element is host of.
diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs
index 42296062840..6930f2553c5 100644
--- a/components/script/dom/servoparser/async_html.rs
+++ b/components/script/dom/servoparser/async_html.rs
@@ -196,7 +196,7 @@ fn create_buffer_queue(mut buffers: VecDeque<SendTendril<UTF8>>) -> BufferQueue
// |_____________| |_______________|
//
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Tokenizer {
document: Dom<Document>,
#[ignore_malloc_size_of = "Defined in std"]
diff --git a/components/script/dom/servoparser/html.rs b/components/script/dom/servoparser/html.rs
index c9e3a06f34f..22e2574a9b4 100644
--- a/components/script/dom/servoparser/html.rs
+++ b/components/script/dom/servoparser/html.rs
@@ -30,7 +30,7 @@ use servo_url::ServoUrl;
use std::io;
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Tokenizer {
#[ignore_malloc_size_of = "Defined in html5ever"]
inner: HtmlTokenizer<TreeBuilder<Dom<Node>, Sink>>,
diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs
index 91b5c9bfce6..004daeed9be 100644
--- a/components/script/dom/servoparser/mod.rs
+++ b/components/script/dom/servoparser/mod.rs
@@ -626,7 +626,7 @@ enum ParserKind {
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
enum Tokenizer {
Html(self::html::Tokenizer),
AsyncHtml(self::async_html::Tokenizer),
@@ -945,7 +945,7 @@ fn insert(parent: &Node, reference_child: Option<&Node>, child: NodeOrText<Dom<N
}
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Sink {
base_url: ServoUrl,
document: Dom<Document>,
diff --git a/components/script/dom/servoparser/prefetch.rs b/components/script/dom/servoparser/prefetch.rs
index 906c9352771..d9de4d7036f 100644
--- a/components/script/dom/servoparser/prefetch.rs
+++ b/components/script/dom/servoparser/prefetch.rs
@@ -32,7 +32,7 @@ use servo_url::ImmutableOrigin;
use servo_url::ServoUrl;
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Tokenizer {
#[ignore_malloc_size_of = "Defined in html5ever"]
inner: HtmlTokenizer<PrefetchSink>,
diff --git a/components/script/dom/servoparser/xml.rs b/components/script/dom/servoparser/xml.rs
index 8f30e54174d..ac900d61ce0 100644
--- a/components/script/dom/servoparser/xml.rs
+++ b/components/script/dom/servoparser/xml.rs
@@ -17,7 +17,7 @@ use xml5ever::tokenizer::XmlTokenizer;
use xml5ever::tree_builder::{Tracer as XmlTracer, XmlTreeBuilder};
#[derive(JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Tokenizer {
#[ignore_malloc_size_of = "Defined in xml5ever"]
inner: XmlTokenizer<XmlTreeBuilder<Dom<Node>, Sink>>,
diff --git a/components/script/dom/stylesheetlist.rs b/components/script/dom/stylesheetlist.rs
index 236f1c9cd9a..391ac55ed91 100644
--- a/components/script/dom/stylesheetlist.rs
+++ b/components/script/dom/stylesheetlist.rs
@@ -16,7 +16,7 @@ use dom_struct::dom_struct;
use servo_arc::Arc;
use style::stylesheets::Stylesheet;
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
pub enum StyleSheetListOwner {
Document(Dom<Document>),
diff --git a/components/script/dom/trackevent.rs b/components/script/dom/trackevent.rs
index 684a0fcde52..5a734a0e4c9 100644
--- a/components/script/dom/trackevent.rs
+++ b/components/script/dom/trackevent.rs
@@ -20,7 +20,7 @@ use crate::dom::window::Window;
use dom_struct::dom_struct;
use servo_atoms::Atom;
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
enum MediaTrack {
Video(Dom<VideoTrack>),
diff --git a/components/script/dom/webgl_extensions/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs
index fa502ca26cd..b7a2f2beb80 100644
--- a/components/script/dom/webgl_extensions/extensions.rs
+++ b/components/script/dom/webgl_extensions/extensions.rs
@@ -140,7 +140,7 @@ impl WebGLExtensionFeatures {
}
/// Handles the list of implemented, supported and enabled WebGL extensions.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
pub struct WebGLExtensions {
extensions: DomRefCell<HashMap<String, Box<dyn WebGLExtensionWrapper>>>,
diff --git a/components/script/dom/webgl_extensions/wrapper.rs b/components/script/dom/webgl_extensions/wrapper.rs
index 6af68c4678e..bf8db31418c 100644
--- a/components/script/dom/webgl_extensions/wrapper.rs
+++ b/components/script/dom/webgl_extensions/wrapper.rs
@@ -28,7 +28,7 @@ pub trait WebGLExtensionWrapper: JSTraceable + MallocSizeOf {
fn as_any(&self) -> &dyn Any;
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
pub struct TypedWebGLExtensionWrapper<T: WebGLExtension> {
extension: MutNullableDom<T::Extension>,
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index df9e194962e..def5b36a27f 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -29,7 +29,7 @@ pub enum CompleteForRendering {
MissingColorAttachment,
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(Clone, JSTraceable, MallocSizeOf)]
enum WebGLFramebufferAttachment {
Renderbuffer(Dom<WebGLRenderbuffer>),
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index c843ab578d1..74fd8068a72 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -4275,7 +4275,7 @@ capabilities! {
STENCIL_TEST,
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable, MallocSizeOf)]
pub struct Textures {
active_unit: Cell<u32>,
@@ -4343,7 +4343,7 @@ impl Textures {
}
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(Default, JSTraceable, MallocSizeOf)]
struct TextureUnit {
tex_2d: MutNullableDom<WebGLTexture>,
diff --git a/components/script/dom/webglvertexarrayobjectoes.rs b/components/script/dom/webglvertexarrayobjectoes.rs
index 22d162782d8..e54eaf3f04a 100644
--- a/components/script/dom/webglvertexarrayobjectoes.rs
+++ b/components/script/dom/webglvertexarrayobjectoes.rs
@@ -258,7 +258,7 @@ impl Drop for WebGLVertexArrayObjectOES {
}
#[derive(Clone, JSTraceable, MallocSizeOf)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct VertexAttribData {
pub enabled_as_array: bool,
pub size: u8,
diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs
index 398710ee558..e882566e07f 100644
--- a/components/script/dom/worklet.rs
+++ b/components/script/dom/worklet.rs
@@ -417,7 +417,7 @@ struct WorkletThreadInit {
}
/// A thread for executing worklets.
-#[must_root]
+#[unrooted_must_root_lint::must_root]
struct WorkletThread {
/// Which role the thread is currently playing
role: WorkletThreadRole,
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 87eec7cab02..deab92ea107 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -7,12 +7,14 @@
#![feature(drain_filter)]
#![feature(inner_deref)]
#![feature(plugin)]
+#![feature(register_tool)]
#![deny(unsafe_code)]
#![allow(non_snake_case)]
#![doc = "The script crate contains all matters DOM."]
#![cfg_attr(not(feature = "unrooted_must_root_lint"), allow(unknown_lints))]
#![allow(deprecated)] // FIXME: Can we make `allow` only apply to the `plugin` crate attribute?
#![plugin(script_plugins)]
+#![register_tool(unrooted_must_root_lint)]
#[macro_use]
extern crate bitflags;
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 20ac88b7bc1..43741209fa1 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -434,7 +434,7 @@ impl OpaqueSender<CommonScriptMsg> for Sender<MainThreadScriptMsg> {
/// The set of all documents managed by this script thread.
#[derive(JSTraceable)]
-#[must_root]
+#[unrooted_must_root_lint::must_root]
pub struct Documents {
map: HashMap<PipelineId, Dom<Document>>,
}
diff --git a/components/script/serviceworkerjob.rs b/components/script/serviceworkerjob.rs
index 8ba955928a3..93340cabe27 100644
--- a/components/script/serviceworkerjob.rs
+++ b/components/script/serviceworkerjob.rs
@@ -38,7 +38,7 @@ pub enum SettleType {
Reject(Error),
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable)]
pub struct Job {
pub job_type: JobType,
@@ -97,7 +97,7 @@ impl PartialEq for Job {
}
}
-#[must_root]
+#[unrooted_must_root_lint::must_root]
#[derive(JSTraceable)]
pub struct JobQueue(pub DomRefCell<HashMap<ServoUrl, Vec<Job>>>);
diff --git a/components/script_plugins/Cargo.toml b/components/script_plugins/Cargo.toml
index c6bc3eb2250..1b86f9cb0b7 100644
--- a/components/script_plugins/Cargo.toml
+++ b/components/script_plugins/Cargo.toml
@@ -11,3 +11,6 @@ plugin = true
[features]
unrooted_must_root_lint = []
+
+[dependencies]
+matches = "0.1"
diff --git a/components/script_plugins/lib.rs b/components/script_plugins/lib.rs
index 740ae9f35ad..ec05f697e05 100644
--- a/components/script_plugins/lib.rs
+++ b/components/script_plugins/lib.rs
@@ -8,9 +8,9 @@
//!
//! - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private
//! - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate
-//! - `#[must_root]` : Prevents data of the marked type from being used on the stack.
+//! - `#[unrooted_must_root_lint::must_root]` : Prevents data of the marked type from being used on the stack.
//! See the lints module for more details
-//! - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`.
+//! - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[unrooted_must_root_lint::must_root]`.
//! Use this for structs that correspond to a DOM type
#![deny(unsafe_code)]
@@ -20,6 +20,8 @@
#![cfg(feature = "unrooted_must_root_lint")]
#[macro_use]
+extern crate matches;
+#[macro_use]
extern crate rustc;
extern crate rustc_driver;
extern crate syntax;
@@ -30,7 +32,7 @@ use rustc::hir::{self, ExprKind, HirId};
use rustc::lint::{LateContext, LateLintPass, LintContext, LintPass};
use rustc::ty;
use rustc_driver::plugin::Registry;
-use syntax::feature_gate::AttributeType::Whitelisted;
+use syntax::ast::{AttrKind, Attribute};
use syntax::source_map;
use syntax::source_map::{ExpnKind, MacroKind, Span};
use syntax::symbol::sym;
@@ -44,9 +46,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
fn registrar(reg: &mut Registry) {
let symbols = Symbols::new();
- reg.register_attribute(symbols.allow_unrooted_interior, Whitelisted);
- reg.register_attribute(symbols.allow_unrooted_in_rc, Whitelisted);
- reg.register_attribute(symbols.must_root, Whitelisted);
reg.lint_store.register_lints(&[&UNROOTED_MUST_ROOT]);
reg.lint_store
.register_late_pass(move || Box::new(UnrootedPass::new(symbols.clone())));
@@ -60,12 +59,12 @@ declare_lint!(
/// Lint for ensuring safe usage of unrooted pointers
///
-/// This lint (disable with `-A unrooted-must-root`/`#[allow(unrooted_must_root)]`) ensures that `#[must_root]`
-/// values are used correctly.
+/// This lint (disable with `-A unrooted-must-root`/`#[allow(unrooted_must_root)]`) ensures that
+/// `#[unrooted_must_root_lint::must_root]` values are used correctly.
///
/// "Incorrect" usage includes:
///
-/// - Not being used in a struct/enum field which is not `#[must_root]` itself
+/// - Not being used in a struct/enum field which is not `#[unrooted_must_root_lint::must_root]` itself
/// - Not being used as an argument to a function (Except onces named `new` and `new_inherited`)
/// - Not being bound locally in a `let` statement, assignment, `for` loop, or `match` statement.
///
@@ -74,7 +73,7 @@ declare_lint!(
///
/// Structs which have their own mechanism of rooting their unrooted contents (e.g. `ScriptThread`)
/// can be marked as `#[allow(unrooted_must_root)]`. Smart pointers which root their interior type
-/// can be marked as `#[allow_unrooted_interior]`
+/// can be marked as `#[unrooted_must_root_lint::allow_unrooted_interior]`
pub(crate) struct UnrootedPass {
symbols: Symbols,
}
@@ -85,22 +84,35 @@ impl UnrootedPass {
}
}
+fn has_lint_attr(sym: &Symbols, attrs: &[Attribute], name: Symbol) -> bool {
+ attrs.iter().any(|attr| {
+ matches!(
+ &attr.kind,
+ AttrKind::Normal(attr_item)
+ if attr_item.path.segments.len() == 2 &&
+ attr_item.path.segments[0].ident.name == sym.unrooted_must_root_lint &&
+ attr_item.path.segments[1].ident.name == name
+ )
+ })
+}
+
/// Checks if a type is unrooted or contains any owned unrooted types
fn is_unrooted_ty(sym: &Symbols, cx: &LateContext, ty: &ty::TyS, in_new_function: bool) -> bool {
let mut ret = false;
ty.maybe_walk(|t| {
match t.kind {
ty::Adt(did, substs) => {
- if cx.tcx.has_attr(did.did, sym.must_root) {
+ let has_attr = |did, name| has_lint_attr(sym, &cx.tcx.get_attrs(did), name);
+ if has_attr(did.did, sym.must_root) {
ret = true;
false
- } else if cx.tcx.has_attr(did.did, sym.allow_unrooted_interior) {
+ } else if has_attr(did.did, sym.allow_unrooted_interior) {
false
} else if match_def_path(cx, did.did, &[sym.alloc, sym.rc, sym.Rc]) {
// Rc<Promise> is okay
let inner = substs.type_at(0);
if let ty::Adt(did, _) = inner.kind {
- if cx.tcx.has_attr(did.did, sym.allow_unrooted_in_rc) {
+ if has_attr(did.did, sym.allow_unrooted_in_rc) {
false
} else {
true
@@ -175,35 +187,33 @@ impl LintPass for UnrootedPass {
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass {
- /// All structs containing #[must_root] types must be #[must_root] themselves
+ /// All structs containing #[unrooted_must_root_lint::must_root] types
+ /// must be #[unrooted_must_root_lint::must_root] themselves
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
- if item
- .attrs
- .iter()
- .any(|a| a.check_name(self.symbols.must_root))
- {
+ if has_lint_attr(&self.symbols, &item.attrs, self.symbols.must_root) {
return;
}
if let hir::ItemKind::Struct(def, ..) = &item.kind {
for ref field in def.fields() {
let def_id = cx.tcx.hir().local_def_id(field.hir_id);
if is_unrooted_ty(&self.symbols, cx, cx.tcx.type_of(def_id), false) {
- cx.span_lint(UNROOTED_MUST_ROOT, field.span,
- "Type must be rooted, use #[must_root] on the struct definition to propagate")
+ cx.span_lint(
+ UNROOTED_MUST_ROOT,
+ field.span,
+ "Type must be rooted, use #[unrooted_must_root_lint::must_root] \
+ on the struct definition to propagate",
+ )
}
}
}
}
- /// All enums containing #[must_root] types must be #[must_root] themselves
+ /// All enums containing #[unrooted_must_root_lint::must_root] types
+ /// must be #[unrooted_must_root_lint::must_root] themselves
fn check_variant(&mut self, cx: &LateContext, var: &hir::Variant) {
let ref map = cx.tcx.hir();
- if map
- .expect_item(map.get_parent_item(var.id))
- .attrs
- .iter()
- .all(|a| !a.check_name(self.symbols.must_root))
- {
+ let parent_item = map.expect_item(map.get_parent_item(var.id));
+ if !has_lint_attr(&self.symbols, &parent_item.attrs, self.symbols.must_root) {
match var.data {
hir::VariantData::Tuple(ref fields, ..) => {
for ref field in fields {
@@ -212,7 +222,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass {
cx.span_lint(
UNROOTED_MUST_ROOT,
field.ty.span,
- "Type must be rooted, use #[must_root] on \
+ "Type must be rooted, use #[unrooted_must_root_lint::must_root] on \
the enum definition to propagate",
)
}
@@ -222,7 +232,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass {
}
}
}
- /// Function arguments that are #[must_root] types are not allowed
+ /// Function arguments that are #[unrooted_must_root_lint::must_root] types are not allowed
fn check_fn(
&mut self,
cx: &LateContext<'a, 'tcx>,
@@ -291,7 +301,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> {
};
match expr.kind {
- // Trait casts from #[must_root] types are not allowed
+ // Trait casts from #[unrooted_must_root_lint::must_root] types are not allowed
ExprKind::Cast(ref subexpr, _) => require_rooted(cx, self.in_new_function, &*subexpr),
// This catches assignments... the main point of this would be to catch mutable
// references to `JS<T>`.
@@ -393,6 +403,7 @@ macro_rules! symbols {
}
symbols! {
+ unrooted_must_root_lint
allow_unrooted_interior
allow_unrooted_in_rc
must_root
diff --git a/rust-toolchain b/rust-toolchain
index fc6d4ce593e..b3cc08aa48a 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1 +1 @@
-nightly-2019-10-26
+nightly-2019-11-15
diff --git a/tests/unit/script_plugins/lib.rs b/tests/unit/script_plugins/lib.rs
index 72877bcfe6b..7899569d15b 100644
--- a/tests/unit/script_plugins/lib.rs
+++ b/tests/unit/script_plugins/lib.rs
@@ -6,11 +6,12 @@
pub mod unrooted_must_root {
/**
```
- #![feature(plugin)]
+ #![feature(plugin, register_tool)]
#![plugin(script_plugins)]
+ #![register_tool(unrooted_must_root_lint)]
- #[must_root] struct Foo(i32);
- #[must_root] struct Bar(Foo);
+ #[unrooted_must_root_lint::must_root] struct Foo(i32);
+ #[unrooted_must_root_lint::must_root] struct Bar(Foo);
fn foo1(_: &Foo) {}
fn foo2(_: &()) -> &Foo { unimplemented!() }
@@ -22,10 +23,11 @@ pub mod unrooted_must_root {
/**
```compile_fail
- #![feature(plugin)]
+ #![feature(plugin, register_tool)]
#![plugin(script_plugins)]
+ #![register_tool(unrooted_must_root_lint)]
- #[must_root] struct Foo(i32);
+ #[unrooted_must_root_lint::must_root] struct Foo(i32);
struct Bar(Foo);
fn main() {}
@@ -35,10 +37,11 @@ pub mod unrooted_must_root {
/**
```compile_fail
- #![feature(plugin)]
+ #![feature(plugin, register_tool)]
#![plugin(script_plugins)]
+ #![register_tool(unrooted_must_root_lint)]
- #[must_root] struct Foo(i32);
+ #[unrooted_must_root_lint::must_root] struct Foo(i32);
fn foo1(_: Foo) {}
@@ -49,10 +52,11 @@ pub mod unrooted_must_root {
/**
```compile_fail
- #![feature(plugin)]
+ #![feature(plugin, register_tool)]
#![plugin(script_plugins)]
+ #![register_tool(unrooted_must_root_lint)]
- #[must_root] struct Foo(i32);
+ #[unrooted_must_root_lint::must_root] struct Foo(i32);
fn foo2() -> Foo { unimplemented!() }