From d0bc6a1f49f2802d603acf086ed54d976a79d703 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 3 Nov 2015 22:48:28 -0800 Subject: [PATCH] Don't chain method calls in #[derive(Debug)] Closes #29540 --- src/libsyntax/ext/deriving/debug.rs | 59 ++-- src/test/run-pass/issue-29540.rs | 501 ++++++++++++++++++++++++++++ 2 files changed, 536 insertions(+), 24 deletions(-) create mode 100644 src/test/run-pass/issue-29540.rs diff --git a/src/libsyntax/ext/deriving/debug.rs b/src/libsyntax/ext/deriving/debug.rs index 537375f7084..8a180e6c093 100644 --- a/src/libsyntax/ext/deriving/debug.rs +++ b/src/libsyntax/ext/deriving/debug.rs @@ -72,34 +72,40 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, let span = Span { expn_id: cx.backtrace(), .. span }; let name = cx.expr_lit(span, ast::Lit_::LitStr(ident.name.as_str(), ast::StrStyle::CookedStr)); - let mut expr = substr.nonself_args[0].clone(); + let builder = token::str_to_ident("builder"); + let builder_expr = cx.expr_ident(span, builder.clone()); - match *substr.fields { + let fmt = substr.nonself_args[0].clone(); + + let stmts = match *substr.fields { Struct(ref fields) | EnumMatching(_, _, ref fields) => { - + let mut stmts = vec![]; if fields.is_empty() || fields[0].name.is_none() { // tuple struct/"normal" variant - expr = cx.expr_method_call(span, - expr, - token::str_to_ident("debug_tuple"), - vec![name]); + let expr = cx.expr_method_call(span, + fmt, + token::str_to_ident("debug_tuple"), + vec![name]); + stmts.push(cx.stmt_let(span, true, builder, expr)); for field in fields { // Use double indirection to make sure this works for unsized types let field = cx.expr_addr_of(field.span, field.self_.clone()); let field = cx.expr_addr_of(field.span, field); - expr = cx.expr_method_call(span, - expr, - token::str_to_ident("field"), - vec![field]); + let expr = cx.expr_method_call(span, + builder_expr.clone(), + token::str_to_ident("field"), + vec![field]); + stmts.push(cx.stmt_expr(expr)); } } else { // normal struct/struct variant - expr = cx.expr_method_call(span, - expr, - token::str_to_ident("debug_struct"), - vec![name]); + let expr = cx.expr_method_call(span, + fmt, + token::str_to_ident("debug_struct"), + vec![name]); + stmts.push(cx.stmt_let(span, true, builder, expr)); for field in fields { let name = cx.expr_lit(field.span, ast::Lit_::LitStr( @@ -109,18 +115,23 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, // Use double indirection to make sure this works for unsized types let field = cx.expr_addr_of(field.span, field.self_.clone()); let field = cx.expr_addr_of(field.span, field); - expr = cx.expr_method_call(span, - expr, - token::str_to_ident("field"), - vec![name, field]); + let expr = cx.expr_method_call(span, + builder_expr.clone(), + token::str_to_ident("field"), + vec![name, field]); + stmts.push(cx.stmt_expr(expr)); } } + stmts } _ => unreachable!() - } + }; - cx.expr_method_call(span, - expr, - token::str_to_ident("finish"), - vec![]) + let expr = cx.expr_method_call(span, + builder_expr, + token::str_to_ident("finish"), + vec![]); + + let block = cx.block(span, stmts, Some(expr)); + cx.expr_block(block) } diff --git a/src/test/run-pass/issue-29540.rs b/src/test/run-pass/issue-29540.rs new file mode 100644 index 00000000000..285cf5763cc --- /dev/null +++ b/src/test/run-pass/issue-29540.rs @@ -0,0 +1,501 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug)] +pub struct Config { + pub name: String, + pub cluster: String, + pub debug_none: String, + pub debug_lockdep: String, + pub debug_context: String, + pub debug_crush: String, + pub debug_mds: String, + pub debug_mds_balancer: String, + pub debug_mds_locker: String, + pub debug_mds_log: String, + pub debug_mds_log_expire: String, + pub debug_mds_migrator: String, + pub debug_buffer: String, + pub debug_timer: String, + pub debug_filer: String, + pub debug_striper: String, + pub debug_objecter: String, + pub debug_rados: String, + pub debug_rbd: String, + pub debug_journaler: String, + pub debug_objectcacher: String, + pub debug_client: String, + pub debug_osd: String, + pub debug_optracker: String, + pub debug_objclass: String, + pub debug_filestore: String, + pub debug_keyvaluestore: String, + pub debug_journal: String, + pub debug_ms: String, + pub debug_mon: String, + pub debug_monc: String, + pub debug_paxos: String, + pub debug_tp: String, + pub debug_auth: String, + pub debug_crypto: String, + pub debug_finisher: String, + pub debug_heartbeatmap: String, + pub debug_perfcounter: String, + pub debug_rgw: String, + pub debug_civetweb: String, + pub debug_javaclient: String, + pub debug_asok: String, + pub debug_throttle: String, + pub host: String, + pub fsid: String, + pub public_addr: String, + pub cluster_addr: String, + pub public_network: String, + pub cluster_network: String, + pub num_client: String, + pub monmap: String, + pub mon_host: String, + pub lockdep: String, + pub run_dir: String, + pub admin_socket: String, + pub daemonize: String, + pub pid_file: String, + pub chdir: String, + pub max_open_files: String, + pub restapi_log_level: String, + pub restapi_base_url: String, + pub fatal_signal_handlers: String, + pub log_file: String, + pub log_max_new: String, + pub log_max_recent: String, + pub log_to_stderr: String, + pub err_to_stderr: String, + pub log_to_syslog: String, + pub err_to_syslog: String, + pub log_flush_on_exit: String, + pub log_stop_at_utilization: String, + pub clog_to_monitors: String, + pub clog_to_syslog: String, + pub clog_to_syslog_level: String, + pub clog_to_syslog_facility: String, + pub mon_cluster_log_to_syslog: String, + pub mon_cluster_log_to_syslog_level: String, + pub mon_cluster_log_to_syslog_facility: String, + pub mon_cluster_log_file: String, + pub mon_cluster_log_file_level: String, + pub key: String, + pub keyfile: String, + pub keyring: String, + pub heartbeat_interval: String, + pub heartbeat_file: String, + pub heartbeat_inject_failure: String, + pub perf: String, + pub ms_tcp_nodelay: String, + pub ms_tcp_rcvbuf: String, + pub ms_initial_backoff: String, + pub ms_max_backoff: String, + pub ms_nocrc: String, + pub ms_die_on_bad_msg: String, + pub ms_die_on_unhandled_msg: String, + pub ms_die_on_old_message: String, + pub ms_dispatch_throttle_bytes: String, + pub ms_bind_ipv6: String, + pub ms_bind_port_min: String, + pub ms_bind_port_max: String, + pub ms_rwthread_stack_bytes: String, + pub ms_tcp_read_timeout: String, + pub ms_pq_max_tokens_per_priority: String, + pub ms_pq_min_cost: String, + pub ms_inject_socket_failures: String, + pub ms_inject_delay_type: String, + pub ms_inject_delay_msg_type: String, + pub ms_inject_delay_max: String, + pub ms_inject_delay_probability: String, + pub ms_inject_internal_delays: String, + pub ms_dump_on_send: String, + pub inject_early_sigterm: String, + pub mon_data: String, + pub mon_initial_members: String, + pub mon_sync_fs_threshold: String, + pub mon_compact_on_start: String, + pub mon_compact_on_bootstrap: String, + pub mon_compact_on_trim: String, + pub mon_tick_interval: String, + pub mon_subscribe_interval: String, + pub mon_delta_reset_interval: String, + pub mon_osd_laggy_halflife: String, + pub mon_osd_laggy_weight: String, + pub mon_osd_adjust_heartbeat_grace: String, + pub mon_osd_adjust_down_out_interval: String, + pub mon_osd_auto_mark_in: String, + pub mon_osd_auto_mark_auto_out_in: String, + pub mon_osd_auto_mark_new_in: String, + pub mon_osd_down_out_interval: String, + pub mon_osd_down_out_subtree_limit: String, + pub mon_osd_min_up_ratio: String, + pub mon_osd_min_in_ratio: String, + pub mon_osd_max_op_age: String, + pub mon_osd_max_split_count: String, + pub mon_osd_allow_primary_temp: String, + pub mon_osd_allow_primary_affinity: String, + pub mon_stat_smooth_intervals: String, + pub mon_lease: String, + pub mon_lease_renew_interval: String, + pub mon_lease_ack_timeout: String, + pub mon_clock_drift_allowed: String, + pub mon_clock_drift_warn_backoff: String, + pub mon_timecheck_interval: String, + pub mon_accept_timeout: String, + pub mon_pg_create_interval: String, + pub mon_pg_stuck_threshold: String, + pub mon_pg_warn_min_per_osd: String, + pub mon_pg_warn_max_object_skew: String, + pub mon_pg_warn_min_objects: String, + pub mon_pg_warn_min_pool_objects: String, + pub mon_cache_target_full_warn_ratio: String, + pub mon_osd_full_ratio: String, + pub mon_osd_nearfull_ratio: String, + pub mon_globalid_prealloc: String, + pub mon_osd_report_timeout: String, + pub mon_force_standby_active: String, + pub mon_warn_on_old_mons: String, + pub mon_warn_on_legacy_crush_tunables: String, + pub mon_warn_on_osd_down_out_interval_zero: String, + pub mon_warn_on_cache_pools_without_hit_sets: String, + pub mon_min_osdmap_epochs: String, + pub mon_max_pgmap_epochs: String, + pub mon_max_log_epochs: String, + pub mon_max_mdsmap_epochs: String, + pub mon_max_osd: String, + pub mon_probe_timeout: String, + pub mon_slurp_timeout: String, + pub mon_slurp_bytes: String, + pub mon_client_bytes: String, + pub mon_daemon_bytes: String, + pub mon_max_log_entries_per_event: String, + pub mon_health_data_update_interval: String, + pub mon_data_avail_crit: String, + pub mon_data_avail_warn: String, + pub mon_config_key_max_entry_size: String, + pub mon_sync_timeout: String, + pub mon_sync_max_payload_size: String, + pub mon_sync_debug: String, + pub mon_sync_debug_leader: String, + pub mon_sync_debug_provider: String, + pub mon_sync_debug_provider_fallback: String, + pub mon_inject_sync_get_chunk_delay: String, + pub mon_osd_min_down_reporters: String, + pub mon_osd_min_down_reports: String, + pub mon_osd_force_trim_to: String, + pub mon_mds_force_trim_to: String, + pub mon_advanced_debug_mode: String, + pub mon_debug_dump_transactions: String, + pub mon_debug_dump_location: String, + pub mon_sync_provider_kill_at: String, + pub mon_sync_requester_kill_at: String, + pub mon_leveldb_write_buffer_size: String, + pub mon_leveldb_cache_size: String, + pub mon_leveldb_block_size: String, + pub mon_leveldb_bloom_size: String, + pub mon_leveldb_max_open_files: String, + pub mon_leveldb_compression: String, + pub mon_leveldb_paranoid: String, + pub mon_leveldb_log: String, + pub mon_leveldb_size_warn: String, + pub mon_force_quorum_join: String, + pub paxos_stash_full_interval: String, + pub paxos_max_join_drift: String, + pub paxos_propose_interval: String, + pub paxos_min_wait: String, + pub paxos_min: String, + pub paxos_trim_min: String, + pub paxos_trim_max: String, + pub paxos_service_trim_min: String, + pub paxos_service_trim_max: String, + pub paxos_kill_at: String, + pub clock_offset: String, + pub auth_cluster_required: String, + pub auth_service_required: String, + pub auth_client_required: String, + pub auth_supported: String, + pub cephx_require_signatures: String, + pub cephx_cluster_require_signatures: String, + pub cephx_service_require_signatures: String, + pub cephx_sign_messages: String, + pub auth_mon_ticket_ttl: String, + pub auth_service_ticket_ttl: String, + pub auth_debug: String, + pub mon_client_hunt_interval: String, + pub mon_client_ping_interval: String, + pub mon_client_ping_timeout: String, + pub mon_client_hunt_interval_backoff: String, + pub mon_client_hunt_interval_max_multiple: String, + pub mon_client_max_log_entries_per_message: String, + pub mon_max_pool_pg_num: String, + pub mon_pool_quota_warn_threshold: String, + pub mon_pool_quota_crit_threshold: String, + pub client_cache_size: String, + pub client_cache_mid: String, + pub client_use_random_mds: String, + pub client_mount_timeout: String, + pub client_tick_interval: String, + pub client_trace: String, + pub client_readahead_min: String, + pub client_readahead_max_bytes: String, + pub client_readahead_max_periods: String, + pub client_snapdir: String, + pub client_mountpoint: String, + pub client_notify_timeout: String, + pub osd_client_watch_timeout: String, + pub client_caps_release_delay: String, + pub client_oc: String, + pub client_oc_size: String, + pub client_oc_max_dirty: String, + pub client_oc_target_dirty: String, + pub client_oc_max_dirty_age: String, + pub client_oc_max_objects: String, + pub client_debug_force_sync_read: String, + pub client_debug_inject_tick_delay: String, + pub client_max_inline_size: String, + pub fuse_use_invalidate_cb: String, + pub fuse_allow_other: String, + pub fuse_default_permissions: String, + pub fuse_big_writes: String, + pub fuse_atomic_o_trunc: String, + pub fuse_debug: String, + pub fuse_multithreaded: String, + pub crush_location: String, + pub objecter_tick_interval: String, + pub objecter_timeout: String, + pub objecter_inflight_op_bytes: String, + pub objecter_inflight_ops: String, + pub journaler_allow_split_entries: String, + pub journaler_write_head_interval: String, + pub journaler_prefetch_periods: String, + pub journaler_prezero_periods: String, + pub journaler_batch_interval: String, + pub journaler_batch_max: String, + pub mds_data: String, + pub mds_max_file_size: String, + pub mds_cache_size: String, + pub mds_cache_mid: String, + pub mds_mem_max: String, + pub mds_dir_max_commit_size: String, + pub mds_decay_halflife: String, + pub mds_beacon_interval: String, + pub mds_beacon_grace: String, + pub mds_enforce_unique_name: String, + pub mds_blacklist_interval: String, + pub mds_session_timeout: String, + pub mds_freeze_tree_timeout: String, + pub mds_session_autoclose: String, + pub mds_reconnect_timeout: String, + pub mds_tick_interval: String, + pub mds_dirstat_min_interval: String, + pub mds_scatter_nudge_interval: String, + pub mds_client_prealloc_inos: String, + pub mds_early_reply: String, + pub mds_default_dir_hash: String, + pub mds_log: String, + pub mds_log_skip_corrupt_events: String, + pub mds_log_max_events: String, + pub mds_log_segment_size: String, + pub mds_log_max_segments: String, + pub mds_log_max_expiring: String, + pub mds_bal_sample_interval: String, + pub mds_bal_replicate_threshold: String, + pub mds_bal_unreplicate_threshold: String, + pub mds_bal_frag: String, + pub mds_bal_split_size: String, + pub mds_bal_split_rd: String, + pub mds_bal_split_wr: String, + pub mds_bal_split_bits: String, + pub mds_bal_merge_size: String, + pub mds_bal_merge_rd: String, + pub mds_bal_merge_wr: String, + pub mds_bal_interval: String, + pub mds_bal_fragment_interval: String, + pub mds_bal_idle_threshold: String, + pub mds_bal_max: String, + pub mds_bal_max_until: String, + pub mds_bal_mode: String, + pub mds_bal_min_rebalance: String, + pub mds_bal_min_start: String, + pub mds_bal_need_min: String, + pub mds_bal_need_max: String, + pub mds_bal_midchunk: String, + pub mds_bal_minchunk: String, + pub mds_bal_target_removal_min: String, + pub mds_bal_target_removal_max: String, + pub mds_replay_interval: String, + pub mds_shutdown_check: String, + pub mds_thrash_exports: String, + pub mds_thrash_fragments: String, + pub mds_dump_cache_on_map: String, + pub mds_dump_cache_after_rejoin: String, + pub mds_verify_scatter: String, + pub mds_debug_scatterstat: String, + pub mds_debug_frag: String, + pub mds_debug_auth_pins: String, + pub mds_debug_subtrees: String, + pub mds_kill_mdstable_at: String, + pub mds_kill_export_at: String, + pub mds_kill_import_at: String, + pub mds_kill_link_at: String, + pub mds_kill_rename_at: String, + pub mds_kill_openc_at: String, + pub mds_kill_journal_at: String, + pub mds_kill_journal_expire_at: String, + pub mds_kill_journal_replay_at: String, + pub mds_kill_create_at: String, + pub mds_open_remote_link_mode: String, + pub mds_inject_traceless_reply_probability: String, + pub mds_wipe_sessions: String, + pub mds_wipe_ino_prealloc: String, + pub mds_skip_ino: String, + pub max_mds: String, + pub mds_standby_for_name: String, + pub mds_standby_for_rank: String, + pub mds_standby_replay: String, + pub osd_compact_leveldb_on_mount: String, + pub osd_max_backfills: String, + pub osd_backfill_full_ratio: String, + pub osd_backfill_retry_interval: String, + pub osd_agent_max_ops: String, + pub osd_agent_min_evict_effort: String, + pub osd_agent_quantize_effort: String, + pub osd_agent_delay_time: String, + pub osd_agent_hist_halflife: String, + pub osd_agent_slop: String, + pub osd_uuid: String, + pub osd_data: String, + pub osd_journal: String, + pub osd_journal_size: String, + pub osd_max_write_size: String, + pub osd_max_pgls: String, + pub osd_client_message_size_cap: String, + pub osd_client_message_cap: String, + pub osd_pg_bits: String, + pub osd_pgp_bits: String, + pub osd_crush_chooseleaf_type: String, + pub osd_pool_default_crush_rule: String, + pub osd_pool_default_crush_replicated_ruleset: String, + pub osd_pool_erasure_code_stripe_width: String, + pub osd_pool_default_size: String, + pub osd_pool_default_min_size: String, + pub osd_pool_default_pg_num: String, + pub osd_pool_default_pgp_num: String, + pub osd_pool_default_erasure_code_directory: String, + pub osd_pool_default_erasure_code_profile: String, + pub osd_erasure_code_plugins: String, + pub osd_pool_default_flags: String, + pub osd_pool_default_flag_hashpspool: String, + pub osd_pool_default_hit_set_bloom_fpp: String, + pub osd_pool_default_cache_target_dirty_ratio: String, + pub osd_pool_default_cache_target_full_ratio: String, + pub osd_pool_default_cache_min_flush_age: String, + pub osd_pool_default_cache_min_evict_age: String, + pub osd_hit_set_min_size: String, + pub osd_hit_set_max_size: String, + pub osd_hit_set_namespace: String, + pub osd_tier_default_cache_mode: String, + pub osd_tier_default_cache_hit_set_count: String, + pub osd_tier_default_cache_hit_set_period: String, + pub osd_tier_default_cache_hit_set_type: String, + pub osd_map_dedup: String, + pub osd_map_max_advance: String, + pub osd_map_cache_size: String, + pub osd_map_message_max: String, + pub osd_map_share_max_epochs: String, + pub osd_op_threads: String, + pub osd_peering_wq_batch_size: String, + pub osd_op_pq_max_tokens_per_priority: String, + pub osd_op_pq_min_cost: String, + pub osd_disk_threads: String, + pub osd_disk_thread_ioprio_class: String, + pub osd_disk_thread_ioprio_priority: String, + pub osd_recovery_threads: String, + pub osd_recover_clone_overlap: String, + pub osd_recover_clone_overlap_limit: String, + pub osd_backfill_scan_min: String, + pub osd_backfill_scan_max: String, + pub osd_op_thread_timeout: String, + pub osd_recovery_thread_timeout: String, + pub osd_snap_trim_thread_timeout: String, + pub osd_snap_trim_sleep: String, + pub osd_scrub_thread_timeout: String, + pub osd_scrub_finalize_thread_timeout: String, + pub osd_scrub_invalid_stats: String, + pub osd_remove_thread_timeout: String, + pub osd_command_thread_timeout: String, + pub osd_age: String, + pub osd_age_time: String, + pub osd_heartbeat_addr: String, + pub osd_heartbeat_interval: String, + pub osd_heartbeat_grace: String, + pub osd_heartbeat_min_peers: String, + pub osd_pg_max_concurrent_snap_trims: String, + pub osd_heartbeat_min_healthy_ratio: String, + pub osd_mon_heartbeat_interval: String, + pub osd_mon_report_interval_max: String, + pub osd_mon_report_interval_min: String, + pub osd_pg_stat_report_interval_max: String, + pub osd_mon_ack_timeout: String, + pub osd_default_data_pool_replay_window: String, + pub osd_preserve_trimmed_log: String, + pub osd_auto_mark_unfound_lost: String, + pub osd_recovery_delay_start: String, + pub osd_recovery_max_active: String, + pub osd_recovery_max_single_start: String, + pub osd_recovery_max_chunk: String, + pub osd_copyfrom_max_chunk: String, + pub osd_push_per_object_cost: String, + pub osd_max_push_cost: String, + pub osd_max_push_objects: String, + pub osd_recovery_forget_lost_objects: String, + pub osd_max_scrubs: String, + pub osd_scrub_load_threshold: String, + pub osd_scrub_min_interval: String, + pub osd_scrub_max_interval: String, + pub osd_scrub_chunk_min: String, + pub osd_scrub_chunk_max: String, + pub osd_scrub_sleep: String, + pub osd_deep_scrub_interval: String, + pub osd_deep_scrub_stride: String, + pub osd_scan_list_ping_tp_interval: String, + pub osd_auto_weight: String, + pub osd_class_dir: String, + pub osd_open_classes_on_start: String, + pub osd_check_for_log_corruption: String, + pub osd_use_stale_snap: String, + pub osd_rollback_to_cluster_snap: String, + pub osd_default_notify_timeout: String, + pub osd_kill_backfill_at: String, + pub osd_pg_epoch_persisted_max_stale: String, + pub osd_min_pg_log_entries: String, + pub osd_max_pg_log_entries: String, + pub osd_op_complaint_time: String, + pub osd_command_max_records: String, + pub osd_op_log_threshold: String, + pub osd_verify_sparse_read_holes: String, + pub osd_debug_drop_ping_probability: String, + pub osd_debug_drop_ping_duration: String, + pub osd_debug_drop_pg_create_probability: String, + pub osd_debug_drop_pg_create_duration: String, + pub osd_debug_drop_op_probability: String, + pub osd_debug_op_order: String, + pub osd_debug_verify_snaps_on_info: String, + pub osd_debug_verify_stray_on_activate: String, + pub osd_debug_skip_full_check_in_backfill_reservation: String, + pub osd_debug_reject_backfill_probability: String, + pub osd_enable_op_tracker: String, +} + +fn main() {}