summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hir/from_ast.cpp2
-rw-r--r--src/hir/pattern.cpp14
-rw-r--r--src/hir/pattern.hpp10
-rw-r--r--src/hir/visitor.cpp5
-rw-r--r--src/hir_conv/bind.cpp161
-rw-r--r--src/hir_expand/closures.cpp2
-rw-r--r--src/hir_typeck/expr_context.cpp6
-rw-r--r--src/hir_typeck/expr_cs.cpp6
-rw-r--r--src/include/tagged_union.hpp2
-rw-r--r--src/mir/from_hir.cpp2
10 files changed, 134 insertions, 76 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index ebf2e2a6..3f492633 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -301,7 +301,7 @@ const ::HIR::SimplePath path_Sized = ::HIR::SimplePath("", {"marker", "Sized"});
return ::HIR::Pattern::Value::make_String(e);
),
(Named,
- return ::HIR::Pattern::Value::make_Named( LowerHIR_Path(sp, e) );
+ return ::HIR::Pattern::Value::make_Named( {LowerHIR_Path(sp, e), nullptr} );
)
)
throw "BUGCHECK: Reached end of LowerHIR_Pattern::H::lowerhir_pattern_value";
diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp
index 386d1699..f3ad277e 100644
--- a/src/hir/pattern.cpp
+++ b/src/hir/pattern.cpp
@@ -12,7 +12,7 @@ namespace HIR {
os << "\"" << e << "\"";
),
(Named,
- os << e;
+ os << e.path;
)
)
return os;
@@ -51,6 +51,9 @@ namespace HIR {
os << s << ", ";
os << ")";
),
+ (StructValue,
+ os << e.path;
+ ),
(StructTuple,
os << e.path;
os << "(";
@@ -59,7 +62,7 @@ namespace HIR {
os << ")";
),
(StructTupleWildcard,
- os << e.path;
+ os << e.path << "(..)";
),
(Struct,
os << e.path;
@@ -145,7 +148,7 @@ namespace {
return ::HIR::Pattern::Value::make_String(e);
),
(Named,
- return ::HIR::Pattern::Value::make_Named(e.clone());
+ return ::HIR::Pattern::Value::make_Named({ e.path.clone(), e.binding });
)
)
throw "";
@@ -173,6 +176,11 @@ namespace {
clone_pat_vec(e.sub_patterns)
}));
),
+ (StructValue,
+ return Pattern(m_binding, Data::make_StructValue({
+ e.path.clone(), e.binding
+ }));
+ ),
(StructTuple,
return Pattern(m_binding, Data::make_StructTuple({
e.path.clone(),
diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp
index b02721b2..2a5ebb2a 100644
--- a/src/hir/pattern.hpp
+++ b/src/hir/pattern.hpp
@@ -12,6 +12,7 @@ namespace HIR {
class Struct;
class Enum;
+class Constant;
struct PatternBinding
{
@@ -50,7 +51,10 @@ struct Pattern
uint64_t value; // Signed numbers are encoded as 2's complement
}),
(String, ::std::string),
- (Named, Path)
+ (Named, struct {
+ Path path;
+ const ::HIR::Constant* binding;
+ })
);
friend ::std::ostream& operator<<(::std::ostream& os, const Pattern::Value& x);
@@ -60,6 +64,10 @@ struct Pattern
(Box, struct { ::std::unique_ptr<Pattern> sub; }),
(Ref, struct { ::HIR::BorrowType type; ::std::unique_ptr<Pattern> sub; } ),
(Tuple, struct { ::std::vector<Pattern> sub_patterns; } ),
+ (StructValue, struct {
+ GenericPath path;
+ const Struct* binding;
+ }),
(StructTuple, struct {
// NOTE: Type paths in patterns _can_ have parameters
GenericPath path;
diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp
index 9767996e..daef834d 100644
--- a/src/hir/visitor.cpp
+++ b/src/hir/visitor.cpp
@@ -330,6 +330,9 @@ void ::HIR::Visitor::visit_pattern(::HIR::Pattern& pat)
for(auto& sp : e.sub_patterns)
this->visit_pattern(sp);
),
+ (StructValue,
+ this->visit_generic_path(e.path, ::HIR::Visitor::PathContext::TYPE);
+ ),
(StructTupleWildcard,
this->visit_generic_path(e.path, ::HIR::Visitor::PathContext::TYPE);
),
@@ -387,7 +390,7 @@ void ::HIR::Visitor::visit_pattern_val(::HIR::Pattern::Value& val)
(String,
),
(Named,
- this->visit_path(e, ::HIR::Visitor::PathContext::VALUE);
+ this->visit_path(e.path, ::HIR::Visitor::PathContext::VALUE);
)
)
}
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index 9457585c..8447daee 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -131,87 +131,108 @@ namespace {
::HIR::Visitor::visit_trait_path(p);
}
- void visit_pattern(::HIR::Pattern& pat) override
+
+ void visit_pattern_Value(const Span& sp, ::HIR::Pattern& pat, ::HIR::Pattern::Value& val)
{
- static Span _sp = Span();
- const Span& sp = _sp;
-
- ::HIR::Visitor::visit_pattern(pat);
+ bool allow_enum = pat.m_data.is_Value();
- TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (e),
- (
- ),
- (Value,
- TU_IFLET( ::HIR::Pattern::Value, e.val, Named, ve,
- TU_IFLET( ::HIR::Path::Data, ve.m_data, Generic, pe,
- const ::HIR::Enum* enm = nullptr;
- const ::HIR::Module* mod = &m_crate.m_root_module;
- const auto& path = pe.m_path;
- for(unsigned int i = 0; i < path.m_components.size() - 1; i ++ )
- {
- const auto& pc = path.m_components[i];
- auto it = mod->m_mod_items.find( pc );
- if( it == mod->m_mod_items.end() ) {
- BUG(sp, "Couldn't find component " << i << " of " << path);
- }
-
- if( i == path.m_components.size() - 2 ) {
- // Here it's allowed to be either a module, or an enum.
- TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2,
- mod = &e2;
- )
- else TU_IFLET( ::HIR::TypeItem, it->second->ent, Enum, e2,
- enm = &e2;
- )
- else {
- BUG(sp, "Node " << i << " of path " << ve << " wasn't a module or enum");
- }
- }
- else {
- TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2,
- mod = &e2;
- )
- else {
- BUG(sp, "Node " << i << " of path " << ve << " wasn't a module");
- }
- }
+ TU_IFLET( ::HIR::Pattern::Value, val, Named, ve,
+ TU_IFLET( ::HIR::Path::Data, ve.path.m_data, Generic, pe,
+ const ::HIR::Enum* enm = nullptr;
+ const ::HIR::Module* mod = &m_crate.m_root_module;
+ const auto& path = pe.m_path;
+ for(unsigned int i = 0; i < path.m_components.size() - 1; i ++ )
+ {
+ const auto& pc = path.m_components[i];
+ auto it = mod->m_mod_items.find( pc );
+ if( it == mod->m_mod_items.end() ) {
+ BUG(sp, "Couldn't find component " << i << " of " << path);
}
- const auto& pc = path.m_components.back();
- if( enm ) {
- // Enum variant
- auto it = ::std::find_if( enm->m_variants.begin(), enm->m_variants.end(), [&](const auto&v){ return v.first == pc; });
- if( it == enm->m_variants.end() ) {
- BUG(sp, "'" << pc << "' isn't a variant in path " << path);
+
+ if( i == path.m_components.size() - 2 ) {
+ // Here it's allowed to be either a module, or an enum.
+ TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2,
+ mod = &e2;
+ )
+ else TU_IFLET( ::HIR::TypeItem, it->second->ent, Enum, e2,
+ enm = &e2;
+ )
+ else {
+ BUG(sp, "Node " << i << " of path " << ve.path << " wasn't a module or enum");
}
- unsigned int index = it - enm->m_variants.begin();
- auto path = mv$(pe);
- fix_type_params(sp, enm->m_params, path.m_params);
- //::std::cout << "HHHH: path=" << path << ::std::endl;
- pat.m_data = ::HIR::Pattern::Data::make_EnumValue({
- mv$(path),
- enm,
- index
- });
}
else {
- auto it = mod->m_value_items.find( pc );
- if( it == mod->m_value_items.end() ) {
- BUG(sp, "Couldn't find final component of " << path);
- }
- // Unit-like struct match or a constant
- // TODO: Store binding
- TU_MATCH_DEF( ::HIR::ValueItem, (it->second->ent), (e2),
- (
- ),
- (StructConstant,
- )
+ TU_IFLET( ::HIR::TypeItem, it->second->ent, Module, e2,
+ mod = &e2;
)
+ else {
+ BUG(sp, "Node " << i << " of path " << ve.path << " wasn't a module");
+ }
}
- )
+ }
+ const auto& pc = path.m_components.back();
+ if( enm ) {
+ if( !allow_enum ) {
+ ERROR(sp, E0000, "Enum variant in range pattern - " << pat);
+ }
+
+ // Enum variant
+ auto it = ::std::find_if( enm->m_variants.begin(), enm->m_variants.end(), [&](const auto&v){ return v.first == pc; });
+ if( it == enm->m_variants.end() ) {
+ BUG(sp, "'" << pc << "' isn't a variant in path " << path);
+ }
+ unsigned int index = it - enm->m_variants.begin();
+ auto path = mv$(pe);
+ fix_type_params(sp, enm->m_params, path.m_params);
+ //::std::cout << "HHHH: path=" << path << ::std::endl;
+ pat.m_data = ::HIR::Pattern::Data::make_EnumValue({
+ mv$(path),
+ enm,
+ index
+ });
+ }
else {
- // UFCS/Opaque, leave for now.
+ auto it = mod->m_value_items.find( pc );
+ if( it == mod->m_value_items.end() ) {
+ BUG(sp, "Couldn't find final component of " << path);
+ }
+ // Unit-like struct match or a constant
+ TU_MATCH_DEF( ::HIR::ValueItem, (it->second->ent), (e2),
+ (
+ ERROR(sp, E0000, "Value pattern pointing to unexpected type")
+ ),
+ (Constant,
+ // TODO: Store reference to this item for later use
+ ),
+ (StructConstant,
+ // TODO: Convert into a dedicated pattern type
+ )
+ )
}
)
+ else {
+ // UFCS/Opaque, leave for now.
+ }
+ )
+ }
+
+
+ void visit_pattern(::HIR::Pattern& pat) override
+ {
+ static Span _sp = Span();
+ const Span& sp = _sp;
+
+ ::HIR::Visitor::visit_pattern(pat);
+
+ TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (e),
+ (
+ ),
+ (Value,
+ this->visit_pattern_Value(sp, pat, e.val);
+ ),
+ (Range,
+ this->visit_pattern_Value(sp, pat, e.start);
+ this->visit_pattern_Value(sp, pat, e.end);
),
(StructTuple,
const auto& str = get_struct_ptr(sp, m_crate, e.path);
diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp
index b76a61ca..3d207f5d 100644
--- a/src/hir_expand/closures.cpp
+++ b/src/hir_expand/closures.cpp
@@ -666,6 +666,8 @@ namespace {
),
// - Enums/Structs
+ (StructValue,
+ ),
(StructTuple,
for(const auto& field : e.sub_patterns) {
add_closure_def_from_pattern(sp, field);
diff --git a/src/hir_typeck/expr_context.cpp b/src/hir_typeck/expr_context.cpp
index 61e0ac68..e1cb6c1f 100644
--- a/src/hir_typeck/expr_context.cpp
+++ b/src/hir_typeck/expr_context.cpp
@@ -182,6 +182,9 @@ void typeck::TypecheckContext::add_binding(const Span& sp, ::HIR::Pattern& pat,
),
// - Enums/Structs
+ (StructValue,
+ throw "TODO";
+ ),
(StructTuple,
this->add_ivars_params( e.path.m_params );
if( type.m_data.is_Infer() ) {
@@ -509,6 +512,9 @@ void typeck::TypecheckContext::apply_pattern(const ::HIR::Pattern& pat, ::HIR::T
),
// - Enums/Structs
+ (StructValue,
+ throw "TODO";
+ ),
(StructTuple,
if( ty.m_data.is_Infer() ) {
ty.m_data = ::HIR::TypeRef::Data::make_Path( {e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)} );
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index f43a2ecd..32af3ff3 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -2548,6 +2548,12 @@ void Context::add_binding(const Span& sp, ::HIR::Pattern& pat, const ::HIR::Type
),
// - Enums/Structs
+ (StructValue,
+ this->add_ivars_params( e.path.m_params );
+ const auto& str = *e.binding;
+ assert( str.m_data.is_Unit() );
+ this->equate_types( sp, type, ::HIR::TypeRef::new_path(e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)) );
+ ),
(StructTuple,
this->add_ivars_params( e.path.m_params );
const auto& str = *e.binding;
diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp
index 1e319b08..0627b525 100644
--- a/src/include/tagged_union.hpp
+++ b/src/include/tagged_union.hpp
@@ -35,6 +35,7 @@
#define _DISP13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) _DISP5(n, a1,a2,a3,a4,a5) _DISP4(n, b1,b2,b3,b4) _DISP4(n, c1,c2,c3,c4)
#define _DISP14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP4(n, c1,c2,c3,c4)
#define _DISP15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP5(n, c1,c2,c3,c4,c5)
+#define _DISP16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) _DISP5(n, a1,a2,a3,a4,a5) _DISP5(n, b1,b2,b3,b4,b5) _DISP5(n, c1,c2,c3,c4,c5) _DISP1(n, d1)
#define _DISPO0(n)
#define _DISPO1(n, _1) n(_1)
@@ -52,6 +53,7 @@
#define _DISPO13(n, a1,a2,a3,a4,a5, b1,b2,b3,b4, c1,c2,c3,c4) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO4(n, b1,b2,b3,b4) _DISPO4(n, c1,c2,c3,c4)
#define _DISPO14(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO4(n, c1,c2,c3,c4)
#define _DISPO15(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO5(n, c1,c2,c3,c4,c5)
+#define _DISPO16(n, a1,a2,a3,a4,a5, b1,b2,b3,b4,b5, c1,c2,c3,c4,c5, d1) _DISPO5(n, a1,a2,a3,a4,a5) _DISPO5(n, b1,b2,b3,b4,b5) _DISPO5(n, c1,c2,c3,c4,c5) _DISPO1(n, d1)
#define TU_DISPA(n, a) n a
#define TU_DISPA1(n, a, _1) TU_DISPA(n, (TU_EXP a, TU_EXP _1))
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 02baf445..6f166f65 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -86,6 +86,8 @@ namespace {
destructure_from_ex(sp, e.sub_patterns[i], ::MIR::LValue::make_Field({ box$( lval.clone() ), i}), allow_refutable);
}
),
+ (StructValue,
+ ),
(StructTuple,
for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ )
{