diff options
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/ast.cpp | 24 | ||||
-rw-r--r-- | src/ast/path.cpp | 25 | ||||
-rw-r--r-- | src/ast/path.hpp | 3 |
3 files changed, 51 insertions, 1 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index b8e6d381..4c400a47 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -80,7 +80,29 @@ Impl Impl::make_concrete(const ::std::vector<TypeRef>& types) const ::rust::option<Impl&> Impl::matches(const Path& trait, const TypeRef& type)
{
- DEBUG("this = " << *this);
+ //DEBUG("this = " << *this);
+
+ // 1. Check the type/trait counting parameters as wildcards (but flagging if one was seen)
+ // > If that fails, just early return
+ int trait_match = m_trait.equal_no_generic(trait);
+ if( trait_match < 0 )
+ return ::rust::option<Impl&>();
+ DEBUG("Trait " << trait << " matches " << trait_match);
+ int type_match = m_type.equal_no_generic(type);
+ if( type_match < 0 )
+ return ::rust::option<Impl&>();
+ DEBUG("Type " << type << " matches " << type_match);
+ // 2. If a parameter was seen, do the more expensive generic checks
+ // > Involves checking that parameters are valid
+ if( trait_match > 0 )
+ {
+ throw CompileError::Todo("Generic-ised match of impl trait");
+ }
+ if( type_match > 0 )
+ {
+ throw CompileError::Todo("Generic-ised match of impl type");
+ }
+ // 3. Return success
if( m_params.ty_params().size() > 0 )
{
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 381685a9..7fa630f9 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -361,6 +361,31 @@ Path& Path::operator+=(const Path& other) return *this; } +int Path::equal_no_generic(const Path& x) const +{ + if( m_class != x.m_class ) + return -1; + if( m_crate != x.m_crate ) + return -1; + + unsigned int i = 0; + for( const auto &e : m_nodes ) + { + if( i >= x.m_nodes.size() ) + return -1; + const auto& xe = x.m_nodes[i]; + if( e.name() != xe.name() ) + return -1; + + if( e.args().size() || xe.args().size() ) + throw CompileError::Todo("Handle Path::equal_no_generic with generic"); + + i ++; + } + + return 0; +} + Ordering Path::ord(const Path& x) const { Ordering rv; diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 2355c88b..21d2dd51 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -264,6 +264,9 @@ public: PathNode& operator[](int idx) { if(idx>=0) return m_nodes[idx]; else return m_nodes[size()+idx]; } const PathNode& operator[](int idx) const { if(idx>=0) return m_nodes[idx]; else return m_nodes[size()+idx]; } + /// Returns 0 if paths are identical, 1 if TypeRef::TagArg is present in one, and -1 if a node differs + int equal_no_generic(const Path& x) const; + Ordering ord(const Path& x) const; bool operator==(const Path& x) const { return ord(x) == OrdEqual; } bool operator!=(const Path& x) const { return ord(x) != OrdEqual; } |