summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_typeck/common.hpp30
-rw-r--r--src/hir_typeck/helpers.cpp20
-rw-r--r--src/hir_typeck/helpers.hpp30
-rw-r--r--src/hir_typeck/static.hpp2
-rw-r--r--src/mir/from_hir.cpp2
-rw-r--r--src/mir/from_hir_match.cpp2
6 files changed, 54 insertions, 32 deletions
diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp
new file mode 100644
index 00000000..3530b157
--- /dev/null
+++ b/src/hir_typeck/common.hpp
@@ -0,0 +1,30 @@
+/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * hir_typeck/common.hpp
+ * - Typecheck common methods
+ */
+#pragma once
+
+#include "impl_ref.hpp"
+#include <hir/type.hpp>
+
+// TODO/NOTE - This is identical to ::HIR::t_cb_resolve_type
+typedef ::std::function<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> t_cb_generic;
+
+extern bool monomorphise_type_needed(const ::HIR::TypeRef& tpl);
+extern bool monomorphise_pathparams_needed(const ::HIR::PathParams& tpl);
+static inline bool monomorphise_genericpath_needed(const ::HIR::GenericPath& tpl) {
+ return monomorphise_pathparams_needed(tpl.m_params);
+}
+extern bool monomorphise_path_needed(const ::HIR::Path& tpl);
+extern bool monomorphise_traitpath_needed(const ::HIR::TraitPath& tpl);
+extern bool monomorphise_type_needed(const ::HIR::TypeRef& tpl);
+extern ::HIR::PathParams monomorphise_path_params_with(const Span& sp, const ::HIR::PathParams& tpl, t_cb_generic callback, bool allow_infer);
+extern ::HIR::GenericPath monomorphise_genericpath_with(const Span& sp, const ::HIR::GenericPath& tpl, t_cb_generic callback, bool allow_infer);
+extern ::HIR::TraitPath monomorphise_traitpath_with(const Span& sp, const ::HIR::TraitPath& tpl, t_cb_generic callback, bool allow_infer);
+extern ::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer=true);
+extern ::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl);
+
+extern void check_type_class_primitive(const Span& sp, const ::HIR::TypeRef& type, ::HIR::InferClass ic, ::HIR::CoreType ct);
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index c5d12d7d..a1d78194 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -2311,8 +2311,13 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
{
unsigned int deref_count = 0;
::HIR::TypeRef tmp_type; // Temporary type used for handling Deref
- const auto* current_ty = &top_ty;
- TU_IFLET(::HIR::TypeRef::Data, this->m_ivars.get_type(top_ty).m_data, Borrow, e,
+ const auto& top_ty_r = this->m_ivars.get_type(top_ty);
+ const auto* current_ty = &top_ty_r;
+
+ bool unconditional_allow_move = (!top_ty_r.m_data.is_Borrow() || top_ty_r.m_data.as_Borrow().type == ::HIR::BorrowType::Owned);
+
+ // If the top is a borrow, search dereferenced first.
+ TU_IFLET(::HIR::TypeRef::Data, top_ty_r.m_data, Borrow, e,
current_ty = &*e.inner;
deref_count += 1;
)
@@ -2326,7 +2331,7 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
return ~0u;
}
- if( this->find_method(sp, traits, ty, method_name, fcn_path) ) {
+ if( this->find_method(sp, traits, ty, method_name, unconditional_allow_move || (deref_count == 0), fcn_path) ) {
return deref_count;
}
@@ -2335,10 +2340,11 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
current_ty = this->autoderef(sp, ty, tmp_type);
} while( current_ty );
- TU_IFLET(::HIR::TypeRef::Data, this->m_ivars.get_type(top_ty).m_data, Borrow, e,
- const auto& ty = this->m_ivars.get_type(top_ty);
+ // If the top is a borrow, search for methods on &/&mut
+ TU_IFLET(::HIR::TypeRef::Data, top_ty_r.m_data, Borrow, e,
+ const auto& ty = top_ty_r;
- if( find_method(sp, traits, ty, method_name, fcn_path) ) {
+ if( find_method(sp, traits, ty, method_name, true, fcn_path) ) {
return 0;
}
)
@@ -2355,7 +2361,7 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
}
}
-bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& traits, const ::HIR::TypeRef& ty, const ::std::string& method_name, /* Out -> */::HIR::Path& fcn_path) const
+bool TraitResolution::find_method(const Span& sp, const HIR::t_trait_list& traits, const ::HIR::TypeRef& ty, const ::std::string& method_name, bool allow_move, /* Out -> */::HIR::Path& fcn_path) const
{
TRACE_FUNCTION_F("ty=" << ty << ", name=" << method_name);
// 1. Search generic bounds for a match
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index 70813635..45a368b1 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -1,30 +1,16 @@
/*
+ * MRustC - Rust Compiler
+ * - By John Hodge (Mutabah/thePowersGang)
+ *
+ * hir_typeck/helpers.hpp
+ * - Typecheck dynamic checker
*/
#pragma once
-#include <hir/type.hpp>
#include <hir/hir.hpp>
-#include <hir/expr.hpp>
-#include "impl_ref.hpp"
+#include <hir/expr.hpp> // t_trait_list
-// TODO/NOTE - This is identical to ::HIR::t_cb_resolve_type
-typedef ::std::function<const ::HIR::TypeRef&(const ::HIR::TypeRef&)> t_cb_generic;
-
-extern bool monomorphise_type_needed(const ::HIR::TypeRef& tpl);
-extern bool monomorphise_pathparams_needed(const ::HIR::PathParams& tpl);
-static inline bool monomorphise_genericpath_needed(const ::HIR::GenericPath& tpl) {
- return monomorphise_pathparams_needed(tpl.m_params);
-}
-extern bool monomorphise_path_needed(const ::HIR::Path& tpl);
-extern bool monomorphise_traitpath_needed(const ::HIR::TraitPath& tpl);
-extern bool monomorphise_type_needed(const ::HIR::TypeRef& tpl);
-extern ::HIR::PathParams monomorphise_path_params_with(const Span& sp, const ::HIR::PathParams& tpl, t_cb_generic callback, bool allow_infer);
-extern ::HIR::GenericPath monomorphise_genericpath_with(const Span& sp, const ::HIR::GenericPath& tpl, t_cb_generic callback, bool allow_infer);
-extern ::HIR::TraitPath monomorphise_traitpath_with(const Span& sp, const ::HIR::TraitPath& tpl, t_cb_generic callback, bool allow_infer);
-extern ::HIR::TypeRef monomorphise_type_with(const Span& sp, const ::HIR::TypeRef& tpl, t_cb_generic callback, bool allow_infer=true);
-extern ::HIR::TypeRef monomorphise_type(const Span& sp, const ::HIR::GenericParams& params_def, const ::HIR::PathParams& params, const ::HIR::TypeRef& tpl);
-
-extern void check_type_class_primitive(const Span& sp, const ::HIR::TypeRef& type, ::HIR::InferClass ic, ::HIR::CoreType ct);
+#include "common.hpp"
class HMTypeInferrence
{
@@ -229,7 +215,7 @@ public:
const ::HIR::TypeRef* autoderef(const Span& sp, const ::HIR::TypeRef& ty, ::HIR::TypeRef& tmp_type) const;
bool find_field(const Span& sp, const ::HIR::TypeRef& ty, const ::std::string& name, /* Out -> */::HIR::TypeRef& field_type) const;
- bool find_method(const Span& sp, const HIR::t_trait_list& traits, const ::HIR::TypeRef& ty, const ::std::string& method_name, /* Out -> */::HIR::Path& fcn_path) const;
+ bool find_method(const Span& sp, const HIR::t_trait_list& traits, const ::HIR::TypeRef& ty, const ::std::string& method_name, bool allow_move, /* Out -> */::HIR::Path& fcn_path) const;
/// Locates a named method in a trait, and returns the path of the trait that contains it (with fixed parameters)
bool trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const;
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index 31ca1870..928367f4 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -8,7 +8,7 @@
#pragma once
#include <hir/hir.hpp>
-#include "helpers.hpp"
+#include "common.hpp"
#include "impl_ref.hpp"
class StaticTraitResolve
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 2a5c50c2..4477d0e6 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -12,7 +12,7 @@
#include <hir/expr.hpp>
#include <hir/hir.hpp>
#include <hir/visitor.hpp>
-#include <hir_typeck/helpers.hpp> // monomorphise_type
+#include <hir_typeck/common.hpp> // monomorphise_type
#include "main_bindings.hpp"
#include "from_hir.hpp"
diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp
index 66b3f685..78691dcc 100644
--- a/src/mir/from_hir_match.cpp
+++ b/src/mir/from_hir_match.cpp
@@ -6,7 +6,7 @@
* - Conversion of `match` blocks into MIR
*/
#include "from_hir.hpp"
-#include <hir_typeck/helpers.hpp> // monomorphise_type
+#include <hir_typeck/common.hpp> // monomorphise_type
#include <algorithm>
void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNode_Match& node, ::MIR::LValue match_val );