summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-09-01 18:52:13 +0800
committerJohn Hodge <tpg@mutabah.net>2016-09-01 18:52:13 +0800
commit33d88d4c4605b6871d421c9ea618121c297e10d8 (patch)
tree930dade49d1b971eb9a030ffe42abae9cb9a896d
parentc0c918cedadb414e7416023841b54f9984e19b90 (diff)
downloadmrust-33d88d4c4605b6871d421c9ea618121c297e10d8.tar.gz
HIR Const Eval - Restructure item lookup to make handling fn pointers easier
-rw-r--r--src/hir_conv/constant_evaluation.cpp139
1 files changed, 78 insertions, 61 deletions
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 0057f42b..335578d0 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -41,12 +41,17 @@ namespace {
throw "";
}
- enum class EntType {
- Function,
- Constant,
- Struct,
+ TAGGED_UNION(EntPtr, Function,
+ (NotFound, struct{}),
+ (Function, const ::HIR::Function*),
+ (Constant, const ::HIR::Constant*),
+ (Struct, const ::HIR::Struct*)
+ );
+ enum class EntNS {
+ Type,
+ Value
};
- const void* get_ent_simplepath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path, EntType et)
+ EntPtr get_ent_simplepath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path, EntNS ns)
{
const ::HIR::Module* mod;
if( path.m_crate_name != "" ) {
@@ -74,78 +79,84 @@ namespace {
)
}
- switch( et )
+ switch( ns )
{
- case EntType::Function: {
+ case EntNS::Value: {
auto it = mod->m_value_items.find( path.m_components.back() );
if( it == mod->m_value_items.end() ) {
- return nullptr;
+ return EntPtr {};
}
- TU_IFLET( ::HIR::ValueItem, it->second->ent, Function, e,
- return &e;
- )
- else {
- BUG(sp, "Path " << path << " didn't point to a functon");
- }
- } break;
- case EntType::Constant: {
- auto it = mod->m_value_items.find( path.m_components.back() );
- if( it == mod->m_value_items.end() ) {
- return nullptr;
- }
-
- TU_IFLET( ::HIR::ValueItem, it->second->ent, Constant, e,
- return &e;
+ TU_MATCH( ::HIR::ValueItem, (it->second->ent), (e),
+ (Import,
+ ),
+ (StructConstant,
+ ),
+ (StructConstructor,
+ ),
+ (Function,
+ return EntPtr { &e };
+ ),
+ (Constant,
+ return EntPtr { &e };
+ ),
+ (Static,
+ )
)
- else {
- BUG(sp, "Path " << path << " didn't point to a functon");
- }
+ BUG(sp, "Path " << path << " pointed to a invalid item - " << it->second->ent.tag_str());
} break;
- case EntType::Struct: {
+ case EntNS::Type: {
auto it = mod->m_mod_items.find( path.m_components.back() );
if( it == mod->m_mod_items.end() ) {
- return nullptr;
+ return EntPtr {};
}
- TU_IFLET( ::HIR::TypeItem, it->second->ent, Struct, e,
+ TU_MATCH( ::HIR::TypeItem, (it->second->ent), (e),
+ (Import,
+ ),
+ (Module,
+ ),
+ (Trait,
+ ),
+ (Struct,
return &e;
+ ),
+ (Enum,
+ ),
+ (TypeAlias,
+ )
)
- else {
- BUG(sp, "Path " << path << " didn't point to a struct");
- }
+ BUG(sp, "Path " << path << " pointed to an invalid item - " << it->second->ent.tag_str());
} break;
}
throw "";
}
- const void* get_ent_fullpath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path, EntType et)
+ EntPtr get_ent_fullpath(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path, EntNS ns)
{
TU_MATCH(::HIR::Path::Data, (path.m_data), (e),
(Generic,
- return get_ent_simplepath(sp, crate, e.m_path, et);
+ return get_ent_simplepath(sp, crate, e.m_path, ns);
),
(UfcsInherent,
// Easy (ish)
- for( const auto& impl : crate.m_type_impls )
- {
- if( ! impl.matches_type(*e.type) ) {
- continue ;
- }
- switch( et )
+ EntPtr rv {};
+ crate.find_type_impls(*e.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) {
+ switch( ns )
{
- case EntType::Function: {
+ case EntNS::Value: {
auto fit = impl.m_methods.find(e.item);
- if( fit == impl.m_methods.end() )
- continue ;
- return &fit->second.data;
+ if( fit != impl.m_methods.end() )
+ {
+ rv = EntPtr { &fit->second.data };
+ return true;
+ }
} break;
- case EntType::Struct:
- break;
- case EntType::Constant:
+ case EntNS::Type:
break;
}
- }
- return nullptr;
+ return false;
+ });
+ return rv;
),
(UfcsKnown,
TODO(sp, "get_ent_fullpath(path = " << path << ")");
@@ -159,27 +170,33 @@ namespace {
}
const ::HIR::Function& get_function(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path)
{
- auto* rv_p = reinterpret_cast<const ::HIR::Function*>( get_ent_fullpath(sp, crate, path, EntType::Function) );
- if( !rv_p ) {
- TODO(sp, "get_function(path = " << path << ")");
+ auto rv = get_ent_fullpath(sp, crate, path, EntNS::Value);
+ TU_IFLET( EntPtr, rv, Function, e,
+ return *e;
+ )
+ else {
+ TODO(sp, "Could not find function for " << path << " - " << rv.tag_str());
}
- return *rv_p;
}
const ::HIR::Struct& get_struct(const Span& sp, const ::HIR::Crate& crate, const ::HIR::SimplePath& path)
{
- auto rv_p = reinterpret_cast<const ::HIR::Struct*>( get_ent_simplepath(sp, crate, path, EntType::Struct) );
- if( !rv_p ) {
- BUG(sp, "Could not find struct name in " << path);
+ auto rv = get_ent_fullpath(sp, crate, path, EntNS::Type);
+ TU_IFLET( EntPtr, rv, Struct, e,
+ return *e;
+ )
+ else {
+ TODO(sp, "Could not find struct for " << path << " - " << rv.tag_str());
}
- return *rv_p;
}
const ::HIR::Constant& get_constant(const Span& sp, const ::HIR::Crate& crate, const ::HIR::Path& path)
{
- auto rv_p = reinterpret_cast<const ::HIR::Constant*>( get_ent_fullpath(sp, crate, path, EntType::Constant) );
- if( !rv_p ) {
- BUG(sp, "Could not find constant in " << path);
+ auto rv = get_ent_fullpath(sp, crate, path, EntNS::Value);
+ TU_IFLET( EntPtr, rv, Constant, e,
+ return *e;
+ )
+ else {
+ TODO(sp, "Could not find const for " << path << " - " << rv.tag_str());
}
- return *rv_p;
}
::HIR::Literal evaluate_constant(const ::HIR::Crate& crate, t_new_values& newval_output, const ::HIR::ItemPath& mod_path, ::std::string prefix, const ::HIR::ExprNode& expr)