Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/slang/hlsl.meta.slang
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ interface ITexelElement
{
associatedtype Element : __BuiltinArithmeticType;
static const int elementCount;
[OverloadRank(-1)]
__init(Element x);
}

Expand Down
6 changes: 4 additions & 2 deletions source/slang/slang-check-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7545,7 +7545,9 @@ void SemanticsVisitor::checkExtensionConformance(ExtensionDecl* decl)
.as<ExtensionDecl>();
auto targetType = getTargetType(m_astBuilder, declRef);

for (auto inheritanceDecl : decl->getMembersOfType<InheritanceDecl>())
// Make a copy of inhertanceDecls first since `checkConformance` may modify decl->members.
auto inheritanceDecls = decl->getMembersOfType<InheritanceDecl>().toList();
for (auto inheritanceDecl : inheritanceDecls)
{
checkConformance(targetType, inheritanceDecl, decl);
}
Expand Down Expand Up @@ -7596,7 +7598,7 @@ void SemanticsVisitor::checkAggTypeConformance(AggTypeDecl* decl)
// just with `abstract` methods that replicate things?
// (That's what C# does).

// Make a copy of inhertanceDecls firstsince `checkConformance` may modify decl->members.
// Make a copy of inhertanceDecls first since `checkConformance` may modify decl->members.
auto inheritanceDecls = decl->getMembersOfType<InheritanceDecl>().toList();
for (auto inheritanceDecl : inheritanceDecls)
{
Expand Down
13 changes: 7 additions & 6 deletions source/slang/slang-check-inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,14 +450,15 @@ InheritanceInfo SharedSemanticsContext::_calcInheritanceInfo(
// then we need to add the extension itself as a facet.
//
auto extDeclRef =
createDefaultSubstitutionsIfNeeded(astBuilder, &visitor, extensionDecl);
auto selfExtFacet = new (arena) Facet::Impl(
createDefaultSubstitutionsIfNeeded(astBuilder, &visitor, extensionDecl)
.as<ExtensionDecl>();
auto extInheritanceInfo = getInheritanceInfo(extDeclRef, circularityInfo);
addDirectBaseFacet(
Facet::Kind::Extension,
Facet::Directness::Direct,
extDeclRef,
selfType,
astBuilder->getTypeEqualityWitness(selfType));
allFacets.add(selfExtFacet);
selfIsSelf,
extDeclRef,
extInheritanceInfo);
}
}

