summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/expr.hpp1
-rw-r--r--src/hir/expr.cpp5
-rw-r--r--src/hir/expr.hpp102
-rw-r--r--src/hir/from_ast.cpp36
-rw-r--r--src/hir/from_ast_expr.cpp102
-rw-r--r--src/hir_conv/resolve_ufcs.cpp188
-rw-r--r--src/hir_typeck/expr.cpp95
-rw-r--r--src/resolve/absolute.cpp83
8 files changed, 394 insertions, 218 deletions
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp
index bddada90..98314824 100644
--- a/src/ast/expr.hpp
+++ b/src/ast/expr.hpp
@@ -33,6 +33,7 @@ public:
void set_pos(Position p) { m_pos = ::std::move(p); }
const Position& get_pos() const { return m_pos; }
+ Span span() const { return m_pos; }
void set_attrs(MetaItems&& mi) {
m_attrs = mv$(mi);
diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp
index a56e608a..3d48f9d4 100644
--- a/src/hir/expr.cpp
+++ b/src/hir/expr.cpp
@@ -5,11 +5,6 @@
::HIR::ExprNode::~ExprNode()
{
}
-const Span& ::HIR::ExprNode::span() const
-{
- static Span rv = Span();
- return rv;
-}
#define DEF_VISIT(nt, n, code) void ::HIR::nt::visit(ExprVisitor& nv) { nv.visit_node(*this); nv.visit(*this); } void ::HIR::ExprVisitorDef::visit(::HIR::nt& n) { code }
diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp
index 72bc2070..b15db07c 100644
--- a/src/hir/expr.hpp
+++ b/src/hir/expr.hpp
@@ -14,14 +14,17 @@ class ExprVisitor;
class ExprNode
{
public:
+ Span m_span;
::HIR::TypeRef m_res_type;
- const Span& span() const;
+ const Span& span() const { return m_span; }
virtual void visit(ExprVisitor& v) = 0;
- ExprNode()
+ ExprNode(Span sp):
+ m_span( mv$(sp) )
{}
- ExprNode(::HIR::TypeRef ty):
+ ExprNode(Span sp, ::HIR::TypeRef ty):
+ m_span( mv$(sp) ),
m_res_type( mv$(ty) )
{}
virtual ~ExprNode();
@@ -39,10 +42,12 @@ struct ExprNode_Block:
::std::vector< ExprNodeP > m_nodes;
::std::vector< ::HIR::SimplePath> m_traits;
- ExprNode_Block():
+ ExprNode_Block(Span sp):
+ ExprNode(mv$(sp)),
m_is_unsafe(false)
{}
- ExprNode_Block(bool is_unsafe, ::std::vector<ExprNodeP> nodes):
+ ExprNode_Block(Span sp, bool is_unsafe, ::std::vector<ExprNodeP> nodes):
+ ExprNode( mv$(sp) ),
m_is_unsafe(is_unsafe),
m_nodes( mv$(nodes) )
{}
@@ -54,8 +59,8 @@ struct ExprNode_Return:
{
::HIR::ExprNodeP m_value;
- ExprNode_Return(::HIR::ExprNodeP value):
- ExprNode(::HIR::TypeRef::Data::make_Diverge({})),
+ ExprNode_Return(Span sp, ::HIR::ExprNodeP value):
+ ExprNode(mv$(sp), ::HIR::TypeRef::new_diverge()),
m_value( mv$(value) )
{
}
@@ -68,8 +73,8 @@ struct ExprNode_Loop:
::std::string m_label;
::HIR::ExprNodeP m_code;
- ExprNode_Loop(::std::string label, ::HIR::ExprNodeP code):
- ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
+ ExprNode_Loop(Span sp, ::std::string label, ::HIR::ExprNodeP code):
+ ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
m_label( mv$(label) ),
m_code( mv$(code) )
{}
@@ -83,8 +88,8 @@ struct ExprNode_LoopControl:
bool m_continue;
//::HIR::ExprNodeP m_value;
- ExprNode_LoopControl(::std::string label, bool cont):
- ExprNode(::HIR::TypeRef::Data::make_Diverge({})),
+ ExprNode_LoopControl(Span sp, ::std::string label, bool cont):
+ ExprNode(mv$(sp), ::HIR::TypeRef::new_diverge()),
m_label( mv$(label) ),
m_continue( cont )
{}
@@ -98,8 +103,8 @@ struct ExprNode_Let:
::HIR::TypeRef m_type;
::HIR::ExprNodeP m_value;
- ExprNode_Let(::HIR::Pattern pat, ::HIR::TypeRef ty, ::HIR::ExprNodeP val):
- ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
+ ExprNode_Let(Span sp, ::HIR::Pattern pat, ::HIR::TypeRef ty, ::HIR::ExprNodeP val):
+ ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
m_pattern( mv$(pat) ),
m_type( mv$(ty) ),
m_value( mv$(val) )
@@ -121,7 +126,8 @@ struct ExprNode_Match:
::HIR::ExprNodeP m_value;
::std::vector<Arm> m_arms;
- ExprNode_Match(::HIR::ExprNodeP val, ::std::vector<Arm> arms):
+ ExprNode_Match(Span sp, ::HIR::ExprNodeP val, ::std::vector<Arm> arms):
+ ExprNode( mv$(sp) ),
m_value( mv$(val) ),
m_arms( mv$(arms) )
{}
@@ -136,7 +142,8 @@ struct ExprNode_If:
::HIR::ExprNodeP m_true;
::HIR::ExprNodeP m_false;
- ExprNode_If(::HIR::ExprNodeP cond, ::HIR::ExprNodeP true_code, ::HIR::ExprNodeP false_code):
+ ExprNode_If(Span sp, ::HIR::ExprNodeP cond, ::HIR::ExprNodeP true_code, ::HIR::ExprNodeP false_code):
+ ExprNode( mv$(sp) ),
m_cond( mv$(cond) ),
m_true( mv$(true_code) ),
m_false( mv$(false_code) )
@@ -160,8 +167,8 @@ struct ExprNode_Assign:
ExprNodeP m_slot;
ExprNodeP m_value;
- ExprNode_Assign(Op op, ::HIR::ExprNodeP slot, ::HIR::ExprNodeP value):
- ExprNode(::HIR::TypeRef(TypeRef::TagUnit{})),
+ ExprNode_Assign(Span sp, Op op, ::HIR::ExprNodeP slot, ::HIR::ExprNodeP value):
+ ExprNode(mv$(sp), ::HIR::TypeRef::new_unit()),
m_op(op),
m_slot( mv$(slot) ),
m_value( mv$(value) )
@@ -193,8 +200,8 @@ struct ExprNode_BinOp:
::HIR::ExprNodeP m_left;
::HIR::ExprNodeP m_right;
- ExprNode_BinOp() {}
- ExprNode_BinOp(Op op, ::HIR::ExprNodeP left, ::HIR::ExprNodeP right):
+ ExprNode_BinOp(Span sp, Op op, ::HIR::ExprNodeP left, ::HIR::ExprNodeP right):
+ ExprNode( mv$(sp) ),
m_op(op),
m_left( mv$(left) ),
m_right( mv$(right) )
@@ -227,7 +234,8 @@ struct ExprNode_UniOp:
Op m_op;
::HIR::ExprNodeP m_value;
- ExprNode_UniOp(Op op, ::HIR::ExprNodeP value):
+ ExprNode_UniOp(Span sp, Op op, ::HIR::ExprNodeP value):
+ ExprNode( mv$(sp) ),
m_op(op),
m_value( mv$(value) )
{}
@@ -239,8 +247,8 @@ struct ExprNode_Cast:
{
::HIR::ExprNodeP m_value;
- ExprNode_Cast(::HIR::ExprNodeP value, ::HIR::TypeRef dst_type):
- ExprNode( mv$(dst_type) ),
+ ExprNode_Cast(Span sp, ::HIR::ExprNodeP value, ::HIR::TypeRef dst_type):
+ ExprNode( mv$(sp), mv$(dst_type) ),
m_value( mv$(value) )
{}
@@ -251,8 +259,8 @@ struct ExprNode_Unsize:
{
::HIR::ExprNodeP m_value;
- ExprNode_Unsize(::HIR::ExprNodeP value, ::HIR::TypeRef dst_type):
- ExprNode( mv$(dst_type) ),
+ ExprNode_Unsize(Span sp, ::HIR::ExprNodeP value, ::HIR::TypeRef dst_type):
+ ExprNode( mv$(sp), mv$(dst_type) ),
m_value( mv$(value) )
{}
@@ -264,7 +272,8 @@ struct ExprNode_Index:
::HIR::ExprNodeP m_val;
::HIR::ExprNodeP m_index;
- ExprNode_Index(::HIR::ExprNodeP val, ::HIR::ExprNodeP index):
+ ExprNode_Index(Span sp, ::HIR::ExprNodeP val, ::HIR::ExprNodeP index):
+ ExprNode(mv$(sp)),
m_val( mv$(val) ),
m_index( mv$(index) )
{}
@@ -276,7 +285,8 @@ struct ExprNode_Deref:
{
::HIR::ExprNodeP m_val;
- ExprNode_Deref(::HIR::ExprNodeP val):
+ ExprNode_Deref(Span sp, ::HIR::ExprNodeP val):
+ ExprNode(mv$(sp)),
m_val( mv$(val) )
{}
@@ -289,7 +299,8 @@ struct ExprNode_CallPath:
::HIR::Path m_path;
::std::vector<ExprNodeP> m_args;
- ExprNode_CallPath(::HIR::Path path, ::std::vector< ::HIR::ExprNodeP> args):
+ ExprNode_CallPath(Span sp, ::HIR::Path path, ::std::vector< ::HIR::ExprNodeP> args):
+ ExprNode(mv$(sp)),
m_path( mv$(path) ),
m_args( mv$(args) )
{}
@@ -302,7 +313,8 @@ struct ExprNode_CallValue:
::HIR::ExprNodeP m_val;
::std::vector<ExprNodeP> m_args;
- ExprNode_CallValue(::HIR::ExprNodeP val, ::std::vector< ::HIR::ExprNodeP> args):
+ ExprNode_CallValue(Span sp, ::HIR::ExprNodeP val, ::std::vector< ::HIR::ExprNodeP> args):
+ ExprNode(mv$(sp)),
m_val( mv$(val) ),
m_args( mv$(args) )
{}
@@ -317,8 +329,8 @@ struct ExprNode_CallMethod:
::HIR::PathParams m_params;
::std::vector< ::HIR::ExprNodeP> m_args;
- ExprNode_CallMethod() {}
- ExprNode_CallMethod(::HIR::ExprNodeP val, ::std::string method_name, ::HIR::PathParams params, ::std::vector< ::HIR::ExprNodeP> args):
+ ExprNode_CallMethod(Span sp, ::HIR::ExprNodeP val, ::std::string method_name, ::HIR::PathParams params, ::std::vector< ::HIR::ExprNodeP> args):
+ ExprNode( mv$(sp) ),
m_val( mv$(val) ),
m_method( mv$(method_name) ),
m_params( mv$(params) ),
@@ -334,7 +346,8 @@ struct ExprNode_Field:
::HIR::ExprNodeP m_val;
::std::string m_field;
- ExprNode_Field(::HIR::ExprNodeP val, ::std::string field):
+ ExprNode_Field(Span sp, ::HIR::ExprNodeP val, ::std::string field):
+ ExprNode(mv$(sp)),
m_val( mv$(val) ),
m_field( mv$(field) )
{}
@@ -361,7 +374,8 @@ struct ExprNode_Literal:
Data m_data;
- ExprNode_Literal(Data data):
+ ExprNode_Literal(Span sp, Data data):
+ ExprNode( mv$(sp) ),
m_data( mv$(data) )
{
TU_MATCH(Data, (m_data), (e),
@@ -404,7 +418,8 @@ struct ExprNode_PathValue:
{
::HIR::Path m_path;
- ExprNode_PathValue(::HIR::Path path):
+ ExprNode_PathValue(Span sp, ::HIR::Path path):
+ ExprNode(mv$(sp)),
m_path( mv$(path) )
{}
@@ -416,7 +431,8 @@ struct ExprNode_Variable:
::std::string m_name;
unsigned int m_slot;
- ExprNode_Variable(::std::string name, unsigned int slot):
+ ExprNode_Variable(Span sp, ::std::string name, unsigned int slot):
+ ExprNode(mv$(sp)),
m_name( mv$(name) ),
m_slot( slot )
{}
@@ -433,12 +449,13 @@ struct ExprNode_StructLiteral:
::HIR::ExprNodeP m_base_value;
t_values m_values;
- ExprNode_StructLiteral(::HIR::GenericPath path, ::HIR::ExprNodeP base_value, t_values values):
+ ExprNode_StructLiteral(Span sp, ::HIR::GenericPath path, ::HIR::ExprNodeP base_value, t_values values):
+ ExprNode( mv$(sp) ),
m_path( mv$(path) ),
m_base_value( mv$(base_value) ),
m_values( mv$(values) )
{
- // TODO: set m_res_type based on path
+ // TODO: set m_res_type based on path?
}
NODE_METHODS();
@@ -448,7 +465,8 @@ struct ExprNode_Tuple:
{
::std::vector< ::HIR::ExprNodeP> m_vals;
- ExprNode_Tuple(::std::vector< ::HIR::ExprNodeP> vals):
+ ExprNode_Tuple(Span sp, ::std::vector< ::HIR::ExprNodeP> vals):
+ ExprNode(mv$(sp)),
m_vals( mv$(vals) )
{}
@@ -459,8 +477,8 @@ struct ExprNode_ArrayList:
{
::std::vector< ::HIR::ExprNodeP> m_vals;
- ExprNode_ArrayList(::std::vector< ::HIR::ExprNodeP> vals):
- ExprNode( ::HIR::TypeRef::Data::make_Array({
+ ExprNode_ArrayList(Span sp, ::std::vector< ::HIR::ExprNodeP> vals):
+ ExprNode( mv$(sp), ::HIR::TypeRef::Data::make_Array({
box$( ::HIR::TypeRef() ),
::HIR::ExprPtr(),
vals.size()
@@ -477,7 +495,8 @@ struct ExprNode_ArraySized:
::HIR::ExprNodeP m_size; // TODO: Has to be constant
size_t m_size_val;
- ExprNode_ArraySized(::HIR::ExprNodeP val, ::HIR::ExprNodeP size):
+ ExprNode_ArraySized(Span sp, ::HIR::ExprNodeP val, ::HIR::ExprNodeP size):
+ ExprNode(mv$(sp)),
m_val( mv$(val) ),
m_size( mv$(size) ),
m_size_val( ~0u )
@@ -495,7 +514,8 @@ struct ExprNode_Closure:
::HIR::TypeRef m_return;
::HIR::ExprNodeP m_code;
- ExprNode_Closure(args_t args, ::HIR::TypeRef rv, ::HIR::ExprNodeP code):
+ ExprNode_Closure(Span sp, args_t args, ::HIR::TypeRef rv, ::HIR::ExprNodeP code):
+ ExprNode(mv$(sp)),
m_args( ::std::move(args) ),
m_return( ::std::move(rv) ),
m_code( ::std::move(code) )
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 7d755d63..0329f3fa 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -384,18 +384,25 @@
throw "BUG: Encountered non-Absolute path when creating ::HIR::GenericPath";
}
}
+::HIR::PathParams LowerHIR_PathParams(const Span& sp, const ::AST::PathParams& src_params)
+{
+ ::HIR::PathParams params;
+
+ // TODO: Lifetime params (not encoded in ::HIR::PathNode as yet)
+ //for(const auto& param : src_params.m_lifetimes) {
+ //}
+
+ for(const auto& param : src_params.m_types) {
+ params.m_types.push_back( LowerHIR_Type(param) );
+ }
+
+ return params;
+}
::HIR::GenericPath LowerHIR_GenericPath(const Span& sp, const ::AST::Path& path)
{
TU_IFLET(::AST::Path::Class, path.m_class, Absolute, e,
auto simpepath = LowerHIR_SimplePath(sp, path, true);
- ::HIR::PathParams params;
- const auto& src_params = e.nodes.back().args();
- //for(const auto& param : src_params.m_lifetimes) {
- //}
- for(const auto& param : src_params.m_types) {
- params.m_types.push_back( LowerHIR_Type(param) );
- }
- // TODO: Lifetime params (not encoded in AST::PathNode as yet)
+ ::HIR::PathParams params = LowerHIR_PathParams(sp, e.nodes.back().args());
auto rv = ::HIR::GenericPath(mv$(simpepath), mv$(params));
DEBUG(path << " => " << rv);
return rv;
@@ -428,12 +435,17 @@
(UFCS,
if( e.nodes.size() != 1 )
TODO(sp, "Handle UFCS with multiple nodes - " << path);
+ auto params = LowerHIR_PathParams(sp, e.nodes.front().args());
if( ! e.trait )
{
+ auto type = box$( LowerHIR_Type(*e.type) );
+ if( type->m_data.is_Generic() ) {
+ BUG(sp, "Generics can't be used with UfcsInherent - " << path);
+ }
return ::HIR::Path(::HIR::Path::Data::make_UfcsInherent({
- box$( LowerHIR_Type(*e.type) ),
+ mv$(type),
e.nodes[0].name(),
- {}
+ mv$(params)
}));
}
else if( ! e.trait->is_valid() )
@@ -441,7 +453,7 @@
return ::HIR::Path(::HIR::Path::Data::make_UfcsUnknown({
box$( LowerHIR_Type(*e.type) ),
e.nodes[0].name(),
- {}
+ mv$(params)
}));
}
else
@@ -450,7 +462,7 @@
box$(LowerHIR_Type(*e.type)),
LowerHIR_GenericPath(sp, *e.trait),
e.nodes[0].name(),
- {}
+ mv$(params)
}));
}
)
diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp
index c48a6ee9..40f27d5a 100644
--- a/src/hir/from_ast_expr.cpp
+++ b/src/hir/from_ast_expr.cpp
@@ -22,14 +22,14 @@ struct LowerHIR_ExprNode_Visitor:
::std::unique_ptr< ::HIR::ExprNode> m_rv;
virtual void visit(::AST::ExprNode_Block& v) override {
- auto rv = new ::HIR::ExprNode_Block();
+ auto rv = new ::HIR::ExprNode_Block(v.span());
for(const auto& n : v.m_nodes)
{
if( n ) {
rv->m_nodes.push_back( LowerHIR_ExprNode_Inner( *n ) );
}
else {
- rv->m_nodes.push_back( ::HIR::ExprNodeP( new ::HIR::ExprNode_Tuple({}) ) );
+ rv->m_nodes.push_back( ::HIR::ExprNodeP( new ::HIR::ExprNode_Tuple(Span(), {}) ) );
}
}
@@ -48,20 +48,20 @@ struct LowerHIR_ExprNode_Visitor:
{
case ::AST::ExprNode_Flow::RETURN:
if( v.m_value )
- m_rv.reset( new ::HIR::ExprNode_Return( LowerHIR_ExprNode_Inner(*v.m_value) ) );
+ m_rv.reset( new ::HIR::ExprNode_Return( v.span(), LowerHIR_ExprNode_Inner(*v.m_value) ) );
else
- m_rv.reset( new ::HIR::ExprNode_Return( ::HIR::ExprNodeP(new ::HIR::ExprNode_Tuple({})) ) );
+ m_rv.reset( new ::HIR::ExprNode_Return( v.span(), ::HIR::ExprNodeP(new ::HIR::ExprNode_Tuple(v.span(), {})) ) );
break;
case ::AST::ExprNode_Flow::CONTINUE:
case ::AST::ExprNode_Flow::BREAK:
if( v.m_value )
TODO(v.get_pos(), "Handle break/continue values in HIR");
- m_rv.reset( new ::HIR::ExprNode_LoopControl( v.m_target, (v.m_type == ::AST::ExprNode_Flow::CONTINUE) ) );
+ m_rv.reset( new ::HIR::ExprNode_LoopControl( v.span(), v.m_target, (v.m_type == ::AST::ExprNode_Flow::CONTINUE) ) );
break;
}
}
virtual void visit(::AST::ExprNode_LetBinding& v) override {
- m_rv.reset( new ::HIR::ExprNode_Let(
+ m_rv.reset( new ::HIR::ExprNode_Let( v.span(),
LowerHIR_Pattern( v.m_pat ),
LowerHIR_Type( v.m_type ),
LowerHIR_ExprNode_Inner_Opt( v.m_value.get() )
@@ -90,7 +90,7 @@ struct LowerHIR_ExprNode_Visitor:
throw "";
}
};
- m_rv.reset( new ::HIR::ExprNode_Assign(
+ m_rv.reset( new ::HIR::ExprNode_Assign( v.span(),
H::get_op(v.m_op),
LowerHIR_ExprNode_Inner( *v.m_slot ),
LowerHIR_ExprNode_Inner( *v.m_value )
@@ -115,18 +115,18 @@ struct LowerHIR_ExprNode_Visitor:
if( v.m_left ) {
if( v.m_right ) {
- m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_Range), nullptr, mv$(values)) );
+ m_rv.reset( new ::HIR::ExprNode_StructLiteral(v.span(), mv$(path_Range), nullptr, mv$(values)) );
}
else {
- m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeFrom), nullptr, mv$(values)) );
+ m_rv.reset( new ::HIR::ExprNode_StructLiteral(v.span(), mv$(path_RangeFrom), nullptr, mv$(values)) );
}
}
else {
if( v.m_right ) {
- m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeTo), nullptr, mv$(values)) );
+ m_rv.reset( new ::HIR::ExprNode_StructLiteral(v.span(), mv$(path_RangeTo), nullptr, mv$(values)) );
}
else {
- m_rv.reset( new ::HIR::ExprNode_PathValue(mv$(path_RangeFull)) );
+ m_rv.reset( new ::HIR::ExprNode_PathValue(v.span(), mv$(path_RangeFull)) );
}
}
break; }
@@ -140,13 +140,13 @@ struct LowerHIR_ExprNode_Visitor:
::HIR::ExprNode_StructLiteral::t_values values;
values.push_back( ::std::make_pair( ::std::string("start"), LowerHIR_ExprNode_Inner( *v.m_left ) ) );
values.push_back( ::std::make_pair( ::std::string("end") , LowerHIR_ExprNode_Inner( *v.m_right ) ) );
- m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeInclusive_NonEmpty), nullptr, mv$(values)) );
+ m_rv.reset( new ::HIR::ExprNode_StructLiteral(v.span(), mv$(path_RangeInclusive_NonEmpty), nullptr, mv$(values)) );
}
else
{
::HIR::ExprNode_StructLiteral::t_values values;
values.push_back( ::std::make_pair( ::std::string("end") , LowerHIR_ExprNode_Inner( *v.m_right ) ) );
- m_rv.reset( new ::HIR::ExprNode_StructLiteral(mv$(path_RangeToInclusive), nullptr, mv$(values)) );
+ m_rv.reset( new ::HIR::ExprNode_StructLiteral(v.span(), mv$(path_RangeToInclusive), nullptr, mv$(values)) );
}
break; }
case ::AST::ExprNode_BinOp::PLACE_IN:
@@ -173,7 +173,7 @@ struct LowerHIR_ExprNode_Visitor:
case ::AST::ExprNode_BinOp::SHR: op = ::HIR::ExprNode_BinOp::Op::Shr; if(0)
case ::AST::ExprNode_BinOp::SHL: op = ::HIR::ExprNode_BinOp::Op::Shl;
- m_rv.reset( new ::HIR::ExprNode_BinOp(
+ m_rv.reset( new ::HIR::ExprNode_BinOp( v.span(),
op,
LowerHIR_ExprNode_Inner( *v.m_left ),
LowerHIR_ExprNode_Inner( *v.m_right )
@@ -197,7 +197,7 @@ struct LowerHIR_ExprNode_Visitor:
case ::AST::ExprNode_UniOp::REFMUT: op = ::HIR::ExprNode_UniOp::Op::RefMut; if(0)
case ::AST::ExprNode_UniOp::INVERT: op = ::HIR::ExprNode_UniOp::Op::Invert; if(0)
case ::AST::ExprNode_UniOp::NEGATE: op = ::HIR::ExprNode_UniOp::Op::Negate;
- m_rv.reset( new ::HIR::ExprNode_UniOp(
+ m_rv.reset( new ::HIR::ExprNode_UniOp( v.span(),
op,
LowerHIR_ExprNode_Inner( *v.m_value )
) );
@@ -205,7 +205,7 @@ struct LowerHIR_ExprNode_Visitor:
}
}
virtual void visit(::AST::ExprNode_Cast & v) override {
- m_rv.reset( new ::HIR::ExprNode_Cast(
+ m_rv.reset( new ::HIR::ExprNode_Cast( v.span(),
LowerHIR_ExprNode_Inner( *v.m_value ),
LowerHIR_Type(v.m_type)
) );
@@ -217,14 +217,14 @@ struct LowerHIR_ExprNode_Visitor:
args.push_back( LowerHIR_ExprNode_Inner(*arg) );
TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e,
- m_rv.reset( new ::HIR::ExprNode_CallValue(
- ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( e.name, v.m_path.binding().as_Variable().slot )),
+ m_rv.reset( new ::HIR::ExprNode_CallValue( v.span(),
+ ::HIR::ExprNodeP(new ::HIR::ExprNode_Variable( v.span(), e.name, v.m_path.binding().as_Variable().slot )),
mv$(args)
) );
)
else
{
- m_rv.reset( new ::HIR::ExprNode_CallPath(
+ m_rv.reset( new ::HIR::ExprNode_CallPath( v.span(),
LowerHIR_Path(Span(v.get_pos()), v.m_path),
mv$( args )
) );
@@ -240,7 +240,7 @@ struct LowerHIR_ExprNode_Visitor:
for(const auto& param : v.m_method.args().m_types)
params.m_types.push_back( LowerHIR_Type(param) );
- m_rv.reset( new ::HIR::ExprNode_CallMethod(
+ m_rv.reset( new ::HIR::ExprNode_CallMethod( v.span(),
LowerHIR_ExprNode_Inner(*v.m_val),
v.m_method.name(),
mv$(params),
@@ -252,7 +252,7 @@ struct LowerHIR_ExprNode_Visitor:
for(const auto& arg : v.m_args)
args.push_back( LowerHIR_ExprNode_Inner(*arg) );
- m_rv.reset( new ::HIR::ExprNode_CallValue(
+ m_rv.reset( new ::HIR::ExprNode_CallValue( v.span(),
LowerHIR_ExprNode_Inner(*v.m_val),
mv$(args)
) );
@@ -261,7 +261,7 @@ struct LowerHIR_ExprNode_Visitor:
switch( v.m_type )
{
case ::AST::ExprNode_Loop::LOOP:
- m_rv.reset( new ::HIR::ExprNode_Loop(
+ m_rv.reset( new ::HIR::ExprNode_Loop( v.span(),
v.m_label,
LowerHIR_ExprNode_Inner(*v.m_code)
) );
@@ -270,16 +270,16 @@ struct LowerHIR_ExprNode_Visitor:
case ::AST::ExprNode_Loop::WHILE: {
::std::vector< ::HIR::ExprNodeP> code;
// - if `m_cond` { () } else { break `m_label` }
- code.push_back( ::HIR::ExprNodeP(new ::HIR::ExprNode_If(
+ code.push_back( ::HIR::ExprNodeP(new ::HIR::ExprNode_If( v.span(),
LowerHIR_ExprNode_Inner(*v.m_cond),
- ::HIR::ExprNodeP( new ::HIR::ExprNode_Tuple({}) ),
- ::HIR::ExprNodeP( new ::HIR::ExprNode_LoopControl(v.m_label, false) )
+ ::HIR::ExprNodeP( new ::HIR::ExprNode_Tuple(v.span(), {}) ),
+ ::HIR::ExprNodeP( new ::HIR::ExprNode_LoopControl(v.span(), v.m_label, false) )
)) );
code.push_back( LowerHIR_ExprNode_Inner(*v.m_code) );
- m_rv.reset( new ::HIR::ExprNode_Loop(
+ m_rv.reset( new ::HIR::ExprNode_Loop( v.span(),
v.m_label,
- ::HIR::ExprNodeP(new ::HIR::ExprNode_Block(false, mv$(code)))
+ ::HIR::ExprNodeP(new ::HIR::ExprNode_Block( v.span(), false, mv$(code)))
) );
assert( m_rv->m_res_type.m_data.is_Tuple() );
break; }
@@ -296,12 +296,12 @@ struct LowerHIR_ExprNode_Visitor:
arms.push_back(::HIR::ExprNode_Match::Arm {
::make_vec1( ::HIR::Pattern() ),
::HIR::ExprNodeP(),
- ::HIR::ExprNodeP( new ::HIR::ExprNode_LoopControl(v.m_label, false) )
+ ::HIR::ExprNodeP( new ::HIR::ExprNode_LoopControl( v.span(), v.m_label, false) )
});
- m_rv.reset( new ::HIR::ExprNode_Loop(
+ m_rv.reset( new ::HIR::ExprNode_Loop( v.span(),
v.m_label,
- ::HIR::ExprNodeP(new ::HIR::ExprNode_Match(
+ ::HIR::ExprNodeP(new ::HIR::ExprNode_Match( v.span(),
LowerHIR_ExprNode_Inner(*v.m_cond),
mv$(arms)
))
@@ -385,13 +385,13 @@ struct LowerHIR_ExprNode_Visitor:
arms.push_back( mv$(new_arm) );
}
- m_rv.reset( new ::HIR::ExprNode_Match(
+ m_rv.reset( new ::HIR::ExprNode_Match( v.span(),
LowerHIR_ExprNode_Inner(*v.m_val),
mv$(arms)
));
}
virtual void visit(::AST::ExprNode_If& v) override {
- m_rv.reset( new ::HIR::ExprNode_If(
+ m_rv.reset( new ::HIR::ExprNode_If( v.span(),
LowerHIR_ExprNode_Inner(*v.m_cond),
LowerHIR_ExprNode_Inner(*v.m_true),
LowerHIR_ExprNode_Inner_Opt(&*v.m_false)
@@ -410,9 +410,9 @@ struct LowerHIR_ExprNode_Visitor:
arms.push_back(::HIR::ExprNode_Match::Arm {
::make_vec1( ::HIR::Pattern() ),
::HIR::ExprNodeP(),
- v.m_false ? LowerHIR_ExprNode_Inner(*v.m_false) : ::HIR::ExprNodeP( new ::HIR::ExprNode_Tuple({}) )
+ v.m_false ? LowerHIR_ExprNode_Inner(*v.m_false) : ::HIR::ExprNodeP(new ::HIR::ExprNode_Tuple(v.span(), {}))
});
- m_rv.reset( new ::HIR::ExprNode_Match(
+ m_rv.reset( new ::HIR::ExprNode_Match( v.span(),
LowerHIR_ExprNode_Inner(*v.m_value),
mv$(arms)
));
@@ -444,7 +444,7 @@ struct LowerHIR_ExprNode_Visitor:
}
}
};
- m_rv.reset( new ::HIR::ExprNode_Literal(
+ m_rv.reset( new ::HIR::ExprNode_Literal( v.span(),
::HIR::ExprNode_Literal::Data::make_Integer({
H::get_type( Span(v.get_pos()), v.m_datatype ),
v.m_value
@@ -461,19 +461,19 @@ struct LowerHIR_ExprNode_Visitor:
default:
BUG(v.get_pos(), "Unknown type for float literal");
}
- m_rv.reset( new ::HIR::ExprNode_Literal( ::HIR::ExprNode_Literal::Data::make_Float({
- ct, v.m_value
- }) ) );
+ m_rv.reset( new ::HIR::ExprNode_Literal( v.span(),
+ ::HIR::ExprNode_Literal::Data::make_Float({ ct, v.m_value })
+ ) );
}
virtual void visit(::AST::ExprNode_Bool& v) override {
- m_rv.reset( new ::HIR::ExprNode_Literal( ::HIR::ExprNode_Literal::Data::make_Boolean( v.m_value ) ) );
+ m_rv.reset( new ::HIR::ExprNode_Literal( v.span(), ::HIR::ExprNode_Literal::Data::make_Boolean( v.m_value ) ) );
}
virtual void visit(::AST::ExprNode_String& v) override {
- m_rv.reset( new ::HIR::ExprNode_Literal( ::HIR::ExprNode_Literal::Data::make_String( v.m_value ) ) );
+ m_rv.reset( new ::HIR::ExprNode_Literal( v.span(), ::HIR::ExprNode_Literal::Data::make_String( v.m_value ) ) );
}
virtual void visit(::AST::ExprNode_ByteString& v) override {
::std::vector<char> dat { v.m_value.begin(), v.m_value.end() };
- m_rv.reset( new ::HIR::ExprNode_Literal( ::HIR::ExprNode_Literal::Data::make_ByteString( mv$(dat) ) ) );
+ m_rv.reset( new ::HIR::ExprNode_Literal( v.span(), ::HIR::ExprNode_Literal::Data::make_ByteString( mv$(dat) ) ) );
}
virtual void visit(::AST::ExprNode_Closure& v) override {
::HIR::ExprNode_Closure::args_t args;
@@ -483,7 +483,7 @@ struct LowerHIR_ExprNode_Visitor:
LowerHIR_Type( arg.second )
) );
}
- m_rv.reset( new ::HIR::ExprNode_Closure(
+ m_rv.reset( new ::HIR::ExprNode_Closure( v.span(),
mv$(args),
LowerHIR_Type(v.m_return),
LowerHIR_ExprNode_Inner(*v.m_code)
@@ -493,7 +493,7 @@ struct LowerHIR_ExprNode_Visitor:
::HIR::ExprNode_StructLiteral::t_values values;
for(const auto& val : v.m_values)
values.push_back( ::std::make_pair(val.first, LowerHIR_ExprNode_Inner(*val.second)) );
- m_rv.reset( new ::HIR::ExprNode_StructLiteral(
+ m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(),
LowerHIR_GenericPath(v.get_pos(), v.m_path),
LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()),
mv$(values)
@@ -502,7 +502,7 @@ struct LowerHIR_ExprNode_Visitor:
virtual void visit(::AST::ExprNode_Array& v) override {
if( v.m_size )
{
- m_rv.reset( new ::HIR::ExprNode_ArraySized(
+ m_rv.reset( new ::HIR::ExprNode_ArraySized( v.span(),
LowerHIR_ExprNode_Inner( *v.m_values.at(0) ),
// TODO: Should this size be a full expression on its own?
LowerHIR_ExprNode_Inner( *v.m_size )
@@ -513,14 +513,14 @@ struct LowerHIR_ExprNode_Visitor:
::std::vector< ::HIR::ExprNodeP> vals;
for(const auto& val : v.m_values)
vals.push_back( LowerHIR_ExprNode_Inner(*val) );
- m_rv.reset( new ::HIR::ExprNode_ArrayList( mv$(vals) ) );
+ m_rv.reset( new ::HIR::ExprNode_ArrayList( v.span(), mv$(vals) ) );
}
}
virtual void visit(::AST::ExprNode_Tuple& v) override {
::std::vector< ::HIR::ExprNodeP> vals;
for(const auto& val : v.m_values)
vals.push_back( LowerHIR_ExprNode_Inner(*val ) );
- m_rv.reset( new ::HIR::ExprNode_Tuple( mv$(vals) ) );
+ m_rv.reset( new ::HIR::ExprNode_Tuple( v.span(), mv$(vals) ) );
}
virtual void visit(::AST::ExprNode_NamedValue& v) override {
TU_IFLET(::AST::Path::Class, v.m_path.m_class, Local, e,
@@ -528,27 +528,27 @@ struct LowerHIR_ExprNode_Visitor:
BUG(v.get_pos(), "Named value was a local, but wasn't bound - " << v.m_path);
}
auto slot = v.m_path.binding().as_Variable().slot;
- m_rv.reset( new ::HIR::ExprNode_Variable( e.name, slot ) );
+ m_rv.reset( new ::HIR::ExprNode_Variable( v.span(), e.name, slot ) );
)
else {
- m_rv.reset( new ::HIR::ExprNode_PathValue( LowerHIR_Path(Span(v.get_pos()), v.m_path) ) );
+ m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path) ) );
}
}
virtual void visit(::AST::ExprNode_Field& v) override {
- m_rv.reset( new ::HIR::ExprNode_Field(
+ m_rv.reset( new ::HIR::ExprNode_Field( v.span(),
LowerHIR_ExprNode_Inner(*v.m_obj),
v.m_name
));
}
virtual void visit(::AST::ExprNode_Index& v) override {
- m_rv.reset( new ::HIR::ExprNode_Index(
+ m_rv.reset( new ::HIR::ExprNode_Index( v.span(),
LowerHIR_ExprNode_Inner(*v.m_obj),
LowerHIR_ExprNode_Inner(*v.m_idx)
));
}
virtual void visit(::AST::ExprNode_Deref& v) override {
- m_rv.reset( new ::HIR::ExprNode_Deref(
+ m_rv.reset( new ::HIR::ExprNode_Deref( v.span(),
LowerHIR_ExprNode_Inner(*v.m_value)
));
}
diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp
index 14b0233a..295de1b0 100644
--- a/src/hir_conv/resolve_ufcs.cpp
+++ b/src/hir_conv/resolve_ufcs.cpp
@@ -16,9 +16,16 @@ namespace {
::std::vector< ::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > m_traits;
+ const ::HIR::GenericParams* m_impl_params;
+ const ::HIR::GenericParams* m_item_params;
+ const ::HIR::Trait* m_current_trait;
+
public:
Visitor(const ::HIR::Crate& crate):
- m_crate(crate)
+ m_crate(crate),
+ m_impl_params(nullptr),
+ m_item_params(nullptr),
+ m_current_trait(nullptr)
{}
void visit_module(::HIR::Module& mod) override
@@ -30,6 +37,18 @@ namespace {
m_traits.pop_back();
}
+ void visit_function(::HIR::Function& fcn) override {
+ m_item_params = &fcn.m_params;
+ ::HIR::Visitor::visit_function(fcn);
+ m_item_params = nullptr;
+ }
+ void visit_trait(::HIR::Trait& trait) override {
+ m_current_trait = &trait;
+ m_impl_params = &trait.m_params;
+ ::HIR::Visitor::visit_trait(trait);
+ m_impl_params = nullptr;
+ m_current_trait = nullptr;
+ }
void visit_expr(::HIR::ExprPtr& expr) override
{
@@ -91,86 +110,139 @@ namespace {
}
}
+ bool locate_trait_item_in_bounds(::HIR::Visitor::PathContext pc, const ::HIR::TypeRef& tr, const ::std::string& name, const ::HIR::GenericParams& params) {
+ DEBUG("TODO: Search for trait impl for " << tr << " with " << name << " in params");
+ return false;
+ }
+
void visit_path(::HIR::Path& p, ::HIR::Visitor::PathContext pc) override
{
+ DEBUG("p = " << p);
TU_IFLET(::HIR::Path::Data, p.m_data, UfcsUnknown, e,
DEBUG("UfcsUnknown - p=" << p);
- // 1. Search all impls of in-scope traits for this method on this type
- for( const auto& trait_info : m_traits )
- {
- const auto& trait_path = *trait_info.first;
- const auto& trait = *trait_info.second;
-
- switch( pc )
+
+ this->visit_type( *e.type );
+ this->visit_path_params( e.params );
+
+ // TODO: Search for matching impls in current generic blocks
+ if( m_item_params != nullptr && locate_trait_item_in_bounds(pc, *e.type, e.item, *m_item_params) ) {
+ return ;
+ }
+ if( m_impl_params != nullptr && locate_trait_item_in_bounds(pc, *e.type, e.item, *m_impl_params) ) {
+ return ;
+ }
+
+ TU_IFLET(::HIR::TypeRef::Data, e.type->m_data, Generic, te,
+ // If processing a trait, and the type is 'Self', search for the type/method on the trait
+ // - TODO: This could be encoded by a `Self: Trait` bound in the generics, but that may have knock-on issues?
+ if( te.name == "Self" && m_current_trait ) {
+ switch(pc)
+ {
+ case ::HIR::Visitor::PathContext::VALUE: {
+ auto it1 = m_current_trait->m_values.find( e.item );
+ if( it1 != m_current_trait->m_values.end() ) {
+ TODO(Span(), "Found in Self trait - need path to trait");
+ // TODO: What's the easiest way to get the path to this trait?
+ //auto new_data = ::HIR::Path::Data::make_UfcsKnown({ mv$(e.type), ::HIR::GenericPath(trait_path), mv$(e.item), mv$(e.params)} );
+ //p.m_data = mv$(new_data);
+ //DEBUG("- Resolved, replace with " << p);
+
+ return ;
+ }
+ } break;
+ case ::HIR::Visitor::PathContext::TRAIT:
+ break;
+ case ::HIR::Visitor::PathContext::TYPE: {
+ auto it1 = m_current_trait->m_types.find( e.item );
+ if( it1 != m_current_trait->m_types.end() ) {
+ TODO(Span(), "Found in Self trait - need path to trait");
+ return ;
+ }
+ } break;
+ }
+ }
+ ERROR(Span(), E0000, "Failed to find impl with '" << e.item << "' for " << *e.type);
+ return ;
+ )
+ else {
+ // 1. Search all impls of in-scope traits for this method on this type
+ for( const auto& trait_info : m_traits )
{
- case ::HIR::Visitor::PathContext::VALUE: {
- auto it1 = trait.m_values.find( e.item );
- if( it1 == trait.m_values.end() ) {
- continue ;
+ const auto& trait_path = *trait_info.first;
+ const auto& trait = *trait_info.second;
+
+ switch( pc )
+ {
+ case ::HIR::Visitor::PathContext::VALUE: {
+ auto it1 = trait.m_values.find( e.item );
+ if( it1 == trait.m_values.end() ) {
+ continue ;
+ }
+ // Found it, just keep going (don't care about details here)
+ } break;
+ case ::HIR::Visitor::PathContext::TRAIT:
+ case ::HIR::Visitor::PathContext::TYPE: {
+ auto it1 = trait.m_types.find( e.item );
+ if( it1 == trait.m_types.end() ) {
+ continue ;
+ }
+ // Found it, just keep going (don't care about details here)
+ } break;
}
- // Found it, just keep going (don't care about details here)
- } break;
- case ::HIR::Visitor::PathContext::TRAIT:
- case ::HIR::Visitor::PathContext::TYPE: {
- auto it1 = trait.m_types.find( e.item );
- if( it1 == trait.m_types.end() ) {
+
+ auto trait_impl_it = m_crate.m_trait_impls.equal_range( trait_path );
+ if( trait_impl_it.first == trait_impl_it.second ) {
continue ;
}
- // Found it, just keep going (don't care about details here)
- } break;
- }
-
- auto trait_impl_it = m_crate.m_trait_impls.equal_range( trait_path );
- if( trait_impl_it.first == trait_impl_it.second ) {
- continue ;
+ for( auto it = trait_impl_it.first; it != trait_impl_it.second; it ++ )
+ {
+ const auto& impl = it->second;
+ if( !impl.matches_type(*e.type) ) {
+ continue ;
+ }
+
+ auto new_data = ::HIR::Path::Data::make_UfcsKnown({ mv$(e.type), ::HIR::GenericPath(trait_path), mv$(e.item), mv$(e.params)} );
+ p.m_data = mv$(new_data);
+ DEBUG("- Resolved, replace with " << p);
+ return ;
+ }
}
- for( auto it = trait_impl_it.first; it != trait_impl_it.second; it ++ )
+
+ // 2. No trait matched, search for inherent impl
+ for( const auto& impl : m_crate.m_type_impls )
{
- const auto& impl = it->second;
if( !impl.matches_type(*e.type) ) {
continue ;
}
+ DEBUG("- matched impl " << *e.type);
+ // TODO: Search for item
+ switch( pc )
+ {
+ case ::HIR::Visitor::PathContext::VALUE: {
+ auto it1 = impl.m_methods.find( e.item );
+ if( it1 == impl.m_methods.end() ) {
+ continue ;
+ }
+ // Found it, just keep going (don't care about details here)
+ } break;
+ case ::HIR::Visitor::PathContext::TRAIT:
+ case ::HIR::Visitor::PathContext::TYPE:
+ continue ;
+ }
- auto new_data = ::HIR::Path::Data::make_UfcsKnown({ mv$(e.type), ::HIR::GenericPath(trait_path), mv$(e.item), mv$(e.params)} );
+ auto new_data = ::HIR::Path::Data::make_UfcsInherent({ mv$(e.type), mv$(e.item), mv$(e.params)} );
p.m_data = mv$(new_data);
DEBUG("- Resolved, replace with " << p);
return ;
}
}
- // 2. No trait matched, search for inherent impl
- for( const auto& impl : m_crate.m_type_impls )
- {
- if( !impl.matches_type(*e.type) ) {
- continue ;
- }
- DEBUG("- matched impl " << *e.type);
- // TODO: Search for item
- switch( pc )
- {
- case ::HIR::Visitor::PathContext::VALUE: {
- auto it1 = impl.m_methods.find( e.item );
- if( it1 == impl.m_methods.end() ) {
- continue ;
- }
- // Found it, just keep going (don't care about details here)
- } break;
- case ::HIR::Visitor::PathContext::TRAIT:
- case ::HIR::Visitor::PathContext::TYPE: {
- continue ;
- // Found it, just keep going (don't care about details here)
- } break;
- }
-
- auto new_data = ::HIR::Path::Data::make_UfcsInherent({ mv$(e.type), mv$(e.item), mv$(e.params)} );
- p.m_data = mv$(new_data);
- DEBUG("- Resolved, replace with " << p);
- return ;
- }
-
// Couldn't find it
DEBUG("Failed to find impl with '" << e.item << "' for " << *e.type);
)
+ else {
+ ::HIR::Visitor::visit_path(p, pc);
+ }
}
diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp
index 48a7a439..c2c2abb9 100644
--- a/src/hir_typeck/expr.cpp
+++ b/src/hir_typeck/expr.cpp
@@ -147,11 +147,27 @@ namespace {
{}
bool is_alias() const { return alias != ~0u; }
};
+ static const ::std::string EMPTY_STRING;
+ struct Variable
+ {
+ ::std::string name;
+ ::HIR::TypeRef type;
+
+ Variable()
+ {}
+ Variable(const ::std::string& name, ::HIR::TypeRef type):
+ name( name ),
+ type( mv$(type) )
+ {}
+ Variable(Variable&&) = default;
+
+ Variable& operator=(Variable&&) = default;
+ };
class TypecheckContext
{
- ::std::vector< ::HIR::TypeRef> m_locals;
- ::std::vector< IVar > m_ivars;
+ ::std::vector< Variable> m_locals;
+ ::std::vector< IVar> m_ivars;
bool m_has_changed;
public:
TypecheckContext():
@@ -175,7 +191,7 @@ namespace {
}
i = 0;
for(const auto& v : m_locals) {
- DEBUG("VAR " << i << " = " << v);
+ DEBUG("VAR " << i << " '"<<v.name<<"' = " << v.type);
i ++;
}
}
@@ -190,20 +206,20 @@ namespace {
}
/// Adds a local variable binding (type is mutable so it can be inferred if required)
- void add_local(unsigned int index, ::HIR::TypeRef type)
+ void add_local(unsigned int index, const ::std::string& name, ::HIR::TypeRef type)
{
if( m_locals.size() <= index )
m_locals.resize(index+1);
- m_locals[index] = mv$(type);
+ m_locals[index] = Variable(name, mv$(type));
}
- const ::HIR::TypeRef& get_var_type(unsigned int index)
+ const ::HIR::TypeRef& get_var_type(const Span& sp, unsigned int index)
{
if( index >= m_locals.size() ) {
this->dump();
- BUG(Span(), "Local index out of range " << index << " >= " << m_locals.size());
+ BUG(sp, "Local index out of range " << index << " >= " << m_locals.size());
}
- return m_locals.at(index);
+ return m_locals.at(index).type;
}
/// Add (and bind) all '_' types in `type`
@@ -262,13 +278,13 @@ namespace {
switch( pb.m_type )
{
case ::HIR::PatternBinding::Type::Move:
- this->add_local( pb.m_slot, mv$(type) );
+ this->add_local( pb.m_slot, pb.m_name, mv$(type) );
break;
case ::HIR::PatternBinding::Type::Ref:
- this->add_local( pb.m_slot, ::HIR::TypeRef::Data::make_Borrow( {::HIR::BorrowType::Shared, box$(mv$(type))} ) );
+ this->add_local( pb.m_slot, pb.m_name, ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, mv$(type)) );
break;
case ::HIR::PatternBinding::Type::MutRef:
- this->add_local( pb.m_slot, ::HIR::TypeRef::Data::make_Borrow( {::HIR::BorrowType::Unique, box$(mv$(type))} ) );
+ this->add_local( pb.m_slot, pb.m_name, ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Unique, mv$(type)) );
break;
}
}
@@ -370,7 +386,7 @@ namespace {
for(auto& sp : e.trailing)
this->add_binding( sp, *te.inner );
if( e.extra_bind.is_valid() ) {
- this->add_local( e.extra_bind.m_slot, type.clone() );
+ this->add_local( e.extra_bind.m_slot, e.extra_bind.m_name, type.clone() );
}
)
)
@@ -858,7 +874,21 @@ namespace {
}
),
(TraitObject,
- TODO(sp, "Recurse in apply_equality TraitObject - " << l_t << " and " << r_t);
+ if( l_e.m_traits.size() != r_e.m_traits.size() ) {
+ // TODO: Possibly allow inferrence reducing the set?
+ ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - trait counts differ");
+ }
+ // NOTE: Lifetime is ignored
+ // TODO: Is this list sorted for consistency?
+ for(unsigned int i = 0; i < l_e.m_traits.size(); i ++ )
+ {
+ auto& l_p = l_e.m_traits[i];
+ auto& r_p = r_e.m_traits[i];
+ if( l_p.m_path != r_p.m_path ) {
+ ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t);
+ }
+ // TODO: Equality of params
+ }
),
(Array,
this->apply_equality(sp, *l_e.inner, *r_e.inner);
@@ -896,7 +926,8 @@ namespace {
const auto& left_slice = l_e.inner->m_data.as_Slice();
TU_IFLET(::HIR::TypeRef::Data, r_e.inner->m_data, Array, right_array,
this->apply_equality(sp, *left_slice.inner, *right_array.inner);
- *node_ptr_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Unsize( mv$(*node_ptr_ptr), l_t.clone() ));
+ auto span = (**node_ptr_ptr).span();
+ *node_ptr_ptr = ::HIR::ExprNodeP(new ::HIR::ExprNode_Unsize( mv$(span), mv$(*node_ptr_ptr), l_t.clone() ));
(*node_ptr_ptr)->m_res_type = l_t.clone();
return ;
)
@@ -1073,9 +1104,10 @@ namespace {
void visit(::HIR::ExprNode_Match& node) override
{
- ::HIR::ExprVisitorDef::visit(node);
TRACE_FUNCTION_F("match ...");
+ this->context.add_ivars(node.m_value->m_res_type);
+
for(auto& arm : node.m_arms)
{
DEBUG("ARM " << arm.m_patterns);
@@ -1084,19 +1116,28 @@ namespace {
this->context.add_binding(pat, node.m_value->m_res_type);
}
}
+
+ ::HIR::ExprVisitorDef::visit(node);
}
void visit(::HIR::ExprNode_Tuple& node) override
{
- // - Remove the ivar created by the generic visitor
- this->context.dump();
- this->context.del_ivar( node.m_res_type.m_data.as_Infer().index );
+ // Only delete and apply if the return type is an ivar
+ // - Can happen with `match (a, b)`
+ TU_IFLET(::HIR::TypeRef::Data, node.m_res_type.m_data, Infer, e,
+ // - Remove the ivar created by the generic visitor
+ this->context.dump();
+ this->context.del_ivar( e.index );
+ )
::HIR::ExprVisitorDef::visit(node);
- ::std::vector< ::HIR::TypeRef> types;
- for( const auto& sn : node.m_vals )
- types.push_back( sn->m_res_type.clone() );
- node.m_res_type = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Tuple(mv$(types)) );
+ if( node.m_res_type.m_data.is_Infer() )
+ {
+ ::std::vector< ::HIR::TypeRef> types;
+ for( const auto& sn : node.m_vals )
+ types.push_back( sn->m_res_type.clone() );
+ node.m_res_type = ::HIR::TypeRef( ::HIR::TypeRef::Data::make_Tuple(mv$(types)) );
+ }
}
void visit(::HIR::ExprNode_Closure& node) override
{
@@ -1112,8 +1153,10 @@ namespace {
// - Variable: Bind to same ivar
void visit(::HIR::ExprNode_Variable& node) override
{
- this->context.del_ivar( node.m_res_type.m_data.as_Infer().index );
- node.m_res_type = this->context.get_var_type(node.m_slot).clone();
+ TU_IFLET(::HIR::TypeRef::Data, node.m_res_type.m_data, Infer, e,
+ this->context.del_ivar( e.index );
+ )
+ node.m_res_type = this->context.get_var_type(node.span(), node.m_slot).clone();
}
};
@@ -1177,6 +1220,7 @@ namespace {
// - Assign: both sides equal
void visit(::HIR::ExprNode_Assign& node) override
{
+ TRACE_FUNCTION_F("... = ...");
if( node.m_op == ::HIR::ExprNode_Assign::Op::None ) {
this->context.apply_equality(node.span(),
node.m_slot->m_res_type, node.m_value->m_res_type,
@@ -1242,8 +1286,9 @@ namespace {
void visit(::HIR::ExprNode_Variable& node) override
{
// TODO: How to apply deref coercions here?
+ TRACE_FUNCTION_F("var #"<<node.m_slot<<" '"<<node.m_name<<"'");
this->context.apply_equality(node.span(),
- node.m_res_type, this->context.get_var_type(node.m_slot)
+ node.m_res_type, this->context.get_var_type(node.span(), node.m_slot)
);
}
// - Struct literal: Semi-known types
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index 86d35ca7..95eef7fa 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -56,7 +56,7 @@ struct Context
Context(const ::AST::Crate& crate, const ::AST::Module& mod):
m_crate(crate),
m_mod(mod),
- m_var_count(0),
+ m_var_count(~0u),
m_block_level(0),
m_frozen_bind_set( false )
{}
@@ -96,6 +96,28 @@ struct Context
m_name_context.pop_back();
}
+ class RootBlockScope {
+ friend class Context;
+ Context& ctxt;
+ unsigned int old_varcount;
+ RootBlockScope(Context& ctxt, unsigned int val):
+ ctxt(ctxt),
+ old_varcount(ctxt.m_var_count)
+ {
+ ctxt.m_var_count = val;
+ }
+ public:
+ ~RootBlockScope() {
+ ctxt.m_var_count = old_varcount;
+ }
+ };
+ RootBlockScope enter_rootblock() {
+ return RootBlockScope(*this, 0);
+ }
+ RootBlockScope clear_rootblock() {
+ return RootBlockScope(*this, ~0u);
+ }
+
void push_self(const TypeRef& tr) {
m_name_context.push_back( Ent::make_ConcreteSelf(&tr) );
}
@@ -131,6 +153,9 @@ struct Context
m_block_level += 1;
}
unsigned int push_var(const Span& sp, const ::std::string& name) {
+ if( m_var_count == ~0u ) {
+ BUG(sp, "Assigning local when there's no variable context");
+ }
// TODO: Handle avoiding duplicate bindings in a pattern
if( m_frozen_bind_set )
{
@@ -155,6 +180,7 @@ struct Context
}
m_name_context.back().as_VarBlock().variables.push_back( Named<unsigned int> { name, m_var_count } );
m_var_count += 1;
+ assert( m_var_count >= m_name_context.back().as_VarBlock().variables.size() );
return m_var_count - 1;
}
}
@@ -428,7 +454,7 @@ struct Context
void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context::LookupMode mode, ::AST::Path& path);
void Resolve_Absolute_Type(Context& context, TypeRef& type);
void Resolve_Absolute_Expr(Context& context, ::AST::Expr& expr);
-void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node);
+void Resolve_Absolute_ExprNode(Context& context, ::AST::ExprNode& node);
void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pattern& pat);
void Resolve_Absolute_Mod(const ::AST::Crate& crate, ::AST::Module& mod);
void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod );
@@ -695,7 +721,7 @@ void Resolve_Absolute_Path(/*const*/ Context& context, const Span& sp, Context::
if( e.nodes.size() > 1 )
{
if( p.m_class.is_Local() ) {
- p = ::AST::Path( ::AST::Path::TagUfcs(), TypeRef(sp, mv$(p)) );
+ p = ::AST::Path( ::AST::Path::TagUfcs(), TypeRef(sp, mv$(p)), ::AST::Path() );
}
if( ! e.nodes[0].args().is_empty() )
{
@@ -830,8 +856,8 @@ void Resolve_Absolute_Type(Context& context, TypeRef& type)
(Array,
Resolve_Absolute_Type(context, *e.inner);
if( e.size ) {
- // TODO: Prevent variables from being picked as the array size
- Resolve_Absolute_Expr(context, *e.size);
+ auto _h = context.enter_rootblock();
+ Resolve_Absolute_ExprNode(context, *e.size);
}
),
(Generic,
@@ -871,15 +897,13 @@ void Resolve_Absolute_Expr(Context& context, ::AST::Expr& expr)
{
if( expr.is_valid() )
{
- auto ov = context.m_var_count;
- context.m_var_count = 0;
- Resolve_Absolute_Expr(context, expr.node());
- context.m_var_count = ov;
+ Resolve_Absolute_ExprNode(context, expr.node());
}
}
-void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node)
+void Resolve_Absolute_ExprNode(Context& context, ::AST::ExprNode& node)
{
TRACE_FUNCTION_F("");
+
struct NV:
public AST::NodeVisitorDef
{
@@ -893,6 +917,7 @@ void Resolve_Absolute_Expr(Context& context, ::AST::ExprNode& node)
void visit(AST::ExprNode_Block& node) override {
DEBUG("ExprNode_Block");
if( node.m_local_mod ) {
+ auto _h = context.clear_rootblock();
this->context.push( *node.m_local_mod );
// Clone just the module stack part of the current context
@@ -1068,7 +1093,6 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa
if( pat.binding().is_valid() ) {
if( !pat.data().is_Any() && ! allow_refutable )
TODO(pat.span(), "Resolve_Absolute_Pattern - Encountered bound destructuring pattern");
- // TODO: Record the local variable number in the binding
pat.binding().m_slot = context.push_var( pat.span(), pat.binding().m_name );
DEBUG("- Binding #" << pat.binding().m_slot << " '" << pat.binding().m_name << "'");
}
@@ -1086,7 +1110,6 @@ void Resolve_Absolute_Pattern(Context& context, bool allow_refutable, ::AST::Pa
}
else {
pat = ::AST::Pattern(::AST::Pattern::TagBind(), mv$(name));
- // TODO: Record the local variable number in the binding
pat.binding().m_slot = context.push_var( pat.span(), pat.binding().m_name );
DEBUG("- Binding #" << pat.binding().m_slot << " '" << pat.binding().m_name << "' (was MaybeBind)");
}
@@ -1176,15 +1199,18 @@ void Resolve_Absolute_ImplItems(Context& item_context, ::AST::NamedList< ::AST:
for(auto& arg : e.args())
Resolve_Absolute_Type( item_context, arg.second );
- item_context.push_block();
- for(auto& arg : e.args()) {
- Resolve_Absolute_Pattern( item_context, false, arg.first );
+ {
+ auto _h = item_context.enter_rootblock();
+ item_context.push_block();
+ for(auto& arg : e.args()) {
+ Resolve_Absolute_Pattern( item_context, false, arg.first );
+ }
+
+ Resolve_Absolute_Expr( item_context, e.code() );
+
+ item_context.pop_block();
}
- Resolve_Absolute_Expr( item_context, e.code() );
-
- item_context.pop_block();
-
item_context.pop( e.params() );
),
(Static,
@@ -1223,6 +1249,7 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod )
{
TU_MATCH(::AST::EnumVariantData, (variant.m_data), (s),
(Value,
+ auto _h = item_context.enter_rootblock();
Resolve_Absolute_Expr(item_context, s.m_value);
),
(Tuple,
@@ -1297,20 +1324,24 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod )
for(auto& arg : e.args())
Resolve_Absolute_Type( item_context, arg.second );
- item_context.push_block();
- for(auto& arg : e.args()) {
- Resolve_Absolute_Pattern( item_context, false, arg.first );
+ {
+ auto _h = item_context.enter_rootblock();
+ item_context.push_block();
+ for(auto& arg : e.args()) {
+ Resolve_Absolute_Pattern( item_context, false, arg.first );
+ }
+
+ Resolve_Absolute_Expr( item_context, e.code() );
+
+ item_context.pop_block();
}
- Resolve_Absolute_Expr( item_context, e.code() );
-
- item_context.pop_block();
-
item_context.pop( e.params() );
),
(Static,
DEBUG("Static - " << i.name);
Resolve_Absolute_Type( item_context, e.type() );
+ auto _h = item_context.enter_rootblock();
Resolve_Absolute_Expr( item_context, e.value() );
)
)