Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
diff mir lint
diff --git a/components/script/dom/bindings/root.rs b/components/script/dom/bindings/root.rs
index 18cb006202..6ac0c41710 100644
--- a/components/script/dom/bindings/root.rs
+++ b/components/script/dom/bindings/root.rs
@@ -126,7 +126,7 @@ where
}
/// A rooted reference to a DOM object.
-pub type DomRoot<T> = Root<Dom<T>>;
+pub type DomRoot<#[must_root] T> = Root<Dom<T>>;
impl<T: Castable> DomRoot<T> {
/// Cast a DOM object root upwards to one of the interfaces it derives from.
diff --git a/components/script_plugins/unrooted_must_root.rs b/components/script_plugins/unrooted_must_root.rs
index 2da3884201..44be157adf 100644
--- a/components/script_plugins/unrooted_must_root.rs
+++ b/components/script_plugins/unrooted_must_root.rs
@@ -193,7 +193,7 @@ impl<'a, 'b, 'tcx> UnrootedCx<'a, 'b, 'tcx> {
ret
}
- fn has_unrooted_generic_substs(&self, did: hir::def_id::DefId, substs: &ty::subst::Substs) -> bool {
+ fn has_unrooted_generic_substs(&self, did: hir::def_id::DefId, substs: &ty::subst::Substs, st: &mut String) -> bool {
let cx = self.late_cx;
if cx.tcx.has_attr(did, "allow_unrooted_interior") {
@@ -211,22 +211,48 @@ impl<'a, 'b, 'tcx> UnrootedCx<'a, 'b, 'tcx> {
return false;
}
- let generics = cx.tcx.generics_of(did);
- for ty_param_def in &generics.types {
- // If type has `#[must_root]`, then it is ok to
- // give it a must-root type, so just skip.
- if cx.tcx.has_attr(ty_param_def.def_id, "must_root") {
- continue;
+ let def_path = get_def_path(cx, did);
+ st.push_str(&def_path.join("::"));
+ st.push_str(&"\n");
+
+ // maybe check if some def_path.last() is/not "{{impl}}"
+ //if cx.tcx.type_of(did).is_trait() {
+ // return false;
+ //}
+ //cx.tcx.type_of(did);
+ if let Some(trref) = cx.tcx.impl_trait_ref(did) {
+ let mut it = trref.substs.types();
+ it.next().expect("trait is implemented for specific type");
+ for arg_ty in it {
+ if self.is_unrooted_ty(arg_ty, false) {
+ st.push_str(&" >! ");
+ st.push_str(&arg_ty.to_string());
+ return true;
+ }
}
+ }
+ else {
+ let generics = cx.tcx.generics_of(did);
+ for ty_param_def in &generics.types {
+ // If type has `#[must_root]`, then it is ok to
+ // give it a must-root type, so just skip.
+ if cx.tcx.has_attr(ty_param_def.def_id, "must_root") {
+ continue;
+ }
- let arg_ty = substs.type_at(ty_param_def.index as usize);
- if self.is_unrooted_ty(arg_ty, false) {
- return true;
+ let arg_ty = substs.type_at(ty_param_def.index as usize);
+ if self.is_unrooted_ty(arg_ty, false) {
+ st.push_str(&" > ");
+ st.push_str(&arg_ty.to_string());
+ return true;
+ }
}
}
+ let generics = cx.tcx.generics_of(did); // hackhack
+ st.push_str(&" par$$ ");
match generics.parent {
- Some(p_did) => self.has_unrooted_generic_substs(p_did, substs),
+ Some(p_did) => self.has_unrooted_generic_substs(p_did, substs, st),
None => false,
}
}
@@ -251,10 +277,11 @@ impl<'a, 'b, 'tcx> MirVisitor<'tcx> for MirFnVisitor<'a, 'b, 'tcx> {
let cx = ur_cx.late_cx;
match decl.ty.sty {
ty::TyAdt(adt_def, substs) => {
+ let mut type_info = String::new();
if adt_def.is_box() && self.in_new_function {
// Boxes of unrooted types are allowed in new functions.
}
- else if ur_cx.has_unrooted_generic_substs(adt_def.did, substs) {
+ else if ur_cx.has_unrooted_generic_substs(adt_def.did, substs, &mut type_info) {
cx.span_lint(UNROOTED_MUST_ROOT, decl.source_info.span, "ADT generic type must be rooted.")
}
},
@@ -270,16 +297,19 @@ impl<'a, 'b, 'tcx> MirVisitor<'tcx> for MirFnVisitor<'a, 'b, 'tcx> {
match constant.ty.sty {
ty::TyFnDef(callee_def_id, callee_substs) => {
let def_path = get_def_path(cx, callee_def_id);
+ let mut type_info = String::new();
// TODO remove following commented code
// cx.span_lint(UNROOTED_MUST_ROOT, constant.span, &def_path.join("::")); // tmp auxiliary call
if self.in_new_function && (// match_def_path(cx, callee_def_id, &["alloc", "boxed", "{{impl}}", "new"]) ||
def_path.last().unwrap().starts_with("new_") || def_path.last().unwrap() == "new") {
// "new"-like (constructors) functions are allowed
}
- else if ur_cx.has_unrooted_generic_substs(callee_def_id, callee_substs) {
+ else if ur_cx.has_unrooted_generic_substs(callee_def_id, callee_substs, &mut type_info) {
// TODO tmp code - delete later
- let mut msg = "Callee generic type must be rooted.".to_string();
- msg.push_str(&def_path.join("::"));
+ let mut msg = "Callee generic type must be rooted.\n".to_string();
+ //msg.push_str(&def_path.join("::"));
+ //msg.push_str(&"\n");
+ msg.push_str(&type_info);
cx.span_lint(UNROOTED_MUST_ROOT, constant.span, &msg);
//cx.span_lint(UNROOTED_MUST_ROOT, constant.span, "Callee generic type must be rooted.")
}
diff --git a/tests/unit/script_plugins/lib.rs b/tests/unit/script_plugins/lib.rs
index 83b5dd4fc4..dc53caf2d2 100644
--- a/tests/unit/script_plugins/lib.rs
+++ b/tests/unit/script_plugins/lib.rs
@@ -280,6 +280,30 @@ pub mod unrooted_must_root {
*/
pub fn allowing_unrooted_interior() {}
+ /**
+ ```
+ #![feature(plugin)]
+ #![plugin(script_plugins)]
+
+ #[must_root] struct Foo(i32);
+
+ trait Bar {
+ fn extract(&self) -> i32;
+ }
+
+ impl Bar for Foo {
+ fn extract(&self) -> i32 { self.0 }
+ }
+
+ fn test() {
+ Foo(3).extract();
+ }
+
+ fn main() {}
+ ```
+ */
+ pub fn allow_impl_for_must_root() {}
+
/* *
```
#![feature(plugin)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.