Refactoring Commands
abstractautoretypebitcast_retypebytestr_to_strcanonicalize_externscanonicalize_structschar_literalsclear_markscommitconvert_cast_as_ptrconvert_format_argsconvert_printfscopy_markscreate_itemdelete_itemsdelete_marksfix_unused_unsafefold_let_assignfunc_to_methodgeneralize_itemsionizelet_x_uninitializedlink_funcslink_incomplete_typesmark_arg_usesmark_callersmark_field_usesmark_pub_in_modmark_related_typesmark_usesownership_annotateownership_mark_pointersownership_split_variantspick_nodeprint_marksprint_spansreconstruct_for_rangereconstruct_whileremove_null_terminatorremove_redundant_castsremove_redundant_let_typesremove_unused_labelsrename_items_regexrename_marksrename_structrename_unnamedreoganize_definitionsreplace_itemsretype_argumentretype_returnretype_staticrewrite_exprrewrite_stmtsrewrite_tyselectselect_phase2set_mutabilityset_visibilitysink_letssink_unsafestatic_collect_to_structstatic_to_localstatic_to_local_refstruct_assign_to_updatestruct_merge_updatestest_analysis_ownershiptest_analysis_type_eqtest_debug_calleestest_f_plus_onetest_insert_remove_argstest_one_plus_onetest_reflecttest_replace_stmtstest_typeck_looptype_fix_rulesuninit_to_defaultwrap_apiwrap_externwrapping_arith_to_normal
abstract
Usage: abstract SIG PAT [BODY]
Replace all instances of pat with calls to a new function whose name and signature is given
by 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 captured
exprs and types are passed as parameters when building the new call expression. The body of
the 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's
name 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, propagating
changes and inserting casts when possible to satisfy type checking. Multiple
simultaneous retypings can be specified in this command as separate
arguments. 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 and
new types. (This implies that the original type and its replacement must be
transmutable to each other.)
bytestr_to_str
Usage: bytestr_to_str
Marks: target
Convert bytestring literal expressions marked target to string literal
expressions.
Note the mark must be placed on the expression, as it is currently difficult to mark a literal node.
canonicalize_externs
Usage: canonicalize_externs MOD_PATH
Marks: target
Replace foreign items ("externs") with references to externs in a different crate or module.
For each foreign fn or static marked target, if a foreign item with the
same symbol exists in the module at MOD_PATH (which can be part of an
external crate), it deletes the marked foreign item and replaces all its uses
with uses of the matching foreign item in MOD_PATH. If a replacement item
has a different type than the original, it also inserts the necessary casts at
each use of the item.
canonicalize_structs
Usage: canonicalize_structs
Marks: target
For each type definition marked target, delete all other type definitions
with 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 #includes 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 the
target type is not visible throughout the crate, this may introduce compile
errors.
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), then read 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 once proves 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
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 the
format args. Replace both the format string and the args with an invocation of the Rust
format_args! macro.
This transformation applies casts to the remaining arguments to account for differences in
argument conversion behavior between C-style and Rust-style string formatting. However, it
does not attempt to convert the format_args! output into something compatible with the
original C function. This results in a type error, so this pass should usually be followed up
by 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 running
convert_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 accepts
the std::fmt::Arguments produced by format_args!.
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 first
child) or after (as a sibling) of the AST node bearing MARK (default: target). Supports
adding items to both mods 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 mods 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 lets 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, replacing
the 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 type
of 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 marked
target, 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, and
passing the type variable VAR when used inside a target item.
If TY is not provided, it defaults to a copy of the first type annotation
that 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 generated
enums 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 to
union variables to assign one of the new enum variants, and updates uses of
union 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;), add
mem::uninitialized() as an initializer expression.
link_funcs
Usage: link_funcs
Link up function declarations and definitions with matching symbols across
modules. For every foreign fn whose symbol matches a fn definition
elsewhere in the program, it replaces all uses of the foreign fn with a
direct 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 the program, it replaces all uses of the foreign type with the type definition, and deletes 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 expressions
passed 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 call
expressions 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 expressions
that 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 same
type 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 are
related, because changing these annotations to two unequal types
would produce a type error. But the i32 annotation on y is
unrelated, 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 that
definition. 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 inferred
ownership 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 results
of 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 multiple
monomorphic 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 all exprs, pats, tys, stmts, and items.
reconstruct_for_range
Usage: reconstruct_for_range
Replaces i = start; while i < end { ...; i += step; } with
for 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 literal
expressions.
Note the mark must be placed on the expression, as it is currently difficult to mark a literal node.
remove_redundant_casts
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 single
struct at a time.
rename_unnamed
Usage: rename_unnamed
Renames all Idents that have unnamed throughout the Crate, so the Crate can
have a completely unique naming scheme for Anonymous Types.
This command should be ran after transpiling using c2rust-transpile, and
is also mainly to be used when doing the reorganize_definition pass; although
this pass can run on any c2rust-transpiled 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
replace_items
Usage: replace_items
Marks: target, repl
Replace all uses of items marked target with reference to the item marked
repl, 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 of
the argument at call sites and within the function body.
WRAP should contain an expression placeholder __old, and should convert
__old from the argument's original type to NEW_TY.
UNWRAP should contain an expression placeholder __new, and should perform
the 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 to
NEW_TY, and use WRAP and UNWRAP to convert values to and from the
original type of the argument at call sites and within the function body.
WRAP should contain an expression placeholder __old, and should convert
__old from the function's original return type to NEW_TY.
UNWRAP should contain an expression placeholder __new, and should perform
the 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) to
convert 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 its initializer expression, the original assigned value is wrapped (as__old) inREV_CONV_ASSIGNto produce a value of typeNEW_TY.CONV_RVAL: In rvalue contexts, the static is wrapped (as__new) inCONV_RVALto produce a value of the static's old type.CONV_LVALandCONV_LVAL_MUTare similar toCONV_RVAL, but for immutable and mutable lvalue contexts respectively. Especially forCONV_LVAL_MUT, the result of wrapping should be an lvalue expression (such as a dereference or field access), not a temporary, as otherwise updates to the static could be lost.CONV_LVAL_MUTis not required for immutable statics, 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 to
capture nodes from the matched AST, and REPL can refer to those same
placeholders to substitute in the captured nodes. See the matcher module for
details 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 same
behavior.
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 is
substituted for $e in $e + $e, producing the final expression x + x.
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 and
REPL are both Rust types. PAT can use placeholders to capture nodes from
the matched AST, and REPL can refer to those same placeholders to substitute
in the captured nodes. See the matcher module for details 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 same
behavior.
See the documentation for rewrite_expr for an example of this style of
rewriting.
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 on
select 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 either
imm 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 Rust
visibility 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's declaration to the innermost block containing all its uses.
"Trivial" is currently defined as no initializer (let x;) or an initializer
without any side effects. This transform requires trivial assignments to avoid
reordering 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 eliminated
from 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, and initializer expression, then delete it. - Generate a new struct definition named
STRUCT. For each marked static, include a field ofSTRUCTwith the same name and type as the static. - Generate a new
static mutnamedVARwhose type isSTRUCT. Initialize it using the initializer expressions for the marked statics. - For each marked static
foo, replace uses offoowithVAR.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 new
local 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 with
uses of newly-introduced reference arguments. Afterward, no user function
directly accesses any target static. At call sites of user functions, a
reference to the original static is passed in for each new argument if the
caller is not itself a user function; otherwise, the caller's own reference
argument is passed through. Note this sometimes results in functions gaining
arguments corresponding to statics that the function itself does not use, but
that 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 debug
RefactorCtxt::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 in
INS (a comma-separated list of integers), then delete the arguments whose
original 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 and AST re-analysis code.
type_fix_rules
Usage: type_fix_rules RULE...
Attempts to fix type errors in the crate using the provided rules. Each rule
has the form "ectx, actual_ty, expected_ty => cast_expr".
ectxis one ofrval,lval,lval_mut, or*, and determines in what kinds of expression contexts the rule applies.actual_tyis a pattern to be matched against the (reflected) actual expression type.expected_tyis a pattern to be matched against the (reflected) expected expression type.cast_expris a template for generating a cast expression.
For expressions in context ectx, whose actual type matches actual_ty and whose
expected type matches expected_ty (and where actual != expected), the expr is substituted
into cast_expr to replace the original expr with one of the expected type. During
substitution, cast_expr has access to variables captured from both actual_ty and
expected_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 an
appropriate 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_wrapperwithfoo's old ABI and an#[export_name="foo"]attribute.
Calls to foo are left unchanged. The result is that callers from C use the
wrapper function, while internal calls use foo directly, and the signature of
foo 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 the
module marked dest, and rewrite all uses of the function to call the wrapper
instead.
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 marked
dest:
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 the
original (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 arithmetic
operators. For example, replace x.wrapping_add(y) with x + y.