@@ -1219,15 +1219,18 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
12191219
12201220 Dsymbol p = v.toParent2();
12211221
1222- if ((v.isScope() || (v.storage_class & STC .maybescope)) &&
1223- ! (v.storage_class & STC .return_) &&
1222+ bool needsReturn = false ;
1223+ if ( ! (v.storage_class & STC .return_) &&
12241224 v.isParameter() &&
1225- ! v.doNotInferReturn &&
1226- sc.func.flags & FUNCFLAG .returnInprocess &&
12271225 p == sc.func)
12281226 {
1229- inferReturn(sc.func, v); // infer addition of 'return'
1230- continue ;
1227+ if ((v.isScope() || (v.storage_class & STC .maybescope)) &&
1228+ sc.func.flags & FUNCFLAG .returnInprocess)
1229+ {
1230+ inferReturn(sc.func, v); // infer addition of 'return'
1231+ continue ;
1232+ }
1233+ needsReturn = true ; // needs 'return' annotation on parameter
12311234 }
12321235
12331236 if (v.isScope())
@@ -1275,6 +1278,17 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
12751278 result = false ;
12761279 }
12771280 }
1281+ else if (needsReturn && sc.func.type.isTypeFunction().purity != PURE .impure && global.params.vsafe &&
1282+ sc._module && sc._module.isRoot())
1283+ {
1284+ /* Pure functions assume their parameters are `scope`, but they don't assume `return`.
1285+ * Hence, the annotation needs to be explicit.
1286+ */
1287+ if (! gag)
1288+ error(e.loc, " `pure` function `%s` returns parameter `%s`, annotate with `return`" ,
1289+ sc.func.ident.toChars(), v.toChars());
1290+ result = true ;
1291+ }
12781292 else
12791293 {
12801294 // printf("no infer for %s in %s, %d\n", v.toChars(), sc.func.ident.toChars(), __LINE__);
0 commit comments