1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 ZeroDDS Contributors
//! Presenting the model and the language CSTs as seesaw graphs. Spec §3.
/// Whether `member` is annotated `@external`.
/// Whether a column that keeps an `@external` member behind an
/// indirection keeps `member` there.
///
/// DDS-XTypes 1.3 Table 21 makes `@external` a member "stored
/// externally to the containing type". A member whose type reaches the
/// aggregate that declares it back over inline edges has nowhere else to
/// be, annotated or not: `@optional Node next` inside `Node` is legal —
/// the absent member is what ends a value of it, XTypes 1.3
/// §7.3.1.2.1.3 — and a column whose member is the value declares a
/// type that contains itself. C++ answered it with `std::optional<T>`'s
/// incomplete-type errors, Rust with E0072, D with a refusal that cited
/// a clause the type does not break.
///
/// [`zerodds_ast_layout::member_held_inline_closes_a_cycle`] is the
/// question, asked of the aggregate that *declares* the member and not
/// of the one a walk is in. A base member flattened into a derived type
/// then has one holder wherever it appears, and the answer can only be
/// wider than the derived type's own: a type that reaches the derived
/// one reaches its base, which the derived type holds inline.
///
/// The columns whose member is a reference already — Java, Kotlin, F#,
/// Python — have no use for this, and C asks for the pointer it declares
/// ([`crate::adapter::c::pointer_member`], through
/// [`crate::emit::CodecTarget::behind_indirection`]): the member that closes a
/// cycle, and every `@external` member that is not a pointer already
/// (XTypes 1.3 §7.5.1.2.3.1).
/// The corpus cases the IDL front end refuses, so that no adapter ever
/// sees a model for them.
///
/// `tests/interop-corpus/resolve-module-named-as-type` is
/// `module common { struct common { … }; }`. OMG IDL 4.2 §7.5.2 states
/// that "the name of a module, structure, union, map, interface, value
/// type, event type, exception or home may not be redefined within the
/// immediate scope" of that same construct, and prints
/// `module M { typedef short M; }` as its own `// Error` example. The
/// case is in the corpus on purpose — it measures which vendors refuse
/// the file and which resolve it anyway — and
/// `tools/idlc/tests/corpus.rs` carries it as an `Intended` diagnostic
/// for the same reason.
///
/// Lowering now reports it (`DiagnosticCode::DuplicateName`), so every
/// corpus walk in this crate stops at the front end rather than at the
/// column. Named here once, so the reason is stated once and the five
/// walks cannot drift apart.
///
/// A list and never a pattern: a case on it that starts lowering is a
/// finding, and the walks assert that it is still refused.
pub const REFUSED_BY_THE_FRONT_END: & = &;
/// A corpus walk's failure lines, minus the ones
/// [`REFUSED_BY_THE_FRONT_END`] accounts for.
///
/// Checked in both directions, the way the two
/// `*_corpus_compiles.rs` gates check their own `REFUSED` lists: a line
/// that is not on the list stays a failure, and a listed case that
/// produced no line at all is reported here rather than passing
/// silently. An exemption nothing checks is an exemption that outlives
/// its cause.
///
/// The lines are `"{case}: {why}"`, which is the shape every walk in
/// this crate builds.
pub