|
| 1 | +/* |
| 2 | +REQUIRED_ARGS: -verrors=simple |
| 3 | +TEST_OUTPUT: |
| 4 | +--- |
| 5 | +compilable/deprecated_enum_member.d(33): Deprecation: enum member `deprecated_enum_member.anon` is deprecated |
| 6 | +compilable/deprecated_enum_member.d(28): `anon` is declared here |
| 7 | +compilable/deprecated_enum_member.d(36): Deprecation: enum member `deprecated_enum_member.E.named` is deprecated |
| 8 | +compilable/deprecated_enum_member.d(29): `named` is declared here |
| 9 | +compilable/deprecated_enum_member.d(39): Deprecation: enum member `deprecated_enum_member.E.named` is deprecated |
| 10 | +compilable/deprecated_enum_member.d(29): `named` is declared here |
| 11 | +compilable/deprecated_enum_member.d(42): Deprecation: enum member `deprecated_enum_member.F.withMsg` is deprecated - use namedB |
| 12 | +compilable/deprecated_enum_member.d(30): `withMsg` is declared here |
| 13 | +compilable/deprecated_enum_member.d(43): Deprecation: enum member `deprecated_enum_member.F.withMsg` is deprecated - use namedB |
| 14 | +compilable/deprecated_enum_member.d(30): `withMsg` is declared here |
| 15 | +compilable/deprecated_enum_member.d(47): Deprecation: enum member `deprecated_enum_member.anon` is deprecated |
| 16 | +compilable/deprecated_enum_member.d(28): `anon` is declared here |
| 17 | +compilable/deprecated_enum_member.d(47): Deprecation: enum member `deprecated_enum_member.anon` is deprecated |
| 18 | +compilable/deprecated_enum_member.d(28): `anon` is declared here |
| 19 | +--- |
| 20 | +*/ |
| 21 | + |
| 22 | +// A deprecated enum member must emit its deprecation diagnostic exactly once per |
| 23 | +// use, regardless of how it is named. Previously an enum member accessed by its |
| 24 | +// unqualified name (an anonymous-enum member, a member found via `with`, or an |
| 25 | +// ImportC enumerator) reported the deprecation twice, because the symbol was |
| 26 | +// checked both during name resolution and again in getVarExp(). See issue 23241. |
| 27 | + |
| 28 | +enum { deprecated anon = 0, anonB } |
| 29 | +enum E { deprecated named = 0, namedB } |
| 30 | +enum F { deprecated("use namedB") withMsg = 0, plain } |
| 31 | + |
| 32 | +// Anonymous enum member, accessed by its unqualified name. |
| 33 | +int useAnon() { return anon; } |
| 34 | + |
| 35 | +// Named enum member, accessed by its fully qualified name. |
| 36 | +int useNamedQualified() { return E.named; } |
| 37 | + |
| 38 | +// Named enum member, accessed by its unqualified name brought into scope by `with`. |
| 39 | +int useNamedWith() { E e; with (e) return named; } |
| 40 | + |
| 41 | +// A deprecated member carrying an explicit message reproduces that message. |
| 42 | +int useWithMsgQualified() { return F.withMsg; } |
| 43 | +int useWithMsgWith() { F f; with (f) return withMsg; } |
| 44 | + |
| 45 | +// Each separate use emits its own diagnostic (the fix removes a duplicate per use, |
| 46 | +// it does not globally deduplicate distinct uses). |
| 47 | +int useAnonAgain() { return anon + anon; } |
| 48 | + |
| 49 | +// Non-deprecated members of the same enums emit nothing. |
| 50 | +int useClean() { return anonB + E.namedB + F.plain; } |
| 51 | + |
| 52 | +// A use from within a deprecated scope is suppressed entirely. |
| 53 | +deprecated int useFromDeprecated() { return anon + E.named + F.withMsg; } |
0 commit comments