[clang] 258c3ae - Revert "Re-apply "Deferred Concept Instantiation Implementation"""

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 1 11:20:52 PDT 2022


Author: Erich Keane
Date: 2022-07-01T11:20:16-07:00
New Revision: 258c3aee54e11bc5c5d8ac137eb15e8d5bbcc7e4

URL: https://github.com/llvm/llvm-project/commit/258c3aee54e11bc5c5d8ac137eb15e8d5bbcc7e4
DIFF: https://github.com/llvm/llvm-project/commit/258c3aee54e11bc5c5d8ac137eb15e8d5bbcc7e4.diff

LOG: Revert "Re-apply "Deferred Concept Instantiation Implementation"""

This reverts commit befa8cf087dbb8159a4d9dc8fa4d6748d6d5049a.

Apparently this breaks some libc++ builds with an apparent assertion,
 so I'm looking into that .

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/AST/Decl.h
    clang/include/clang/AST/DeclBase.h
    clang/include/clang/Sema/Sema.h
    clang/include/clang/Sema/Template.h
    clang/lib/AST/ASTImporter.cpp
    clang/lib/AST/Decl.cpp
    clang/lib/AST/DeclBase.cpp
    clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
    clang/lib/Sema/SemaConcept.cpp
    clang/lib/Sema/SemaOverload.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/lib/Serialization/ASTWriterDecl.cpp
    clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
    clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
    clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
    clang/test/SemaTemplate/concepts.cpp
    clang/test/SemaTemplate/instantiate-requires-clause.cpp

Removed: 
    clang/test/SemaTemplate/concepts-friends.cpp
    clang/test/SemaTemplate/deferred-concept-inst.cpp
    clang/test/SemaTemplate/trailing-return-short-circuit.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 26d769deee6d4..3342f6208c4f8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -451,11 +451,10 @@ C++20 Feature Support
 - No longer attempt to evaluate a consteval UDL function call at runtime when
   it is called through a template instantiation. This fixes
   `Issue 54578 <https://github.com/llvm/llvm-project/issues/54578>`_.
-- Implemented `__builtin_source_location()` which enables library support for std::source_location.
-- Clang now correctly delays the instantiation of function constraints until
-  the time of checking, which should now allow the libstdc++ ranges implementation
-  to work for at least trivial examples.  This fixes
-  `Issue 44178 <https://github.com/llvm/llvm-project/issues/44178>`_.
+
+- Implemented ``__builtin_source_location()``, which enables library support
+  for ``std::source_location``.
+
 - The mangling scheme for C++20 modules has incompatibly changed. The
   initial mangling was discovered not to be reversible, and the weak
   ownership design decision did not give the backwards compatibility

diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 0a7dc63d1c25d..66fab94b45b8a 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -1890,9 +1890,7 @@ class FunctionDecl : public DeclaratorDecl,
     TK_FunctionTemplateSpecialization,
     // A function template specialization that hasn't yet been resolved to a
     // particular specialized function template.
-    TK_DependentFunctionTemplateSpecialization,
-    // A non templated function which is in a dependent scope.
-    TK_DependentNonTemplate
+    TK_DependentFunctionTemplateSpecialization
   };
 
   /// Stashed information about a defaulted function definition whose body has
@@ -1941,21 +1939,20 @@ class FunctionDecl : public DeclaratorDecl,
   /// The template or declaration that this declaration
   /// describes or was instantiated from, respectively.
   ///
-  /// For non-templates this value will be NULL, unless this non-template
-  /// function declaration was declared directly inside of a function template,
-  /// in which case this will have a pointer to a FunctionDecl, stored in the
-  /// NamedDecl. For function declarations that describe a function template,
-  /// this will be a pointer to a FunctionTemplateDecl, stored in the NamedDecl.
-  /// For member functions of class template specializations, this will be a
-  /// MemberSpecializationInfo pointer containing information about the
-  /// specialization. For function template specializations, this will be a
-  /// FunctionTemplateSpecializationInfo, which contains information about the
-  /// template being specialized and the template arguments involved in that
-  /// specialization.
-  llvm::PointerUnion<NamedDecl *, MemberSpecializationInfo *,
+  /// For non-templates, this value will be NULL. For function
+  /// declarations that describe a function template, this will be a
+  /// pointer to a FunctionTemplateDecl. For member functions
+  /// of class template specializations, this will be a MemberSpecializationInfo
+  /// pointer containing information about the specialization.
+  /// For function template specializations, this will be a
+  /// FunctionTemplateSpecializationInfo, which contains information about
+  /// the template being specialized and the template arguments involved in
+  /// that specialization.
+  llvm::PointerUnion<FunctionTemplateDecl *,
+                     MemberSpecializationInfo *,
                      FunctionTemplateSpecializationInfo *,
                      DependentFunctionTemplateSpecializationInfo *>
-      TemplateOrSpecialization;
+    TemplateOrSpecialization;
 
   /// Provides source/type location info for the declaration name embedded in
   /// the DeclaratorDecl base class.
@@ -2698,11 +2695,6 @@ class FunctionDecl : public DeclaratorDecl,
     setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
   }
 
-  /// Specify that this function declaration was instantiated from FunctionDecl
-  /// FD. This is only used if this is a function declaration declared locally
-  /// inside of a function template.
-  void setInstantiatedFromDecl(FunctionDecl *FD);
-
   /// Retrieves the function template that is described by this
   /// function declaration.
   ///
@@ -2717,8 +2709,6 @@ class FunctionDecl : public DeclaratorDecl,
   /// FunctionTemplateDecl from a FunctionDecl.
   FunctionTemplateDecl *getDescribedFunctionTemplate() const;
 
-  FunctionDecl *getInstantiatedFromDecl() const;
-
   void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);
 
   /// Determine whether this function is a function template

