Fix error when struct initializer isn't accepted (#21086)

* Fix error when struct initializer isn't accepted

* Rename StructDeclaration.hasRegularCtor parameter to ignoreDisabled

checkDisabled detected disabled ctors when it was false, which was
confusing!

* Update tests
This commit is contained in:
Nick Treleaven 2025-03-26 10:28:07 +00:00 committed by GitHub
parent 3142290b6f
commit 13b0745e33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 16 additions and 11 deletions

View file

@ -196,7 +196,7 @@ public:
unsigned numArgTypes() const; unsigned numArgTypes() const;
Type *argType(unsigned index); Type *argType(unsigned index);
bool hasRegularCtor(bool checkDisabled = false); bool hasRegularCtor(bool ignoreDisabled = false);
}; };
class UnionDeclaration final : public StructDeclaration class UnionDeclaration final : public StructDeclaration

View file

@ -399,13 +399,12 @@ extern (C++) class StructDeclaration : AggregateDeclaration
* is not disabled. * is not disabled.
* *
* Params: * Params:
* checkDisabled = if the struct has a regular * ignoreDisabled = true to ignore disabled constructors
non-disabled constructor
* Returns: * Returns:
* true, if the struct has a regular (optionally, * true, if the struct has a regular (optionally,
* not disabled) constructor, false otherwise. * not disabled) constructor, false otherwise.
*/ */
final bool hasRegularCtor(bool checkDisabled = false) final bool hasRegularCtor(bool ignoreDisabled = false)
{ {
if (!ctor) if (!ctor)
return false; return false;
@ -415,7 +414,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
{ {
if (auto td = s.isTemplateDeclaration()) if (auto td = s.isTemplateDeclaration())
{ {
if (checkDisabled && td.onemember) if (ignoreDisabled && td.onemember)
{ {
if (auto ctorDecl = td.onemember.isCtorDeclaration()) if (auto ctorDecl = td.onemember.isCtorDeclaration())
{ {
@ -428,7 +427,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
} }
if (auto ctorDecl = s.isCtorDeclaration()) if (auto ctorDecl = s.isCtorDeclaration())
{ {
if (!ctorDecl.isCpCtor && (!checkDisabled || !(ctorDecl.storage_class & STC.disable))) if (!ctorDecl.isCpCtor && (!ignoreDisabled || !(ctorDecl.storage_class & STC.disable)))
{ {
result = true; result = true;
return 1; return 1;

View file

@ -7441,7 +7441,7 @@ public:
void accept(Visitor* v) override; void accept(Visitor* v) override;
uint32_t numArgTypes() const; uint32_t numArgTypes() const;
Type* argType(uint32_t index); Type* argType(uint32_t index);
bool hasRegularCtor(bool checkDisabled = false); bool hasRegularCtor(bool ignoreDisabled = false);
}; };
class UnionDeclaration final : public StructDeclaration class UnionDeclaration final : public StructDeclaration

View file

@ -153,7 +153,10 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
// that is not disabled. // that is not disabled.
if (sd.hasRegularCtor(true)) if (sd.hasRegularCtor(true))
{ {
error(i.loc, "%s `%s` has constructors, cannot use `{ initializers }`, use `%s( initializers )` instead", sd.kind(), sd.toChars(), sd.toChars()); error(i.loc, "Cannot use %s initializer syntax for %s `%s` because it has a constructor",
sd.kind(), sd.kind(), sd.toChars());
errorSupplemental(i.loc, "Use `%s( arguments )` instead of `{ initializers }`",
sd.toChars());
return err(); return err();
} }
sd.size(i.loc); sd.size(i.loc);

View file

@ -3,8 +3,10 @@
/* /*
TEST_OUTPUT: TEST_OUTPUT:
--- ---
fail_compilation/fail21547.d(32): Error: struct `Bar` has constructors, cannot use `{ initializers }`, use `Bar( initializers )` instead fail_compilation/fail21547.d(34): Error: Cannot use struct initializer syntax for struct `Bar` because it has a constructor
fail_compilation/fail21547.d(33): Error: struct `Bar1` has constructors, cannot use `{ initializers }`, use `Bar1( initializers )` instead fail_compilation/fail21547.d(34): Use `Bar( arguments )` instead of `{ initializers }`
fail_compilation/fail21547.d(35): Error: Cannot use struct initializer syntax for struct `Bar1` because it has a constructor
fail_compilation/fail21547.d(35): Use `Bar1( arguments )` instead of `{ initializers }`
--- ---
*/ */

View file

@ -1,7 +1,8 @@
/* /*
TEST_OUTPUT: TEST_OUTPUT:
--- ---
fail_compilation/fail336.d(16): Error: struct `S` has constructors, cannot use `{ initializers }`, use `S( initializers )` instead fail_compilation/fail336.d(17): Error: Cannot use struct initializer syntax for struct `S` because it has a constructor
fail_compilation/fail336.d(17): Use `S( arguments )` instead of `{ initializers }`
--- ---
*/ */