From 847929cb07d64d516c07b1479cc14daa8203eced Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 30 Jul 2015 11:51:38 -0700 Subject: [PATCH] plugins: Forbid trait casts of rooted objects. This was a quick soundness improvement and didn't break anything. --- .../plugins/lints/unrooted_must_root.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index d51fe19871e..16a10e442c4 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.rs @@ -153,6 +153,25 @@ impl LintPass for UnrootedPass { } } + /// Trait casts from #[must_root] types are not allowed + fn check_expr(&mut self, cx: &Context, expr: &ast::Expr) { + fn require_rooted(cx: &Context, in_new_function: bool, subexpr: &ast::Expr) { + let ty = cx.tcx.expr_ty(&*subexpr); + if is_unrooted_ty(cx, ty, in_new_function) { + cx.span_lint(UNROOTED_MUST_ROOT, + subexpr.span, + &format!("Expression of type {:?} must be rooted", ty)) + } + }; + + match expr.node { + ast::ExprCast(ref subexpr, _) => require_rooted(cx, self.in_new_function, &*subexpr), + _ => { + // TODO(pcwalton): Check generics with a whitelist of allowed generics. + } + } + } + // Partially copied from rustc::middle::lint::builtin // Catches `let` statements and assignments which store a #[must_root] value // Expressions which return out of blocks eventually end up in a `let` or assignment