diff  --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 3a5cb5cb7b723..52fe8dd6b1e57 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -920,10 +920,10 @@ class alignas(8) Decl {
 
   /// If this decl is defined inside a function/method/block it returns
   /// the corresponding DeclContext, otherwise it returns null.
-  const DeclContext *getParentFunctionOrMethod(bool Lexical = false) const;
-  DeclContext *getParentFunctionOrMethod(bool Lexical = false) {
-    return const_cast<DeclContext *>(
-        const_cast<const Decl *>(this)->getParentFunctionOrMethod(Lexical));
+  const DeclContext *getParentFunctionOrMethod() const;
+  DeclContext *getParentFunctionOrMethod() {
+    return const_cast<DeclContext*>(
+                    const_cast<const Decl*>(this)->getParentFunctionOrMethod());
   }
 
   /// Retrieves the "canonical" declaration of the given declaration.

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index eafb7c5624096..17c9b1c2a5d32 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3622,11 +3622,6 @@ class Sema final {
                   bool ConsiderCudaAttrs = true,
                   bool ConsiderRequiresClauses = true);
 
-  // Calculates whether the expression Constraint depends on an enclosing
-  // template, for the purposes of [temp.friend] p9.
-  bool ConstraintExpressionDependsOnEnclosingTemplate(unsigned TemplateDepth,
-                                                      const Expr *Constraint);
-
   enum class AllowedExplicit {
     /// Allow no explicit functions to be used.
     None,
@@ -7096,21 +7091,6 @@ class Sema final {
       LocalInstantiationScope &Scope,
       const MultiLevelTemplateArgumentList &TemplateArgs);
 
-  /// used by SetupConstraintCheckingTemplateArgumentsAndScope to recursively(in
-  /// the case of lambdas) set up the LocalInstantiationScope of the current
-  /// function.
-  bool SetupConstraintScope(
-      FunctionDecl *FD, llvm::Optional<ArrayRef<TemplateArgument>> TemplateArgs,
-      MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope);
-
-  /// Used during constraint checking, sets up the constraint template arguemnt
-  /// lists, and calls SetupConstraintScope to set up the
-  /// LocalInstantiationScope to have the proper set of ParVarDecls configured.
-  llvm::Optional<MultiLevelTemplateArgumentList>
-  SetupConstraintCheckingTemplateArgumentsAndScope(
-      FunctionDecl *FD, llvm::Optional<ArrayRef<TemplateArgument>> TemplateArgs,
-      LocalInstantiationScope &Scope);
-
 public:
   const NormalizedConstraint *
   getNormalizedAssociatedConstraints(
@@ -7141,10 +7121,8 @@ class Sema final {
   /// check (either a concept or a constrained entity).
   /// \param ConstraintExprs a list of constraint expressions, treated as if
   /// they were 'AND'ed together.
-  /// \param TemplateArgList the multi-level list of template arguments to
-  /// substitute into the constraint expression. This should be relative to the
-  /// top-level (hence multi-level), since we need to instantiate fully at the
-  /// time of checking.
+  /// \param TemplateArgs the list of template arguments to substitute into the
+  /// constraint expression.
   /// \param TemplateIDRange The source range of the template id that
   /// caused the constraints check.
   /// \param Satisfaction if true is returned, will contain details of the
@@ -7154,40 +7132,7 @@ class Sema final {
   /// false otherwise.
   bool CheckConstraintSatisfaction(
       const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
-      const MultiLevelTemplateArgumentList &TemplateArgList,
-      SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
-    llvm::SmallVector<Expr *, 4> Converted;
-    return CheckConstraintSatisfaction(Template, ConstraintExprs, Converted,
-                                       TemplateArgList, TemplateIDRange,
-                                       Satisfaction);
-  }
-
-  /// \brief Check whether the given list of constraint expressions are
-  /// satisfied (as if in a 'conjunction') given template arguments.
-  /// Additionally, takes an empty list of Expressions which is populated with
-  /// the instantiated versions of the ConstraintExprs.
-  /// \param Template the template-like entity that triggered the constraints
-  /// check (either a concept or a constrained entity).
-  /// \param ConstraintExprs a list of constraint expressions, treated as if
-  /// they were 'AND'ed together.
-  /// \param ConvertedConstraints a out parameter that will get populated with
-  /// the instantiated version of the ConstraintExprs if we successfully checked
-  /// satisfaction.
-  /// \param TemplateArgList the multi-level list of template arguments to
-  /// substitute into the constraint expression. This should be relative to the
-  /// top-level (hence multi-level), since we need to instantiate fully at the
-  /// time of checking.
-  /// \param TemplateIDRange The source range of the template id that
-  /// caused the constraints check.
-  /// \param Satisfaction if true is returned, will contain details of the
-  /// satisfaction, with enough information to diagnose an unsatisfied
-  /// expression.
-  /// \returns true if an error occurred and satisfaction could not be checked,
-  /// false otherwise.
-  bool CheckConstraintSatisfaction(
-      const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
-      llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
-      const MultiLevelTemplateArgumentList &TemplateArgList,
+      ArrayRef<TemplateArgument> TemplateArgs,
       SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
 
   /// \brief Check whether the given non-dependent constraint expression is
@@ -7223,9 +7168,9 @@ class Sema final {
   ///
   /// \returns true if the constrains are not satisfied or could not be checked
   /// for satisfaction, false if the constraints are satisfied.
-  bool EnsureTemplateArgumentListConstraints(
-      TemplateDecl *Template, MultiLevelTemplateArgumentList TemplateArgs,
-      SourceRange TemplateIDRange);
+  bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template,
+                                       ArrayRef<TemplateArgument> TemplateArgs,
+                                             SourceRange TemplateIDRange);
 
   /// \brief Emit diagnostics explaining why a constraint expression was deemed
   /// unsatisfied.
@@ -8959,8 +8904,7 @@ class Sema final {
 
   MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
       const NamedDecl *D, const TemplateArgumentList *Innermost = nullptr,
-      bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
-      bool LookBeyondLambda = false, bool IncludeContainingStruct = false);
+      bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr);
 
   /// A context in which code is being synthesized (where a source location
   /// alone is not sufficient to identify the context). This covers template
@@ -9693,11 +9637,6 @@ class Sema final {
                       ExtParameterInfoBuilder &ParamInfos);
   ExprResult SubstExpr(Expr *E,
                        const MultiLevelTemplateArgumentList &TemplateArgs);
-  // Unlike the above, this evaluates constraints, which should only happen at
-  // 'constraint checking' time.
-  ExprResult
-  SubstConstraintExpr(Expr *E,
-                      const MultiLevelTemplateArgumentList &TemplateArgs);
 
   /// Substitute the given template arguments into a list of
   /// expressions, expanding pack expansions if required.
@@ -9721,14 +9660,13 @@ class Sema final {
 
   TemplateParameterList *
   SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-                      const MultiLevelTemplateArgumentList &TemplateArgs,
-                      bool InstantiateConstraints = false);
+                      const MultiLevelTemplateArgumentList &TemplateArgs);
 
   bool
   SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
                          const MultiLevelTemplateArgumentList &TemplateArgs,
-                         TemplateArgumentListInfo &Outputs,
-                         bool InstantiateConstraints = false);
+                         TemplateArgumentListInfo &Outputs);
+
 
   Decl *SubstDecl(Decl *D, DeclContext *Owner,
                   const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -9820,8 +9758,7 @@ class Sema final {
                     const MultiLevelTemplateArgumentList &TemplateArgs);
 
   bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
-                           const MultiLevelTemplateArgumentList &TemplateArgs,
-                           bool isEvaluatingAConstraint);
+                           const MultiLevelTemplateArgumentList &TemplateArgs);
 
   bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
                                   ParmVarDecl *Param);

diff  --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 602faf8607412..5dcde77b5dd37 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -75,8 +75,6 @@ enum class TemplateSubstitutionKind : char {
   class MultiLevelTemplateArgumentList {
     /// The template argument list at a certain template depth
     using ArgList = ArrayRef<TemplateArgument>;
-    using ArgListsIterator = SmallVector<ArgList, 4>::iterator;
-    using ConstArgListsIterator = SmallVector<ArgList, 4>::const_iterator;
 
     /// The template argument lists, stored from the innermost template
     /// argument list (first) to the outermost template argument list (last).
@@ -123,12 +121,6 @@ enum class TemplateSubstitutionKind : char {
       return TemplateArgumentLists.size();
     }
 
-    /// Determine the number of substituted args at 'Depth'.
-    unsigned getNumSubstitutedArgs(unsigned Depth) const {
-      assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
-      return TemplateArgumentLists[getNumLevels() - Depth - 1].size();
-    }
-
     unsigned getNumRetainedOuterLevels() const {
       return NumRetainedOuterLevels;
     }
@@ -166,14 +158,6 @@ enum class TemplateSubstitutionKind : char {
       return !(*this)(Depth, Index).isNull();
     }
 
-    bool isAnyArgInstantiationDependent() const {
-      for (ArgList List : TemplateArgumentLists)
-        for (const TemplateArgument &TA : List)
-          if (TA.isInstantiationDependent())
-            return true;
-      return false;
-    }
-
     /// Clear out a specific template argument.
     void setArgument(unsigned Depth, unsigned Index,
                      TemplateArgument Arg) {
@@ -199,14 +183,6 @@ enum class TemplateSubstitutionKind : char {
       TemplateArgumentLists.push_back(Args);
     }
 
-    /// Replaces the current 'innermost' level with the provided argument list.
-    /// This is useful for type deduction cases where we need to get the entire
-    /// list from the AST, but then add the deduced innermost list.
-    void replaceInnermostTemplateArguments(ArgList Args) {
-      assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?");
-      TemplateArgumentLists[0] = Args;
-    }
-
     /// Add an outermost level that we are not substituting. We have no
     /// arguments at this level, and do not remove it from the depth of inner
     /// template parameters that we instantiate.
@@ -221,16 +197,6 @@ enum class TemplateSubstitutionKind : char {
     const ArgList &getInnermost() const {
       return TemplateArgumentLists.front();
     }
-
-    /// Retrieve the outermost template argument list.
-    const ArgList &getOutermost() const { return TemplateArgumentLists.back(); }
-
-    ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
-    ConstArgListsIterator begin() const {
-      return TemplateArgumentLists.begin();
-    }
-    ArgListsIterator end() { return TemplateArgumentLists.end(); }
-    ConstArgListsIterator end() const { return TemplateArgumentLists.end(); }
   };
 
   /// The context in which partial ordering of function templates occurs.
@@ -503,7 +469,6 @@ enum class TemplateSubstitutionKind : char {
     const MultiLevelTemplateArgumentList &TemplateArgs;
     Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
     LocalInstantiationScope *StartingScope = nullptr;
-    bool EvaluatingAConstraint = false;
 
     /// A list of out-of-line class template partial
     /// specializations that will need to be instantiated after the
@@ -522,12 +487,10 @@ enum class TemplateSubstitutionKind : char {
 
   public:
     TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
-                             const MultiLevelTemplateArgumentList &TemplateArgs,
-                             bool EvaluatingConstraint = false)
+                             const MultiLevelTemplateArgumentList &TemplateArgs)
         : SemaRef(SemaRef),
           SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
-          Owner(Owner), TemplateArgs(TemplateArgs),
-          EvaluatingAConstraint(EvaluatingConstraint) {}
+          Owner(Owner), TemplateArgs(TemplateArgs) {}
 
 // Define all the decl visitors using DeclNodes.inc
 #define DECL(DERIVED, BASE) \

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 7a20807aa1f90..8d930ead97d3e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3109,11 +3109,6 @@ Error ASTNodeImporter::ImportTemplateInformation(
   case FunctionDecl::TK_FunctionTemplate:
     return Error::success();
 
-  case FunctionDecl::TK_DependentNonTemplate:
-    if (Expected<FunctionDecl *> InstFDOrErr =
-            import(FromFD->getInstantiatedFromDecl()))
-      ToFD->setInstantiatedFromDecl(*InstFDOrErr);
-    return Error::success();
   case FunctionDecl::TK_MemberSpecialization: {
     TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind();
 

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 3bf3bd66ff326..5e5101203e6cf 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3732,12 +3732,8 @@ const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
 FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
   if (TemplateOrSpecialization.isNull())
     return TK_NonTemplate;
-  if (auto *ND = TemplateOrSpecialization.dyn_cast<NamedDecl *>()) {
-    if (isa<FunctionDecl>(ND))
-      return TK_DependentNonTemplate;
-    assert(isa<FunctionTemplateDecl>(ND) && "No other types it could be?");
+  if (TemplateOrSpecialization.is<FunctionTemplateDecl *>())
     return TK_FunctionTemplate;
-  }
   if (TemplateOrSpecialization.is<MemberSpecializationInfo *>())
     return TK_MemberSpecialization;
   if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>())
@@ -3778,28 +3774,15 @@ FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
 }
 
 FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const {
-  return dyn_cast_or_null<FunctionTemplateDecl>(
-      TemplateOrSpecialization.dyn_cast<NamedDecl *>());
+  return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl *>();
 }
 
-void FunctionDecl::setDescribedFunctionTemplate(
-    FunctionTemplateDecl *Template) {
+void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
   assert(TemplateOrSpecialization.isNull() &&
          "Member function is already a specialization");
   TemplateOrSpecialization = Template;
 }
 
-void FunctionDecl::setInstantiatedFromDecl(FunctionDecl *FD) {
-  assert(TemplateOrSpecialization.isNull() &&
-         "function is already a specialization");
-  TemplateOrSpecialization = FD;
-}
-
-FunctionDecl *FunctionDecl::getInstantiatedFromDecl() const {
-  return dyn_cast_or_null<FunctionDecl>(
-      TemplateOrSpecialization.dyn_cast<NamedDecl *>());
-}
-
 bool FunctionDecl::isImplicitlyInstantiable() const {
   // If the function is invalid, it can't be implicitly instantiated.
   if (isInvalidDecl())

diff  --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 9c1deaedf6b07..13dd6da3f24fe 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -283,9 +283,8 @@ unsigned Decl::getTemplateDepth() const {
   return cast<Decl>(DC)->getTemplateDepth();
 }
 
-const DeclContext *Decl::getParentFunctionOrMethod(bool Lexical) const {
-  for (const DeclContext *DC = Lexical ? getLexicalDeclContext()
-                                       : getDeclContext();
+const DeclContext *Decl::getParentFunctionOrMethod() const {
+  for (const DeclContext *DC = getDeclContext();
        DC && !DC->isTranslationUnit() && !DC->isNamespace();
        DC = DC->getParent())
     if (DC->isFunctionOrMethod())

diff  --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index 1a785182e3634..bffa66c2d9448 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -303,7 +303,6 @@ class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> {
     // Skip templated functions.
     switch (Decl->getTemplatedKind()) {
     case FunctionDecl::TK_NonTemplate:
-    case FunctionDecl::TK_DependentNonTemplate:
       break;
     case FunctionDecl::TK_MemberSpecialization:
     case FunctionDecl::TK_FunctionTemplateSpecialization:

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 9edba27bea5ea..239e5dc4394c3 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -30,7 +30,6 @@ using namespace sema;
 
 namespace {
 class LogicalBinOp {
-  SourceLocation Loc;
   OverloadedOperatorKind Op = OO_None;
   const Expr *LHS = nullptr;
   const Expr *RHS = nullptr;
@@ -41,14 +40,12 @@ class LogicalBinOp {
       Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
       LHS = BO->getLHS();
       RHS = BO->getRHS();
-      Loc = BO->getExprLoc();
     } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
       // If OO is not || or && it might not have exactly 2 arguments.
       if (OO->getNumArgs() == 2) {
         Op = OO->getOperator();
         LHS = OO->getArg(0);
         RHS = OO->getArg(1);
-        Loc = OO->getOperatorLoc();
       }
     }
   }
@@ -59,26 +56,6 @@ class LogicalBinOp {
 
   const Expr *getLHS() const { return LHS; }
   const Expr *getRHS() const { return RHS; }
-
-  ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const {
-    return recreateBinOp(SemaRef, LHS, const_cast<Expr *>(getRHS()));
-  }
-
-  ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS,
-                           ExprResult RHS) const {
-    assert((isAnd() || isOr()) && "Not the right kind of op?");
-    assert((!LHS.isInvalid() && !RHS.isInvalid()) && "not good expressions?");
-
-    if (!LHS.isUsable() || !RHS.isUsable())
-      return ExprEmpty();
-
-    // We should just be able to 'normalize' these to the builtin Binary
-    // Operator, since that is how they are evaluated in constriant checks.
-    return BinaryOperator::Create(SemaRef.Context, LHS.get(), RHS.get(),
-                                  BinaryOperator::getOverloadedOpcode(Op),
-                                  SemaRef.Context.BoolTy, VK_PRValue,
-                                  OK_Ordinary, Loc, FPOptionsOverride{});
-  }
 };
 }
 
@@ -145,18 +122,16 @@ bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
 }
 
 template <typename AtomicEvaluator>
-static ExprResult
+static bool
 calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
                                 ConstraintSatisfaction &Satisfaction,
                                 AtomicEvaluator &&Evaluator) {
   ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
 
   if (LogicalBinOp BO = ConstraintExpr) {
-    ExprResult LHSRes = calculateConstraintSatisfaction(
-        S, BO.getLHS(), Satisfaction, Evaluator);
-
-    if (LHSRes.isInvalid())
-      return ExprError();
+    if (calculateConstraintSatisfaction(S, BO.getLHS(), Satisfaction,
+                                        Evaluator))
+      return true;
 
     bool IsLHSSatisfied = Satisfaction.IsSatisfied;
 
@@ -167,7 +142,7 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
       //    is checked. If that is satisfied, the disjunction is satisfied.
       //    Otherwise, the disjunction is satisfied if and only if the second
       //    operand is satisfied.
-      return BO.recreateBinOp(S, LHSRes);
+      return false;
 
     if (BO.isAnd() && !IsLHSSatisfied)
       // [temp.constr.op] p2
@@ -176,21 +151,12 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
       //    is checked. If that is not satisfied, the conjunction is not
       //    satisfied. Otherwise, the conjunction is satisfied if and only if
       //    the second operand is satisfied.
-      return BO.recreateBinOp(S, LHSRes);
-
-    ExprResult RHSRes = calculateConstraintSatisfaction(
-        S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
-    if (RHSRes.isInvalid())
-      return ExprError();
-
-    return BO.recreateBinOp(S, LHSRes, RHSRes);
-  }
+      return false;
 
-  if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
-    // These aren't evaluated, so we don't care about cleanups, so we can just
-    // evaluate these as if the cleanups didn't exist.
     return calculateConstraintSatisfaction(
-        S, C->getSubExpr(), Satisfaction,
+        S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
+  } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
+    return calculateConstraintSatisfaction(S, C->getSubExpr(), Satisfaction,
         std::forward<AtomicEvaluator>(Evaluator));
   }
 
@@ -198,11 +164,11 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
   ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
 
   if (SubstitutedAtomicExpr.isInvalid())
-    return ExprError();
+    return true;
 
   if (!SubstitutedAtomicExpr.isUsable())
     // Evaluator has decided satisfaction without yielding an expression.
-    return ExprEmpty();
+    return false;
 
   EnterExpressionEvaluationContext ConstantEvaluated(
       S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
@@ -219,7 +185,7 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
         << SubstitutedAtomicExpr.get()->getSourceRange();
     for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
       S.Diag(PDiag.first, PDiag.second);
-    return ExprError();
+    return true;
   }
 
   assert(EvalResult.Val.isInt() &&
@@ -229,13 +195,13 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
     Satisfaction.Details.emplace_back(ConstraintExpr,
                                       SubstitutedAtomicExpr.get());
 
-  return SubstitutedAtomicExpr;
+  return false;
 }
 
-static ExprResult calculateConstraintSatisfaction(
-    Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
-    const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
-    ConstraintSatisfaction &Satisfaction) {
+static bool calculateConstraintSatisfaction(
+    Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
+    SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL,
+    const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) {
   return calculateConstraintSatisfaction(
       S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
         EnterExpressionEvaluationContext ConstantEvaluated(
@@ -253,8 +219,8 @@ static ExprResult calculateConstraintSatisfaction(
             return ExprError();
           // We do not want error diagnostics escaping here.
           Sema::SFINAETrap Trap(S);
-          SubstitutedExpression =
-              S.SubstConstraintExpr(const_cast<Expr *>(AtomicExpr), MLTAL);
+          SubstitutedExpression = S.SubstExpr(const_cast<Expr *>(AtomicExpr),
+                                              MLTAL);
           // Substitution might have stripped off a contextual conversion to
           // bool if this is the operand of an '&&' or '||'. For example, we
           // might lose an lvalue-to-rvalue conversion here. If so, put it back
@@ -302,92 +268,72 @@ static ExprResult calculateConstraintSatisfaction(
       });
 }
 
-static bool CheckConstraintSatisfaction(
-    Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
-    llvm::SmallVectorImpl<Expr *> &Converted,
-    const MultiLevelTemplateArgumentList &TemplateArgsList,
-    SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
+static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template,
+                                        ArrayRef<const Expr *> ConstraintExprs,
+                                        ArrayRef<TemplateArgument> TemplateArgs,
+                                        SourceRange TemplateIDRange,
+                                        ConstraintSatisfaction &Satisfaction) {
   if (ConstraintExprs.empty()) {
     Satisfaction.IsSatisfied = true;
     return false;
   }
 
-  if (TemplateArgsList.isAnyArgInstantiationDependent()) {
-    //  No need to check satisfaction for dependent constraint expressions.
-    Satisfaction.IsSatisfied = true;
-    return false;
-  }
-
-  ArrayRef<TemplateArgument> TemplateArgs =
-      TemplateArgsList.getNumSubstitutedLevels() > 0
-          ? TemplateArgsList.getOutermost()
-          : ArrayRef<TemplateArgument>{};
+  for (auto& Arg : TemplateArgs)
+    if (Arg.isInstantiationDependent()) {
+      // No need to check satisfaction for dependent constraint expressions.
+      Satisfaction.IsSatisfied = true;
+      return false;
+    }
 
-  Sema::InstantiatingTemplate Inst(
-      S, TemplateIDRange.getBegin(),
+  Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
       Sema::InstantiatingTemplate::ConstraintsCheck{},
       const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
   if (Inst.isInvalid())
     return true;
 
+  MultiLevelTemplateArgumentList MLTAL;
+  MLTAL.addOuterTemplateArguments(TemplateArgs);
+
   for (const Expr *ConstraintExpr : ConstraintExprs) {
-    ExprResult Res = calculateConstraintSatisfaction(
-        S, Template, TemplateIDRange.getBegin(), TemplateArgsList,
-        ConstraintExpr, Satisfaction);
-    if (Res.isInvalid())
+    if (calculateConstraintSatisfaction(S, Template, TemplateArgs,
+                                        TemplateIDRange.getBegin(), MLTAL,
+                                        ConstraintExpr, Satisfaction))
       return true;
-
-    Converted.push_back(Res.get());
-    if (!Satisfaction.IsSatisfied) {
-      // Backfill the 'converted' list with nulls so we can keep the Converted
-      // and unconverted lists in sync.
-      Converted.append(ConstraintExprs.size() - Converted.size(), nullptr);
+    if (!Satisfaction.IsSatisfied)
       // [temp.constr.op] p2
-      // [...] To determine if a conjunction is satisfied, the satisfaction
-      // of the first operand is checked. If that is not satisfied, the
-      // conjunction is not satisfied. [...]
+      //   [...] To determine if a conjunction is satisfied, the satisfaction
+      //   of the first operand is checked. If that is not satisfied, the
+      //   conjunction is not satisfied. [...]
       return false;
-    }
   }
   return false;
 }
 
 bool Sema::CheckConstraintSatisfaction(
     const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
-    llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
-    const MultiLevelTemplateArgumentList &TemplateArgsList,
-    SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
+    ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange,
+    ConstraintSatisfaction &OutSatisfaction) {
   if (ConstraintExprs.empty()) {
     OutSatisfaction.IsSatisfied = true;
     return false;
   }
   if (!Template) {
     return ::CheckConstraintSatisfaction(*this, nullptr, ConstraintExprs,
-                                         ConvertedConstraints, TemplateArgsList,
-                                         TemplateIDRange, OutSatisfaction);
+                                         TemplateArgs, TemplateIDRange,
+                                         OutSatisfaction);
   }
-
-  // A list of the template argument list flattened in a predictible manner for
-  // the purposes of caching. The ConstraintSatisfaction type is in AST so it
-  // has no access to the MultiLevelTemplateArgumentList, so this has to happen
-  // here.
-  llvm::SmallVector<TemplateArgument, 4> FlattenedArgs;
-  for (ArrayRef<TemplateArgument> List : TemplateArgsList)
-    FlattenedArgs.insert(FlattenedArgs.end(), List.begin(), List.end());
-
   llvm::FoldingSetNodeID ID;
-  ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
-
+  ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
   void *InsertPos;
   if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
     OutSatisfaction = *Cached;
     return false;
   }
   auto Satisfaction =
-      std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
+      std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs);
   if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
-                                    ConvertedConstraints, TemplateArgsList,
-                                    TemplateIDRange, *Satisfaction)) {
+                                    TemplateArgs, TemplateIDRange,
+                                    *Satisfaction)) {
     return true;
   }
   OutSatisfaction = *Satisfaction;
@@ -401,118 +347,21 @@ bool Sema::CheckConstraintSatisfaction(
 bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
                                        ConstraintSatisfaction &Satisfaction) {
   return calculateConstraintSatisfaction(
-             *this, ConstraintExpr, Satisfaction,
-             [this](const Expr *AtomicExpr) -> ExprResult {
-               // We only do this to immitate lvalue-to-rvalue conversion.
-               return PerformContextuallyConvertToBool(
-                   const_cast<Expr *>(AtomicExpr));
-             })
-      .isInvalid();
-}
-
-bool Sema::SetupConstraintScope(
-    FunctionDecl *FD, llvm::Optional<ArrayRef<TemplateArgument>> TemplateArgs,
-    MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope) {
-  if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
-    FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
-    InstantiatingTemplate Inst(
-        *this, FD->getPointOfInstantiation(),
-        Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
-        TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
-        SourceRange());
-    if (Inst.isInvalid())
-      return true;
-
-    // addInstantiatedParametersToScope creates a map of 'uninstantiated' to
-    // 'instantiated' parameters and adds it to the context. For the case where
-    // this function is a template being instantiated NOW, we also need to add
-    // the list of current template arguments to the list so that they also can
-    // be picked out of the map.
-    if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) {
-      MultiLevelTemplateArgumentList JustTemplArgs(*SpecArgs);
-      if (addInstantiatedParametersToScope(
-              FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs))
-        return true;
-    }
-
-    // If this is a member function, make sure we get the parameters that
-    // reference the original primary template.
-    if (const auto *FromMemTempl =
-            PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
-      if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
-                                           Scope, MLTAL))
-        return true;
-    }
-
-    return false;
-  }
-
-  if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
-      FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) {
-    FunctionDecl *InstantiatedFrom =
-        FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization
-            ? FD->getInstantiatedFromMemberFunction()
-            : FD->getInstantiatedFromDecl();
-
-    InstantiatingTemplate Inst(
-        *this, FD->getPointOfInstantiation(),
-        Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
-        TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
-        SourceRange());
-    if (Inst.isInvalid())
-      return true;
-
-    // Case where this was not a template, but instantiated as a
-    // child-function.
-    if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
-      return true;
-  }
-
-  return false;
-}
-
-// This function collects all of the template arguments for the purposes of
-// constraint-instantiation and checking.
-llvm::Optional<MultiLevelTemplateArgumentList>
-Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
-    FunctionDecl *FD, llvm::Optional<ArrayRef<TemplateArgument>> TemplateArgs,
-    LocalInstantiationScope &Scope) {
-  MultiLevelTemplateArgumentList MLTAL;
-
-  // Collect the list of template arguments relative to the 'primary' template.
-  // We need the entire list, since the constraint is completely uninstantiated
-  // at this point.
-  MLTAL = getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary*/ true,
-                                       /*Pattern*/ nullptr,
-                                       /*LookBeyondLambda*/ true);
-  if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
-    return {};
-
-  return MLTAL;
+      *this, ConstraintExpr, Satisfaction,
+      [this](const Expr *AtomicExpr) -> ExprResult {
+        // We only do this to immitate lvalue-to-rvalue conversion.
+        return PerformContextuallyConvertToBool(const_cast<Expr *>(AtomicExpr));
+      });
 }
 
 bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
                                     ConstraintSatisfaction &Satisfaction,
                                     SourceLocation UsageLoc) {
-  // Don't check constraints if the function is dependent. Also don't check if
-  // this is a function template specialization, as the call to
-  // CheckinstantiatedFunctionTemplateConstraints after this will check it
-  // better.
-  if (FD->isDependentContext() ||
-      FD->getTemplatedKind() ==
-          FunctionDecl::TK_FunctionTemplateSpecialization) {
+  const Expr *RC = FD->getTrailingRequiresClause();
+  if (RC->isInstantiationDependent()) {
     Satisfaction.IsSatisfied = true;
     return false;
   }
-
-  ContextRAII SavedContext{
-      *this, cast<DeclContext>(
-                 const_cast<FunctionDecl *>(FD)->getNonClosureContext())};
-  LocalInstantiationScope Scope(*this, true);
-  llvm::Optional<MultiLevelTemplateArgumentList> MLTAL =
-      SetupConstraintCheckingTemplateArgumentsAndScope(
-          const_cast<FunctionDecl *>(FD), {}, Scope);
-
   Qualifiers ThisQuals;
   CXXRecordDecl *Record = nullptr;
   if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
@@ -523,27 +372,14 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
   // We substitute with empty arguments in order to rebuild the atomic
   // constraint in a constant-evaluated context.
   // FIXME: Should this be a dedicated TreeTransform?
-  const Expr *RC = FD->getTrailingRequiresClause();
-  llvm::SmallVector<Expr *, 1> Converted;
-
-  if (CheckConstraintSatisfaction(
-          FD, {RC}, Converted, *MLTAL,
-          SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
-          Satisfaction))
-    return true;
-
-  // FIXME: we need to do this for the function constraints for
-  // comparison of constraints to work, but do we also need to do it for
-  // CheckInstantiatedFunctionConstraints?  That one is more 
diff icult, but we
-  // seem to always just pick up the constraints from the primary template.
-  assert(Converted.size() <= 1 && "Got more expressions converted?");
-  if (!Converted.empty() && Converted[0] != nullptr)
-    const_cast<FunctionDecl *>(FD)->setTrailingRequiresClause(Converted[0]);
-  return false;
+  return CheckConstraintSatisfaction(
+      FD, {RC}, /*TemplateArgs=*/{},
+      SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
+      Satisfaction);
 }
 
 bool Sema::EnsureTemplateArgumentListConstraints(
-    TemplateDecl *TD, MultiLevelTemplateArgumentList TemplateArgs,
+    TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs,
     SourceRange TemplateIDRange) {
   ConstraintSatisfaction Satisfaction;
   llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
@@ -556,8 +392,7 @@ bool Sema::EnsureTemplateArgumentListConstraints(
     SmallString<128> TemplateArgString;
     TemplateArgString = " ";
     TemplateArgString += getTemplateArgumentBindingsText(
-        TD->getTemplateParameters(), TemplateArgs.getInnermost().data(),
-        TemplateArgs.getInnermost().size());
+        TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size());
 
     Diag(TemplateIDRange.getBegin(),
          diag::err_template_arg_list_constraints_not_satisfied)
@@ -589,13 +424,21 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
   Sema::ContextRAII savedContext(*this, Decl);
   LocalInstantiationScope Scope(*this);
 
-  Optional<MultiLevelTemplateArgumentList> MLTAL =
-      SetupConstraintCheckingTemplateArgumentsAndScope(Decl, TemplateArgs,
-                                                       Scope);
-
-  if (!MLTAL)
-    return true;
-
+  // If this is not an explicit specialization - we need to get the instantiated
+  // version of the template arguments and add them to scope for the
+  // substitution.
+  if (Decl->isTemplateInstantiation()) {
+    InstantiatingTemplate Inst(*this, Decl->getPointOfInstantiation(),
+        InstantiatingTemplate::ConstraintsCheck{}, Decl->getPrimaryTemplate(),
+        TemplateArgs, SourceRange());
+    if (Inst.isInvalid())
+      return true;
+    MultiLevelTemplateArgumentList MLTAL(
+        *Decl->getTemplateSpecializationArgs());
+    if (addInstantiatedParametersToScope(
+            Decl, Decl->getPrimaryTemplate()->getTemplatedDecl(), Scope, MLTAL))
+      return true;
+  }
   Qualifiers ThisQuals;
   CXXRecordDecl *Record = nullptr;
   if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
@@ -603,8 +446,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints(
     Record = Method->getParent();
   }
   CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
-  llvm::SmallVector<Expr *, 1> Converted;
-  return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,
+  return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs,
                                      PointOfInstantiation, Satisfaction);
 }
 
