summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-check-expr.cpp')
-rw-r--r--source/slang/slang-check-expr.cpp42
1 files changed, 16 insertions, 26 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 89a7373ee..33a1fa680 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -3183,8 +3183,12 @@ namespace Slang
expr->type = m_astBuilder->getBoolType();
expr->value = originalVal;
+ auto valueType = expr->value->type.type;
+ if (auto typeType = as<TypeType>(valueType))
+ valueType = typeType->getType();
+
// If value is a subtype of `type`, then this expr is always true.
- if(isSubtype(expr->value->type.type, expr->typeExpr.type))
+ if(isSubtype(valueType, expr->typeExpr.type))
{
// Instead of returning a BoolLiteralExpr, we use a field to indicate this scenario,
// so that the language server can still see the original syntax tree.
@@ -3195,10 +3199,11 @@ namespace Slang
return expr;
}
- // Otherwise, we need to ensure the target type is a subtype of value->type.
+ // Otherwise, if the target type is a subtype of value->type, we need to grab the
+ // subtype witness for runtime checks.
expr->value = maybeOpenExistential(originalVal);
- expr->witnessArg = tryGetSubtypeWitness(expr->typeExpr.type, originalVal->type.type);
+ expr->witnessArg = tryGetSubtypeWitness(expr->typeExpr.type, valueType);
if (expr->witnessArg)
{
// For now we can only support the scenario where `expr->value` is an interface type.
@@ -3208,15 +3213,6 @@ namespace Slang
}
return expr;
}
-
- if (!as<ErrorType>(expr->typeExpr.type) && !as<ErrorType>(expr->value->type.type))
- {
- // The type is not in the same hierarchy, so we evaluate to false.
- expr->constantVal = m_astBuilder->create<BoolLiteralExpr>();
- expr->constantVal->type = m_astBuilder->getBoolType();
- expr->constantVal->value = false;
- expr->constantVal->loc = expr->loc;
- }
return expr;
}
@@ -3241,27 +3237,21 @@ namespace Slang
return makeOptional;
}
- // For now we can only support the scenario where `expr->value` is an interface type.
- if (!isInterfaceType(expr->value->type))
- {
- getSink()->diagnose(expr, Diagnostics::isOperatorValueMustBeInterfaceType);
- }
-
- expr->typeExpr = typeExpr.exp;
+ // If target type is an interface type, we will obtain the witness here for
+ // runtime casting.
expr->witnessArg = tryGetSubtypeWitness(typeExpr.type, expr->value->type.type);
if (expr->witnessArg)
{
+ // For now we can only support the scenario where `expr->value` is an interface type.
+ if (!isInterfaceType(expr->value->type.type))
+ {
+ getSink()->diagnose(expr, Diagnostics::isOperatorValueMustBeInterfaceType);
+ }
expr->value = maybeOpenExistential(expr->value);
return expr;
}
- if (!as<ErrorType>(typeExpr.type) && !as<ErrorType>(expr->value->type.type))
- {
- getSink()->diagnose(expr, Diagnostics::typeNotInTheSameHierarchy, expr->value->type.type, typeExpr.type);
- }
-
- expr->type = m_astBuilder->getErrorType();
-
+ expr->typeExpr = typeExpr.exp;
return expr;
}