Index: tests/collections/.expect/string-operator-ERR15.txt
===================================================================
--- tests/collections/.expect/string-operator-ERR15.txt	(revision d1757672712417b16598464c053288dcfff22d7e)
+++ tests/collections/.expect/string-operator-ERR15.txt	(revision d1757672712417b16598464c053288dcfff22d7e)
@@ -0,0 +1,141 @@
+collections/string-operator.cfa:317:1 error: Cannot choose between 2 alternatives for expression
+Applying untyped:
+  Name: printf
+...to:
+  Constant Expression ("%c\n": array of char with dimension of Constant Expression (4: unsigned long int)
+  ... with resolved type:
+    unsigned long int)
+  ... with resolved type:
+    array of char with dimension of Constant Expression (4: unsigned long int)
+    ... with resolved type:
+      unsigned long int
+  Applying untyped:
+    Name: ?+?
+  ...to:
+    Constant Expression ('a': char)
+    ... with resolved type:
+      char
+    Constant Expression ('b': char)
+    ... with resolved type:
+      char
+
+ Alternatives are:
+Cost ( 1, 0, 0, 1, 0, 0, 0, 0 ): Application of
+      Variable Expression: printf: extern function
+      ... with parameters
+        restrict pointer to const char
+        and a variable number of other arguments
+      ... returning
+        signed int
+
+      ... with resolved type:
+        pointer to function
+        ... with parameters
+          restrict pointer to const char
+          and a variable number of other arguments
+        ... returning
+          signed int
+
+      ... to arguments
+      Generated Cast of:
+        Constant Expression ("%c\n": pointer to char)
+        ... with resolved type:
+          pointer to char
+      ... to:
+        restrict pointer to const char
+      ... with resolved type:
+        restrict pointer to const char
+      Application of
+        Variable Expression: ?+?: function
+        ... with parameters
+          char
+          char
+        ... returning
+          char
+
+        ... with resolved type:
+          pointer to function
+          ... with parameters
+            char
+            char
+          ... returning
+            char
+
+        ... to arguments
+        Constant Expression ('a': char)
+        ... with resolved type:
+          char
+        Constant Expression ('b': char)
+        ... with resolved type:
+          char
+
+      ... with resolved type:
+        char
+
+    ... with resolved type:
+      signed int
+  (types:
+    signed int
+  )
+  Environment:
+
+Cost ( 1, 0, 0, 1, 0, 0, 0, 0 ): Application of
+      Variable Expression: printf: extern function
+      ... with parameters
+        restrict pointer to const char
+        and a variable number of other arguments
+      ... returning
+        signed int
+
+      ... with resolved type:
+        pointer to function
+        ... with parameters
+          restrict pointer to const char
+          and a variable number of other arguments
+        ... returning
+          signed int
+
+      ... to arguments
+      Generated Cast of:
+        Constant Expression ("%c\n": pointer to char)
+        ... with resolved type:
+          pointer to char
+      ... to:
+        restrict pointer to const char
+      ... with resolved type:
+        restrict pointer to const char
+      Application of
+        Variable Expression: ?+?: function
+        ... with parameters
+          char
+          char
+        ... returning
+          instance of struct string with body
+
+        ... with resolved type:
+          pointer to function
+          ... with parameters
+            char
+            char
+          ... returning
+            instance of struct string with body
+
+        ... to arguments
+        Constant Expression ('a': char)
+        ... with resolved type:
+          char
+        Constant Expression ('b': char)
+        ... with resolved type:
+          char
+
+      ... with resolved type:
+        instance of struct string with body
+
+    ... with resolved type:
+      signed int
+  (types:
+    signed int
+  )
+  Environment:
+
+
Index: tests/collections/.expect/string-operator.txt
===================================================================
--- tests/collections/.expect/string-operator.txt	(revision d1757672712417b16598464c053288dcfff22d7e)
+++ tests/collections/.expect/string-operator.txt	(revision d1757672712417b16598464c053288dcfff22d7e)
@@ -0,0 +1,100 @@
+------------- Explicit char arithmetic
+Ã
+
+------------- Initialization
+Ã
+ab
+ab
+ab
+
+Ãx
+abx
+abx
+abx
+
+xab
+xab
+xab
+xab
+
+axb
+axb
+axb
+axb
+
+aaa
+bbb
+ÃÃÃ
+cdcdcd
+
+291
+bbb
+ababab
+cdcdcd
+
+------------- Assignment
+Ã
+ab
+ab
+ab
+
+Ã
+abÃ
+ababÃ
+abababÃ
+
+ab
+abab
+ababab
+abababab
+
+ab
+aabb
+aaabbb
+aaaabbbb
+
+aaa
+bbb
+ÃÃÃ
+cdcdcd
+
+291
+bbb
+ababab
+cdcdcd
+
+------------- Bare (sout-direct)
+ab
+ab
+ab
+ab
+
+Ãx
+abx
+abx
+abx
+
+xab
+xab
+xab
+xab
+
+axb
+axb
+axb
+axb
+
+aaa
+bbb
+ÃÃÃ
+cdcdcd
+
+291
+bbb
+ababab
+cdcdcd
+
+------------- Miscellany
+(skip)
+291
+0x2a 0x2d
Index: tests/collections/string-operator.cfa
===================================================================
--- tests/collections/string-operator.cfa	(revision d1757672712417b16598464c053288dcfff22d7e)
+++ tests/collections/string-operator.cfa	(revision d1757672712417b16598464c053288dcfff22d7e)
@@ -0,0 +1,324 @@
+#include <fstream.hfa>
+#include <string.hfa>
+
+// "May Reject" (MR) handling
+// This test traces how several SUT revisions treat a common set of cases.
+// Sometimes the handling is a compiler rejection.
+// When it is, that case has to be skipped from the main run, and run individually to show the rejection.
+// Just because some SUT revision will reject / once rejected, doesn't mean it rejects currently.
+
+// These MR points do reject in the current revision, so they have satellite "-ERR" cases:
+// MR15
+
+// These MR points do not reject in the current revision, so they join the "happy run":
+#define TRY_MR01
+#define TRY_MR02
+#define TRY_MR03
+#define TRY_MR04
+#define TRY_MR05
+#define TRY_MR06
+#define TRY_MR07
+#define TRY_MR08
+#define TRY_MR09
+#define TRY_MR10
+#define TRY_MR11
+#define TRY_MR12
+#define TRY_MR13
+#define TRY_MR14
+#define TRY_MR16
+
+
+#ifdef TRY_MR01
+#define MR01(...) __VA_ARGS__
+#else
+#define MR01(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR02
+#define MR02(...) __VA_ARGS__
+#else
+#define MR02(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR03
+#define MR03(...) __VA_ARGS__
+#else
+#define MR03(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR04
+#define MR04(...) __VA_ARGS__
+#else
+#define MR04(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR05
+#define MR05(...) __VA_ARGS__
+#else
+#define MR05(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR06
+#define MR06(...) __VA_ARGS__
+#else
+#define MR06(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR07
+#define MR07(...) __VA_ARGS__
+#else
+#define MR07(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR08
+#define MR08(...) __VA_ARGS__
+#else
+#define MR08(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR09
+#define MR09(...) __VA_ARGS__
+#else
+#define MR09(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR10
+#define MR10(...) __VA_ARGS__
+#else
+#define MR10(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR11
+#define MR11(...) __VA_ARGS__
+#else
+#define MR11(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR12
+#define MR12(...) __VA_ARGS__
+#else
+#define MR12(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR13
+#define MR13(...) __VA_ARGS__
+#else
+#define MR13(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR14
+#define MR14(...) __VA_ARGS__
+#else
+#define MR14(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR15
+#define MR15(...) __VA_ARGS__
+#else
+#define MR15(...) sout | "(skip)";
+#endif
+
+#ifdef TRY_MR16
+#define MR16(...) __VA_ARGS__
+#else
+#define MR16(...) sout | "(skip)";
+#endif
+
+
+int main() {
+        sout | "------------- Explicit char arithmetic";
+        {
+            char ch;
+            ch = 'a' + 'b';
+            sout | ch;                  // Ã
+            sout | nl;
+        }
+
+
+        sout | "------------- Initialization";
+MR01(  {string s = 'a' + 'b';           // Ãb
+        sout | s;}              )
+       {string s = 'a' + "b";           // ab
+        sout | s;}
+       {string s = "a" + 'b';           // ab
+        sout | s;}
+       {string s = "a" + "b";           // ab
+        sout | s;}
+        sout | nl;                      //
+
+        string s0 = "x";
+
+MR02(  {string s = 'a' + 'b' + s0;      // Ãx
+        sout | s;}              )
+       {string s = 'a' + "b" + s0;      // abx
+        sout | s;}
+       {string s = "a" + 'b' + s0;      // abx
+        sout | s;}
+       {string s = "a" + "b" + s0;      // abx
+        sout | s;}
+        sout | nl;                      //
+
+       {string s = s0 + 'a' + 'b';      // xab
+        sout | s;}
+       {string s = s0 + 'a' + "b";      // xab
+        sout | s;}
+       {string s = s0 + "a" + 'b';      // xab
+        sout | s;}
+       {string s = s0 + "a" + "b";      // xab
+        sout | s;}
+        sout | nl;                      //
+
+       {string s = 'a' + s0 + 'b';      // axb
+        sout | s;}
+       {string s = 'a' + s0 + "b";      // axb
+        sout | s;}
+       {string s = "a" + s0 + 'b';      // axb
+        sout | s;}
+       {string s = "a" + s0 + "b";      // axb
+        sout | s;}
+        sout | nl;                      //
+
+MR03(  {string s = 'a' * 3;             // aaa
+        sout | s;}              )
+       {string s = "b" * 3;             // bbb
+        sout | s;}
+       {string s = ('a' + 'b') * 3;     // ÃÃÃ
+        sout | s;}
+       {string s = ('c' + "d") * 3;     // cdcdcd
+        sout | s;}
+        sout | nl;                      //
+
+MR04(  {string s = 3 * 'a';             // 291
+        sout | s;}              )
+       {string s = 3 * "b";             // bbb
+        sout | s;}
+       {string s = 3 * ('a' + 'b');     // ababab
+        sout | s;}
+       {string s = 3 * ('c' + "d");     // cdcdcd
+        sout | s;}
+        sout | nl;                      //
+
+
+        sout | "------------- Assignment";
+
+        string s;
+
+        s = "";
+MR05(   s = 'a' + 'b';          // Ã
+        sout | s;              )
+        s = 'a' + "b";          // ab
+        sout | s;
+        s = "a" + 'b';          // ab
+        sout | s;
+        s = "a" + "b";          // ab
+        sout | s;
+        sout | nl;              //
+
+        s = "";
+MR06(   s = 'a' + 'b' + s;      // Ã
+        sout | s;              )
+        s = 'a' + "b" + s;      // abÃ
+        sout | s;
+        s = "a" + 'b' + s;      // ababÃ
+        sout | s;
+        s = "a" + "b" + s;      // abababÃ
+        sout | s;
+        sout | nl;              //
+
+        s = "";
+        s = s + 'a' + 'b';      // ab
+        sout | s;
+        s = s + 'a' + "b";      // abab
+        sout | s;
+        s = s + "a" + 'b';      // ababab
+        sout | s;
+        s = s + "a" + "b";      // abababab
+        sout | s;
+        sout | nl;              //
+
+        s = "";
+        s = 'a' + s + 'b';      // ab
+        sout | s;
+        s = 'a' + s + "b";      // aabb
+        sout | s;
+        s = "a" + s + 'b';      // aaabbb
+        sout | s;
+        s = "a" + s + "b";      // aaaabbbb
+        sout | s;
+        sout | nl;              //
+
+        s = "";
+MR07(   s = 'a' * 3;            // aaa
+        sout | s;              )
+        s = "b" * 3;            // bbb
+        sout | s;
+        s = ('a' + 'b') * 3;    // ÃÃÃ
+        sout | s;
+        s = ('c' + "d") * 3;    // cdcdcd
+        sout | s;
+        sout | nl;              //
+
+        s = "";
+MR08(   s = 3 * 'a';            // 291
+        sout | s;              )
+        s = 3 * "b";            // bbb
+        sout | s;
+        s = 3 * ('a' + 'b');    // ababab
+        sout | s;
+        s = 3 * ('c' + "d");    // cdcdcd
+        sout | s;
+        sout | nl;              //
+
+
+        sout | "------------- Bare (sout-direct)";
+
+        s = "x";
+
+MR09(   sout | 'a' + 'b';      )    // ab
+        sout | 'a' + "b";           // ab
+        sout | "a" + 'b';           // ab
+        sout | "a" + "b";           // ab
+        sout | nl;                  //
+
+MR10(   sout | 'a' + 'b' + s;  )    // Ãx
+        sout | 'a' + "b" + s;       // abx
+        sout | "a" + 'b' + s;       // abx
+        sout | "a" + "b" + s;       // abx
+        sout | nl;                  //
+
+        sout | s + 'a' + 'b';       // xab
+        sout | s + 'a' + "b";       // xab
+        sout | s + "a" + 'b';       // xab
+        sout | s + "a" + "b";       // xab
+        sout | nl;                  //
+
+        sout | 'a' + s + 'b';       // axb
+        sout | 'a' + s + "b";       // axb
+        sout | "a" + s + 'b';       // axb
+        sout | "a" + s + "b";       // axb
+        sout | nl;                  //
+
+MR11(   sout | 'a' * 3;          )  // aaa
+        sout | "b" * 3;             // bbb
+MR12(   sout | ('a' + 'b') * 3;  )  // ÃÃÃ
+        sout | ('c' + "d") * 3;     // cdcdcd
+        sout | nl;                  //
+
+MR13(   sout | 3 * 'a';          )  // 291
+        sout | 3 * "b";             // bbb
+MR14(   sout | 3 * ('a' + 'b');  )  // ababab
+        sout | 3 * ('c' + "d");     // cdcdcd
+        sout | nl;                  //
+
+        sout | "------------- Miscellany";
+
+        // random examples that have been discussed
+
+MR15(   printf( "%c\n", 'a' + 'b'); )    // (ambiguous)
+MR16(   printf( "%d\n", 'a' * 3 );  )    // 291
+
+        {   // (picks arithmetic; there is no interpretation of `_ + 3` that's string)
+            char ch = 42;
+            printf( "0x%x 0x%x\n", ch, ch + 3 );  // 0x3 0x6 
+        }
+}
