- Refactoring Commands
- abstract
- autoretype
- bitcast_retype
- bytestr_to_str
- canonicalize_externs
- canonicalize_structs
- char_literals
- clear_marks
- commit
- convert_cast_as_ptr
- convert_format_args
- convert_printfs
- copy_marks
- create_item
- delete_items
- delete_marks
- fix_unused_unsafe
- fold_let_assign
- func_to_method
- generalize_items
- ionize
- let_x_uninitialized
- link_funcs
- link_incomplete_types
- mark_arg_uses
- mark_callers
- mark_field_uses
- mark_pub_in_mod
- mark_related_types
- mark_uses
- ownership_annotate
- ownership_mark_pointers
- ownership_split_variants
- pick_node
- print_marks
- print_spans
- reconstruct_for_range
- reconstruct_while
- remove_null_terminator
- remove_redundant_casts
- remove_redundant_let_types
- remove_unused_labels
- rename_items_regex
- rename_marks
- rename_struct
- rename_unnamed
- reoganize_definitions
- replace_items
- retype_argument
- retype_return
- retype_static
- rewrite_expr
- rewrite_stmts
- rewrite_ty
- select
- select_phase2
- set_mutability
- set_visibility
- sink_lets
- sink_unsafe
- static_collect_to_struct
- static_to_local
- static_to_local_ref
- struct_assign_to_update
- struct_merge_updates
- test_analysis_ownership
- test_analysis_type_eq
- test_debug_callees
- test_f_plus_one
- test_insert_remove_args
- test_one_plus_one
- test_reflect
- test_replace_stmts
- test_typeck_loop
- type_fix_rules
- uninit_to_default
- wrap_api
- wrap_extern
- wrapping_arith_to_normal
Refactoring Commands
abstract
Usage: abstract SIG PAT [BODY]
Replace all instances of pat
with calls to a new function whose name and signature is givenby sig
. Example:
Input:
1 + 2
After running abstract 'add(x: u32, y: u32) -> u32' 'x + y'
:
add(1, 2)
// Elsewhere:
fn add(x: u32, y: u32) -> u32 { x + y }
All type and value parameter names in sig
act as bindings when matching pat
. The capturedexprs and types are passed as parameters when building the new call expression. The body ofthe function is body
, if provided, otherwise pat
itself.
Non-ident patterns in sig
are not supported. It is also an error for any type parameter'sname to collide with any value parameter.
If matching with pat
fails to capture expressions for any of the value parameters of sig
,it is an error. If it fails to capture for a type parameter, the parameter is filled in with_
(infer).
autoretype
Usage: autoretype 'A: T'…
Marks: A
… (specified in command)
Change the type of nodes with mark A
to the new type T
, propagatingchanges and inserting casts when possible to satisfy type checking. Multiplesimultaneous retypings can be specified in this command as separatearguments. Each argument should be of the form: label: type
where label
is a mark label and type
can be parsed as a valid rust type.
bitcast_retype
Usage: bitcast_retype PAT REPL
Marks: may read marks depending on PAT
For every type in the crate matching PAT
, change the type to REPL
. PAT
and REPL
are types, and can use placeholders in the manner of rewrite_ty
.For each definitions whose type has changed, it also inserts mem::transmute
calls at each use of the definition to fix discrepancies between the old andnew types. (This implies that the original type and its replacement must betransmutable to each other.)
bytestr_to_str
Usage: bytestr_to_str
Marks: target
Convert bytestring literal expressions marked target
to string literalexpressions.
Note the mark must be placed on the expression, as it is currently difficult tomark a literal node.
canonicalize_externs
Usage: canonicalize_externs MOD_PATH
Marks: target
Replace foreign items ("externs") with references to externsin a different crate or module.
For each foreign fn
or static
marked target
, if a foreign item with thesame symbol exists in the module at MOD_PATH
(which can be part of anexternal crate), it deletes the marked foreign item and replaces all its useswith uses of the matching foreign item in MOD_PATH
. If a replacement itemhas a different type than the original, it also inserts the necessary casts ateach use of the item.
canonicalize_structs
Usage: canonicalize_structs
Marks: target
For each type definition marked target
, delete all other type definitionswith the same name, and replace their uses with uses of the target
type.
This only works when all the identically-named types have the same definition,such as when all are generated from #include
s of the same C header.
Example:
mod a {
pub struct Foo { ... } // Foo: target
}
mod b {
struct Foo { ... } // same as ::a::Foo
unsafe fn use_foo(x: &Foo) { ... }
}
After running canonicalize_structs
:
mod a {
pub struct Foo { ... }
}
mod b {
// 1. `struct Foo` has been deleted
// 2. `use_foo` now references `::a::Foo` directly
unsafe fn use_foo(x: &::a::Foo) { ... }
}
Note that this transform does not check or adjust item visibility. If thetarget
type is not visible throughout the crate, this may introduce compileerrors.
char_literals
Obsolete - the translator now does this automatically.
Usage: char_literals
Replace integer literals cast to libc::c_char
with actual char literals.For example, replaces 65 as libc::c_char
with 'A' as libc::c_char
.
clear_marks
Usage: clear_marks
Marks: clears all marks
Remove all marks from all nodes.
commit
Usage: commit
Write the current crate to disk (by rewriting the original source files), thenread it back in, clearing all mark. This can be useful as a "checkpoint"between two sets of transformations, if applying both sets of changes at onceproves to be too much for the rewriter.
This is only useful when the rewrite mode is inplace
. Otherwise the "write"part of the operation won't actually change the original source files, and the"read" part will revert the crate to its original form.
convert_cast_as_ptr
](https://c2rust.com/manual/c2rust-refactor/#convert_cast_as_ptr)[
convert_format_args
Usage: convert_format_args
Marks: target
For each function call, if one of its argument expressions is marked target
,then parse that argument as a printf
format string, with the subsequent arguments as theformat args. Replace both the format string and the args with an invocation of the Rustformat_args!
macro.
This transformation applies casts to the remaining arguments to account for differences inargument conversion behavior between C-style and Rust-style string formatting. However, itdoes not attempt to convert the format_args!
output into something compatible with theoriginal C function. This results in a type error, so this pass should usually be followed upby an additional rewrite to change the function being called.
Example:
printf("hello %d\n", 123);
If the string "hello %d\n"
is marked target
, then runningconvert_format_string
will replace this call with
printf(format_args!("hello {:}\n", 123 as i32));
At this point, it would be wise to replace the printf
expression with a function that acceptsthe std::fmt::Arguments
produced by format_args!
.
convert_printfs
](https://c2rust.com/manual/c2rust-refactor/#convert_printfs)[
copy_marks
Usage: copy_marks OLD_MARK NEW_MARK
Marks: reads OLD_MARK
; sets NEW_MARK
For every node bearing OLD_MARK
, also apply NEW_MARK
.
create_item
Usage: create_item ITEMS <inside/after> [MARK]
Marks: MARK
/target
Parse ITEMS
as item definitions, and insert the parsed items either inside
(as the firstchild) or after
(as a sibling) of the AST node bearing MARK
(default: target
). Supportsadding items to both mod
s and blocks.
Note that other itemlikes, such as impl and trait items, are not handled by this command.
delete_items
Usage: delete_items
Marks: target
Delete all items marked target
from the AST. This handles items in both mod
s and blocks,but doesn't handle other itemlikes.
delete_marks
Usage: delete_marks MARK
Marks: clears MARK
Remove MARK
from every node where it appears.
fix_unused_unsafe
Usage: fix_unused_unsafe
Find unused unsafe
blocks and turn them into ordinary blocks.
fold_let_assign
Usage: fold_let_assign
Fold together let
s with no initializer or a trivial one, and subsequent assignments.For example, replace let x; x = 10;
with let x = 10;
.
func_to_method
Usage: func_to_method
Marks: target
, dest
Turn functions marked target
into static methods (no self
) in the impl
block marked dest
.Turn functions that have an argument marked target
into methods, replacingthe named argument with self
.Rewrite all uses of marked functions to call the new method versions.
Marked arguments of type T
, &T
, and &mut T
(where T
is the Self
typeof the dest
impl
) will be converted to self
, &self
, and &mut self
respectively.
generalize_items
Usage: generalize_items VAR [TY]
Marks: target
Replace marked types with generic type parameters.
Specifically: add a new type parameter called VAR
to each item markedtarget
, replacing type annotations inside that item that are marked target
with uses of the type parameter. Also update all uses of target
items,passing TY
as the new type argument when used inside a non-target
item, andpassing the type variable VAR
when used inside a target
item.
If TY
is not provided, it defaults to a copy of the first type annotationthat was replaced with VAR
.
Example:
struct Foo { // Foo: target
x: i32, // i32: target
y: i32,
}
fn f(foo: Foo) { ... } // f: target
fn main() {
f(...);
}
After running generalize_items T
:
// 1. Foo gains a new type parameter `T`
struct Foo<T> {
// 2. Marked type annotations become `T`
x: T,
y: i32,
}
// 3. `f` gains a new type parameter `T`, and passes
// it through to uses of `Foo`
fn f<T>(foo: Foo<T>) { ... }
struct Bar<T> {
foo: Foo<T>,
}
fn main() {
// 4. Uses outside target items use `i32`, the
// first type that was replaced with `T`.
f::<i32>(...);
}
ionize
Usage: ionize
Marks: target
Convert each union marked target
to a type-safe Rust enum. The generatedenums will have as_variant
and as_variant_mut
methods for each union field,which panic if the enum is not the named variant. Also updates assignments tounion variables to assign one of the new enum variants, and updates uses ofunion fields to call the new methods instead.
let_x_uninitialized
Obsolete - the translator now does this automatically.
Usage: let_x_uninitialized
For each local variable that is uninitialized (let x;
), addmem::uninitialized()
as an initializer expression.
link_funcs
Usage: link_funcs
Link up function declarations and definitions with matching symbols acrossmodules. For every foreign fn
whose symbol matches a fn
definitionelsewhere in the program, it replaces all uses of the foreign fn
with adirect call of the fn
definition, and deletes the foreign fn
.
Example:
mod a {
#[no_mangle]
unsafe extern "C" fn foo() { ... }
}
mod b {
extern "C" {
// This resolves to `a::foo` during linking.
fn foo();
}
unsafe fn use_foo() {
foo();
}
}
After running link_funcs
:
mod a {
#[no_mangle]
unsafe extern "C" fn foo() { ... }
}
mod b {
// 1. Foreign fn `foo` has been deleted
unsafe fn use_foo() {
// 2. `use_foo` now calls `foo` directly
::a::foo();
}
}
link_incomplete_types
Usage: link_incomplete_types
Link up type declarations and definitions with matching names across modules.For every foreign type whose name matches a type definition elsewhere in theprogram, it replaces all uses of the foreign type with the type definition, anddeletes the foreign type.
Example:
mod a {
struct Foo { ... }
}
mod b {
extern "C" {
type Foo;
}
unsafe fn use_foo(x: &Foo) { ... }
}
After running link_incomplete_types
:
mod a {
struct Foo { ... }
}
mod b {
// 1. Foreign fn `Foo` has been deleted
// 2. `use_foo` now references `Foo` directly
unsafe fn use_foo(x: &::a::Foo) { ... }
}
mark_arg_uses
Usage: mark_arg_uses ARG_IDX MARK
Marks: reads MARK
; sets/clears MARK
For every fn
definition bearing MARK
, apply MARK
to expressionspassed in as argument ARG_IDX
in calls to that function.Removes MARK
from the original function.
mark_callers
Usage: mark_callers MARK
Marks: reads MARK
; sets/clears MARK
For every fn
definition bearing MARK
, apply MARK
to callexpressions that call that function.Removes MARK
from the original function.
mark_field_uses
Obsolete - use select
with match_expr!(typed!(::TheStruct).field)
instead
Usage: mark_field_uses FIELD MARK
Marks: reads MARK
; sets/clears MARK
For every struct definition bearing MARK
, apply MARK
to expressionsthat use FIELD
of that struct. Removes MARK
from the original struct.
mark_pub_in_mod
Obsolete - use select
instead.
Usage: mark_pub_in_mod MARK
Marks: reads MARK
; sets MARK
In each mod
bearing MARK
, apply MARK
to every public item in the module.
mark_related_types
Usage: mark_related_types [MARK]
Marks: MARK
/target
For each type annotation bearing MARK
(default: target
),apply MARK
to all other type annotations that must be the sametype according to (a simplified version of) Rust's typing rules.
For example, in this code:
fn f(x: i32, y: i32) -> i32 {
x
}
The i32
annotations on x
and the return type of f
arerelated, because changing these annotations to two unequal typeswould produce a type error. But the i32
annotation on y
isunrelated, and can be changed independently of the other two.
mark_uses
Usage: mark_uses MARK
Marks: reads MARK
; sets/clears MARK
For every top-level definition bearing MARK
, apply MARK
to uses of thatdefinition. Removes MARK
from the original definitions.
ownership_annotate
Usage: ownership_annotate [MARK]
Marks: MARK
/target
Run ownership analysis on functions bearing MARK
(default: target
),and add attributes to each function describing its inferredownership properties.See analysis/ownership/README.md
for details on ownership inference.
ownership_mark_pointers
Usage: ownership_mark_pointers [MARK]
Marks: reads MARK
/target
; sets ref
, mut
, and box
Run ownership analysis on functions bearing MARK
(default: target
),then for pointer type appearing in their argument and return types,apply one of the marks ref
, mut
, or box
, reflecting the resultsof the ownership analysis.See analysis/ownership/README.md
for details on ownership inference.
ownership_split_variants
Usage: ownership_split_variants [MARK]
Marks: MARK
/target
Run ownership analysis on functions bearing MARK
(default: target
),and split each ownership-polymorphic functions into multiplemonomorphic variants.See analysis/ownership/README.md
for details on ownership inference.
pick_node
Test command - not intended for general use.
Usage: pick_node KIND FILE LINE COL
Find a node of kind KIND
at location FILE:LINE:COL
.If successful, logs the node's ID and span at level info
.
print_marks
Test command - not intended for general use.
Usage: print_marks
Marks: reads all
Logs the ID and label of every mark, at level info
.
print_spans
Test command - not intended for general use.
Usage: print_spans
Print IDs, spans, and pretty-printed source for allexprs, pats, tys, stmts, and items.
reconstruct_for_range
Usage: reconstruct_for_range
Replaces i = start; while i < end { …; i += step; }
withfor i in (start .. end).step_by(step) { …; }
.
reconstruct_while
Obsolete - the translator now does this automatically.
Usage: reconstruct_while
Replaces all instances of loop { if !cond { break; } … }
with while
loops.
remove_null_terminator
Usage: remove_null_terminator
Marks: target
Remove a trailing \0
character from marked string and bytestring literalexpressions.
Note the mark must be placed on the expression, as it is currently difficult tomark a literal node.
remove_redundant_casts
](https://c2rust.com/manual/c2rust-refactor/#remove_redundant_casts)[
remove_redundant_let_types
](https://c2rust.com/manual/c2rust-refactor/#remove_redundant_let_types)[
remove_unused_labels
Usage: remove_unused_labels
Removes loop labels that are not used in a named break
or continue
.
rename_items_regex
Usage: rename_items_regex PAT REPL [FILTER]
Marks: reads FILTER
Replace PAT
(a regular expression) with REPL
in all item names. If FILTER
is provided,only items bearing the FILTER
mark will be renamed.
rename_marks
Usage: rename_marks OLD_MARK NEW_MARK
Marks: reads/clears OLD_MARK
; sets NEW_MARK
For every node bearing OLD_MARK
, remove OLD_MARK
and apply NEW_MARK
.
rename_struct
Obsolete - use rename_items_regex
instead.
Usage: rename_struct NAME
Marks: target
Rename the struct marked target
to NAME
. Only supports renaming a singlestruct at a time.
rename_unnamed
Usage: rename_unnamed
Renames all Ident
s that have unnamed
throughout the Crate
, so the Crate
canhave a completely unique naming scheme for Anonymous Types.This command should be ran after transpiling using c2rust-transpile
, andis also mainly to be used when doing the reorganize_definition
pass; althoughthis pass can run on any c2rust-transpile
d project.
Example:
pub mod foo {
pub struct unnamed {
a: i32
}
}
pub mod bar {
pub struct unnamed {
b: usize
}
}
Becomes:
pub mod foo {
pub struct unnamed {
a: i32
}
}
pub mod bar {
pub struct unnamed_1 {
b: usize
}
}
reoganize_definitions
](https://c2rust.com/manual/c2rust-refactor/#reoganize_definitions)[
replace_items
Usage: replace_items
Marks: target
, repl
Replace all uses of items marked target
with reference to the item markedrepl
, then remove all target
items.
retype_argument
Usage: retype_argument NEW_TY WRAP UNWRAP
Marks: target
For each argument marked target
, change the type of the argument to NEW_TY
,and use WRAP
and UNWRAP
to convert values to and from the original type ofthe argument at call sites and within the function body.
WRAP
should contain an expression placeholder old
, and should convertold
from the argument's original type to NEW_TY
.UNWRAP
should contain an expression placeholder __new
, and should performthe opposite conversion.
retype_return
Usage: retype_return NEW_TY WRAP UNWRAP
Marks: target
For each function marked target
, change the return type of the function toNEW_TY
, and use WRAP
and UNWRAP
to convert values to and from theoriginal type of the argument at call sites and within the function body.
WRAP
should contain an expression placeholder old
, and should convertold
from the function's original return type to NEW_TY
.UNWRAP
should contain an expression placeholder __new
, and should performthe opposite conversion.
retype_static
Usage: retype_static NEW_TY REV_CONV_ASSIGN CONV_RVAL CONV_LVAL [CONV_LVAL_MUT]
Marks: target
For each static marked target
, change the type of the static to NEW_TY
,using the remaining arguments (which are all all expression templates) toconvert between the old and new types at the definition and use sites.
The expression arguments are used as follows:
REV_CONV_ASSIGN
: In direct assignments to the static and in itsinitializer expression, the original assigned value is wrapped (as__old
)inREV_CONV_ASSIGN
to produce a value of typeNEW_TY
.CONV_RVAL
: In rvalue contexts, the static is wrapped (as__new
) inCONV_RVAL
to produce a value of the static's old type.CONV_LVAL
andCONV_LVAL_MUT
are similar toCONV_RVAL
, but forimmutable and mutable lvalue contexts respectively. Especially forCONV_LVAL_MUT
, the result of wrapping should be an lvalue expression (suchas a dereference or field access), not a temporary, as otherwise updates tothe static could be lost.CONV_LVAL_MUT
is not required for immutablestatics, which cannot appear in mutable lvalue contexts.
rewrite_expr
Usage: rewrite_expr PAT REPL [FILTER]
Marks: reads FILTER
, if set; may read other marks depending on PAT
For every expression in the crate matching PAT
, replace it with REPL
.PAT
and REPL
are both Rust expressions. PAT
can use placeholders tocapture nodes from the matched AST, and REPL
can refer to those sameplaceholders to substitute in the captured nodes. See the matcher
module fordetails on AST pattern matching.
If FILTER
is provided, only expressions marked FILTER
will be rewritten.This usage is obsolete - change PAT
to marked!(PAT, FILTER)
to get the samebehavior.
Example:
fn double(x: i32) -> i32 {
x * 2
}
After running rewrite_expr '$e * 2' '$e + $e'
:
fn double(x: i32) -> i32 {
x + x
}
Here $e 2
matches x
2
, capturing x
as $e
. Then x
issubstituted for $e
in $e + $e
, producing the final expression x + x
.
rewrite_stmts
](https://c2rust.com/manual/c2rust-refactor/#rewrite_stmts)[
rewrite_ty
Usage: rewrite_ty PAT REPL [FILTER]
Marks: reads FILTER
, if set; may read other marks depending on PAT
For every type in the crate matching PAT
, replace it with REPL
. PAT
andREPL
are both Rust types. PAT
can use placeholders to capture nodes fromthe matched AST, and REPL
can refer to those same placeholders to substitutein the captured nodes. See the matcher
module for details on AST patternmatching.
If FILTER
is provided, only expressions marked FILTER
will be rewritten.This usage is obsolete - change PAT
to marked!(PAT, FILTER)
to get the samebehavior.
See the documentation for rewrite_expr
for an example of this style ofrewriting.
select
Usage: select MARK SCRIPT
Marks: sets MARK
; may set/clear other marks depending on SCRIPT
Run node-selection script SCRIPT
, and apply MARK
to the nodes it selects.See select::SelectOp
, select::Filter
, and select::parser
for details onselect script syntax.
select_phase2
Usage: select_phase2 MARK SCRIPT
Marks: sets MARK
; may set/clear other marks depending on SCRIPT
Works like select
, but stops the compiler's analyses before typechecking happens.This means type information will not available, and script commands that refer to it will fail.
set_mutability
Usage: set_mutability MUT
Marks: target
Set the mutability of all items marked target
to MUT
. MUT
is eitherimm
or mut
. This command only affects static
items (including extern statics).
set_visibility
Usage: set_visibility VIS
Marks: target
Set the visibility of all items marked target
to VIS
. VIS
is a Rustvisibility qualifier such as pub
, pub(crate)
, or the empty string.
Doesn't handle struct field visibility, for now.
sink_lets
Usage: sink_lets
For each local variable with a trivial initializer, move the local'sdeclaration to the innermost block containing all its uses.
"Trivial" is currently defined as no initializer (let x;
) or an initializerwithout any side effects. This transform requires trivial assignments to avoidreordering side effects.
sink_unsafe
Usage: sink_unsafe
Marks: target
For functions marked target
, convert unsafe fn f() { … }
into fn () { unsafe { … } }
. Useful once unsafe argument handling has been eliminatedfrom the function.
static_collect_to_struct
Usage: static_collect_to_struct STRUCT VAR
Marks: target
Collect marked statics into a single static struct.
Specifically:
- Find all statics marked
target
. For each one, record its name, type, andinitializer expression, then delete it. - Generate a new struct definition named
STRUCT
. For each marked static,include a field ofSTRUCT
with the same name and type as the static. - Generate a new
static mut
namedVAR
whose type isSTRUCT
. Initializeit using the initializer expressions for the marked statics. - For each marked static
foo
, replace uses offoo
withVAR.foo
. Example:
static mut FOO: i32 = 100;
static mut BAR: bool = true;
unsafe fn f() -> i32 {
FOO
}
After running static_collect_to_struct Globals G
, with both statics marked:
struct Globals {
FOO: i32,
BAR: bool,
}
static mut G: Globals = Globals {
FOO: 100,
BAR: true,
};
unsafe fn f() -> i32 {
G.FOO
}
static_to_local
Usage: static_to_local
Marks: target
Delete each static marked target
. For each function that uses a marked static, insert a newlocal variable definition replicating the marked static.
Example:
static mut FOO: i32 = 100; // FOO: target
unsafe fn f() -> i32 {
FOO
}
unsafe fn g() -> i32 {
FOO + 1
}
After running static_to_local
:
// `FOO` deleted
// `f` gains a new local, replicating `FOO`.
unsafe fn f() -> i32 {
let FOO: i32 = 100;
FOO
}
// If multiple functions use `FOO`, each one gets its own copy.
unsafe fn g() -> i32 {
let FOO: i32 = 100;
FOO + 1
}
static_to_local_ref
Usage: static_to_local_ref
Marks: target
, user
For each function marked user
, replace uses of statics marked target
withuses of newly-introduced reference arguments. Afterward, no user
functiondirectly accesses any target
static. At call sites of user
functions, areference to the original static is passed in for each new argument if thecaller is not itself a user
function; otherwise, the caller's own referenceargument is passed through. Note this sometimes results in functions gainingarguments corresponding to statics that the function itself does not use, butthat its callees do.
Example:
static mut FOO: i32 = 100; // FOO: target
unsafe fn f() -> i32 { // f: user
FOO
}
unsafe fn g() -> i32 { // g: user
f()
}
unsafe fn h() -> i32 {
g()
}
After running static_to_local_ref
:
static mut FOO: i32 = 100;
// `f` is a `user` that references `FOO`, so it
// gains a new argument `FOO_`.
unsafe fn f(FOO_: &mut i32) -> i32 {
// References to `FOO` are replaced with `*FOO_`
*FOO_
}
// `g` is a `user` that references `FOO` indirectly,
// via fellow `user` `f`.
unsafe fn g(FOO_: &mut i32) -> i32 {
// `g` passes through its own `FOO_` reference
// when calling `f`.
f(FOO_)
}
// `h` is not a `user`, so its signature is unchanged.
unsafe fn h() -> i32 {
// `h` passes in a reference to the original
// static `FOO`.
g(&mut FOO)
}
struct_assign_to_update
Usage: struct_assign_to_update
Replace all struct field assignments with functional update expressions.
Example:
let mut x: S = ...;
x.f = 1;
x.g = 2;
After running struct_assign_to_update
:
let mut x: S = ...;
x = S { f: 1, ..x };
x = S { g: 2, ..x };
struct_merge_updates
Usage: struct_merge_updates
Merge consecutive struct updates into a single update.
Example:
let mut x: S = ...;
x = S { f: 1, ..x };
x = S { g: 2, ..x };
After running struct_assign_to_update
:
let mut x: S = ...;
x = S { f: 1, g: 2, ..x };
test_analysis_ownership
Test command - not intended for general use.
Usage: test_analysis_ownership
Runs the ownership
analysis and dumps the results to stderr.
test_analysis_type_eq
Test command - not intended for general use.
Usage: test_analysis_type_eq
Runs the type_eq
analysis and logs the result (at level info
).
test_debug_callees
Test command - not intended for general use.
Usage: test_debug_callees
Inspect the details of each Call expression. Used to debugRefactorCtxt::opt_callee_info
.
test_f_plus_one
Test command - not intended for general use.
Usage: test_f_plus_one
Replace the expression f(x)
with x + 1
everywhere it appears.
test_insert_remove_args
Test command - not intended for general use.
Usage: test_insert_remove_args INS REM
In each function marked target
, insert new arguments at each index listed inINS
(a comma-separated list of integers), then delete the arguments whoseoriginal indices are listed in REM
.
This is used for testing sequence rewriting of fn
argument lists.
test_one_plus_one
Test command - not intended for general use.
Usage: test_one_plus_one
Replace the expression 2
with 1 + 1
everywhere it appears.
test_reflect
Test command - not intended for general use.
Usage: test_reflect
Applies path and ty reflection on every expr in the program.
test_replace_stmts
Test command - not intended for general use.
Usage: test_replace_stmts OLD NEW
Replace statement(s) OLD
with NEW
everywhere it appears.
test_typeck_loop
Test command - not intended for general use.
Usage: test_typeck_loop
Runs a no-op typechecking loop for three iterations. Used to test the typechecking loop andAST re-analysis code.
type_fix_rules
Usage: type_fix_rules RULE…
Attempts to fix type errors in the crate using the provided rules. Each rulehas the form "ectx, actual_ty, expected_ty => cast_expr"
.
ectx
is one ofrval
,lval
,lval_mut
, or*
, and determines in what kinds ofexpression contexts the rule applies.actual_ty
is a pattern to be matched against the (reflected) actual expression type.expected_ty
is a pattern to be matched against the (reflected) expected expressiontype.cast_expr
is a template for generating a cast expression.
For expressions in context ectx
, whose actual type matches actual_ty
and whoseexpected type matches expected_ty
(and where actual != expected), the expr is substitutedinto cast_expr
to replace the original expr with one of the expected type. Duringsubstitution, cast_expr
has access to variables captured from both actual_ty
andexpected_ty
, as well as __old
containing the original (ill-typed) expression.
uninit_to_default
Obsolete - works around translator problems that no longer exist.
Usage: uninit_to_default
In local variable initializers, replace mem::uninitialized()
with anappropriate default value of the variable's type.
wrap_api
Usage: wrap_api
Marks: target
For each function foo
marked target
:
- Reset the function's ABI to
"Rust"
(the default) - Remove any
#[no_mangle]
or#[export_name]
attributes - Generate a new wrapper function called
foo_wrapper
withfoo
's old ABIand an#[export_name="foo"]
attribute. Calls tofoo
are left unchanged. The result is that callers from C use thewrapper function, while internal calls usefoo
directly, and the signature offoo
can be changed freely without affecting external callers.
wrap_extern
Usage: wrap_extern
Marks: target
, dest
For each foreign function marked target
, generate a wrapper function in themodule marked dest
, and rewrite all uses of the function to call the wrapperinstead.
Example:
extern "C" {
fn foo(x: i32) -> i32;
}
mod wrappers {
// empty
}
fn main() {
let x = unsafe { foo(123) };
}
After transformation, with fn foo
marked target
and mod wrappers
markeddest
:
extern "C" {
fn foo(x: i32) -> i32;
}
mod wrappers {
unsafe fn foo(x: i32) -> i32 {
::foo(x)
}
}
fn main() {
let x = unsafe { ::wrappers::foo(123) };
}
Note that this also replaces the function in expressions that take its address,which may cause problem as the wrapper function has a different type that theoriginal (it lacks the extern "C"
ABI qualifier).
wrapping_arith_to_normal
Usage: wrapping_arith_to_normal
Replace all uses of wrapping arithmetic methods with ordinary arithmeticoperators. For example, replace x.wrapping_add(y)
with x + y
.