Skip to content

Commit

Permalink
HIR Expand ErasedTypes - Re-expand associated types that involved an …
Browse files Browse the repository at this point in the history
…expanded ErasedType
  • Loading branch information
thepowersgang committed May 19, 2024
1 parent 5b873d6 commit b427cdb
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 40 deletions.
73 changes: 73 additions & 0 deletions src/hir/visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
#include <hir/hir.hpp>
#include <hir/visitor.hpp>
#include <hir_typeck/static.hpp>

::HIR::Visitor::~Visitor()
{
Expand Down Expand Up @@ -125,6 +126,9 @@ void ::HIR::Visitor::visit_type_impl(::HIR::TypeImpl& impl)
{
::HIR::ItemPath p { impl.m_type };
TRACE_FUNCTION_F("impl.m_type=" << impl.m_type);
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, impl.m_params);
}
this->visit_params(impl.m_params);
this->visit_type(impl.m_type);

Expand All @@ -136,11 +140,17 @@ void ::HIR::Visitor::visit_type_impl(::HIR::TypeImpl& impl)
DEBUG("const " << ent.first);
this->visit_constant(p + ent.first, ent.second.data);
}
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl)
{
::HIR::ItemPath p( impl.m_type, trait_path, impl.m_trait_args );
TRACE_FUNCTION_F("impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type );
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, impl.m_params);
}
this->visit_params(impl.m_params);
// - HACK: Create a generic path to visit (so that proper checks are performed)
{
Expand All @@ -166,27 +176,51 @@ void ::HIR::Visitor::visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR
DEBUG("type " << ent.first);
this->visit_type(ent.second.data);
}
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl)
{
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, impl.m_params);
}
this->visit_params(impl.m_params);
this->visit_path_params(impl.m_trait_args);
this->visit_type(impl.m_type);
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}

