/gist:51a11dcf5e8c5367235ebc9d3f58f358
Secret
Last active Apr 10, 2018
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