@@ -879,22 +721,22 @@ Sema::getNormalizedAssociatedConstraints(
   return CacheEntry->second;
 }
 
-static bool
-substituteParameterMappings(Sema &S, NormalizedConstraint &N,
-                            ConceptDecl *Concept,
-                            const MultiLevelTemplateArgumentList &MLTAL,
-                            const ASTTemplateArgumentListInfo *ArgsAsWritten) {
+static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
+    ConceptDecl *Concept, ArrayRef<TemplateArgument> TemplateArgs,
+    const ASTTemplateArgumentListInfo *ArgsAsWritten) {
   if (!N.isAtomic()) {
-    if (substituteParameterMappings(S, N.getLHS(), Concept, MLTAL,
+    if (substituteParameterMappings(S, N.getLHS(), Concept, TemplateArgs,
                                     ArgsAsWritten))
       return true;
-    return substituteParameterMappings(S, N.getRHS(), Concept, MLTAL,
+    return substituteParameterMappings(S, N.getRHS(), Concept, TemplateArgs,
                                        ArgsAsWritten);
   }
   TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
 
   AtomicConstraint &Atomic = *N.getAtomicConstraint();
   TemplateArgumentListInfo SubstArgs;
+  MultiLevelTemplateArgumentList MLTAL;
+  MLTAL.addOuterTemplateArguments(TemplateArgs);
   if (!Atomic.ParameterMapping) {
     llvm::SmallBitVector OccurringIndices(TemplateParams->size());
     S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
@@ -924,8 +766,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
       Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
       SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(),
                   ArgsAsWritten->arguments().back().getSourceRange().getEnd()));
-  if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs,
-                               /*InstantiateConstraints=*/true))
+  if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
     return true;
   Atomic.ParameterMapping.emplace(
         MutableArrayRef<TemplateArgumentLoc>(
@@ -936,20 +777,6 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
   return false;
 }
 
-static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
-                                        const ConceptSpecializationExpr *CSE) {
-  TemplateArgumentList TAL{TemplateArgumentList::OnStack,
-                           CSE->getTemplateArguments()};
-  MultiLevelTemplateArgumentList MLTAL =
-      S.getTemplateInstantiationArgs(CSE->getNamedConcept(), &TAL,
-                                     /*RelativeToPrimary*/ true,
-                                     /*Pattern*/ nullptr,
-                                     /*LookBeyondLambda*/ true);
-
-  return substituteParameterMappings(S, N, CSE->getNamedConcept(), MLTAL,
-                                     CSE->getTemplateArgsAsWritten());
-}
-
 Optional<NormalizedConstraint>
 NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
                                           ArrayRef<const Expr *> E) {
@@ -1012,7 +839,9 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
     Optional<NormalizedConstraint> New;
     New.emplace(S.Context, *SubNF);
 
-    if (substituteParameterMappings(S, *New, CSE))
+    if (substituteParameterMappings(
+            S, *New, CSE->getNamedConcept(),
+            CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten()))
       return None;
 
     return New;

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 644114c9485ee..c226ed6254790 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -992,78 +992,6 @@ static bool checkArgPlaceholdersForOverload(Sema &S, MultiExprArg Args,
   return false;
 }
 
-// Figure out the to-translation-unit depth for this function declaration for
-// the purpose of seeing if they 
diff er by constraints. This isn't the same as
-// getTemplateDepth, because it includes already instantiated parents.
-static unsigned CalculateTemplateDepthForConstraints(Sema &S,
-                                                     FunctionDecl *FD) {
-  MultiLevelTemplateArgumentList MLTAL =
-      S.getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary*/ true,
-                                     /*Pattern*/ nullptr,
-                                     /*LookBeyondLambda*/ true);
-  return MLTAL.getNumSubstitutedLevels();
-}
-
-// Friend definitions can appear identical but be 
diff erent declarations based
-// on the last sentence of the rule below (others included for clarification):
-// C++20 [temp.friend] p9: A non-template friend declaration
-// with a requires-clause shall be a definition.  A friend function template
-// with a constraint that depends on a template parameter from an enclosing
-// template shall be a definition.  Such a constrained friend function or
-// function template declaration does not declare the same function or function
-// template as a declaration in any other scope.
-static bool FriendsDifferByConstraints(Sema &S, DeclContext *CurContext,
-                                       FunctionDecl *Old, FunctionDecl *New,
-                                       Scope *Scope) {
-  // If these aren't friends, than they aren't friends that 
diff ere by
-  // constraints.
-  if (!Old->getFriendObjectKind() || !New->getFriendObjectKind())
-    return false;
-
-  // If the the two functions share lexical declaration context, they are not in
-  // separate instantations, and thus in the same scope.
-  if (New->getLexicalDeclContext() == Old->getLexicalDeclContext())
-    return false;
-
-  if (!Old->getDescribedFunctionTemplate()) {
-    assert(!New->getDescribedFunctionTemplate() &&
-           "How would these be the same if they aren't both templates?");
-
-    // If these friends don't have constraints, they aren't constrained, and
-    // thus don't fall under temp.friend p9. Else the simple presence of a
-    // constraint makes them unique.
-    return Old->getTrailingRequiresClause();
-  }
-
-  SmallVector<const Expr *, 3> OldAC;
-  Old->getDescribedFunctionTemplate()->getAssociatedConstraints(OldAC);
-
-#ifndef NDEBUG
-  SmallVector<const Expr *, 3> NewAC;
-  New->getDescribedFunctionTemplate()->getAssociatedConstraints(NewAC);
-  assert(OldAC.size() == NewAC.size() &&
-         "Difference should have been noticed earlier if sizes of constraints "
-         "aren't the same");
-#endif
-  // If there are no constraints, these are not constrained friend function or
-  // friend function templates.
-  if (OldAC.size() == 0)
-    return false;
-
-  unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(S, Old);
-
-  // At this point, if the constrained function template declaration depends on
-  // a template parameter from an enclosing template, they are not the same
-  // function.  Since these were deemed identical before we got here, we only
-  // have to look into 1 side to see if they refer to a containing template.
-  for (const Expr *Constraint : OldAC)
-    if (S.ConstraintExpressionDependsOnEnclosingTemplate(OldTemplateDepth,
-                                                         Constraint))
-      return true;
-
-  return false;
-}
-
 /// Determine whether the given New declaration is an overload of the
 /// declarations in Old. This routine returns Ovl_Match or Ovl_NonFunction if
 /// New and Old cannot be overloaded, e.g., if New has the same signature as
