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;
Type *argType(unsigned index);
bool hasRegularCtor(bool checkDisabled = false);
bool hasRegularCtor(bool ignoreDisabled = false);
};
class UnionDeclaration final : public StructDeclaration

View file

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

View file

@ -7441,7 +7441,7 @@ public:
void accept(Visitor* v) override;
uint32_t numArgTypes() const;
Type* argType(uint32_t index);
bool hasRegularCtor(bool checkDisabled = false);
bool hasRegularCtor(bool ignoreDisabled = false);
};
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.
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();
}
sd.size(i.loc);

View file

@ -3,8 +3,10 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail21547.d(32): Error: struct `Bar` has constructors, cannot use `{ initializers }`, use `Bar( initializers )` instead
fail_compilation/fail21547.d(33): Error: struct `Bar1` has constructors, cannot use `{ initializers }`, use `Bar1( 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(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:
---
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 }`
---
*/