aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_plugins/unrooted_must_root.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script_plugins/unrooted_must_root.rs')
-rw-r--r--components/script_plugins/unrooted_must_root.rs22
1 files changed, 15 insertions, 7 deletions
diff --git a/components/script_plugins/unrooted_must_root.rs b/components/script_plugins/unrooted_must_root.rs
index 5dbd2b1a3bd..f3f5e60ab62 100644
--- a/components/script_plugins/unrooted_must_root.rs
+++ b/components/script_plugins/unrooted_must_root.rs
@@ -182,7 +182,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> {
}
match expr.node {
- /// Trait casts from #[must_root] types are not allowed
+ // Trait casts from #[must_root] types are not allowed
hir::ExprCast(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>`.
@@ -206,13 +206,21 @@ impl<'a, 'b, 'tcx> visit::Visitor<'tcx> for FnDefVisitor<'a, 'b, 'tcx> {
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
let cx = self.cx;
- if let hir::PatKind::Binding(hir::BindingMode::BindByValue(_), _, _, _) = pat.node {
- let ty = cx.tables.pat_ty(pat);
- if is_unrooted_ty(cx, ty, self.in_new_function) {
- cx.span_lint(UNROOTED_MUST_ROOT,
- pat.span,
- &format!("Expression of type {:?} must be rooted", ty))
+ // We want to detect pattern bindings that move a value onto the stack.
+ // When "default binding modes" https://github.com/rust-lang/rust/issues/42640
+ // are implemented, the `Unannotated` case could cause false-positives.
+ // These should be fixable by adding an explicit `ref`.
+ match pat.node {
+ hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, _) |
+ hir::PatKind::Binding(hir::BindingAnnotation::Mutable, _, _, _) => {
+ let ty = cx.tables.pat_ty(pat);
+ if is_unrooted_ty(cx, ty, self.in_new_function) {
+ cx.span_lint(UNROOTED_MUST_ROOT,
+ pat.span,
+ &format!("Expression of type {:?} must be rooted", ty))
+ }
}
+ _ => {}
}
visit::walk_pat(self, pat);