diff options
author | Philip Herron <philip.herron@embecosm.com> | 2020-12-03 15:34:15 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2020-12-03 17:25:24 +0000 |
commit | 064c6e4815b212d72f008082939376f570897c19 (patch) | |
tree | 4090d53e54ea8565d9515b3668f432306a2ee697 /gcc/rust/analysis | |
parent | 03fc0e389fae2576a7f217fb0afb7cb0f18689f8 (diff) | |
download | gcc-064c6e4815b212d72f008082939376f570897c19.zip gcc-064c6e4815b212d72f008082939376f570897c19.tar.gz gcc-064c6e4815b212d72f008082939376f570897c19.tar.bz2 |
Type Resolve ReturnExpr's to ensure they match the function type.
This an implementation to check return types for functions it needs work
to handle structs and other data structures later on.
Diffstat (limited to 'gcc/rust/analysis')
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.cc | 52 | ||||
-rw-r--r-- | gcc/rust/analysis/rust-type-resolution.h | 8 |
2 files changed, 57 insertions, 3 deletions
diff --git a/gcc/rust/analysis/rust-type-resolution.cc b/gcc/rust/analysis/rust-type-resolution.cc index 8558847..51c7380 100644 --- a/gcc/rust/analysis/rust-type-resolution.cc +++ b/gcc/rust/analysis/rust-type-resolution.cc @@ -774,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_expr ()->accept_vis (*this); + + if (typeBuffer.size () <= before) + { + rust_error_at (expr.get_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_function_return_type ()) + { + rust_error_at (expr.get_locus (), "return for void function %s", + function->as_string ().c_str ()); + return; + } + + if (!typesAreCompatible (function->return_type.get (), inferedType, + expr.get_locus_slow ())) + { + return; + } +} + void TypeResolution::visit (AST::UnsafeBlockExpr &expr) {} @@ -889,18 +922,26 @@ TypeResolution::visit (AST::Function &function) // its a marker for a void function scope.InsertType (function.function_name, function.return_type.get ()); scope.InsertFunction (function.function_name, &function); + scope.PushFunction (&function); scope.Push (); for (auto ¶m : function.function_params) { if (!isTypeInScope (param.type.get (), param.locus)) - return; + { + scope.Pop (); + scope.PopFunction (); + return; + } auto before = letPatternBuffer.size (); param.param_name->accept_vis (*this); if (letPatternBuffer.size () <= before) { rust_error_at (param.locus, "failed to analyse parameter name"); + + scope.Pop (); + scope.PopFunction (); return; } @@ -913,7 +954,11 @@ TypeResolution::visit (AST::Function &function) if (function.has_function_return_type ()) { if (!isTypeInScope (function.return_type.get (), function.locus)) - return; + { + scope.Pop (); + scope.PopFunction (); + return; + } } // walk the expression body @@ -927,6 +972,7 @@ TypeResolution::visit (AST::Function &function) function.locals.push_back (value); scope.Pop (); + scope.PopFunction (); } void diff --git a/gcc/rust/analysis/rust-type-resolution.h b/gcc/rust/analysis/rust-type-resolution.h index d461b66..0fef2ae 100644 --- a/gcc/rust/analysis/rust-type-resolution.h +++ b/gcc/rust/analysis/rust-type-resolution.h @@ -55,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); @@ -91,6 +97,8 @@ public: } private: + std::vector<AST::Function *> functionStack; + Scope<AST::Function *> functionScope; Scope<AST::LetStmt *> localsPerBlock; Scope<AST::StructStruct *> structsPerBlock; |