From 59cfce08eb46088f6fd1d4049cc8c7dbce355374 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 5 Apr 2015 11:33:57 +0800 Subject: Tag params with source, rewrite find_impl to return boolean --- src/ast/ast.cpp | 31 ++++++++++++++++++++----------- src/ast/ast.hpp | 18 +++++++++++++++++- src/convert/ast_iterate.cpp | 2 +- src/convert/resolve.cpp | 29 +++++++++++++++++++++++++---- src/types.cpp | 12 ++++++++++-- src/types.hpp | 5 +++++ 6 files changed, 78 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 03dc76d2..58c0a74b 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -284,10 +284,10 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) return true; } else if( type.is_reference() ) { - return check_impls_wildcard(trait, type.sub_types()[0]); + return find_impl(trait, type.sub_types()[0]).is_some(); } else if( type.is_pointer() ) { - return check_impls_wildcard(trait, type.sub_types()[0]); + return find_impl(trait, type.sub_types()[0]).is_some(); } else if( type.is_type_param() ) { // TODO: Include an annotation to the TypeParams structure relevant to this type @@ -310,7 +310,7 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) fld_ty.resolve_args( resolve_fn ); DEBUG("- Fld '" << fld.name << "' := " << fld.data << " => " << fld_ty); // TODO: Defer failure until after all fields are processed - if( !check_impls_wildcard(trait, fld_ty) ) + if( !find_impl(trait, fld_ty).is_some() ) return false; } return true; } @@ -325,7 +325,7 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) real_ty.resolve_args( resolve_fn ); DEBUG("- Var '" << var.m_name << "' := " << ty << " => " << real_ty); // TODO: Defer failure until after all fields are processed - if( !check_impls_wildcard(trait, real_ty) ) + if( !find_impl(trait, real_ty).is_some() ) return false; } } @@ -340,10 +340,12 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) } } -::rust::option Crate::find_impl(const Path& trait, const TypeRef& type) +bool Crate::find_impl(const Path& trait, const TypeRef& type, Impl** out_impl) { DEBUG("trait = " << trait << ", type = " << type); + if(out_impl) *out_impl = nullptr; + // 0. Handle generic bounds // TODO: Handle more complex bounds like "[T]: Trait" if( type.is_type_param() ) @@ -355,14 +357,19 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) // Search bounds for type: trait for( const auto& bound : tps.bounds() ) { + DEBUG("bound = " << bound); if( bound.is_trait() && bound.test() == type && bound.bound() == trait ) { // If found, success! + DEBUG("- Success!"); // TODO: What should be returned, kinda need to return a boolean - throw CompileError::Todo("find_impl - Return successful impl for generic"); + if(out_impl) throw CompileError::BugCheck("find_impl - Asking for a concrete impl, but generic passed"); + return true; } } // Else, failure - return ::rust::option(); + DEBUG("- No impl :("); + if(out_impl) throw CompileError::BugCheck("find_impl - Asking for a concrete impl, but generic passed"); + return false; } // TODO: Do a sort to allow a binary search @@ -377,10 +384,11 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) // This is a wildcard trait, need to locate either a negative, or check contents if( check_impls_wildcard(trait, type) ) { - return ::rust::option(impl); + if(out_impl) *out_impl = &impl; + return true; } else { - return ::rust::option(); + return false; } } @@ -395,11 +403,12 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) ::rust::option oimpl = impl.matches(trait, type); if( oimpl.is_some() ) { - return oimpl.unwrap(); + if(out_impl) *out_impl = &oimpl.unwrap(); + return true; } } DEBUG("No impl of " << trait << " for " << type); - return ::rust::option(); + return false; } Function& Crate::lookup_method(const TypeRef& type, const char *name) diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 2b60ba57..2f6ab45f 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -1,3 +1,10 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * ast/ast.hpp + * - Core AST header + */ #ifndef AST_HPP_INCLUDED #define AST_HPP_INCLUDED @@ -755,7 +762,16 @@ public: void post_parse(); - ::rust::option find_impl(const Path& trait, const TypeRef& type); + bool find_impl(const Path& trait, const TypeRef& type, Impl** out_impl); + ::rust::option find_impl(const Path& trait, const TypeRef& type) { + Impl* impl_ptr; + if( find_impl(trait, type, &impl_ptr) ) { + return ::rust::option(*impl_ptr); + } + else { + return ::rust::option(); + } + } Function& lookup_method(const TypeRef& type, const char *name); void load_extern_crate(::std::string name); diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index 35df8904..46ca4458 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -28,7 +28,7 @@ void CASTIterator::handle_params(AST::TypeParams& params) for( auto& param : params.ty_params() ) { handle_type(param.get_default()); - local_type( param.name(), TypeRef(TypeRef::TagArg(), param.name()) ); + local_type( param.name(), TypeRef(TypeRef::TagArg(), param.name(), params) ); } DEBUG("Bounds"); for( auto& bound : params.bounds() ) diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index bca0f576..029d368a 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -408,7 +408,8 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode throw ParseError::Generic("Type used in expression context?"); // Convert to a UFCS path DEBUG("Local type"); - auto np = AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), path[0].name()), TypeRef()); + // - "::nodes" + auto np = AST::Path(AST::Path::TagUfcs(), local.tr, TypeRef()); DEBUG("np = " << np); np.add_tailing(path); DEBUG("np = " << np); @@ -484,22 +485,42 @@ void CPathResolver::handle_type(TypeRef& type) if( type.is_path() && type.path().is_trivial() ) { const auto& name = type.path()[0].name(); + auto opt_local = lookup_local(LocalItem::TYPE, name); if( name == "Self" ) { // TODO: Handle "Self" correctly - // THIS IS WRONG! (well, I think) + // - Needs to be tagged with the soure params, but since Self is special... + // - Shouldn't matter, as Self should be resolved out before it needs that tagging type = TypeRef(TypeRef::TagArg(), "Self"); } - else if( lookup_local(LocalItem::TYPE, name).is_some() ) + else if( opt_local.is_some() ) { - type = TypeRef(TypeRef::TagArg(), name); + type = opt_local.unwrap().tr; } else { // Not a type param, fall back to other checks } } + else if( type.is_type_param() ) + { + const auto& name = type.type_param(); + auto opt_local = lookup_local(LocalItem::TYPE, name); + if( name == "Self" ) + { + // Good as it is + } + else if( opt_local.is_some() ) + { + type = opt_local.unwrap().tr; + } + else + { + // Not a type param, fall back to other checks + throw CompileError::Generic( FMT("CPathResolver::handle_type - Invalid parameter '" << name << "'") ); + } + } //if( type.is_type_param() && type.type_param() == "Self" ) //{ diff --git a/src/types.cpp b/src/types.cpp index 9d2e42d4..1925e579 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -378,8 +378,16 @@ Ordering TypeRef::ord(const TypeRef& x) const } return OrdEqual; case TypeRef::GENERIC: - DEBUG(*this << " == " << x); - throw ::std::runtime_error("BUGCHECK - Can't compare generic type"); + if( m_tagged_ptr != x.m_tagged_ptr ) + { + DEBUG(*this << " == " << x); + if( m_tagged_ptr ) DEBUG("- (L) " << *type_params_ptr()); + if( x.m_tagged_ptr ) DEBUG("- (R) " << *x.type_params_ptr()); + throw ::std::runtime_error("BUGCHECK - Can't compare mismatched generic types"); + } + else { + } + return m_path.ord( x.m_path ); case TypeRef::PATH: return m_path.ord( x.m_path ); case TypeRef::MULTIDST: diff --git a/src/types.hpp b/src/types.hpp index a5052c9b..c56875f9 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -144,6 +144,11 @@ public: m_path( ::std::move(name) ), m_tagged_ptr(nullptr) {} + TypeRef(TagArg, ::std::string name, const AST::TypeParams& params): + m_class(GENERIC), + m_path( ::std::move(name) ), + m_tagged_ptr(¶ms) + {} TypeRef(::std::string name): TypeRef(TagArg(), ::std::move(name)) {} -- cgit v1.2.3