Why can’t config be merged with the contents of “Attribute Set”?

I’m trying to make a module, but I’m running into some problems.
Here’s how I tried to write it.

{ lib
, pkgs
, config
, ...
}:
with lib;
let
  cfg = config.hp.hardware.gpu;


in
{

  options = {
    hp.hardware.gpu =
      {
        enable = mkOption {
          type = types.bool;
          default = false;
        };

        core = mkOption {
          type = types.nullOr types.str;
          default = config.hp.hardware.cpu;
        };

      };
  };

  config = mkIf ((cfg.enable || builtins.elem config.hp.lib.tags.gui config.hp.base.tags) && config.hp.hardware.gpu.core != null)
    { } // {

    intel = {

      hardware.opengl = {
        enable = true;
        driSupport = true;
        extraPackages = with pkgs;[
          intel-compute-runtime
          intel-media-driver # LIBVA_DRIVER_NAME=iHD
          (vaapiIntel.override { enableHybridCodec = true; }) # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
          vaapiVdpau
          libvdpau-va-gl
        ];
      };

      environment.sessionVariables = { LIBVA_DRIVER_NAME = "iHD"; }; # Force intel-media-driver
      # https://nixos.wiki/wiki/Intel_Graphics
      # boot.kernelParams = [ "i915.force_probe=<device ID>" ];

    };

    amd = {

      hardware.opengl = {
        enable = true;
        driSupport = true;
        extraPackages = with pkgs;[
          rocmPackages.clr.icd
          amdvlk
        ];
      };

      boot.initrd.kernelModules = [ "amdgpu" ];

      systemd.tmpfiles.rules = [
        "L+    /opt/rocm/hip   -    -    -     -    ${pkgs.rocmPackages.clr}"
      ];

    };

    nvidia = { };

  }.${config.hp.hardware.gpu.core} or { };

}

{ lib
, pkgs
, config
, ...
}:
with lib;
let
  cfg = config.hp.hardware.gpu;

  intel = {

    hardware.opengl = {
      enable = true;
      driSupport = true;
      extraPackages = with pkgs;[
        intel-compute-runtime
        intel-media-driver # LIBVA_DRIVER_NAME=iHD
        (vaapiIntel.override { enableHybridCodec = true; }) # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
        vaapiVdpau
        libvdpau-va-gl
      ];
    };

    environment.sessionVariables = { LIBVA_DRIVER_NAME = "iHD"; }; # Force intel-media-driver
    # https://nixos.wiki/wiki/Intel_Graphics
    # boot.kernelParams = [ "i915.force_probe=<device ID>" ];

  };

  amd = {

    hardware.opengl = {
      enable = true;
      driSupport = true;
      extraPackages = with pkgs;[
        rocmPackages.clr.icd
        amdvlk
      ];
    };

    boot.initrd.kernelModules = [ "amdgpu" ];

    systemd.tmpfiles.rules = [
      "L+    /opt/rocm/hip   -    -    -     -    ${pkgs.rocmPackages.clr}"
    ];

  };

  nvidia = { };

in
{

  options = {
    hp.hardware.gpu =
      {
        enable = mkOption {
          type = types.bool;
          default = false;
        };

        core = mkOption {
          type = types.nullOr types.str;
          default = config.hp.hardware.cpu;
        };

      };
  };

  config =
    if ((cfg.enable || builtins.elem config.hp.lib.tags.gui config.hp.base.tags) && config.hp.hardware.gpu.core != null)
    then if config.hp.hardware.gpu.core == "intel"
    then intel
    else if config.hp.hardware.gpu.core == "amd"
    then amd
    else { }
    else { };
}

None of them work.
Error:

error:
       … while calling the 'seq' builtin

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:322:18:

          321|         options = checked options;
          322|         config = checked (removeAttrs config [ "_module" ]);
             |                  ^
          323|         _module = checked (config._module);

       … while evaluating a branch condition

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:261:9:

          260|       checkUnmatched =
          261|         if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
             |         ^
          262|           let

       … in the left operand of the AND (&&) operator

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:261:72:

          260|       checkUnmatched =
          261|         if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
             |                                                                        ^
          262|           let

       … in the left operand of the AND (&&) operator

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:261:33:

          260|       checkUnmatched =
          261|         if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [] then
             |                                 ^
          262|           let

       … while evaluating a branch condition

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:254:12:

          253|
          254|         in if declaredConfig._module.freeformType == null then declaredConfig
             |            ^
          255|           # Because all definitions that had an associated option ended in

       … while calling 'g'

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/attrsets.nix:736:19:

          735|           g =
          736|             name: value:
             |                   ^
          737|             if isAttrs value && cond value

       … from call site

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/attrsets.nix:739:20:

          738|               then recurse (path ++ [name]) value
          739|               else f (path ++ [name]) value;
             |                    ^
          740|         in mapAttrs g;

       … while calling anonymous lambda

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:242:72:

          241|           # For definitions that have an associated option
          242|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                                                                        ^
          243|

       … while evaluating the option `_module.freeformType':

       … while calling anonymous lambda

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:540:19:

          539|     mergeModules' prefix modules
          540|       (concatMap (m: map (config: { file = m._file; inherit config; }) (pushDownProperties m.config)) modules);
             |                   ^
          541|

       … from call site

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:540:73:

          539|     mergeModules' prefix modules
          540|       (concatMap (m: map (config: { file = m._file; inherit config; }) (pushDownProperties m.config)) modules);
             |                                                                         ^
          541|

       … while calling 'pushDownProperties'

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:876:24:

          875|   */
          876|   pushDownProperties = cfg:
             |                        ^
          877|     if cfg._type or "" == "merge" then

       … from call site

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:474:20:

          473|           options = m.options or {};
          474|           config = addFreeformType (addMeta (m.config or {}));
             |                    ^
          475|         }

       … while calling 'addFreeformType'

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:459:25:

          458|         else config;
          459|       addFreeformType = config: if m ? freeformType
             |                         ^
          460|         then mkMerge [ config { _module.freeformType = m.freeformType; } ]

       … from call site

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:474:37:

          473|           options = m.options or {};
          474|           config = addFreeformType (addMeta (m.config or {}));
             |                                     ^
          475|         }

       … while calling 'addMeta'

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:456:17:

          455|     let
          456|       addMeta = config: if m ? meta
             |                 ^
          457|         then mkMerge [ config { meta = m.meta; } ]

       … while calling anonymous lambda

         at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:506:44:

          505|       context = name: ''while evaluating the module argument `${name}' in "${key}":'';
          506|       extraArgs = builtins.mapAttrs (name: _:
             |                                            ^
          507|         builtins.addErrorContext (context name)

       … while evaluating the module argument `config' in "/nix/store/fscysyyr9g9kg3hazr3vxy1w52xkmfq9-source/nixosModule/hardware/gpu.nix":

       error: infinite recursion encountered

       at /nix/store/12q868mnlryg9px31hiirv5hdm0gmpdb-source/lib/modules.nix:233:21:

          232|           (regularModules ++ [ internalModule ])
          233|           ({ inherit lib options config specialArgs; } // specialArgs);
             |                     ^
          234|         in mergeModules prefix (reverseList collected);

How can I make it work correctly?

Why can’t config be merged with the contents of “Attribute Set”?