Skip to content

Commit dfb5675

Browse files
LeonMatthesKDABahayzen-kdab
authored andcommitted
Disallow duplicate type names
This would be ambiguous otherwise
1 parent a877c24 commit dfb5675

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

crates/cxx-qt-gen/src/naming/type_names.rs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
//
44
// SPDX-License-Identifier: MIT OR Apache-2.0
55

6-
use std::collections::BTreeMap;
6+
use std::collections::{btree_map::Entry, BTreeMap};
77

88
use syn::{
9-
token::Brace, Attribute, Ident, Item, ItemEnum, ItemForeignMod, ItemStruct, Path, Result,
9+
token::Brace, Attribute, Error, Ident, Item, ItemEnum, ItemForeignMod, ItemStruct, Path, Result,
1010
};
1111

1212
use crate::syntax::{
@@ -177,8 +177,8 @@ impl TypeNames {
177177
Ok(())
178178
}
179179

180-
fn unknown_type(&self, ident: &Ident) -> syn::Error {
181-
syn::Error::new_spanned(ident, format!("Undeclared type: `{ident}`!"))
180+
fn unknown_type(&self, ident: &Ident) -> Error {
181+
Error::new_spanned(ident, format!("Undeclared type: `{ident}`!"))
182182
}
183183

184184
/// For a given rust ident return the CXX name with its namespace
@@ -246,9 +246,19 @@ impl TypeNames {
246246
module_ident: &Ident,
247247
) -> Result<()> {
248248
let name = Name::from_ident_and_attrs(ident, attrs, parent_namespace, module_ident)?;
249-
// TODO: Check for duplicates
250-
self.names.insert(name.rust.clone(), name);
251-
Ok(())
249+
250+
let entry = self.names.entry(name.rust.clone());
251+
252+
match entry {
253+
Entry::Occupied(_) => Err(Error::new_spanned(
254+
ident,
255+
format!("The type name `{ident}` is defined multiple times"),
256+
)),
257+
Entry::Vacant(entry) => {
258+
entry.insert(name);
259+
Ok(())
260+
}
261+
}
252262
}
253263

254264
#[cfg(test)]
@@ -567,4 +577,26 @@ mod tests {
567577
);
568578
assert_eq!(types.rust_qualified(&ident), parse_quote! { ffi::StructA });
569579
}
580+
581+
#[test]
582+
fn test_duplicate_types() {
583+
let items = [
584+
parse_quote! {
585+
extern "C++" {
586+
#[rust_name="B"]
587+
type A;
588+
}
589+
},
590+
parse_quote! {
591+
extern "Rust" {
592+
type B;
593+
}
594+
},
595+
];
596+
597+
let mut types = TypeNames::default();
598+
assert!(types
599+
.populate_from_cxx_items(&items, None, &format_ident!("ffi"))
600+
.is_err());
601+
}
570602
}

0 commit comments

Comments
 (0)