diff options
author | John Hodge <tpg@mutabah.net> | 2016-06-11 00:06:50 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-06-11 00:06:50 +0800 |
commit | 436dad1104d40270d6b6a805b412d4603f27249c (patch) | |
tree | c77dc5dd11ca268e933945c8685030e110e43fa9 | |
parent | 44e187830d542acaf280f5139c8dc25e3c9fb72c (diff) | |
download | mrust-436dad1104d40270d6b6a805b412d4603f27249c.tar.gz |
HIR Typecheck - Constants
-rw-r--r-- | src/ast/path.hpp | 2 | ||||
-rw-r--r-- | src/hir/expr.cpp | 1 | ||||
-rw-r--r-- | src/hir/expr.hpp | 29 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 25 | ||||
-rw-r--r-- | src/hir/hir.hpp | 18 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 3 | ||||
-rw-r--r-- | src/hir_typeck/expr.cpp | 47 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 8 |
8 files changed, 126 insertions, 7 deletions
diff --git a/src/ast/path.hpp b/src/ast/path.hpp index c31f4bc0..efd367b1 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -61,7 +61,7 @@ TAGGED_UNION_EX(PathBinding, (), Unbound, ( ::std::string name; }), (TraitMethod, struct { - const Trait* struct_; + const Trait* trait_; ::std::string name; }), diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index 00953c5d..31493a3d 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -95,6 +95,7 @@ DEF_VISIT(ExprNode_Field, node, ) DEF_VISIT(ExprNode_Literal, , ) +DEF_VISIT(ExprNode_UnitVariant, , ) DEF_VISIT(ExprNode_PathValue, , ) DEF_VISIT(ExprNode_Variable, , ) DEF_VISIT(ExprNode_StructLiteral, node, diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index b2ee623e..8c9d89c2 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -465,14 +465,37 @@ struct ExprNode_Literal: NODE_METHODS(); }; +struct ExprNode_UnitVariant: + public ExprNode +{ + // Path to variant/struct + ::HIR::GenericPath m_path; + bool m_is_struct; + + ExprNode_UnitVariant(Span sp, ::HIR::GenericPath path, bool is_struct): + ExprNode(mv$(sp)), + m_path( mv$(path) ), + m_is_struct( is_struct ) + {} + + NODE_METHODS(); +}; struct ExprNode_PathValue: public ExprNode { + enum Target { + UNKNOWN, + FUNCTION, + STATIC, + CONSTANT, + }; ::HIR::Path m_path; + Target m_target; - ExprNode_PathValue(Span sp, ::HIR::Path path): + ExprNode_PathValue(Span sp, ::HIR::Path path, Target target): ExprNode(mv$(sp)), - m_path( mv$(path) ) + m_path( mv$(path) ), + m_target( target ) {} NODE_METHODS(); @@ -611,6 +634,7 @@ public: NV(ExprNode_Field); NV(ExprNode_Literal); + NV(ExprNode_UnitVariant); NV(ExprNode_PathValue); NV(ExprNode_Variable); @@ -652,6 +676,7 @@ public: NV(ExprNode_Field); NV(ExprNode_Literal); + NV(ExprNode_UnitVariant); NV(ExprNode_PathValue); NV(ExprNode_Variable); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 742a4fed..1dcbf261 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -126,7 +126,7 @@ struct LowerHIR_ExprNode_Visitor: m_rv.reset( new ::HIR::ExprNode_StructLiteral(v.span(), mv$(path_RangeTo), nullptr, mv$(values)) ); } else { - m_rv.reset( new ::HIR::ExprNode_PathValue(v.span(), mv$(path_RangeFull)) ); + m_rv.reset( new ::HIR::ExprNode_UnitVariant(v.span(), mv$(path_RangeFull), true) ); } } break; } @@ -547,7 +547,28 @@ struct LowerHIR_ExprNode_Visitor: m_rv.reset( new ::HIR::ExprNode_Variable( v.span(), e.name, slot ) ); ) else { - m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path) ) ); + TU_MATCH_DEF(::AST::PathBinding, (v.m_path.binding()), (e), + ( + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::UNKNOWN ) ); + ), + (Struct, + m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(Span(v.get_pos()), v.m_path), true ) ); + ), + (EnumVar, + m_rv.reset( new ::HIR::ExprNode_UnitVariant( v.span(), LowerHIR_GenericPath(Span(v.get_pos()), v.m_path), false ) ); + ), + (Function, + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::FUNCTION ) ); + ), + (Static, + if( e.static_->s_class() != ::AST::Static::CONST ) { + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::STATIC ) ); + } + else { + m_rv.reset( new ::HIR::ExprNode_PathValue( v.span(), LowerHIR_Path(Span(v.get_pos()), v.m_path), ::HIR::ExprNode_PathValue::CONSTANT ) ); + } + ) + ) } } diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index a938579a..1b0b091f 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -275,6 +275,24 @@ public: const ::HIR::ValueItem& get_valitem_by_path(const Span& sp, const ::HIR::SimplePath& path) const; const ::HIR::Function& get_function_by_path(const Span& sp, const ::HIR::SimplePath& path) const; + const ::HIR::Static& get_static_by_path(const Span& sp, const ::HIR::SimplePath& path) const { + const auto& ti = this->get_valitem_by_path(sp, path); + TU_IFLET(::HIR::ValueItem, ti, Static, e, + return e; + ) + else { + BUG(sp, "`static` path " << path << " didn't point to an enum"); + } + } + const ::HIR::Constant& get_constant_by_path(const Span& sp, const ::HIR::SimplePath& path) const { + const auto& ti = this->get_valitem_by_path(sp, path); + TU_IFLET(::HIR::ValueItem, ti, Constant, e, + return e; + ) + else { + BUG(sp, "`const` path " << path << " didn't point to an enum"); + } + } bool find_trait_impls(const ::HIR::SimplePath& path, const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TraitImpl&)> callback) const; bool find_type_impls(const ::HIR::TypeRef& type, t_cb_resolve_type ty_res, ::std::function<bool(const ::HIR::TypeImpl&)> callback) const; diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index c9fcaf0a..fe1c46ca 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -418,6 +418,9 @@ namespace { ) ) } + void visit(::HIR::ExprNode_UnitVariant& node) override { + TODO(node.span(), "Unit varant/struct constructors in constant context"); + } void visit(::HIR::ExprNode_PathValue& node) override { const auto& c = get_constant(node.span(), m_crate, node.m_path); if( c.m_value_res.is_Invalid() ) { diff --git a/src/hir_typeck/expr.cpp b/src/hir_typeck/expr.cpp index d677dfea..b9420c70 100644 --- a/src/hir_typeck/expr.cpp +++ b/src/hir_typeck/expr.cpp @@ -784,6 +784,12 @@ namespace typeck { } ) else { + TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Infer, e, + if( e.ty_class == ::HIR::InferClass::Integer ) { + this->context.apply_equality(node.span(), node.m_res_type, ty); + break; + } + ) // TODO: Search for an implementation of ops::Not } break; @@ -802,6 +808,12 @@ namespace typeck { } ) else { + TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Infer, e, + if( e.ty_class == ::HIR::InferClass::Integer || e.ty_class == ::HIR::InferClass::Float ) { + this->context.apply_equality(node.span(), node.m_res_type, ty); + break; + } + ) // TODO: Search for an implementation of ops::Neg } break; @@ -1376,6 +1388,41 @@ namespace typeck { // - PathValue: Insert type from path void visit(::HIR::ExprNode_PathValue& node) override { + const auto& sp = node.span(); + TU_MATCH(::HIR::Path::Data, (node.m_path.m_data), (e), + (Generic, + switch(node.m_target) { + case ::HIR::ExprNode_PathValue::UNKNOWN: + BUG(sp, "Unknown target PathValue encountered with Generic path"); + case ::HIR::ExprNode_PathValue::FUNCTION: { + //const auto& f = this->context.m_crate.get_fcn_by_path(sp, e.m_path); + } break; + case ::HIR::ExprNode_PathValue::STATIC: { + const auto& v = this->context.m_crate.get_static_by_path(sp, e.m_path); + DEBUG("static v.m_type = " << v.m_type); + this->context.apply_equality(sp, node.m_res_type, v.m_type); + } break; + case ::HIR::ExprNode_PathValue::CONSTANT: { + const auto& v = this->context.m_crate.get_constant_by_path(sp, e.m_path); + DEBUG("const"<<v.m_params.fmt_args()<<" v.m_type = " << v.m_type); + if( v.m_params.m_types.size() > 0 ) { + TODO(sp, "Support generic constants in typeck"); + } + this->context.apply_equality(sp, node.m_res_type, v.m_type); + } break; + } + DEBUG("TODO: Get type for constant/static - " << e); + ), + (UfcsUnknown, + BUG(sp, "Encountered UfcsUnknown"); + ), + (UfcsKnown, + TODO(sp, "Look up associated constants/statics (trait)"); + ), + (UfcsInherent, + TODO(sp, "Look up associated constants/statics (inherent)"); + ) + ) ::HIR::ExprVisitorDef::visit(node); } // - Variable: Bind to same ivar diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 393120b9..4bb3c51d 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -534,7 +534,7 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L for( const auto& item : tr.items() ) { if( item.name != node.name() ) { - break; + continue; } TU_MATCH_DEF(::AST::Item, (item.data), (e), ( @@ -551,12 +551,16 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L for( const auto& item : tr.items() ) { if( item.name != node.name() ) { - break; + continue; } TU_MATCH_DEF(::AST::Item, (item.data), (e), ( // TODO: Error ), + (Function, + // Bind as trait method + path.bind_function(e); + ), (Static, // Resolve to asociated type ) |