mirror of
https://github.com/servo/servo.git
synced 2025-07-30 18:50:36 +01:00
Make enum/fn part of unrooted_must_root handle type parameters
This commit is contained in:
parent
fda3eb6327
commit
521d8bc32e
3 changed files with 19 additions and 27 deletions
|
@ -6,7 +6,8 @@ use syntax::{ast, codemap, visit};
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use rustc::ast_map;
|
use rustc::ast_map;
|
||||||
use rustc::lint::{Context, LintPass, LintArray};
|
use rustc::lint::{Context, LintPass, LintArray};
|
||||||
use rustc::middle::{ty, def};
|
use rustc::middle::ty;
|
||||||
|
use rustc::middle::astconv_util::ast_ty_to_prim_ty;
|
||||||
use utils::{match_def_path, unsafe_context};
|
use utils::{match_def_path, unsafe_context};
|
||||||
|
|
||||||
declare_lint!(UNROOTED_MUST_ROOT, Deny,
|
declare_lint!(UNROOTED_MUST_ROOT, Deny,
|
||||||
|
@ -36,27 +37,8 @@ impl UnrootedPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Checks if a type has the #[must_root] annotation.
|
|
||||||
// Unwraps pointers as well
|
|
||||||
// TODO (#3874, sort of): unwrap other types like Vec/Option/HashMap/etc
|
|
||||||
fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) {
|
|
||||||
match ty.node {
|
|
||||||
ast::TyVec(ref t) | ast::TyFixedLengthVec(ref t, _) =>
|
|
||||||
lint_unrooted_ty(cx, &**t, warning),
|
|
||||||
ast::TyPath(..) => {
|
|
||||||
match cx.tcx.def_map.borrow()[&ty.id] {
|
|
||||||
def::PathResolution{ base_def: def::DefTy(def_id, _), .. } => {
|
|
||||||
if cx.tcx.has_attr(def_id, "must_root") {
|
|
||||||
cx.span_lint(UNROOTED_MUST_ROOT, ty.span, warning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// Checks if a type is unrooted or contains any owned unrooted types
|
||||||
fn is_unrooted_ty(cx: &Context, ty: &ty::TyS, in_new_function: bool) -> bool {
|
fn is_unrooted_ty(cx: &Context, ty: &ty::TyS, in_new_function: bool) -> bool {
|
||||||
let mut ret = false;
|
let mut ret = false;
|
||||||
ty.maybe_walk(|t| {
|
ty.maybe_walk(|t| {
|
||||||
|
@ -104,7 +86,8 @@ impl LintPass for UnrootedPass {
|
||||||
if item.attrs.iter().all(|a| !a.check_name("must_root")) {
|
if item.attrs.iter().all(|a| !a.check_name("must_root")) {
|
||||||
for ref field in def.fields.iter() {
|
for ref field in def.fields.iter() {
|
||||||
if is_unrooted_ty(cx, cx.tcx.node_id_to_type(field.node.id), false) {
|
if is_unrooted_ty(cx, cx.tcx.node_id_to_type(field.node.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 #[must_root] on the struct definition to propagate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,8 +99,13 @@ impl LintPass for UnrootedPass {
|
||||||
match var.node.kind {
|
match var.node.kind {
|
||||||
ast::TupleVariantKind(ref vec) => {
|
ast::TupleVariantKind(ref vec) => {
|
||||||
for ty in vec.iter() {
|
for ty in vec.iter() {
|
||||||
lint_unrooted_ty(cx, &*ty.ty,
|
ast_ty_to_prim_ty(cx.tcx, &*ty.ty).map(|t| {
|
||||||
"Type must be rooted, use #[must_root] on the enum definition to propagate")
|
if is_unrooted_ty(cx, t, false) {
|
||||||
|
cx.span_lint(UNROOTED_MUST_ROOT, ty.ty.span,
|
||||||
|
"Type must be rooted, use #[must_root] on \
|
||||||
|
the enum definition to propagate")
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => () // Struct variants already caught by check_struct_def
|
_ => () // Struct variants already caught by check_struct_def
|
||||||
|
@ -150,8 +138,11 @@ impl LintPass for UnrootedPass {
|
||||||
match block.rules {
|
match block.rules {
|
||||||
ast::DefaultBlock => {
|
ast::DefaultBlock => {
|
||||||
for arg in decl.inputs.iter() {
|
for arg in decl.inputs.iter() {
|
||||||
lint_unrooted_ty(cx, &*arg.ty,
|
ast_ty_to_prim_ty(cx.tcx, &*arg.ty).map(|t| {
|
||||||
"Type must be rooted")
|
if is_unrooted_ty(cx, t, false) {
|
||||||
|
cx.span_lint(UNROOTED_MUST_ROOT, arg.ty.span, "Type must be rooted")
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => () // fn is `unsafe`
|
_ => () // fn is `unsafe`
|
||||||
|
|
|
@ -81,6 +81,7 @@ impl<T: Reflectable> JS<T> {
|
||||||
|
|
||||||
/// An unrooted reference to a DOM object for use in layout. `Layout*Helpers`
|
/// An unrooted reference to a DOM object for use in layout. `Layout*Helpers`
|
||||||
/// traits must be implemented on this.
|
/// traits must be implemented on this.
|
||||||
|
#[allow_unrooted_interior]
|
||||||
pub struct LayoutJS<T> {
|
pub struct LayoutJS<T> {
|
||||||
ptr: NonZero<*const T>
|
ptr: NonZero<*const T>
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use std::rc::Rc;
|
||||||
|
|
||||||
/// Encapsulates a handle to a frame in a frame tree.
|
/// Encapsulates a handle to a frame in a frame tree.
|
||||||
#[derive(JSTraceable)]
|
#[derive(JSTraceable)]
|
||||||
#[allow(unrooted_must_root)] // FIXME(#6686) this is wrong
|
#[allow(unrooted_must_root)] // FIXME(#6687) this is wrong
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
/// Pipeline id associated with this page.
|
/// Pipeline id associated with this page.
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue