fixhunt

eslint prefer-arrow-callback

labelled safe
Runs / 2026-10-22T18-25-08-132Z-qxj6-eslint-prefer-arrow-callbackeslint 9.39.52026-10-22 18:25 UTC8 programs × 2 round(s)16 programs, 2 fired, 2 fixed, 0 findings, 2 rejectedmodel cost $0.0029

Analysis Nemotron 3 Super

Flags function expressions used as callbacks or function arguments that could be replaced by arrow functions without changing behavior.

Fix: Replaces the function expression with an arrow function having the same parameters and body, preserving implicit returns and removing braces for single-expression bodies where applicable.

12 hazards
  • Rewriting a function expression containing 'arguments' changes its meaning because arrow functions do not have their own arguments object.
  • If the function expression uses 'yield', replacing it with an arrow function breaks generator semantics unless wrapped appropriately.
  • Moving a function expression inside a conditional or loop via hoisting differences may alter execution timing if the original relied on function declaration hoisting.
  • If the function expression is named and referenced recursively within its body, the arrow function rewrite removes that name, breaking recursion.
  • Comments attached to the function keyword or braces may be lost or misplaced during the rewrite, affecting readability or tooling dependencies.
  • In strict mode, the 'this' value inside the original function may be undefined, but the arrow function captures 'this' from outer scope, altering behavior if the outer 'this' differs.
  • If the function expression is used as a constructor (e.g., new fn()), replacing it with an arrow function throws because arrow functions are not callable with new.
  • When the function expression has default or rest parameters, the rewrite must preserve them exactly; incorrect transformation could alter parameter handling.
  • If the function expression is part of a larger expression where its syntactic form affects precedence (rare), the arrow function’s tighter binding could change evaluation order.
  • In TypeScript, if the function expression has a type assertion or generic constraint tied to the function keyword, removing it may break type checking.
  • If the function expression is used in a context where its prototype property is accessed (e.g., fn.prototype), the arrow function lacks a prototype property, causing runtime errors.
  • If the function expression contains a 'return' statement that exits an outer function, the arrow function’s implicit return or altered control flow may not replicate the same early exit behavior.

Programs

idresulttitlehazard
r1-p001silent prediction offPrototype Property AccessArrow function replacement removes .prototype property, breaking code that expects it.
r1-p002silent prediction offPrecedence Change via Binding TightnessArrow function binds tighter than function expression, altering evaluation order in mixed expressions.
r1-p003invalidClass Fields / Private Names / Super CallReplacing method expression breaks private field/super access due to lexical this capture.
r1-p004silent prediction offGetter/Setter/DefineProperty Side EffectsArrow function replacement loses identity, breaking defineProperty configurability/watch.
r1-p005silent prediction offThis Binding / Method Extraction / Call/Apply/BindArrow function captures outer this, breaking method borrowing and explicit binding.
r1-p006silent prediction offConstructor UsageArrow function replacement makes 'new fn()' throw, as arrow functions aren't constructible.
r1-p007invalidName Collisions Across Scopes After MoveMoving arrow function into inner scope causes accidental shadowing of outer variable.
r1-p008silent prediction offVar Hoisting and Re-declaration in Loops/After UseReplacing var function with arrow disrupts hoisting, causing TDZ if re-declared after use.
r2-p001fix okEarly return from outer functionIf the function expression contains a 'return' statement that exits an outer function, the arrow function’s implicit return or altered control flow may not replicate the same early exit behavior.
r2-p002silent prediction offPrecedence change via binding tightnessIf the function expression is part of a larger expression where its syntactic form affects precedence (rare), the arrow function’s tighter binding could change evaluation order.
r2-p003fix okTypeScript type assertion/generic constraintIn TypeScript, if the function expression has a type assertion or generic constraint tied to the function keyword, removing it may break type checking.
r2-p004silent prediction offnull/undefined distinction, optional chaining short-circuitnull/undefined distinction, optional chaining short-circuit, nullish vs falsy
r2-p005silent prediction offGenerator function with yieldIf the function expression uses 'yield', replacing it with an arrow function breaks generator semantics unless wrapped appropriately.
r2-p006silent prediction offNumeric/string coercion: + vs template literalnumeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt
r2-p007silent prediction offthis binding: method extraction and call/apply/bindthis binding: arrow vs function, methods extracted from objects, call/apply/bind
r2-p008silentFunction declaration inside block/switch/labeledfunction declarations inside blocks, switch cases, labeled statements

Sources

r1-p001 · Prototype Property Access
1function factory(){return function(){}};
2let F = factory();
3console.log(F.prototype !== undefined ? 'has' : 'no-proto');
has
r1-p002 · Precedence Change via Binding Tightness
1let x=1,y=2,z=0;
2x + y * z === 1 ? console.log('A') : console.log('B',x+y*z);
3(function(){z=x+y;})();
4console.log(z);
A
3
r1-p003 · Class Fields / Private Names / Super Call (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-25-0)
1class Base{constructor(){this.pub=1;}getPub(){return this.pub;}}
2class Der extends Base{constructor(){super();this.#priv=2;}
3 get(){return this.#priv + super.getPub();}}
4#DerPrv;let d=new Der();console.log(d.get());
r1-p004 · Getter/Setter/DefineProperty Side Effects
1let o={},id=null;function log(){id=this;return 42;}
2Object.defineProperty(o,'val',{get:log,configurable:true});
3console.log(o.val,id===o?'bound':'lost');
4delete o.val;Object.defineProperty(o,'val',{get:log});
5console.log(o.val,id===o?'bound':'lost');
42 bound
42 bound
r1-p005 · This Binding / Method Extraction / Call/Apply/Bind
1const obj={value:42,getValue:function(){return this.value;}};
2const fn=obj.getValue;
3console.log('direct:',obj.getValue());
4console.log('call:',fn.call(obj));
5console.log('bind:',fn.bind(obj)());
direct: 42
call: 42
bind: 42
r1-p006 · Constructor Usage
1function makeCtor(){return function Custom(){this.x=1;}};
2let C=makeCtor();try{let i=new C();console.log('ok',i.x);}catch(e){console.log(e.name,e.message);}
ok 1
r1-p007 · Name Collisions Across Scopes After Move (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-25-0)
1let x=9;(function(){let x=5;[1,2].map(v=>{console.log('inner',x+v);return x+v;}))();
2console.log('outer',x);
r1-p008 · Var Hoisting and Re-declaration in Loops/After Use
1(function(){console.log(typeof f);var f=function(){return 1};console.log(f());})();
undefined
1
r2-p001 · Early return from outer function
1function outer() {
2 [1,2].map(function(v) { if (v === 2) return 'found'; });
3 return 'not found';
4}
5console.log(outer());
--- orig.js	2026-10-22 14:25:25.586418929 -0400
+++ fixed.js	2026-10-22 14:25:28.766560568 -0400
@@ -1,5 +1,5 @@
 function outer() {
-  [1,2].map(function(v) { if (v === 2) return 'found'; });
+  [1,2].map((v) => { if (v === 2) return 'found'; });
   return 'not found';
 }
 console.log(outer());
not found
r2-p002 · Precedence change via binding tightness
1let result;
2try {
3 result = 0 + function() { return 1; }();
4} catch (e) {
5 result = e;
6}
7console.log(result);
1
r2-p003 · TypeScript type assertion/generic constraint
1// @ts-ignore
2const x = [];
3x.map(function(item) { return item.length; });
4console.log(x.map);
--- orig.js	2026-10-22 14:25:25.588419018 -0400
+++ fixed.js	2026-10-22 14:25:28.775560969 -0400
@@ -1,4 +1,4 @@
 // @ts-ignore
 const x = [];
-x.map(function(item) { return item.length; });
+x.map((item) => { return item.length; });
 console.log(x.map);
[Function: map]
r2-p004 · null/undefined distinction, optional chaining short-circuit
1const obj = { prop: null };
2let val = obj.prop != null ? obj.prop() : 10;
3console.log(val);
4val = obj.prop == null ? obj.prop() : 10;
5console.log(val);
10
r2-p005 · Generator function with yield
1function* gen() {
2 yield [1,2].map(function*(v) { yield v * 2; });
3}
4const g = gen();
5console.log(g.next().value);
[ Object [Generator] {}, Object [Generator] {} ]
r2-p006 · Numeric/string coercion: + vs template literal
1const obj = { valueOf: () => 5, toString: () => '5' };
2console.log(+obj);
3console.log(`${obj}`);
5
5
r2-p007 · this binding: method extraction and call/apply/bind
1const o = { x: 42, getX: function() { return this.x; } };
2const f = o.getX;
3console.log(f.call(o));
4console.log(f());
42
undefined
r2-p008 · Function declaration inside block/switch/labeled
1switch (1) {
2 case 1:
3 function f() { return 1; }
4 break;
5}
6console.log(typeof f);
function