diff options
-rw-r--r-- | components/plugins/lints/unrooted_must_root.rs | 22 | ||||
-rw-r--r-- | components/plugins/utils.rs | 16 |
2 files changed, 32 insertions, 6 deletions
diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index cc2ce5d8220..bb599e845de 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.rs @@ -4,12 +4,11 @@ use rustc::front::map as ast_map; use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; -use rustc::middle::astconv_util::ast_ty_to_prim_ty; use rustc::middle::ty; use rustc_front::{hir, visit}; use syntax::attr::AttrMetaMethods; use syntax::{ast, codemap}; -use utils::{match_def_path, unsafe_context}; +use utils::{match_def_path, unsafe_context, in_derive_expn}; declare_lint!(UNROOTED_MUST_ROOT, Deny, "Warn and report usage of unrooted jsmanaged objects"); @@ -107,7 +106,7 @@ impl LateLintPass for UnrootedPass { match var.node.kind { hir::TupleVariantKind(ref vec) => { for ty in vec { - ast_ty_to_prim_ty(cx.tcx, &*ty.ty).map(|t| { + cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty.id).map(|t| { if is_unrooted_ty(cx, t, false) { cx.span_lint(UNROOTED_MUST_ROOT, ty.ty.span, "Type must be rooted, use #[must_root] on \ @@ -122,7 +121,7 @@ impl LateLintPass for UnrootedPass { } /// Function arguments that are #[must_root] types are not allowed fn check_fn(&mut self, cx: &LateContext, kind: visit::FnKind, decl: &hir::FnDecl, - block: &hir::Block, _span: codemap::Span, id: ast::NodeId) { + block: &hir::Block, span: codemap::Span, id: ast::NodeId) { match kind { visit::FnKind::ItemFn(n, _, _, _, _, _) | visit::FnKind::Method(n, _, _) if n.as_str() == "new" @@ -145,12 +144,25 @@ impl LateLintPass for UnrootedPass { match block.rules { hir::DefaultBlock => { for arg in &decl.inputs { - ast_ty_to_prim_ty(cx.tcx, &*arg.ty).map(|t| { + cx.tcx.ast_ty_to_ty_cache.borrow().get(&arg.ty.id).map(|t| { if is_unrooted_ty(cx, t, false) { + if in_derive_expn(cx, span) { + return; + } cx.span_lint(UNROOTED_MUST_ROOT, arg.ty.span, "Type must be rooted") } }); } + if let hir::Return(ref ty) = decl.output { + cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty.id).map(|t| { + if is_unrooted_ty(cx, t, false) { + if in_derive_expn(cx, span) { + return; + } + cx.span_lint(UNROOTED_MUST_ROOT, ty.span, "Type must be rooted") + } + }); + } } _ => () // fn is `unsafe` } diff --git a/components/plugins/utils.rs b/components/plugins/utils.rs index 7576437a939..d9816c7a921 100644 --- a/components/plugins/utils.rs +++ b/components/plugins/utils.rs @@ -3,12 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use rustc::front::map as ast_map; -use rustc::lint::LateContext; +use rustc::lint::{LateContext, LintContext}; use rustc::middle::def; use rustc::middle::def_id::DefId; use rustc_front::hir; use syntax::ast; use syntax::attr::mark_used; +use syntax::codemap::{ExpnFormat, Span}; use syntax::ptr::P; @@ -100,3 +101,16 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool { cx.tcx.with_path(def_id, |iter| iter.map(|elem| elem.name()) .zip(path.iter()).all(|(nm, p)| &nm.as_str() == p)) } + +pub fn in_derive_expn(cx: &LateContext, span: Span) -> bool { + cx.sess().codemap().with_expn_info(span.expn_id, + |info| { + if let Some(i) = info { + if let ExpnFormat::MacroAttribute(n) = i.callee.format { + if n.as_str().contains("derive") { + true + } else { false } + } else { false } + } else { false } + }) +} |