diff options
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 56b0a991b..351d5a9cc 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -1843,6 +1843,14 @@ namespace Slang return false; } + if (satisfyingMemberDeclRef.getDecl()->hasModifier<ConstRefAttribute>() + && !requiredMemberDeclRef.getDecl()->hasModifier<ConstRefAttribute>()) + { + // A `[constref]` method can't satisfy a non-`[constref]` requirement, + // but vice-versa is okay. + return false; + } + if(satisfyingMemberDeclRef.getDecl()->hasModifier<HLSLStaticModifier>() != requiredMemberDeclRef.getDecl()->hasModifier<HLSLStaticModifier>()) { @@ -2710,7 +2718,14 @@ namespace Slang auto synMutatingAttr = m_astBuilder->create<MutatingAttribute>(); addModifier(synFuncDecl, synMutatingAttr); } - + if (requiredMemberDeclRef.getDecl()->hasModifier<ConstRefAttribute>()) + { + // If the interface requirement is `[constref]` then our + // synthesized method should be too. + // + auto synConstRefAttr = m_astBuilder->create<ConstRefAttribute>(); + addModifier(synFuncDecl, synConstRefAttr); + } if (requiredMemberDeclRef.getDecl()->hasModifier<NoDiffThisAttribute>()) { auto noDiffThisAttr = m_astBuilder->create<NoDiffThisAttribute>(); @@ -5161,6 +5176,11 @@ namespace Slang // if(fstParam.getDecl()->hasModifier<RefModifier>() != sndParam.getDecl()->hasModifier<RefModifier>()) return false; + + // If one parameter is `constref` and the other isn't, then they don't match. + // + if (fstParam.getDecl()->hasModifier<ConstRefModifier>() != sndParam.getDecl()->hasModifier<ConstRefModifier>()) + return false; } // Note(tfoley): return type doesn't enter into it, because we can't take @@ -5625,20 +5645,31 @@ namespace Slang // Remove all existing direction modifiers, and replace them with a single Ref modifier. List<Modifier*> newModifiers; bool hasRefModifier = false; + bool isMutable = false; for (auto modifier : paramDecl->modifiers) { - if (as<InModifier>(modifier) || as<InOutModifier>(modifier) || as<OutModifier>(modifier)) + if (as<InModifier>(modifier)) + { + continue; + } + else if (as<InOutModifier>(modifier) || as<OutModifier>(modifier)) { + isMutable = true; continue; } - if (as<RefModifier>(modifier)) + if (as<RefModifier>(modifier) || as<ConstRefModifier>(modifier)) { hasRefModifier = true; } newModifiers.add(modifier); } if (!hasRefModifier) - newModifiers.add(this->getASTBuilder()->create<RefModifier>()); + { + if (isMutable) + newModifiers.add(this->getASTBuilder()->create<RefModifier>()); + else + newModifiers.add(this->getASTBuilder()->create<ConstRefModifier>()); + } paramDecl->modifiers.first = newModifiers.getFirst(); for (Index i = 0; i < newModifiers.getCount(); i++) { @@ -5774,6 +5805,9 @@ namespace Slang case ParameterDirection::kParameterDirection_Ref: addModifier(param, m_astBuilder->create<RefModifier>()); break; + case ParameterDirection::kParameterDirection_ConstRef: + addModifier(param, m_astBuilder->create<ConstRefModifier>()); + break; default: break; } @@ -5879,7 +5913,9 @@ namespace Slang // specialization. for (auto paramDecl : decl->getParameters()) { - if (paramDecl->type.type && !isTypeDifferentiable(paramDecl->type.type)) + if (!paramDecl->type.type) + continue; + if (!isTypeDifferentiable(paramDecl->type.type)) { if (!paramDecl->hasModifier<NoDiffModifier>()) { @@ -5888,6 +5924,24 @@ namespace Slang addModifier(paramDecl, noDiffModifier); } } + if (!paramDecl->hasModifier<NoDiffModifier>()) + { + if (auto modifier = paramDecl->findModifier<ConstRefModifier>()) + { + getSink()->diagnose(modifier, Diagnostics::cannotUseConstRefOnDifferentiableParameter); + } + } + } + if (!isEffectivelyStatic(decl)) + { + auto constrefAttr = decl->findModifier<ConstRefAttribute>(); + if (constrefAttr) + { + if (isTypeDifferentiable(calcThisType(getParentDecl(decl)))) + { + getSink()->diagnose(constrefAttr, Diagnostics::cannotUseConstRefOnDifferentiableMemberMethod); + } + } } } } |
