+
+/// Walk the FullLibraryAST, determining if impl aliases need to be marked cloneable.
+fn walk_ast_second_pass<'a>(ast_storage: &'a FullLibraryAST, crate_types: &CrateTypes<'a>) {
+ for (module, astmod) in ast_storage.modules.iter() {
+ let orig_crate = module.splitn(2, "::").next().unwrap();
+ let ASTModule { ref attrs, ref items, .. } = astmod;
+ assert_eq!(export_status(&attrs), ExportStatus::Export);
+
+ let import_resolver = ImportResolver::new(orig_crate, ast_storage, module, items);
+ let mut types = TypeResolver::new(module, import_resolver, crate_types);
+
+ for item in items.iter() {
+ match item {
+ syn::Item::Impl(i) => {
+ match export_status(&i.attrs) {
+ ExportStatus::Export => {},
+ ExportStatus::NoExport|ExportStatus::TestOnly => continue,
+ ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"),
+ }
+ if let Some(trait_path) = i.trait_.as_ref() {
+ if path_matches_nongeneric(&trait_path.1, &["core", "clone", "Clone"]) ||
+ path_matches_nongeneric(&trait_path.1, &["Clone"])
+ {
+ if let &syn::Type::Path(ref p) = &*i.self_ty {
+ if let Some(resolved_path) = types.maybe_resolve_path(&p.path, None) {
+ create_alias_for_impl(resolved_path, i, &mut types, |aliased_impl, types| {
+ if let &syn::Type::Path(ref p) = &*aliased_impl.self_ty {
+ if let Some(resolved_aliased_path) = types.maybe_resolve_path(&p.path, None) {
+ crate_types.set_clonable("crate::".to_owned() + &resolved_aliased_path);
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+}
+