@@ -1140,15 +1068,6 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
             !shouldLinkPossiblyHiddenDecl(*I, New))
           continue;
 
-        // C++20 [temp.friend] p9: A non-template friend declaration with a
-        // requires-clause shall be a definition.  A friend function template
-        // with a constraint that depends on a template parameter from an
-        // enclosing template shall be a definition.  Such a constrained friend
-        // function or function template declaration does not declare the same
-        // function or function template as a declaration in any other scope.
-        if (FriendsDifferByConstraints(*this, CurContext, OldF, New, S))
-          continue;
-
         Match = *I;
         return Ovl_Match;
       }

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8e300f0b05b45..dbfe6164bda2c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1685,59 +1685,6 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(Scope* S,
   return Param;
 }
 
-namespace {
-class ConstraintRefersToContainingTemplateChecker
-    : public TreeTransform<ConstraintRefersToContainingTemplateChecker> {
-  bool Result = false;
-  unsigned TemplateDepth = 0;
-
-public:
-  using inherited = TreeTransform<ConstraintRefersToContainingTemplateChecker>;
-
-  ConstraintRefersToContainingTemplateChecker(Sema &SemaRef,
-                                              unsigned TemplateDepth)
-      : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
-  bool getResult() const { return Result; }
-
-  // This should be the only template parm type that we have to deal with.
-  // SubstTempalteTypeParmPack, SubstNonTypeTemplateParmPack, and
-  // FunctionParmPackExpr are all partially substituted, which cannot happen
-  // with concepts at this point in translation.
-  QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
-                                         TemplateTypeParmTypeLoc TL) {
-    assert(TL.getDecl()->getDepth() <= TemplateDepth &&
-           "Nothing should reference a value below the actual template depth, "
-           "depth is likely wrong");
-    if (TL.getDecl()->getDepth() != TemplateDepth)
-      Result = true;
-    return inherited::TransformTemplateTypeParmType(TLB, TL);
-  }
-
-  Decl *TransformDecl(SourceLocation Loc, Decl *D) {
-    // FIXME : This is possibly an incomplete list, but it is unclear what other
-    // Decl kinds could be used to refer to the template parameters.  This is a
-    // best guess so far based on examples currently available, but the
-    // unreachable should catch future instances/cases.
-    if (auto *TD = dyn_cast<TypedefNameDecl>(D))
-      TransformType(TD->getUnderlyingType());
-    else if (auto *VD = dyn_cast<ValueDecl>(D))
-      TransformType(VD->getType());
-    else if (auto *TD = dyn_cast<TemplateDecl>(D))
-      TransformTemplateParameterList(TD->getTemplateParameters());
-    else
-      llvm_unreachable("Don't know how to handle this declaration type yet");
-    return D;
-  }
-};
-} // namespace
-
-bool Sema::ConstraintExpressionDependsOnEnclosingTemplate(
-    unsigned TemplateDepth, const Expr *Constraint) {
-  ConstraintRefersToContainingTemplateChecker Checker(*this, TemplateDepth);
-  Checker.TransformExpr(const_cast<Expr *>(Constraint));
-  return Checker.getResult();
-}
-
 /// ActOnTemplateParameterList - Builds a TemplateParameterList, optionally
 /// constrained by RequiresClause, that contains the template parameters in
 /// Params.
@@ -2339,8 +2286,7 @@ struct ConvertConstructorToDeductionGuideTransform {
           TTP->isExpandedParameterPack() ?
           llvm::Optional<unsigned>(TTP->getNumExpansionParameters()) : None);
       if (const auto *TC = TTP->getTypeConstraint())
-        SemaRef.SubstTypeConstraint(NewTTP, TC, Args,
-                                    /*IsEvaluatingAConstraint*/ false);
+        SemaRef.SubstTypeConstraint(NewTTP, TC, Args);
       if (TTP->hasDefaultArgument()) {
         TypeSourceInfo *InstantiatedDefaultArg =
             SemaRef.SubstType(TTP->getDefaultArgumentInfo(), Args,
@@ -4757,11 +4703,9 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
   bool AreArgsDependent =
       TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs,
                                                                 Converted);
-  MultiLevelTemplateArgumentList MLTAL;
-  MLTAL.addOuterTemplateArguments(Converted);
   if (!AreArgsDependent &&
       CheckConstraintSatisfaction(
-          NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL,
+          NamedConcept, {NamedConcept->getConstraintExpr()}, Converted,
           SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(),
                       TemplateArgs->getRAngleLoc()),
           Satisfaction))
@@ -5623,8 +5567,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
 
     TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted);
     Params = SubstTemplateParams(Params, CurContext,
-                                 MultiLevelTemplateArgumentList(TemplateArgs),
-                                 /*InstantiateConstraints*/ true);
+                                 MultiLevelTemplateArgumentList(TemplateArgs));
     if (!Params)
       return true;
   }
