diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-11 12:05:30 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-11 12:05:30 +0800 |
commit | 5585040f36b6f8ffd6c0c44689525ce29ccb74d9 (patch) | |
tree | 9c5566dcb60260643293965cd216c505b4423ead /src | |
parent | 556cf732e28ae68185f778a4c5c63d0d2bec032a (diff) | |
download | mrust-5585040f36b6f8ffd6c0c44689525ce29ccb74d9.tar.gz |
HIR Typecheck - autoderef arrays to slices, don't check method if unknown
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/hir.cpp | 6 | ||||
-rw-r--r-- | src/hir/type.hpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 7 | ||||
-rw-r--r-- | src/hir_typeck/expr.hpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_context.cpp | 19 |
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 ); |