aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_plugins/lib.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2019-11-15 17:07:13 -0500
committerGitHub <noreply@github.com>2019-11-15 17:07:13 -0500
commitd92f705573ac26fb8e16abc18d7d19e1fb384715 (patch)
tree7072475f19a837d6395acfc23061029eeb7619d2 /components/script_plugins/lib.rs
parentb9cdf9ebda07411c4c172e945599584edc5ba474 (diff)
parentbea73951db5a758f78842a0056daccba9d89a9c0 (diff)
downloadservo-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.rs73
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