diff options
| author | Yong He <yonghe@outlook.com> | 2024-03-28 16:57:53 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-28 16:57:53 -0700 |
| commit | 75afa659e9a16589638083a1fcf9e879225619cd (patch) | |
| tree | 1462b68a47f2f1b4856e298185ad24145a4acc83 /source | |
| parent | 56928794d0800824dc91e150cb345b5fec24d930 (diff) | |
Fix type union logic in generic type inference. (#3852)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-ast-support-types.h | 9 | ||||
| -rw-r--r-- | source/slang/slang-check-constraint.cpp | 12 | ||||
| -rw-r--r-- | source/slang/slang-check-conversion.cpp | 11 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang.natvis | 10 |
6 files changed, 38 insertions, 14 deletions
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h index 196a1d002..93fc3365d 100644 --- a/source/slang/slang-ast-support-types.h +++ b/source/slang/slang-ast-support-types.h @@ -140,12 +140,15 @@ namespace Slang // Cost of converting a pointer to bool kConversionCost_PtrToBool = 400, + // Cost of converting an integer to int16_t + kConversionCost_IntegerTruncate = 450, + + // Cost of converting an integer to a half type + kConversionCost_IntegerToHalfConversion = 500, + // Default case (usable for user-defined conversions) kConversionCost_Default = 500, - // Cost of converting an integer to int16_t - kConversionCost_IntegerTruncate = 700, - // Catch-all for conversions that should be discouraged // (i.e., that really shouldn't be made implicitly) // diff --git a/source/slang/slang-check-constraint.cpp b/source/slang/slang-check-constraint.cpp index 97dbbcfa3..6a9b0adfa 100644 --- a/source/slang/slang-check-constraint.cpp +++ b/source/slang/slang-check-constraint.cpp @@ -105,6 +105,7 @@ namespace Slang // through types `X` that are also builtin scalar types. // Type* bestType = nullptr; + ConversionCost bestCost = kConversionCost_Explicit; if(auto basicType = dynamicCast<BasicExpressionType>(type)) { for(Int baseTypeFlavorIndex = 0; baseTypeFlavorIndex < Int(BaseType::CountOf); baseTypeFlavorIndex++) @@ -123,7 +124,8 @@ namespace Slang continue; // We only want to consider types where we can implicitly convert from `type` - if(!canConvertImplicitly(candidateType, type)) + auto conversionCost = getConversionCost(candidateType, type); + if(!canConvertImplicitly(conversionCost)) continue; // At this point, we have a candidate type that is usable. @@ -139,18 +141,16 @@ namespace Slang // Otherwise, we want to pick the "better" type between `candidateType` // and `bestType`. // - // We are going to be a bit loose here, and not worry about the - // case where conversion is allowed in both directions. + // The candidate type that has lower conversion cost from `type` is better. // - // TODO: make this completely robust. - // - if(canConvertImplicitly(bestType, candidateType)) + if(conversionCost < bestCost) { // Our candidate can convert to the current "best" type, so // it is logically a more specific type that satisfies our // constraints, therefore we should keep it. // bestType = candidateType; + bestCost = conversionCost; } } } diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp index aeb964cc9..e55a88077 100644 --- a/source/slang/slang-check-conversion.cpp +++ b/source/slang/slang-check-conversion.cpp @@ -1389,13 +1389,22 @@ namespace Slang } bool SemanticsVisitor::canConvertImplicitly( + ConversionCost conversionCost) + { + // Is the conversion cheap enough to be done implicitly? + if (conversionCost >= kConversionCost_GeneralConversion) + return false; + return true; + } + + bool SemanticsVisitor::canConvertImplicitly( Type* toType, QualType fromType) { auto conversionCost = getConversionCost(toType, fromType); // Is the conversion cheap enough to be done implicitly? - if (conversionCost >= kConversionCost_GeneralConversion) + if (canConvertImplicitly(conversionCost)) return false; return true; diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index a3ecc28b4..945618f36 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -2077,6 +2077,9 @@ namespace Slang Type* toType, QualType fromType); + bool canConvertImplicitly( + ConversionCost cost); + ConversionCost getConversionCost(Type* toType, QualType fromType); Type* _tryJoinTypeWithInterface( diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 2bc24d8ec..3c8b48e00 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -222,7 +222,12 @@ namespace Slang { return kConversionCost_IntegerToFloatConversion; } - + else if (toInfo.conversionKind == kBaseTypeConversionKind_Float + && toInfo.conversionRank >= kBaseTypeConversionRank_Int16 + && fromInfo.conversionRank >= kBaseTypeConversionRank_Int8) + { + return kConversionCost_IntegerToHalfConversion; + } // All other cases are considered as "general" conversions, // where we don't consider any one conversion better than // any others. diff --git a/source/slang/slang.natvis b/source/slang/slang.natvis index b1b52bc5c..c86faa065 100644 --- a/source/slang/slang.natvis +++ b/source/slang/slang.natvis @@ -439,7 +439,6 @@ <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::ResourceType">(Slang::ResourceType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TextureTypeBase">(Slang::TextureTypeBase*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TextureType">(Slang::TextureType*)&astNodeType</ExpandedItem> - <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TextureSamplerType">(Slang::TextureSamplerType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::GLSLImageType">(Slang::GLSLImageType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::SamplerStateType">(Slang::SamplerStateType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::BuiltinGenericType">(Slang::BuiltinGenericType*)&astNodeType</ExpandedItem> @@ -504,6 +503,13 @@ <Item Name="[Raw View]">(Slang::Type*)this,!</Item> </Expand> </Type> + <Type Name="Slang::DirectDeclRef"> + <DisplayString>DirectDeclRef{(Decl*)m_operands.m_buffer[0].values.nodeOperand}</DisplayString> + <Expand> + <ExpandedItem>(Decl*)m_operands.m_buffer[0].values.nodeOperand</ExpandedItem> + + </Expand> + </Type> <Type Name="Slang::SubstitutionSet"> <DisplayString>SubstitutionSet{declRef,en}</DisplayString> <Expand> @@ -581,7 +587,6 @@ <DisplayString Condition="astNodeType == Slang::ASTNodeType::ResourceType">{*(Slang::ResourceType*)this}</DisplayString> <DisplayString Condition="astNodeType == Slang::ASTNodeType::TextureTypeBase">{*(Slang::TextureTypeBase*)this}</DisplayString> <DisplayString Condition="astNodeType == Slang::ASTNodeType::TextureType">{*(Slang::TextureType*)this}</DisplayString> - <DisplayString Condition="astNodeType == Slang::ASTNodeType::TextureSamplerType">{*(Slang::TextureSamplerType*)this}</DisplayString> <DisplayString Condition="astNodeType == Slang::ASTNodeType::GLSLImageType">{*(Slang::GLSLImageType*)this}</DisplayString> <DisplayString Condition="astNodeType == Slang::ASTNodeType::SamplerStateType">{*(Slang::SamplerStateType*)this}</DisplayString> <DisplayString Condition="astNodeType == Slang::ASTNodeType::BuiltinGenericType">{*(Slang::BuiltinGenericType*)this}</DisplayString> @@ -666,7 +671,6 @@ <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::ResourceType">(Slang::ResourceType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TextureTypeBase">(Slang::TextureTypeBase*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TextureType">(Slang::TextureType*)&astNodeType</ExpandedItem> - <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::TextureSamplerType">(Slang::TextureSamplerType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::GLSLImageType">(Slang::GLSLImageType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::SamplerStateType">(Slang::SamplerStateType*)&astNodeType</ExpandedItem> <ExpandedItem Condition="astNodeType == Slang::ASTNodeType::BuiltinGenericType">(Slang::BuiltinGenericType*)&astNodeType</ExpandedItem> |
