diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-11-15 17:07:13 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-15 17:07:13 -0500 |
commit | d92f705573ac26fb8e16abc18d7d19e1fb384715 (patch) | |
tree | 7072475f19a837d6395acfc23061029eeb7619d2 /components/script_plugins/lib.rs | |
parent | b9cdf9ebda07411c4c172e945599584edc5ba474 (diff) | |
parent | bea73951db5a758f78842a0056daccba9d89a9c0 (diff) | |
download | servo-d92f705573ac26fb8e16abc18d7d19e1fb384715.tar.gz servo-d92f705573ac26fb8e16abc18d7d19e1fb384715.zip |
Auto merge of #24750 - servo:register-tool, r=jdm
Use `#![register_tool]` instead of `Registry::register_attribute`
CC https://github.com/rust-lang/rust/pull/66344, https://github.com/rust-lang/rust/issues/66079
Diffstat (limited to 'components/script_plugins/lib.rs')
-rw-r--r-- | components/script_plugins/lib.rs | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/components/script_plugins/lib.rs b/components/script_plugins/lib.rs index 740ae9f35ad..ec05f697e05 100644 --- a/components/script_plugins/lib.rs +++ b/components/script_plugins/lib.rs @@ -8,9 +8,9 @@ //! //! - `#[derive(DenyPublicFields)]` : Forces all fields in a struct/enum to be private //! - `#[derive(JSTraceable)]` : Auto-derives an implementation of `JSTraceable` for a struct in the script crate -//! - `#[must_root]` : Prevents data of the marked type from being used on the stack. +//! - `#[unrooted_must_root_lint::must_root]` : Prevents data of the marked type from being used on the stack. //! See the lints module for more details -//! - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[must_root]`. +//! - `#[dom_struct]` : Implies #[derive(JSTraceable, DenyPublicFields)]`, and `#[unrooted_must_root_lint::must_root]`. //! Use this for structs that correspond to a DOM type #![deny(unsafe_code)] @@ -20,6 +20,8 @@ #![cfg(feature = "unrooted_must_root_lint")] #[macro_use] +extern crate matches; +#[macro_use] extern crate rustc; extern crate rustc_driver; extern crate syntax; @@ -30,7 +32,7 @@ use rustc::hir::{self, ExprKind, HirId}; use rustc::lint::{LateContext, LateLintPass, LintContext, LintPass}; use rustc::ty; use rustc_driver::plugin::Registry; -use syntax::feature_gate::AttributeType::Whitelisted; +use syntax::ast::{AttrKind, Attribute}; use syntax::source_map; use syntax::source_map::{ExpnKind, MacroKind, Span}; use syntax::symbol::sym; @@ -44,9 +46,6 @@ pub fn plugin_registrar(reg: &mut Registry) { fn registrar(reg: &mut Registry) { let symbols = Symbols::new(); - reg.register_attribute(symbols.allow_unrooted_interior, Whitelisted); - reg.register_attribute(symbols.allow_unrooted_in_rc, Whitelisted); - reg.register_attribute(symbols.must_root, Whitelisted); reg.lint_store.register_lints(&[&UNROOTED_MUST_ROOT]); reg.lint_store .register_late_pass(move || Box::new(UnrootedPass::new(symbols.clone()))); @@ -60,12 +59,12 @@ declare_lint!( /// Lint for ensuring safe usage of unrooted pointers /// -/// This lint (disable with `-A unrooted-must-root`/`#[allow(unrooted_must_root)]`) ensures that `#[must_root]` -/// values are used correctly. +/// This lint (disable with `-A unrooted-must-root`/`#[allow(unrooted_must_root)]`) ensures that +/// `#[unrooted_must_root_lint::must_root]` values are used correctly. /// /// "Incorrect" usage includes: /// -/// - Not being used in a struct/enum field which is not `#[must_root]` itself +/// - Not being used in a struct/enum field which is not `#[unrooted_must_root_lint::must_root]` itself /// - Not being used as an argument to a function (Except onces named `new` and `new_inherited`) /// - Not being bound locally in a `let` statement, assignment, `for` loop, or `match` statement. /// @@ -74,7 +73,7 @@ declare_lint!( /// /// Structs which have their own mechanism of rooting their unrooted contents (e.g. `ScriptThread`) /// can be marked as `#[allow(unrooted_must_root)]`. Smart pointers which root their interior type -/// can be marked as `#[allow_unrooted_interior]` +/// can be marked as `#[unrooted_must_root_lint::allow_unrooted_interior]` pub(crate) struct UnrootedPass { symbols: Symbols, } @@ -85,22 +84,35 @@ impl UnrootedPass { } } +fn has_lint_attr(sym: &Symbols, attrs: &[Attribute], name: Symbol) -> bool { + attrs.iter().any(|attr| { + matches!( + &attr.kind, + AttrKind::Normal(attr_item) + if attr_item.path.segments.len() == 2 && + attr_item.path.segments[0].ident.name == sym.unrooted_must_root_lint && + attr_item.path.segments[1].ident.name == name + ) + }) +} + /// Checks if a type is unrooted or contains any owned unrooted types fn is_unrooted_ty(sym: &Symbols, cx: &LateContext, ty: &ty::TyS, in_new_function: bool) -> bool { let mut ret = false; ty.maybe_walk(|t| { match t.kind { ty::Adt(did, substs) => { - if cx.tcx.has_attr(did.did, sym.must_root) { + let has_attr = |did, name| has_lint_attr(sym, &cx.tcx.get_attrs(did), name); + if has_attr(did.did, sym.must_root) { ret = true; false - } else if cx.tcx.has_attr(did.did, sym.allow_unrooted_interior) { + } else if has_attr(did.did, sym.allow_unrooted_interior) { false } else if match_def_path(cx, did.did, &[sym.alloc, sym.rc, sym.Rc]) { // Rc<Promise> is okay let inner = substs.type_at(0); if let ty::Adt(did, _) = inner.kind { - if cx.tcx.has_attr(did.did, sym.allow_unrooted_in_rc) { + if has_attr(did.did, sym.allow_unrooted_in_rc) { false } else { true @@ -175,35 +187,33 @@ impl LintPass for UnrootedPass { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass { - /// All structs containing #[must_root] types must be #[must_root] themselves + /// All structs containing #[unrooted_must_root_lint::must_root] types + /// must be #[unrooted_must_root_lint::must_root] themselves fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) { - if item - .attrs - .iter() - .any(|a| a.check_name(self.symbols.must_root)) - { + if has_lint_attr(&self.symbols, &item.attrs, self.symbols.must_root) { return; } if let hir::ItemKind::Struct(def, ..) = &item.kind { for ref field in def.fields() { let def_id = cx.tcx.hir().local_def_id(field.hir_id); if is_unrooted_ty(&self.symbols, cx, cx.tcx.type_of(def_id), false) { - cx.span_lint(UNROOTED_MUST_ROOT, field.span, - "Type must be rooted, use #[must_root] on the struct definition to propagate") + cx.span_lint( + UNROOTED_MUST_ROOT, + field.span, + "Type must be rooted, use #[unrooted_must_root_lint::must_root] \ + on the struct definition to propagate", + ) } } } } - /// All enums containing #[must_root] types must be #[must_root] themselves + /// All enums containing #[unrooted_must_root_lint::must_root] types + /// must be #[unrooted_must_root_lint::must_root] themselves fn check_variant(&mut self, cx: &LateContext, var: &hir::Variant) { let ref map = cx.tcx.hir(); - if map - .expect_item(map.get_parent_item(var.id)) - .attrs - .iter() - .all(|a| !a.check_name(self.symbols.must_root)) - { + let parent_item = map.expect_item(map.get_parent_item(var.id)); + if !has_lint_attr(&self.symbols, &parent_item.attrs, self.symbols.must_root) { match var.data { hir::VariantData::Tuple(ref fields, ..) => { for ref field in fields { @@ -212,7 +222,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass { cx.span_lint( UNROOTED_MUST_ROOT, field.ty.span, - "Type must be rooted, use #[must_root] on \ + "Type must be rooted, use #[unrooted_must_root_lint::must_root] on \ the enum definition to propagate", ) } @@ -222,7 +232,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass { } } } - /// Function arguments that are #[must_root] types are not allowed + /// Function arguments that are #[unrooted_must_root_lint::must_root] types are not allowed fn check_fn( &mut self, cx: &LateContext<'a, 'tcx>, @@ -291,7 +301,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> { }; match expr.kind { - // Trait casts from #[must_root] types are not allowed + // Trait casts from #[unrooted_must_root_lint::must_root] types are not allowed ExprKind::Cast(ref subexpr, _) => require_rooted(cx, self.in_new_function, &*subexpr), // This catches assignments... the main point of this would be to catch mutable // references to `JS<T>`. @@ -393,6 +403,7 @@ macro_rules! symbols { } symbols! { + unrooted_must_root_lint allow_unrooted_interior allow_unrooted_in_rc must_root |