mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Make struct part of unrooted_must_root handle type parameters
This commit is contained in:
parent
511e3337fb
commit
fda3eb6327
4 changed files with 40 additions and 28 deletions
|
@ -57,6 +57,35 @@ fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_unrooted_ty(cx: &Context, ty: &ty::TyS, in_new_function: bool) -> bool {
|
||||||
|
let mut ret = false;
|
||||||
|
ty.maybe_walk(|t| {
|
||||||
|
match t.sty {
|
||||||
|
ty::TyStruct(did, _) |
|
||||||
|
ty::TyEnum(did, _) => {
|
||||||
|
if cx.tcx.has_attr(did, "must_root") {
|
||||||
|
ret = true;
|
||||||
|
false
|
||||||
|
} else if cx.tcx.has_attr(did, "allow_unrooted_interior") {
|
||||||
|
false
|
||||||
|
} else if match_def_path(cx, did, &["core", "cell", "Ref"])
|
||||||
|
|| match_def_path(cx, did, &["core", "cell", "RefMut"]) {
|
||||||
|
// Ref and RefMut are borrowed pointers, okay to hold unrooted stuff
|
||||||
|
// since it will be rooted elsewhere
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ty::TyBox(..) if in_new_function => false, // box in new() is okay
|
||||||
|
ty::TyRef(..) => false, // don't recurse down &ptrs
|
||||||
|
ty::TyRawPtr(..) => false, // don't recurse down *ptrs
|
||||||
|
_ => true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
impl LintPass for UnrootedPass {
|
impl LintPass for UnrootedPass {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
lint_array!(UNROOTED_MUST_ROOT)
|
lint_array!(UNROOTED_MUST_ROOT)
|
||||||
|
@ -74,8 +103,9 @@ 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() {
|
||||||
lint_unrooted_ty(cx, &*field.node.ty,
|
if is_unrooted_ty(cx, cx.tcx.node_id_to_type(field.node.id), false) {
|
||||||
"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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,31 +198,9 @@ impl LintPass for UnrootedPass {
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty = cx.tcx.expr_ty(&*expr);
|
let ty = cx.tcx.expr_ty(&*expr);
|
||||||
ty.maybe_walk(|t| {
|
if is_unrooted_ty(cx, ty, self.in_new_function) {
|
||||||
match t.sty {
|
cx.span_lint(UNROOTED_MUST_ROOT, expr.span,
|
||||||
ty::TyStruct(did, _) |
|
&format!("Expression of type {:?} must be rooted", ty))
|
||||||
ty::TyEnum(did, _) => {
|
}
|
||||||
if cx.tcx.has_attr(did, "must_root") {
|
|
||||||
cx.span_lint(UNROOTED_MUST_ROOT, expr.span,
|
|
||||||
&format!("Expression of type {:?} in type {:?} must be rooted", t, ty));
|
|
||||||
false
|
|
||||||
} else if cx.tcx.has_attr(did, "allow_unrooted_interior") {
|
|
||||||
false
|
|
||||||
} else if match_def_path(cx, did, &["core", "cell", "Ref"])
|
|
||||||
|| match_def_path(cx, did, &["core", "cell", "RefMut"]) {
|
|
||||||
// Ref and RefMut are borrowed pointers, okay to hold unrooted stuff
|
|
||||||
// since it will be rooted elsewhere
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ty::TyBox(..) if self.in_new_function => false, // box in new() is okay
|
|
||||||
ty::TyRef(..) => false, // don't recurse down &ptrs
|
|
||||||
ty::TyRawPtr(..) => false, // don't recurse down *ptrs
|
|
||||||
_ => true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ use std::default::Default;
|
||||||
#[derive(JSTraceable)]
|
#[derive(JSTraceable)]
|
||||||
#[privatize]
|
#[privatize]
|
||||||
#[allow(raw_pointer_derive)]
|
#[allow(raw_pointer_derive)]
|
||||||
|
#[must_root]
|
||||||
pub struct BrowsingContext {
|
pub struct BrowsingContext {
|
||||||
history: Vec<SessionHistoryEntry>,
|
history: Vec<SessionHistoryEntry>,
|
||||||
active_index: usize,
|
active_index: usize,
|
||||||
|
|
|
@ -14,6 +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
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
/// Pipeline id associated with this page.
|
/// Pipeline id associated with this page.
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
|
|
|
@ -287,6 +287,8 @@ impl Drop for StackRootTLS {
|
||||||
/// Information for an entire page. Pages are top-level browsing contexts and can contain multiple
|
/// Information for an entire page. Pages are top-level browsing contexts and can contain multiple
|
||||||
/// frames.
|
/// frames.
|
||||||
#[derive(JSTraceable)]
|
#[derive(JSTraceable)]
|
||||||
|
// ScriptTask instances are rooted on creation, so this is okay
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
pub struct ScriptTask {
|
pub struct ScriptTask {
|
||||||
/// A handle to the information pertaining to page layout
|
/// A handle to the information pertaining to page layout
|
||||||
page: DOMRefCell<Option<Rc<Page>>>,
|
page: DOMRefCell<Option<Rc<Page>>>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue