summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/expr_cs.cpp21
-rw-r--r--src/hir_typeck/helpers.cpp34
2 files changed, 48 insertions, 7 deletions
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 8011e0a8..7312bb3b 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2523,14 +2523,25 @@ namespace {
this->context.equate_types(sp, node.m_res_type, node.m_cache.m_arg_types.back());
// Add derefs
- if( deref_count >= ~3u )
+ if( deref_count >= ~6u )
{
+ auto inv = ~deref_count;
+ bool is_box_deref = (inv > 3);
+ auto borrow_ty = inv % 3;
+
+ if( is_box_deref ) {
+ const auto& ity = this->context.get_type(node.m_value->m_res_type).m_data.as_Path().path.m_data.as_Generic().m_params.m_types.at(0);
+ auto span = node.m_value->span();
+ DEBUG("- Deref Box " << &*node.m_value << " -> " << ity);
+ node.m_value = NEWNODE(ity.clone(), span, _Deref, mv$(node.m_value));
+ }
+
::HIR::BorrowType bt = ::HIR::BorrowType::Shared;
- switch(deref_count)
+ switch(borrow_ty)
{
- case ~1u: bt = ::HIR::BorrowType::Shared; break;
- case ~2u: bt = ::HIR::BorrowType::Unique; break;
- case ~3u: bt = ::HIR::BorrowType::Owned ; break;
+ case 1: bt = ::HIR::BorrowType::Shared; break;
+ case 2: bt = ::HIR::BorrowType::Unique; break;
+ case 0: bt = ::HIR::BorrowType::Owned ; break;
default:
BUG(sp, "Invalid deref return count - " << deref_count);
}
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 245b6320..a8c7ddfa 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -2945,7 +2945,10 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
return ~0u;
}
- // TODO: Insert a single reference and try again (only allowing by-value methods), returning a magic value (e.g. ~1u)
+ // TODO: Try the following after dereferencing a Box? - Requires indiciating via the return that the caller should deref+ref
+ // - Should refactor to change searching to search for functions taking the current type as a receiver (not method searching as is currently done)
+
+ // Insert a single reference and try again (only allowing by-value methods), returning a magic value (e.g. ~1u)
// - Required for calling `(self[..]: str).into_searcher(haystack)` - Which invokes `<&str as Pattern>::into_searcher(&self[..], haystack)`
// - Have to do several tries, each with different borrow classes.
auto borrow_ty = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, top_ty.clone());
@@ -2961,9 +2964,36 @@ unsigned int TraitResolution::autoderef_find_method(const Span& sp, const HIR::t
borrow_ty.m_data.as_Borrow().type = ::HIR::BorrowType::Owned;
if( find_method(sp, traits, ivars, borrow_ty, method_name, AllowedReceivers::Value, fcn_path) ) {
DEBUG("FOUND &mut, fcn_path = " << fcn_path);
- return ~2u;
+ return ~3u;
}
+ // Handle `self: Box<Self>` methods by detecting m_lang_Box and searchig for box receiver methods
+ TU_IFLET(::HIR::TypeRef::Data, top_ty_r.m_data, Path, e,
+ TU_IFLET(::HIR::Path::Data, e.path.m_data, Generic, pe,
+ if( pe.m_path == m_lang_Box )
+ {
+ const auto& ty = this->m_ivars.get_type( pe.m_params.m_types.at(0) );
+ assert( ! ty.m_data.is_Infer() );
+
+ auto borrow_ty = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, ty.clone());
+ if( find_method(sp, traits, ivars, borrow_ty, method_name, AllowedReceivers::Value, fcn_path) ) {
+ DEBUG("FOUND &*box, fcn_path = " << fcn_path);
+ return ~4u;
+ }
+ borrow_ty.m_data.as_Borrow().type = ::HIR::BorrowType::Unique;
+ if( find_method(sp, traits, ivars, borrow_ty, method_name, AllowedReceivers::Value, fcn_path) ) {
+ DEBUG("FOUND &mut*box, fcn_path = " << fcn_path);
+ return ~5u;
+ }
+ borrow_ty.m_data.as_Borrow().type = ::HIR::BorrowType::Owned;
+ if( find_method(sp, traits, ivars, borrow_ty, method_name, AllowedReceivers::Value, fcn_path) ) {
+ DEBUG("FOUND &mut*box, fcn_path = " << fcn_path);
+ return ~6u;
+ }
+ }
+ )
+ )
+
// Dereference failed! This is a hard error (hitting _ is checked above and returns ~0)
this->m_ivars.dump();
ERROR(sp, E0000, "Could not find method `" << method_name << "` on type `" << top_ty << "`");