1 #include <torch/csrc/jit/ir.h> 2 #include <torch/csrc/jit/script/final_returns.h> 14 void checkNoReturn(
const TreeRef& ref) {
15 if (ref->kind() == TK_RETURN)
16 throw ErrorReport(ref) <<
"return is not allowed from a loop.";
17 for (
const TreeRef& child : ref->trees()) {
32 return makeReturnsFinal(stmts.range(), stmts.get()->trees(), return_none);
38 std::vector<TreeRef> changed;
39 changed.reserve(stmts.
size());
40 for (
size_t i = 0; i < stmts.
size(); ++i) {
41 const TreeRef& stmt = stmts[i];
42 switch (stmt->kind()) {
44 auto if_stmt =
If(stmt);
45 auto true_final = makeReturnsFinal(if_stmt.trueBranch(),
false);
47 if (true_final.returns_ && if_stmt.falseBranch().size() == 0) {
49 makeReturnsFinal(range, stmts.
slice(i + 1), return_none);
50 if (!rest_final.returns_) {
52 <<
"This if statement performs an early return, but the block of code that follows it does not return." 53 <<
" Early returns are only allowed when the block following them also returns.";
56 if_stmt.withNewBranches(true_final.stmts_, rest_final.stmts_));
60 auto false_final = makeReturnsFinal(if_stmt.falseBranch(),
false);
62 if (!true_final.returns_ && !false_final.returns_) {
63 changed.emplace_back(if_stmt);
67 if (true_final.returns_ && false_final.returns_) {
69 if_stmt.withNewBranches(true_final.stmts_, false_final.stmts_));
73 <<
"This if statement contains some paths that return and some paths that do not. " 74 <<
"If statements must either entirely return or never return.";
78 changed.emplace_back(stmt);
82 changed.emplace_back(stmt);
86 changed.emplace_back(stmt);
93 Return::create(range,
Expr(Compound::create(TK_NONE, range, {}))));
101 return makeReturnsFinal(stmts,
true).stmts_;
AT_CPP14_CONSTEXPR ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
constexpr size_t size() const
size - Get the array size.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...