aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/analysis
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2020-12-03 15:34:15 +0000
committerPhilip Herron <herron.philip@googlemail.com>2020-12-03 17:25:24 +0000
commit064c6e4815b212d72f008082939376f570897c19 (patch)
tree4090d53e54ea8565d9515b3668f432306a2ee697 /gcc/rust/analysis
parent03fc0e389fae2576a7f217fb0afb7cb0f18689f8 (diff)
downloadgcc-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.cc52
-rw-r--r--gcc/rust/analysis/rust-type-resolution.h8
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 &param : 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;