Exempt Rc<Promise> from unrooted_must_root

fixes #22504
This commit is contained in:
Manish Goregaokar 2019-01-03 16:17:06 -08:00
parent 7a64588efa
commit e28e73c81f
3 changed files with 15 additions and 1 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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"]) ||