Code review comment: Can a non error type reach as `detailType` here?

Code under review:
public void visit(BLangErrorConstructorExpr errorConstructorExpr, AnalyzerData data) {
        BLangUserDefinedType userProvidedTypeRef = errorConstructorExpr.errorTypeRef;
        if (userProvidedTypeRef != null) {
            symResolver.resolveTypeNode(userProvidedTypeRef, data.env,
                                        DiagnosticErrorCode.UNDEFINED_ERROR_TYPE_DESCRIPTOR);
        }
        validateErrorConstructorPositionalArgs(errorConstructorExpr, data);

        List<BType> expandedCandidates = getTypeCandidatesForErrorConstructor(errorConstructorExpr, data);

        List<BType> errorDetailTypes = new ArrayList<>(expandedCandidates.size());
        for (BType expandedCandidate : expandedCandidates) {
            BType detailType = Types.getReferredType(expandedCandidate);
            if (detailType.tag == TypeTags.INTERSECTION) {
                detailType = ((BIntersectionType) detailType).effectiveType;
            }
            detailType = ((BErrorType) detailType).detailType;
            errorDetailTypes.add(Types.getReferredType(detailType));
        }

        BType detailCandidate;
        if (errorDetailTypes.size() == 1) {
            detailCandidate = errorDetailTypes.get(0);
        } else {
            detailCandidate = BUnionType.create(null, new LinkedHashSet<>(errorDetailTypes));
        }

        BLangRecordLiteral recordLiteral = createRecordLiteralForErrorConstructor(errorConstructorExpr);
        BType inferredDetailType = checkExprSilent(recordLiteral, detailCandidate, data);

        int index = errorDetailTypes.indexOf(inferredDetailType);
        BType selectedCandidate = index < 0 ? symTable.semanticError : expandedCandidates.get(index);

        if (selectedCandidate != symTable.semanticError
                && (userProvidedTypeRef == null
                || Types.getReferredType(userProvidedTypeRef.getBType()) == Types.getReferredType(selectedCandidate))) {
            checkProvidedErrorDetails(errorConstructorExpr, inferredDetailType, data);
            
            
            data.resultType = types.checkType(errorConstructorExpr.pos, selectedCandidate, data.expType,
                    DiagnosticErrorCode.INCOMPATIBLE_TYPES);
            return;
        }

        if (userProvidedTypeRef == null && errorDetailTypes.size() > 1) {
            dlog.error(errorConstructorExpr.pos, DiagnosticErrorCode.CANNOT_INFER_ERROR_TYPE, data.expType);
        }

        boolean validTypeRefFound = false;
        
        
        BErrorType errorType;
        if (userProvidedTypeRef != null
                && Types.getReferredType(userProvidedTypeRef.getBType()).tag == TypeTags.ERROR) {
            errorType = (BErrorType) Types.getReferredType(userProvidedTypeRef.getBType());
            validTypeRefFound = true;
        } else if (expandedCandidates.size() == 1) {
            errorType = (BErrorType) Types.getReferredType(expandedCandidates.get(0));
        } else {
            errorType = symTable.errorType;
        }
        List<BLangNamedArgsExpression> namedArgs =
                checkProvidedErrorDetails(errorConstructorExpr, errorType.detailType, data);

        BType detailType = errorType.detailType;

        if (Types.getReferredType(detailType).tag == TypeTags.MAP) {
            BType errorDetailTypeConstraint = ((BMapType) Types.getReferredType(detailType)).constraint;
            for (BLangNamedArgsExpression namedArgExpr: namedArgs) {
                if (Types.getReferredType(errorDetailTypeConstraint).tag == TypeTags.UNION &&
                        !types.isAssignable(namedArgExpr.expr.getBType(), errorDetailTypeConstraint)) {
                    dlog.error(namedArgExpr.pos, DiagnosticErrorCode.INVALID_ERROR_DETAIL_ARG_TYPE,
                               namedArgExpr.name, errorDetailTypeConstraint, namedArgExpr.expr.getBType());
                }
            }
        } else if (Types.getReferredType(detailType).tag == TypeTags.RECORD) {
            BRecordType targetErrorDetailRec = (BRecordType) Types.getReferredType(errorType.detailType);

            LinkedList<String> missingRequiredFields = targetErrorDetailRec.fields.values().stream()
                    .filter(f -> (f.symbol.flags & Flags.REQUIRED) == Flags.REQUIRED)
                    .map(f -> f.name.value)
                    .collect(Collectors.toCollection(LinkedList::new));

            LinkedHashMap<String, BField> targetFields = targetErrorDetailRec.fields;
            for (BLangNamedArgsExpression namedArg : namedArgs) {
                BField field = targetFields.get(namedArg.name.value);
                Location pos = namedArg.pos;
                if (field == null) {
                    if (targetErrorDetailRec.sealed) {
                        dlog.error(pos, DiagnosticErrorCode.UNKNOWN_DETAIL_ARG_TO_CLOSED_ERROR_DETAIL_REC,
                                namedArg.name, targetErrorDetailRec);
                    } else if (targetFields.isEmpty()
                            && !types.isAssignable(namedArg.expr.getBType(), targetErrorDetailRec.restFieldType)) {
                        dlog.error(pos, DiagnosticErrorCode.INVALID_ERROR_DETAIL_REST_ARG_TYPE,
                                namedArg.name, targetErrorDetailRec);
                    }
                } else {
                    missingRequiredFields.remove(namedArg.name.value);
                    if (Types.getReferredType(field.type).tag == TypeTags.UNION &&
                            !types.isAssignable(namedArg.expr.getBType(), field.type)) {
                        dlog.error(pos, DiagnosticErrorCode.INVALID_ERROR_DETAIL_ARG_TYPE,
                                   namedArg.name, field.type, namedArg.expr.getBType());
                    }
                }
            }

            for (String requiredField : missingRequiredFields) {
                dlog.error(errorConstructorExpr.pos, DiagnosticErrorCode.MISSING_ERROR_DETAIL_ARG, requiredField);
            }
        }

        if (userProvidedTypeRef != null) {
            errorConstructorExpr.setBType(Types.getReferredType(userProvidedTypeRef.getBType()));
        } else {
            errorConstructorExpr.setBType(errorType);
        }

        BType resolvedType = errorConstructorExpr.getBType();
        if (resolvedType != symTable.semanticError && data.expType != symTable.noType &&
                !types.isAssignable(resolvedType, data.expType)) {
            if (validTypeRefFound) {
                dlog.error(errorConstructorExpr.pos, DiagnosticErrorCode.INCOMPATIBLE_TYPES,
                        data.expType, userProvidedTypeRef);
            } else {
                dlog.error(errorConstructorExpr.pos,
                        DiagnosticErrorCode.ERROR_CONSTRUCTOR_COMPATIBLE_TYPE_NOT_FOUND, data.expType);
            }
            data.resultType = symTable.semanticError;
            return;
        }
        data.resultType = resolvedType;
    }

