Skip to content

Commit 3bc4fb0

Browse files
authored
Include libc dependency only when needed (#1373)
* Fixes #1362 Since most C types are now imported from `std::ffi`, there is less need to always include the `libc` library. This changes it so that it's only included when actually needed. To implement this, `TypeConverter` now tracks external crates, separately from `Translator`. The two lists are merged afterwards. While working on this, I also spotted a bug that `f128` wasn't being included from `TypeConverter` and a few other places, so I included fixes for that as well.
2 parents a931982 + 6a43b9d commit 3bc4fb0

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

c2rust-transpile/src/convert_type.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ use crate::c_ast::CDeclId;
22
use crate::c_ast::*;
33
use crate::diagnostics::TranslationResult;
44
use crate::renamer::*;
5+
use crate::{CrateSet, ExternCrate};
56
use c2rust_ast_builder::{mk, properties::*};
67
use failure::format_err;
8+
use indexmap::IndexSet;
79
use std::collections::{HashMap, HashSet};
810
use std::ops::Index;
911
use syn::*;
@@ -20,6 +22,7 @@ pub struct TypeConverter {
2022
fields: HashMap<CDeclId, Renamer<FieldKey>>,
2123
suffix_names: HashMap<(CDeclId, &'static str), String>,
2224
features: HashSet<&'static str>,
25+
extern_crates: CrateSet,
2326
}
2427

2528
pub const RESERVED_NAMES: [&str; 103] = [
@@ -146,13 +149,22 @@ impl TypeConverter {
146149
fields: HashMap::new(),
147150
suffix_names: HashMap::new(),
148151
features: HashSet::new(),
152+
extern_crates: IndexSet::new(),
149153
}
150154
}
151155

156+
fn use_crate(&mut self, extern_crate: ExternCrate) {
157+
self.extern_crates.insert(extern_crate);
158+
}
159+
152160
pub fn features_used(&self) -> &HashSet<&'static str> {
153161
&self.features
154162
}
155163

164+
pub fn extern_crates_used(&self) -> &CrateSet {
165+
&self.extern_crates
166+
}
167+
156168
pub fn declare_decl_name(&mut self, decl_id: CDeclId, name: &str) -> String {
157169
self.renamer
158170
.insert(decl_id, name)
@@ -326,6 +338,7 @@ impl TypeConverter {
326338
CTypeKind::Char => Ok(mk().path_ty(mk().path(vec!["std", "ffi", "c_char"]))),
327339
CTypeKind::Double => Ok(mk().path_ty(mk().path(vec!["std", "ffi", "c_double"]))),
328340
CTypeKind::LongDouble | CTypeKind::Float128 => {
341+
self.use_crate(ExternCrate::F128);
329342
Ok(mk().path_ty(mk().path(vec!["f128", "f128"])))
330343
}
331344
CTypeKind::Float => Ok(mk().path_ty(mk().path(vec!["std", "ffi", "c_float"]))),
@@ -343,12 +356,21 @@ impl TypeConverter {
343356
CTypeKind::UInt32 => Ok(mk().path_ty(mk().path(vec!["u32"]))),
344357
CTypeKind::UInt64 => Ok(mk().path_ty(mk().path(vec!["u64"]))),
345358
CTypeKind::UIntPtr => Ok(mk().path_ty(mk().path(vec!["usize"]))),
346-
CTypeKind::IntMax => Ok(mk().path_ty(mk().path(vec!["libc", "intmax_t"]))),
347-
CTypeKind::UIntMax => Ok(mk().path_ty(mk().path(vec!["libc", "uintmax_t"]))),
359+
CTypeKind::IntMax => {
360+
self.use_crate(ExternCrate::Libc);
361+
Ok(mk().path_ty(mk().path(vec!["libc", "intmax_t"])))
362+
}
363+
CTypeKind::UIntMax => {
364+
self.use_crate(ExternCrate::Libc);
365+
Ok(mk().path_ty(mk().path(vec!["libc", "uintmax_t"])))
366+
}
348367
CTypeKind::Size => Ok(mk().path_ty(mk().path(vec!["usize"]))),
349368
CTypeKind::SSize => Ok(mk().path_ty(mk().path(vec!["isize"]))),
350369
CTypeKind::PtrDiff => Ok(mk().path_ty(mk().path(vec!["isize"]))),
351-
CTypeKind::WChar => Ok(mk().path_ty(mk().path(vec!["libc", "wchar_t"]))),
370+
CTypeKind::WChar => {
371+
self.use_crate(ExternCrate::Libc);
372+
Ok(mk().path_ty(mk().path(vec!["libc", "wchar_t"])))
373+
}
352374

353375
CTypeKind::Pointer(qtype) => self.convert_pointer(ctxt, qtype),
354376

c2rust-transpile/src/translator/builtins.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ impl<'c> Translation<'c> {
308308
mk().block(vec![mk().expr_stmt(minus_one)]),
309309
Some(mk().lit_expr(mk().int_lit(0, "isize"))),
310310
);
311+
self.use_crate(ExternCrate::Libc);
311312
let size_t = mk().path_ty(vec!["libc", "size_t"]);
312313
mk().cast_expr(if_expr, size_t)
313314
}))
@@ -752,6 +753,7 @@ impl<'c> Translation<'c> {
752753
arg_types: &[LibcFnArgType],
753754
) -> TranslationResult<WithStmts<Box<Expr>>> {
754755
let name = &builtin_name[10..];
756+
self.use_crate(ExternCrate::Libc);
755757
let mem = mk().path_expr(vec!["libc", name]);
756758
let args = self.convert_exprs(ctx.used(), args, None)?;
757759
args.and_then(|args| {
@@ -765,13 +767,13 @@ impl<'c> Translation<'c> {
765767
))
766768
.context(TranslationErrorKind::Generic))?
767769
}
768-
let size_t = || mk().path_ty(vec!["libc", "size_t"]);
769770
let args_casted = args
770771
.into_iter()
771772
.zip(arg_types)
772773
.map(|(arg, &ty)| {
773774
if ty == LibcFnArgType::Size {
774-
mk().cast_expr(arg, size_t())
775+
self.use_crate(ExternCrate::Libc);
776+
mk().cast_expr(arg, mk().path_ty(vec!["libc", "size_t"]))
775777
} else {
776778
arg
777779
}

c2rust-transpile/src/translator/mod.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,6 @@ pub fn translate(
492492
};
493493

494494
{
495-
t.use_crate(ExternCrate::Libc);
496-
497495
// Sort the top-level declarations by file and source location so that we
498496
// preserve the ordering of all declarations in each file.
499497
t.ast_context.sort_top_decls();
@@ -767,9 +765,6 @@ pub fn translate(
767765
store.add_item(initializer_static);
768766
}
769767

770-
let pragmas = t.get_pragmas();
771-
let crates = t.extern_crates.borrow().clone();
772-
773768
let mut mod_items: Vec<Box<Item>> = Vec::new();
774769

775770
// Keep track of new uses we need while building header submodules
@@ -869,6 +864,15 @@ pub fn translate(
869864
items: all_items.into_iter().map(|x| *x).collect(),
870865
}
871866
});
867+
868+
let pragmas = t.get_pragmas();
869+
let extern_crates = t.extern_crates.borrow();
870+
let type_converter = t.type_converter.borrow();
871+
let crates = extern_crates
872+
.union(type_converter.extern_crates_used())
873+
.copied()
874+
.collect();
875+
872876
(translation, pragmas, crates)
873877
}
874878
}
@@ -4392,6 +4396,7 @@ impl<'c> Translation<'c> {
43924396
{
43934397
let target_ty = self.convert_type(target_cty.ctype)?;
43944398
val.and_then(|x| {
4399+
self.use_crate(ExternCrate::Libc);
43954400
let intptr_t = mk().path_ty(vec!["libc", "intptr_t"]);
43964401
let intptr = mk().cast_expr(x, intptr_t.clone());
43974402
Ok(WithStmts::new_unsafe_val(transmute_expr(
@@ -4444,6 +4449,7 @@ impl<'c> Translation<'c> {
44444449
})
44454450
} else if target_ty_kind.is_pointer() && source_ty_kind.is_bool() {
44464451
val.and_then(|x| {
4452+
self.use_crate(ExternCrate::Libc);
44474453
Ok(WithStmts::new_val(mk().cast_expr(
44484454
mk().cast_expr(x, mk().path_ty(vec!["libc", "size_t"])),
44494455
target_ty,
@@ -4722,9 +4728,12 @@ impl<'c> Translation<'c> {
47224728
))
47234729
} else if resolved_ty.is_floating_type() {
47244730
match self.ast_context[ty_id].kind {
4725-
CTypeKind::LongDouble => Ok(WithStmts::new_val(
4726-
mk().path_expr(vec!["f128", "f128", "ZERO"]),
4727-
)),
4731+
CTypeKind::LongDouble => {
4732+
self.use_crate(ExternCrate::F128);
4733+
Ok(WithStmts::new_val(
4734+
mk().path_expr(vec!["f128", "f128", "ZERO"]),
4735+
))
4736+
}
47284737
_ => Ok(WithStmts::new_val(
47294738
mk().lit_expr(mk().float_unsuffixed_lit("0.")),
47304739
)),

0 commit comments

Comments
 (0)