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 | |
parent | 66b9f2589107f60041f024873512f93c9c8aee63 (diff) | |
download | mrust-74868acb8e3db00cbab565abd6fbd76cbf763674.tar.gz |
AST - Spanned paths in impl blocks, remove dead code
Diffstat (limited to 'src')
-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 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 4 | ||||
-rw-r--r-- | src/expand/derive.cpp | 12 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 8 | ||||
-rw-r--r-- | src/include/serialise.hpp | 6 | ||||
-rw-r--r-- | src/include/span.hpp | 8 | ||||
-rw-r--r-- | src/parse/root.cpp | 24 | ||||
-rw-r--r-- | src/resolve/absolute.cpp | 27 | ||||
-rw-r--r-- | src/types.cpp | 122 |
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, ¶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 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 { |