diff options
Diffstat (limited to 'components/script_plugins/unrooted_must_root.rs')
-rw-r--r-- | components/script_plugins/unrooted_must_root.rs | 22 |
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); |