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. 1 + 2

After running abstract 'add(x: u32, y: u32) -> u32' 'x + y':

  1. add(1, 2)
  2. // Elsewhere:
  3. 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 labelis 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. PATand REPL are types, and can use placeholders in the manner of rewrite_ty.For each definitions whose type has changed, it also inserts mem::transmutecalls 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 #includes of the same C header.

Example:

  1. mod a {
  2. pub struct Foo { ... } // Foo: target
  3. }
  4. mod b {
  5. struct Foo { ... } // same as ::a::Foo
  6. unsafe fn use_foo(x: &Foo) { ... }
  7. }

After running canonicalize_structs:

  1. mod a {
  2. pub struct Foo { ... }
  3. }
  4. mod b {
  5. // 1. `struct Foo` has been deleted
  6. // 2. `use_foo` now references `::a::Foo` directly
  7. unsafe fn use_foo(x: &::a::Foo) { ... }
  8. }

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:

  1. printf("hello %d\n", 123);

If the string "hello %d\n" is marked target, then runningconvert_format_string will replace this call with

  1. 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 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 implblock 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 selfrespectively.

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 targetwith 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:

  1. struct Foo { // Foo: target
  2. x: i32, // i32: target
  3. y: i32,
  4. }
  5. fn f(foo: Foo) { ... } // f: target
  6. fn main() {
  7. f(...);
  8. }

After running generalize_items T:

  1. // 1. Foo gains a new type parameter `T`
  2. struct Foo<T> {
  3. // 2. Marked type annotations become `T`
  4. x: T,
  5. y: i32,
  6. }
  7. // 3. `f` gains a new type parameter `T`, and passes
  8. // it through to uses of `Foo`
  9. fn f<T>(foo: Foo<T>) { ... }
  10. struct Bar<T> {
  11. foo: Foo<T>,
  12. }
  13. fn main() {
  14. // 4. Uses outside target items use `i32`, the
  15. // first type that was replaced with `T`.
  16. f::<i32>(...);
  17. }

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.

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:

  1. mod a {
  2. #[no_mangle]
  3. unsafe extern "C" fn foo() { ... }
  4. }
  5. mod b {
  6. extern "C" {
  7. // This resolves to `a::foo` during linking.
  8. fn foo();
  9. }
  10. unsafe fn use_foo() {
  11. foo();
  12. }
  13. }

After running link_funcs:

  1. mod a {
  2. #[no_mangle]
  3. unsafe extern "C" fn foo() { ... }
  4. }
  5. mod b {
  6. // 1. Foreign fn `foo` has been deleted
  7. unsafe fn use_foo() {
  8. // 2. `use_foo` now calls `foo` directly
  9. ::a::foo();
  10. }
  11. }

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:

  1. mod a {
  2. struct Foo { ... }
  3. }
  4. mod b {
  5. extern "C" {
  6. type Foo;
  7. }
  8. unsafe fn use_foo(x: &Foo) { ... }
  9. }

After running link_incomplete_types:

  1. mod a {
  2. struct Foo { ... }
  3. }
  4. mod b {
  5. // 1. Foreign fn `Foo` has been deleted
  6. // 2. `use_foo` now references `Foo` directly
  7. unsafe fn use_foo(x: &::a::Foo) { ... }
  8. }

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.

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:

  1. fn f(x: i32, y: i32) -> i32 {
  2. x
  3. }

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 Idents 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-transpiled project.

Example:

  1. pub mod foo {
  2. pub struct unnamed {
  3. a: i32
  4. }
  5. }
  6. pub mod bar {
  7. pub struct unnamed {
  8. b: usize
  9. }
  10. }

Becomes:

  1. pub mod foo {
  2. pub struct unnamed {
  3. a: i32
  4. }
  5. }
  6. pub mod bar {
  7. pub struct unnamed_1 {
  8. b: usize
  9. }
  10. }

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)in REV_CONV_ASSIGN to produce a value of type NEW_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 and CONV_LVAL_MUT are similar to CONV_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:

  1. fn double(x: i32) -> i32 {
  2. x * 2
  3. }

