mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
gccrs: typecheck: Refactor rust-hir-trait-reference.h
Move function body to their own cc file instead of keeping them in the header file. gcc/rust/ChangeLog: * Make-lang.in: Add `rust-hir-trait-reference.o`. * typecheck/rust-hir-trait-reference.h: Remove multiple function body. * typecheck/rust-hir-trait-reference.cc: Add multiple function body. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
This commit is contained in:
committed by
Arthur Cohen
parent
fbd5244df6
commit
5fd04425c0
@@ -123,6 +123,7 @@ GRS_OBJS = \
|
||||
rust/rust-tyty-bounds.o \
|
||||
rust/rust-hir-type-check-util.o \
|
||||
rust/rust-hir-trait-resolve.o \
|
||||
rust/rust-hir-trait-reference.o \
|
||||
rust/rust-hir-type-check-item.o \
|
||||
rust/rust-hir-type-check-type.o \
|
||||
rust/rust-hir-type-check-struct.o \
|
||||
|
||||
463
gcc/rust/typecheck/rust-hir-trait-reference.cc
Normal file
463
gcc/rust/typecheck/rust-hir-trait-reference.cc
Normal file
@@ -0,0 +1,463 @@
|
||||
// Copyright (C) 2020-2022 Free Software Foundation, Inc.
|
||||
|
||||
// This file is part of GCC.
|
||||
|
||||
// GCC is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 3, or (at your option) any later
|
||||
// version.
|
||||
|
||||
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GCC; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "rust-hir-trait-reference.h"
|
||||
|
||||
namespace Rust {
|
||||
namespace Resolver {
|
||||
|
||||
std::string
|
||||
TraitItemReference::as_string () const
|
||||
{
|
||||
return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")";
|
||||
}
|
||||
|
||||
bool
|
||||
TraitItemReference::is_error () const
|
||||
{
|
||||
return type == ERROR;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitItemReference::is_optional () const
|
||||
{
|
||||
return optional_flag;
|
||||
};
|
||||
|
||||
std::string
|
||||
TraitItemReference::get_identifier () const
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
TraitItemReference::TraitItemType
|
||||
TraitItemReference::get_trait_item_type () const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
HIR::TraitItem *
|
||||
TraitItemReference::get_hir_trait_item () const
|
||||
{
|
||||
return hir_trait_item;
|
||||
}
|
||||
|
||||
Location
|
||||
TraitItemReference::get_locus () const
|
||||
{
|
||||
return locus;
|
||||
}
|
||||
|
||||
const Analysis::NodeMapping
|
||||
TraitItemReference::get_mappings () const
|
||||
{
|
||||
return hir_trait_item->get_mappings ();
|
||||
}
|
||||
|
||||
TyTy::BaseType *
|
||||
TraitItemReference::get_tyty () const
|
||||
{
|
||||
rust_assert (hir_trait_item != nullptr);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CONST:
|
||||
return get_type_from_constant (
|
||||
static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
|
||||
break;
|
||||
|
||||
case TYPE:
|
||||
return get_type_from_typealias (
|
||||
static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
|
||||
|
||||
case FN:
|
||||
return get_type_from_fn (
|
||||
static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
|
||||
break;
|
||||
|
||||
default:
|
||||
return get_error ();
|
||||
}
|
||||
|
||||
gcc_unreachable ();
|
||||
return get_error ();
|
||||
}
|
||||
|
||||
TyTy::ErrorType *
|
||||
TraitItemReference::get_error () const
|
||||
{
|
||||
return new TyTy::ErrorType (get_mappings ().get_hirid ());
|
||||
}
|
||||
|
||||
TraitReference::TraitReference (
|
||||
const HIR::Trait *hir_trait_ref, std::vector<TraitItemReference> item_refs,
|
||||
std::vector<const TraitReference *> super_traits,
|
||||
std::vector<TyTy::SubstitutionParamMapping> substs)
|
||||
: hir_trait_ref (hir_trait_ref), item_refs (item_refs),
|
||||
super_traits (super_traits)
|
||||
{
|
||||
trait_substs.clear ();
|
||||
trait_substs.reserve (substs.size ());
|
||||
for (const auto &p : substs)
|
||||
trait_substs.push_back (p.clone ());
|
||||
}
|
||||
|
||||
TraitReference::TraitReference (TraitReference const &other)
|
||||
: hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
|
||||
super_traits (other.super_traits)
|
||||
{
|
||||
trait_substs.clear ();
|
||||
trait_substs.reserve (other.trait_substs.size ());
|
||||
for (const auto &p : other.trait_substs)
|
||||
trait_substs.push_back (p.clone ());
|
||||
}
|
||||
|
||||
TraitReference &
|
||||
TraitReference::operator= (TraitReference const &other)
|
||||
{
|
||||
hir_trait_ref = other.hir_trait_ref;
|
||||
item_refs = other.item_refs;
|
||||
super_traits = other.super_traits;
|
||||
|
||||
trait_substs.clear ();
|
||||
trait_substs.reserve (other.trait_substs.size ());
|
||||
for (const auto &p : other.trait_substs)
|
||||
trait_substs.push_back (p.clone ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::is_error () const
|
||||
{
|
||||
return hir_trait_ref == nullptr;
|
||||
}
|
||||
|
||||
Location
|
||||
TraitReference::get_locus () const
|
||||
{
|
||||
return hir_trait_ref->get_locus ();
|
||||
}
|
||||
|
||||
std::string
|
||||
TraitReference::get_name () const
|
||||
{
|
||||
rust_assert (!is_error ());
|
||||
return hir_trait_ref->get_name ();
|
||||
}
|
||||
|
||||
std::string
|
||||
TraitReference::as_string () const
|
||||
{
|
||||
if (is_error ())
|
||||
return "<trait-ref-error-node>";
|
||||
|
||||
std::string item_buf;
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
item_buf += item.as_string () + ", ";
|
||||
}
|
||||
return "HIR Trait: " + get_name () + "->"
|
||||
+ hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]";
|
||||
}
|
||||
|
||||
const HIR::Trait *
|
||||
TraitReference::get_hir_trait_ref () const
|
||||
{
|
||||
return hir_trait_ref;
|
||||
}
|
||||
|
||||
const Analysis::NodeMapping &
|
||||
TraitReference::get_mappings () const
|
||||
{
|
||||
return hir_trait_ref->get_mappings ();
|
||||
}
|
||||
|
||||
DefId
|
||||
TraitReference::get_defid () const
|
||||
{
|
||||
return get_mappings ().get_defid ();
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
|
||||
TraitItemReference **ref)
|
||||
{
|
||||
return lookup_trait_item (item.trait_identifier (), ref);
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::lookup_trait_item (const std::string &ident,
|
||||
TraitItemReference **ref)
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::lookup_trait_item_by_type (
|
||||
const std::string &ident, TraitItemReference::TraitItemType type,
|
||||
TraitItemReference **ref)
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (item.get_trait_item_type () != type)
|
||||
continue;
|
||||
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::lookup_trait_item_by_type (
|
||||
const std::string &ident, TraitItemReference::TraitItemType type,
|
||||
const TraitItemReference **ref) const
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (item.get_trait_item_type () != type)
|
||||
continue;
|
||||
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item,
|
||||
const TraitItemReference **ref) const
|
||||
{
|
||||
return lookup_trait_item (item.trait_identifier (), ref);
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::lookup_trait_item (const std::string &ident,
|
||||
const TraitItemReference **ref) const
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// lookup super traits
|
||||
for (const auto &super_trait : super_traits)
|
||||
{
|
||||
bool found = super_trait->lookup_trait_item (ident, ref);
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const TraitItemReference *
|
||||
TraitReference::lookup_trait_item (const std::string &ident,
|
||||
TraitItemReference::TraitItemType type) const
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (item.get_trait_item_type () != type)
|
||||
continue;
|
||||
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
return &item;
|
||||
}
|
||||
|
||||
// lookup super traits
|
||||
for (const auto &super_trait : super_traits)
|
||||
{
|
||||
const TraitItemReference *res
|
||||
= super_trait->lookup_trait_item (ident, type);
|
||||
if (!res->is_error ())
|
||||
return res;
|
||||
}
|
||||
|
||||
return &TraitItemReference::error_node ();
|
||||
}
|
||||
|
||||
size_t
|
||||
TraitReference::size () const
|
||||
{
|
||||
return item_refs.size ();
|
||||
}
|
||||
|
||||
const std::vector<TraitItemReference> &
|
||||
TraitReference::get_trait_items () const
|
||||
{
|
||||
return item_refs;
|
||||
}
|
||||
|
||||
void
|
||||
TraitReference::get_trait_items_and_supers (
|
||||
std::vector<const TraitItemReference *> &result) const
|
||||
{
|
||||
for (const auto &item : item_refs)
|
||||
result.push_back (&item);
|
||||
|
||||
for (const auto &super_trait : super_traits)
|
||||
super_trait->get_trait_items_and_supers (result);
|
||||
}
|
||||
|
||||
void
|
||||
TraitReference::on_resolved ()
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
item.on_resolved ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TraitReference::clear_associated_types ()
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
bool is_assoc_type = item.get_trait_item_type ()
|
||||
== TraitItemReference::TraitItemType::TYPE;
|
||||
if (is_assoc_type)
|
||||
item.associated_type_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::is_equal (const TraitReference &other) const
|
||||
{
|
||||
DefId this_id = get_mappings ().get_defid ();
|
||||
DefId other_id = other.get_mappings ().get_defid ();
|
||||
return this_id == other_id;
|
||||
}
|
||||
|
||||
const std::vector<const TraitReference *>
|
||||
TraitReference::get_super_traits () const
|
||||
{
|
||||
return super_traits;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::is_object_safe (bool emit_error, Location locus) const
|
||||
{
|
||||
// https: // doc.rust-lang.org/reference/items/traits.html#object-safety
|
||||
std::vector<const TraitReference *> non_object_super_traits;
|
||||
for (auto &item : super_traits)
|
||||
{
|
||||
if (!item->is_object_safe (false, Location ()))
|
||||
non_object_super_traits.push_back (item);
|
||||
}
|
||||
|
||||
std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
|
||||
for (auto &item : get_trait_items ())
|
||||
{
|
||||
if (!item.is_object_safe ())
|
||||
non_object_safe_items.push_back (&item);
|
||||
}
|
||||
|
||||
bool is_safe
|
||||
= non_object_super_traits.empty () && non_object_safe_items.empty ();
|
||||
if (emit_error && !is_safe)
|
||||
{
|
||||
RichLocation r (locus);
|
||||
for (auto &item : non_object_super_traits)
|
||||
r.add_range (item->get_locus ());
|
||||
for (auto &item : non_object_safe_items)
|
||||
r.add_range (item->get_locus ());
|
||||
|
||||
rust_error_at (r, "trait bound is not object safe");
|
||||
}
|
||||
|
||||
return is_safe;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::trait_has_generics () const
|
||||
{
|
||||
return !trait_substs.empty ();
|
||||
}
|
||||
|
||||
std::vector<TyTy::SubstitutionParamMapping>
|
||||
TraitReference::get_trait_substs () const
|
||||
{
|
||||
return trait_substs;
|
||||
}
|
||||
|
||||
bool
|
||||
TraitReference::satisfies_bound (const TraitReference &reference) const
|
||||
{
|
||||
if (is_equal (reference))
|
||||
return true;
|
||||
|
||||
for (const auto &super_trait : super_traits)
|
||||
{
|
||||
if (super_trait->satisfies_bound (reference))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait,
|
||||
HIR::ImplBlock *impl,
|
||||
TyTy::BaseType *self,
|
||||
Resolver::TypeCheckContext *context)
|
||||
: trait (trait), impl (impl), self (self), context (context)
|
||||
{}
|
||||
|
||||
TraitReference *
|
||||
AssociatedImplTrait::get_trait ()
|
||||
{
|
||||
return trait;
|
||||
}
|
||||
|
||||
HIR::ImplBlock *
|
||||
AssociatedImplTrait::get_impl_block ()
|
||||
{
|
||||
return impl;
|
||||
}
|
||||
|
||||
TyTy::BaseType *
|
||||
AssociatedImplTrait::get_self ()
|
||||
{
|
||||
return self;
|
||||
}
|
||||
const TyTy::BaseType *
|
||||
AssociatedImplTrait::get_self () const
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace Resolver
|
||||
} // namespace Rust
|
||||
@@ -20,8 +20,8 @@
|
||||
#define RUST_HIR_TRAIT_REF_H
|
||||
|
||||
#include "rust-hir-full.h"
|
||||
#include "rust-tyty-visitor.h"
|
||||
#include "rust-hir-type-check-util.h"
|
||||
#include "rust-tyty-visitor.h"
|
||||
|
||||
namespace Rust {
|
||||
namespace Resolver {
|
||||
@@ -61,13 +61,9 @@ public:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool is_error () const { return type == ERROR; }
|
||||
bool is_error () const;
|
||||
|
||||
std::string as_string () const
|
||||
{
|
||||
return "(" + trait_item_type_as_string (type) + " " + identifier + " "
|
||||
+ ")";
|
||||
}
|
||||
std::string as_string () const;
|
||||
|
||||
static std::string trait_item_type_as_string (TraitItemType ty)
|
||||
{
|
||||
@@ -85,53 +81,24 @@ public:
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
bool is_optional () const { return optional_flag; }
|
||||
bool is_optional () const;
|
||||
|
||||
std::string get_identifier () const { return identifier; }
|
||||
std::string get_identifier () const;
|
||||
|
||||
TraitItemType get_trait_item_type () const { return type; }
|
||||
TraitItemType get_trait_item_type () const;
|
||||
|
||||
HIR::TraitItem *get_hir_trait_item () const { return hir_trait_item; }
|
||||
HIR::TraitItem *get_hir_trait_item () const;
|
||||
|
||||
Location get_locus () const { return locus; }
|
||||
Location get_locus () const;
|
||||
|
||||
const Analysis::NodeMapping get_mappings () const
|
||||
{
|
||||
return hir_trait_item->get_mappings ();
|
||||
}
|
||||
const Analysis::NodeMapping get_mappings () const;
|
||||
|
||||
TyTy::BaseType *get_tyty () const
|
||||
{
|
||||
rust_assert (hir_trait_item != nullptr);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CONST:
|
||||
return get_type_from_constant (
|
||||
static_cast</*const*/ HIR::TraitItemConst &> (*hir_trait_item));
|
||||
break;
|
||||
|
||||
case TYPE:
|
||||
return get_type_from_typealias (
|
||||
static_cast</*const*/ HIR::TraitItemType &> (*hir_trait_item));
|
||||
|
||||
case FN:
|
||||
return get_type_from_fn (
|
||||
static_cast</*const*/ HIR::TraitItemFunc &> (*hir_trait_item));
|
||||
break;
|
||||
|
||||
default:
|
||||
return get_error ();
|
||||
}
|
||||
|
||||
gcc_unreachable ();
|
||||
return get_error ();
|
||||
}
|
||||
TyTy::BaseType *get_tyty () const;
|
||||
|
||||
Analysis::NodeMapping get_parent_trait_mappings () const;
|
||||
|
||||
// this is called when the trait is completed resolution and gives the items a
|
||||
// chance to run their specific type resolution passes. If we call their
|
||||
// this is called when the trait is completed resolution and gives the items
|
||||
// a chance to run their specific type resolution passes. If we call their
|
||||
// resolution on construction it can lead to a case where the trait being
|
||||
// resolved recursively trying to resolve the trait itself infinitely since
|
||||
// the trait will not be stored in its own map yet
|
||||
@@ -144,10 +111,7 @@ public:
|
||||
bool is_object_safe () const;
|
||||
|
||||
private:
|
||||
TyTy::ErrorType *get_error () const
|
||||
{
|
||||
return new TyTy::ErrorType (get_mappings ().get_hirid ());
|
||||
}
|
||||
TyTy::ErrorType *get_error () const;
|
||||
|
||||
TyTy::BaseType *get_type_from_typealias (/*const*/
|
||||
HIR::TraitItemType &type) const;
|
||||
@@ -182,39 +146,11 @@ public:
|
||||
TraitReference (const HIR::Trait *hir_trait_ref,
|
||||
std::vector<TraitItemReference> item_refs,
|
||||
std::vector<const TraitReference *> super_traits,
|
||||
std::vector<TyTy::SubstitutionParamMapping> substs)
|
||||
: hir_trait_ref (hir_trait_ref), item_refs (item_refs),
|
||||
super_traits (super_traits)
|
||||
{
|
||||
trait_substs.clear ();
|
||||
trait_substs.reserve (substs.size ());
|
||||
for (const auto &p : substs)
|
||||
trait_substs.push_back (p.clone ());
|
||||
}
|
||||
std::vector<TyTy::SubstitutionParamMapping> substs);
|
||||
|
||||
TraitReference (TraitReference const &other)
|
||||
: hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs),
|
||||
super_traits (other.super_traits)
|
||||
{
|
||||
trait_substs.clear ();
|
||||
trait_substs.reserve (other.trait_substs.size ());
|
||||
for (const auto &p : other.trait_substs)
|
||||
trait_substs.push_back (p.clone ());
|
||||
}
|
||||
TraitReference (TraitReference const &other);
|
||||
|
||||
TraitReference &operator= (TraitReference const &other)
|
||||
{
|
||||
hir_trait_ref = other.hir_trait_ref;
|
||||
item_refs = other.item_refs;
|
||||
super_traits = other.super_traits;
|
||||
|
||||
trait_substs.clear ();
|
||||
trait_substs.reserve (other.trait_substs.size ());
|
||||
for (const auto &p : other.trait_substs)
|
||||
trait_substs.push_back (p.clone ());
|
||||
|
||||
return *this;
|
||||
}
|
||||
TraitReference &operator= (TraitReference const &other);
|
||||
|
||||
TraitReference (TraitReference &&other) = default;
|
||||
TraitReference &operator= (TraitReference &&other) = default;
|
||||
@@ -224,7 +160,7 @@ public:
|
||||
return TraitReference (nullptr, {}, {}, {});
|
||||
}
|
||||
|
||||
bool is_error () const { return hir_trait_ref == nullptr; }
|
||||
bool is_error () const;
|
||||
|
||||
static TraitReference &error_node ()
|
||||
{
|
||||
@@ -232,248 +168,63 @@ public:
|
||||
return trait_error_node;
|
||||
}
|
||||
|
||||
Location get_locus () const { return hir_trait_ref->get_locus (); }
|
||||
Location get_locus () const;
|
||||
|
||||
std::string get_name () const
|
||||
{
|
||||
rust_assert (!is_error ());
|
||||
return hir_trait_ref->get_name ();
|
||||
}
|
||||
std::string get_name () const;
|
||||
|
||||
std::string as_string () const
|
||||
{
|
||||
if (is_error ())
|
||||
return "<trait-ref-error-node>";
|
||||
std::string as_string () const;
|
||||
|
||||
std::string item_buf;
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
item_buf += item.as_string () + ", ";
|
||||
}
|
||||
return "HIR Trait: " + get_name () + "->"
|
||||
+ hir_trait_ref->get_mappings ().as_string () + " [" + item_buf
|
||||
+ "]";
|
||||
}
|
||||
const HIR::Trait *get_hir_trait_ref () const;
|
||||
|
||||
const HIR::Trait *get_hir_trait_ref () const { return hir_trait_ref; }
|
||||
const Analysis::NodeMapping &get_mappings () const;
|
||||
|
||||
const Analysis::NodeMapping &get_mappings () const
|
||||
{
|
||||
return hir_trait_ref->get_mappings ();
|
||||
}
|
||||
|
||||
DefId get_defid () const { return get_mappings ().get_defid (); }
|
||||
DefId get_defid () const;
|
||||
|
||||
bool lookup_hir_trait_item (const HIR::TraitItem &item,
|
||||
TraitItemReference **ref)
|
||||
{
|
||||
return lookup_trait_item (item.trait_identifier (), ref);
|
||||
}
|
||||
TraitItemReference **ref);
|
||||
|
||||
bool lookup_trait_item (const std::string &ident, TraitItemReference **ref)
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool lookup_trait_item (const std::string &ident, TraitItemReference **ref);
|
||||
|
||||
bool lookup_trait_item_by_type (const std::string &ident,
|
||||
TraitItemReference::TraitItemType type,
|
||||
TraitItemReference **ref)
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (item.get_trait_item_type () != type)
|
||||
continue;
|
||||
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TraitItemReference **ref);
|
||||
|
||||
bool lookup_trait_item_by_type (const std::string &ident,
|
||||
TraitItemReference::TraitItemType type,
|
||||
const TraitItemReference **ref) const
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (item.get_trait_item_type () != type)
|
||||
continue;
|
||||
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const TraitItemReference **ref) const;
|
||||
|
||||
bool lookup_hir_trait_item (const HIR::TraitItem &item,
|
||||
const TraitItemReference **ref) const
|
||||
{
|
||||
return lookup_trait_item (item.trait_identifier (), ref);
|
||||
}
|
||||
const TraitItemReference **ref) const;
|
||||
|
||||
bool lookup_trait_item (const std::string &ident,
|
||||
const TraitItemReference **ref) const
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
{
|
||||
*ref = &item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// lookup super traits
|
||||
for (const auto &super_trait : super_traits)
|
||||
{
|
||||
bool found = super_trait->lookup_trait_item (ident, ref);
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
const TraitItemReference **ref) const;
|
||||
|
||||
const TraitItemReference *
|
||||
lookup_trait_item (const std::string &ident,
|
||||
TraitItemReference::TraitItemType type) const
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
if (item.get_trait_item_type () != type)
|
||||
continue;
|
||||
TraitItemReference::TraitItemType type) const;
|
||||
|
||||
if (ident.compare (item.get_identifier ()) == 0)
|
||||
return &item;
|
||||
}
|
||||
size_t size () const;
|
||||
|
||||
// lookup super traits
|
||||
for (const auto &super_trait : super_traits)
|
||||
{
|
||||
const TraitItemReference *res
|
||||
= super_trait->lookup_trait_item (ident, type);
|
||||
if (!res->is_error ())
|
||||
return res;
|
||||
}
|
||||
|
||||
return &TraitItemReference::error_node ();
|
||||
}
|
||||
|
||||
size_t size () const { return item_refs.size (); }
|
||||
|
||||
const std::vector<TraitItemReference> &get_trait_items () const
|
||||
{
|
||||
return item_refs;
|
||||
}
|
||||
const std::vector<TraitItemReference> &get_trait_items () const;
|
||||
|
||||
void get_trait_items_and_supers (
|
||||
std::vector<const TraitItemReference *> &result) const
|
||||
{
|
||||
for (const auto &item : item_refs)
|
||||
result.push_back (&item);
|
||||
std::vector<const TraitItemReference *> &result) const;
|
||||
|
||||
for (const auto &super_trait : super_traits)
|
||||
super_trait->get_trait_items_and_supers (result);
|
||||
}
|
||||
void on_resolved ();
|
||||
|
||||
void on_resolved ()
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
item.on_resolved ();
|
||||
}
|
||||
}
|
||||
void clear_associated_types ();
|
||||
|
||||
void clear_associated_types ()
|
||||
{
|
||||
for (auto &item : item_refs)
|
||||
{
|
||||
bool is_assoc_type = item.get_trait_item_type ()
|
||||
== TraitItemReference::TraitItemType::TYPE;
|
||||
if (is_assoc_type)
|
||||
item.associated_type_reset ();
|
||||
}
|
||||
}
|
||||
bool is_equal (const TraitReference &other) const;
|
||||
|
||||
bool is_equal (const TraitReference &other) const
|
||||
{
|
||||
DefId this_id = get_mappings ().get_defid ();
|
||||
DefId other_id = other.get_mappings ().get_defid ();
|
||||
return this_id == other_id;
|
||||
}
|
||||
const std::vector<const TraitReference *> get_super_traits () const;
|
||||
|
||||
const std::vector<const TraitReference *> get_super_traits () const
|
||||
{
|
||||
return super_traits;
|
||||
}
|
||||
bool is_object_safe (bool emit_error, Location locus) const;
|
||||
|
||||
bool is_object_safe (bool emit_error, Location locus) const
|
||||
{
|
||||
// https: // doc.rust-lang.org/reference/items/traits.html#object-safety
|
||||
std::vector<const TraitReference *> non_object_super_traits;
|
||||
for (auto &item : super_traits)
|
||||
{
|
||||
if (!item->is_object_safe (false, Location ()))
|
||||
non_object_super_traits.push_back (item);
|
||||
}
|
||||
bool trait_has_generics () const;
|
||||
|
||||
std::vector<const Resolver::TraitItemReference *> non_object_safe_items;
|
||||
for (auto &item : get_trait_items ())
|
||||
{
|
||||
if (!item.is_object_safe ())
|
||||
non_object_safe_items.push_back (&item);
|
||||
}
|
||||
std::vector<TyTy::SubstitutionParamMapping> get_trait_substs () const;
|
||||
|
||||
bool is_safe
|
||||
= non_object_super_traits.empty () && non_object_safe_items.empty ();
|
||||
if (emit_error && !is_safe)
|
||||
{
|
||||
RichLocation r (locus);
|
||||
for (auto &item : non_object_super_traits)
|
||||
r.add_range (item->get_locus ());
|
||||
for (auto &item : non_object_safe_items)
|
||||
r.add_range (item->get_locus ());
|
||||
|
||||
rust_error_at (r, "trait bound is not object safe");
|
||||
}
|
||||
|
||||
return is_safe;
|
||||
}
|
||||
|
||||
bool trait_has_generics () const { return !trait_substs.empty (); }
|
||||
|
||||
std::vector<TyTy::SubstitutionParamMapping> get_trait_substs () const
|
||||
{
|
||||
return trait_substs;
|
||||
}
|
||||
|
||||
bool satisfies_bound (const TraitReference &reference) const
|
||||
{
|
||||
if (is_equal (reference))
|
||||
return true;
|
||||
|
||||
for (const auto &super_trait : super_traits)
|
||||
{
|
||||
if (super_trait->satisfies_bound (reference))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool satisfies_bound (const TraitReference &reference) const;
|
||||
|
||||
private:
|
||||
const HIR::Trait *hir_trait_ref;
|
||||
@@ -487,16 +238,14 @@ class AssociatedImplTrait
|
||||
public:
|
||||
AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl,
|
||||
TyTy::BaseType *self,
|
||||
Resolver::TypeCheckContext *context)
|
||||
: trait (trait), impl (impl), self (self), context (context)
|
||||
{}
|
||||
Resolver::TypeCheckContext *context);
|
||||
|
||||
TraitReference *get_trait () { return trait; }
|
||||
TraitReference *get_trait ();
|
||||
|
||||
HIR::ImplBlock *get_impl_block () { return impl; }
|
||||
HIR::ImplBlock *get_impl_block ();
|
||||
|
||||
TyTy::BaseType *get_self () { return self; }
|
||||
const TyTy::BaseType *get_self () const { return self; }
|
||||
TyTy::BaseType *get_self ();
|
||||
const TyTy::BaseType *get_self () const;
|
||||
|
||||
TyTy::BaseType *
|
||||
setup_associated_types (const TyTy::BaseType *self,
|
||||
|
||||
Reference in New Issue
Block a user