void ::HIR::Visitor::visit_type_alias(::HIR::ItemPath p, ::HIR::TypeAlias& item)
{
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, item.m_params);
}
this->visit_params(item.m_params);
this->visit_type(item.m_type);
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_trait_alias(::HIR::ItemPath p, ::HIR::TraitAlias& item)
{
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, item.m_params);
}
this->visit_params(item.m_params);
for(auto& p : item.m_traits)
this->visit_trait_path(p);
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_trait(::HIR::ItemPath p, ::HIR::Trait& item)
{
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, item.m_params);
}
::HIR::SimplePath trait_sp = p.get_simple_path();
ItemPath trait_ip(trait_sp);
TRACE_FUNCTION;
Expand Down Expand Up @@ -221,9 +255,15 @@ void ::HIR::Visitor::visit_trait(::HIR::ItemPath p, ::HIR::Trait& item)
)
)
}
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_struct(::HIR::ItemPath p, ::HIR::Struct& item)
{
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, item.m_params);
}
this->visit_params(item.m_params);
TU_MATCH_HDRA( (item.m_data), {)
TU_ARMA(Unit, e) {
Expand All @@ -239,9 +279,15 @@ void ::HIR::Visitor::visit_struct(::HIR::ItemPath p, ::HIR::Struct& item)
}
}
}
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_enum(::HIR::ItemPath p, ::HIR::Enum& item)
{
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::None, item.m_params);
}
this->visit_params(item.m_params);
TU_MATCH_HDRA( (item.m_data), {)
TU_ARMA(Value, e) {
Expand All @@ -257,13 +303,22 @@ void ::HIR::Visitor::visit_enum(::HIR::ItemPath p, ::HIR::Enum& item)
}
}
}
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_union(::HIR::ItemPath p, ::HIR::Union& item)
{
TRACE_FUNCTION_F(p);
if( m_resolve ) {
m_resolve->set_impl_generics_raw(MetadataType::Unknown, item.m_params);
}
this->visit_params(item.m_params);
for(auto& var : item.m_variants)
this->visit_type(var.second.ent);
if( m_resolve ) {
m_resolve->clear_impl_generics();
}
}
void ::HIR::Visitor::visit_associatedtype(ItemPath p, ::HIR::AssociatedType& item)
{
Expand All @@ -275,6 +330,9 @@ void ::HIR::Visitor::visit_associatedtype(ItemPath p, ::HIR::AssociatedType& ite
void ::HIR::Visitor::visit_function(::HIR::ItemPath p, ::HIR::Function& item)
{
TRACE_FUNCTION_F(p);
if( m_resolve ) {
m_resolve->set_item_generics_raw(item.m_params);
}
this->visit_params(item.m_params);
for(auto& arg : item.m_args)
{
Expand All @@ -283,19 +341,34 @@ void ::HIR::Visitor::visit_function(::HIR::ItemPath p, ::HIR::Function& item)
}
this->visit_type(item.m_return);
this->visit_expr(item.m_code);
if( m_resolve ) {
m_resolve->clear_item_generics();
}
}
void ::HIR::Visitor::visit_static(::HIR::ItemPath p, ::HIR::Static& item)
{
TRACE_FUNCTION_F(p);
if( m_resolve ) {
m_resolve->set_item_generics_raw(item.m_params);
}
this->visit_type(item.m_type);
this->visit_expr(item.m_value);
if( m_resolve ) {
m_resolve->clear_item_generics();
}
}
void ::HIR::Visitor::visit_constant(::HIR::ItemPath p, ::HIR::Constant& item)
{
TRACE_FUNCTION_F(p);
if( m_resolve ) {
m_resolve->set_item_generics_raw(item.m_params);
}
this->visit_params(item.m_params);
this->visit_type(item.m_type);
this->visit_expr(item.m_value);
if( m_resolve ) {
m_resolve->clear_item_generics();
}
}

void ::HIR::Visitor::visit_params(::HIR::GenericParams& params)
Expand Down
4 changes: 4 additions & 0 deletions src/hir/visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
#include <hir/hir.hpp>
#include <hir/item_path.hpp>

class StaticTraitResolve;

namespace HIR {

// TODO: Split into Visitor and ItemVisitor
class Visitor
{
StaticTraitResolve* m_resolve;
public:
Visitor(::StaticTraitResolve* resolve=nullptr): m_resolve(resolve) {}
virtual ~Visitor();

virtual void visit_crate(::HIR::Crate& crate);
Expand Down
98 changes: 58 additions & 40 deletions src/hir_expand/erased_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,55 @@ namespace {
ty = mv$(new_ty);
}

void visit_type(const Span& sp, const StaticTraitResolve& resolve, ::HIR::TypeRef& ty) {
TRACE_FUNCTION_FR(ty, ty);
class V:
public ::HIR::Visitor
{
const Span& sp;
const StaticTraitResolve& m_resolve;
bool clear_opaque;
public:
V(const Span& sp, const StaticTraitResolve& resolve)
: sp(sp)
, m_resolve(resolve)
, clear_opaque(false)
{}

void visit_type(::HIR::TypeRef& ty) override
{
static const Span sp;
auto saved_clear_opaque = this->clear_opaque;
this->clear_opaque = false;
if( ty.data().is_ErasedType() )
{
TRACE_FUNCTION_FR(ty, ty);

expand_erased_type(sp, m_resolve, ty);

// Recurse (TODO: Cleanly prevent infinite recursion - TRACE_FUNCTION does crude prevention)
this->visit_type(ty);
this->clear_opaque = true;
}
else
{
::HIR::Visitor::visit_type(ty);
// If there was an erased type anywhere within this type, then clear an Opaque binding so EAT runs again
if( auto* p = ty.data_mut().opt_Path() ) {
// NOTE: This is both an optimisation, and avoids issues (if all types are cleared, the alias list in
// `StaticTraitResolve` ends up with un-expanded ATYs which leads to expansion not happening when it shoud.
if( this->clear_opaque && p->binding.is_Opaque() ) {
p->binding = HIR::TypePathBinding::make_Unbound({});
}
}
}
this->clear_opaque |= saved_clear_opaque;
}
} v(sp, resolve);
v.visit_type(ty);
resolve.expand_associated_types(sp, ty);
}

class ExprVisitor_Extract:
public ::HIR::ExprVisitorDef
{
Expand Down Expand Up @@ -83,31 +132,18 @@ namespace {
void visit_type(::HIR::TypeRef& ty) override
{
static Span sp;

if( ty.data().is_ErasedType() )
{
TRACE_FUNCTION_FR(ty, ty);

expand_erased_type(sp, m_resolve, ty);

// Recurse (TODO: Cleanly prevent infinite recursion - TRACE_FUNCTION does crude prevention)
visit_type(ty);
}
else
{
::HIR::ExprVisitorDef::visit_type(ty);
}
::visit_type(sp, m_resolve, ty);
}
};

class OuterVisitor:
public ::HIR::Visitor
{
StaticTraitResolve m_resolve;
const ::HIR::ItemPath* m_fcn_path = nullptr;
public:
OuterVisitor(const ::HIR::Crate& crate):
m_resolve(crate)
OuterVisitor(const ::HIR::Crate& crate)
: ::HIR::Visitor(&m_resolve)
, m_resolve(crate)
{}

void visit_expr(::HIR::ExprPtr& exp) override
Expand All @@ -118,39 +154,21 @@ namespace {
ev.visit_root( exp );
}
}

void visit_function(::HIR::ItemPath p, ::HIR::Function& fcn) override
{
m_fcn_path = &p;
::HIR::Visitor::visit_function(p, fcn);
m_fcn_path = nullptr;
}
};
class OuterVisitor_Fixup:
public ::HIR::Visitor
{
StaticTraitResolve m_resolve;
public:
OuterVisitor_Fixup(const ::HIR::Crate& crate):
m_resolve(crate)
OuterVisitor_Fixup(const ::HIR::Crate& crate)
: ::HIR::Visitor(&m_resolve)
, m_resolve(crate)
{}

void visit_type(::HIR::TypeRef& ty) override
{
static const Span sp;
if( ty.data().is_ErasedType() )
{
TRACE_FUNCTION_FR(ty, ty);

expand_erased_type(sp, m_resolve, ty);

// Recurse (TODO: Cleanly prevent infinite recursion - TRACE_FUNCTION does crude prevention)
visit_type(ty);
}
else
{
::HIR::Visitor::visit_type(ty);
}
static Span sp;
::visit_type(sp, m_resolve, ty);
}
};
}
Expand Down

0 comments on commit b427cdb

Please sign in to comment.