After running rewrite_expr '$e * 2' '$e + $e':

  1. fn double(x: i32) -> i32 {
  2. x + x
  3. }

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 of STRUCT with the same name and type as the static.
  • Generate a new static mut named VAR whose type is STRUCT. Initializeit using the initializer expressions for the marked statics.
  • For each marked static foo, replace uses of foo with VAR.foo. Example:
  1. static mut FOO: i32 = 100;
  2. static mut BAR: bool = true;
  3. unsafe fn f() -> i32 {
  4. FOO
  5. }

After running static_collect_to_struct Globals G, with both statics marked:

  1. struct Globals {
  2. FOO: i32,
  3. BAR: bool,
  4. }
  5. static mut G: Globals = Globals {
  6. FOO: 100,
  7. BAR: true,
  8. };
  9. unsafe fn f() -> i32 {
  10. G.FOO
  11. }

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:

  1. static mut FOO: i32 = 100; // FOO: target
  2. unsafe fn f() -> i32 {
  3. FOO
  4. }
  5. unsafe fn g() -> i32 {
  6. FOO + 1
  7. }

After running static_to_local:

  1. // `FOO` deleted
  2. // `f` gains a new local, replicating `FOO`.
  3. unsafe fn f() -> i32 {
  4. let FOO: i32 = 100;
  5. FOO
  6. }
  7. // If multiple functions use `FOO`, each one gets its own copy.
  8. unsafe fn g() -> i32 {
  9. let FOO: i32 = 100;
  10. FOO + 1
  11. }

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:

  1. static mut FOO: i32 = 100; // FOO: target
  2. unsafe fn f() -> i32 { // f: user
  3. FOO
  4. }
  5. unsafe fn g() -> i32 { // g: user
  6. f()
  7. }
  8. unsafe fn h() -> i32 {
  9. g()
  10. }

After running static_to_local_ref:

  1. static mut FOO: i32 = 100;
  2. // `f` is a `user` that references `FOO`, so it
  3. // gains a new argument `FOO_`.
  4. unsafe fn f(FOO_: &mut i32) -> i32 {
  5. // References to `FOO` are replaced with `*FOO_`
  6. *FOO_
  7. }
  8. // `g` is a `user` that references `FOO` indirectly,
  9. // via fellow `user` `f`.
  10. unsafe fn g(FOO_: &mut i32) -> i32 {
  11. // `g` passes through its own `FOO_` reference
  12. // when calling `f`.
  13. f(FOO_)
  14. }
  15. // `h` is not a `user`, so its signature is unchanged.
  16. unsafe fn h() -> i32 {
  17. // `h` passes in a reference to the original
  18. // static `FOO`.
  19. g(&mut FOO)
  20. }

struct_assign_to_update

Usage: struct_assign_to_update

Replace all struct field assignments with functional update expressions.

Example:

  1. let mut x: S = ...;
  2. x.f = 1;
  3. x.g = 2;

After running struct_assign_to_update:

  1. let mut x: S = ...;
  2. x = S { f: 1, ..x };
  3. x = S { g: 2, ..x };

struct_merge_updates

Usage: struct_merge_updates

Merge consecutive struct updates into a single update.

Example:

  1. let mut x: S = ...;
  2. x = S { f: 1, ..x };
  3. x = S { g: 2, ..x };

After running struct_assign_to_update:

  1. let mut x: S = ...;
  2. 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 of rval, 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 with foo's old ABIand an #[export_name="foo"] attribute. Calls to foo are left unchanged. The result is that callers from C use thewrapper function, while internal calls use foo 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:

  1. extern "C" {
  2. fn foo(x: i32) -> i32;
  3. }
  4. mod wrappers {
  5. // empty
  6. }
  7. fn main() {
  8. let x = unsafe { foo(123) };
  9. }

After transformation, with fn foo marked target and mod wrappers markeddest:

  1. extern "C" {
  2. fn foo(x: i32) -> i32;
  3. }
  4. mod wrappers {
  5. unsafe fn foo(x: i32) -> i32 {
  6. ::foo(x)
  7. }
  8. }
  9. fn main() {
  10. let x = unsafe { ::wrappers::foo(123) };
  11. }

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.