diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2019-01-03 16:17:06 -0800 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2019-01-04 09:34:04 -0800 |
commit | e28e73c81fcbed570955f2175d56ee794de6882a (patch) | |
tree | 9574591ce539ea4d458a31d7e37325b8646c3294 | |
parent | 7a64588efaf45f307677b4a025b241fe3fc3b380 (diff) | |
download | servo-e28e73c81fcbed570955f2175d56ee794de6882a.tar.gz servo-e28e73c81fcbed570955f2175d56ee794de6882a.zip |
Exempt Rc<Promise> from unrooted_must_root
fixes #22504
-rw-r--r-- | components/script/dom/promise.rs | 1 | ||||
-rw-r--r-- | components/script_plugins/lib.rs | 1 | ||||
-rw-r--r-- | components/script_plugins/unrooted_must_root.rs | 14 |
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"]) || |