diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-24 18:57:39 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-24 18:57:39 +0800 |
commit | 74868acb8e3db00cbab565abd6fbd76cbf763674 (patch) | |
tree | 1e3d1f59182df3e11b3726a4ceeb989596a4e6a6 /src/ast | |
parent | 66b9f2589107f60041f024873512f93c9c8aee63 (diff) | |
download | mrust-74868acb8e3db00cbab565abd6fbd76cbf763674.tar.gz |
AST - Spanned paths in impl blocks, remove dead code
Diffstat (limited to 'src/ast')
-rw-r--r-- | src/ast/ast.cpp | 179 | ||||
-rw-r--r-- | src/ast/ast.hpp | 45 | ||||
-rw-r--r-- | src/ast/crate.cpp | 196 | ||||
-rw-r--r-- | src/ast/crate.hpp | 23 |
4 files changed, 33 insertions, 410 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index c7202797..90fd8286 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -73,62 +73,20 @@ SERIALISE_TYPE(MetaItem::, "AST_MetaItem", { //s.item(m_sub_items);
})
-bool ImplDef::matches(::std::vector<TypeRef>& out_types, const Path& trait, const TypeRef& type) const
-{
- // 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 false;
- int type_match = m_type.equal_no_generic(type);
- if( type_match < 0 )
- return false;
- DEBUG("Match Tr:" <<trait_match << ", Ty:" << type_match << " for Trait " << trait << ", Type " << type);
-
- // 2. If a parameter was seen, do the more expensive generic checks
- // > Involves checking that parameters are valid
- if( m_params.ty_params().size() )
- {
- if( trait_match == 0 && type_match == 0 )
- throw CompileError::Generic( "Unbound generic in impl" );
- }
-
- // If there was a fuzzy match, then make it less fuzzy.
- if( !(trait_match == 0 && type_match == 0) )
- {
- out_types.clear();
- out_types.resize(m_params.ty_params().size());
- try
- {
- auto c = [&](const char* name,const TypeRef& ty) {
- if( strcmp(name, "Self") == 0 ) {
- if( ty != type )
- throw CompileError::Generic(FMT("Self mismatch : " << ty));
- return ;
- }
- int idx = m_params.find_name(name);
- assert( idx >= 0 );
- assert( (unsigned)idx < out_types.size() );
- out_types[idx].merge_with( ty );
- };
- m_trait.match_args(trait, c);
- m_type.match_args(type, c);
- }
- catch(const CompileError::Base& e)
- {
- DEBUG("No match - " << e.what());
- return false;
- }
-
- // TODO: Validate params against bounds?
- }
-
- // Perfect match
- return true;
+template<typename T>
+void operator<<(Serialiser& s, const Spanned<T>& x) {
+ //s << x.sp;
+ s << x.ent;
+}
+template<typename T>
+void operator>>(Deserialiser& s, Spanned<T>& x) {
+ //s >> x.sp;
+ s >> x.ent;
}
+
::std::ostream& operator<<(::std::ostream& os, const ImplDef& impl)
{
- return os << "impl<" << impl.m_params << "> " << impl.m_trait << " for " << impl.m_type << "";
+ return os << "impl<" << impl.m_params << "> " << impl.m_trait.ent << " for " << impl.m_type << "";
}
SERIALISE_TYPE(ImplDef::, "AST_ImplDef", {
s << m_params;
@@ -136,7 +94,7 @@ SERIALISE_TYPE(ImplDef::, "AST_ImplDef", { s << m_type;
},{
s.item(m_params);
- s.item(m_trait);
+ s >> m_trait;
s.item(m_type);
})
@@ -187,34 +145,7 @@ Impl& Impl::get_concrete(const ::std::vector<TypeRef>& param_types) Impl Impl::make_concrete(const ::std::vector<TypeRef>& types) const
{
- TRACE_FUNCTION_F("*this = " << *this << ", types={" << types << "}");
- assert(m_def.params().ty_params().size());
-
- GenericResolveClosure resolver(m_def.params(), types);
-
- Impl ret( MetaItems(), GenericParams(), m_def.type(), m_def.trait() );
- ret.m_def.trait().resolve_args( resolver );
- ret.m_def.type().resolve_args( resolver );
-
throw ParseError::Todo("Impl::make_concrete");
-/*
- for(const auto& fcn : m_functions)
- {
- GenericParams new_fcn_params = fcn.data.params();
- for( auto& b : new_fcn_params.bounds() )
- b.type().resolve_args(resolver);
- TypeRef new_ret_type = fcn.data.rettype();
- new_ret_type.resolve_args(resolver);
- Function::Arglist new_args = fcn.data.args();
- for( auto& t : new_args )
- t.second.resolve_args(resolver);
-
- ret.add_function( fcn.is_pub, fcn.name, Function( ::std::move(new_fcn_params), fcn.data.fcn_class(), ::std::move(new_ret_type), ::std::move(new_args), Expr() ) );
- }
-
- UNINDENT();
- return ret;
-*/
}
::std::ostream& operator<<(::std::ostream& os, const Impl& impl)
@@ -328,19 +259,6 @@ void Module::prescan() //}
}
-void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate)
-{
- for( auto& item : this->m_items )
- {
- TU_MATCH_DEF(::AST::Item, (item.data), (e),
- ( ),
- (Function,
- visitor(crate, *this, e);
- )
- )
- }
-}
-
template<typename T>
typename ::std::vector<Named<T> >::const_iterator find_named(const ::std::vector<Named<T> >& vec, const ::std::string& name)
{
@@ -722,79 +640,6 @@ int GenericParams::find_name(const char* name) const return -1;
}
-bool GenericParams::check_params(Crate& crate, const ::std::vector<TypeRef>& types) const
-{
- return check_params( crate, const_cast< ::std::vector<TypeRef>&>(types), false );
-}
-bool GenericParams::check_params(Crate& crate, ::std::vector<TypeRef>& types, bool allow_infer) const
-{
- // Check parameter counts
- if( types.size() > m_type_params.size() )
- {
- throw ::std::runtime_error(FMT("Too many generic params ("<<types.size()<<" passed, expecting "<< m_type_params.size()<<")"));
- }
- else if( types.size() < m_type_params.size() )
- {
- if( allow_infer )
- {
- while( types.size() < m_type_params.size() )
- {
- types.push_back( m_type_params[types.size()].get_default() );
- }
- }
- else
- {
- throw ::std::runtime_error(FMT("Too few generic params, (" << types.size() << " passed, expecting " << m_type_params.size() << ")"));
- }
- }
- else
- {
- // Counts are good, time to validate types
- }
-
- for( unsigned int i = 0; i < types.size(); i ++ )
- {
- auto& type = types[i];
- auto& param = m_type_params[i].name();
- TypeRef test(TypeRef::TagArg(), param);
- if( type.is_wildcard() )
- {
- for( const auto& bound : m_bounds )
- {
- if( bound.is_IsTrait() && bound.as_IsTrait().type == test )
- {
- const auto& trait = bound.as_IsTrait().trait;
- //const auto& ty_traits = type.traits();
-
- //auto it = ::std::find(ty_traits.begin(), ty_traits.end(), trait);
- //if( it == ty_traits.end() )
- {
- throw ::std::runtime_error( FMT("No matching impl of "<<trait<<" for "<<type));
- }
- }
- }
- }
- else
- {
- // Not a wildcard!
- // Check that the type fits the bounds applied to it
- for( const auto& bound : m_bounds )
- {
- if( bound.is_IsTrait() && bound.as_IsTrait().type == test )
- {
- const auto& trait = bound.as_IsTrait().trait;
- // Check if 'type' impls 'trait'
- if( !crate.find_impl(trait, TypeRef(Span(), trait), nullptr, nullptr) )
- {
- throw ::std::runtime_error( FMT("No matching impl of "<<trait<<" for "<<type));
- }
- }
- }
- }
- }
- return true;
-}
-
::std::ostream& operator<<(::std::ostream& os, const GenericParams& tps)
{
return os << "<" << tps.m_lifetime_params << "," << tps.m_type_params << "> where {" << tps.m_bounds << "}";
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 8b42c0bb..2c379f9a 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -357,9 +357,8 @@ public: m_data( StructData::make_Tuple({mv$(fields)}) )
{}
- const GenericParams& params() const { return m_params; }
-
- GenericParams& params() { return m_params; }
+ const GenericParams& params() const { return m_params; }
+ GenericParams& params() { return m_params; }
TypeRef get_field_type(const char *name, const ::std::vector<TypeRef>& args);
@@ -369,33 +368,33 @@ public: class ImplDef:
public Serialisable
{
+ Span m_span;
MetaItems m_attrs;
GenericParams m_params;
- Path m_trait;
+ Spanned<Path> m_trait;
TypeRef m_type;
public:
ImplDef() {}
ImplDef(ImplDef&&) /*noexcept*/ = default;
- ImplDef(MetaItems attrs, GenericParams params, Path trait_type, TypeRef impl_type):
- m_attrs( move(attrs) ),
- m_params( move(params) ),
- m_trait( move(trait_type) ),
- m_type( move(impl_type) )
+ ImplDef(Span sp, MetaItems attrs, GenericParams params, Spanned<Path> trait_type, TypeRef impl_type):
+ m_span( mv$(sp) ),
+ m_attrs( mv$(attrs) ),
+ m_params( mv$(params) ),
+ m_trait( mv$(trait_type) ),
+ m_type( mv$(impl_type) )
{}
ImplDef& operator=(ImplDef&&) = default;
// Accessors
const MetaItems& attrs() const { return m_attrs; }
+
const GenericParams& params() const { return m_params; }
- const Path& trait() const { return m_trait; }
+ GenericParams& params() { return m_params; }
+ const Spanned<Path>& trait() const { return m_trait; }
+ Spanned<Path>& trait() { return m_trait; }
const TypeRef& type() const { return m_type; }
+ TypeRef& type() { return m_type; }
- GenericParams& params() { return m_params; }
- Path& trait() { return m_trait; }
- TypeRef& type() { return m_type; }
-
- /// Compare this impl against a trait,type pair
- bool matches(::std::vector<TypeRef>& types, const Path& trait, const TypeRef& type) const;
friend ::std::ostream& operator<<(::std::ostream& os, const ImplDef& impl);
SERIALISABLE_PROTOTYPES();
@@ -405,6 +404,7 @@ class Impl: public Serialisable
{
ImplDef m_def;
+ Span m_span;
NamedList<Item> m_items;
//NamedList<TypeRef> m_types;
@@ -417,8 +417,8 @@ public: Impl() {}
Impl(Impl&&) /*noexcept*/ = default;
- Impl(MetaItems attrs, GenericParams params, TypeRef impl_type, Path trait_type):
- m_def( move(attrs), move(params), move(trait_type), move(impl_type) )
+ Impl(ImplDef def):
+ m_def( mv$(def) )
{}
Impl& operator=(Impl&&) = default;
@@ -468,8 +468,6 @@ struct UseStmt: SERIALISABLE_PROTOTYPES();
};
-typedef void fcn_visitor_t(const AST::Crate& crate, const AST::Module& mod, Function& fcn);
-
/// Representation of a parsed (and being converted) function
class Module:
public Serialisable
@@ -599,10 +597,10 @@ public: void add_submod(bool is_public, ::std::string name, Module mod, MetaItems attrs);
void add_impl(Impl impl) {
- m_impls.emplace_back( ::std::move(impl) );
+ m_impls.emplace_back( mv$(impl) );
}
void add_neg_impl(ImplDef impl) {
- m_neg_impls.emplace_back( ::std::move(impl) );
+ m_neg_impls.emplace_back( mv$(impl) );
}
void add_macro(bool is_exported, ::std::string name, MacroRulesPtr macro);
void add_macro_import(::std::string name, const MacroRules& mr) {
@@ -622,8 +620,6 @@ public: return m_anon_modules.size()-1;
}
- void iterate_functions(fcn_visitor_t* visitor, const Crate& crate);
-
const ::AST::Path& path() const { return m_my_path; }
ItemRef find_item(const ::std::string& needle, bool allow_leaves = true, bool ignore_private_wildcard = true) const;
@@ -675,6 +671,7 @@ TAGGED_UNION_EX(Item, (: public Serialisable), None, (
public:
MetaItems attrs;
+ Span span;
SERIALISABLE_PROTOTYPES();
)
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index 500598b0..369ef33d 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -46,10 +46,6 @@ void Crate::load_externs() } -void Crate::iterate_functions(fcn_visitor_t* visitor) -{ - m_root_module.iterate_functions(visitor, *this); -} Module& Crate::get_root_module(const ::std::string& name) { return const_cast<Module&>( const_cast<const Crate*>(this)->get_root_module(name) ); } @@ -63,198 +59,6 @@ const Module& Crate::get_root_module(const ::std::string& name) const { throw ParseError::Generic("crate name unknown"); } -bool Crate::is_trait_implicit(const Path& trait) const -{ - // 1. Handle lang_item traits (e.g. FhantomFn) - if( m_lang_item_PhantomFn.is_valid() && trait.equal_no_generic( m_lang_item_PhantomFn ) >= 0 ) - { - return true; - } - return false; -} - -/** - * \brief Checks if a type implements the provided wildcard trait - * \param trait Trait path - * \param type Type in question - * \note Wildcard trait = A trait for which there exists a 'impl Trait for ..' definition - * - * \return True if the trait is implemented (either exlicitly, or implicitly) - */ -bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) const -{ - ::std::vector<TypeRef> _params; - TRACE_FUNCTION_F("trait="<<trait<<", type="<<type); - - // 1. Look for a negative impl for this type - for( auto implptr : m_neg_impl_index ) - { - const ImplDef& neg_impl = *implptr; - - if( neg_impl.matches(_params, trait, type) ) - { - return false; - } - } - DEBUG("No negative impl of " << trait << " for " << type); - - // 2. Look for a positive impl for this type (i.e. an unsafe impl) - for( auto implptr : m_impl_index ) - { - const Impl& impl = *implptr; - if( impl.def().matches(_params, trait, type) ) - { - return true; - } - } - DEBUG("No positive impl of " << trait << " for " << type); - - // 3. If none found, destructure the type - return type.impls_wildcard(*this, trait); -} - - -bool Crate::find_inherent_impls(const TypeRef& type, ::std::function<bool(const Impl& , ::std::vector<TypeRef> )> callback) const -{ - assert( !type.is_type_param() ); - - for( auto implptr : m_impl_index ) - { - Impl& impl = *implptr; - if( impl.def().trait().is_valid() ) - { - // Trait - } - else - { - DEBUG("- " << impl.def()); - ::std::vector<TypeRef> out_params; - if( impl.def().matches(out_params, AST::Path(), type) ) - { - if( callback(impl, out_params) ) { - return true; - } - } - } - } - - return false; -} - -::rust::option<ImplRef> Crate::find_impl(const Path& trait, const TypeRef& type) const -{ - ::std::vector<TypeRef> params; - Impl *out_impl; - if( find_impl(trait, type, &out_impl, ¶ms) ) - { - return ::rust::Some( ImplRef(*out_impl, params) ); - } - else { - return ::rust::None<ImplRef>(); - } -} - -bool Crate::find_impl(const Path& trait, const TypeRef& type, Impl** out_impl, ::std::vector<TypeRef>* out_params) const -{ - TRACE_FUNCTION_F("trait = " << trait << ", type = " << type); - - // If no params output provided, use a dud locaton - ::std::vector<TypeRef> dud_params; - if(out_params) - *out_params = ::std::vector<TypeRef>(); - else - out_params = &dud_params; - - // Zero output - if(out_impl) - *out_impl = nullptr; - - if( is_trait_implicit(trait) ) - { - if(out_impl) throw CompileError::BugCheck("find_impl - Asking for concrete impl of a marker trait"); - return true; - } - - // 0. Handle generic bounds - // TODO: Handle more complex bounds like "[T]: Trait" - if( type.is_type_param() ) - { - if( trait.is_valid() ) - { - assert(type.type_params_ptr()); - // Search bounds for type: trait - for( const auto& bound : type.type_params_ptr()->bounds() ) - { - DEBUG("bound = " << bound); - TU_MATCH_DEF(GenericBound, (bound), (ent), - (), - (IsTrait, - if(ent.type == type && ent.trait == trait) { - // If found, success! - DEBUG("- Success!"); - // TODO: What should be returned, kinda need to return a boolean - if(out_impl) throw CompileError::BugCheck("find_impl - Asking for a concrete impl, but generic passed"); - return true; - } - ) - ) - } - // Else, failure - DEBUG("- No impl :("); - //if(out_impl) throw CompileError::BugCheck("find_impl - Asking for a concrete impl, but generic passed"); - return false; - } - else - { - DEBUG("- No inherent impl for generic params"); - return false; - } - } - - // TODO: Do a sort to allow a binary search - // 1. Search for wildcard traits (i.e. ones like "impl Send for ..") - // - These require special handling, as negatives apply - for( auto implptr : m_impl_index ) - { - Impl& impl = *implptr; - ::std::vector<TypeRef> _p; - if( impl.def().matches(_p, trait, TypeRef()) ) - { - assert(_p.size() == 0); - // This is a wildcard trait, need to locate either a negative, or check contents - if( check_impls_wildcard(trait, type) ) - { - if(out_impl) *out_impl = &impl; - return true; - } - else { - return false; - } - } - - } - - // 2. Check real impls - DEBUG("Not wildcard"); - for( auto implptr : m_impl_index ) - { - Impl& impl = *implptr; - // TODO: What if there's two impls that match this combination? - if( impl.def().matches(*out_params, trait, type) ) - { - if(out_impl) *out_impl = &impl; - return true; - } - } - DEBUG("No impl of " << trait << " for " << type); - return false; -} - -Function& Crate::lookup_method(const TypeRef& type, const char *name) -{ - throw ParseError::Generic( FMT("TODO: Lookup method "<<name<<" for type " <<type)); -} - void Crate::load_extern_crate(::std::string name) { ::std::ifstream is("output/"+name+".ast"); diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index b88b9307..0306205b 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -46,32 +46,9 @@ public: /// Load referenced crates void load_externs(); - bool is_trait_implicit(const Path& trait) const; - - - //::std::vector<ImplRef> find_inherent_impls(const TypeRef& type) const; - bool find_inherent_impls(const TypeRef& type, ::std::function<bool(const Impl& , ::std::vector<TypeRef> )>) const; - ::rust::option<ImplRef> find_impl(const Path& trait, const TypeRef& type) const; - bool find_impl(const Path& trait, const TypeRef& type, Impl** out_impl, ::std::vector<TypeRef>* out_prams=nullptr) const; - const ::rust::option<Impl&> get_impl(const Path& trait, const TypeRef& type) { - Impl* impl_ptr; - ::std::vector<TypeRef> params; - if( find_impl(trait, type, &impl_ptr, ¶ms) ) { - return ::rust::option<Impl&>( impl_ptr->get_concrete(params) ); - } - else { - return ::rust::option<Impl&>(); - } - } - Function& lookup_method(const TypeRef& type, const char *name); - void load_extern_crate(::std::string name); - void iterate_functions( fcn_visitor_t* visitor ); - SERIALISABLE_PROTOTYPES(); -private: - bool check_impls_wildcard(const Path& trait, const TypeRef& type) const; }; /// Representation of an imported crate |