From c2684e5058415746c83e38676f91bfc32d2ee6eb Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 31 Mar 2015 22:40:04 +0800 Subject: Root-level typecheck now up to requiring Sized --- src/ast/ast.cpp | 55 +++++++++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) (limited to 'src/ast/ast.cpp') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index c071e139..0ebc3e4e 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -92,37 +92,42 @@ Impl Impl::make_concrete(const ::std::vector& types) const if( type_match < 0 ) return ::rust::option(); DEBUG("Type " << type << " matches " << type_match); + // 2. If a parameter was seen, do the more expensive generic checks // > Involves checking that parameters are valid - if( trait_match > 0 ) - { - throw CompileError::Todo("Generic-ised match of impl trait"); - } - if( type_match > 0 ) + if( m_params.ty_params().size() ) { - throw CompileError::Todo("Generic-ised match of impl type"); - } - // 3. Return success - - if( m_params.ty_params().size() > 0 ) + if( trait_match == 0 && type_match == 0 ) + throw CompileError::Generic( "Unbound generic in impl" ); + } + + if( !(trait_match == 0 && type_match == 0) ) { ::std::vector param_types(m_params.ty_params().size()); try { - auto c = [&](const char* name,const TypeRef& ty){ + 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 < param_types.size() ); param_types[idx].merge_with( ty ); }; - throw CompileError::Todo("Match arguments in path for m_trait"); - //m_trait.match_args(TypeRef(trait), c); + m_trait.match_args(trait, c); m_type.match_args(type, c); - - // Check that conditions match - // - TODO: Requires locating/checking trait implementations on types - - // The above two will throw if matching failed, so if we get here, it's a match + } + catch(const CompileError::Base& e) + { + DEBUG("No match - " << e.what()); + return ::rust::option(); + } + + if( param_types.size() > 0 ) + { for( auto& i : m_concrete_impls ) { if( i.first == param_types ) @@ -130,22 +135,12 @@ Impl Impl::make_concrete(const ::std::vector& types) const return ::rust::option(i.second); } } + m_concrete_impls.push_back( make_pair(param_types, this->make_concrete(param_types)) ); return ::rust::option( m_concrete_impls.back().second ); } - catch( const ::std::runtime_error& e ) - { - DEBUG("No match - " << e.what()); - } } - else - { - if( m_trait == trait && m_type == type ) - { - return ::rust::option( *this ); - } - } - return ::rust::option(); + return ::rust::option( *this ); } ::std::ostream& operator<<(::std::ostream& os, const Impl& impl) -- cgit v1.2.3