Code review comment: You mean without looking fieldwise? Could work, we'll be creating an extra type I guess, but if it reduces special casing and is temporary should be OK. I believe we also discussed this once @prakanth97.  > What I'm suggesting is we don't touch the `immutableTypeMaps` in the overridden method  Populating the type in `immutableTypeMaps` will also have to be done here though? At the end maybe.

Code under review:
public void visit(BRecordType bRecordType) {
        BRecordType origRecordType = bRecordType.mutableType;
        BTypeSymbol structureSymbol = bRecordType.tsymbol;
        if (origRecordType != null) {
            if (origRecordType.fields.size() != bRecordType.fields.size()) {
                LinkedHashMap<String, BField> fields = new LinkedHashMap<>();
                for (BField origField : origRecordType.fields.values()) {
                    BType fieldType = ImmutableTypeCloner.getImmutableType(loc, types, origField.type, env,
                            env.enclPkg.packageID, env.scope.owner, symTable, anonymousModelHelper, names,
                            new HashSet<>());

                    Name origFieldName = origField.name;
                    BVarSymbol fieldSymbol;
                    BType referredType = Types.getReferredType(fieldType);
                    if (referredType.tag == TypeTags.INVOKABLE && referredType.tsymbol != null) {
                        fieldSymbol = new BInvokableSymbol(origField.symbol.tag,
                                origField.symbol.flags | Flags.READONLY, origFieldName, pkgID, fieldType,
                                structureSymbol, origField.symbol.pos, SOURCE);
                        BInvokableTypeSymbol tsymbol = (BInvokableTypeSymbol) referredType.tsymbol;
                        BInvokableSymbol invokableSymbol = (BInvokableSymbol) fieldSymbol;
                        invokableSymbol.params = tsymbol.params == null ? null : new ArrayList<>(tsymbol.params);
                        invokableSymbol.restParam = tsymbol.restParam;
                        invokableSymbol.retType = tsymbol.returnType;
                        invokableSymbol.flags = tsymbol.flags;
                    } else if (fieldType == symTable.semanticError) {
                        
                        fieldSymbol = new BVarSymbol(origField.symbol.flags | Flags.READONLY | Flags.OPTIONAL,
                                origFieldName, pkgID, symTable.neverType,
                                structureSymbol, origField.symbol.pos, SOURCE);
                    } else {
                        fieldSymbol = new BVarSymbol(origField.symbol.flags | Flags.READONLY, origFieldName, pkgID,
                                fieldType, structureSymbol,
                                origField.symbol.pos, SOURCE);
                    }
                    String nameString = origFieldName.value;
                    fields.put(nameString, new BField(origFieldName, null, fieldSymbol));
                    structureSymbol.scope.define(origFieldName, fieldSymbol);
                }
                bRecordType.fields = fields;
                bRecordType.restFieldType = origRecordType.restFieldType;
            } else {
                for (BField immutableField : bRecordType.fields.values()) {
                    BField origField = origRecordType.fields.get(immutableField.name.value);
                    if (immutableField.type.tag == TypeTags.NEVER) {
                        immutableField.type = ImmutableTypeCloner.getImmutableType(loc, types, origField.type, env,
                                env.enclPkg.packageID, env.scope.owner, symTable, anonymousModelHelper, names,
                                new HashSet<>());
                    }
                    Name origFieldName = origField.name;
                    updateType(immutableField.type, loc, pkgID, typeNode, env);
                    immutableField.symbol = new BVarSymbol(origField.symbol.flags | Flags.READONLY, origFieldName,
                            pkgID, immutableField.type, structureSymbol, origField.symbol.pos, SOURCE);
                    structureSymbol.scope.define(origFieldName, immutableField.symbol);
                }
            }
            bRecordType.mutableType = null;
        }
    }

Line commented on: if (origRecordType.fields.size() != bRecordType.fields.size()) {

Revised code:
public void visit(BRecordType bRecordType) {
        BRecordType origRecordType = bRecordType.mutableType;
        BTypeSymbol structureSymbol = bRecordType.tsymbol;
        if (origRecordType != null) {
            if (origRecordType.fields.size() != bRecordType.fields.size()) {
                LinkedHashMap<String, BField> fields = new LinkedHashMap<>();
                for (BField origField : origRecordType.fields.values()) {
                    BType fieldType = ImmutableTypeCloner.getImmutableType(loc, types, origField.type, env,
                            pkgID, env.scope.owner, symTable, anonymousModelHelper, names,
                            new HashSet<>());

                    Name origFieldName = origField.name;
                    BVarSymbol fieldSymbol;
                    BType referredType = Types.getReferredType(fieldType);
                    if (referredType.tag == TypeTags.INVOKABLE && referredType.tsymbol != null) {
                        fieldSymbol = new BInvokableSymbol(origField.symbol.tag,
                                origField.symbol.flags | Flags.READONLY, origFieldName, pkgID, fieldType,
                                structureSymbol, origField.symbol.pos, SOURCE);
                        BInvokableTypeSymbol tsymbol = (BInvokableTypeSymbol) referredType.tsymbol;
                        BInvokableSymbol invokableSymbol = (BInvokableSymbol) fieldSymbol;
                        invokableSymbol.params = tsymbol.params == null ? null : new ArrayList<>(tsymbol.params);
                        invokableSymbol.restParam = tsymbol.restParam;
                        invokableSymbol.retType = tsymbol.returnType;
                        invokableSymbol.flags = tsymbol.flags;
                    } else if (fieldType == symTable.semanticError) {
                        
                        fieldSymbol = new BVarSymbol(origField.symbol.flags | Flags.READONLY | Flags.OPTIONAL,
                                origFieldName, pkgID, symTable.neverType,
                                structureSymbol, origField.symbol.pos, SOURCE);
                    } else {
                        fieldSymbol = new BVarSymbol(origField.symbol.flags | Flags.READONLY, origFieldName, pkgID,
                                fieldType, structureSymbol,
                                origField.symbol.pos, SOURCE);
                    }
                    String nameString = origFieldName.value;
                    fields.put(nameString, new BField(origFieldName, null, fieldSymbol));
                    structureSymbol.scope.define(origFieldName, fieldSymbol);
                }
                bRecordType.fields = fields;
                bRecordType.restFieldType = origRecordType.restFieldType;
            } else {
                for (BField immutableField : bRecordType.fields.values()) {
                    BField origField = origRecordType.fields.get(immutableField.name.value);
                    if (immutableField.type.tag == TypeTags.NEVER) {
                        immutableField.type = ImmutableTypeCloner.getImmutableType(loc, types, origField.type, env,
                                pkgID, env.scope.owner, symTable, anonymousModelHelper, names,
                                new HashSet<>());
                    }
                    Name origFieldName = origField.name;
                    updateType(immutableField.type, loc, pkgID, typeNode, env);
                    immutableField.symbol = new BVarSymbol(origField.symbol.flags | Flags.READONLY, origFieldName,
                            pkgID, immutableField.type, structureSymbol, origField.symbol.pos, SOURCE);
                    structureSymbol.scope.define(origFieldName, immutableField.symbol);
                }
            }
            bRecordType.mutableType = null;
        }
    }