anchor.diff:       | App' (Def tc, _) -> tc = typedefof<Rec<_>>
        | _ -> false
   
  -  let rec tryGen limit reached rules objEnv tyEnv stack ty =
  +  let addFailurePath (rules: RuleSet.RuleSet) stack ty msg =
  +    lock rules.cache.lastFailures <| fun () ->
  +    rules.cache.lastFailures.Enqueue (msg, ty::stack)
  +    if rules.cache.lastFailures.Count > 10 then
  +      rules.cache.lastFailures.Dequeue () |> ignore
  +
  +  let rec tryGen limit (rules: RuleSet.RuleSet) objEnv tyEnv stack ty =
       if limit <= 0 then
  -      reached := true
  +      rules.cache.limitReached <- true
         Seq.empty
       else
         let search limit =
  -         let rules = RuleSet.maybeAddConRules ty rules
  -         RuleSet.rulesFor rules ty
  -         |> Seq.collect (fun rule ->
  -            let rule = Rule.freshVars rule
  -            Ty.tryMatchIn rule.ReturnType ty tyEnv
  -            |> Option.collect (fun tyEnv ->
  +        let rules = RuleSet.maybeAddConRules ty rules
  +        RuleSet.rulesFor rules ty
  +        |> Seq.collect (fun rule ->
  +           let rule = Rule.freshVars rule
  +           match Ty.tryMatchIn rule.ReturnType ty tyEnv with
  +            | None ->
  +              addFailurePath rules stack ty "No rule for Tycon"
  +              Seq.empty
  +            | Some tyEnv ->
                  let rec outer args rules objEnv tyEnv ty parTys =
                    let ty = Ty.resolve tyEnv ty
                    let stack = stack |> List.map (Ty.resolve tyEnv)
  
positive.code: 
    let newEmpty () =
      {cache = {rules = ConcurrentDictionary<_, _> ()
                trees = ConcurrentDictionary<_, _> ()}
       rules = HashEqSet.empty
       tree = TyTree.build []}
  
  
negative.code:           | Some o -> Seq.singleton (Value (monoTy, o), objEnv, tyEnv)
            | None -> search limit |> Seq.truncate 1
  
    let generateWithLimits minDepth maxDepth (rulesObj: obj) : 't =
      let desTy = Ty.ofTypeIn <| Fresh.newMapper () <| typeof<'t>
      let rules =
        RuleSet.newEmpty ()
        |> RuleSet.maybeAddRulesObj rulesObj
      let rec gen limit =
        rules.cache.limitReached <- false
        rules.cache.lastFailures.Clear ()
        match tryGen limit rules HashEqMap.empty Map.empty [] desTy
              |> Seq.tryPick (fun (result, _, _) ->
                 match result with
                  | Ruled _ -> None
                  | Value (_, value) -> Some (unbox<'t> value)) with
         | None ->
           if rules.cache.limitReached && limit < maxDepth
           then gen (limit + 1)
           else match rules.cache.lastFailures.ToArray () with
                 | [||] ->
                   failwithf "%A cannot derive %A."
                    <| rulesObj.GetType ()
                    <| typeof<'t>
                 | paths ->
                   failwithf "%A cannot derive %A.  Last failure paths:\n\n%s\n"
                    <| rulesObj.GetType ()
                    <| typeof<'t>
                    <| (paths
                        |> Array.map (fun (msg, path) ->
                           sprintf "%s:\n%s" msg
                            (path
                            |> List.map (sprintf "  %A")
                            |> String.concat "\n"))
                        |> String.concat "\n\n")
         | Some t -> t
      gen minDepth
  
    let generate' (rules: 'r when 'r :> Rules) : 't =
      generateWithLimits 1 Int32.MaxValue rules
  
    let generate<'r, 't when 'r :> Rules and 'r: (new: unit -> 'r)> : 't =
      StaticSet.getOrInvoke<'t> <| fun () ->
      generate' (new 'r ())
  
    let generateDFS' (rules: 'r when 'r :> Rules) : 't =
      generateWithLimits Int32.MaxValue Int32.MaxValue rules
  
    let generateDFS<'r, 't when 'r :> Rules and 'r: (new: unit -> 'r)> : 't =
      StaticSet.getOrInvoke<'t> <| fun () ->
      generateDFS' (new 'r ())
  