diff options
Diffstat (limited to 'source/slang/slang-check-conversion.cpp')
| -rw-r--r-- | source/slang/slang-check-conversion.cpp | 52 |
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); } |
