Skip to content

Commit fbc2237

Browse files
committed
parser: Fix resolution of #[path] dependencies from certain modules.
We need the current mod dir to resolve #[path], not the one we get for rust 2018. Fixes #599
1 parent 9f558e3 commit fbc2237

File tree

12 files changed

+87
-12
lines changed

12 files changed

+87
-12
lines changed

src/bindgen/parser.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl<'a> Parser<'a> {
205205
self.cache_expanded_crate.get(&pkg.name).unwrap().clone()
206206
};
207207

208-
self.process_mod(pkg, None, &mod_items, 0)
208+
self.process_mod(pkg, None, None, &mod_items, 0)
209209
}
210210

211211
fn parse_mod(
@@ -240,30 +240,37 @@ impl<'a> Parser<'a> {
240240
};
241241

242242
// Compute module directory according to Rust 2018 rules
243-
let mod_dir_2018;
243+
let submod_dir_2018;
244244

245-
let mod_dir = if depth == 0 || mod_path.ends_with("mod.rs") {
246-
mod_path.parent().unwrap()
245+
let mod_dir = mod_path.parent().unwrap();
246+
247+
let submod_dir = if depth == 0 || mod_path.ends_with("mod.rs") {
248+
mod_dir
247249
} else {
248-
mod_dir_2018 = mod_path
250+
submod_dir_2018 = mod_path
249251
.parent()
250252
.unwrap()
251253
.join(mod_path.file_stem().unwrap());
252-
&mod_dir_2018
254+
&submod_dir_2018
253255
};
254256

255-
self.process_mod(pkg, Some(&mod_dir), &mod_items, depth)
257+
self.process_mod(pkg, Some(mod_dir), Some(submod_dir), &mod_items, depth)
256258
}
257259

258260
/// `mod_dir` is the path to the current directory of the module. It may be
259261
/// `None` for pre-expanded modules.
262+
///
263+
/// `submod_dir` is the path to search submodules in by default, which might
264+
/// be different for rust 2018 for example.
260265
fn process_mod(
261266
&mut self,
262267
pkg: &PackageRef,
263268
mod_dir: Option<&FilePath>,
269+
submod_dir: Option<&FilePath>,
264270
items: &[syn::Item],
265271
depth: usize,
266272
) -> Result<(), Error> {
273+
debug_assert_eq!(mod_dir.is_some(), submod_dir.is_some());
267274
// We process the items first then the nested modules.
268275
let nested_modules = self.out.load_syn_crate_mod(
269276
&self.config,
@@ -275,18 +282,24 @@ impl<'a> Parser<'a> {
275282

276283
for item in nested_modules {
277284
let next_mod_name = item.ident.to_string();
278-
279285
let cfg = Cfg::load(&item.attrs);
280286
if let Some(ref cfg) = cfg {
281287
self.cfg_stack.push(cfg.clone());
282288
}
283289

284290
if let Some((_, ref inline_items)) = item.content {
285-
let next_mod_dir = mod_dir.map(|dir| dir.join(&next_mod_name));
286-
self.process_mod(pkg, next_mod_dir.as_deref(), inline_items, depth)?;
291+
let next_submod_dir = submod_dir.map(|dir| dir.join(&next_mod_name));
292+
self.process_mod(
293+
pkg,
294+
mod_dir,
295+
next_submod_dir.as_deref(),
296+
inline_items,
297+
depth,
298+
)?;
287299
} else if let Some(mod_dir) = mod_dir {
288-
let next_mod_path1 = mod_dir.join(next_mod_name.clone() + ".rs");
289-
let next_mod_path2 = mod_dir.join(next_mod_name.clone()).join("mod.rs");
300+
let submod_dir = submod_dir.unwrap();
301+
let next_mod_path1 = submod_dir.join(next_mod_name.clone() + ".rs");
302+
let next_mod_path2 = submod_dir.join(next_mod_name.clone()).join("mod.rs");
290303

291304
if next_mod_path1.exists() {
292305
self.parse_mod(pkg, next_mod_path1.as_path(), depth + 1)?;

tests/expectations/mod_2018.both.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ typedef struct ExportMe {
99
uint64_t val;
1010
} ExportMe;
1111

12+
typedef struct ExportMe2 {
13+
uint64_t val;
14+
} ExportMe2;
15+
1216
void export_me(struct ExportMe *val);
17+
18+
void export_me_2(struct ExportMe2*);

tests/expectations/mod_2018.both.compat.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ typedef struct ExportMe {
99
uint64_t val;
1010
} ExportMe;
1111

12+
typedef struct ExportMe2 {
13+
uint64_t val;
14+
} ExportMe2;
15+
1216
#ifdef __cplusplus
1317
extern "C" {
1418
#endif // __cplusplus
1519

1620
void export_me(struct ExportMe *val);
1721

22+
void export_me_2(struct ExportMe2*);
23+
1824
#ifdef __cplusplus
1925
} // extern "C"
2026
#endif // __cplusplus

tests/expectations/mod_2018.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ typedef struct {
99
uint64_t val;
1010
} ExportMe;
1111

12+
typedef struct {
13+
uint64_t val;
14+
} ExportMe2;
15+
1216
void export_me(ExportMe *val);
17+
18+
void export_me_2(ExportMe2*);

tests/expectations/mod_2018.compat.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ typedef struct {
99
uint64_t val;
1010
} ExportMe;
1111

12+
typedef struct {
13+
uint64_t val;
14+
} ExportMe2;
15+
1216
#ifdef __cplusplus
1317
extern "C" {
1418
#endif // __cplusplus
1519

1620
void export_me(ExportMe *val);
1721

22+
void export_me_2(ExportMe2*);
23+
1824
#ifdef __cplusplus
1925
} // extern "C"
2026
#endif // __cplusplus

tests/expectations/mod_2018.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@ struct ExportMe {
1010
uint64_t val;
1111
};
1212

13+
struct ExportMe2 {
14+
uint64_t val;
15+
};
16+
1317
extern "C" {
1418

1519
void export_me(ExportMe *val);
1620

21+
void export_me_2(ExportMe2*);
22+
1723
} // extern "C"

tests/expectations/mod_2018.pyx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ cdef extern from *:
1111
ctypedef struct ExportMe:
1212
uint64_t val;
1313

14+
ctypedef struct ExportMe2:
15+
uint64_t val;
16+
1417
void export_me(ExportMe *val);
18+
19+
void export_me_2(ExportMe2*);

tests/expectations/mod_2018.tag.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ struct ExportMe {
99
uint64_t val;
1010
};
1111

12+
struct ExportMe2 {
13+
uint64_t val;
14+
};
15+
1216
void export_me(struct ExportMe *val);
17+
18+
void export_me_2(struct ExportMe2*);

tests/expectations/mod_2018.tag.compat.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ struct ExportMe {
99
uint64_t val;
1010
};
1111

12+
struct ExportMe2 {
13+
uint64_t val;
14+
};
15+
1216
#ifdef __cplusplus
1317
extern "C" {
1418
#endif // __cplusplus
1519

1620
void export_me(struct ExportMe *val);
1721

22+
void export_me_2(struct ExportMe2*);
23+
1824
#ifdef __cplusplus
1925
} // extern "C"
2026
#endif // __cplusplus

tests/expectations/mod_2018.tag.pyx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ cdef extern from *:
1111
cdef struct ExportMe:
1212
uint64_t val;
1313

14+
cdef struct ExportMe2:
15+
uint64_t val;
16+
1417
void export_me(ExportMe *val);
18+
19+
void export_me_2(ExportMe2*);

0 commit comments

Comments
 (0)