Index: src/tests/polymorphism.c
===================================================================
--- src/tests/polymorphism.c	(revision 1ba5803c90674cf77489dd4409a2afd3b782551e)
+++ src/tests/polymorphism.c	(revision 3787dc10d1993f80425a349e04b19fa8316d8a40)
@@ -14,4 +14,7 @@
 //
 
+#include <assert.h>
+#include <inttypes.h>
+
 forall(otype T)
 T f(T x, T y) {
@@ -24,15 +27,90 @@
 }
 
+forall( otype T, otype U )
+size_t struct_size( T i, U j ) {
+	struct S { T i; U j; };
+	return sizeof(S);
+}
+
+forall( otype T, otype U )
+size_t union_size( T i, U j ) {
+	union B { T i; U j; };
+	return sizeof(B);
+}
+
+// perform some simple operations on aggregates of T and U
+forall( otype T | { void print(T); int ?==?(T, T); }, otype U | { void print(U); U ?=?(U&, zero_t); } )
+U foo(T i, U j) {
+	struct S { T i; U j; };
+	union B { T i; U j; };
+
+	S s;
+	s.i = i;
+	assert(s.i == i);
+
+	B b;
+	b.j = 0;
+	b.i = s.i;
+	return b.j;
+}
+
 int main() {
-	// ensure that x is not changed by the invocation of a polymorphic function
-	int x = 123;
-	int y = 456;
-	int z = f(x, y);
-	printf("%d %d %d\n", x, y, z);
+	{
+		// ensure that x is not changed by the invocation of a polymorphic function
+		int x = 123;
+		int y = 456;
+		int z = f(x, y);
+		printf("%d %d %d\n", x, y, z);
+	}
 
-	// explicitly specialize function
-	int (*f)(int) = ident;
-	((int(*)(int))ident);
-	printf("%d %d\n", f(5), ((int(*)(int))ident)(5));
+	{
+		// explicitly specialize function
+		int (*f)(int) = ident;
+		((int(*)(int))ident);
+		printf("%d %d\n", f(5), ((int(*)(int))ident)(5));
+	}
+
+	{
+		// test aggregates with polymorphic members
+		typedef uint32_t x_type;
+		typedef uint64_t y_type;
+
+		x_type x = 3;
+		y_type y = 3;
+
+		struct S {
+			x_type f1;
+			y_type f2;
+		};
+		union U {
+			x_type f1;
+			y_type f2;
+		};
+		// ensure that the size of aggregates with polymorphic members
+		// matches the size of the aggregates in a monomorphic context
+		assert( struct_size(x, y) == sizeof(S) );
+		assert( union_size(x, y) == sizeof(U) );
+
+		y_type ?=?(y_type & this, zero_t) {
+			this = (int)0;
+			return this;
+		}
+
+		void print(x_type x) {
+			printf("%"PRIu32"\n", x);
+		}
+
+		void print(y_type y) {
+			printf("%"PRIu64"\n", y);
+		}
+
+		y_type ret = foo(x, y);
+
+		// duplicate logic from inside of foo to ensure the same results
+		U u;
+		u.f2 = 0;
+		u.f1 = x;
+		assert(ret == u.f2);
+	}
 }
 