@@ -5979,20 +5922,13 @@ bool Sema::CheckTemplateArgumentList(
   if (UpdateArgsWithConversions)
     TemplateArgs = std::move(NewArgs);
 
-  if (!PartialTemplateArgs) {
-    TemplateArgumentList StackTemplateArgs(TemplateArgumentList::OnStack,
-                                           Converted);
-    MultiLevelTemplateArgumentList MLTAL = getTemplateInstantiationArgs(
-        Template, &StackTemplateArgs, /*RelativeToPrimary*/ true,
-        /*Pattern*/ nullptr,
-        /*LookBeyondLambda*/ true, /*IncludeContainingStruct*/ true);
-    if (EnsureTemplateArgumentListConstraints(
-            Template, MLTAL,
-            SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) {
-      if (ConstraintsNotSatisfied)
-        *ConstraintsNotSatisfied = true;
-      return true;
-    }
+  if (!PartialTemplateArgs &&
+      EnsureTemplateArgumentListConstraints(
+        Template, Converted, SourceRange(TemplateLoc,
+                                         TemplateArgs.getRAngleLoc()))) {
+    if (ConstraintsNotSatisfied)
+      *ConstraintsNotSatisfied = true;
+    return true;
   }
 
   return false;
@@ -7522,9 +7458,7 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
       //   are not considered.
       if (ParamsAC.empty())
         return false;
-
       Template->getAssociatedConstraints(TemplateAC);
-
       bool IsParamAtLeastAsConstrained;
       if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
                                  IsParamAtLeastAsConstrained))

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index fb7a13a21deb0..9ec33e8981983 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2783,20 +2783,6 @@ template<>
 struct IsPartialSpecialization<VarTemplatePartialSpecializationDecl> {
   static constexpr bool value = true;
 };
-template <typename TemplateDeclT>
-static bool DeducedArgsNeedReplacement(TemplateDeclT *Template) {
-  return false;
-}
-template <>
-bool DeducedArgsNeedReplacement<VarTemplatePartialSpecializationDecl>(
-    VarTemplatePartialSpecializationDecl *Spec) {
-  return !Spec->isClassScopeExplicitSpecialization();
-}
-template <>
-bool DeducedArgsNeedReplacement<ClassTemplatePartialSpecializationDecl>(
-    ClassTemplatePartialSpecializationDecl *Spec) {
-  return !Spec->isClassScopeExplicitSpecialization();
-}
 
 template<typename TemplateDeclT>
 static Sema::TemplateDeductionResult
@@ -2805,25 +2791,8 @@ CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template,
                                 TemplateDeductionInfo& Info) {
   llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
   Template->getAssociatedConstraints(AssociatedConstraints);
-  MultiLevelTemplateArgumentList MLTAL;
-
-  bool NeedsReplacement = DeducedArgsNeedReplacement(Template);
-  TemplateArgumentList DeducedTAL{TemplateArgumentList::OnStack, DeducedArgs};
-
-  MLTAL = S.getTemplateInstantiationArgs(
-      Template, /*InnerMost*/ NeedsReplacement ? nullptr : &DeducedTAL,
-      /*RelativeToPrimary*/ true, /*Pattern*/
-      nullptr, /*LookBeyondLambda*/ true);
-
-  // getTemplateInstantiationArgs picks up the non-deduced version of the
-  // template args when this is a variable template partial specialization and
-  // not class-scope explicit specialization, so replace with Deduced Args
-  // instead of adding to inner-most.
-  if (NeedsReplacement)
-    MLTAL.replaceInnermostTemplateArguments(DeducedArgs);
-
-  if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL,
-                                    Info.getLocation(),
+  if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints,
+                                    DeducedArgs, Info.getLocation(),
                                     Info.AssociatedConstraintsSatisfaction) ||
       !Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
     Info.reset(TemplateArgumentList::CreateCopy(S.Context, DeducedArgs));
@@ -4603,11 +4572,8 @@ CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
   if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs,
                                   /*PartialTemplateArgs=*/false, Converted))
     return Sema::DAR_FailedAlreadyDiagnosed;
-
-  MultiLevelTemplateArgumentList MLTAL;
-  MLTAL.addOuterTemplateArguments(Converted);
   if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
-                                    MLTAL, TypeLoc.getLocalSourceRange(),
+                                    Converted, TypeLoc.getLocalSourceRange(),
                                     Satisfaction))
     return Sema::DAR_FailedAlreadyDiagnosed;
   if (!Satisfaction.IsSatisfied) {

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 4da1e0a2db3d3..f09b3473c0749 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -57,18 +57,9 @@ using namespace sema;
 /// instantiating the definition of the given declaration, \p D. This is
 /// used to determine the proper set of template instantiation arguments for
 /// friend function template specializations.
-///
-/// \param LookBeyondLambda Indicates that this collection of arguments should
-/// continue looking when it encounters a lambda generic call operator.
-///
-/// \param IncludeContainingStructArgs Indicates that this collection of
-/// arguments should include arguments for any class template that this
-/// declaration is included inside of.
-
 MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
     const NamedDecl *D, const TemplateArgumentList *Innermost,
-    bool RelativeToPrimary, const FunctionDecl *Pattern, bool LookBeyondLambda,
-    bool IncludeContainingStructArgs) {
+    bool RelativeToPrimary, const FunctionDecl *Pattern) {
   // Accumulate the set of template argument lists in this structure.
   MultiLevelTemplateArgumentList Result;
 
@@ -164,13 +155,11 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
           break;
 
         // If this function is a generic lambda specialization, we are done.
-        if (!LookBeyondLambda &&
-            isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function))
+        if (isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function))
           break;
 
       } else if (Function->getDescribedFunctionTemplate()) {
-        assert((IncludeContainingStructArgs ||
-                Result.getNumSubstitutedLevels() == 0) &&
+        assert(Result.getNumSubstitutedLevels() == 0 &&
                "Outer template not instantiated?");
       }
 
@@ -187,18 +176,10 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
       }
     } else if (const auto *Rec = dyn_cast<CXXRecordDecl>(Ctx)) {
       if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
-        assert((IncludeContainingStructArgs ||
-                Result.getNumSubstitutedLevels() == 0) &&
+        assert(Result.getNumSubstitutedLevels() == 0 &&
                "Outer template not instantiated?");
         if (ClassTemplate->isMemberSpecialization())
           break;
-        if (IncludeContainingStructArgs) {
-          QualType RecordType = Context.getTypeDeclType(Rec);
-          QualType Injected = cast<InjectedClassNameType>(RecordType)
-                                  ->getInjectedSpecializationType();
-          const auto *InjectedType = cast<TemplateSpecializationType>(Injected);
-          Result.addOuterTemplateArguments(InjectedType->template_arguments());
-        }
       }
     }
 
@@ -949,17 +930,16 @@ namespace {
     const MultiLevelTemplateArgumentList &TemplateArgs;
     SourceLocation Loc;
     DeclarationName Entity;
-    bool EvaluatingAConstraint = false;
 
   public:
     typedef TreeTransform<TemplateInstantiator> inherited;
 
     TemplateInstantiator(Sema &SemaRef,
                          const MultiLevelTemplateArgumentList &TemplateArgs,
-                         SourceLocation Loc, DeclarationName Entity,
-                         bool EvaluatingConstraint = false)
-        : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
-          Entity(Entity), EvaluatingAConstraint(EvaluatingConstraint) {}
+                         SourceLocation Loc,
+                         DeclarationName Entity)
+      : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
+        Entity(Entity) { }
 
     /// Determine whether the given type \p T has already been
     /// transformed.
@@ -1214,18 +1194,6 @@ namespace {
       return DeclInstantiator.SubstTemplateParams(OrigTPL);
     }
 
-    TemplateParameterList *
-    TransformRequiresTemplateParameterList(TemplateParameterList *OrigTPL) {
-      if (!OrigTPL || !OrigTPL->size())
-        return OrigTPL;
-
-      DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
-      TemplateDeclInstantiator DeclInstantiator(
-          getSema(),
-          /* DeclContext *Owner */ Owner, TemplateArgs, EvaluatingAConstraint);
-      return DeclInstantiator.SubstTemplateParams(OrigTPL);
-    }
-
     concepts::TypeRequirement *
     TransformTypeRequirement(concepts::TypeRequirement *Req);
     concepts::ExprRequirement *
@@ -2018,7 +1986,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
     if (TPLInst.isInvalid())
       return nullptr;
     TemplateParameterList *TPL =
-        TransformRequiresTemplateParameterList(OrigTPL);
+        TransformTemplateParameterList(OrigTPL);
     if (!TPL)
       TransRetReq.emplace(createSubstDiag(SemaRef, Info,
           [&] (llvm::raw_ostream& OS) {
@@ -2381,21 +2349,9 @@ namespace {
 
 bool Sema::SubstTypeConstraint(
     TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
-    const MultiLevelTemplateArgumentList &TemplateArgs,
-    bool isEvaluatingAConstraint) {
+    const MultiLevelTemplateArgumentList &TemplateArgs) {
   const ASTTemplateArgumentListInfo *TemplArgInfo =
       TC->getTemplateArgsAsWritten();
-
-  // If we're not checking a constraint, we shouldn't be instantiating the type
-  // constraint, so we should just create a copy of the previous one.
-  if (!isEvaluatingAConstraint) {
-    Inst->setTypeConstraint(TC->getNestedNameSpecifierLoc(),
-                            TC->getConceptNameInfo(), TC->getNamedConcept(),
-                            TC->getNamedConcept(), TemplArgInfo,
-                            TC->getImmediatelyDeclaredConstraint());
-    return false;
-  }
-
   TemplateArgumentListInfo InstArgs;
 
   if (TemplArgInfo) {
@@ -2476,8 +2432,9 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
       // template's described function, but we might also get here later.
       // Make sure we do not instantiate the TypeConstraint more than once.
       if (Inst && !Inst->getTypeConstraint()) {
-        if (SubstTypeConstraint(Inst, TC, TemplateArgs,
-                                /*isEvaluatingAConstraint*/ false))
+        // TODO: Concepts: do not instantiate the constraint (delayed constraint
+        // substitution)
+        if (SubstTypeConstraint(Inst, TC, TemplateArgs))
           return nullptr;
       }
     }
@@ -3563,10 +3520,10 @@ Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
 bool Sema::SubstTemplateArguments(
     ArrayRef<TemplateArgumentLoc> Args,
     const MultiLevelTemplateArgumentList &TemplateArgs,
-    TemplateArgumentListInfo &Out, bool InstantiateConstraints) {
-  TemplateInstantiator Instantiator(
-      *this, TemplateArgs, SourceLocation(), DeclarationName(),
-      InstantiateConstraints);
+    TemplateArgumentListInfo &Out) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs,
+                                    SourceLocation(),
+                                    DeclarationName());
   return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(),
                                                  Out);
 }
@@ -3582,18 +3539,6 @@ Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
   return Instantiator.TransformExpr(E);
 }
 
-ExprResult
-Sema::SubstConstraintExpr(Expr *E,
-                          const MultiLevelTemplateArgumentList &TemplateArgs) {
-  if (!E)
-    return E;
-
-  TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
-                                    DeclarationName(),
-                                    /*EvaluatingConstraint*/ true);
-  return Instantiator.TransformExpr(E);
-}
-
 ExprResult Sema::SubstInitializer(Expr *Init,
                           const MultiLevelTemplateArgumentList &TemplateArgs,
                           bool CXXDirectInit) {

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index be099f5ccf6c2..d7558017948a2 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2062,7 +2062,19 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
       return nullptr;
   }
 
+  // FIXME: Concepts: Do not substitute into constraint expressions
   Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
+  if (TrailingRequiresClause) {
+    EnterExpressionEvaluationContext ConstantEvaluated(
+        SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
+    ExprResult SubstRC = SemaRef.SubstExpr(TrailingRequiresClause,
+                                           TemplateArgs);
+    if (SubstRC.isInvalid())
+      return nullptr;
+    TrailingRequiresClause = SubstRC.get();
+    if (!SemaRef.CheckConstraintExpression(TrailingRequiresClause))
+      return nullptr;
+  }
 
   // If we're instantiating a local function declaration, put the result
   // in the enclosing namespace; otherwise we need to find the instantiated
@@ -2170,11 +2182,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
     // definition. We don't want non-template functions to be marked as being
     // template instantiations.
     Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
-  } else if (!isFriend) {
-    // If this is not a function template, and this is not a friend (that is,
-    // this is a locally declared function), save the instantiation relationship
-    // for the purposes of constraint instantiation.
-    Function->setInstantiatedFromDecl(D);
   }
 
   if (isFriend) {
@@ -2413,6 +2420,23 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
       return nullptr;
   }
 
