diff -urp vala-0.9.3.orig/codegen/valaccodecontrolflowmodule.vala vala-0.9.3.new/codegen/valaccodecontrolflowmodule.vala
--- vala-0.9.3.orig/codegen/valaccodecontrolflowmodule.vala	2010-06-08 07:40:54.000000000 +0100
+++ vala-0.9.3.new/codegen/valaccodecontrolflowmodule.vala	2010-07-18 17:17:03.571822719 +0100
@@ -46,19 +46,19 @@ public class Vala.CCodeControlFlowModule
 		var temp_var = get_temp_variable (stmt.expression.value_type, stmt.expression.value_type.value_owned, stmt, false);
 		stmt.expression.temp_vars.insert (0, temp_var);
 
-		var ctemp = get_variable_cexpression (temp_var.name);
-		var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
+		var cswitchvar = get_variable_cexpression (temp_var.name);
+		var cinit = new CCodeAssignment (cswitchvar, (CCodeExpression) stmt.expression.ccodenode);
 		var czero = new CCodeConstant ("0");
 
 		var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
-		free_call.add_argument (ctemp);
+		free_call.add_argument (cswitchvar);
 
 		var cswitchblock = new CCodeFragment ();
 		stmt.ccodenode = cswitchblock;
 
-		var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
+		var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), cswitchvar);
 		var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-		cquark.add_argument (ctemp);
+		cquark.add_argument (cswitchvar);
 
 		var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
 
