aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2019-01-03 16:17:06 -0800
committerManish Goregaokar <manishsmail@gmail.com>2019-01-04 09:34:04 -0800
commite28e73c81fcbed570955f2175d56ee794de6882a (patch)
tree9574591ce539ea4d458a31d7e37325b8646c3294
parent7a64588efaf45f307677b4a025b241fe3fc3b380 (diff)
downloadservo-e28e73c81fcbed570955f2175d56ee794de6882a.tar.gz
servo-e28e73c81fcbed570955f2175d56ee794de6882a.zip
Exempt Rc<Promise> from unrooted_must_root
fixes #22504
-rw-r--r--components/script/dom/promise.rs1
-rw-r--r--components/script_plugins/lib.rs1
-rw-r--r--components/script_plugins/unrooted_must_root.rs14
3 files changed, 15 insertions, 1 deletions
diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs
index 41f08ac293e..1de065f992e 100644
--- a/components/script/dom/promise.rs
+++ b/components/script/dom/promise.rs
@@ -35,6 +35,7 @@ use std::ptr;
use std::rc::Rc;
#[dom_struct]
+#[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_plugins/lib.rs b/components/script_plugins/lib.rs
index 7fdfb10fcce..36c81ce6239 100644
--- a/components/script_plugins/lib.rs
+++ b/components/script_plugins/lib.rs
@@ -41,5 +41,6 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_late_lint_pass(Box::new(unrooted_must_root::UnrootedPass::new()));
reg.register_attribute("allow_unrooted_interior".to_string(), Whitelisted);
+ reg.register_attribute("allow_unrooted_in_rc".to_string(), Whitelisted);
reg.register_attribute("must_root".to_string(), Whitelisted);
}
diff --git a/components/script_plugins/unrooted_must_root.rs b/components/script_plugins/unrooted_must_root.rs
index 73ebcd76065..58700e5d6b6 100644
--- a/components/script_plugins/unrooted_must_root.rs
+++ b/components/script_plugins/unrooted_must_root.rs
@@ -45,12 +45,24 @@ fn is_unrooted_ty(cx: &LateContext, ty: &ty::TyS, in_new_function: bool) -> bool
let mut ret = false;
ty.maybe_walk(|t| {
match t.sty {
- ty::Adt(did, _) => {
+ ty::Adt(did, substs) => {
if cx.tcx.has_attr(did.did, "must_root") {
ret = true;
false
} else if cx.tcx.has_attr(did.did, "allow_unrooted_interior") {
false
+ } else if match_def_path(cx, did.did, &["alloc", "rc", "Rc"]) {
+ // Rc<Promise> is okay
+ let inner = substs.type_at(0);
+ if let ty::Adt(did, _) = inner.sty {
+ if cx.tcx.has_attr(did.did, "allow_unrooted_in_rc") {
+ false
+ } else {
+ true
+ }
+ } else {
+ true
+ }
} else if match_def_path(cx, did.did, &["core", "cell", "Ref"]) ||
match_def_path(cx, did.did, &["core", "cell", "RefMut"]) ||
match_def_path(cx, did.did, &["core", "slice", "Iter"]) ||