summaryrefslogtreecommitdiff
path: root/src/ast
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-24 18:57:39 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-24 18:57:39 +0800
commit74868acb8e3db00cbab565abd6fbd76cbf763674 (patch)
tree1e3d1f59182df3e11b3726a4ceeb989596a4e6a6 /src/ast
parent66b9f2589107f60041f024873512f93c9c8aee63 (diff)
downloadmrust-74868acb8e3db00cbab565abd6fbd76cbf763674.tar.gz
AST - Spanned paths in impl blocks, remove dead code
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/ast.cpp179
-rw-r--r--src/ast/ast.hpp45
-rw-r--r--src/ast/crate.cpp196
-rw-r--r--src/ast/crate.hpp23
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, &params) )
- {
- 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, &params) ) {
- 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