diff --git a/sol/call.hpp b/sol/call.hpp
index cbe4e2cf..db27c1d4 100644
--- a/sol/call.hpp
+++ b/sol/call.hpp
@@ -47,7 +47,7 @@ namespace sol {
 		}
 
 		template <typename T, typename List>
-		struct void_call;
+		struct void_call : void_call<T, meta::function_args_t<List>> {};
 
 		template <typename T, typename... Args>
 		struct void_call<T, types<Args...>> {
@@ -345,12 +345,12 @@ namespace sol {
 
 			template <typename V>
 			static int call(lua_State* L, V&& f) {
-				return call_const(std::is_const<typename traits_type::return_type>(), L, f);
+				return call_const(std::is_const<typename traits_type::return_type>(), L, std::forward<V>(f));
 			}
 
 			template <typename V>
 			static int call(lua_State* L, V&& f, object_type& o) {
-				return call_const(std::is_const<typename traits_type::return_type>(), L, f, o);
+				return call_const(std::is_const<typename traits_type::return_type>(), L, std::forward<V>(f), o);
 			}
 		};
 
@@ -364,7 +364,7 @@ namespace sol {
 			static int call(lua_State* L, V&& f, object_type& o) {
 				typedef typename wrap::returns_list returns_list;
 				typedef typename wrap::caller caller;
-				return stack::call_into_lua<checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
+				return stack::call_into_lua<checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<V>(f), o);
 			}
 
 			template <typename V>
diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp
index 423869df..02cd8586 100644
--- a/sol/usertype_metatable.hpp
+++ b/sol/usertype_metatable.hpp
@@ -174,15 +174,24 @@ namespace sol {
 		template <typename T, bool is_simple>
 		inline int metatable_newindex(lua_State* L) {
 			int isnum = 0;
-			lua_Integer magic = lua_tointegerx(L, lua_upvalueindex(4), &isnum);
+			lua_Integer magic = lua_tointegerx(L, upvalue_index(4), &isnum);
 			if (isnum != 0 && magic == toplevel_magic) {
-				bool mustindex = lua_isboolean(L, lua_upvalueindex(5)) != 0 && (lua_toboolean(L, lua_upvalueindex(5)) != 0);
+				bool mustindex = lua_isboolean(L, upvalue_index(5)) != 0 && (lua_toboolean(L, upvalue_index(5)) != 0);
 				if (!is_simple && mustindex) {
-					mapping_t& mapping = stack::get<light<mapping_t>>(L, lua_upvalueindex(3));
-					std::vector<object>& runtime = stack::get<light<std::vector<object>>>(L, lua_upvalueindex(2));
+					mapping_t& mapping = stack::get<light<mapping_t>>(L, upvalue_index(3));
+					std::vector<object>& runtime = stack::get<light<std::vector<object>>>(L, upvalue_index(2));
 					int target = static_cast<int>(runtime.size());
-					runtime.emplace_back(L, 3);
-					mapping.emplace_hint(mapping.cend(), stack::get<std::string>(L, 2), call_information(&runtime_object_call, &runtime_object_call, target));
+					std::string accessor = stack::get<std::string>(L, 2);
+					auto preexistingit = mapping.find(accessor);
+					if (preexistingit == mapping.cend()) {
+						target = preexistingit->second.runtime_target;
+						runtime[target] = sol::object(L, 3);
+						preexistingit->second = call_information(&runtime_object_call, &runtime_object_call, target);
+					}
+					else {
+						runtime.emplace_back(L, 3);
+						mapping.emplace_hint(mapping.cend(), accessor, call_information(&runtime_object_call, &runtime_object_call, target));
+					}
 				}
 				for (std::size_t i = 0; i < 4; lua_pop(L, 1), ++i) {
 					const char* metakey = nullptr;
diff --git a/test_usertypes.cpp b/test_usertypes.cpp
index d2c12d4e..22689110 100644
--- a/test_usertypes.cpp
+++ b/test_usertypes.cpp
@@ -715,7 +715,6 @@ TEST_CASE("usertype/overloading", "Check if overloading works properly for usert
 	REQUIRE((lua["a"] == 1));
 	REQUIRE((lua["b"] == 3.5));
 	REQUIRE((lua["c"] == bark_58));
-
 	REQUIRE_THROWS(lua.script("r:func(1,2,'meow')"));
 }