Index: src/Parser/TypeData.cpp
===================================================================
--- src/Parser/TypeData.cpp	(revision 597ddfeb10fef2c06e63efb640839e2647564036)
+++ src/Parser/TypeData.cpp	(revision 6174ecc742d3800f0a71962e3e54fc334b9e774b)
@@ -1585,8 +1585,29 @@
 	buildParamList( td->function.params, params );
 	buildForall( td->forall, forall );
-	// Functions do not store their assertions there anymore.
+	// Functions do not store their assertions there anymore.  <-- FIXME: clarify or remove this comment
+	// Assertions were parsed as belonging to the type that preceded them.
+	// forall ( T | is_foo(T), U | are_bar(T, U) )
+	//   => parse
+	// forall( [ typarm( T, [is_foo(T)] ), typarm( U, [are_bar(T, U)] ) ] )
+	//   => now, flatten as
+	// forall( [ T, U ] ), assns( [ is_foo(T), are_bar(T, U)] )
 	for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
 		auto mut = type_param.get_and_mutate();
 		splice( assertions, mut->assertions );
+	}
+	// When assertions without a type preceding them were parsed, placeholder
+	// types were invented to hold them.
+	// forall ( | is_foo(), U | is_bar(U) )
+	//   => parse
+	// forall( [ typarm( PLCHLD, [is_foo()] ), typarm( U, [is_bar(U)] ) ] )
+	//   => prev step
+	// forall( [ PLCHLD, U ] ), assns( [ is_foo(), is_bar(U)] )
+	//   => now, remove the placeholders
+	// forall( [ U ] ), assns( [ is_foo(), is_bar(U)] )
+	for (std::vector<ast::ptr<ast::TypeDecl>>::iterator it = forall.begin();
+			it != forall.end(); ) {
+		// placeholder types have empty names
+		if ( (*it)->name == "" ) it = forall.erase(it);
+		else ++it;
 	}
 	if ( td->base ) {
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 597ddfeb10fef2c06e63efb640839e2647564036)
+++ src/Parser/parser.yy	(revision 6174ecc742d3800f0a71962e3e54fc334b9e774b)
@@ -3132,5 +3132,6 @@
 	// | type_specifier identifier_parameter_declarator
 	| assertion_list
-		{ $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
+		// Invent a placeholder type to wrap these bare assertions.  Rely on buildFunctionDecl to remove the placeholder.
+		{ $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( "" ) )->addAssertions( $1 ); }
 	| ENUM '(' identifier_or_type_name ')' identifier_or_type_name new_type_class type_initializer_opt assertion_list_opt
 		{	