+  // FIXME: Concepts: Do not substitute into constraint expressions
+  Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
+  if (TrailingRequiresClause) {
+    EnterExpressionEvaluationContext ConstantEvaluated(
+        SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
+    auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
+    Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext,
+                                     D->getMethodQualifiers(), ThisContext);
+    ExprResult SubstRC = SemaRef.SubstExpr(TrailingRequiresClause,
+                                           TemplateArgs);
+    if (SubstRC.isInvalid())
+      return nullptr;
+    TrailingRequiresClause = SubstRC.get();
+    if (!SemaRef.CheckConstraintExpression(TrailingRequiresClause))
+      return nullptr;
+  }
+
   DeclContext *DC = Owner;
   if (isFriend) {
     if (QualifierLoc) {
@@ -2430,9 +2454,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
     if (!DC) return nullptr;
   }
 
-  CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
-  Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
-
   DeclarationNameInfo NameInfo
     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
 
@@ -2440,6 +2461,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
     adjustForRewrite(FunctionRewriteKind, D, T, TInfo, NameInfo);
 
   // Build the instantiated method declaration.
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
   CXXMethodDecl *Method = nullptr;
 
   SourceLocation StartLoc = D->getInnerLocStart();
@@ -2747,8 +2769,10 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
       // Invented template parameter type constraints will be instantiated with
       // the corresponding auto-typed parameter as it might reference other
       // parameters.
-      if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs,
-                                      EvaluatingAConstraint))
+
+      // TODO: Concepts: do not instantiate the constraint (delayed constraint
+      // substitution)
+      if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs))
         return nullptr;
     }
   }
@@ -3992,7 +4016,18 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
   if (Invalid)
     return nullptr;
 
-  Expr *InstRequiresClause = L->getRequiresClause();
+  // FIXME: Concepts: Substitution into requires clause should only happen when
+  // checking satisfaction.
+  Expr *InstRequiresClause = nullptr;
+  if (Expr *E = L->getRequiresClause()) {
+    EnterExpressionEvaluationContext ConstantEvaluated(
+        SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
+    ExprResult Res = SemaRef.SubstExpr(E, TemplateArgs);
+    if (Res.isInvalid() || !Res.isUsable()) {
+      return nullptr;
+    }
+    InstRequiresClause = Res.get();
+  }
 
   TemplateParameterList *InstL
     = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
@@ -4003,10 +4038,8 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-                          const MultiLevelTemplateArgumentList &TemplateArgs,
-                          bool InstantiateConstraints) {
-  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
-                                        InstantiateConstraints);
+                          const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
   return Instantiator.SubstTemplateParams(Params);
 }
 

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 96408b36860cb..8fe7d5545ba7c 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -13079,6 +13079,13 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
                                                         NewCallOpType);
   }
 
+  // Transform the trailing requires clause
+  ExprResult NewTrailingRequiresClause;
+  if (Expr *TRC = E->getCallOperator()->getTrailingRequiresClause())
+    // FIXME: Concepts: Substitution into requires clause should only happen
+    //                  when checking satisfaction.
+    NewTrailingRequiresClause = getDerived().TransformExpr(TRC);
+
   // Create the local class that will describe the lambda.
 
   // FIXME: DependencyKind below is wrong when substituting inside a templated
@@ -13113,7 +13120,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
       E->getCallOperator()->getEndLoc(),
       NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
       E->getCallOperator()->getConstexprKind(),
-      E->getCallOperator()->getTrailingRequiresClause());
+      NewTrailingRequiresClause.get());
 
   LSI->CallOperator = NewCallOperator;
 

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index d70e824224dfe..b4506da2bb2ba 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -953,10 +953,6 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   case FunctionDecl::TK_NonTemplate:
     mergeRedeclarable(FD, Redecl);
     break;
-  case FunctionDecl::TK_DependentNonTemplate:
-    mergeRedeclarable(FD, Redecl);
-    FD->setInstantiatedFromDecl(readDeclAs<FunctionDecl>());
-    break;
   case FunctionDecl::TK_FunctionTemplate:
     // Merged when we merge the template.
     FD->setDescribedFunctionTemplate(readDeclAs<FunctionTemplateDecl>());

