diff options
author | John Hodge <tpg@mutabah.net> | 2015-04-05 11:33:57 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-04-05 11:33:57 +0800 |
commit | 59cfce08eb46088f6fd1d4049cc8c7dbce355374 (patch) | |
tree | 6135d40eaedc41ea2ea3296887f7a59901693134 /src | |
parent | 1e02026fb0edb878361c1b7f59d30dae02f4abc9 (diff) | |
download | mrust-59cfce08eb46088f6fd1d4049cc8c7dbce355374.tar.gz |
Tag params with source, rewrite find_impl to return boolean
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 31 | ||||
-rw-r--r-- | src/ast/ast.hpp | 18 | ||||
-rw-r--r-- | src/convert/ast_iterate.cpp | 2 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 29 | ||||
-rw-r--r-- | src/types.cpp | 12 | ||||
-rw-r--r-- | src/types.hpp | 5 |
6 files changed, 78 insertions, 19 deletions
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<Impl&> 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<Impl&>();
+ 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&>(impl);
+ if(out_impl) *out_impl = &impl;
+ return true;
}
else {
- return ::rust::option<Impl&>();
+ return false;
}
}
@@ -395,11 +403,12 @@ bool Crate::check_impls_wildcard(const Path& trait, const TypeRef& type) ::rust::option<Impl&> 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<Impl&>();
+ 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<Impl&> find_impl(const Path& trait, const TypeRef& type);
+ bool find_impl(const Path& trait, const TypeRef& type, Impl** out_impl);
+ ::rust::option<Impl&> find_impl(const Path& trait, const TypeRef& type) {
+ Impl* impl_ptr;
+ if( find_impl(trait, type, &impl_ptr) ) {
+ return ::rust::option<Impl&>(*impl_ptr);
+ }
+ else {
+ return ::rust::option<Impl&>();
+ }
+ }
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());
+ // - "<Type as _>::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))
{}
|