diff options
-rw-r--r-- | src/hir_typeck/common.hpp | 30 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 20 | ||||
-rw-r--r-- | src/hir_typeck/helpers.hpp | 30 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 2 |
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 ); |