mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Use #![register_tool]
instead of #![register_attr]
CC https://github.com/rust-lang/rust/issues/66079
This commit is contained in:
parent
091feba0ba
commit
bea73951db
46 changed files with 129 additions and 105 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -4228,6 +4228,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "script_plugins"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "script_plugins_tests"
|
||||
|
|
|
@ -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)]
|
||||
};
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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>>,
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>>>,
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -237,7 +237,7 @@ pub struct HTMLInputElement {
|
|||
}
|
||||
|
||||
#[derive(JSTraceable)]
|
||||
#[must_root]
|
||||
#[unrooted_must_root_lint::must_root]
|
||||
#[derive(MallocSizeOf)]
|
||||
struct InputActivationState {
|
||||
indeterminate: bool,
|
||||
|
|
|
@ -268,7 +268,7 @@ impl FrameRenderer for MediaFrameRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_root]
|
||||
#[unrooted_must_root_lint::must_root]
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
enum SrcObject {
|
||||
MediaStream(Dom<MediaStream>),
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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>>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>>,
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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>>>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>),
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -7,16 +7,14 @@
|
|||
#![feature(drain_filter)]
|
||||
#![feature(inner_deref)]
|
||||
#![feature(plugin)]
|
||||
#![feature(register_attr)]
|
||||
#![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_attr(allow_unrooted_interior)]
|
||||
#![register_attr(allow_unrooted_in_rc)]
|
||||
#![register_attr(must_root)]
|
||||
#![register_tool(unrooted_must_root_lint)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
|
|
@ -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>>,
|
||||
}
|
||||
|
|
|
@ -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>>>);
|
||||
|
||||
|
|
|
@ -11,3 +11,6 @@ plugin = true
|
|||
|
||||
[features]
|
||||
unrooted_must_root_lint = []
|
||||
|
||||
[dependencies]
|
||||
matches = "0.1"
|
||||
|
|
|
@ -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)]
|
||||
|
@ -19,6 +19,8 @@
|
|||
#![feature(rustc_private)]
|
||||
#![cfg(feature = "unrooted_must_root_lint")]
|
||||
|
||||
#[macro_use]
|
||||
extern crate matches;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_driver;
|
||||
|
@ -30,6 +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::ast::{AttrKind, Attribute};
|
||||
use syntax::source_map;
|
||||
use syntax::source_map::{ExpnKind, MacroKind, Span};
|
||||
use syntax::symbol::sym;
|
||||
|
@ -56,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.
|
||||
///
|
||||
|
@ -70,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,
|
||||
}
|
||||
|
@ -81,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
|
||||
|
@ -171,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 {
|
||||
|
@ -208,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",
|
||||
)
|
||||
}
|
||||
|
@ -218,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>,
|
||||
|
@ -287,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>`.
|
||||
|
@ -389,6 +403,7 @@ macro_rules! symbols {
|
|||
}
|
||||
|
||||
symbols! {
|
||||
unrooted_must_root_lint
|
||||
allow_unrooted_interior
|
||||
allow_unrooted_in_rc
|
||||
must_root
|
||||
|
|
|
@ -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!() }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue