diff --git a/src/ir/context.rs b/src/ir/context.rs index bd21058c4b..44df063a9b 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -2723,8 +2723,16 @@ impl ItemResolver { assert!(ctx.collected_typerefs()); let mut id = self.id; + let mut seen_ids = HashSet::default(); loop { let item = ctx.resolve_item(id); + + // Detect cycles and bail out. These can happen in certain cases + // involving incomplete qualified dependent types (#2085). + if !seen_ids.insert(id) { + return item; + } + let ty_kind = item.as_type().map(|t| t.kind()); match ty_kind { Some(&TypeKind::ResolvedTypeRef(next_id)) diff --git a/tests/expectations/tests/qualified-dependent-types.rs b/tests/expectations/tests/qualified-dependent-types.rs new file mode 100644 index 0000000000..f1b2c8459c --- /dev/null +++ b/tests/expectations/tests/qualified-dependent-types.rs @@ -0,0 +1,17 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Foo { + pub _address: u8, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Bar { + pub _address: u8, +} diff --git a/tests/headers/qualified-dependent-types.hpp b/tests/headers/qualified-dependent-types.hpp new file mode 100644 index 0000000000..fcdfc87c81 --- /dev/null +++ b/tests/headers/qualified-dependent-types.hpp @@ -0,0 +1,16 @@ +// Issue #2085. + +template +struct Foo; + +template +struct Bar {}; + +template +struct Bar { + using BarDependent = typename Foo::Dependent; + void method(const BarDependent &); +}; + +template +void Bar::method(const BarDependent &) {}