Skip to content

Commit 6f8ecae

Browse files
authored
Make Rust type rules standalone functions (#164)
Changes the format of the Rust side of type rules to: ```rust fn t<digit>() -> TYPE { return DEFAULT-INITIALIZER; } ``` Actual changes to rules: - The initializer for the unsafe rules `t1`, `t2`, and `t3` in `fstream` was changed from `::std::fs::File::open("")?` to `::std::fs::File::open("").unwrap()`. This change was made because the `?` operator requires the function to return a value of type `Result` or `Option`. Additionally, other rules for file-related types already use `::std::fs::File::open("").unwrap()` as an initializer (for example, rule `t1` in `iostream`). - Added a missing generic parameter to the refcount rules `f10` and `f11` in `unique_ptr`. These rules were relying on the struct defined at the top of the type.
1 parent 3aac70f commit 6f8ecae

23 files changed

Lines changed: 168 additions & 138 deletions

rule-preprocessor/src/syntactic.rs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,11 @@ impl SyntacticAnalysis {
124124
let Some(name) = fn_item.name() else { continue };
125125
let fn_name = name.text().to_string();
126126

127-
if fn_name == "types" {
128-
for (name, ir) in TypeIrBuilder::new(&fn_item).build() {
129-
file_ir.insert(name, RuleIr::Type(ir));
130-
}
127+
if fn_name.starts_with('t') {
128+
file_ir.insert(
129+
fn_name.clone(),
130+
RuleIr::Type(TypeIrBuilder::new(&fn_item).build()),
131+
);
131132
} else if fn_name.starts_with('f') {
132133
if !cfg_matches_host(&fn_item) {
133134
continue;
@@ -531,35 +532,35 @@ impl<'a> TypeIrBuilder<'a> {
531532
Self { fn_item }
532533
}
533534

534-
fn build(&self) -> Vec<(String, TypeIr)> {
535-
let Some(body) = self.fn_item.body() else {
536-
return Vec::new();
537-
};
538-
let mut results = Vec::new();
539-
for stmt in body.syntax().descendants().filter_map(ast::LetStmt::cast) {
540-
let Some(pat) = stmt.pat() else { continue };
541-
let pat_text = pat.syntax().text().to_string();
542-
if !pat_text.starts_with('t') {
543-
continue;
544-
}
545-
let Some(ty) = stmt.ty() else { continue };
546-
let Some(init) = stmt.initializer() else {
547-
continue;
548-
};
535+
fn build(&self) -> TypeIr {
536+
let ty = self
537+
.fn_item
538+
.ret_type()
539+
.and_then(|rt| rt.ty())
540+
.expect("Type rules must declare a return type");
541+
let (is_refcount_pointer, is_unsafe_pointer) = pointer_flags(&ty);
549542

550-
let (is_refcount_pointer, is_unsafe_pointer) = pointer_flags(&ty);
551-
results.push((
552-
pat_text,
553-
TypeIr {
554-
init: init.syntax().text().to_string(),
555-
type_info: TypeInfo {
556-
ty: ty.syntax().text().to_string(),
557-
is_refcount_pointer,
558-
is_unsafe_pointer,
559-
},
560-
},
561-
));
543+
let stmts = self
544+
.fn_item
545+
.body()
546+
.and_then(|bd| bd.stmt_list())
547+
.expect("Types rule must have a body");
548+
assert!(
549+
stmts.statements().count() == 0,
550+
"Type rules mustn't contain anything in the body besides the tail expression"
551+
);
552+
553+
let init = stmts
554+
.tail_expr()
555+
.expect("Type rules must yield an initializer");
556+
557+
TypeIr {
558+
init: init.syntax().text().to_string(),
559+
type_info: TypeInfo {
560+
ty: ty.syntax().text().to_string(),
561+
is_refcount_pointer,
562+
is_unsafe_pointer,
563+
},
562564
}
563-
results
564565
}
565566
}

rules/array/tgt_unsafe.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33

44
use libcc2rs::*;
55

6-
struct T1;
7-
8-
fn types() {
9-
let t1: Vec<T1> = Default::default();
6+
fn t1<T1>() -> Vec<T1> {
7+
Default::default()
108
}
119

1210
unsafe fn f1<T1>(a0: Vec<T1>) -> *const T1 {

rules/brotli/tgt_unsafe.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
// Copyright (c) 2022-present INESC-ID.
22
// Distributed under the MIT license that can be found in the LICENSE file.
33

4-
fn types() {
5-
let t1: ::brotli_sys::BrotliDecoderResult = ::brotli_sys::BROTLI_DECODER_RESULT_ERROR;
6-
let t2: ::brotli_sys::BrotliEncoderMode = ::brotli_sys::BROTLI_MODE_GENERIC;
7-
let t3: *mut ::brotli_sys::BrotliDecoderState = std::ptr::null_mut();
8-
let t4: *const ::brotli_sys::BrotliDecoderState = std::ptr::null();
9-
let t5: ::brotli_sys::BrotliDecoderErrorCode = ::brotli_sys::BROTLI_DECODER_NO_ERROR;
4+
fn t1() -> ::brotli_sys::BrotliDecoderResult {
5+
::brotli_sys::BROTLI_DECODER_RESULT_ERROR
6+
}
7+
8+
fn t2() -> ::brotli_sys::BrotliEncoderMode {
9+
::brotli_sys::BROTLI_MODE_GENERIC
10+
}
11+
12+
fn t3() -> *mut ::brotli_sys::BrotliDecoderState {
13+
std::ptr::null_mut()
14+
}
15+
16+
fn t4() -> *const ::brotli_sys::BrotliDecoderState {
17+
std::ptr::null()
18+
}
19+
20+
fn t5() -> ::brotli_sys::BrotliDecoderErrorCode {
21+
::brotli_sys::BROTLI_DECODER_NO_ERROR
1022
}
1123

1224
unsafe fn f1() -> ::brotli_sys::BrotliEncoderMode {

rules/carray/tgt_refcount.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33

44
use libcc2rs::*;
55

6-
struct T1;
6+
fn t1<T1>() -> Box<[Value<Box<[T1]>>]> {
7+
Box::new([Default::default()])
8+
}
79

8-
fn types() {
9-
let t1: Box<[Value<Box<[T1]>>]> = Box::new([Default::default()]);
10-
let t2: Box<[Value<Box<[Value<Box<[T1]>>]>>]> = Box::new([Default::default()]);
10+
fn t2<T1>() -> Box<[Value<Box<[Value<Box<[T1]>>]>>]> {
11+
Box::new([Default::default()])
1112
}

rules/carray/tgt_unsafe.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Copyright (c) 2022-present INESC-ID.
22
// Distributed under the MIT license that can be found in the LICENSE file.
33

4-
fn types() {
5-
let t1: libcc2rs::IgnoreRule = libcc2rs::IgnoreRule;
6-
let t2: libcc2rs::IgnoreRule = libcc2rs::IgnoreRule;
4+
fn t1() -> libcc2rs::IgnoreRule {
5+
libcc2rs::IgnoreRule
6+
}
7+
8+
fn t2() -> libcc2rs::IgnoreRule {
9+
libcc2rs::IgnoreRule
710
}

rules/deque/tgt_unsafe.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33

44
use libcc2rs::*;
55

6-
struct T1;
7-
8-
fn types() {
9-
// TODO: it should be VecDeque, but we don't have the neccessary infrastructure in Ptr<> to
10-
// make this work.
11-
let t1: Vec<T1> = Default::default();
6+
// TODO: it should be VecDeque, but we don't have the neccessary infrastructure in Ptr<> to
7+
// make this work.
8+
fn t1<T1>() -> Vec<T1> {
9+
Default::default()
1210
}
1311

1412
unsafe fn f1<T1>(a0: &mut Vec<T1>) -> *const T1 {

rules/fstream/tgt_unsafe.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
// Copyright (c) 2022-present INESC-ID.
22
// Distributed under the MIT license that can be found in the LICENSE file.
33

4-
fn types() -> Result<(), Box<dyn std::error::Error>> {
5-
let t1: ::std::fs::File = ::std::fs::File::open("")?;
6-
let t2: ::std::fs::File = ::std::fs::File::open("")?;
7-
let t3: ::std::fs::File = ::std::fs::File::open("")?;
8-
Ok(())
4+
fn t1() -> ::std::fs::File {
5+
::std::fs::File::open("").unwrap()
6+
}
7+
8+
fn t2() -> ::std::fs::File {
9+
::std::fs::File::open("").unwrap()
10+
}
11+
12+
fn t3() -> ::std::fs::File {
13+
::std::fs::File::open("").unwrap()
914
}
1015

1116
unsafe fn f1(a0: *const u8) -> ::std::fs::File {

rules/initializer_list/tgt_unsafe.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33

44
use libcc2rs::*;
55

6-
struct T1;
7-
8-
fn types() {
9-
let t1: Vec<T1> = Default::default();
6+
fn t1<T1>() -> Vec<T1> {
7+
Default::default()
108
}
119

1210
unsafe fn f1<T1>(a0: Vec<T1>) -> u64 {

rules/iostream/tgt_refcount.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ use libcc2rs::*;
55
use std::os::fd::AsFd;
66

77
// TODO: t2 and t3 should be translated to Ptr<dyn Traits>
8-
fn types() {
9-
let t2: Ptr<std::fs::File> = Ptr::null();
10-
let t3: Ptr<std::fs::File> = Ptr::null();
8+
fn t2() -> Ptr<std::fs::File> {
9+
Ptr::null()
10+
}
11+
12+
fn t3() -> Ptr<std::fs::File> {
13+
Ptr::null()
1114
}
1215

1316
fn f1() -> ::std::fs::File {

rules/iostream/tgt_unsafe.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
use libcc2rs::*;
55
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
66

7+
fn t1() -> std::fs::File {
8+
std::fs::File::open("").unwrap()
9+
}
10+
711
// TODO: t2 and t3 should be translated to *mut dyn Traits
8-
unsafe fn types() {
9-
let t1: std::fs::File = std::fs::File::open("").unwrap();
10-
let t2: *mut std::fs::File = libcc2rs::cout_unsafe();
11-
let t3: *mut std::fs::File = libcc2rs::cout_unsafe();
12+
unsafe fn t2() -> *mut std::fs::File {
13+
libcc2rs::cout_unsafe()
14+
}
15+
16+
unsafe fn t3() -> *mut std::fs::File {
17+
libcc2rs::cout_unsafe()
1218
}
1319

1420
unsafe fn f1() -> ::std::fs::File {

0 commit comments

Comments
 (0)