diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-05-04 17:36:07 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-05-04 17:36:07 +0800 |
commit | 8a74857d5a6323a46757f12078b46718464a006d (patch) | |
tree | 59995482609e4ebf33a4de6a1316377b2181d92f | |
parent | 771c9385a5d7213cb12c1d7b969553b3402c498b (diff) | |
download | mrust-8a74857d5a6323a46757f12078b46718464a006d.tar.gz |
Match Ergonomics - Auto-deref in `ref` patterns to get `&T`
-rw-r--r-- | src/hir/pattern.hpp | 8 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 25 | ||||
-rw-r--r-- | src/mir/check.cpp | 6 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 5 |
4 files changed, 26 insertions, 18 deletions
diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index cd6c7422..d16fd942 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -32,19 +32,23 @@ struct PatternBinding ::std::string m_name; unsigned int m_slot; + unsigned m_implicit_deref_count = 0; + bool is_valid() const { return m_name != ""; } PatternBinding(): m_mutable(false), m_type(Type::Move), m_name(""), - m_slot(0) + m_slot(0), + m_implicit_deref_count(0) {} PatternBinding(bool mut, Type type, ::std::string name, unsigned int slot): m_mutable(mut), m_type(type), m_name( mv$(name) ), - m_slot( slot ) + m_slot( slot ), + m_implicit_deref_count(0) {} }; diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index a8e80a56..0b6b0089 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -4134,33 +4134,30 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T break; case ::HIR::PatternBinding::Type::MutRef: // NOTE: Needs to deref and borrow to get just `&mut T` (where T isn't a &mut T) - //while( TU_TEST1(type_p->m_data, Borrow, .type >= ::HIR::BorrowType::Unique) ) - //{ - // n_deref ++; - // type_p = &context.m_ivars.get_type(*type_p->m_data.as_Borrow().inner); - //} + while( TU_TEST1(type_p->m_data, Borrow, .type >= ::HIR::BorrowType::Unique) ) + { + n_deref ++; + type_p = &context.m_ivars.get_type(*type_p->m_data.as_Borrow().inner); + } DEBUG(n_deref << " from " << type << " to " << *type_p); binding_type = &(tmp = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Unique, type_p->clone())); break; case ::HIR::PatternBinding::Type::Ref: // NOTE: Needs to deref and borrow to get just `&mut T` (where T isn't a &mut T) - //while( type_p->m_data.is_Borrow() ) - //{ - // n_deref ++; - // type_p = &context.m_ivars.get_type(*type_p->m_data.as_Borrow().inner); - //} + while( type_p->m_data.is_Borrow() ) + { + n_deref ++; + type_p = &context.m_ivars.get_type(*type_p->m_data.as_Borrow().inner); + } DEBUG(n_deref << " from " << type << " to " << *type_p); binding_type = &(tmp = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, type_p->clone())); break; default: TODO(sp, "Assign variable type using mode " << (int)binding_mode << " and " << type); } - if( n_deref > 0 ) { - TODO(sp, "Handle autoderef of ref bindings in match ergonomics"); - } assert(binding_type); context.equate_types(sp, context.get_var(sp, pattern.m_binding.m_slot), *binding_type); - //pattern.m_binding.n_deref = n_deref; + pattern.m_binding.m_implicit_deref_count = n_deref; } // For `_` patterns, there's nothing to match, so they just succeed with no derefs diff --git a/src/mir/check.cpp b/src/mir/check.cpp index b2d86590..b5abdb0a 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -686,10 +686,12 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path // TODO: Check that the input type is Copy ), (Borrow, - // TODO: Check return type + ::HIR::TypeRef tmp; + check_types( dst_ty, ::HIR::TypeRef::new_borrow(e.type, state.get_lvalue_type(tmp, e.val).clone()) ); ), (Cast, - // TODO: Check return type + // Check return type + check_types( dst_ty, e.type ); // TODO: Check suitability of source type (COMPLEX) ), (BinOp, diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 912b8c78..8d51bf55 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -174,6 +174,11 @@ namespace { destructure_from_ex(sp, pat, lval.clone(), 3); } + for(size_t i = 0; i < pat.m_binding.m_implicit_deref_count; i ++) + { + lval = ::MIR::LValue::make_Deref({ box$(lval) }); + } + switch( pat.m_binding.m_type ) { case ::HIR::PatternBinding::Type::Move: |