Index: libcfa/src/collections/string.hfa
===================================================================
--- libcfa/src/collections/string.hfa	(revision aacd1e17bd7033c9616fd50316ce5c38575314dc)
+++ libcfa/src/collections/string.hfa	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -23,10 +23,7 @@
 };
 
-// Getters
-static inline size_t len( const string & s ) { return len( *s.inner ); }
-static inline size_t len( const char * cs ) { return strlen( cs ); };
-static inline size_t strlen( const string & s ) { return len( s ); }
-
 // RAII, assignment
+void ^?{}( string & s );
+
 void ?{}( string & s );									// empty string
 void ?{}( string & s, const string & s2 );
@@ -58,10 +55,4 @@
 string & assign( string & s, const string & c, size_t n );
 string & assign( string & s, const char * c, size_t n );
-
-static inline string & strcpy( string & s, const char * c ) { s = c; return s; }
-static inline string & strncpy( string & s, const char * c, size_t n ) { assign( s, c, n ); return s; }
-static inline string & strcpy( string & s, const string & c ) { s = c; return s; }
-static inline string & strncpy( string & s, const string & c, size_t n ) { assign( s, c, n ); return s; }
-
 string & ?=?( string & s, ssize_t rhs );
 string & ?=?( string & s, size_t rhs );
@@ -71,5 +62,8 @@
 string & ?=?( string & s, long double _Complex rhs );
 
-void ^?{}( string & s );
+static inline string & strcpy( string & s, const char * c ) { s = c; return s; }
+static inline string & strncpy( string & s, const char * c, size_t n ) { assign( s, c, n ); return s; }
+static inline string & strcpy( string & s, const string & c ) { s = c; return s; }
+static inline string & strncpy( string & s, const string & c, size_t n ) { assign( s, c, n ); return s; }
 
 // Alternate construction: request shared edits
@@ -79,4 +73,9 @@
 string_Share ?`share( string & s );
 void ?{}( string & s, string_Share src );
+
+// Getters
+static inline size_t len( const string & s ) { return len( *s.inner ); }
+static inline size_t len( const char * cs ) { return strlen( cs ); };
+static inline size_t strlen( const string & s ) { return len( s ); }
 
 // IO Operator
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision aacd1e17bd7033c9616fd50316ce5c38575314dc)
+++ src/AST/Util.cpp	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -260,4 +260,5 @@
 			}
 		}
+		if ( ! type->assertions.empty() ) visit_children = false;
 	}
 
Index: src/Parser/TypeData.cpp
===================================================================
--- src/Parser/TypeData.cpp	(revision aacd1e17bd7033c9616fd50316ce5c38575314dc)
+++ src/Parser/TypeData.cpp	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -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 aacd1e17bd7033c9616fd50316ce5c38575314dc)
+++ src/Parser/parser.yy	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -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
 		{	
Index: src/SymTab/Mangler.cpp
===================================================================
--- src/SymTab/Mangler.cpp	(revision aacd1e17bd7033c9616fd50316ce5c38575314dc)
+++ src/SymTab/Mangler.cpp	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -290,5 +290,5 @@
 	if ( typeMode ) return;
 	auto funcType = dynamic_cast<const ast::FunctionType *>( type );
-	if ( funcType && !funcType->forall.empty() ) {
+	if ( funcType && (!funcType->forall.empty() || !funcType->assertions.empty()) ) {
 		std::list< std::string > assertionNames;
 		int dcount = 0, fcount = 0, vcount = 0, acount = 0;
Index: tests/.expect/poly-bare-assn.txt
===================================================================
--- tests/.expect/poly-bare-assn.txt	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
+++ tests/.expect/poly-bare-assn.txt	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -0,0 +1,2 @@
+the world is boring
+this is the world; this is fun
Index: tests/poly-bare-assn.cfa
===================================================================
--- tests/poly-bare-assn.cfa	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
+++ tests/poly-bare-assn.cfa	(revision 831b2ecd507a0a1b00a7397e1cba0ef34c37c0c6)
@@ -0,0 +1,125 @@
+// A bare assertion is one that occurs without any here-bound type variables.
+// The test shows that bare assertions can occur on a function or on a type,
+// without introducing any "fake" type variables.
+
+// Related to Trac #185.
+// Present state, the test (in a test.py run) shows a fix of the #185
+// sub-case where there two overloads, already differentiated by other factors,
+// and one of them gets a bare assertion, without being charged a polymorphism
+// cost.  The two "still required" points following do not run under test.py.
+
+// Still required to fix 185: parse bare assertions on traits
+#ifdef TRY_MISSING_SYNTAX
+#define MAYBE_SYNTAX(...) __VA_ARGS__
+#else
+#define MAYBE_SYNTAX(...)
+#endif
+
+// Still required to fix 185: support bare assertions on types (orig 185 repro)
+#ifdef TRY_BROKEN_TYPE
+#define MAYBE_TYPE(...) __VA_ARGS__
+#else
+#define MAYBE_TYPE(...)
+#endif
+
+MAYBE_TYPE (
+    forall ( | {void fun();} ) {
+
+        struct thing {};
+
+        void ?{}( thing & this ) {
+            fun();
+        }
+    }
+)
+
+void greet() {
+    printf("the world is boring\n");
+}
+
+forall ( | {void fun();} )
+void greet() {
+    printf("this is the world; ");
+    fun();
+}
+
+MAYBE_SYNTAX(
+    trait world_is_fun() { void fun(); }
+
+    MAYBE_TYPE(
+        forall ( | world_is_fun() ) {
+
+            struct thing2 {};
+
+            void ?{}( thing2 & this ) {
+                fun();
+            }
+        }
+    )
+
+    void greet2() {
+        printf("the galaxy is boring\n");
+    }
+
+    forall ( | {void fun();} )
+    void greet2() {
+        printf("this is the galaxy; ");
+        fun();
+    }
+)
+
+void greetworld_nofun() {
+    greet();
+}
+
+MAYBE_SYNTAX(
+    void greetgalaxy_nofun() {
+        greet2();
+    }
+)
+
+void fun() {
+    printf("this is fun\n");
+}
+
+void greetworld_withfun() {
+    greet();
+}
+
+MAYBE_SYNTAX(
+    void greetgalaxy_withfun() {
+        greet2();
+    }
+)
+
+MAYBE_TYPE(
+    // A type declared with a bare assertion can be used ("instantiated") without
+    // adding type arguments.  You shouldn't have to provide any type arguments
+    // when you use it because it was decalred with no type parameters.
+    void test_type() {
+        thing x;   (void) x;
+    #ifdef TRY_MISSING_SYNTAX
+        thing2 y;  (void) y;
+    #endif
+    }
+)
+
+// A function overload declared with a bare assertion is called when the
+// assertion is satisfied.  Your cost calculation should not have the asserting
+// overload incur the penalty of a type variable because it was decalred with
+// no type parameters.
+void test_costs() {
+    greetworld_nofun();
+    greetworld_withfun();
+  MAYBE_SYNTAX(
+    greetgalaxy_nofun();
+    greetgalaxy_withfun();
+  )
+}
+
+int main() {
+  MAYBE_TYPE(
+    test_type();
+  )
+    test_costs();
+}