Line commented on: detailType = ((BErrorType) detailType).detailType;

Revised code:
public void visit(BLangErrorConstructorExpr errorConstructorExpr, AnalyzerData data) {
        BLangUserDefinedType userProvidedTypeRef = errorConstructorExpr.errorTypeRef;
        if (userProvidedTypeRef != null) {
            symResolver.resolveTypeNode(userProvidedTypeRef, data.env,
                                        DiagnosticErrorCode.UNDEFINED_ERROR_TYPE_DESCRIPTOR);
        }
        validateErrorConstructorPositionalArgs(errorConstructorExpr, data);

        List<BType> expandedCandidates = getTypeCandidatesForErrorConstructor(errorConstructorExpr, data);

        List<BType> errorDetailTypes = new ArrayList<>(expandedCandidates.size());
        for (BType expandedCandidate : expandedCandidates) {
            BType detailType = ((BErrorType) Types.getEffectiveType(Types
                    .getReferredType(expandedCandidate))).detailType;
            errorDetailTypes.add(Types.getReferredType(detailType));
        }

        BType detailCandidate;
        if (errorDetailTypes.size() == 1) {
            detailCandidate = errorDetailTypes.get(0);
        } else {
            detailCandidate = BUnionType.create(null, new LinkedHashSet<>(errorDetailTypes));
        }

        BLangRecordLiteral recordLiteral = createRecordLiteralForErrorConstructor(errorConstructorExpr);
        BType inferredDetailType = checkExprSilent(recordLiteral, detailCandidate, data);

        int index = errorDetailTypes.indexOf(inferredDetailType);
        BType selectedCandidate = index < 0 ? symTable.semanticError : expandedCandidates.get(index);

        if (selectedCandidate != symTable.semanticError
                && (userProvidedTypeRef == null
                || Types.getReferredType(userProvidedTypeRef.getBType()) == Types.getReferredType(selectedCandidate))) {
            checkProvidedErrorDetails(errorConstructorExpr, inferredDetailType, data);
            
            
            data.resultType = types.checkType(errorConstructorExpr.pos, selectedCandidate, data.expType,
                    DiagnosticErrorCode.INCOMPATIBLE_TYPES);
            return;
        }

        if (userProvidedTypeRef == null && errorDetailTypes.size() > 1) {
            dlog.error(errorConstructorExpr.pos, DiagnosticErrorCode.CANNOT_INFER_ERROR_TYPE, data.expType);
        }

        boolean validTypeRefFound = false;
        
        
        BErrorType errorType;
        if (userProvidedTypeRef != null
                && Types.getReferredType(userProvidedTypeRef.getBType()).tag == TypeTags.ERROR) {
            errorType = (BErrorType) Types.getReferredType(userProvidedTypeRef.getBType());
            validTypeRefFound = true;
        } else if (expandedCandidates.size() == 1) {
            errorType = (BErrorType) Types.getReferredType(expandedCandidates.get(0));
        } else {
            errorType = symTable.errorType;
        }
        List<BLangNamedArgsExpression> namedArgs =
                checkProvidedErrorDetails(errorConstructorExpr, errorType.detailType, data);

        BType detailType = errorType.detailType;

        if (Types.getReferredType(detailType).tag == TypeTags.MAP) {
            BType errorDetailTypeConstraint = ((BMapType) Types.getReferredType(detailType)).constraint;
            for (BLangNamedArgsExpression namedArgExpr: namedArgs) {
                if (Types.getReferredType(errorDetailTypeConstraint).tag == TypeTags.UNION &&
                        !types.isAssignable(namedArgExpr.expr.getBType(), errorDetailTypeConstraint)) {
                    dlog.error(namedArgExpr.pos, DiagnosticErrorCode.INVALID_ERROR_DETAIL_ARG_TYPE,
                               namedArgExpr.name, errorDetailTypeConstraint, namedArgExpr.expr.getBType());
                }
            }
        } else if (Types.getReferredType(detailType).tag == TypeTags.RECORD) {
            BRecordType targetErrorDetailRec = (BRecordType) Types.getReferredType(errorType.detailType);

            LinkedList<String> missingRequiredFields = targetErrorDetailRec.fields.values().stream()
                    .filter(f -> (f.symbol.flags & Flags.REQUIRED) == Flags.REQUIRED)
                    .map(f -> f.name.value)
                    .collect(Collectors.toCollection(LinkedList::new));

            LinkedHashMap<String, BField> targetFields = targetErrorDetailRec.fields;
            for (BLangNamedArgsExpression namedArg : namedArgs) {
                BField field = targetFields.get(namedArg.name.value);
                Location pos = namedArg.pos;
                if (field == null) {
                    if (targetErrorDetailRec.sealed) {
                        dlog.error(pos, DiagnosticErrorCode.UNKNOWN_DETAIL_ARG_TO_CLOSED_ERROR_DETAIL_REC,
                                namedArg.name, targetErrorDetailRec);
                    } else if (targetFields.isEmpty()
                            && !types.isAssignable(namedArg.expr.getBType(), targetErrorDetailRec.restFieldType)) {
                        dlog.error(pos, DiagnosticErrorCode.INVALID_ERROR_DETAIL_REST_ARG_TYPE,
                                namedArg.name, targetErrorDetailRec);
                    }
                } else {
                    missingRequiredFields.remove(namedArg.name.value);
                    if (Types.getReferredType(field.type).tag == TypeTags.UNION &&
                            !types.isAssignable(namedArg.expr.getBType(), field.type)) {
                        dlog.error(pos, DiagnosticErrorCode.INVALID_ERROR_DETAIL_ARG_TYPE,
                                   namedArg.name, field.type, namedArg.expr.getBType());
                    }
                }
            }

            for (String requiredField : missingRequiredFields) {
                dlog.error(errorConstructorExpr.pos, DiagnosticErrorCode.MISSING_ERROR_DETAIL_ARG, requiredField);
            }
        }

        if (userProvidedTypeRef != null) {
            errorConstructorExpr.setBType(Types.getReferredType(userProvidedTypeRef.getBType()));
        } else {
            errorConstructorExpr.setBType(errorType);
        }

        BType resolvedType = errorConstructorExpr.getBType();
        if (resolvedType != symTable.semanticError && data.expType != symTable.noType &&
                !types.isAssignable(resolvedType, data.expType)) {
            if (validTypeRefFound) {
                dlog.error(errorConstructorExpr.pos, DiagnosticErrorCode.INCOMPATIBLE_TYPES,
                        data.expType, userProvidedTypeRef);
            } else {
                dlog.error(errorConstructorExpr.pos,
                        DiagnosticErrorCode.ERROR_CONSTRUCTOR_COMPATIBLE_TYPE_NOT_FOUND, data.expType);
            }
            data.resultType = symTable.semanticError;
            return;
        }
        data.resultType = resolvedType;
    }