diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2015-07-21 23:24:42 +0530 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-07-22 00:01:26 +0530 |
commit | fda3eb632703a3b11fe586516fe03c5e05a73a45 (patch) | |
tree | a14de65b9a482565e8ba871f48a856147a6be87d /components/plugins/lints/unrooted_must_root.rs | |
parent | 511e3337fb3b1839ac00039d56ef6861762ed5d1 (diff) | |
download | servo-fda3eb632703a3b11fe586516fe03c5e05a73a45.tar.gz servo-fda3eb632703a3b11fe586516fe03c5e05a73a45.zip |
Make struct part of unrooted_must_root handle type parameters
Diffstat (limited to 'components/plugins/lints/unrooted_must_root.rs')
-rw-r--r-- | components/plugins/lints/unrooted_must_root.rs | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index be6175c2cce..073212eabe6 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.rs @@ -57,6 +57,35 @@ fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) { }; } +fn is_unrooted_ty(cx: &Context, ty: &ty::TyS, in_new_function: bool) -> bool { + let mut ret = false; + ty.maybe_walk(|t| { + match t.sty { + ty::TyStruct(did, _) | + ty::TyEnum(did, _) => { + if cx.tcx.has_attr(did, "must_root") { + ret = true; + false + } else if cx.tcx.has_attr(did, "allow_unrooted_interior") { + false + } else if match_def_path(cx, did, &["core", "cell", "Ref"]) + || match_def_path(cx, did, &["core", "cell", "RefMut"]) { + // Ref and RefMut are borrowed pointers, okay to hold unrooted stuff + // since it will be rooted elsewhere + false + } else { + true + } + }, + ty::TyBox(..) if in_new_function => false, // box in new() is okay + ty::TyRef(..) => false, // don't recurse down &ptrs + ty::TyRawPtr(..) => false, // don't recurse down *ptrs + _ => true + } + }); + ret +} + impl LintPass for UnrootedPass { fn get_lints(&self) -> LintArray { lint_array!(UNROOTED_MUST_ROOT) @@ -74,8 +103,9 @@ impl LintPass for UnrootedPass { }; if item.attrs.iter().all(|a| !a.check_name("must_root")) { for ref field in def.fields.iter() { - lint_unrooted_ty(cx, &*field.node.ty, - "Type must be rooted, use #[must_root] on the struct definition to propagate"); + if is_unrooted_ty(cx, cx.tcx.node_id_to_type(field.node.id), false) { + cx.span_lint(UNROOTED_MUST_ROOT, field.span, "Type must be rooted, use #[must_root] on the struct definition to propagate") + } } } } @@ -168,31 +198,9 @@ impl LintPass for UnrootedPass { }; let ty = cx.tcx.expr_ty(&*expr); - ty.maybe_walk(|t| { - match t.sty { - ty::TyStruct(did, _) | - ty::TyEnum(did, _) => { - if cx.tcx.has_attr(did, "must_root") { - cx.span_lint(UNROOTED_MUST_ROOT, expr.span, - &format!("Expression of type {:?} in type {:?} must be rooted", t, ty)); - false - } else if cx.tcx.has_attr(did, "allow_unrooted_interior") { - false - } else if match_def_path(cx, did, &["core", "cell", "Ref"]) - || match_def_path(cx, did, &["core", "cell", "RefMut"]) { - // Ref and RefMut are borrowed pointers, okay to hold unrooted stuff - // since it will be rooted elsewhere - false - } else { - true - } - }, - ty::TyBox(..) if self.in_new_function => false, // box in new() is okay - ty::TyRef(..) => false, // don't recurse down &ptrs - ty::TyRawPtr(..) => false, // don't recurse down *ptrs - _ => true - } - }) - + if is_unrooted_ty(cx, ty, self.in_new_function) { + cx.span_lint(UNROOTED_MUST_ROOT, expr.span, + &format!("Expression of type {:?} must be rooted", ty)) + } } } |