Make TypeBoundPredicate a subclass of the SubstitutionRef

This will allow us to reuse our generic substitions code to manage generic
traits and their substitions better. It will unify the handling in one
path so we get the same error handling.
This commit is contained in:
Philip Herron 2022-03-16 15:22:52 +00:00
parent 56a1571614
commit 7ac9a76c89
7 changed files with 75 additions and 19 deletions

View File

@ -407,7 +407,7 @@ public:
bool trait_has_generics () const { return !trait_substs.empty (); }
const std::vector<TyTy::SubstitutionParamMapping> &get_trait_substs () const
std::vector<TyTy::SubstitutionParamMapping> get_trait_substs () const
{
return trait_substs;
}

View File

@ -150,8 +150,13 @@ private:
// They also inherit themselves as a bound this enables a trait item to
// reference other Self::trait_items
std::vector<TyTy::SubstitutionParamMapping> self_subst_copy;
for (auto &sub : substitutions)
self_subst_copy.push_back (sub.clone ());
specified_bounds.push_back (
TyTy::TypeBoundPredicate (trait_reference->get_mappings ().get_defid (),
std::move (self_subst_copy),
trait_reference->get_locus ()));
std::vector<const TraitReference *> super_traits;
@ -168,8 +173,8 @@ private:
// FIXME this might be recursive we need a check for that
TraitReference *trait = resolve_trait_path (b->get_path ());
TyTy::TypeBoundPredicate predicate (
trait->get_mappings ().get_defid (), bound->get_locus ());
TyTy::TypeBoundPredicate predicate (*trait,
bound->get_locus ());
specified_bounds.push_back (std::move (predicate));
super_traits.push_back (predicate.get ());

View File

@ -79,8 +79,8 @@ public:
rust_assert (!trait_reference->is_error ());
// setup the bound
TyTy::TypeBoundPredicate predicate (
trait_reference->get_mappings ().get_defid (), ref->get_locus ());
TyTy::TypeBoundPredicate predicate (*trait_reference,
ref->get_locus ());
auto &final_seg = ref->get_final_segment ();
if (final_seg->is_generic_segment ())
{

View File

@ -550,8 +550,7 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
auto &type_path = trait_bound.get_path ();
TraitReference *trait = resolve_trait_path (type_path);
TyTy::TypeBoundPredicate predicate (trait->get_mappings ().get_defid (),
trait_bound.get_locus ());
TyTy::TypeBoundPredicate predicate (*trait, trait_bound.get_locus ());
auto &final_seg = type_path.get_final_segment ();
if (final_seg->is_generic_segment ())
{

View File

@ -247,8 +247,7 @@ public:
auto &type_path = b->get_path ();
TraitReference *trait = resolve_trait_path (type_path);
TyTy::TypeBoundPredicate predicate (
trait->get_mappings ().get_defid (), b->get_locus ());
TyTy::TypeBoundPredicate predicate (*trait, b->get_locus ());
auto &final_seg = type_path.get_final_segment ();
if (final_seg->is_generic_segment ())
@ -318,8 +317,7 @@ public:
auto &type_path = b->get_path ();
TraitReference *trait = resolve_trait_path (type_path);
TyTy::TypeBoundPredicate predicate (
trait->get_mappings ().get_defid (), b->get_locus ());
TyTy::TypeBoundPredicate predicate (*trait, b->get_locus ());
auto &final_seg = type_path.get_final_segment ();
if (final_seg->is_generic_segment ())

View File

@ -67,17 +67,38 @@ TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
namespace TyTy {
TypeBoundPredicate::TypeBoundPredicate (DefId reference, Location locus)
: reference (reference), locus (locus), args (nullptr)
TypeBoundPredicate::TypeBoundPredicate (
const Resolver::TraitReference &trait_reference, Location locus)
: SubstitutionRef (trait_reference.get_trait_substs (),
SubstitutionArgumentMappings::error ()),
reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
args (nullptr), error_flag (false)
{}
TypeBoundPredicate::TypeBoundPredicate (
DefId reference, std::vector<SubstitutionParamMapping> substitutions,
Location locus)
: SubstitutionRef (std::move (substitutions),
SubstitutionArgumentMappings::error ()),
reference (reference), locus (locus), args (nullptr), error_flag (false)
{}
TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
: SubstitutionRef ({}, other.used_arguments), reference (other.reference),
locus (other.locus), args (other.args), error_flag (other.error_flag)
{
substitutions.clear ();
if (!other.is_error ())
{
for (const auto &p : other.get_substs ())
substitutions.push_back (p.clone ());
}
}
std::string
TypeBoundPredicate::as_string () const
{
return get ()->as_string ()
+ (has_generic_args ()
? std::string ("<") + args->as_string () + std::string (">")
: "");
return get ()->as_string () + subst_as_string ();
}
const Resolver::TraitReference *
@ -183,6 +204,25 @@ TypeBoundPredicateItem::get_tyty_for_receiver (
return resolved;
}
bool
TypeBoundPredicate::is_error () const
{
auto context = Resolver::TypeCheckContext::get ();
Resolver::TraitReference *ref = nullptr;
bool ok = context->lookup_trait_reference (reference, &ref);
return !ok || error_flag;
}
BaseType *
TypeBoundPredicate::handle_substitions (SubstitutionArgumentMappings mappings)
{
gcc_unreachable ();
return nullptr;
}
// trait item reference
const Resolver::TraitItemReference *
TypeBoundPredicateItem::get_raw_item () const

View File

@ -939,10 +939,17 @@ protected:
SubstitutionArgumentMappings used_arguments;
};
class TypeBoundPredicate
class TypeBoundPredicate : public SubstitutionRef
{
public:
TypeBoundPredicate (DefId reference, Location locus);
TypeBoundPredicate (const Resolver::TraitReference &trait_reference,
Location locus);
TypeBoundPredicate (DefId reference,
std::vector<SubstitutionParamMapping> substitutions,
Location locus);
TypeBoundPredicate (const TypeBoundPredicate &other);
std::string as_string () const;
@ -975,10 +982,17 @@ public:
return args->has_generic_args ();
}
// WARNING THIS WILL ALWAYS RETURN NULLPTR
BaseType *
handle_substitions (SubstitutionArgumentMappings mappings) override final;
bool is_error () const;
private:
DefId reference;
Location locus;
HIR::GenericArgs *args;
bool error_flag;
};
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html