diff  --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 35b8db27bd0eb..01f692c9611b7 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -585,9 +585,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   switch (D->getTemplatedKind()) {
   case FunctionDecl::TK_NonTemplate:
     break;
-  case FunctionDecl::TK_DependentNonTemplate:
-    Record.AddDeclRef(D->getInstantiatedFromDecl());
-    break;
   case FunctionDecl::TK_FunctionTemplate:
     Record.AddDeclRef(D->getDescribedFunctionTemplate());
     break;

diff  --git a/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
index 15e00e4481e75..dd6bfe8011ddf 100644
--- a/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
+++ b/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
@@ -90,24 +90,3 @@ struct D { };
 
 static_assert(C<int>{}); // expected-note{{while checking constraint satisfaction for template 'C<int>' required here}}
 static_assert(D<int>{}); // expected-note{{while checking constraint satisfaction for template 'D<int>' required here}}
-
-// Test the delayed instantiation, the 'foo' implementation shouldn't cause the
-// constraint failure(or crash!) until the use to create 'y'.
-namespace DelayedInst {
-template <unsigned I>
-struct AAA {
-  template <typename T>
-    requires(sizeof(T) == I) // expected-note {{because 'sizeof(int) == 5U' (4 == 5) evaluated to false}}
-  struct B {
-    static constexpr int a = 0;
-  };
-
-  static constexpr auto foo() {
-    return B<int>::a; // expected-error{{constraints not satisfied for class template 'B' [with T = int]}}
-  }
-};
-
-constexpr auto x = AAA<4>::foo();
-constexpr auto y = AAA<5>::foo(); // expected-note {{in instantiation of member function 'DelayedInst::AAA<5>::foo' requested here}}
-
-} // namespace DelayedInst

diff  --git a/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
index 7772eecc69be8..ceb5af87b8f02 100644
--- a/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
+++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
@@ -52,30 +52,6 @@ static_assert(F<unsigned>::value == 2);
 static_assert(F<char[10]>::value == 3);
 static_assert(F<char>::value == 1);
 
-template <unsigned I>
-struct S {
-  template <typename T>
-  struct F {
-    enum { value = 1 };
-  };
-
-  template <typename T>
-    requires C1<T> && C2<T>
-  struct F<T> {
-    enum { value = 2 };
-  };
-
-  template <typename T>
-    requires C1<T> || C2<T>
-  struct F<T> {
-    enum { value = 3 };
-  };
-};
-
-static_assert(S<1>::F<unsigned>::value == 2);
-static_assert(S<1>::F<char[10]>::value == 3);
-static_assert(S<1>::F<char>::value == 1);
-
 // Make sure atomic constraints subsume each other only if their parameter
 // mappings are identical.
 

diff  --git a/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
index 972a4fd0c5c82..98bfaead773aa 100644
--- a/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
+++ b/clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -51,20 +51,5 @@ static_assert(f<unsigned> == 2);
 static_assert(f<char[10]> == 3);
 static_assert(f<char> == 1);
 
-template <int I>
-struct S {
-  template <typename T>
-  static constexpr int f = 1;
-
-  template <typename T>
-    requires C1<T> && C2<T>
-  static constexpr int f<T> = 2;
-
-  template <typename T>
-    requires C1<T> || C2<T>
-  static constexpr int f<T> = 3;
-};
-
-static_assert(S<1>::f<unsigned> == 2);
-static_assert(S<1>::f<char[10]> == 3);
-static_assert(S<1>::f<char> == 1);
+
+

diff  --git a/clang/test/SemaTemplate/concepts-friends.cpp b/clang/test/SemaTemplate/concepts-friends.cpp
deleted file mode 100644
index 650376732339e..0000000000000
--- a/clang/test/SemaTemplate/concepts-friends.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
-
-template <typename T>
-concept constraint = false;
-namespace temp_friend_9 {
-// A non-template friend declaration with a requires-clause shall be a
-// definition. ...Such a constrained friend function ... does not declare the
-// same function or function template as a declaration in any other scope.
-template <typename T>
-struct NonTemplateFriend {
-  friend void foo()
-    requires true
-  {}
-};
-
-// A friend function template with a constraint that depends on a template
-// parameter from an enclosing template shall be a definition.  Such a ...
-// function template declaration does not declare the same function or
-// function template as a declaration in any other scope.
-template <typename T>
-struct TemplateFromEnclosing {
-  template <typename U>
-  friend void foo()
-    requires constraint<T>
-  {}
-
-  T variable;
-  template <typename U>
-  friend void foo2()
-    requires constraint<decltype(variable)>
-  {}
-
-  template <typename U>
-  friend void foo3(T parmvar)
-    requires constraint<decltype(parmvar)>
-  {}
-
-  template <typename U>
-  friend void foo4()
-    requires requires(T &req) { (void)req; }
-  {}
-
-  using Alias = T;
-  template <typename U>
-  friend void foo5()
-    requires constraint<Alias>
-  {}
-
-  // All of these refer to a parent, so these are not duplicate definitions.
-  struct ChildOfEnclosing {
-    template <typename U>
-    friend void foo6()
-      requires constraint<T>
-    {}
-    template <typename U>
-    friend void foo7()
-      requires constraint<decltype(variable)>
-    {}
-    template <typename U>
-    friend void foo8(T parmvar)
-      requires constraint<decltype(parmvar)>
-    {}
-    // This is NOT a duplicate since it itself is not a template.
-    friend void foo9()
-      requires true
-    {}
-  };
-  template <typename T2>
-  struct TemplChildOfEnclosing {
-    template <typename U>
-    friend void foo10()
-      requires constraint<T>
-    {}
-  };
-};
-
-// Doesn't meet either of the requirements in the above as they don't refer to
-// an enclosing scope.
-template <typename T>
-struct Redefinition {
-  template <typename U>
-  friend void foo() // #REDEF
-    requires constraint<U>
-  {}
-
-  struct ChildOfRedef {
-    template <typename U>
-    friend void foo2() // #REDEF2
-      requires constraint<U>
-    {}
-  };
-  template <typename T2>
-  struct ChildOfRedef2 {
-    template <typename U>
-    friend void foo3() // #REDEF3
-      requires constraint<U>
-    {}
-  };
-};
-
-void bar() {
-  NonTemplateFriend<int> S1;
-  NonTemplateFriend<float> S2;
-  TemplateFromEnclosing<int> S3;
-  TemplateFromEnclosing<int>::ChildOfEnclosing S3b;
-  TemplateFromEnclosing<float> S4;
-  TemplateFromEnclosing<float>::ChildOfEnclosing S4b;
-  Redefinition<int> S5;
-  Redefinition<float> S6;
-  // expected-error@#REDEF {{redefinition of 'foo'}}
-  // expected-note at -2{{in instantiation of template class }}
-  // expected-note@#REDEF {{previous definition is here}}
-  Redefinition<int>::ChildOfRedef S7;
-  Redefinition<float>::ChildOfRedef S8;
-  // expected-error@#REDEF2 {{redefinition of 'foo2'}}
-  // expected-note at -2{{in instantiation of member class }}
-  // expected-note@#REDEF2 {{previous definition is here}}
-
-  Redefinition<int>::ChildOfRedef2<int> S9;
-  Redefinition<float>::ChildOfRedef2<float> S10;
-  // expected-error@#REDEF3 {{redefinition of 'foo3'}}
-  // expected-note at -2{{in instantiation of template class }}
-  // expected-note@#REDEF3 {{previous definition is here}}
-}
-} // namespace temp_friend_9
-
-namespace SameScopeRedefs {
-template <typename T>
-struct NonTemplateFriend {
-  friend void foo() // #NTF1
-    requires true
-  {}
-  friend void foo() // #NTF2
-    requires true
-  {}
-};
-
-template <typename T>
-struct TemplateFromEnclosing {
-  template <typename U>
-  friend void foo() // #TFE1
-    requires constraint<T>
-  {}
-  template <typename U>
-  friend void foo() // #TFE2
-    requires constraint<T>
-  {}
-};
-// Same as above, but doesn't require an instantiation pair to cause.
-template <typename T>
-struct Redefinition {
-  template <typename U>
-  friend void foo() // #RD1
-    requires constraint<U>
-  {}
-  template <typename U>
-  friend void foo() // #RD2
-    requires constraint<U>
-  {}
-};
-void bar() {
-  NonTemplateFriend<int> S1;
-  // expected-error@#NTF2 {{redefinition of 'foo'}}
-  // expected-note at -2{{in instantiation of template class}}
-  // expected-note@#NTF1 {{previous definition is here}}
-
-  TemplateFromEnclosing<int> S2;
-  // expected-error@#TFE2 {{redefinition of 'foo'}}
-  // expected-note at -2{{in instantiation of template class}}
-  // expected-note@#TFE1 {{previous definition is here}}
-
-  Redefinition<int> S3;
-  // expected-error@#RD2 {{redefinition of 'foo'}}
-  // expected-note at -2{{in instantiation of template class}}
-  // expected-note@#RD1 {{previous definition is here}}
-}
-} // namespace SameScopeRedefs
-
-namespace LibCXXOperatorRedef {
-template <typename T, typename U> struct is_same {
-  static constexpr bool value = false;
-};
-template <typename T> struct is_same<T, T> {
-  static constexpr bool value = false;
-};
-
-template <typename T, typename U>
-concept same_as = is_same<T, U>::value;
-
-// An issue found from libcxx when trying to commit the deferred concepts patch.
-// This caused an error of 'redefinition of funcN'.
-template <class _Tp> struct __range_adaptor_closure {
-  template <typename _View, typename _Closure>
-    requires same_as<_Tp, _Closure>
-  friend constexpr decltype(auto) R1func1(_View &&__view,
-                                          _Closure &&__closure){};
-  template <typename _View, typename _Closure>
-  friend constexpr decltype(auto) R1func2(_View &&__view,
-                                          _Closure &&__closure)
-    requires same_as<_Tp, _Closure>
-  {};
-  template <same_as<_Tp> _View, typename _Closure>
-  friend constexpr decltype(auto) R1func3(_View &&__view,
-                                          _Closure &&__closure){};
-};
-
-struct A : __range_adaptor_closure<A> {};
-struct B : __range_adaptor_closure<B> {};
-
-// These three fail because after the 1st pass of instantiation, they are still
-// identical.
-template <class _Tp> struct __range_adaptor_closure2 {
-  template <typename _View, typename _Closure>
-    requires same_as<_View, _Closure>
-  friend constexpr decltype(auto) R2func1(_View &&__view, // #FUNC1
-                                          _Closure &&__closure){};
-  template <typename _View, typename _Closure>
-  friend constexpr decltype(auto) R2func2(_View &&__view, // #FUNC2
-                                          _Closure &&__closure)
-    requires same_as<_View, _Closure>
-  {};
-  template <typename _View, same_as<_View> _Closure>
-  friend constexpr decltype(auto) R2func3(_View &&__view, // #FUNC3
-                                          _Closure &&__closure){};
-};
-
-struct A2 : __range_adaptor_closure2<A2> {};
-struct B2 : __range_adaptor_closure2<B2> {};
-// expected-error@#FUNC1{{redefinition of 'R2func1'}}
-// expected-note at -2{{in instantiation of template class}}
-// expected-note@#FUNC1{{previous definition is here}}
-// expected-error@#FUNC2{{redefinition of 'R2func2'}}
-// expected-note@#FUNC2{{previous definition is here}}
-// expected-error@#FUNC3{{redefinition of 'R2func3'}}
-// expected-note@#FUNC3{{previous definition is here}}
-
-// These three are fine, they all depend on the parent template parameter, so
-// are 
diff erent despite ::type not being valid.
-template <class _Tp> struct __range_adaptor_closure3 {
-  template <typename _View, typename _Closure>
-    requires same_as<typename _Tp::type, _Closure>
-  friend constexpr decltype(auto) R3func1(_View &&__view,
-                                          _Closure &&__closure){};
-  template <typename _View, typename _Closure>
-  friend constexpr decltype(auto) R3func2(_View &&__view,
-                                          _Closure &&__closure)
-    requires same_as<typename _Tp::type, _Closure>
-  {};
-  template <same_as<typename _Tp::type> _View, typename _Closure>
-  friend constexpr decltype(auto) R3func3(_View &&__view,
-                                          _Closure &&__closure){};
-};
-
-struct A3 : __range_adaptor_closure3<A3> {};
-struct B3 : __range_adaptor_closure3<B3> {};
-
-template <class _Tp> struct __range_adaptor_closure4 {
-  template <typename _View, typename _Closure>
-    requires same_as<_Tp, _View>
-  // expected-note at +1{{previous definition is here}}
-  void foo1(_View &&, _Closure &&) {}
-  template <typename _View, typename _Closure>
-    requires same_as<_Tp, _View>
-  // expected-error at +1{{class member cannot be redeclared}}
-  void foo1(_View &&, _Closure &&) {}
-
-  template <typename _View, typename _Closure>
-  // expected-note at +1{{previous definition is here}}
-  void foo2(_View &&, _Closure &&)
-    requires same_as<_Tp, _View>
-  {}
-  template <typename _View, typename _Closure>
-  // expected-error at +1{{class member cannot be redeclared}}
-  void foo2(_View &&, _Closure &&)
-    requires same_as<_Tp, _View>
-  {}
-
-  template <same_as<_Tp> _View, typename _Closure>
-  // expected-note at +1{{previous definition is here}}
-  void foo3(_View &&, _Closure &&) {}
-  template <same_as<_Tp> _View, typename _Closure>
-  // expected-error at +1{{class member cannot be redeclared}}
-  void foo3(_View &&, _Closure &&) {}
-};
-
-// Requires instantiation to fail, so no errors here.
-template <class _Tp> struct __range_adaptor_closure5 {
-  template <same_as<_Tp> U>
-  friend void foo() {}
-  template <same_as<_Tp> U>
-  friend void foo() {}
-};
-
-template <class _Tp> struct __range_adaptor_closure6 {
-  template <same_as<_Tp> U>
-  friend void foo() {} // #RAC6FOO1
-  template <same_as<_Tp> U>
-  friend void foo() {} // #RAC6FOO2
-};
-struct A6 : __range_adaptor_closure6<A6> {};
-// expected-error@#RAC6FOO2{{redefinition of 'foo'}}
-// expected-note at -2{{in instantiation of template class}}
-// expected-note@#RAC6FOO1{{previous definition is here}}
-
-template <class T> struct S1 {
-  template <typename U>
-  friend void dupe() {} // #S1DUPE
-
-  template <typename U>
-    requires same_as<U, U>
-  friend void dupe2() {} // #S1DUPE2
-};
-template <class T> struct S2 {
-  template <typename U>
-  friend void dupe() {} // #S2DUPE
-
-  template <typename U>
-    requires same_as<U, U>
-  friend void dupe2() {} // #S2DUPE2
-};
-
-template <class T> struct S3 {
-  template <typename U>
-    requires same_as<T, U>
-  friend void dupe() {}
-};
-template <class T> struct S4 {
-  template <typename U>
-    requires same_as<T, U>
-  friend void dupe() {}
-};
-
-// Same as S3 and S4, but aren't instantiated with the same T.
-template <class T> struct S5 {
-  template <typename U>
-    requires same_as<T, U>
-  friend void not_dupe() {}
-};
-template <class T> struct S6 {
-  template <typename U>
-    requires same_as<T, U>
-  friend void not_dupe() {}
-};
-
-template <class T> struct S7 {
-  void not_dupe()
-    requires same_as<T, T>
-  {}
-};
-
-void useS() {
-  S1<int> s1;
-  S2<double> s2;
-  // expected-error@#S2DUPE{{redefinition}}
-  // expected-note at -2{{in instantiation of template class}}
-  // expected-note@#S1DUPE{{previous definition is here}}
-  // expected-error@#S2DUPE2{{redefinition}}
-  // expected-note@#S1DUPE2{{previous definition is here}}
-
-  // OK, they have 
diff erent 'scopes'.
-  S3<int> s3;
-  S4<int> s4;
-
-  // OK, because only instantiated with 
diff erent T.
-  S5<int> s5;
-  S6<double> s6;
-
-  S7<int> s7;
-}
-
-} // namespace LibCXXOperatorRedef

diff  --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 390d0e4562725..23c79421bb6f8 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -256,321 +256,3 @@ C auto **j1 = g();   // expected-error {{deduced type 'int' does not satisfy 'C'
 C auto **&j2 = g();  // expected-error {{deduced type 'int' does not satisfy 'C'}}
 C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}}
 }
