diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-29 19:20:03 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-29 19:20:03 +0800 |
commit | 36439817677e14fd95932a5f6e4134799682e35e (patch) | |
tree | 40874923b66223f8ea54dcd61cff6aeeea71af34 | |
parent | c6bf13f352d333b0a58b9789a7f4df8d1eb4b52f (diff) | |
download | mrust-36439817677e14fd95932a5f6e4134799682e35e.tar.gz |
Resolve Abs - Hacking up extern support
-rw-r--r-- | src/ast/crate.cpp | 3 | ||||
-rw-r--r-- | src/ast/crate.hpp | 1 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 47 |
3 files changed, 46 insertions, 5 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index b9915bc8..fe084b54 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -62,7 +62,8 @@ void Crate::load_extern_crate(const ::std::string& name) m_extern_crates.insert(::std::make_pair( name, ExternCrate { name, "output/lib"+name+".hir" } )); } -ExternCrate::ExternCrate(const ::std::string& name, const ::std::string& path) +ExternCrate::ExternCrate(const ::std::string& name, const ::std::string& path): + m_name(name) { m_hir = HIR_Deserialise(path, name); diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index 3b01d221..4b8a42c5 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -57,6 +57,7 @@ public: class ExternCrate { public: + ::std::string m_name; ::HIR::CratePtr m_hir; ExternCrate(const ::std::string& name, const ::std::string& path); diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index 0cffc347..5c18aa25 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -548,10 +548,14 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L { // Trait is specified, definitely a trait item // - Must resolve here - if( ! ufcs.trait->binding().is_Trait() ) { + const auto& pb = ufcs.trait->binding(); + if( ! pb.is_Trait() ) { ERROR(sp, E0000, "UFCS trait was not a trait - " << *ufcs.trait); } - const auto& tr = *ufcs.trait->binding().as_Trait().trait_; + if( !pb.as_Trait().trait_ ) + return ; + assert( pb.as_Trait().trait_ ); + const auto& tr = *pb.as_Trait().trait_; switch(mode) { @@ -591,7 +595,7 @@ void Resolve_Absolute_Path_BindUFCS(Context& context, const Span& sp, Context::L path.bind_function(e); ), (Static, - // Resolve to asociated type + // Resolve to asociated static ) ) } @@ -704,7 +708,42 @@ namespace { hmod = &e; ), (Trait, - TODO(sp, "Bind via extern trait - " << path); + auto trait_path = ::AST::Path( crate.m_name, {} ); + for(unsigned int j = start; j <= i; j ++) + trait_path.nodes().push_back( path_abs.nodes[j].name() ); + if( !n.args().is_empty() ) { + trait_path.nodes().back().args() = mv$(n.args()); + } + trait_path.bind( ::AST::PathBinding::make_Trait({nullptr}) ); + + ::AST::Path new_path; + const auto& next_node = path_abs.nodes[i+1]; + // TODO: If the named item can't be found in the trait, fall back to it being a type binding + // - What if this item is from a nested trait? + bool found = false; + switch( i+1 < path_abs.nodes.size() ? Context::LookupMode::Namespace : mode ) + { + case Context::LookupMode::Namespace: + case Context::LookupMode::Type: + case Context::LookupMode::Pattern: + found = (e.m_types.find( next_node.name() ) != e.m_types.end()); + case Context::LookupMode::Constant: + case Context::LookupMode::Variable: + found = (e.m_values.find( next_node.name() ) != e.m_values.end()); + break; + } + + if( !found ) { + new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(sp, mv$(trait_path))); + } + else { + new_path = ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(), mv$(trait_path)); + } + for( unsigned int j = i+1; j < path_abs.nodes.size(); j ++ ) + new_path.nodes().push_back( mv$(path_abs.nodes[j]) ); + + path = mv$(new_path); + return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); ), (TypeAlias, path = split_into_ufcs_ty(sp, mv$(path), i); |