Skip to content

Commit

Permalink
Generate code with less warnings.
Browse files Browse the repository at this point in the history
- Add several #![allow(...)] directives in order to disable warnings.
  (Future code-gen might redo lexical conventions, but later.)
  Suggestion by @marshrayms
- Enable use-analysis for for-loop variables, so as to be able to detect
  variables that *become* unused when compiling those to range loops.
  • Loading branch information
msprotz committed Jan 23, 2024
1 parent dda3571 commit 65a3310
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
13 changes: 12 additions & 1 deletion lib/AstToMiniRust.ml
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,8 @@ and translate_expr_with_type (env: env) (e: Ast.expr) (t_ret: MiniRust.typ): env

(* b is in scope for e_test, e_incr, e_body! *)
let e_end = match e_test.node, e_incr.node with
(* If we have `i < e_end; i := i + 1`, then this is a range-loop and we can
lift `e_end` by 1. *)
| EApp ({ node = EOp (Lt, _); _ }, [ { node = EBound 0; _ }; e_end ]),
EAssign ({ node = EBound 0; _ },
{ node = EApp ({ node = EOp ((Add | AddW), _); _ }, [
Expand All @@ -788,7 +790,16 @@ and translate_expr_with_type (env: env) (e: Ast.expr) (t_ret: MiniRust.typ): env
PrintAst.Ops.pexpr e_test
PrintAst.Ops.pexpr e_incr
in
let binding: MiniRust.binding = { name = b.node.name; typ = translate_type env b.typ; mut = false } in
(* The loop index is unused if it has at most three uses; in that case,
all of those are in `i < e_end i := i + 1`, and they all go away since
this loop compiles to `i in e_start..e_end`, effectively marking this
variable unused. *)
let unused = snd !(b.node.mark) = AtMost 3 in
(* We do an ad-hoc thing since this didn't go through lowstar.ignore
insertion. Rust uses the OCaml convention (which I recall I did suggest
to Graydon back in 2010). *)
let unused = if unused then "_" else "" in
let binding: MiniRust.binding = { name = unused ^ b.node.name; typ = translate_type env b.typ; mut = false } in
let env, e_start = translate_expr env e_start in
let env, e_end = translate_expr env e_end in
let _, e_body = translate_expr (push env binding) e_body in
Expand Down
11 changes: 10 additions & 1 deletion lib/OutputRust.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

open PPrint

let directives = String.trim {|
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
|}

let rust_name f = f ^ ".rs"

let write_file file =
Expand All @@ -14,7 +20,10 @@ let write_file file =
Driver.mkdirp dirs;
let filename = Driver.((^^)) dirs (rust_name filename) in
Utils.with_open_out_bin filename (fun oc ->
let doc = separate_map (hardline ^^ hardline) (PrintMiniRust.print_decl prefix) decls ^^ hardline in
let doc =
string directives ^^ hardline ^^ hardline ^^
separate_map (hardline ^^ hardline) (PrintMiniRust.print_decl prefix) decls ^^ hardline
in
PPrint.ToChannel.pretty 0.95 100 oc doc
)

Expand Down
2 changes: 1 addition & 1 deletion lib/PrintMiniRust.ml
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ and prec_of_op2 o =
| BAnd -> 11, 11, 10
| BXor -> 12, 12, 11
| BOr -> 13, 13, 12
| Eq | Neq | Lt | Gt | Lte | Gte -> max_int, 13, 13
| Eq | Neq | Lt | Gt | Lte | Gte -> 14, 13, 13
| And -> 15, 15, 14
| Or -> 16, 16, 15
| _ -> failwith ("unexpected: unknown binary operator: " ^ Constant.show_op o)
Expand Down
13 changes: 12 additions & 1 deletion lib/UseAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,18 @@ let build_usage_map_and_mark ifdefs = object(self)
map

method! visit_EFor env b e1 e2 e3 e4 =
restrict_map (super#visit_EFor env b e1 e2 e3 e4) (List.length (fst env))
let env0 = self#extend (fst env) b in
let map = KList.reduce self#plus [
self#visit_expr_w env0 e2;
self#visit_expr_w env0 e3;
self#visit_expr_w env0 e4;
] in
let level = List.length (fst env) in
let v = match IntMap.find_opt level map with None -> zero | Some v -> v in
b.node.mark := v;
let map = restrict_map map level in
assert (snd v <> AtMost 0);
self#plus map (self#visit_expr env e1)

method! visit_branch env (binders, _, _ as b) =
let map = super#visit_branch env b in
Expand Down

0 comments on commit 65a3310

Please sign in to comment.