summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-06-11 00:06:50 +0800
committerJohn Hodge <tpg@mutabah.net>2016-06-11 00:06:50 +0800
commit436dad1104d40270d6b6a805b412d4603f27249c (patch)
treec77dc5dd11ca268e933945c8685030e110e43fa9
parent44e187830d542acaf280f5139c8dc25e3c9fb72c (diff)
downloadmrust-436dad1104d40270d6b6a805b412d4603f27249c.tar.gz
HIR Typecheck - Constants
-rw-r--r--src/ast/path.hpp2
-rw-r--r--src/hir/expr.cpp1
-rw-r--r--src/hir/expr.hpp29
-rw-r--r--src/hir/from_ast_expr.cpp25
-rw-r--r--src/hir/hir.hpp18
-rw-r--r--src/hir_conv/constant_evaluation.cpp3
-rw-r--r--src/hir_typeck/expr.cpp47
-rw-r--r--src/resolve/absolute.cpp8
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
)