-
-namespace SubConstraintChecks {
-template <typename T>
-concept TrueConstraint = true;
-template <typename T>
-concept FalseConstraint = false;
-
-template <typename T, typename... Us>
-class ContainsConstrainedFuncTrue {
-public:
-  template <typename V, TrueConstraint Constrained>
-  static void func(V &&, Constrained &&C);
-};
-template <typename T, typename... Us>
-class ContainsConstrainedFuncFalse {
-public:
-  template <typename V, FalseConstraint Constrained>
-  static void func(V &&, Constrained &&C);
-};
-
-template <typename... Us>
-concept TrueConstraint2 =
-    requires(float &&t) {
-      ContainsConstrainedFuncTrue<float, Us...>::func(5, 0.0);
-    };
-template <typename... Us>
-concept FalseConstraint2 =
-    requires(float &&t) {
-      ContainsConstrainedFuncFalse<float, Us...>::func(5, 0.0); // #FC2_CONSTR
-    };
-
-template <typename T>
-void useTrue(int F)
-  requires TrueConstraint2<int>
-{}
-
-template <typename T>
-void useFalse(int F)             // #USE_FALSE
-  requires FalseConstraint2<int> // #USE_FALSE_CONSTR
-{}
-
-// Should only diagnose 'false' once instantiated.
-void UseUse() {
-  useTrue<int>(5);
-  useFalse<int>(5);
-  // expected-error at -1{{no matching function for call to 'useFalse'}}
-  // expected-note@#USE_FALSE{{constraints not satisfied}}
-  // expected-note@#USE_FALSE_CONSTR{{because 'int' does not satisfy 'FalseConstraint2'}}
-  // expected-note@#FC2_CONSTR {{would be invalid: no matching function for call to 'func'}}
-}
-} // namespace SubConstraintChecks
-
-namespace DeducedTemplateArgs {
-template <typename Itr> struct ItrTraits {
-  template <typename PtrItr> struct Ptr {
-  };
-  template <typename PtrItr>
-    requires requires { typename PtrItr::pointer; }
-  struct Ptr<PtrItr> {
-    using type = typename Itr::pointer;
-  };
-  using pointer = typename Ptr<Itr>::type; // #TRAITS_PTR
-};
-
-struct complete_itr {
-  using pointer = int;
-};
-
-template <typename T> class Complete {
-  using ItrType = ItrTraits<complete_itr>;
-  ItrType begin() noexcept { return ItrType(); }
-};
-
-// This version doesn't have 'pointer', so error confirms we are in the first
-// verison of 'Ptr'.
-struct not_complete_itr {
-};
-
-template <typename T> class NotComplete {
-  using ItrType = ItrTraits<not_complete_itr>;
-  ItrType begin() noexcept { return ItrType(); }
-  // expected-error@#TRAITS_PTR{{no type named 'type' in }}
-  // expected-note at -2{{in instantiation of template class }}
-};
-} // namespace DeducedTemplateArgs
-
-namespace DeferredInstantiationInstScope {
-template <typename T>
-struct remove_ref {
-  using type = T;
-};
-template <typename T>
-struct remove_ref<T &> {
-  using type = T;
-};
-template <typename T>
-struct remove_ref<T &&> {
-  using type = T;
-};
-
-template <typename T>
-constexpr bool IsInt = PR54443::is_same<typename remove_ref<T>::type,
-                                        int>::value;
-
-template <typename U>
-void SingleDepthReferencesTop(U &&u) {
-  struct lc {
-    void operator()()             // #SDRT_OP
-      requires IsInt<decltype(u)> // #SDRT_REQ
-    {}
-  };
-  lc lv;
-  lv(); // #SDRT_CALL
-}
-
-template <typename U>
-void SingleDepthReferencesTopNotCalled(U &&u) {
-  struct lc {
-    void operator()()
-      requires IsInt<typename decltype(u)::FOO>
-    {}
-  };
-  lc lv;
-}
-
-template <typename U>
-void SingleDepthReferencesTopCalled(U &&u) {
-  struct lc {
-    void operator()()                           // #CALLOP
-      requires IsInt<typename decltype(u)::FOO> // #CONSTR
-    {}
-  };
-  lc lv;
-  lv();
-  // expected-error at -1{{no matching function for call to object of type 'lc'}}
-  // expected-note@#SDRTC{{in instantiation of function template}}
-  // expected-note@#CALLOP{{constraints not satisfied}}
-  // expected-note@#CONSTR{{substituted constraint expression is ill-formed}}
-}
-
-template <typename U>
-void SingleDepthReferencesTopLambda(U &&u) {
-  []()
-    requires IsInt<decltype(u)>
-  {}();
-}
-
-template <typename U>
-void DoubleDepthReferencesTop(U &&u) {
-  struct lc { // #DDRT_STRCT
-    void operator()() {
-      struct lc2 {
-        void operator()()             // #DDRT_OP
-          requires IsInt<decltype(u)> // #DDRT_REQ
-        {}
-      };
-      lc2 lv2;
-      lv2(); // #DDRT_CALL
-    }
-  };
-  lc lv;
-  lv();
-}
-
-template <typename U>
-void DoubleDepthReferencesTopLambda(U &&u) {
-  []() { []()
-           requires IsInt<decltype(u)>
-         {}(); }();
-}
-
-template <typename U>
-void DoubleDepthReferencesAll(U &&u) {
-  struct lc { // #DDRA_STRCT
-    void operator()(U &&u2) {
-      struct lc2 {
-        void operator()(U &&u3)          // #DDRA_OP
-          requires IsInt<decltype(u)> && // #DDRA_REQ
-                   IsInt<decltype(u2)> && IsInt<decltype(u3)>
-        {}
-      };
-      lc2 lv2;
-      lv2(u2); // #DDRA_CALL
-    }
-  };
-  lc lv;
-  lv(u);
-}
-
-template <typename U>
-void DoubleDepthReferencesAllLambda(U &&u) {
-  [](U &&u2) {
-    [](U && u3)
-      requires IsInt<decltype(u)> &&
-               IsInt<decltype(u2)> && IsInt<decltype(u3)>
-    {}(u2);
-  }(u);
-}
-
-template <typename U>
-struct CausesFriendConstraint {
-  template <typename V>
-  friend void FriendFunc(CausesFriendConstraint, V) // #FF_DECL
-    requires IsInt<U> &&
-             IsInt<V> // #FF_REQ
-  {}
-};
-// FIXME: Re-enable this test when constraints are allowed to refer to captures.
-// template<typename T>
-// void ChecksCapture(T x) {
-//   [y = x]() requires(IsInt<decltype(y)>){}();
-// }
-
-template <typename T>
-void ChecksLocalVar(T x) {
-  T Local;
-  []()
-    requires(IsInt<decltype(Local)>)
-  {}();
-}
-
-template <typename T>
-void LocalStructMemberVar(T x) {
-  struct S {
-    T local;
-    void foo()
-      requires(IsInt<decltype(local)>) // #LSMV_REQ
-    {}
-  } s;
-  s.foo(); // #LSMV_CALL
-};
-
-template <typename T>
-struct ChecksMemberVar {
-  T t;
-  void foo()
-    requires(IsInt<decltype(t)>) // #CMV_FOO
-  {}
-  template <typename U>
-  void foo2()                    // #CMV_FOO2
-    requires(IsInt<decltype(t)>) // #CMV_FOO2_REQ
-  {}
-};
-
-void test_dependent() {
-  int v = 0;
-  float will_fail;
-  SingleDepthReferencesTop(v);
-  SingleDepthReferencesTop(will_fail);
-  // expected-error@#SDRT_CALL{{no matching function for call to object of type 'lc'}}
-  // expected-note at -2{{in instantiation of function template specialization}}
-  // expected-note@#SDRT_OP{{candidate function not viable}}
-  // expected-note@#SDRT_REQ{{'IsInt<decltype(u)>' evaluated to false}}
-
-  SingleDepthReferencesTopNotCalled(v);
-  // Won't error unless we try to call it.
-  SingleDepthReferencesTopNotCalled(will_fail);
-  SingleDepthReferencesTopCalled(v); // #SDRTC
-  SingleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
-  SingleDepthReferencesTopLambda(will_fail);
-  DoubleDepthReferencesTop(v);
-  DoubleDepthReferencesTop(will_fail);
-  // expected-error@#DDRT_CALL{{no matching function for call to object of type 'lc2'}}
-  // expected-note at -2{{in instantiation of function template specialization}}
-  // expected-note@#DDRT_STRCT{{in instantiation of member function}}
-  // expected-note@#DDRT_OP{{candidate function not viable}}
-  // expected-note@#DDRT_REQ{{'IsInt<decltype(u)>' evaluated to false}}
-
-  DoubleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
-  DoubleDepthReferencesTopLambda(will_fail);
-  DoubleDepthReferencesAll(v);
-  DoubleDepthReferencesAll(will_fail);
-  // expected-error@#DDRA_CALL{{no matching function for call to object of type 'lc2'}}
-  // expected-note at -2{{in instantiation of function template specialization}}
-  // expected-note@#DDRA_STRCT{{in instantiation of member function}}
-  // expected-note@#DDRA_OP{{candidate function not viable}}
-  // expected-note@#DDRA_REQ{{'IsInt<decltype(u)>' evaluated to false}}
-
-  DoubleDepthReferencesAllLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
-  DoubleDepthReferencesAllLambda(will_fail);
-
-  CausesFriendConstraint<int> CFC;
-  FriendFunc(CFC, 1);
-  FriendFunc(CFC, 1.0);
-  // expected-error at -1{{no matching function for call to 'FriendFunc'}}
-  // expected-note@#FF_DECL{{constraints not satisfied}}
-  // expected-note@#FF_REQ{{because 'IsInt<double>' evaluated to false}}
-
-  // FIXME: Re-enable this test when constraints are allowed to refer to captures.
-  // ChecksCapture(v);
-
-  ChecksLocalVar(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
-  ChecksLocalVar(will_fail);
-
-  LocalStructMemberVar(v);
-  LocalStructMemberVar(will_fail);
-  // expected-error@#LSMV_CALL{{invalid reference to function 'foo'}}
-  // expected-note at -2{{in instantiation of function template specialization}}
-  // expected-note@#LSMV_REQ{{because 'IsInt<decltype(this->local)>' evaluated to false}}
-
-  ChecksMemberVar<int> CMV;
-  CMV.foo();
-  CMV.foo2<int>();
-
-  ChecksMemberVar<float> CMV2;
-  CMV2.foo();
-  // expected-error at -1{{invalid reference to function 'foo'}}
-  // expected-note@#CMV_FOO{{because 'IsInt<decltype(this->t)>' evaluated to false}}
-  CMV2.foo2<float>();
-  // expected-error at -1{{no matching member function for call to 'foo2'}}
-  // expected-note@#CMV_FOO2{{constraints not satisfied}}
-  // expected-note@#CMV_FOO2_REQ{{because 'IsInt<decltype(this->t)>' evaluated to false}}
-}
-} // namespace DeferredInstantiationInstScope

diff  --git a/clang/test/SemaTemplate/deferred-concept-inst.cpp b/clang/test/SemaTemplate/deferred-concept-inst.cpp
deleted file mode 100644
index dd9a4086a42ed..0000000000000
--- a/clang/test/SemaTemplate/deferred-concept-inst.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -fsyntax-only -Wno-unused-value
-// expected-no-diagnostics
-
-namespace GithubBug44178 {
-template <typename D>
-struct CRTP {
-  void call_foo()
-    requires requires(D &v) { v.foo(); }
-  {
-    static_cast<D *>(this)->foo();
-  }
-};
-
-struct Test : public CRTP<Test> {
-  void foo() {}
-};
-
-int main() {
-  Test t;
-  t.call_foo();
-  return 0;
-}
-} // namespace GithubBug44178

diff  --git a/clang/test/SemaTemplate/instantiate-requires-clause.cpp b/clang/test/SemaTemplate/instantiate-requires-clause.cpp
index 3f438d8885a20..73dd20d27d226 100644
--- a/clang/test/SemaTemplate/instantiate-requires-clause.cpp
+++ b/clang/test/SemaTemplate/instantiate-requires-clause.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -x c++ %s -Wno-unused-value -verify
+// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
 
 template <typename... Args> requires ((sizeof(Args) == 1), ...)
 // expected-note at -1 {{because '(sizeof(int) == 1) , (sizeof(char) == 1) , (sizeof(int) == 1)' evaluated to false}}
@@ -40,20 +40,6 @@ struct S {
 
 static_assert(S<void>::f(1));
 
-// Similar to the 'S' test, but tries to use 'U' in the requires clause.
-template <typename T2>
-struct S1 {
-  // expected-note at +3 {{candidate template ignored: constraints not satisfied [with U = int]}}
-  // expected-note at +3 {{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}
-  template <typename U>
-  static constexpr auto f(U const index)
-    requires(U::foo)
-  { return true; }
-};
-
-// expected-error at +1 {{no matching function for call to 'f'}}
-static_assert(S1<void>::f(1));
-
 constexpr auto value = 0;
 
 template<typename T>

diff  --git a/clang/test/SemaTemplate/trailing-return-short-circuit.cpp b/clang/test/SemaTemplate/trailing-return-short-circuit.cpp
deleted file mode 100644
index 0d1c9b52b0e85..0000000000000
--- a/clang/test/SemaTemplate/trailing-return-short-circuit.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -verify %s
-
-template <class T>
-  requires(sizeof(T) > 2) || T::value // #FOO_REQ
-void Foo(T){};                        // #FOO
-
-template <class T>
-void TrailingReturn(T)       // #TRAILING
-  requires(sizeof(T) > 2) || // #TRAILING_REQ
-          T::value           // #TRAILING_REQ_VAL
-{};
-template <bool B>
-struct HasValue {
-  static constexpr bool value = B;
-};
-static_assert(sizeof(HasValue<true>) <= 2);
-
-template <bool B>
-struct HasValueLarge {
-  static constexpr bool value = B;
-  int I;
-};
-static_assert(sizeof(HasValueLarge<true>) > 2);
-
-void usage() {
-  // Passes the 1st check, short-circuit so the 2nd ::value is not evaluated.
-  Foo(1.0);
-  TrailingReturn(1.0);
-
-  // Fails the 1st check, but has a ::value, so the check happens correctly.
-  Foo(HasValue<true>{});
-  TrailingReturn(HasValue<true>{});
-
-  // Passes the 1st check, but would have passed the 2nd one.
-  Foo(HasValueLarge<true>{});
-  TrailingReturn(HasValueLarge<true>{});
-
-  // Fails the 1st check, fails 2nd because there is no ::value.
-  Foo(true);
-  // expected-error at -1{{no matching function for call to 'Foo'}}
-  // expected-note@#FOO{{candidate template ignored: constraints not satisfied [with T = bool]}}
-  // expected-note@#FOO_REQ{{because 'sizeof(_Bool) > 2' (1 > 2) evaluated to false}}
-  // expected-note@#FOO_REQ{{because substituted constraint expression is ill-formed: type 'bool' cannot be used prior to '::' because it has no members}}
-
-  TrailingReturn(true);
-  // expected-error at -1{{no matching function for call to 'TrailingReturn'}}
-  // expected-note@#TRAILING{{candidate template ignored: constraints not satisfied [with T = bool]}}
-  // expected-note@#TRAILING_REQ{{because 'sizeof(_Bool) > 2' (1 > 2) evaluated to false}}
-  // expected-note@#TRAILING_REQ_VAL{{because substituted constraint expression is ill-formed: type 'bool' cannot be used prior to '::' because it has no members}}
-
-  // Fails the 1st check, fails 2nd because ::value is false.
-  Foo(HasValue<false>{});
-  // expected-error at -1 {{no matching function for call to 'Foo'}}
-  // expected-note@#FOO{{candidate template ignored: constraints not satisfied [with T = HasValue<false>]}}
-  // expected-note@#FOO_REQ{{because 'sizeof(HasValue<false>) > 2' (1 > 2) evaluated to false}}
-  // expected-note@#FOO_REQ{{and 'HasValue<false>::value' evaluated to false}}
-  TrailingReturn(HasValue<false>{});
-  // expected-error at -1 {{no matching function for call to 'TrailingReturn'}}
-  // expected-note@#TRAILING{{candidate template ignored: constraints not satisfied [with T = HasValue<false>]}}
-  // expected-note@#TRAILING_REQ{{because 'sizeof(HasValue<false>) > 2' (1 > 2) evaluated to false}}
-  // expected-note@#TRAILING_REQ_VAL{{and 'HasValue<false>::value' evaluated to false}}
-}


        


More information about the cfe-commits mailing list