mizvekov added a comment.

Hello, thanks, I appreciate that you found it helpful!

It's pretty late for me now, I will give this another look tomorrow.



================
Comment at: clang/include/clang/Sema/SemaConcept.h:48-52
+      if (ArgA.getKind() == TemplateArgument::Expression &&
+          ArgB.getKind() == TemplateArgument::Expression &&
+          ArgA.getAsExpr()->getType()->isUndeducedAutoType() &&
+          ArgB.getAsExpr()->getType()->isUndeducedAutoType())
+        continue;
----------------
ychen wrote:
> mizvekov wrote:
> > Why are looking at only the type of the expression?
> > The expression can be arbitrarily different, but as long as they are both 
> > undeduced auto, that is okay?
> In the partial ordering context, the expression is the same explicit template 
> argument. So we could treat two undeduced autos as equal. 
> 
> This code is to deal with the fact that, `AuoType` is currently being uniqued 
> on type constrained, which goes against the spirit of P2113R0 which considers 
> type constraints only when the two types are equivalent.
> 
> I think the more neat way is to unique auto template parameter with the kind 
> of placeholder type (`auto`, `auto*`, `auto&`, `decltype(auto)`, ...), and 
> its template parameter depth/index. Then we don't need the workaround here 
> and I could simplify the code in `SemaTemplateDeduction.cpp` too. WDYT?
If you mean a change so that constraints are not part of the canonical type of 
undeduced AutoType, that is worth a try.
I can't think right now of a reason why they should be part of it in the first 
place.


================
Comment at: clang/include/clang/Sema/SemaConcept.h:54-68
+      if (ArgA.getKind() == TemplateArgument::Type &&
+          ArgB.getKind() == TemplateArgument::Type)
+        if (const auto *SubstA =
+                ArgA.getAsType()->getAs<SubstTemplateTypeParmType>())
+          if (const auto *SubstB =
+                  ArgB.getAsType()->getAs<SubstTemplateTypeParmType>()) {
+            QualType ReplacementA = SubstA->getReplacementType();
----------------
ychen wrote:
> mizvekov wrote:
> > It's a bit odd to find `SubstTemplateTypeParmType` necessary to implement 
> > the semantics of this change.
> > 
> > This is just type sugar we leave behind in the template instantiator to 
> > mark where type replacement happened.
> > 
> > There are several potential issues here:
> > 1) This could be marking a substitution that happened at any template 
> > depth. Ie this could be marking a substitution from an outer template. Does 
> > the level not matter here at all? 
> > 2) If the level does matter, you won't be able to reconstitute that easily 
> > without further improvements. See 
> > https://github.com/llvm/llvm-project/issues/55886 for example.
> > 3) A substitution can replace a dependent type for another one, and when 
> > that other gets replaced, we lose track of that because 
> > `SubstTemplateTypeParmType` only holds a canonical underlying type.
> > 
> > ----
> > 
> > Leaving that aside, I get the impression you are trying to work around the 
> > fact that when an expression appears in a canonical type, presumably 
> > because that expression is dependent on an NTTP, we can't rely on uniquing 
> > anymore to compare if they are the same type, as we lack in Clang the 
> > equivalent concept of canonicalization for expressions.
> > 
> > But this however is a bit hard to implement. Are we sure the standard 
> > requires this, or can we simply consider these types always different?
> > It's a bit odd to find SubstTemplateTypeParmType necessary to implement the 
> > semantics of this change.
> 
> Odd indeed. 
> 
> > Leaving that aside, I get the impression you are trying to work around the 
> > fact that when an expression appears in a canonical type, presumably 
> > because that expression is dependent on an NTTP, we can't rely on uniquing 
> > anymore to compare if they are the same type, as we lack in Clang the 
> > equivalent concept of canonicalization for expressions.
> 
> Yeah, sort of . This workaround is to deal with the fact that `DecltypeType` 
> is not uniqued. However, the injected template argument for `t` of 
> `template<auto t>` is `decltype(t)` (which on a side note, might be wrong 
> since `auto` means using template arg deduct rules; `decltype(auto)` means 
> using `decltype(expr)` type, let's keep it this way now since this code path 
> is still needed when Clang starts to support `decltype(auto)` as NTTP type) 
> and concepts partial ordering rules need to compare these concept template 
> arguments (https://eel.is/c++draft/temp.constr#atomic-1). 
> 
> Looking at the motivation why `DecltypeType` is not uniqued 
> (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ASTContext.cpp#L5637-L5640),
>  I think maybe we should unique decltype on the expr to deal with concepts 
> cleanly. Thoughts?
I see, there should be no problem with a change to unique a DecltypeType, but 
it might not help you, because expressions typically have source location 
information embedded in them.


================
Comment at: clang/lib/Sema/SemaOverload.cpp:9675-9676
-  // when comparing template functions. 
-  if (Cand1.Function && Cand2.Function && Cand1.Function->hasPrototype() &&
-      Cand2.Function->hasPrototype()) {
     auto *PT1 = cast<FunctionProtoType>(Cand1.Function->getFunctionType());
----------------
ychen wrote:
> mizvekov wrote:
> > Why are these `hasPrototype` checks not needed anymore?
> > 
> > I don't see other changes which would obliviate the need for it. Presumably 
> > the code below is assuming we have them when we perform that 
> > `FunctionProtoType` cast.
> > 
> > Maybe this was either not possible, or we simply never added tests for it.
> In c++, there will always be a prototype for the function?
Yeah that makes the most sense :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128750/new/

https://reviews.llvm.org/D128750

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to