@@ -75,7 +75,9 @@ public class Vala.CCodeControlFlowModule
 			foreach (SwitchLabel label in section.get_labels ()) {
 				var cexpr = (CCodeExpression) label.expression.ccodenode;
 
-				if (is_constant_ccode_expression (cexpr)) {
+				if (is_constant_ccode_expression (cexpr) &&
+					label.expression.value_type.data_type != regex_type.data_type)
+				{
 					var cname = "%s_label%d".printf (temp_var.name, label_count++);
 					var cdecl = new CCodeDeclaration (gquark_type.get_cname ());
 
@@ -89,7 +91,7 @@ public class Vala.CCodeControlFlowModule
 
 		cswitchblock.append (new CCodeExpressionStatement (cinit));
 
-		ctemp = get_variable_cexpression (temp_var.name);
+		var ctemp = get_variable_cexpression (temp_var.name);
 		cinit = new CCodeAssignment (ctemp, ccond);
 
 		cswitchblock.append (new CCodeExpressionStatement (cinit));
@@ -103,7 +105,7 @@ public class Vala.CCodeControlFlowModule
 		List<Statement> default_statements = null;
 		label_count = 0;
 
-		// generate nested if statements		
+		// generate nested if statements
 		CCodeStatement ctopstmt = null;
 		CCodeIfStatement coldif = null;
 
@@ -113,26 +115,39 @@ public class Vala.CCodeControlFlowModule
 				continue;
 			}
 
-			CCodeBinaryExpression cor = null;
+			CCodeExpression cor = null;
 			foreach (SwitchLabel label in section.get_labels ()) {
 				var cexpr = (CCodeExpression) label.expression.ccodenode;
 
-				if (is_constant_ccode_expression (cexpr)) {
-					var cname = new CCodeIdentifier ("%s_label%d".printf (temp_var.name, label_count++));
-					var ccondition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
-					var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
-					cinit = new CCodeAssignment (cname, ccall);
-
-					ccall.add_argument (cexpr);
+				CCodeExpression ccmp = null;
 
-					cexpr = new CCodeConditionalExpression (ccondition, cname, cinit);
-				} else {
-					var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-					ccall.add_argument (cexpr);
-					cexpr = ccall;
+				if (label.expression.value_type.data_type == regex_type.data_type) {
+					var cmatch = new CCodeFunctionCall (new CCodeIdentifier ("g_regex_match"));
+					cmatch.add_argument (cexpr);
+					cmatch.add_argument (cswitchvar);
+					cmatch.add_argument (new CCodeConstant ("0"));
+					cmatch.add_argument (new CCodeConstant ("NULL"));
+					var cnotnull = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeConstant ("NULL"), cswitchvar);
+					ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.AND, cnotnull, cmatch);
 				}
+				else {
+					if (is_constant_ccode_expression (cexpr)) {
+						var cname = new CCodeIdentifier ("%s_label%d".printf (temp_var.name, label_count++));
+						var ccondition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
+						var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
+						cinit = new CCodeAssignment (cname, ccall);
+
+						ccall.add_argument (cexpr);
 
-				var ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
+						cexpr = new CCodeConditionalExpression (ccondition, cname, cinit);
+					} else {
+						var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
+						ccall.add_argument (cexpr);
+						cexpr = ccall;
+					}
+
+					ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
+				}
 
 				if (cor == null) {
 					cor = ccmp;
diff -urp vala-0.9.3.orig/vala/valageniescanner.vala vala-0.9.3.new/vala/valageniescanner.vala
--- vala-0.9.3.orig/vala/valageniescanner.vala	2010-06-08 07:40:54.000000000 +0100
+++ vala-0.9.3.new/vala/valageniescanner.vala	2010-07-18 16:59:43.388880612 +0100
@@ -1214,6 +1214,7 @@ public class Vala.Genie.Scanner {
 				case TokenType.OPEN_PARENS:
 				case TokenType.PLUS:
 				case TokenType.RETURN:
+				case TokenType.WHEN:
 					type = TokenType.OPEN_REGEX_LITERAL;
 					state_stack += State.REGEX_LITERAL;
 					current++;
diff -urp vala-0.9.3.orig/vala/valascanner.vala vala-0.9.3.new/vala/valascanner.vala
--- vala-0.9.3.orig/vala/valascanner.vala	2010-06-30 19:13:09.000000000 +0100
+++ vala-0.9.3.new/vala/valascanner.vala	2010-07-18 16:59:43.388880612 +0100
@@ -1037,6 +1037,7 @@ public class Vala.Scanner {
 				case TokenType.OPEN_PARENS:
 				case TokenType.PLUS:
 				case TokenType.RETURN:
+				case TokenType.CASE:
 					type = TokenType.OPEN_REGEX_LITERAL;
 					state_stack += State.REGEX_LITERAL;
 					current++;
diff -urp vala-0.9.3.orig/vala/valaswitchlabel.vala vala-0.9.3.new/vala/valaswitchlabel.vala
--- vala-0.9.3.orig/vala/valaswitchlabel.vala	2009-09-04 06:35:01.000000000 +0100
+++ vala-0.9.3.new/vala/valaswitchlabel.vala	2010-07-18 17:02:53.839754870 +0100
@@ -77,7 +77,11 @@ public class Vala.SwitchLabel : CodeNode
 				Report.error (expression.source_reference, "Expression must be constant");
 				return false;
 			}
-			if (!expression.value_type.compatible (switch_statement.expression.value_type)) {
+
+			if (!(expression.value_type.compatible (switch_statement.expression.value_type) ||
+				(expression.value_type.data_type == analyzer.regex_type.data_type &&
+				 switch_statement.expression.value_type.data_type == analyzer.string_type.data_type)))
+			{
 				error = true;
 				Report.error (expression.source_reference, "Cannot convert from `%s' to `%s'".printf (expression.value_type.to_string (), switch_statement.expression.value_type.to_string ()));
 				return false;
diff -urp vala-0.9.3.orig/vala/valaswitchstatement.vala vala-0.9.3.new/vala/valaswitchstatement.vala
--- vala-0.9.3.orig/vala/valaswitchstatement.vala	2010-06-08 07:40:54.000000000 +0100
+++ vala-0.9.3.new/vala/valaswitchstatement.vala	2010-07-18 16:59:43.388880612 +0100
@@ -117,6 +117,7 @@ public class Vala.SwitchStatement : Code
 		expression.target_type = expression.value_type.copy ();
 
 		var labelset = new HashSet<string> (str_hash, str_equal);
+		var labelregexset = new HashSet<string> (str_hash, str_equal);
 		foreach (SwitchSection section in sections) {
 			section.check (analyzer);
 
@@ -124,13 +125,19 @@ public class Vala.SwitchStatement : Code
 			// FIXME: make it work for all constant expressions
 			foreach (SwitchLabel label in section.get_labels ()) {
 				string? value = null;
+				HashSet<string>? set = null;
 				if (label.expression is StringLiteral) {
 					value = ((StringLiteral)label.expression).eval ();
+					set = labelset;
+				} else if (label.expression is RegexLiteral) {
+					value = ((RegexLiteral)label.expression).to_string ();
+					set = labelregexset;
 				} else if (label.expression is Literal) {
 					value = ((Literal)label.expression).to_string ();
+					set = labelset;
 				}
 
-				if (value != null && !labelset.add (value)) {
+				if (value != null && !set.add (value)) {
 					error = true;
 					Report.error (label.expression.source_reference, "Switch statement already contains this label");
 				}
