diff options
author | John Hodge <tpg@mutabah.net> | 2016-11-25 14:49:55 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-11-25 14:49:55 +0800 |
commit | 6ceb82723d6594d96a1308aa16f9ec863246935d (patch) | |
tree | 5eb6541a066d8022b00e85958203294022c99814 | |
parent | 7b0dfc5a859d8fb2cc940764d0c8106c87b5f05b (diff) | |
download | mrust-6ceb82723d6594d96a1308aa16f9ec863246935d.tar.gz |
HIR - Shift markings to their own pass, store in crate metadata.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/hir/deserialise.cpp | 35 | ||||
-rw-r--r-- | src/hir/hir.hpp | 2 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 31 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 44 | ||||
-rw-r--r-- | src/hir_conv/main_bindings.hpp | 3 | ||||
-rw-r--r-- | src/hir_conv/markings.cpp | 85 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 36 | ||||
-rw-r--r-- | src/main.cpp | 4 |
9 files changed, 185 insertions, 57 deletions
@@ -81,7 +81,7 @@ OBJ += hir/hir.o hir/generic_params.o OBJ += hir/crate_ptr.o hir/type_ptr.o hir/expr_ptr.o OBJ += hir/type.o hir/path.o hir/expr.o hir/pattern.o OBJ += hir/visitor.o hir/crate_post_load.o -OBJ += hir_conv/expand_type.o hir_conv/constant_evaluation.o hir_conv/resolve_ufcs.o hir_conv/bind.o +OBJ += hir_conv/expand_type.o hir_conv/constant_evaluation.o hir_conv/resolve_ufcs.o hir_conv/bind.o hir_conv/markings.o OBJ += hir_typeck/outer.o hir_typeck/common.o hir_typeck/helpers.o hir_typeck/static.o hir_typeck/impl_ref.o OBJ += hir_typeck/expr_visit.o OBJ += hir_typeck/expr_cs.o diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index fffff7fa..1880b660 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -510,6 +510,22 @@ namespace { deserialise_type() }; } + ::HIR::TraitMarkings deserialise_markings() + { + ::HIR::TraitMarkings m; + uint8_t bitflag_1 = m_in.read_u8(); + #define BIT(i,fld) fld = (bitflag_1 & (1 << (i))) != 0; + BIT(0, m.can_coerce) + BIT(1, m.can_unsize) + BIT(2, m.has_a_deref) + BIT(3, m.is_always_unsized) + BIT(4, m.is_always_sized) + BIT(5, m.is_copy) + #undef BIT + // TODO: auto_impls + return m; + } + ::HIR::Enum deserialise_enum(); ::HIR::Enum::Variant deserialise_enumvariant(); @@ -751,14 +767,15 @@ namespace { throw ""; } } - + ::HIR::Enum HirDeserialiser::deserialise_enum() { TRACE_FUNCTION; return ::HIR::Enum { deserialise_genericparams(), static_cast< ::HIR::Enum::Repr>(m_in.read_tag()), - deserialise_vec< ::std::pair< ::std::string, ::HIR::Enum::Variant> >() + deserialise_vec< ::std::pair< ::std::string, ::HIR::Enum::Variant> >(), + deserialise_markings() }; } ::HIR::Enum::Variant HirDeserialiser::deserialise_enumvariant() @@ -785,10 +802,11 @@ namespace { TRACE_FUNCTION; auto params = deserialise_genericparams(); auto repr = static_cast< ::HIR::Union::Repr>( m_in.read_tag() ); + auto variants = deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >(); + auto markings = deserialise_markings(); return ::HIR::Union { - mv$(params), repr, - deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() + mv$(params), repr, mv$(variants), mv$(markings) }; } ::HIR::Struct HirDeserialiser::deserialise_struct() @@ -804,19 +822,22 @@ namespace { DEBUG("Unit"); return ::HIR::Struct { mv$(params), repr, - ::HIR::Struct::Data::make_Unit( {} ) + ::HIR::Struct::Data::make_Unit( {} ), + deserialise_markings() }; case ::HIR::Struct::Data::TAG_Tuple: DEBUG("Tuple"); return ::HIR::Struct { mv$(params), repr, - ::HIR::Struct::Data( deserialise_vec< ::HIR::VisEnt< ::HIR::TypeRef> >() ) + ::HIR::Struct::Data( deserialise_vec< ::HIR::VisEnt< ::HIR::TypeRef> >() ), + deserialise_markings() }; case ::HIR::Struct::Data::TAG_Named: DEBUG("Named"); return ::HIR::Struct { mv$(params), repr, - ::HIR::Struct::Data( deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() ) + ::HIR::Struct::Data( deserialise_vec< ::std::pair< ::std::string, ::HIR::VisEnt< ::HIR::TypeRef> > >() ), + deserialise_markings() }; default: throw ""; diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index d5f04fd3..6843e93d 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -135,6 +135,8 @@ struct TraitMarkings { /// There is at least one CoerceUnsized impl for this type bool can_coerce = false; + /// There is at least one CoerceUnsized impl for this type + bool can_unsize = false; /// Indicates that there is at least one Deref impl bool has_a_deref = false; diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index dd68a792..bf28a53f 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -727,11 +727,14 @@ namespace { serialise_generics(ta.m_params); serialise_type(ta.m_type); } - void serialise(const ::HIR::Enum& ta) + void serialise(const ::HIR::Enum& item) { - serialise_generics(ta.m_params); - m_out.write_tag( static_cast<int>(ta.m_repr) ); - serialise_vec( ta.m_variants ); + serialise_generics(item.m_params); + m_out.write_tag( static_cast<int>(item.m_repr) ); + + serialise_vec( item.m_variants ); + + serialise(item.m_markings); } void serialise(const ::HIR::Enum::Variant& v) { @@ -751,6 +754,21 @@ namespace { ) ) } + + void serialise(const ::HIR::TraitMarkings& m) + { + uint8_t bitflag_1 = 0; + #define BIT(i,fld) if(fld) bitflag_1 |= 1 << (i); + BIT(0, m.can_coerce) + BIT(1, m.can_unsize) + BIT(2, m.has_a_deref) + BIT(3, m.is_always_unsized) + BIT(4, m.is_always_sized) + BIT(5, m.is_copy) + #undef BIT + m_out.write_u8(bitflag_1); + // TODO: auto_impls + } void serialise(const ::HIR::Struct& item) { @@ -770,6 +788,8 @@ namespace { serialise_vec(e); ) ) + + serialise(item.m_markings); } void serialise(const ::HIR::Union& item) { @@ -777,7 +797,10 @@ namespace { serialise_generics(item.m_params); m_out.write_tag( static_cast<int>(item.m_repr) ); + serialise_vec(item.m_variants); + + serialise(item.m_markings); } void serialise(const ::HIR::Trait& item) { diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 7a1049e6..d88a9fbb 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -131,14 +131,10 @@ namespace { public ::HIR::Visitor { const ::HIR::Crate& m_crate; - const ::HIR::SimplePath& m_lang_CoerceUnsized; - const ::HIR::SimplePath& m_lang_Deref; public: Visitor(const ::HIR::Crate& crate): - m_crate(crate), - m_lang_CoerceUnsized(m_crate.get_lang_item_path_opt("coerce_unsized")), - m_lang_Deref(m_crate.get_lang_item_path_opt("coerce_unsized")) + m_crate(crate) {} void visit_trait_path(::HIR::TraitPath& p) override @@ -487,44 +483,6 @@ namespace { (*expr).visit(v); } } - - void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override - { - ::HIR::Visitor::visit_trait_impl(trait_path, impl); - - TU_IFLET(::HIR::TypeRef::Data, impl.m_type.m_data, Path, te, - ::HIR::TraitMarkings* markings = nullptr; - TU_MATCHA( (te.binding), (tpb), - (Unbound, - // Wut? - ), - (Opaque, - // Just ignore, it's a wildcard... wait? is that valid? - ), - (Struct, - markings = &const_cast<HIR::Struct*>(tpb)->m_markings; - ), - (Union, - markings = &const_cast<HIR::Union*>(tpb)->m_markings; - ), - (Enum, - markings = &const_cast<HIR::Enum*>(tpb)->m_markings; - ) - ) - - if( markings ) - { - // CoerceUnsized - set flag to avoid needless searches later - if( trait_path == m_lang_CoerceUnsized ) { - markings->can_coerce = true; - } - // Deref - set flag to avoid needless searches later - else if( trait_path == m_lang_Deref ) { - markings->has_a_deref = true; - } - } - ) - } }; } diff --git a/src/hir_conv/main_bindings.hpp b/src/hir_conv/main_bindings.hpp index 732e1722..fe99b859 100644 --- a/src/hir_conv/main_bindings.hpp +++ b/src/hir_conv/main_bindings.hpp @@ -6,7 +6,8 @@ namespace HIR { class Crate; }; -extern void ConvertHIR_ResolveUFCS(::HIR::Crate& crate); extern void ConvertHIR_ExpandAliases(::HIR::Crate& crate); extern void ConvertHIR_Bind(::HIR::Crate& crate); +extern void ConvertHIR_ResolveUFCS(::HIR::Crate& crate); +extern void ConvertHIR_Markings(::HIR::Crate& crate); extern void ConvertHIR_ConstantEvaluate(::HIR::Crate& hir_crate); diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp new file mode 100644 index 00000000..577ed63a --- /dev/null +++ b/src/hir_conv/markings.cpp @@ -0,0 +1,85 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * hir_conv/markings.cpp + * - Fills the TraitMarkings structure on types + */ +#include "main_bindings.hpp" +#include <hir/visitor.hpp> +#include <hir/expr.hpp> +#include <algorithm> // std::find_if + +#include <hir_typeck/static.hpp> + +namespace { + +class Visitor: + public ::HIR::Visitor +{ + const ::HIR::Crate& m_crate; + const ::HIR::SimplePath& m_lang_Unsize; + const ::HIR::SimplePath& m_lang_CoerceUnsized; + const ::HIR::SimplePath& m_lang_Deref; +public: + Visitor(const ::HIR::Crate& crate): + m_crate(crate), + m_lang_Unsize( crate.get_lang_item_path_opt("unsize") ), + m_lang_CoerceUnsized( crate.get_lang_item_path_opt("coerce_unsized") ), + m_lang_Deref( crate.get_lang_item_path_opt("deref") ) + { + } + + void visit_struct(::HIR::ItemPath ip, ::HIR::Struct& str) override + { + ::HIR::Visitor::visit_struct(ip, str); + } + + void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override + { + static Span sp; + + ::HIR::Visitor::visit_trait_impl(trait_path, impl); + + if( impl.m_type.m_data.is_Path() ) + { + const auto& te = impl.m_type.m_data.as_Path(); + const ::HIR::TraitMarkings* markings_ptr = nullptr; + TU_MATCHA( (te.binding), (tpb), + (Unbound, BUG(sp, "Unbound type path in trait impl - " << impl.m_type); ), + (Opaque, ), + (Struct, markings_ptr = &tpb->m_markings; ), + (Union , markings_ptr = &tpb->m_markings; ), + (Enum , markings_ptr = &tpb->m_markings; ) + ) + if( markings_ptr ) + { + ::HIR::TraitMarkings& markings = *const_cast<::HIR::TraitMarkings*>(markings_ptr); + if( trait_path == m_lang_Unsize ) { + DEBUG("Type " << impl.m_type << " can Unsize"); + markings.can_unsize = true; + } + else if( trait_path == m_lang_CoerceUnsized ) { + DEBUG("Type " << impl.m_type << " can Coerce"); + markings.can_coerce = true; + } + else if( trait_path == m_lang_Deref ) { + DEBUG("Type " << impl.m_type << " can Deref"); + markings.has_a_deref = true; + } + // TODO: Marker traits (with conditions) + else { + } + } + } + } +}; + +} // namespace + +void ConvertHIR_Markings(::HIR::Crate& crate) +{ + Visitor exp { crate }; + exp.visit_crate( crate ); +} + diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 962bf42c..73524d87 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -5110,8 +5110,9 @@ namespace { } // Types are equal from the view of being coercion targets - // - Inequality here means that the targets could coexist (e.g. &[u8; N] and &[u8]) + // - Inequality here means that the targets could coexist in the list (e.g. &[u8; N] and &[u8]) // - Equality means that they HAVE to be equal (even if they're not currently due to ivars) + // - E.g. &mut HashMap<_1> and &mut HashMap<T> would unify static bool equal_to(const Context& context, const ::HIR::TypeRef& ia, const ::HIR::TypeRef& ib) { const auto& a = context.m_ivars.get_type(ia); const auto& b = context.m_ivars.get_type(ib); @@ -5135,6 +5136,39 @@ namespace { (Infer, return false; ), + (Path, + #if 0 + if( e_ia.binding.tag() != e_ib.binding.tag() ) + return false; + const ::HIR::TraitMarkings* tm = nullptr; + TU_MATCHA( (e_ia.binding, e_ib.binding), (pbe_a, pbe_b), + (Unbound, return false; ), + (Opaque, + // TODO: Check bounds? + return false; + ), + (Struct, + if(pbe_a != pbe_b) return false; + tm = &pbe_a->m_markings; + ), + (Union, + if(pbe_a != pbe_b) return false; + tm = &pbe_a->m_markings; + ), + (Enum, + if(pbe_a != pbe_b) return false; + tm = &pbe_a->m_markings; + ) + ) + assert(tm); + if( !tm->can_unsize ) + return true; + // It _could_ unsize, so let it coexist + return false; + #else + return context.m_ivars.types_equal(ia, ib); + #endif + ), (Slice, const auto& ia2 = context.m_ivars.get_type(*e_ia.inner); const auto& ib2 = context.m_ivars.get_type(*e_ib.inner); diff --git a/src/main.cpp b/src/main.cpp index eb177268..45e5bfa8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,6 +45,7 @@ void init_debug_list() g_debug_disable_map.insert( "Resolve Type Aliases" );
g_debug_disable_map.insert( "Resolve Bind" );
g_debug_disable_map.insert( "Resolve UFCS paths" );
+ g_debug_disable_map.insert( "Resolve HIR Markings" );
g_debug_disable_map.insert( "Constant Evaluate" );
g_debug_disable_map.insert( "Typecheck Outer");
@@ -309,6 +310,9 @@ int main(int argc, char *argv[]) CompilePhaseV("Resolve UFCS paths", [&]() {
ConvertHIR_ResolveUFCS(*hir_crate);
});
+ CompilePhaseV("Resolve HIR Markings", [&]() {
+ ConvertHIR_Markings(*hir_crate);
+ });
CompilePhaseV("Constant Evaluate", [&]() {
ConvertHIR_ConstantEvaluate(*hir_crate);
});
|