Skip to content

Commit 3b8a6cd

Browse files
authored
transpile: fix curl transpile breakage while maintaining a total SrcLoc order (#1163)
#1128 fixed the non-total (non-transitive) `SrcLoc` ordering, but accidentally broke the `curl` transpilation test in `c2rust-testsuites`, which is tested in CI, but was broken for external contributors PRs (fixed now in #1159). In the `curl` transpilation, a couple of `use` imports (`__sigset_t` and `C2RustUnnamed_4`) were missing, cause the build to fail afterward. I'm still not exactly sure why this fixes the issue while maintaining a transitive, total order, but it passes the total order test and transpiles `curl` correctly now. Hopefully this is a complete fix, and I didn't just fix a one-off error in `curl`. * 9679a3b is the real fix. * a4a052b are generally useful for testing and debugging.
2 parents a3a47ba + 9679a3b commit 3b8a6cd

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

c2rust-ast-exporter/src/clang_ast.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use serde_bytes::ByteBuf;
22
use serde_cbor::error;
3-
use std;
43
use std::collections::{HashMap, VecDeque};
54
use std::convert::TryInto;
5+
use std::fmt::{Display, Formatter};
66
use std::path::{Path, PathBuf};
7+
use std::{self, fmt};
78

89
pub use serde_cbor::value::{from_value, Value};
910

@@ -31,6 +32,17 @@ pub struct SrcLoc {
3132
pub column: u64,
3233
}
3334

35+
impl Display for SrcLoc {
36+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
37+
let Self {
38+
fileid,
39+
line,
40+
column,
41+
} = *self;
42+
write!(f, "file_{fileid}:{line}:{column}")
43+
}
44+
}
45+
3446
#[derive(Copy, Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
3547
pub struct SrcSpan {
3648
pub fileid: u64,
@@ -40,6 +52,22 @@ pub struct SrcSpan {
4052
pub end_column: u64,
4153
}
4254

55+
impl Display for SrcSpan {
56+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
57+
let Self {
58+
fileid,
59+
begin_line,
60+
begin_column,
61+
end_line,
62+
end_column,
63+
} = *self;
64+
write!(
65+
f,
66+
"file_{fileid}:{begin_line}:{begin_column}-{end_line}:{end_column}"
67+
)
68+
}
69+
}
70+
4371
impl From<SrcLoc> for SrcSpan {
4472
fn from(loc: SrcLoc) -> Self {
4573
Self {

c2rust-transpile/src/c_ast/mod.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,14 @@ impl TypedAstContext {
208208

209209
/// Compare two [`SrcLoc`]s based on their import path
210210
pub fn compare_src_locs(&self, a: &SrcLoc, b: &SrcLoc) -> Ordering {
211+
/// Compare without regard to `fileid`.
212+
fn cmp_pos(a: &SrcLoc, b: &SrcLoc) -> Ordering {
213+
(a.line, a.column).cmp(&(b.line, b.column))
214+
}
215+
211216
use Ordering::*;
212-
let path_a = &self.include_map[self.file_map[a.fileid as usize]];
213-
let path_b = &self.include_map[self.file_map[b.fileid as usize]];
217+
let path_a = &self.include_map[self.file_map[a.fileid as usize]][..];
218+
let path_b = &self.include_map[self.file_map[b.fileid as usize]][..];
214219

215220
// Find the first include that does not match between the two
216221
let common_len = path_a.len().min(path_b.len());
@@ -221,22 +226,21 @@ impl TypedAstContext {
221226

222227
// Either all parent includes are the same, or the include paths are of different lengths
223228
// because .zip() stops when one of the iterators is empty.
224-
let (a, b) = match path_a.len().cmp(&path_b.len()) {
229+
match path_a.len().cmp(&path_b.len()) {
225230
Less => {
226231
// a has the shorter path, which means b was included in a's file
227232
// so extract that include and compare the position to a
228233
let b = &path_b[path_a.len()];
229-
(a, b)
234+
cmp_pos(a, b)
230235
}
231-
Equal => (a, b), // a and b have the same include path and are thus in the same file
236+
Equal => a.cmp(b), // a and b have the same include path and are thus in the same file
232237
Greater => {
233238
// b has the shorter path, which means a was included in b's file
234239
// so extract that include and compare the position to b
235240
let a = &path_a[path_b.len()];
236-
(a, b)
241+
cmp_pos(a, b)
237242
}
238-
};
239-
a.cmp(b)
243+
}
240244
}
241245

242246
pub fn get_file_include_line_number(&self, file: FileId) -> Option<u64> {
@@ -2101,7 +2105,12 @@ mod tests {
21012105
let bc = ctx.compare_src_locs(&b, &c);
21022106
let ac = ctx.compare_src_locs(&a, &c);
21032107
if ab == bc {
2104-
assert_eq!(ab, ac, "Total order (transitivity) has been violated");
2108+
let [ab, bc, ac] = [ab, bc, ac].map(|ord| match ord {
2109+
Ordering::Less => "<",
2110+
Ordering::Equal => "==",
2111+
Ordering::Greater => ">",
2112+
});
2113+
assert_eq!(ab, ac, "Total order (transitivity) has been violated: {a} {ab} {b} and {b} {bc} {c}, but {a} {ac} {c}");
21052114
}
21062115
}
21072116
}

0 commit comments

Comments
 (0)