anchor.diff:          
           let ctx, bindings =
               ((ctx, []), foldArgs [] (inExpr.Args, args)) ||> List.fold (fun (ctx, bindings) (argId, arg) ->
  -                let argId = resolveInlinedIdent ctx info argId
  +                let argId = resolveInlineIdent ctx info argId
                   // Change type and mark argId as compiler-generated so Fable also
                   // tries to inline it in DEBUG mode (some patterns depend on this)
                   let argId = { argId with Type = arg.Type; IsCompilerGenerated = true }
  
positive.code:                 ctx, (argId, arg)::bindings)
  
          let ctx = { ctx with ScopeInlineArgs = ctx.ScopeInlineArgs @ bindings }
          bindings, resolveInlinedExpr this ctx info inExpr.Body
  
      interface IFableCompiler with
          member _.WarnOnlyOnce(msg, ?range) =
  
negative.code:                 ctx.UsedNamesInDeclarationScope.Add(resolvedName) |> ignore
                  info.ResolvedIdents.Add(ident.Name, resolvedName)
                  resolvedName
          { ident with Name = sanitizedName; Type = resolveInlineType ctx ident.Type }
      else ident
  
  let resolveInlinedCallInfo com ctx info (callInfo: Fable.CallInfo) =
      { callInfo with
            ThisArg = Option.map (resolveInlineExpr com ctx info) callInfo.ThisArg
            Args = List.map (resolveInlineExpr com ctx info) callInfo.Args
            GenericArgs = List.map (resolveInlineType ctx) callInfo.GenericArgs }
  
  let resolveInlineExpr (com: IFableCompiler) ctx info expr =
      match expr with
      | Fable.Let(i, v, b) ->
          let i = resolveInlineIdent ctx info i
          let v = resolveInlineExpr com ctx info v
          let ctx = { ctx with Scope = (None, i, Some v)::ctx.Scope }
          Fable.Let(i, v, resolveInlineExpr com ctx info b)
  
      | Fable.LetRec(bindings, b) ->
          let ctx, bindings =
              ((ctx, bindings), bindings) ||> List.fold(fun (ctx, bindings) (i, e) ->
                  let i = resolveInlineIdent ctx info i
                  let e = resolveInlineExpr com ctx info e
                  { ctx with Scope = (None, i, Some e)::ctx.Scope }, (i, e)::bindings)
          Fable.LetRec(List.rev bindings, resolveInlineExpr com ctx info b)
  
      | Fable.Call(callee, callInfo, typ, r) ->
          let callInfo = resolveInlinedCallInfo com ctx info callInfo
          Fable.Call(resolveInlineExpr com ctx info callee, callInfo, resolveInlineType ctx typ, r)
  
      | Fable.Emit(emitInfo, typ, r) ->
          let emitInfo = { emitInfo with CallInfo = resolveInlinedCallInfo com ctx info emitInfo.CallInfo }
          Fable.Emit(emitInfo, resolveInlineType ctx typ, r)
  
      | Fable.CurriedApply(callee, args, typ, r) ->
          let args = List.map (resolveInlineExpr com ctx info) args
          Fable.CurriedApply(resolveInlineExpr com ctx info callee, args, resolveInlineType ctx typ, r)
  
      | Fable.Operation(kind, t, r) ->
          let t = resolveInlineType ctx t
          match kind with
          | Fable.Unary(operator, operand) ->
              Fable.Operation(Fable.Unary(operator, resolveInlineExpr com ctx info operand), t, r)
          | Fable.Binary(op, left, right) ->
              Fable.Operation(Fable.Binary(op, resolveInlineExpr com ctx info left, resolveInlineExpr com ctx info right), t, r)
          | Fable.Logical(op, left, right) ->
              Fable.Operation(Fable.Logical(op, resolveInlineExpr com ctx info left, resolveInlineExpr com ctx info right), t, r)
  
      | Fable.Get(e, kind, t, r) ->
          let kind =
              match kind with
              | Fable.ExprGet e2 -> Fable.ExprGet(resolveInlineExpr com ctx info e2)
              | Fable.ListHead | Fable.ListTail | Fable.OptionValue | Fable.TupleIndex _ | Fable.UnionTag
              | Fable.UnionField _ | Fable.FieldGet _ -> kind
          Fable.Get(resolveInlineExpr com ctx info e, kind, resolveInlineType ctx t, r)
  
      | Fable.Set(e, kind, t, v, r) ->
          let kind =
              match kind with
              | Fable.ExprSet e2 -> Fable.ExprSet(resolveInlineExpr com ctx info e2)
              | Fable.FieldSet _
              | Fable.ValueSet -> kind
          Fable.Set(resolveInlineExpr com ctx info e, kind, resolveInlineType ctx t, resolveInlineExpr com ctx info v, r)
  
      | Fable.Test(e, kind, r) ->
          let kind =
              match kind with
              | Fable.TypeTest t -> Fable.TypeTest(resolveInlineType ctx t)
              | Fable.OptionTest _
              | Fable.ListTest _
              | Fable.UnionCaseTest _ -> kind
          Fable.Test(resolveInlineExpr com ctx info e, kind, r)
  
      | Fable.Sequential exprs ->
          List.map (resolveInlineExpr com ctx info) exprs |> Fable.Sequential
  
      | Fable.IdentExpr i -> Fable.IdentExpr(resolveInlineIdent ctx info i)
  
      | Fable.Lambda(arg, b, n) -> Fable.Lambda(resolveInlineIdent ctx info arg, resolveInlineExpr com ctx info b, n)
  
      | Fable.Delegate(args, b, n) -> Fable.Delegate(List.map (resolveInlineIdent ctx info) args, resolveInlineExpr com ctx info b, n)
  
      | Fable.IfThenElse(cond, thenExpr, elseExpr, r) -> Fable.IfThenElse(resolveInlineExpr com ctx info cond, resolveInlineExpr com ctx info thenExpr, resolveInlineExpr com ctx info elseExpr, r)
  
      | Fable.DecisionTree(e, targets) ->
          let targets = targets |> List.map(fun (idents, e) ->
              List.map (resolveInlineIdent ctx info) idents, resolveInlineExpr com ctx info e)
          Fable.DecisionTree(resolveInlineExpr com ctx info e, targets)
  
      | Fable.DecisionTreeSuccess(idx, boundValues, t) ->
          let boundValues = List.map (resolveInlineExpr com ctx info) boundValues
          Fable.DecisionTreeSuccess(idx, boundValues, resolveInlineType ctx t)
  
      | Fable.ForLoop(i, s, l, b, u, r) -> Fable.ForLoop(resolveInlineIdent ctx info i, resolveInlineExpr com ctx info s, resolveInlineExpr com ctx info l, resolveInlineExpr com ctx info b, u, r)
  
      | Fable.WhileLoop(e1, e2, label, r) -> Fable.WhileLoop(resolveInlineExpr com ctx info e1, resolveInlineExpr com ctx info e2, label, r)
  
      | Fable.TryCatch(b, c, d, r) -> Fable.TryCatch(resolveInlineExpr com ctx info b, (c |> Option.map (fun (i, e) -> resolveInlineIdent ctx info i, resolveInlineExpr com ctx info e)), (d |> Option.map (resolveInlineExpr com ctx info)), r)
  
      | Fable.TypeCast(e, t) -> Fable.TypeCast(resolveInlineExpr com ctx info e, resolveInlineType ctx t)
  
      | Fable.ObjectExpr(members, t, baseCall) ->
          let members = members |> List.map (fun m ->
              { m with Args = List.map (fun a -> { a with Ident = resolveInlineIdent ctx info a.Ident }) m.Args
                       Body = resolveInlineExpr com ctx info m.Body })
          Fable.ObjectExpr(members, resolveInlineType ctx t, baseCall |> Option.map (resolveInlineExpr com ctx info))
  
      // TODO: add test
      | Fable.Import(importInfo, t, r) as e ->
          let t = resolveInlineType ctx t
          if Path.isRelativePath importInfo.Path then
              // If it happens we're importing a member in the current file
              // use IdentExpr instead of Import
              let isImportToSameFile =
                  info.FileName = com.CurrentFile && (
                      let dirName, info = Path.GetDirectoryAndFileNames(importInfo.Path)
                      dirName = "." && info = Path.GetFileName(com.CurrentFile)
                  )
              if isImportToSameFile then
                  Fable.IdentExpr { makeTypedIdent t importInfo.Selector with Range = r }
              else
                  let path = fixImportedRelativePath com importInfo.Path info.FileName
                  Fable.Import({ importInfo with Path = path }, t, r)
          else e
  
      | Fable.Value(kind, r) as e ->
          match kind with
          | Fable.UnitConstant
          | Fable.BoolConstant _
          | Fable.CharConstant _
          | Fable.StringConstant _
          | Fable.NumberConstant _
          | Fable.RegexConstant _ -> e
          | Fable.StringTemplate(tag, parts, exprs) -> Fable.StringTemplate(tag, parts, List.map (resolveInlineExpr com ctx info) exprs) |> makeValue r
          | Fable.NewOption(e, t, isStruct) -> Fable.NewOption(Option.map (resolveInlineExpr com ctx info) e, resolveInlineType ctx t, isStruct) |> makeValue r
          | Fable.NewTuple(exprs, isStruct) -> Fable.NewTuple(List.map (resolveInlineExpr com ctx info) exprs, isStruct) |> makeValue r
          | Fable.NewArray(Fable.ArrayValues exprs, t, i) -> Fable.NewArray(List.map (resolveInlineExpr com ctx info) exprs |> Fable.ArrayValues, resolveInlineType ctx t, i) |> makeValue r
          | Fable.NewArray(Fable.ArrayFrom expr, t, i) -> Fable.NewArray(resolveInlineExpr com ctx info expr |> Fable.ArrayFrom, resolveInlineType ctx t, i) |> makeValue r
          | Fable.NewArray(Fable.ArrayAlloc expr, t, i) -> Fable.NewArray(resolveInlineExpr com ctx info expr |> Fable.ArrayAlloc, resolveInlineType ctx t, i) |> makeValue r
          | Fable.NewList(ht, t) ->
              let ht = ht |> Option.map (fun (h,t) -> resolveInlineExpr com ctx info h, resolveInlineExpr com ctx info t)
              Fable.NewList(ht, resolveInlineType ctx t) |> makeValue r
          | Fable.NewRecord(exprs, ent, genArgs) ->
              let genArgs = List.map (resolveInlineType ctx) genArgs
              Fable.NewRecord(List.map (resolveInlineExpr com ctx info) exprs, ent, genArgs) |> makeValue r
          | Fable.NewAnonymousRecord(exprs, fields, genArgs) ->
              let genArgs = List.map (resolveInlineType ctx) genArgs
              Fable.NewAnonymousRecord(List.map (resolveInlineExpr com ctx info) exprs, fields, genArgs) |> makeValue r
          | Fable.NewUnion(exprs, uci, ent, genArgs) ->
              let genArgs = List.map (resolveInlineType ctx) genArgs
              Fable.NewUnion(List.map (resolveInlineExpr com ctx info) exprs, uci, ent, genArgs) |> makeValue r
          | Fable.ThisValue t -> Fable.ThisValue(resolveInlineType ctx t) |> makeValue r
          | Fable.Null t -> Fable.Null(resolveInlineType ctx t) |> makeValue r
          | Fable.BaseValue(i, t) -> Fable.BaseValue(Option.map (resolveInlineIdent ctx info) i, resolveInlineType ctx t) |> makeValue r
          | Fable.TypeInfo(t, d) -> Fable.TypeInfo(resolveInlineType ctx t, d) |> makeValue r
  
      | Fable.Extended(kind, r) as e ->
          match kind with
          | Fable.Curry(e, arity) ->
              Fable.Extended(Fable.Curry(resolveInlineExpr com ctx info e, arity), r)
          | Fable.Throw(e, t) ->
              Fable.Extended(Fable.Throw(Option.map (resolveInlineExpr com ctx info) e, resolveInlineType ctx t), r)
          | Fable.Debugger
          | Fable.RegionStart _ -> e
  
      | Fable.Unresolved(e, t, r) ->
          match e with
          | Fable.UnresolvedTraitCall(sourceTypes, traitName, isInstance, argTypes, argExprs) ->
              let t = resolveInlineType ctx t
              let argTypes = argTypes |> List.map (resolveInlineType ctx)
              let argExprs = argExprs |> List.map (resolveInlineExpr com ctx info)
  
              match tryFindWitness ctx argTypes isInstance traitName with
              | None ->
                 let sourceTypes = sourceTypes |> List.map (resolveInlineType ctx)
                 transformTraitCall com ctx r t sourceTypes traitName isInstance argTypes argExprs
              | Some w ->
                  let callee = resolveInlineExpr com ctx { info with FileName = w.FileName } w.Expr
                  let callInfo = makeCallInfo None argExprs argTypes
                  makeCall r t callInfo callee
  
          | Fable.UnresolvedInlineCall(membUniqueName, witnesses, callee, callInfo) ->
              let t = resolveInlineType ctx t
              let callee = callee |> Option.map (resolveInlineExpr com ctx info)
              let callInfo = resolveInlinedCallInfo com ctx info callInfo
              let ctx = { ctx with Witnesses = witnesses @ ctx.Witnesses }
              inlineExpr com ctx r t callee callInfo membUniqueName
  
          | Fable.UnresolvedReplaceCall(thisArg, args, callInfo, attachedCall) ->
              let typ = resolveInlineType ctx t
              let thisArg = thisArg |> Option.map (resolveInlineExpr com ctx info)
              let args = args |> List.map (resolveInlineExpr com ctx info)
              let callInfo = { callInfo with GenericArgs = callInfo.GenericArgs |> List.map (resolveInlineType ctx) }
              match com.TryReplace(ctx, r, typ, callInfo, thisArg, args) with
              | Some e -> e
              | None when callInfo.IsInterface ->
                  match attachedCall with
                  | Some e -> resolveInlineExpr com ctx info e
                  | None ->
                      "Unexpected, missing attached call in unresolved replace call"
                      |> addErrorAndReturnNull com ctx.InlinePath r
              | None -> failReplace com ctx r callInfo
  
  type FableCompiler(com: Compiler) =
      let attachedMembers = Dictionary<string, _>()
  