summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorJay Kwak <82421531+jkwak-work@users.noreply.github.com>2025-05-15 01:55:17 +0000
committerGitHub <noreply@github.com>2025-05-15 01:55:17 +0000
commit2275e18fc052239fe67f3fda68252ad92bb83ca9 (patch)
tree19cdf1917811e1c40362ef468c5d3d6a20344517 /source/slang
parent8c98714df2198db1aff4ce6c6f7922850e400f80 (diff)
Do not print errors in _coerce when "JustTrying". (#7064)
* Do not print errors in _coerce when "JustTrying". While figuring out which generic-overload works best, `_coerce()` is printing errors and Slang compilation terminates prematurely. When `TryCheckGenericOverloadCandidateTypes()` is calling `_coerce()` in "JustTrying" mode, the error messages should be snoozed. The following logic shows the intention of how to silence the error messages, but the chain of `sink` was broken in the middle and `_coerce()` was using `getSink()` from the SemanticVisitor. val = ExtractGenericArgInteger( arg, getType(m_astBuilder, valParamRef), context.mode == OverloadResolveContext::Mode::JustTrying ? nullptr : getSink()); * Use tempSink when available.
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-check-conversion.cpp80
-rw-r--r--source/slang/slang-check-decl.cpp15
-rw-r--r--source/slang/slang-check-expr.cpp20
-rw-r--r--source/slang/slang-check-impl.h5
-rw-r--r--source/slang/slang-check-modifier.cpp2
-rw-r--r--source/slang/slang-check-overload.cpp9
-rw-r--r--source/slang/slang-check-stmt.cpp6
7 files changed, 89 insertions, 48 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index a2cb0f91b..68e5df7ce 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -137,6 +137,7 @@ bool SemanticsVisitor::_readValueFromInitializerList(
outToExpr,
firstInitExpr->type,
firstInitExpr,
+ getSink(),
nullptr);
}
@@ -491,7 +492,14 @@ bool SemanticsVisitor::_readAggregateValueFromInitializerList(
if (ioArgIndex < argCount)
{
auto arg = fromInitializerListExpr->args[ioArgIndex++];
- return _coerce(CoercionSite::Initializer, toType, outToExpr, arg->type, arg, nullptr);
+ return _coerce(
+ CoercionSite::Initializer,
+ toType,
+ outToExpr,
+ arg->type,
+ arg,
+ getSink(),
+ nullptr);
}
else
{
@@ -882,7 +890,7 @@ bool SemanticsVisitor::_coerceInitializerList(
// composition this shouldn't fail.
if (!as<InitializerListType>(fromInitializerListExpr->type) &&
!canCoerce(toType, fromInitializerListExpr->type, nullptr))
- return _failedCoercion(toType, outToExpr, fromInitializerListExpr);
+ return _failedCoercion(toType, outToExpr, fromInitializerListExpr, getSink());
// Try to invoke the user-defined constructor if it exists. This call will
// report error diagnostics if the used-defined constructor exists but does not
@@ -921,7 +929,11 @@ bool SemanticsVisitor::_coerceInitializerList(
return true;
}
-bool SemanticsVisitor::_failedCoercion(Type* toType, Expr** outToExpr, Expr* fromExpr)
+bool SemanticsVisitor::_failedCoercion(
+ Type* toType,
+ Expr** outToExpr,
+ Expr* fromExpr,
+ DiagnosticSink* sink)
{
if (outToExpr)
{
@@ -936,7 +948,10 @@ bool SemanticsVisitor::_failedCoercion(Type* toType, Expr** outToExpr, Expr* fro
}
else
{
- getSink()->diagnose(fromExpr->loc, Diagnostics::typeMismatch, toType, fromExpr->type);
+ if (sink)
+ {
+ sink->diagnose(fromExpr->loc, Diagnostics::typeMismatch, toType, fromExpr->type);
+ }
}
}
return false;
@@ -1108,6 +1123,7 @@ bool SemanticsVisitor::_coerce(
Expr** outToExpr,
QualType fromType,
Expr* fromExpr,
+ DiagnosticSink* sink,
ConversionCost* outCost)
{
// If we are about to try and coerce an overloaded expression,
@@ -1227,7 +1243,7 @@ bool SemanticsVisitor::_coerce(
//
if (!_canModifierBeAddedDuringCoercion(modifier))
{
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
}
}
@@ -1246,7 +1262,7 @@ bool SemanticsVisitor::_coerce(
//
if (!_canModifierBeDroppedDuringCoercion(modifier))
{
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
}
}
@@ -1425,7 +1441,7 @@ bool SemanticsVisitor::_coerce(
//
if (as<ParameterGroupType>(toType))
{
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
// We allow implicit conversion of a parameter group type like
@@ -1451,7 +1467,7 @@ bool SemanticsVisitor::_coerce(
derefExpr->checked = true;
}
- if (!_coerce(site, toType, outToExpr, fromElementType, derefExpr, &subCost))
+ if (!_coerce(site, toType, outToExpr, fromElementType, derefExpr, sink, &subCost))
{
return false;
}
@@ -1503,7 +1519,7 @@ bool SemanticsVisitor::_coerce(
openRefExpr = maybeOpenRef(fromExpr);
}
- if (!_coerce(site, toType, outToExpr, fromValueType, openRefExpr, &subCost))
+ if (!_coerce(site, toType, outToExpr, fromValueType, openRefExpr, sink, &subCost))
{
return false;
}
@@ -1550,7 +1566,7 @@ bool SemanticsVisitor::_coerce(
if (cachedMethod->conversionFuncOverloadCandidate.status !=
OverloadCandidate::Status::Applicable)
{
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
overloadContext.bestCandidateStorage = cachedMethod->conversionFuncOverloadCandidate;
overloadContext.bestCandidate = &overloadContext.bestCandidateStorage;
@@ -1594,7 +1610,7 @@ bool SemanticsVisitor::_coerce(
{
getShared()->cacheImplicitCastMethod(implicitCastKey, ImplicitCastMethod{});
}
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
// If all of the candidates in `bestCandidates` are applicable,
@@ -1622,7 +1638,10 @@ bool SemanticsVisitor::_coerce(
//
if (outToExpr)
{
- getSink()->diagnose(fromExpr, Diagnostics::ambiguousConversion, fromType, toType);
+ if (sink)
+ {
+ sink->diagnose(fromExpr, Diagnostics::ambiguousConversion, fromType, toType);
+ }
*outToExpr = CreateErrorExpr(fromExpr);
}
@@ -1653,7 +1672,7 @@ bool SemanticsVisitor::_coerce(
{
getShared()->cacheImplicitCastMethod(implicitCastKey, ImplicitCastMethod{});
}
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
// Next, we need to look at the implicit conversion
@@ -1675,12 +1694,15 @@ bool SemanticsVisitor::_coerce(
{
if (cost >= kConversionCost_Explicit)
{
- getSink()->diagnose(fromExpr, Diagnostics::typeMismatch, toType, fromType);
- getSink()->diagnoseWithoutSourceView(
- fromExpr,
- Diagnostics::noteExplicitConversionPossible,
- fromType,
- toType);
+ if (sink)
+ {
+ sink->diagnose(fromExpr, Diagnostics::typeMismatch, toType, fromType);
+ sink->diagnoseWithoutSourceView(
+ fromExpr,
+ Diagnostics::noteExplicitConversionPossible,
+ fromType,
+ toType);
+ }
}
else if (cost >= kConversionCost_Default)
{
@@ -1704,9 +1726,9 @@ bool SemanticsVisitor::_coerce(
}
}
}
- if (shouldEmitGeneralWarning)
+ if (shouldEmitGeneralWarning && sink)
{
- getSink()->diagnose(
+ sink->diagnose(
fromExpr,
Diagnostics::unrecommendedImplicitConversion,
fromType,
@@ -1714,14 +1736,14 @@ bool SemanticsVisitor::_coerce(
}
}
- if (site == CoercionSite::Argument)
+ if (site == CoercionSite::Argument && sink)
{
auto builtinConversionKind = getImplicitConversionBuiltinKind(
overloadContext.bestCandidate->item.declRef.getDecl());
if (builtinConversionKind == kBuiltinConversion_FloatToDouble)
{
if (!as<FloatingPointLiteralExpr>(fromExpr))
- getSink()->diagnose(fromExpr, Diagnostics::implicitConversionToDouble);
+ sink->diagnose(fromExpr, Diagnostics::implicitConversionToDouble);
}
}
}
@@ -1788,7 +1810,7 @@ bool SemanticsVisitor::_coerce(
{
getShared()->cacheImplicitCastMethod(implicitCastKey, ImplicitCastMethod{});
}
- return _failedCoercion(toType, outToExpr, fromExpr);
+ return _failedCoercion(toType, outToExpr, fromExpr, sink);
}
bool SemanticsVisitor::canCoerce(
@@ -1830,7 +1852,7 @@ bool SemanticsVisitor::canCoerce(
// which suppresses emission of any diagnostics
// during the coercion process.
//
- bool rs = _coerce(CoercionSite::General, toType, nullptr, fromType, fromExpr, &cost);
+ bool rs = _coerce(CoercionSite::General, toType, nullptr, fromType, fromExpr, getSink(), &cost);
if (outCost)
*outCost = cost;
@@ -1887,10 +1909,14 @@ Expr* SemanticsVisitor::createModifierCastExpr(Type* toType, Expr* fromExpr)
}
-Expr* SemanticsVisitor::coerce(CoercionSite site, Type* toType, Expr* fromExpr)
+Expr* SemanticsVisitor::coerce(
+ CoercionSite site,
+ Type* toType,
+ Expr* fromExpr,
+ DiagnosticSink* sink)
{
Expr* expr = nullptr;
- if (!_coerce(site, toType, &expr, fromExpr->type, fromExpr, nullptr))
+ if (!_coerce(site, toType, &expr, fromExpr->type, fromExpr, sink, nullptr))
{
// Note(tfoley): We don't call `CreateErrorExpr` here, because that would
// clobber the type on `fromExpr`, and an invariant here is that coercion
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index c2c0c2cb6..bdd59c2c5 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1868,7 +1868,8 @@ void SemanticsDeclHeaderVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
if (auto initExpr = varDecl->initExpr)
{
initExpr = CheckTerm(initExpr);
- initExpr = coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr);
+ initExpr =
+ coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr, getSink());
varDecl->initExpr = initExpr;
maybeInferArraySizeForVariable(varDecl);
@@ -2348,7 +2349,7 @@ void SemanticsDeclBodyVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
if (initExpr->type.isWriteOnly)
getSink()->diagnose(initExpr, Diagnostics::readingFromWriteOnly);
- initExpr = coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr);
+ initExpr = coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr, getSink());
varDecl->initExpr = initExpr;
// We need to ensure that any variable doesn't introduce
@@ -4948,7 +4949,7 @@ bool SemanticsVisitor::trySynthesizeMethodRequirementWitness(
// so we also need to coerce the result of the call to
// the expected type.
//
- auto coercedCall = subVisitor.coerce(CoercionSite::Return, resultType, checkedCall);
+ auto coercedCall = subVisitor.coerce(CoercionSite::Return, resultType, checkedCall, getSink());
// If our overload resolution or type coercion failed,
// then we have not been able to synthesize a witness
@@ -5803,7 +5804,7 @@ bool SemanticsVisitor::synthesizeAccessorRequirements(
// the expected type of the property.
//
auto coercedMemberRef =
- subVisitor.coerce(CoercionSite::Return, resultType, synBoundStorageExpr);
+ subVisitor.coerce(CoercionSite::Return, resultType, synBoundStorageExpr, getSink());
auto synReturn = m_astBuilder->create<ReturnStmt>();
synReturn->expression = coercedMemberRef;
@@ -8092,7 +8093,7 @@ void SemanticsDeclBodyVisitor::visitEnumCaseDecl(EnumCaseDecl* decl)
if (auto initExpr = decl->tagExpr)
{
initExpr = CheckTerm(initExpr);
- initExpr = coerce(CoercionSite::General, tagType, initExpr);
+ initExpr = coerce(CoercionSite::General, tagType, initExpr, getSink());
// We want to enforce that this is an integer constant
// expression.
@@ -9139,7 +9140,7 @@ void SemanticsDeclBodyVisitor::visitParamDecl(ParamDecl* paramDecl)
// actual type of the parameter.
//
initExpr = CheckTerm(initExpr);
- initExpr = coerce(CoercionSite::Initializer, typeExpr.type, initExpr);
+ initExpr = coerce(CoercionSite::Initializer, typeExpr.type, initExpr, getSink());
paramDecl->initExpr = initExpr;
// TODO: a default argument expression needs to
@@ -9284,7 +9285,7 @@ void SemanticsDeclBodyVisitor::synthesizeCtorBodyForBases(
invoke->arguments.addRange(argumentList);
auto assign = m_astBuilder->create<AssignExpr>();
- assign->left = coerce(CoercionSite::Initializer, declRefType, thisExpr);
+ assign->left = coerce(CoercionSite::Initializer, declRefType, thisExpr, getSink());
assign->right = invoke;
auto stmt = m_astBuilder->create<ExpressionStmt>();
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index d151d37be..41f945763 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -518,7 +518,11 @@ Expr* SemanticsVisitor::constructDerefExpr(Expr* base, QualType elementType, Sou
{
if (auto resPtrType = as<DescriptorHandleType>(base->type))
{
- return coerce(CoercionSite::ExplicitCoercion, resPtrType->getElementType(), base);
+ return coerce(
+ CoercionSite::ExplicitCoercion,
+ resPtrType->getElementType(),
+ base,
+ getSink());
}
auto derefExpr = m_astBuilder->create<DerefExpr>();
@@ -2254,7 +2258,7 @@ IntVal* SemanticsVisitor::CheckIntegerConstantExpression(
switch (coercionType)
{
case IntegerConstantExpressionCoercionType::SpecificType:
- expr = coerce(CoercionSite::General, expectedType, inExpr);
+ expr = coerce(CoercionSite::General, expectedType, inExpr, sink);
break;
case IntegerConstantExpressionCoercionType::AnyInteger:
if (isScalarIntegerType(inExpr->type))
@@ -2262,7 +2266,7 @@ IntVal* SemanticsVisitor::CheckIntegerConstantExpression(
else if (isEnumType(inExpr->type))
expr = inExpr;
else
- expr = coerce(CoercionSite::General, m_astBuilder->getIntType(), inExpr);
+ expr = coerce(CoercionSite::General, m_astBuilder->getIntType(), inExpr, sink);
break;
default:
break;
@@ -2527,7 +2531,7 @@ Expr* SemanticsVisitor::checkAssignWithCheckedOperands(AssignExpr* expr)
type = atomicType->getElementType();
}
auto right = maybeOpenRef(expr->right);
- expr->right = coerce(CoercionSite::Assignment, type, right);
+ expr->right = coerce(CoercionSite::Assignment, type, right, getSink());
if (!expr->left->type.isLeftValue)
{
@@ -2956,7 +2960,7 @@ Expr* SemanticsExprVisitor::convertToLogicOperatorExpr(InvokeExpr* expr)
// to handle if this expression doesn't support short-circuiting.
for (auto& arg : expr->arguments)
{
- arg = coerce(CoercionSite::Argument, m_astBuilder->getBoolType(), arg);
+ arg = coerce(CoercionSite::Argument, m_astBuilder->getBoolType(), arg, getSink());
}
expr->functionExpr = CheckTerm(expr->functionExpr);
@@ -3920,7 +3924,11 @@ Expr* SemanticsExprVisitor::visitTypeCastExpr(TypeCastExpr* expr)
auto checkedInitListExpr = visitInitializerListExpr(initListExpr);
- return coerce(CoercionSite::General, typeExp.type, checkedInitListExpr);
+ return coerce(
+ CoercionSite::General,
+ typeExp.type,
+ checkedInitListExpr,
+ getSink());
}
}
}
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 6c9a0409d..f0884503f 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -1646,7 +1646,7 @@ public:
InitializerListExpr* fromInitializerListExpr);
/// Report that implicit type coercion is not possible.
- bool _failedCoercion(Type* toType, Expr** outToExpr, Expr* fromExpr);
+ bool _failedCoercion(Type* toType, Expr** outToExpr, Expr* fromExpr, DiagnosticSink* sink);
/// Central engine for implementing implicit coercion logic
///
@@ -1674,6 +1674,7 @@ public:
Expr** outToExpr,
QualType fromType,
Expr* fromExpr,
+ DiagnosticSink* sink,
ConversionCost* outCost);
/// Check whether implicit type coercion from `fromType` to `toType` is possible.
@@ -1698,7 +1699,7 @@ public:
Expr* createCastToInterfaceExpr(Type* toType, Expr* fromExpr, Val* witness);
/// Implicitly coerce `fromExpr` to `toType` and diagnose errors if it isn't possible
- Expr* coerce(CoercionSite site, Type* toType, Expr* fromExpr);
+ Expr* coerce(CoercionSite site, Type* toType, Expr* fromExpr, DiagnosticSink* sink);
// Fill in default substitutions for the 'subtype' part of a type constraint decl
void CheckConstraintSubType(TypeExp& typeExp);
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index cebcbe540..f9ad3a02f 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -828,7 +828,7 @@ Modifier* SemanticsVisitor::validateAttribute(
if (!typeChecked)
{
arg = CheckTerm(arg);
- arg = coerce(CoercionSite::Argument, paramDecl->getType(), arg);
+ arg = coerce(CoercionSite::Argument, paramDecl->getType(), arg, getSink());
}
}
paramIndex++;
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index 44fdf45cf..f13f9a99e 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -481,7 +481,11 @@ bool SemanticsVisitor::TryCheckGenericOverloadCandidateTypes(
}
else
{
- arg = coerce(CoercionSite::Argument, getType(m_astBuilder, valParamRef), arg);
+ arg = coerce(
+ CoercionSite::Argument,
+ getType(m_astBuilder, valParamRef),
+ arg,
+ getSink());
}
// If we have an argument to work with, then we will
@@ -712,7 +716,7 @@ bool SemanticsVisitor::TryCheckOverloadCandidateTypes(
}
else
{
- Expr* coercedExpr = coerce(CoercionSite::Argument, paramType, arg.argExpr);
+ Expr* coercedExpr = coerce(CoercionSite::Argument, paramType, arg.argExpr, getSink());
// Check if concrete-to-interface coercion caused loss of l-valueness.
if (coercedExpr && !coercedExpr->type.isLeftValue && paramType.isLeftValue &&
@@ -2650,6 +2654,7 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr)
&resultExpr,
expr->arguments[0]->type,
expr->arguments[0],
+ &tempSink,
&conversionCost);
if (coerceResult)
return resultExpr;
diff --git a/source/slang/slang-check-stmt.cpp b/source/slang/slang-check-stmt.cpp
index 0e5ed92aa..2dc8c2685 100644
--- a/source/slang/slang-check-stmt.cpp
+++ b/source/slang/slang-check-stmt.cpp
@@ -255,7 +255,7 @@ Expr* SemanticsVisitor::checkPredicateExpr(Expr* expr)
}
Expr* e = expr;
e = CheckTerm(e);
- e = coerce(CoercionSite::General, m_astBuilder->getBoolType(), e);
+ e = coerce(CoercionSite::General, m_astBuilder->getBoolType(), e, getSink());
return e;
}
@@ -408,7 +408,7 @@ void SemanticsStmtVisitor::visitCaseStmt(CaseStmt* stmt)
// Check that the type for the `case` is consistent with the type for the `switch`.
auto expr = CheckExpr(stmt->expr);
- expr = coerce(CoercionSite::Argument, switchStmt->condition->type, expr);
+ expr = coerce(CoercionSite::Argument, switchStmt->condition->type, expr, getSink());
// coerce to type being switch on, and ensure that value is a compile-time constant
// The Vals in the AST are pointer-unique, making them easy to check for duplicates
@@ -574,7 +574,7 @@ void SemanticsStmtVisitor::visitReturnStmt(ReturnStmt* stmt)
if (!m_parentLambdaExpr && expectedReturnType)
{
stmt->expression =
- coerce(CoercionSite::Return, expectedReturnType, stmt->expression);
+ coerce(CoercionSite::Return, expectedReturnType, stmt->expression, getSink());
}
}
}