一句话:将 Rust 的 Extract Method 重构分解为函数提升与一系列程序修复步骤,并实现工具 REM。
Extract Method 是最成熟、应用最广的自动重构之一,但在 Rust 中可靠实现却因所有权与基于生命周期的类型系统而异常困难。本文对 Rust 程序的 Extract Method 重构做了系统性分解:把它视为「朴素函数提升」与一系列自动程序修复过程的组合,每个变换负责满足 Rust 类型安全的一个方面,逐步使结果程序「更加良类型」,最终产出类型正确的 Rust 程序。修复预言机包括一种新颖的静态过程内所有权分析(为被提取函数的参数推断正确的共享标注)以及 rustc 的生命周期检查器。作者在 IntelliJ IDEA 的 Rust 插件之上实现了工具 REM,并在五个流行 Rust 项目的变更语料上做了广泛评估,表明 REM 能比现有重构工具提取更丰富、语义正确的代码片段,能复现开发者过去手工完成的方法提取,且效率足以支撑交互式开发。
We present a design and implementation of the automated "Extract Method" refactoring for Rust programs. Even though Extract Method is one of the most well-studied and widely used in practice automated refactorings, featured in all major IDEs for all popular programming languages, implementing it soundly for Rust is surprisingly non-trivial due to the restrictions of the Rust's ownership and lifetime-based type system. In this work, we provide a systematic decomposition of the Extract Method refactoring for Rust programs into a series of program transformations, each concerned with satisfying a particular aspect of Rust type safety, eventually producing a well-typed Rust program. Our key discovery is the formulation of Extract Method as a composition of naive function hoisting and a series of automated program repair procedures that progressively make the resulting program "more well-typed" by relying on the corresponding repair oracles. Those oracles include a novel static intra-procedural ownership analysis that infers correct sharing annotations for the extracted function's parameters, and the lifetime checker of rustc, Rust's reference compiler. We implemented our approach in a tool called REM---an automated Extract Method refactoring built on top of IntelliJ IDEA plugin for Rust. Our extensive evaluation on a corpus of changes in five popular Rust projects shows that REM (a) can extract a larger class of feature-rich code fragments into semantically correct functions than other existing refactoring tools, (b) can reproduce method extractions performed manually by human developers in the past, and (c) is efficient enough to be used in interactive development.
@article{paperbot1854,
title = {Adventure of a Lifetime: Extract Method Refactoring for Rust},
author = {Sewen Thy and Andreea Costea and Kiran Gopinathan and Ilya Sergey},
journal = {Proceedings of the ACM on Programming Languages},
volume = {7},
number = {OOPSLA2},
year = {2023},
doi = {10.1145/3622821}
}