HM module causing infrec

I haven’t been able to figure this one out, but it’s probably simple.
When I import my module (imports = [) infrec encountered.

Trace: https://termbin.com/rxwe

{
  config,
  lib,
  pkgs,
  ...
}: let
  inherit (lib) types;
  cfg = config.programs.firefox.profilesUserChrome;

  chromeDesc = types.submodule ({name, ...}: {
    options = {
      name = lib.mkOption {
        type = types.str;
        default = name;
        description = lib.mdDoc ''
          Profile name.
        '';
      };
    };
  });
in {
  options = {
    programs.firefox.profilesUserChrome = lib.mkOption {
      type = types.attrsOf types.attrs;
      default = {};
    };
  };

  config =
    lib.traceSeqN 1 {} cfg;
}

Uhm, that last line (config = lib.traceSeqN 1 {} cfg) definitely looks wrong.

What are you trying to do there exactly?

EDIT: see below.

As it’s written, you are forcing the value of config and then assigning whatever would come out of that (an attrset with the first level of attributes forced) to config itself, which means that config has as a value the result of the call to traceSeqN, which depends on config, which depends on …,

And this causes the infinite recursion.

I don’t know how to rewrite this without knowing what you are actually trying to do.

I was just trying to get it to evaluate cfg without infrec. I should be able to use cfg in config without infrec, this is very common practice. I gave an MCVE.

My previous assessment was wrong.

It’s actually simpler, you just cannot assign something refering to config to config itself, since the evaluator cannot make progress on such a thing.

And your expression can be expanded into

config = config.programs.firefox.profileUserChrome;

which is basically doing that.

So yes, you can use cfg inside expressions in config, but you cannot assign it directly to config, does that make sense?

You can play with this in a REPL session:

nix-repl> :lf . # ran in a nixpkgs clone, this brings nixpkgs in scope
nix-repl> allowUndefinedOptions = { config._module.freeformType = lib.types.attrs; } # avoid needing to declare options

# This does work
nix-repl> :p (lib.evalModules { modules = [ allowUndefinedOptions { config.foo = "foo"; } ( { config, ... }: { config.bar = config.foo; }) ]; }).config
{ bar = "foo"; foo = "foo"; }

# This doesn't, we cannot assign directly to config
nix-repl> :p (lib.evalModules { modules = [ allowUndefinedOptions { config.foo = "foo"; } ( { config, ... }: { config = config.foo; }) ]; }).config
error: infinite recursion encountered