diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala
index 53b84c6..d2e4164 100644
--- a/vala/valaconstant.vala
+++ b/vala/valaconstant.vala
@@ -78,7 +78,9 @@ public class Vala.Constant : Symbol, Lockable {
 	}
 
 	public override void accept_children (CodeVisitor visitor) {
+		if (type_reference != null) {
 		type_reference.accept (visitor);
+		}
 
 		if (value != null) {
 			value.accept (visitor);
@@ -123,26 +125,69 @@ public class Vala.Constant : Symbol, Lockable {
 			context.analyzer.current_symbol = this;
 		}
 
-		type_reference.check (context);
+		if (!external) {
+			if (value == null) {
+				error = true;
+				Report.error (source_reference, "A const field requires a value to be provided");
+				return false;
+			}
 
-		if (!check_const_type (type_reference, context)) {
+			value.target_type = type_reference;
+
+			if (!value.check (context)) {
 			error = true;
-			Report.error (source_reference, "`%s' not supported as type for constants".printf (type_reference.to_string ()));
 			return false;
 		}
 
-		if (!external) {
+			if (type_reference == null) {
+				/* var type */
+
 			if (value == null) {
 				error = true;
-				Report.error (source_reference, "A const field requires a value to be provided");
-			} else {
+					Report.error (source_reference, "var declaration not allowed without initializer");
+					return false;
+				}
+				if (value.value_type == null) {
+					error = true;
+					Report.error (source_reference, "var declaration not allowed with non-typed initializer");
+					return false;
+				}
+				if (value.value_type is FieldPrototype) {
+					error = true;
+					Report.error (value.source_reference, "Access to instance member `%s' denied".printf (value.symbol_reference.get_full_name ()));
+					return false;
+				}
+
+				type_reference = value.value_type.copy ();
+				type_reference.value_owned = false;
+				type_reference.floating_reference = false;
+
 				value.target_type = type_reference;
+			}
 
-				if (!value.check (context)) {
+		} else {
+			if (value != null) {
+				error = true;
+				Report.error (source_reference, "External constants cannot use values");
+				return false;
+			}
+
+			if (type_reference == null) {
 					error = true;
+				Report.error (source_reference, "A const field requires a value to be provided");
 					return false;
 				}
+		}
+
+		type_reference.check (context);
 
+		if (!check_const_type (type_reference, context)) {
+			error = true;
+			Report.error (source_reference, "`%s' not supported as type for constants".printf (type_reference.to_string ()));
+			return false;
+		}
+
+		if (!external) {
 				if (!value.value_type.compatible (type_reference)) {
 					error = true;
 					Report.error (source_reference, "Cannot convert from `%s' to `%s'".printf (value.value_type.to_string (), type_reference.to_string ()));
@@ -170,12 +215,6 @@ public class Vala.Constant : Symbol, Lockable {
 					return false;
 				}
 			}
-		} else {
-			if (value != null) {
-				error = true;
-				Report.error (source_reference, "External constants cannot use values");
-			}
-		}
 
 		if (!external_package && !hides && get_hidden_member () != null) {
 			Report.warning (source_reference, "%s hides inherited constant `%s'. Use the `new' keyword if hiding was intentional".printf (get_full_name (), get_hidden_member ().get_full_name ()));
diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala
index 4fd8daf..1077065 100644
--- a/vala/valalocalvariable.vala
+++ b/vala/valalocalvariable.vala
@@ -37,6 +37,8 @@ public class Vala.LocalVariable : Variable {
 
 	public bool no_init { get; set; }
 
+	public bool unowned_var_type { get; set; }
+
 	/**
 	 * Creates a new local variable.
 	 *
@@ -119,7 +121,7 @@ public class Vala.LocalVariable : Variable {
 			}
 
 			variable_type = initializer.value_type.copy ();
-			variable_type.value_owned = true;
+			variable_type.value_owned = !unowned_var_type;
 			variable_type.floating_reference = false;
 
 			initializer.target_type = variable_type;
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 76ea0b9..33807df 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1758,15 +1758,26 @@ public class Vala.Parser : CodeVisitor {
 
 	void parse_local_variable_declarations (Block block) throws ParseError {
 		DataType variable_type;
+
+		var begin = get_location ();
+
+		bool value_owned = true;
+
+		if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
+			variable_type = null;
+			value_owned = false;
+		} else {
+			rollback (begin);
 		if (accept (TokenType.VAR)) {
 			variable_type = null;
 		} else {
 			variable_type = parse_type (true, true);
 		}
+		}
 		do {
-			if (variable_type == null && accept (TokenType.OPEN_PARENS)) {
+			if (variable_type == null && value_owned && accept (TokenType.OPEN_PARENS)) {
 				// tuple
-				var begin = get_location ();
+				begin = get_location ();
 
 				string[] identifiers = {};
 				do {
@@ -1795,6 +1806,7 @@ public class Vala.Parser : CodeVisitor {
 				type_copy = variable_type.copy ();
 			}
 			var local = parse_local_variable (type_copy);
+			local.unowned_var_type = !value_owned;
 			block.add_statement (new DeclarationStatement (local, local.source_reference));
 		} while (accept (TokenType.COMMA));
 		expect (TokenType.SEMICOLON);
@@ -1815,9 +1827,17 @@ public class Vala.Parser : CodeVisitor {
 
 	void parse_local_constant_declarations (Block block) throws ParseError {
 		expect (TokenType.CONST);
-		var constant_type = parse_type (false, false);
+
+		DataType constant_type;
+
+		if (accept (TokenType.VAR)) {
+			constant_type = null;
+		} else {
+			constant_type = parse_type (false, false);
+		}
+
 		do {
-			DataType type_copy = constant_type.copy ();
+			DataType type_copy = constant_type != null ? constant_type.copy () : null;
 			var local = parse_local_constant (type_copy);
 			block.add_statement (new DeclarationStatement (local, local.source_reference));
 			block.add_local_constant (local);
@@ -1826,7 +1846,7 @@ public class Vala.Parser : CodeVisitor {
 		expect (TokenType.SEMICOLON);
 	}
 
-	Constant parse_local_constant (DataType constant_type) throws ParseError {
+	Constant parse_local_constant (DataType? constant_type) throws ParseError {
 		var begin = get_location ();
 		string id = parse_identifier ();
 
