summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-10-02 09:27:03 +0800
committerJohn Hodge <tpg@mutabah.net>2016-10-02 09:27:03 +0800
commit2338a0b913fa6e2867f4234a27e9bb69ad7b74a9 (patch)
treedaea40c17c7e43d3bb9a207ff84988584835ca59
parentb60cbd35a5a7fdb22b0d031a9d684c0d88c60157 (diff)
downloadmrust-2338a0b913fa6e2867f4234a27e9bb69ad7b74a9.tar.gz
HIR Typecheck Expr - Handle Self in trait_contains_method
-rw-r--r--src/hir_typeck/helpers.cpp23
-rw-r--r--src/hir_typeck/helpers.hpp2
2 files changed, 18 insertions, 7 deletions
diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp
index 4accaf56..a5fa7aa5 100644
--- a/src/hir_typeck/helpers.cpp
+++ b/src/hir_typeck/helpers.cpp
@@ -1678,6 +1678,7 @@ void TraitResolution::expand_associated_types_inplace__UfcsKnown(const Span& sp,
// 2. Crate-level impls
// TODO: Search for the actual trait containing this associated type
::HIR::GenericPath trait_path;
+ //if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), *pe.type, pe.item, trait_path) )
if( !this->trait_contains_type(sp, pe.trait, this->m_crate.get_trait_by_path(sp, pe.trait.m_path), pe.item, trait_path) )
BUG(sp, "Cannot find associated type " << pe.item << " anywhere in trait " << pe.trait);
//pe.trait = mv$(trait_path);
@@ -2373,7 +2374,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp,
return match;
}
-bool TraitResolution::trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, bool allow_move, ::HIR::GenericPath& out_path) const
+bool TraitResolution::trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::HIR::TypeRef& self, const ::std::string& name, bool allow_move, ::HIR::GenericPath& out_path) const
{
auto it = trait_ptr.m_values.find(name);
if( it != trait_ptr.m_values.end() ) {
@@ -2398,11 +2399,19 @@ bool TraitResolution::trait_contains_method(const Span& sp, const ::HIR::Generic
for(const auto& st : trait_ptr.m_parent_traits)
{
auto& st_ptr = this->m_crate.get_trait_by_path(sp, st.m_path.m_path);
- if( trait_contains_method(sp, st.m_path, st_ptr, name, allow_move, out_path) ) {
+ if( trait_contains_method(sp, st.m_path, st_ptr, self, name, allow_move, out_path) ) {
out_path.m_params = monomorphise_path_params_with(sp, mv$(out_path.m_params), [&](const auto& gt)->const auto& {
const auto& ge = gt.m_data.as_Generic();
- assert(ge.binding < 256);
- assert(ge.binding < trait_path.m_params.m_types.size());
+ if( ge.binding == 0xFFFF ) {
+ return self;
+ }
+ else if( (ge.binding >> 8) == 0 ) {
+ auto idx = ge.binding & 0xFF;
+ assert(idx < trait_path.m_params.m_types.size());
+ }
+ else {
+ BUG(sp, "Unexpected type parameter " << gt);
+ }
return trait_path.m_params.m_types[ge.binding];
}, false);
return true;
@@ -2620,9 +2629,11 @@ bool TraitResolution::find_method(
DEBUG("Bound `" << e.type << " : " << e.trait.m_path << "` - Matches " << ty);
::HIR::GenericPath final_trait_path;
assert(e.trait.m_trait_ptr);
- if( !this->trait_contains_method(sp, e.trait.m_path, *e.trait.m_trait_ptr, method_name, ar != AllowedReceivers::AnyBorrow, final_trait_path) )
+ if( !this->trait_contains_method(sp, e.trait.m_path, *e.trait.m_trait_ptr, ty, method_name, ar != AllowedReceivers::AnyBorrow, final_trait_path) )
continue ;
DEBUG("- Found trait " << final_trait_path);
+ // TODO: Re-monomorphise final trait using `ty`?
+ // - Could collide with legitimate uses of `Self`
// Found the method, return the UFCS path for it
fcn_path = ::HIR::Path( ::HIR::Path::Data::make_UfcsKnown({
@@ -2682,7 +2693,7 @@ bool TraitResolution::find_method(
{
ASSERT_BUG(sp, bound.m_trait_ptr, "Pointer to trait " << bound.m_path << " not set in " << e.trait.m_path);
::HIR::GenericPath final_trait_path;
- if( !this->trait_contains_method(sp, bound.m_path, *bound.m_trait_ptr, method_name, ar != AllowedReceivers::AnyBorrow, final_trait_path) )
+ if( !this->trait_contains_method(sp, bound.m_path, *bound.m_trait_ptr, ::HIR::TypeRef("Self", 0xFFFF), method_name, ar != AllowedReceivers::AnyBorrow, final_trait_path) )
continue ;
DEBUG("- Found trait " << final_trait_path);
diff --git a/src/hir_typeck/helpers.hpp b/src/hir_typeck/helpers.hpp
index 86ac4c15..daedf062 100644
--- a/src/hir_typeck/helpers.hpp
+++ b/src/hir_typeck/helpers.hpp
@@ -236,7 +236,7 @@ public:
bool find_method(const Span& sp, const HIR::t_trait_list& traits, const ::std::vector<unsigned>& ivars, const ::HIR::TypeRef& ty, const ::std::string& method_name, AllowedReceivers ar, /* Out -> */::HIR::Path& fcn_path) const;
/// Locates a named method in a trait, and returns the path of the trait that contains it (with fixed parameters)
- bool trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, bool allow_move, ::HIR::GenericPath& out_path) const;
+ bool trait_contains_method(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::HIR::TypeRef& self, const ::std::string& name, bool allow_move, ::HIR::GenericPath& out_path) const;
bool trait_contains_type(const Span& sp, const ::HIR::GenericPath& trait_path, const ::HIR::Trait& trait_ptr, const ::std::string& name, ::HIR::GenericPath& out_path) const;
bool type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const;