diff options
author | SimplyTheOther <simplytheother@gmail.com> | 2020-12-09 15:29:51 +0800 |
---|---|---|
committer | SimplyTheOther <simplytheother@gmail.com> | 2020-12-09 15:29:51 +0800 |
commit | 41c14b45ac604ebd69a6715445cdb10fc5c5ec07 (patch) | |
tree | fb9e6c7e60b9024b1857c0fcf6241c118f2f67f4 /gcc/rust/analysis | |
parent | 815c9e8b0734d45a6e5b5a7d50f38d4af7120a8c (diff) | |
parent | cef34bd730d80b4664d8633e2cc27a64c5cae246 (diff) | |
download | gcc-41c14b45ac604ebd69a6715445cdb10fc5c5ec07.zip gcc-41c14b45ac604ebd69a6715445cdb10fc5c5ec07.tar.gz gcc-41c14b45ac604ebd69a6715445cdb10fc5c5ec07.tar.bz2 |
Merge branch 'master' of https://github.com/redbrain/gccrs
Diffstat (limited to 'gcc/rust/analysis')
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.cc | 245 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.h | 25 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-visitor.h | 261 |
3 files changed, 515 insertions, 16 deletions
diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc index 3e2db7f..f1edec8 100644 --- a/gcc/rust/analysis/rust-type-resolution.cc +++ b/gcc/rust/analysis/rust-type-resolution.cc @@ -1,5 +1,6 @@ #include "rust-type-resolution.h" #include "rust-diagnostics.h" +#include "rust-type-visitor.h" #define ADD_BUILTIN_TYPE(_X, _S) \ do \ @@ -104,7 +105,13 @@ TypeResolution::typesAreCompatible (AST::Type *lhs, AST::Type *rhs, } AST::Type *val = NULL; - return scope.LookupType (lhsTypeStr, &val); + if (!scope.LookupType (lhsTypeStr, &val)) + { + rust_error_at (locus, "Unknown type: %s", lhsTypeStr.c_str ()); + return false; + } + + return true; } bool @@ -395,19 +402,133 @@ TypeResolution::visit (AST::CompoundAssignmentExpr &expr) void TypeResolution::visit (AST::GroupedExpr &expr) {} -// void TypeResolution::visit(ArrayElems& elems) {} + void TypeResolution::visit (AST::ArrayElemsValues &elems) -{} +{ + // we need to generate the AST::ArrayType for this array init_expression + // we can get the size via get_num_values() but we need to ensure each element + // are type compatible + + bool failed = false; + AST::Type *last_inferred_type = nullptr; + elems.iterate ([&] (AST::Expr *expr) mutable -> bool { + size_t before; + before = typeBuffer.size (); + expr->accept_vis (*this); + if (typeBuffer.size () <= before) + { + rust_error_at (expr->get_locus_slow (), + "unable to determine element type"); + return false; + } + + AST::Type *inferedType = typeBuffer.back (); + typeBuffer.pop_back (); + + if (last_inferred_type == nullptr) + last_inferred_type = inferedType; + else + { + if (!typesAreCompatible (last_inferred_type, inferedType, + expr->get_locus_slow ())) + { + failed = true; + return false; + } + } + + return true; + }); + + // nothing to do when its failed + if (failed) + return; + + // FIXME This will leak + auto capacity + = new AST::LiteralExpr (std::to_string (elems.get_num_values ()), + AST::Literal::INT, + Linemap::predeclared_location ()); + auto arrayType = new AST::ArrayType (last_inferred_type->clone_type (), + std::unique_ptr<AST::Expr> (capacity), + Linemap::predeclared_location ()); + typeBuffer.push_back (arrayType); +} + void TypeResolution::visit (AST::ArrayElemsCopied &elems) -{} +{ + printf ("ArrayElemsCopied: %s\n", elems.as_string ().c_str ()); +} + void TypeResolution::visit (AST::ArrayExpr &expr) -{} +{ + auto& elements = expr.get_array_elems (); + + auto before = typeBuffer.size (); + elements->accept_vis (*this); + if (typeBuffer.size () <= before) + { + rust_error_at (expr.get_locus_slow (), + "unable to determine type for ArrayExpr"); + return; + } + + expr.set_inferred_type (typeBuffer.back ()); +} + void TypeResolution::visit (AST::ArrayIndexExpr &expr) -{} +{ + auto before = typeBuffer.size (); + expr.get_array_expr ()->accept_vis (*this); + if (typeBuffer.size () <= before) + { + rust_error_at (expr.get_locus_slow (), + "unable to determine type for array index expression"); + return; + } + AST::Type *array_expr_type = typeBuffer.back (); + typeBuffer.pop_back (); + + before = typeBuffer.size (); + expr.get_index_expr ()->accept_vis (*this); + if (typeBuffer.size () <= before) + { + rust_error_at (expr.get_index_expr ()->get_locus_slow (), + "unable to determine type for index expression"); + return; + } + + AST::Type *array_index_type = typeBuffer.back (); + typeBuffer.pop_back (); + + // check the index_type should be an i32 which should really be + // more permissive + AST::Type *i32 = nullptr; + scope.LookupType ("i32", &i32); + rust_assert (i32 != nullptr); + + if (!typesAreCompatible (array_index_type, i32, + expr.get_index_expr ()->get_locus_slow ())) + { + return; + } + + // the the element type from the array_expr_type and it _must_ be an array + AST::ArrayType *resolved = ArrayTypeVisitor::Resolve (array_expr_type); + if (resolved == nullptr) + { + rust_error_at (expr.get_locus_slow (), + "unable to resolve type for array expression"); + return; + } + + typeBuffer.push_back (resolved->get_elem_type ().get ()); +} + void TypeResolution::visit (AST::TupleExpr &expr) {} @@ -516,6 +637,10 @@ TypeResolution::visit (AST::StructExprStructFields &expr) } } + // need to correct the ordering with the respect to the struct definition and + // ensure we handle missing values and give them defaults + // FIXME + // setup a path in type AST::PathIdentSegment seg (expr.get_struct_name ().as_string ()); auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( @@ -649,9 +774,42 @@ TypeResolution::visit (AST::RangeFromToInclExpr &expr) void TypeResolution::visit (AST::RangeToInclExpr &expr) {} + void TypeResolution::visit (AST::ReturnExpr &expr) -{} +{ + // Ensure the type of this matches the function + auto before = typeBuffer.size (); + expr.get_returned_expr ()->accept_vis (*this); + + if (typeBuffer.size () <= before) + { + rust_error_at (expr.get_returned_expr ()->get_locus_slow (), + "unable to determine type for return expr"); + return; + } + + auto inferedType = typeBuffer.back (); + typeBuffer.pop_back (); + + // check this is compatible with the return type + // this will again have issues with structs before we move to HIR + + auto function = scope.CurrentFunction (); + if (!function->has_return_type ()) + { + rust_error_at (expr.get_locus (), "return for void function %s", + function->as_string ().c_str ()); + return; + } + + if (!typesAreCompatible (function->get_return_type ().get (), inferedType, + expr.get_locus_slow ())) + { + return; + } +} + void TypeResolution::visit (AST::UnsafeBlockExpr &expr) {} @@ -764,18 +922,26 @@ TypeResolution::visit (AST::Function &function) // its a marker for a void function scope.InsertType (function.get_function_name (), function.get_return_type ().get ()); scope.InsertFunction (function.get_function_name (), &function); + scope.PushFunction (&function); scope.Push (); for (auto ¶m : function.get_function_params ()) { if (!isTypeInScope (param.get_type ().get (), param.get_locus ())) - return; + { + scope.Pop (); + scope.PopFunction (); + return; + } auto before = letPatternBuffer.size (); param.get_pattern ()->accept_vis (*this); if (letPatternBuffer.size () <= before) { rust_error_at (param.get_locus (), "failed to analyse parameter name"); + + scope.Pop (); + scope.PopFunction (); return; } @@ -788,7 +954,11 @@ TypeResolution::visit (AST::Function &function) if (function.has_return_type ()) { if (!isTypeInScope (function.get_return_type ().get (), function.get_locus ())) - return; + { + scope.Pop (); + scope.PopFunction (); + return; + } } // walk the expression body @@ -802,6 +972,7 @@ TypeResolution::visit (AST::Function &function) function.locals.push_back (value); scope.Pop (); + scope.PopFunction (); } void @@ -1011,7 +1182,7 @@ TypeResolution::visit (AST::LetStmt &stmt) return; } - AST::Type *inferedType = NULL; + AST::Type *inferedType = nullptr; if (stmt.has_init_expr ()) { auto before = typeBuffer.size (); @@ -1044,13 +1215,51 @@ TypeResolution::visit (AST::LetStmt &stmt) return; } } - else if (stmt.has_type () && !stmt.has_init_expr ()) + else if (stmt.has_type ()) { - inferedType = stmt.get_type ().get (); + auto before = typeComparisonBuffer.size (); + stmt.get_type ()->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (stmt.get_locus (), "failed to understand type for lhs"); + return; + } + auto typeString = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + + // AST::Type *val = NULL; + // if (!scope.LookupType (typeString, &val)) + // { + // rust_error_at (stmt.locus, "LetStmt has unknown type: %s", + // stmt.type->as_string ().c_str ()); + // return; + // } + } + else if (inferedType != nullptr) + { + auto before = typeComparisonBuffer.size (); + inferedType->accept_vis (*this); + if (typeComparisonBuffer.size () <= before) + { + rust_error_at (stmt.get_locus (), "failed to understand type for lhs"); + return; + } + auto typeString = typeComparisonBuffer.back (); + typeComparisonBuffer.pop_back (); + + // AST::Type *val = NULL; + // if (!scope.LookupType (typeString, &val)) + // { + // rust_error_at (stmt.get_locus (), "Inferred unknown type: %s", + // inferedType->as_string ().c_str ()); + // return; + // } + } + else + { + rust_fatal_error (stmt.get_locus (), "Failed to determine any type for LetStmt"); + return; } - - // TODO check we know what the type is in the scope requires the builtins to - // be defined at the constructor // ensure the decl has the type set for compilation later on if (!stmt.has_type ()) @@ -1118,9 +1327,13 @@ TypeResolution::visit (AST::RawPointerType &type) void TypeResolution::visit (AST::ReferenceType &type) {} + void TypeResolution::visit (AST::ArrayType &type) -{} +{ + typeComparisonBuffer.push_back (type.get_elem_type ()->as_string ()); +} + void TypeResolution::visit (AST::SliceType &type) {} diff --git a/gcc/rust/analysis/rust-type-resolution.h b/gcc/rust/analysis/rust-type-resolution.h index 0c6413b..2f61a39 100644 --- a/gcc/rust/analysis/rust-type-resolution.h +++ b/gcc/rust/analysis/rust-type-resolution.h @@ -1,3 +1,20 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. #pragma once #include "rust-resolution.h" @@ -38,6 +55,12 @@ public: return functionScope.Lookup (ident, fn); } + void PushFunction (AST::Function *fn) { functionStack.push_back (fn); } + + void PopFunction () { functionStack.pop_back (); } + + AST::Function *CurrentFunction () { return functionStack.back (); } + void InsertLocal (std::string ident, AST::LetStmt *let) { localsPerBlock.Insert (ident, let); @@ -74,6 +97,8 @@ public: } private: + std::vector<AST::Function *> functionStack; + Scope<AST::Function *> functionScope; Scope<AST::LetStmt *> localsPerBlock; Scope<AST::StructStruct *> structsPerBlock; diff --git a/gcc/rust/analysis/rust-type-visitor.h b/gcc/rust/analysis/rust-type-visitor.h new file mode 100644 index 0000000..8cfe156 --- /dev/null +++ b/gcc/rust/analysis/rust-type-visitor.h @@ -0,0 +1,261 @@ +// rust-type-visitor.h -- Rust AST Visitor to AST::Type specific +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_TYPE_VISITOR_H +#define RUST_TYPE_VISITOR_H + +#include "rust-system.h" +#include "rust-ast-full.h" +#include "rust-ast-visitor.h" +#include "rust-scan.h" + +namespace Rust { +namespace Analysis { + +class BaseTypeVisitor : public AST::ASTVisitor +{ +public: + // visitor impl + // rust-ast.h + // virtual void visit(AttrInput& attr_input); + // virtual void visit(TokenTree& token_tree); + // virtual void visit(MacroMatch& macro_match); + virtual void visit (AST::Token &tok) override {} + virtual void visit (AST::DelimTokenTree &delim_tok_tree) override {} + virtual void visit (AST::AttrInputMetaItemContainer &input) override {} + // virtual void visit(MetaItem& meta_item) override {} + // void vsit(Stmt& stmt) override {} + // virtual void visit(Expr& expr) override {} + virtual void visit (AST::IdentifierExpr &ident_expr) override {} + // virtual void visit(Pattern& pattern) override {} + // virtual void visit(Type& type) override {} + // virtual void visit(TypeParamBound& type_param_bound) override {} + virtual void visit (AST::Lifetime &lifetime) override {} + // virtual void visit(GenericParam& generic_param) override {} + virtual void visit (AST::LifetimeParam &lifetime_param) override {} + // virtual void visit(TraitItem& trait_item) override {} + // virtual void visit(InherentImplItem& inherent_impl_item) override {} + // virtual void visit(TraitImplItem& trait_impl_item) override {} + virtual void visit (AST::MacroInvocationSemi ¯o) override {} + + // rust-path.h + virtual void visit (AST::PathInExpression &path) override {} + virtual void visit (AST::TypePathSegment &segment) override {} + virtual void visit (AST::TypePathSegmentGeneric &segment) override {} + virtual void visit (AST::TypePathSegmentFunction &segment) override {} + virtual void visit (AST::TypePath &path) override {} + virtual void visit (AST::QualifiedPathInExpression &path) override {} + virtual void visit (AST::QualifiedPathInType &path) override {} + + // rust-expr.h + virtual void visit (AST::LiteralExpr &expr) override {} + virtual void visit (AST::AttrInputLiteral &attr_input) override {} + virtual void visit (AST::MetaItemLitExpr &meta_item) override {} + virtual void visit (AST::MetaItemPathLit &meta_item) override {} + virtual void visit (AST::BorrowExpr &expr) override {} + virtual void visit (AST::DereferenceExpr &expr) override {} + virtual void visit (AST::ErrorPropagationExpr &expr) override {} + virtual void visit (AST::NegationExpr &expr) override {} + virtual void visit (AST::ArithmeticOrLogicalExpr &expr) override {} + virtual void visit (AST::ComparisonExpr &expr) override {} + virtual void visit (AST::LazyBooleanExpr &expr) override {} + virtual void visit (AST::TypeCastExpr &expr) override {} + virtual void visit (AST::AssignmentExpr &expr) override {} + virtual void visit (AST::CompoundAssignmentExpr &expr) override {} + virtual void visit (AST::GroupedExpr &expr) override {} + // virtual void visit(ArrayElems& elems) override {} + virtual void visit (AST::ArrayElemsValues &elems) override {} + virtual void visit (AST::ArrayElemsCopied &elems) override {} + virtual void visit (AST::ArrayExpr &expr) override {} + virtual void visit (AST::ArrayIndexExpr &expr) override {} + virtual void visit (AST::TupleExpr &expr) override {} + virtual void visit (AST::TupleIndexExpr &expr) override {} + virtual void visit (AST::StructExprStruct &expr) override {} + // virtual void visit(StructExprField& field) override {} + virtual void visit (AST::StructExprFieldIdentifier &field) override {} + virtual void visit (AST::StructExprFieldIdentifierValue &field) override {} + virtual void visit (AST::StructExprFieldIndexValue &field) override {} + virtual void visit (AST::StructExprStructFields &expr) override {} + virtual void visit (AST::StructExprStructBase &expr) override {} + virtual void visit (AST::StructExprTuple &expr) override {} + virtual void visit (AST::StructExprUnit &expr) override {} + // virtual void visit(EnumExprField& field) override {} + virtual void visit (AST::EnumExprFieldIdentifier &field) override {} + virtual void visit (AST::EnumExprFieldIdentifierValue &field) override {} + virtual void visit (AST::EnumExprFieldIndexValue &field) override {} + virtual void visit (AST::EnumExprStruct &expr) override {} + virtual void visit (AST::EnumExprTuple &expr) override {} + virtual void visit (AST::EnumExprFieldless &expr) override {} + virtual void visit (AST::CallExpr &expr) override {} + virtual void visit (AST::MethodCallExpr &expr) override {} + virtual void visit (AST::FieldAccessExpr &expr) override {} + virtual void visit (AST::ClosureExprInner &expr) override {} + virtual void visit (AST::BlockExpr &expr) override {} + virtual void visit (AST::ClosureExprInnerTyped &expr) override {} + virtual void visit (AST::ContinueExpr &expr) override {} + virtual void visit (AST::BreakExpr &expr) override {} + virtual void visit (AST::RangeFromToExpr &expr) override {} + virtual void visit (AST::RangeFromExpr &expr) override {} + virtual void visit (AST::RangeToExpr &expr) override {} + virtual void visit (AST::RangeFullExpr &expr) override {} + virtual void visit (AST::RangeFromToInclExpr &expr) override {} + virtual void visit (AST::RangeToInclExpr &expr) override {} + virtual void visit (AST::ReturnExpr &expr) override {} + virtual void visit (AST::UnsafeBlockExpr &expr) override {} + virtual void visit (AST::LoopExpr &expr) override {} + virtual void visit (AST::WhileLoopExpr &expr) override {} + virtual void visit (AST::WhileLetLoopExpr &expr) override {} + virtual void visit (AST::ForLoopExpr &expr) override {} + virtual void visit (AST::IfExpr &expr) override {} + virtual void visit (AST::IfExprConseqElse &expr) override {} + virtual void visit (AST::IfExprConseqIf &expr) override {} + virtual void visit (AST::IfExprConseqIfLet &expr) override {} + virtual void visit (AST::IfLetExpr &expr) override {} + virtual void visit (AST::IfLetExprConseqElse &expr) override {} + virtual void visit (AST::IfLetExprConseqIf &expr) override {} + virtual void visit (AST::IfLetExprConseqIfLet &expr) override {} + // virtual void visit(MatchCase& match_case) override {} + // virtual void visit (AST::MatchCaseBlockExpr &match_case) override {} + // virtual void visit (AST::MatchCaseExpr &match_case) override {} + virtual void visit (AST::MatchExpr &expr) override {} + virtual void visit (AST::AwaitExpr &expr) override {} + virtual void visit (AST::AsyncBlockExpr &expr) override {} + + // rust-item.h + virtual void visit (AST::TypeParam ¶m) override {} + // virtual void visit(WhereClauseItem& item) override {} + virtual void visit (AST::LifetimeWhereClauseItem &item) override {} + virtual void visit (AST::TypeBoundWhereClauseItem &item) override {} + virtual void visit (AST::Method &method) override {} + virtual void visit (AST::ModuleBodied &module) override {} + virtual void visit (AST::ModuleNoBody &module) override {} + virtual void visit (AST::ExternCrate &crate) override {} + // virtual void visit(UseTree& use_tree) override {} + virtual void visit (AST::UseTreeGlob &use_tree) override {} + virtual void visit (AST::UseTreeList &use_tree) override {} + virtual void visit (AST::UseTreeRebind &use_tree) override {} + virtual void visit (AST::UseDeclaration &use_decl) override {} + virtual void visit (AST::Function &function) override {} + virtual void visit (AST::TypeAlias &type_alias) override {} + virtual void visit (AST::StructStruct &struct_item) override {} + virtual void visit (AST::TupleStruct &tuple_struct) override {} + virtual void visit (AST::EnumItem &item) override {} + virtual void visit (AST::EnumItemTuple &item) override {} + virtual void visit (AST::EnumItemStruct &item) override {} + virtual void visit (AST::EnumItemDiscriminant &item) override {} + virtual void visit (AST::Enum &enum_item) override {} + virtual void visit (AST::Union &union_item) override {} + virtual void visit (AST::ConstantItem &const_item) override {} + virtual void visit (AST::StaticItem &static_item) override {} + virtual void visit (AST::TraitItemFunc &item) override {} + virtual void visit (AST::TraitItemMethod &item) override {} + virtual void visit (AST::TraitItemConst &item) override {} + virtual void visit (AST::TraitItemType &item) override {} + virtual void visit (AST::Trait &trait) override {} + virtual void visit (AST::InherentImpl &impl) override {} + virtual void visit (AST::TraitImpl &impl) override {} + // virtual void visit(ExternalItem& item) override {} + virtual void visit (AST::ExternalStaticItem &item) override {} + virtual void visit (AST::ExternalFunctionItem &item) override {} + virtual void visit (AST::ExternBlock &block) override {} + + // rust-macro.h + virtual void visit (AST::MacroMatchFragment &match) override {} + virtual void visit (AST::MacroMatchRepetition &match) override {} + virtual void visit (AST::MacroMatcher &matcher) override {} + virtual void visit (AST::MacroRulesDefinition &rules_def) override {} + virtual void visit (AST::MacroInvocation ¯o_invoc) override {} + virtual void visit (AST::MetaItemPath &meta_item) override {} + virtual void visit (AST::MetaItemSeq &meta_item) override {} + virtual void visit (AST::MetaWord &meta_item) override {} + virtual void visit (AST::MetaNameValueStr &meta_item) override {} + virtual void visit (AST::MetaListPaths &meta_item) override {} + virtual void visit (AST::MetaListNameValueStr &meta_item) override {} + + // rust-pattern.h + virtual void visit (AST::LiteralPattern &pattern) override {} + virtual void visit (AST::IdentifierPattern &pattern) override {} + virtual void visit (AST::WildcardPattern &pattern) override {} + // virtual void visit(RangePatternBound& bound) override {} + virtual void visit (AST::RangePatternBoundLiteral &bound) override {} + virtual void visit (AST::RangePatternBoundPath &bound) override {} + virtual void visit (AST::RangePatternBoundQualPath &bound) override {} + virtual void visit (AST::RangePattern &pattern) override {} + virtual void visit (AST::ReferencePattern &pattern) override {} + // virtual void visit(StructPatternField& field) override {} + virtual void visit (AST::StructPatternFieldTuplePat &field) override {} + virtual void visit (AST::StructPatternFieldIdentPat &field) override {} + virtual void visit (AST::StructPatternFieldIdent &field) override {} + virtual void visit (AST::StructPattern &pattern) override {} + // virtual void visit(TupleStructItems& tuple_items) override {} + virtual void visit (AST::TupleStructItemsNoRange &tuple_items) override {} + virtual void visit (AST::TupleStructItemsRange &tuple_items) override {} + virtual void visit (AST::TupleStructPattern &pattern) override {} + // virtual void visit(TuplePatternItems& tuple_items) override {} + virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) override {} + virtual void visit (AST::TuplePatternItemsRanged &tuple_items) override {} + virtual void visit (AST::TuplePattern &pattern) override {} + virtual void visit (AST::GroupedPattern &pattern) override {} + virtual void visit (AST::SlicePattern &pattern) override {} + + // rust-stmt.h + virtual void visit (AST::EmptyStmt &stmt) override {} + virtual void visit (AST::LetStmt &stmt) override {} + virtual void visit (AST::ExprStmtWithoutBlock &stmt) override {} + virtual void visit (AST::ExprStmtWithBlock &stmt) override {} + + // rust-type.h + virtual void visit (AST::TraitBound &bound) override {} + virtual void visit (AST::ImplTraitType &type) override {} + virtual void visit (AST::TraitObjectType &type) override {} + virtual void visit (AST::ParenthesisedType &type) override {} + virtual void visit (AST::ImplTraitTypeOneBound &type) override {} + virtual void visit (AST::TraitObjectTypeOneBound &type) override {} + virtual void visit (AST::TupleType &type) override {} + virtual void visit (AST::NeverType &type) override {} + virtual void visit (AST::RawPointerType &type) override {} + virtual void visit (AST::ReferenceType &type) override {} + virtual void visit (AST::ArrayType &type) override {} + virtual void visit (AST::SliceType &type) override {} + virtual void visit (AST::InferredType &type) override {} + virtual void visit (AST::BareFunctionType &type) override {} +}; + +class ArrayTypeVisitor : public BaseTypeVisitor +{ +public: + static AST::ArrayType *Resolve (AST::Type *type) + { + ArrayTypeVisitor vis; + type->accept_vis (vis); + return vis.resolved; + } + + virtual void visit (AST::ArrayType &type) override { resolved = &type; }; + +private: + ArrayTypeVisitor () : resolved (nullptr) {} + + AST::ArrayType *resolved; +}; + +} // namespace Analysis +} // namespace Rust + +#endif // RUST_TYPE_VISITOR_H |