Skip to content

Commit

Permalink
Keep fixing test errors
Browse files Browse the repository at this point in the history
1. When extension of a struct defines __init, we should not synthesize
   __init anymore.

2. For the synthesized __init signature, we correct the default value
   for the parameter. Figuring out what exactly is "default initialize
   type". If a type has a ctor can take 0 parameter, it's default
   initialize type.
  • Loading branch information
kaizhangNV committed Oct 9, 2024
1 parent 28dc6f9 commit b8094bd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
1 change: 1 addition & 0 deletions source/slang/slang-ast-decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ SLANG_UNREFLECTED
// We will use these auxiliary to help in synthesizing the member initialize constructor.
Slang::HashSet<VarDeclBase*> m_membersVisibleInCtor;
Dictionary<int, ConstructorDecl*> m_synthesizedCtorMap;
bool m_hasExplicitCtorInExtension = false;
};

class ClassDecl : public AggTypeDecl
Expand Down
53 changes: 41 additions & 12 deletions source/slang/slang-check-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2194,16 +2194,10 @@ namespace Slang
return true;
}

static Expr* constructDefaultInitExprForType(SemanticsVisitor* visitor, VarDeclBase* varDecl)
static Expr* constructDefaultConstructorForType(SemanticsVisitor* visitor, Type* type)
{
if (!varDecl->type || !varDecl->type.type)
return nullptr;

if (!isDefaultInitializable(varDecl))
return nullptr;

ConstructorDecl* defaultCtor = nullptr;
auto declRefType = as<DeclRefType>(varDecl->type.type);
auto declRefType = as<DeclRefType>(type);
if (declRefType)
{
if (auto structDecl = as<StructDecl>(declRefType->getDeclRef().getDecl()))
Expand All @@ -2219,6 +2213,22 @@ namespace Slang
invoke->functionExpr = visitor->ConstructDeclRefExpr(member, nullptr, defaultCtor->getName(), defaultCtor->loc, nullptr);
return invoke;
}

return nullptr;
}

static Expr* constructDefaultInitExprForType(SemanticsVisitor* visitor, VarDeclBase* varDecl)
{
if (!varDecl->type || !varDecl->type.type)
return nullptr;

if (!isDefaultInitializable(varDecl))
return nullptr;

if (auto defaultInitExpr = constructDefaultConstructorForType(visitor, varDecl->type.type))
{
return defaultInitExpr;
}
else
{
auto* defaultCall = visitor->getASTBuilder()->create<DefaultConstructExpr>();
Expand Down Expand Up @@ -7241,6 +7251,10 @@ namespace Slang

auto _hasExplicitCtor = [](StructDecl* structDecl) -> bool
{
// First check if the extension of this struct defines an explicit constructor.
if (structDecl->m_hasExplicitCtorInExtension)
return true;

for (auto ctor : structDecl->getMembersOfType<ConstructorDecl>())
{
// constructor that is not synthesized must be user defined.
Expand Down Expand Up @@ -9232,6 +9246,15 @@ namespace Slang

_validateCrossModuleInheritance(decl, inheritanceDecl);
}

if(decl->getMembersOfType<ConstructorDecl>().getCount() > 0)
{
if (auto structDeclRef = isDeclRefTypeOf<StructDecl>(decl->targetType.type))
{
auto structDecl = structDeclRef.getDecl();
structDecl->m_hasExplicitCtorInExtension = true;
}
}
}

Type* SemanticsVisitor::calcThisType(DeclRef<Decl> declRef)
Expand Down Expand Up @@ -11347,9 +11370,9 @@ namespace Slang

// If a struct's member has:
// 1. an initialize expersion: Struct S {int a = 1;}; or
// 2. a default value: Struct T{}; Struct S {T t;}
// Note, If a type is not default initializable, it doesn't have default value.
// it can be associated with default value expression in the constructor signature.
// 2. this member is a default initializable type.
// See https://github.com/shader-slang/slang/blob/master/docs/proposals/004-initialization.md#default-initializable-type
// for the definition of "Default Initializable type".
// This function helps to check whether either of those 2 conditions are met and create
// a default value for the parameter.
// It's totally fine that there is no default value for the parameter, in this case, user
Expand All @@ -11364,7 +11387,13 @@ namespace Slang

// For the 2nd condition, we need to check if the type is default initializable, if so,
// we can use the default constructor.
return constructDefaultInitExprForType(visitor, varDecl);
if (!varDecl->type || !varDecl->type.type)
return nullptr;

if (!isDefaultInitializable(varDecl))
return nullptr;

return constructDefaultConstructorForType(visitor, varDecl->type.type);
}

void SemanticsDeclAttributesVisitor::_synthesizeCtorSignature(StructDecl* structDecl)
Expand Down
1 change: 1 addition & 0 deletions tests/diagnostics/mismatching-types.slang
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ void main(uint3 dispatchThreadID : SV_DispatchThreadID)
// expected an expression of type 'GenericOuter<int>.NonGenericInner', got 'GenericOuter<float>.NonGenericInner'
a.ng = b.ng;
// expected an expression of type 'NonGenericOuter.GenericInner<int>', got 'int'
// explicit conversion from 'int' to 'GenericInner<int>' is possible
c.i = 0;
// expected an expression of type 'NonGenericOuter.GenericInner<int>', got 'NonGenericOuter.GenericInner<float>'
c.i = c.f;
Expand Down
2 changes: 2 additions & 0 deletions tests/diagnostics/mismatching-types.slang.expected
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ tests/diagnostics/mismatching-types.slang(63): error 30019: expected an expressi
tests/diagnostics/mismatching-types.slang(65): error 30019: expected an expression of type 'GenericInner<int>', got 'int'
c.i = 0;
^
tests/diagnostics/mismatching-types.slang(65): note: explicit conversion from 'int' to 'GenericInner<int>' is possible
tests/diagnostics/mismatching-types.slang(67): error 30019: expected an expression of type 'GenericInner<int>', got 'GenericInner<float>'
c.i = c.f;
^
Expand All @@ -32,6 +33,7 @@ tests/diagnostics/mismatching-types.slang(80): error 30019: expected an expressi
^~~
tests/diagnostics/mismatching-types.slang(82): error 30019: expected an expression of type 'Texture2D<float>', got 'Texture1D<float>'
Texture2D<float> t2 = tex;
^~~
}
standard output = {
}

0 comments on commit b8094bd

Please sign in to comment.