Expand Down
32 changes: 28 additions & 4 deletions source/slang/slang-check-overload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,34 @@ int SemanticsVisitor::CompareLookupResultItems(
LookupResultItem const& left,
LookupResultItem const& right)
{
auto leftDeclRefParent = getParentDeclRef(left.declRef);
auto rightDeclRefParent = getParentDeclRef(right.declRef);

bool leftIsExtension = false;
bool rightIsExtension = false;
bool leftIsFreeFormExtension = false;
bool rightIsFreeFormExtension = false;

// Prefer declarations that are not in free-form generic extensions, i.e.
// `extension<T:IFoo> T { /* declaration here should have lower precedence. */ }
if (auto leftExt = as<ExtensionDecl>(leftDeclRefParent.getDecl()))
{
leftIsExtension = true;
if (isDeclRefTypeOf<GenericTypeParamDeclBase>(leftExt->targetType))
leftIsFreeFormExtension = true;
}
if (auto rightExt = as<ExtensionDecl>(rightDeclRefParent.getDecl()))
{
rightIsExtension = true;
if (isDeclRefTypeOf<GenericTypeParamDeclBase>(rightExt->targetType))
rightIsFreeFormExtension = true;
}

// If one of the candidates is a free-form extension, it is always worse than
// a non-free-form extension.
if (leftIsFreeFormExtension != rightIsFreeFormExtension)
return int(leftIsFreeFormExtension) - int(rightIsFreeFormExtension);

// It is possible for lookup to return both an interface requirement
// and the concrete function that satisfies that requirement.
// We always want to favor a concrete method over an interface
Expand All @@ -1334,16 +1362,12 @@ int SemanticsVisitor::CompareLookupResultItems(
// directly (it is only visible through the requirement witness
// information for inheritance declarations).
//
auto leftDeclRefParent = getParentDeclRef(left.declRef);
auto rightDeclRefParent = getParentDeclRef(right.declRef);
bool leftIsInterfaceRequirement = isInterfaceRequirement(left.declRef.getDecl());
bool rightIsInterfaceRequirement = isInterfaceRequirement(right.declRef.getDecl());
if (leftIsInterfaceRequirement != rightIsInterfaceRequirement)
return int(leftIsInterfaceRequirement) - int(rightIsInterfaceRequirement);

// Prefer non-extension declarations over extension declarations.
bool leftIsExtension = as<ExtensionDecl>(leftDeclRefParent.getDecl()) != nullptr;
bool rightIsExtension = as<ExtensionDecl>(rightDeclRefParent.getDecl()) != nullptr;
if (leftIsExtension != rightIsExtension)
{
// Add a special case for constructors, where we prefer the one that is not synthesized,
Expand Down
45 changes: 28 additions & 17 deletions source/slang/slang-lower-to-ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3094,9 +3094,10 @@ struct StmtLoweringVisitor;

void maybeEmitDebugLine(
IRGenContext* context,
StmtLoweringVisitor& visitor,
StmtLoweringVisitor* visitor,
Stmt* stmt,
SourceLoc loc = SourceLoc());
SourceLoc loc = SourceLoc(),
bool allowNullStmt = false);

// When lowering something callable (most commonly a function declaration),
// we need to construct an appropriate parameter list for the IR function
Expand Down Expand Up @@ -5221,6 +5222,8 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo>
auto afterBlock = builder->createBlock();
auto irCond = getSimpleVal(context, lowerRValueExpr(context, expr->arguments[0]));

maybeEmitDebugLine(context, nullptr, nullptr, irCond->sourceLoc, true);

// ifElse(<first param>, %true-block, %false-block, %after-block)
builder->emitIfElse(irCond, thenBlock, elseBlock, afterBlock);

Expand Down Expand Up @@ -6211,6 +6214,8 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>

auto irCond = getSimpleVal(context, lowerRValueExpr(context, condExpr));

maybeEmitDebugLine(context, this, stmt, condExpr->loc);

IRInst* ifInst = nullptr;

if (elseStmt)
Expand Down Expand Up @@ -6323,7 +6328,7 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
// want to emit the expression for the loop condition:
if (const auto condExpr = stmt->predicateExpression)
{
maybeEmitDebugLine(context, *this, stmt, condExpr->loc);
maybeEmitDebugLine(context, this, stmt, condExpr->loc);

auto irCondition =
getSimpleVal(context, lowerRValueExpr(context, stmt->predicateExpression));
Expand Down Expand Up @@ -6383,7 +6388,7 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
insertBlock(continueLabel);
if (auto incrExpr = stmt->sideEffectExpression)
{
maybeEmitDebugLine(context, *this, stmt, incrExpr->loc);
maybeEmitDebugLine(context, this, stmt, incrExpr->loc);
lowerRValueExpr(context, incrExpr);
}

Expand Down Expand Up @@ -6432,7 +6437,7 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
// want to emit the expression for the loop condition:
if (auto condExpr = stmt->predicate)
{
maybeEmitDebugLine(context, *this, stmt, condExpr->loc);
maybeEmitDebugLine(context, this, stmt, condExpr->loc);

auto irCondition = getSimpleVal(context, lowerRValueExpr(context, condExpr));

Expand Down Expand Up @@ -6498,7 +6503,7 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
// want to emit the expression for the loop condition:
if (auto condExpr = stmt->predicate)
{
maybeEmitDebugLine(context, *this, stmt, stmt->predicate->loc);
maybeEmitDebugLine(context, this, stmt, stmt->predicate->loc);

auto irCondition = getSimpleVal(context, lowerRValueExpr(context, condExpr));

Expand Down Expand Up @@ -7398,24 +7403,29 @@ IRInst* getOrEmitDebugSource(IRGenContext* context, PathInfo path)

void maybeEmitDebugLine(
IRGenContext* context,
StmtLoweringVisitor& visitor,
StmtLoweringVisitor* visitor,
Stmt* stmt,
SourceLoc loc)
SourceLoc loc,
bool allowNullStmt)
{
if (!context->includeDebugInfo)
return;
if (as<EmptyStmt>(stmt))
return;
if (!loc.isValid())
loc = stmt->loc;

if (!allowNullStmt)
{
if (as<EmptyStmt>(stmt))
return;
if (!loc.isValid())
loc = stmt->loc;
}

auto sourceManager = context->getLinkage()->getSourceManager();
auto sourceView = context->getLinkage()->getSourceManager()->findSourceView(loc);
auto sourceView = sourceManager->findSourceView(loc);
if (!sourceView)
return;

IRInst* debugSourceInst = nullptr;
auto humaneLoc =
context->getLinkage()->getSourceManager()->getHumaneLoc(loc, SourceLocType::Emit);
auto humaneLoc = sourceManager->getHumaneLoc(loc, SourceLocType::Emit);

// Do a best-effort attempt to retrieve the nominal source file.
auto pathInfo = sourceView->getPathInfo(loc, SourceLocType::Emit);
Expand All @@ -7434,7 +7444,8 @@ void maybeEmitDebugLine(
{
debugSourceInst = getOrEmitDebugSource(context, pathInfo);
}
visitor.startBlockIfNeeded(stmt);
if (visitor)
visitor->startBlockIfNeeded(stmt);
context->irBuilder->emitDebugLine(
debugSourceInst,
humaneLoc.line,
Expand Down Expand Up @@ -7471,7 +7482,7 @@ void lowerStmt(IRGenContext* context, Stmt* stmt)

try
{
maybeEmitDebugLine(context, visitor, stmt, stmt->loc);
maybeEmitDebugLine(context, &visitor, stmt, stmt->loc);
visitor.dispatch(stmt);
}
// Don't emit any context message for an explicit `AbortCompilationException`
Expand Down
41 changes: 41 additions & 0 deletions tests/language-feature/extensions/extension-override-2.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//TEST:INTERPRET(filecheck=CHECK):
interface IBar
{}

interface IFoo : IBar
{
void execute();
}

struct Impl : IFoo
{
void execute()
{
printf("Impl::execute();\n");
}
}

extension<T:IBar> T : IFoo
{
void execute()
{
printf("Extension::execute();\n");
}
}

struct Base : IBar{}

void test<T:IFoo>(T t)
{
t.execute();
}

void main()
{
// CHECK: Impl::execute();
Impl f;
test(f);
// CHECK: Extension::execute();
Base b;
test(b);
}
Loading