1110: Add Reachability visitors for items with generics r=CohenArthur a=CohenArthur

This factors generics' predicates visiting in the `ReachabilityVisitor` and calls the function in other items with generic parameters

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
This commit is contained in:
bors[bot] 2022-04-14 07:27:52 +00:00 committed by GitHub
commit d36a3c5752
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 42 deletions

View File

@ -31,6 +31,41 @@ maybe_get_vis_item (std::unique_ptr<HIR::Item> &item)
return static_cast<HIR::VisItem *> (item.get ());
}
ReachLevel
ReachabilityVisitor::get_reachability_level (
const HIR::Visibility &item_visibility)
{
return item_visibility.is_public () ? current_level : ReachLevel::Unreachable;
}
void
ReachabilityVisitor::visit_generic_predicates (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generics,
ReachLevel item_reach)
{
if (item_reach == ReachLevel::Unreachable)
return;
for (const auto &generic : generics)
{
if (generic->get_kind () == HIR::GenericParam::TYPE)
{
TyTy::BaseType *generic_ty = nullptr;
auto ok = ty_ctx.lookup_type (generic->get_mappings ().get_hirid (),
&generic_ty);
rust_assert (ok);
rust_assert (generic_ty->get_kind () == TyTy::PARAM);
auto generic_param = static_cast<TyTy::ParamType *> (generic_ty);
for (const auto &bound : generic_param->get_specified_bounds ())
{
const auto trait = bound.get ()->get_hir_trait_ref ();
ctx.update_reachability (trait->get_mappings (), item_reach);
}
}
}
}
void
ReachabilityVisitor::visit (HIR::Module &mod)
{
@ -56,18 +91,25 @@ ReachabilityVisitor::visit (HIR::UseDeclaration &use_decl)
void
ReachabilityVisitor::visit (HIR::Function &func)
{}
{
auto fn_reach = get_reachability_level (func.get_visibility ());
fn_reach = ctx.update_reachability (func.get_mappings (), fn_reach);
visit_generic_predicates (func.get_generic_params (), fn_reach);
}
void
ReachabilityVisitor::visit (HIR::TypeAlias &type_alias)
{}
{
auto type_reach = get_reachability_level (type_alias.get_visibility ());
visit_generic_predicates (type_alias.get_generic_params (), type_reach);
}
void
ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
{
auto struct_reach = ReachLevel::Unreachable;
if (struct_item.get_visibility ().is_public ())
struct_reach = current_level;
auto struct_reach = get_reachability_level (struct_item.get_visibility ());
struct_reach
= ctx.update_reachability (struct_item.get_mappings (), struct_reach);
@ -75,41 +117,10 @@ ReachabilityVisitor::visit (HIR::StructStruct &struct_item)
auto old_level = current_level;
current_level = struct_reach;
visit_generic_predicates (struct_item.get_generic_params (), struct_reach);
if (struct_reach != ReachLevel::Unreachable)
{
for (auto &field : struct_item.get_fields ())
if (field.get_visibility ().is_public ())
ctx.update_reachability (field.get_mappings (), struct_reach);
for (auto &generic : struct_item.get_generic_params ())
{
switch (generic->get_kind ())
{
case HIR::GenericParam::LIFETIME:
break;
case HIR::GenericParam::TYPE:
TyTy::BaseType *generic_ty = nullptr;
rust_assert (
ty_ctx.lookup_type (generic->get_mappings ().get_hirid (),
&generic_ty));
if (generic_ty->get_kind () == TyTy::PARAM)
{
auto generic_param
= static_cast<TyTy::ParamType *> (generic_ty);
for (const auto &bound :
generic_param->get_specified_bounds ())
{
const auto trait = bound.get ()->get_hir_trait_ref ();
ctx.update_reachability (trait->get_mappings (),
struct_reach);
}
}
break;
}
}
for (auto &field : struct_item.get_fields ())
if (field.get_visibility ().is_public ())
ctx.update_reachability (field.get_field_type ()->get_mappings (),
@ -125,11 +136,22 @@ ReachabilityVisitor::visit (HIR::TupleStruct &tuple_struct)
void
ReachabilityVisitor::visit (HIR::Enum &enum_item)
{}
{
auto enum_reach = get_reachability_level (enum_item.get_visibility ());
enum_reach = ctx.update_reachability (enum_item.get_mappings (), enum_reach);
visit_generic_predicates (enum_item.get_generic_params (), enum_reach);
}
void
ReachabilityVisitor::visit (HIR::Union &union_item)
{}
{
auto union_reach = get_reachability_level (union_item.get_visibility ());
union_reach
= ctx.update_reachability (union_item.get_mappings (), union_reach);
visit_generic_predicates (union_item.get_generic_params (), union_reach);
}
void
ReachabilityVisitor::visit (HIR::ConstantItem &const_item)
@ -141,11 +163,21 @@ ReachabilityVisitor::visit (HIR::StaticItem &static_item)
void
ReachabilityVisitor::visit (HIR::Trait &trait)
{}
{
auto trait_reach = get_reachability_level (trait.get_visibility ());
trait_reach = ctx.update_reachability (trait.get_mappings (), trait_reach);
visit_generic_predicates (trait.get_generic_params (), trait_reach);
}
void
ReachabilityVisitor::visit (HIR::ImplBlock &impl)
{}
{
auto impl_reach = get_reachability_level (impl.get_visibility ());
impl_reach = ctx.update_reachability (impl.get_mappings (), impl_reach);
visit_generic_predicates (impl.get_generic_params (), impl_reach);
}
void
ReachabilityVisitor::visit (HIR::ExternBlock &block)

View File

@ -46,6 +46,19 @@ public:
: current_level (ReachLevel::Reachable), ctx (ctx), ty_ctx (ty_ctx)
{}
/**
* Visit all the predicates of all the generic types of a given item, marking
* them as reachable or not.
*/
void visit_generic_predicates (
const std::vector<std::unique_ptr<HIR::GenericParam>> &generics,
ReachLevel item_reach);
/**
* Get the initial reach level for an item based on its visibility.
*/
ReachLevel get_reachability_level (const HIR::Visibility &item_visibility);
virtual void visit (HIR::Module &mod);
virtual void visit (HIR::ExternCrate &crate);
virtual void visit (HIR::UseDeclaration &use_decl);