diff options
| author | John Hodge <tpg@mutabah.net> | 2015-03-22 14:46:48 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@mutabah.net> | 2015-03-22 14:46:48 +0800 | 
| commit | fc9a04403eb5b694d37f77baa0de2f8e363f46f1 (patch) | |
| tree | 0f85ba516b784d6151fd45555b86d50c533e909f /src | |
| parent | 5aac662e859d10f42b541405fa0b8d14a1c1e2a8 (diff) | |
| download | mrust-fc9a04403eb5b694d37f77baa0de2f8e363f46f1.tar.gz | |
Parsing "Composite" DSTs (Trait + Trait2 + Trait3)
Diffstat (limited to 'src')
| -rw-r--r-- | src/parse/root.cpp | 2 | ||||
| -rw-r--r-- | src/parse/types.cpp | 28 | ||||
| -rw-r--r-- | src/types.hpp | 8 | 
3 files changed, 33 insertions, 5 deletions
| diff --git a/src/parse/root.cpp b/src/parse/root.cpp index c88b51a5..759c65ac 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -666,6 +666,8 @@ AST::Impl Parse_Impl(TokenStream& lex, bool is_unsafe/*=false*/)          lex.putback(tok);
          impl_type = Parse_Type(lex);
 +        // TODO: Handle the "impl Any + Send" syntax here
 +        
          if( GET_TOK(tok, lex) == TOK_RWORD_FOR )
          {
              // Implementing a trait for another type, get the target type
 diff --git a/src/parse/types.cpp b/src/parse/types.cpp index aa29af64..57c1bad8 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -65,6 +65,7 @@ TypeRef Parse_Type(TokenStream& lex)      // '<' - An associated type cast      case TOK_LT: {          DEBUG("Associated type"); +        // TODO: This should instead use the path code, not a special case in typing          // <Type as Trait>::Inner          TypeRef base = Parse_Type(lex);          GET_CHECK_TOK(tok, lex, TOK_RWORD_AS); @@ -86,12 +87,29 @@ TypeRef Parse_Type(TokenStream& lex)              if( tok.str() == CORETYPES[i].name )                  return TypeRef(TypeRef::TagPrimitive(), CORETYPES[i].type);          } -        lex.putback(tok); -        return TypeRef(TypeRef::TagPath(), Parse_Path(lex, false, PATH_GENERIC_TYPE)); // relative path +        // - Fall through to path handling      // '::' - Absolute path -    case TOK_DOUBLE_COLON: -        // Path with generics -        return TypeRef(TypeRef::TagPath(), Parse_Path(lex, true, PATH_GENERIC_TYPE)); +    case TOK_DOUBLE_COLON: { +        lex.putback(tok); +        ::std::vector<AST::Path>    traits; +        ::std::vector< ::std::string>   lifetimes; +        do { +            if( LOOK_AHEAD(lex) == TOK_LIFETIME ) { +                GET_TOK(tok, lex); +                lifetimes.push_back( tok.str() ); +            } +            else +                traits.push_back( Parse_Path(lex, PATH_GENERIC_TYPE) ); +        } while( GET_TOK(tok, lex) == TOK_PLUS ); +        lex.putback(tok); +        if( traits.size() > 1 || lifetimes.size() > 0 ) { +            if( lifetimes.size() ) +                DEBUG("TODO: Lifetime bounds on trait objects"); +            return TypeRef(::std::move(traits)); +        } +        else  +            return TypeRef(TypeRef::TagPath(), traits.at(0)); +        }      // 'super' - Parent relative path      case TOK_RWORD_SUPER:          GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); diff --git a/src/types.hpp b/src/types.hpp index 9505f2cd..86733ad1 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -55,6 +55,7 @@ class TypeRef:          ARRAY,
          GENERIC,
          PATH,
 +        MULTIDST,   // Multi-trait DST (e.g. Trait + Send + Sync)
          ASSOCIATED,
      };
 @@ -147,6 +148,13 @@ public:          TypeRef(TagPath(), ::std::move(path))
      {}
 +    TypeRef( ::std::vector<AST::Path> traits ):
 +        m_class(MULTIDST)
 +    {
 +        for( auto& t : traits )
 +            m_inner_types.push_back( TypeRef(::std::move(t)) );
 +    }
 +    
      struct TagAssoc {};
      TypeRef(TagAssoc, TypeRef base, TypeRef trait, ::std::string assoc_name):
          TypeRef(::std::move(base), ::std::move(trait), ::std::move(assoc_name))
 | 
