summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir/hir.cpp6
-rw-r--r--src/hir/type.hpp3
-rw-r--r--src/hir_typeck/expr.cpp7
-rw-r--r--src/hir_typeck/expr.hpp2
-rw-r--r--src/hir_typeck/expr_context.cpp19
5 files changed, 33 insertions, 4 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp
index 818b7b28..1eb4609a 100644
--- a/src/hir/hir.cpp
+++ b/src/hir/hir.cpp
@@ -170,6 +170,9 @@ const ::HIR::SimplePath& ::HIR::Crate::get_lang_item_path(const Span& sp, const
const ::HIR::TypeItem& ::HIR::Crate::get_typeitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const
{
+ if( path.m_components.size() == 0) {
+ BUG(sp, "get_typeitem_by_path received invalid path");
+ }
if( path.m_crate_name != "" )
TODO(sp, "::HIR::Crate::get_typeitem_by_path in extern crate");
@@ -229,6 +232,9 @@ const ::HIR::Enum& ::HIR::Crate::get_enum_by_path(const Span& sp, const ::HIR::S
const ::HIR::ValueItem& ::HIR::Crate::get_valitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const
{
+ if( path.m_components.size() == 0) {
+ BUG(sp, "get_valitem_by_path received invalid path");
+ }
if( path.m_crate_name != "" )
TODO(sp, "::HIR::Crate::get_valitem_by_path in extern crate");
diff --git a/src/hir/type.hpp b/src/hir/type.hpp
index 6dd02804..e5ccf0ce 100644
--- a/src/hir/type.hpp
+++ b/src/hir/type.hpp
@@ -170,6 +170,9 @@ public:
static TypeRef new_pointer(BorrowType bt, TypeRef inner) {
return TypeRef(Data::make_Pointer({bt, box$(mv$(inner))}));
}
+ static TypeRef new_slice(TypeRef inner) {
+ return TypeRef(Data::make_Slice({box$(mv$(inner))}));
+ }
static TypeRef new_array(TypeRef inner, unsigned int size) {
assert(size != ~0u);
return TypeRef(Data::make_Array({box$(mv$(inner)), ::HIR::ExprPtr(), size}));
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index 4251f0d4..269d0850 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -1365,7 +1365,7 @@ namespace typeck {
if( node.m_method_path.m_data.is_Generic() && node.m_method_path.m_data.as_Generic().m_path.m_components.size() == 0 )
{
const auto& ty = this->context.get_type(node.m_value->m_res_type);
- DEBUG("ty = " << ty);
+ DEBUG("(CallMethod) ty = " << ty);
// Using autoderef, locate this method on the type
::HIR::Path fcn_path { ::HIR::SimplePath() };
unsigned int deref_count = this->context.autoderef_find_method(node.span(), ty, node.m_method, fcn_path);
@@ -1394,6 +1394,11 @@ namespace typeck {
deref_count -= 1;
}
}
+ else
+ {
+ // Return early, don't know enough yet
+ return ;
+ }
}
assert(node_ptr.get() == &node);
diff --git a/src/hir_typeck/expr.hpp b/src/hir_typeck/expr.hpp
index adf60c67..83469264 100644
--- a/src/hir_typeck/expr.hpp
+++ b/src/hir_typeck/expr.hpp
@@ -125,7 +125,7 @@ public:
bool iterate_bounds( ::std::function<bool(const ::HIR::GenericBound&)> cb) const;
/// Searches for a trait impl that matches the provided trait name and type
- bool find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, ::std::function<bool(const ::HIR::PathParams&)> callback);
+ bool find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, ::std::function<bool(const ::HIR::PathParams&)> callback) const;
/// Locate a named trait in the provied trait (either itself or as a parent trait)
bool find_named_trait_in_trait(const Span& sp, const ::HIR::SimplePath& des, const ::HIR::Trait& trait_ptr, const ::HIR::PathParams& pp, ::std::function<bool(const ::HIR::PathParams&)> callback) const;
/// Search for a trait implementation in current bounds
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 5e982342..13e52674 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -995,7 +995,7 @@ bool typeck::TypecheckContext::iterate_bounds( ::std::function<bool(const ::HIR:
}
return false;
}
-bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, ::std::function<bool(const ::HIR::PathParams&)> callback)
+bool typeck::TypecheckContext::find_trait_impls(const ::HIR::SimplePath& trait, const ::HIR::TypeRef& type, ::std::function<bool(const ::HIR::PathParams&)> callback) const
{
Span sp = Span();
TRACE_FUNCTION_F("trait = " << trait << ", type = " << type);
@@ -1392,6 +1392,7 @@ bool typeck::TypecheckContext::trait_contains_method(const Span& sp, const ::HIR
unsigned int typeck::TypecheckContext::autoderef_find_method(const Span& sp, const ::HIR::TypeRef& top_ty, const ::std::string& method_name, /* Out -> */::HIR::Path& fcn_path) const
{
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->get_type(top_ty).m_data, Borrow, e,
current_ty = &*e.inner;
@@ -1411,11 +1412,25 @@ unsigned int typeck::TypecheckContext::autoderef_find_method(const Span& sp, con
// 3. Dereference and try again
deref_count += 1;
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Borrow, e,
+ DEBUG("Deref " << ty << " into " << *e.inner);
current_ty = &*e.inner;
)
+ else TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,
+ DEBUG("Deref " << ty << " into [" << *e.inner << "]");
+ tmp_type = ::HIR::TypeRef::new_slice( e.inner->clone() );
+ current_ty = &tmp_type;
+ )
else {
// TODO: Search for a Deref impl
- current_ty = nullptr;
+ bool succ = this->find_trait_impls(this->m_crate.get_lang_item_path(sp, "deref"), ty, [&](const auto& args) {
+ return true;
+ });
+ if( succ ) {
+ TODO(sp, "Found a Deref impl for " << ty << ", use the output of it");
+ }
+ else {
+ current_ty = nullptr;
+ }
}
} while( current_ty );