Index: cp/pt.c
===================================================================
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 200378)
+++ cp/parser.c	(working copy)
@@ -16431,6 +16431,33 @@ cp_parser_init_declarator (cp_parser* pa
   attributes_start_token = cp_lexer_peek_token (parser->lexer);
   attributes = cp_parser_attributes_opt (parser);
 
+  // Save off the current template constraints. These will apply
+  // to the nested scope, not the declarator. Consider, an out-of-class
+  // member definition:
+  //
+  //    template<typename T>
+  //      requires C<T>()
+  //        void S<T>::f() requires D<T>() { ... }
+  //
+  // At the point we parse the 2nd requires clause, the previous the
+  // current constraints will have been used to resolve the enclosing
+  // class S<T>. The D<T>() requirement applies only to the definition
+  // of f and do not include C<T>().
+  tree saved_template_reqs = release (current_template_reqs);
+
+  // Parse an optional requires clause. Currently, requirements can
+  // be written for out-of-class member function definitions.
+  //
+  // TODO: It may be better to always parse and diagnose the error
+  // as a semantic one later on.
+  if (flag_concepts && scope && function_declarator_p (declarator))
+    {
+      if (tree r = cp_parser_requires_clause_opt (parser))
+        current_template_reqs = finish_template_requirements (r);
+    }
+  else
+    current_template_reqs = saved_template_reqs;
+
   /* Peek at the next token.  */
   token = cp_lexer_peek_token (parser->lexer);
   /* Check to see if the token indicates the start of a
@@ -16444,6 +16471,7 @@ cp_parser_init_declarator (cp_parser* pa
 	     error message.  */
 	  cp_parser_error (parser,
 			   "a function-definition is not allowed here");
+          current_template_reqs = saved_template_reqs;
 	  return error_mark_node;
 	}
       else
@@ -16481,6 +16509,9 @@ cp_parser_init_declarator (cp_parser* pa
 		= func_brace_location;
 	    }
 
+          // Restore the current requirements before returning.
+          current_template_reqs = saved_template_reqs;
+
 	  return decl;
 	}
     }
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 200378)
+++ cp/decl2.c	(working copy)
@@ -655,6 +655,11 @@ check_classfn (tree ctype, tree function
       return error_mark_node;
     }
 
+  // Use the current template requirements as the constraints
+  // for function. Unfortunately, when this is called, FUNCTION
+  // does not have a TEMPLATE_DECL yet.
+  tree constr = current_template_reqs;
+
   /* We must enter the scope here, because conversion operators are
      named by target type, and type equivalence relies on typenames
      resolving within the scope of CTYPE.  */
@@ -707,6 +712,7 @@ check_classfn (tree ctype, tree function
 	      && (!is_template
 		  || comp_template_parms (template_parms,
 					  DECL_TEMPLATE_PARMS (fndecl)))
+              && equivalent_constraints (constr, get_constraints (fndecl))
 	      && (DECL_TEMPLATE_SPECIALIZATION (function)
 		  == DECL_TEMPLATE_SPECIALIZATION (fndecl))
 	      && (!DECL_TEMPLATE_SPECIALIZATION (function)
Index: cp/constraint.cc
===================================================================
--- cp/constraint.cc	(revision 200378)
+++ cp/constraint.cc	(working copy)
@@ -545,7 +545,7 @@ bool
 equivalently_constrained (tree a, tree b)
 {
   gcc_assert (TREE_CODE (a) == TREE_CODE (b));
-  return equivalent_constraints (DECL_CONSTRAINTS (a), DECL_CONSTRAINTS (b));
+  return equivalent_constraints (get_constraints (a), get_constraints (b));
 }
 
 // Returns true when the A contains more atomic properties than B.
@@ -561,7 +561,7 @@ bool
 more_constrained (tree a, tree b)
 {
   gcc_assert (TREE_CODE (a) == TREE_CODE (b));
-  return more_constraints (DECL_CONSTRAINTS (a), DECL_CONSTRAINTS (b));
+  return more_constraints (get_constraints (a), get_constraints (b));
 }
 
 
