summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-conversion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-check-conversion.cpp')
-rw-r--r--source/slang/slang-check-conversion.cpp52
1 files changed, 24 insertions, 28 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 357b75cce..abe9f4817 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -891,43 +891,39 @@ namespace Slang
}
return true;
}
- // If we are casting to an interface type, then that will succeed
- // if the "from" type conforms to the interface.
+
+ // A type is always convertible to any of its supertypes.
//
- if (auto toDeclRefType = as<DeclRefType>(toType))
+ if(auto witness = tryGetSubtypeWitness(fromType, toType))
{
- auto toTypeDeclRef = toDeclRefType->declRef;
- if (auto toAggTypeDeclRef = toTypeDeclRef.as<AggTypeDecl>())
+ if (outToExpr)
{
- if(auto witness = tryGetSubtypeWitness(fromType, toAggTypeDeclRef))
+ *outToExpr = createCastToSuperTypeExpr(toType, fromExpr, witness);
+
+ // If the original expression was an l-value, then the result
+ // of the cast may be an l-value itself. We want to be able
+ // to invoke `[mutating]` methods on a value that is cast to
+ // an interface it conforms to, and we also expect to be able
+ // to pass a value of a derived `struct` type into methods that
+ // expect a value of its base type.
+ //
+ // TODO: vet this logic for correctness.
+ //
+ if (fromExpr && fromExpr->type.isLeftValue)
{
- if (outToExpr)
- {
- *outToExpr = createCastToSuperTypeExpr(toType, fromExpr, witness);
-
- // If the original expression was an l-value, then the result
- // of the cast may be an l-value itself. We want to be able
- // to invoke `[mutating]` methods on a value that is cast to
- // an interface it conforms to, and we also expect to be able
- // to pass a value of a derived `struct` type into methods that
- // expect a value of its base type.
- //
- // TODO: vet this logic for correctness.
- //
- if (fromExpr && fromExpr->type.isLeftValue)
- {
- (*outToExpr)->type.isLeftValue = true;
- }
- }
- if (outCost)
- *outCost = kConversionCost_CastToInterface;
- return true;
+ (*outToExpr)->type.isLeftValue = true;
}
}
+ if (outCost)
+ *outCost = kConversionCost_CastToInterface;
+ return true;
}
// Disallow converting to a ParameterGroupType.
- if (const auto toParameterGroupType = as<ParameterGroupType>(toType))
+ //
+ // TODO(tfoley): Under what circumstances would this check ever be needed?
+ //
+ if (auto toParameterGroupType = as<ParameterGroupType>(toType))
{
return _failedCoercion(toType, outToExpr, fromExpr);
}