summaryrefslogtreecommitdiff
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
parent66b9f2589107f60041f024873512f93c9c8aee63 (diff)
downloadmrust-74868acb8e3db00cbab565abd6fbd76cbf763674.tar.gz
AST - Spanned paths in impl blocks, remove dead code
-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
-rw-r--r--src/dump_as_rust.cpp4
-rw-r--r--src/expand/derive.cpp12
-rw-r--r--src/hir/from_ast.cpp8
-rw-r--r--src/include/serialise.hpp6
-rw-r--r--src/include/span.hpp8
-rw-r--r--src/parse/root.cpp24
-rw-r--r--src/resolve/absolute.cpp27
-rw-r--r--src/types.cpp122
12 files changed, 89 insertions, 565 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
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp
index 4e233663..4091842a 100644
--- a/src/dump_as_rust.cpp
+++ b/src/dump_as_rust.cpp
@@ -667,9 +667,9 @@ void RustPrinter::handle_module(const AST::Module& mod)
m_os << "\n";
m_os << indent() << "impl";
print_params(i.def().params());
- if( i.def().trait() != AST::Path() )
+ if( i.def().trait().ent != AST::Path() )
{
- m_os << " " << i.def().trait() << " for";
+ m_os << " " << i.def().trait().ent << " for";
}
m_os << " " << i.def().type() << "\n";
diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp
index c14753e9..0270eaa6 100644
--- a/src/expand/derive.cpp
+++ b/src/expand/derive.cpp
@@ -24,7 +24,7 @@ static inline AST::ExprNodeP mk_exprnodep(AST::ExprNode* en){ return AST::ExprNo
/// Interface for derive handlers
struct Deriver
{
- virtual AST::Impl handle_item(const AST::GenericParams& params, const TypeRef& type, const AST::Struct& str) const = 0;
+ virtual AST::Impl handle_item(Span sp, const AST::GenericParams& params, const TypeRef& type, const AST::Struct& str) const = 0;
};
/// 'Debug' derive handler
@@ -45,7 +45,7 @@ class Deriver_Debug:
//}
public:
- AST::Impl handle_item(const AST::GenericParams& p, const TypeRef& type, const AST::Struct& str) const override
+ AST::Impl handle_item(Span sp, const AST::GenericParams& p, const TypeRef& type, const AST::Struct& str) const override
{
// TODO: be correct herhe and use "core" as the crate name
// - Requires handling the crate_name crate attribute correctly
@@ -118,7 +118,7 @@ public:
);
fcn.set_code( NEWNODE(AST::ExprNode_Block, vec$(mv$(node)), ::std::unique_ptr<AST::Module>()) );
- AST::Impl rv( AST::MetaItems(), p, type, debug_trait );
+ AST::Impl rv( AST::ImplDef( sp, AST::MetaItems(), p, make_spanned(sp, debug_trait), type ) );
rv.add_function(false, "fmt", mv$(fcn));
return mv$(rv);
}
@@ -137,7 +137,7 @@ static const Deriver* find_impl(const ::std::string& trait_name)
}
template<typename T>
-static void derive_item(AST::Module& mod, const AST::MetaItem& attr, const AST::Path& path, const T& item)
+static void derive_item(const Span& sp, AST::Module& mod, const AST::MetaItem& attr, const AST::Path& path, const T& item)
{
if( !attr.has_sub_items() ) {
//throw CompileError::Generic("#[derive()] requires a list of known traits to derive");
@@ -162,7 +162,7 @@ static void derive_item(AST::Module& mod, const AST::MetaItem& attr, const AST::
continue ;
}
- mod.add_impl( dp->handle_item(params, type, item) );
+ mod.add_impl( dp->handle_item(sp, params, type, item) );
}
if( fail ) {
@@ -181,7 +181,7 @@ public:
(
),
(Struct,
- derive_item(mod, attr, path, e);
+ derive_item(i.span, mod, attr, path, e);
)
)
}
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 2d5339ac..925f34f0 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -765,10 +765,10 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
auto params = LowerHIR_GenericParams(impl.def().params());
auto type = LowerHIR_Type(impl.def().type());
- if( impl.def().trait().is_valid() )
+ if( impl.def().trait().ent.is_valid() )
{
- bool is_marker = impl.def().trait().binding().as_Trait().trait_->is_marker();
- auto trait = LowerHIR_GenericPath(Span(), impl.def().trait());
+ bool is_marker = impl.def().trait().ent.binding().as_Trait().trait_->is_marker();
+ auto trait = LowerHIR_GenericPath(impl.def().trait().sp, impl.def().trait().ent);
auto trait_name = mv$(trait.m_path);
auto trait_args = mv$(trait.m_params);
@@ -844,7 +844,7 @@ void LowerHIR_Module_Impls(const ::AST::Module& ast_mod, ::HIR::Crate& hir_crat
{
auto params = LowerHIR_GenericParams(impl.params());
auto type = LowerHIR_Type(impl.type());
- auto trait = LowerHIR_GenericPath(Span(), impl.trait());
+ auto trait = LowerHIR_GenericPath(impl.trait().sp, impl.trait().ent);
auto trait_name = mv$(trait.m_path);
auto trait_args = mv$(trait.m_params);
diff --git a/src/include/serialise.hpp b/src/include/serialise.hpp
index 9af379e7..31abc358 100644
--- a/src/include/serialise.hpp
+++ b/src/include/serialise.hpp
@@ -130,7 +130,11 @@ public:
virtual void end_object(const char *tag) = 0;
::std::string start_object();
- void item(Serialisable& v);
+ void item(Serialisable& v);
+ Deserialiser& operator>>(Serialisable& v) {
+ this->item(v);
+ return *this;
+ }
template<typename T>
void item(::std::vector<T>& v) {
diff --git a/src/include/span.hpp b/src/include/span.hpp
index f57fa8a9..e7bd2694 100644
--- a/src/include/span.hpp
+++ b/src/include/span.hpp
@@ -56,9 +56,13 @@ struct Span
template<typename T>
struct Spanned
{
- Span m_span;
- T m_item;
+ Span sp;
+ T ent;
};
+template<typename T>
+Spanned<T> make_spanned(Span sp, T val) {
+ return Spanned<T> { ::std::move(sp), ::std::move(val) };
+}
#define ERROR(span, code, msg) do { ::Span(span).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0)
#define WARNING(span, code, msg) do { ::Span(span).warning(code, [&](::std::ostream& os) { os << msg; }); } while(0)
diff --git a/src/parse/root.cpp b/src/parse/root.cpp
index 4f856fbc..80cffdfe 100644
--- a/src/parse/root.cpp
+++ b/src/parse/root.cpp
@@ -15,6 +15,16 @@
#include "common.hpp"
#include <cassert>
+template<typename T>
+Spanned<T> get_spanned(TokenStream& lex, ::std::function<T()> f) {
+ auto ps = lex.start_span();
+ auto v = f();
+ return Spanned<T> {
+ lex.end_span(ps),
+ mv$(v)
+ };
+}
+
::std::string dirname(::std::string input) {
while( input.size() > 0 && input.back() != '/' ) {
input.pop_back();
@@ -828,6 +838,7 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i
{
TRACE_FUNCTION;
Token tok;
+ auto ps = lex.start_span();
AST::GenericParams params;
// 1. (optional) type parameters
@@ -841,13 +852,13 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i
}
// 2. Either a trait name (with type params), or the type to impl
- AST::Path trait_path;
+ Spanned<AST::Path> trait_path;
TypeRef impl_type;
// - Handle negative impls, which must be a trait
// "impl !Trait for Type {}"
if( GET_TOK(tok, lex) == TOK_EXCLAM )
{
- trait_path = Parse_Path(lex, PATH_GENERIC_TYPE);
+ trait_path = get_spanned< ::AST::Path>(lex, [&]() { return Parse_Path(lex, PATH_GENERIC_TYPE); });
GET_CHECK_TOK(tok, lex, TOK_RWORD_FOR);
impl_type = Parse_Type(lex);
@@ -860,7 +871,7 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i
// negative impls can't have any content
GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
- mod.add_neg_impl( AST::ImplDef( AST::MetaItems(), ::std::move(params), ::std::move(trait_path), ::std::move(impl_type) ) );
+ mod.add_neg_impl( AST::ImplDef(lex.end_span(ps), AST::MetaItems(), mv$(params), mv$(trait_path), mv$(impl_type) ) );
return ;
}
else
@@ -875,7 +886,10 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i
{
if( !impl_type.is_path() )
throw ParseError::Generic(lex, "Trait was not a path");
- trait_path = mv$(impl_type.path());
+ trait_path = Spanned< AST::Path> {
+ impl_type.span(),
+ mv$(impl_type.path())
+ };
// Implementing a trait for another type, get the target type
if( GET_TOK(tok, lex) == TOK_DOUBLE_DOT )
{
@@ -910,7 +924,7 @@ void Parse_Impl(TokenStream& lex, AST::Module& mod, AST::MetaItems attrs, bool i
GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
}
- AST::Impl impl( mv$(attrs), ::std::move(params), ::std::move(impl_type), ::std::move(trait_path) );
+ AST::Impl impl( AST::ImplDef( lex.end_span(ps), mv$(attrs), mv$(params), mv$(trait_path), mv$(impl_type) ) );
// A sequence of method implementations
while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index 45e70e98..103497e6 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -1257,20 +1257,21 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod )
for(auto& impl : mod.impls())
{
- if( ! impl.def().type().is_valid() )
+ auto& def = impl.def();
+ if( ! def.type().is_valid() )
{
- item_context.push(impl.def().params(), GenericSlot::Level::Top);
- Resolve_Absolute_Generic(item_context, impl.def().params());
- assert( impl.def().trait().is_valid() );
- Resolve_Absolute_Path(item_context, Span(), Context::LookupMode::Type, impl.def().trait());
+ item_context.push(def.params(), GenericSlot::Level::Top);
+ Resolve_Absolute_Generic(item_context, def.params());
+ assert( def.trait().ent.is_valid() );
+ Resolve_Absolute_Path(item_context, def.trait().sp, Context::LookupMode::Type, def.trait().ent);
if( impl.items().size() != 0 ) {
ERROR(Span(), E0000, "impl Trait for .. with methods");
}
- item_context.pop(impl.def().params());
+ item_context.pop(def.params());
- const_cast< ::AST::Trait*>(impl.def().trait().binding().as_Trait().trait_)->set_is_marker();
+ const_cast< ::AST::Trait*>(def.trait().ent.binding().as_Trait().trait_)->set_is_marker();
}
else
{
@@ -1279,14 +1280,14 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod )
Resolve_Absolute_Generic(item_context, impl.def().params());
Resolve_Absolute_Type(item_context, impl.def().type());
- if( impl.def().trait().is_valid() ) {
- Resolve_Absolute_Path(item_context, Span(), Context::LookupMode::Type, impl.def().trait());
+ if( def.trait().ent.is_valid() ) {
+ Resolve_Absolute_Path(item_context, def.trait().sp, Context::LookupMode::Type, def.trait().ent);
}
Resolve_Absolute_ImplItems(item_context, impl.items());
- item_context.pop(impl.def().params());
- item_context.pop_self( impl.def().type() );
+ item_context.pop(def.params());
+ item_context.pop_self( def.type() );
}
}
@@ -1297,9 +1298,9 @@ void Resolve_Absolute_Mod( Context item_context, ::AST::Module& mod )
Resolve_Absolute_Generic(item_context, impl_def.params());
Resolve_Absolute_Type(item_context, impl_def.type());
- if( !impl_def.trait().is_valid() )
+ if( !impl_def.trait().ent.is_valid() )
BUG(Span(), "Encountered negative impl with no trait");
- Resolve_Absolute_Path(item_context, Span(), Context::LookupMode::Type, impl_def.trait());
+ Resolve_Absolute_Path(item_context, impl_def.trait().sp, Context::LookupMode::Type, impl_def.trait().ent);
// No items
diff --git a/src/types.cpp b/src/types.cpp
index a75506d1..8a3ee638 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -392,128 +392,6 @@ void TypeRef::match_args(const TypeRef& other, ::std::function<void(const char*,
)
}
-bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) const
-{
- TU_MATCH(TypeData, (m_data), (ent),
- (None,
- throw CompileError::BugCheck("TypeRef::impls_wildcard on !");
- ),
- (Macro,
- throw CompileError::BugCheck("TypeRef::impls_wildcard - unexpanded macro");
- ),
- (Any,
- throw CompileError::BugCheck("TypeRef::impls_wildcard on _");
- ),
- // Generics are an error?
- (Generic,
- // TODO: Include an annotation to the GenericParams structure relevant to this type
- // - Allows searching the params for the impl, without having to pass the params down
- throw CompileError::Todo("TypeRef::impls_wildcard - param");
- ),
- // Primitives always impl
- (Unit, return true; ),
- (Primitive, return true; ),
- // Functions are pointers (currently), so they implement the trait
- (Function, return true; ),
- // Pointers/arrays inherit directly
- (Borrow,
- return crate.find_impl(trait, *ent.inner, nullptr, nullptr);
- ),
- (Pointer,
- return crate.find_impl(trait, *ent.inner, nullptr, nullptr);
- ),
- (Array,
- return crate.find_impl(trait, *ent.inner, nullptr, nullptr);
- ),
- // Tuples just destructure
- (Tuple,
- for( const auto& fld : ent.inner_types )
- {
- if( !crate.find_impl(trait, fld, nullptr, nullptr) )
- return false;
- }
- return true;
- ),
- // Path types destructure
- (Path,
- // - structs need all fields to impl this trait (cache result)
- // - same for enums, tuples, arrays, pointers...
- // - traits check the Self bounds
- // CATCH: Need to handle recursion, keep a list of currently processing paths and assume true if found
- TU_MATCH_DEF(AST::PathBinding, (ent.path.binding()), (info),
- (
- throw CompileError::Todo("wildcard impls - auto determine path");
- ),
- (Struct,
- const auto &s = *info.struct_;
- GenericResolveClosure resolve_fn( s.params(), ent.path.nodes().back().args() );
- TU_MATCH(::AST::StructData, (s.m_data), (e),
- (Struct,
- for(const auto& fld : e.ents)
- {
- auto fld_ty = fld.m_type;
- fld_ty.resolve_args( resolve_fn );
- DEBUG("- Fld '" << fld.m_name << "' := " << fld.m_type << " => " << fld_ty);
- if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) )
- return false;
- }
- ),
- (Tuple,
- for(const auto& fld : e.ents)
- {
- auto fld_ty = fld.m_type;
- fld_ty.resolve_args( resolve_fn );
- DEBUG("- Fld ? := " << fld.m_type << " => " << fld_ty);
- if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) )
- return false;
- }
- )
- )
- return true;
- ),
- (Enum,
- const auto& i = *info.enum_;
- GenericResolveClosure resolve_fn( i.params(), ent.path.nodes().back().args() );
- for( const auto& var : i.variants() )
- {
- TU_MATCH(AST::EnumVariantData, (var.m_data), (e),
- (Value,
- ),
- (Tuple,
- for( const auto& ty : e.m_sub_types )
- {
- TypeRef real_ty = ty;
- real_ty.resolve_args( resolve_fn );
- DEBUG("- Var '" << var.m_name << "' := " << ty << " => " << real_ty);
- if( !crate.find_impl(trait, real_ty, nullptr, nullptr) )
- return false;
- }
- ),
- (Struct,
- for( const auto& fld : e.m_fields )
- {
- auto fld_ty = fld.m_type;
- fld_ty.resolve_args( resolve_fn );
- DEBUG("- Fld '" << fld.m_name << "' := " << fld.m_type << " => " << fld_ty);
- if( !crate.find_impl(trait, fld_ty, nullptr, nullptr) )
- return false;
- }
- )
- )
- }
- return true;
- )
- )
- ),
- // MultiDST is special - It only impls if this trait is in the list
- // (or if a listed trait requires/impls the trait)
- (TraitObject,
- throw CompileError::Todo("TypeRef::impls_wildcard - MULTIDST");
- )
- )
- throw CompileError::BugCheck("TypeRef::impls_wildcard - Fell off end");
-}
-
/// Checks if the type is fully bounded
bool TypeRef::is_concrete() const
{