// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/tint/lang/core/intrinsic/table.h"

#include <algorithm>
#include <limits>
#include <ostream>
#include <utility>

#include "src/tint/lang/core/evaluation_stage.h"
#include "src/tint/lang/core/intrinsic/table_data.h"
#include "src/tint/lang/core/type/invalid.h"
#include "src/tint/lang/core/type/manager.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/utils/containers/slice.h"
#include "src/tint/utils/ice/ice.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/text_style.h"

namespace tint::core::intrinsic {

const Number Number::any{Number::kAny};
const Number Number::invalid{Number::kInvalid};

Any::Any() : Base(0u, core::type::Flags{}) {}
Any::~Any() = default;

bool Any::Equals(const core::type::UniqueNode&) const {
    return false;
}

std::string Any::FriendlyName() const {
    return "<any>";
}

core::type::Type* Any::Clone(core::type::CloneContext&) const {
    return nullptr;
}

namespace {

/// The Vector `N` template argument value for arrays of parameters.
constexpr const size_t kNumFixedParameters = Overload::kNumFixedParameters;

/// The Vector `N` template argument value for arrays of overload candidates.
constexpr const size_t kNumFixedCandidates = 8;

/// A list of candidates
using Candidates = Vector<Candidate, kNumFixedCandidates>;

/// Callback function when no overloads match.
using OnNoMatch = std::function<StyledText(VectorRef<Candidate>)>;

/// Sorts the candidates based on their score, with the lowest (best-ranking) scores first.
static inline void SortCandidates(Candidates& candidates) {
    std::stable_sort(candidates.begin(), candidates.end(),
                     [&](const Candidate& a, const Candidate& b) { return a.score < b.score; });
}

/// Prints a list of types.
static void PrintTypeList(StyledText& ss, VectorRef<const core::type::Type*> types) {
    bool first = true;
    for (auto* arg : types) {
        if (!first) {
            ss << ", ";
        }
        first = false;
        ss << style::Type(arg->FriendlyName());
    }
}

/// Attempts to find a single intrinsic overload that matches the provided argument types.
/// @param context the intrinsic context
/// @param intrinsic the intrinsic being called
/// @param intrinsic_name the name of the intrinsic
/// @param template_args the template argument types
/// @param args the argument types
/// @param on_no_match an error callback when no intrinsic overloads matched the provided
///                    arguments.
/// @returns the matched intrinsic
Result<Overload, StyledText> MatchIntrinsic(Context& context,
                                            const IntrinsicInfo& intrinsic,
                                            std::string_view intrinsic_name,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage,
                                            const OnNoMatch& on_no_match);

/// The scoring mode for ScoreOverload()
enum class ScoreMode {
    /// If the overload doesn't match, then the returned Candidate will simply have a score of 1.
    /// No other fields will be populated.
    kEarlyReject,
    /// A more expensive score calculations will be made for the overload, which can be used
    /// to rank potential overloads
    kFull
};

/// Evaluates the single overload for the provided argument types.
/// @param context the intrinsic context
/// @param overload the overload being considered
/// @param template_args the template argument types
/// @param args the argument types
/// @tparam MODE the scoring mode to use. Passed as a template argument to ensure that the
/// extremely-hot function is specialized without scoring logic for the common code path.
/// @returns the evaluated Candidate information.
template <ScoreMode MODE>
Candidate ScoreOverload(Context& context,
                        const OverloadInfo& overload,
                        VectorRef<const core::type::Type*> template_args,
                        VectorRef<const core::type::Type*> args,
                        EvaluationStage earliest_eval_stage);

/// Performs overload resolution given the list of candidates, by ranking the conversions of
/// arguments to the each of the candidate's parameter types.
/// @param context the intrinsic context
/// @param candidates the list of candidate overloads
/// @param intrinsic_name the name of the intrinsic
/// @param template_args the template argument types
/// @param args the argument types
/// @see https://www.w3.org/TR/WGSL/#overload-resolution-section
/// @returns the resolved Candidate.
Result<Candidate, StyledText> ResolveCandidate(Context& context,
                                               Candidates&& candidates,
                                               std::string_view intrinsic_name,
                                               VectorRef<const core::type::Type*> template_args,
                                               VectorRef<const core::type::Type*> args);

// Prints the list of candidates for emitting diagnostics
void PrintCandidates(StyledText& err,
                     Context& context,
                     VectorRef<Candidate> candidates,
                     std::string_view intrinsic_name,
                     VectorRef<const core::type::Type*> template_args,
                     VectorRef<const core::type::Type*> args);

/// Raises an ICE when no overload is a clear winner of overload resolution
StyledText ErrAmbiguousOverload(Context& context,
                                std::string_view intrinsic_name,
                                VectorRef<const core::type::Type*> template_args,
                                VectorRef<const core::type::Type*> args,
                                VectorRef<Candidate> candidates);

/// @return a string representing a call to a builtin with the given argument types.
StyledText CallSignature(std::string_view intrinsic_name,
                         VectorRef<const core::type::Type*> template_args,
                         VectorRef<const core::type::Type*> args) {
    StyledText out;
    out << style::Code << style::Function(intrinsic_name);
    if (!template_args.IsEmpty()) {
        out << "<";
        PrintTypeList(out, template_args);
        out << ">";
    }
    out << "(";
    PrintTypeList(out, args);
    out << ")";

    return out;
}

Result<Overload, StyledText> MatchIntrinsic(Context& context,
                                            const IntrinsicInfo& intrinsic,
                                            std::string_view intrinsic_name,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage,
                                            const OnNoMatch& on_no_match) {
    const size_t num_overloads = static_cast<size_t>(intrinsic.num_overloads);
    size_t num_matched = 0;
    size_t match_idx = 0;
    Vector<Candidate, kNumFixedCandidates> candidates;
    candidates.Reserve(intrinsic.num_overloads);
    for (size_t overload_idx = 0; overload_idx < num_overloads; overload_idx++) {
        auto& overload = context.data[intrinsic.overloads + overload_idx];
        auto candidate = ScoreOverload<ScoreMode::kEarlyReject>(context, overload, template_args,
                                                                args, earliest_eval_stage);
        if (candidate.score == 0) {
            match_idx = overload_idx;
            num_matched++;
        }
        candidates.Push(std::move(candidate));
    }

    // How many candidates matched?
    if (TINT_UNLIKELY(num_matched == 0)) {
        // Perform the full scoring of each overload
        for (size_t overload_idx = 0; overload_idx < num_overloads; overload_idx++) {
            auto& overload = context.data[intrinsic.overloads + overload_idx];
            candidates[overload_idx] = ScoreOverload<ScoreMode::kFull>(
                context, overload, template_args, args, earliest_eval_stage);
        }
        // Sort the candidates with the most promising first
        SortCandidates(candidates);
        return on_no_match(std::move(candidates));
    }

    Candidate match;

    if (num_matched == 1) {
        match = std::move(candidates[match_idx]);
    } else {
        auto result =
            ResolveCandidate(context, std::move(candidates), intrinsic_name, template_args, args);
        if (TINT_UNLIKELY(result != Success)) {
            return result.Failure();
        }
        match = result.Get();
    }

    // Build the return type
    const core::type::Type* return_type = nullptr;
    if (auto* matcher_indices = context.data[match.overload->return_matcher_indices]) {
        Any any;
        return_type =
            context.Match(match.templates, *match.overload, matcher_indices, earliest_eval_stage)
                .Type(&any);
        if (TINT_UNLIKELY(!return_type)) {
            StyledText err;
            err << "MatchState.MatchState() returned null";
            TINT_ICE() << err.Plain();
            return err;
        }
    } else {
        return_type = context.types.void_();
    }

    return Overload{match.overload, return_type, std::move(match.parameters),
                    context.data[match.overload->const_eval_fn]};
}

template <ScoreMode MODE>
Candidate ScoreOverload(Context& context,
                        const OverloadInfo& overload,
                        VectorRef<const core::type::Type*> template_args,
                        VectorRef<const core::type::Type*> args,
                        EvaluationStage earliest_eval_stage) {
#define MATCH_FAILURE(PENALTY)                           \
    do {                                                 \
        if constexpr (MODE == ScoreMode::kEarlyReject) { \
            return Candidate{1};                         \
        } else {                                         \
            score += PENALTY;                            \
        }                                                \
    } while (false)

    // Penalty weights for overload mismatching.
    // This scoring is used to order the suggested overloads in diagnostic on overload mismatch, and
    // has no impact for a correct program.
    // The overloads with the lowest score will be displayed first (top-most).
    constexpr int kMismatchedExplicitTemplateCountPenalty = 10;
    constexpr int kMismatchedParamCountPenalty = 3;
    constexpr int kMismatchedParamTypePenalty = 2;
    constexpr int kMismatchedExplicitTemplateTypePenalty = 1;
    constexpr int kMismatchedImplicitTemplateTypePenalty = 1;
    constexpr int kMismatchedImplicitTemplateNumberPenalty = 1;

    const size_t num_parameters = static_cast<size_t>(overload.num_parameters);
    const size_t num_arguments = static_cast<size_t>(args.Length());

    size_t score = 0;

    if (num_parameters != num_arguments) {
        MATCH_FAILURE(kMismatchedParamCountPenalty * (std::max(num_parameters, num_arguments) -
                                                      std::min(num_parameters, num_arguments)));
    }

    // Check that all of the template arguments provided are actually expected by the overload.
    const size_t expected_templates = overload.num_explicit_templates;
    const size_t provided_templates = template_args.Length();
    if (provided_templates != expected_templates) {
        MATCH_FAILURE(kMismatchedExplicitTemplateCountPenalty *
                      (std::max(expected_templates, provided_templates) -
                       std::min(expected_templates, provided_templates)));
    }

    TemplateState templates;

    // Check that the explicit template arguments match the constraint if specified, otherwise
    // just set the template type.
    auto num_tmpl_args = std::min<size_t>(overload.num_explicit_templates, template_args.Length());
    for (size_t i = 0; i < num_tmpl_args; ++i) {
        auto& tmpl = context.data[overload.templates + i];
        auto* type = template_args[i];
        if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
            // Ensure type matches the template's matcher.
            type =
                context.Match(templates, overload, matcher_indices, earliest_eval_stage).Type(type);
            if (!type) {
                MATCH_FAILURE(kMismatchedExplicitTemplateTypePenalty);
                continue;
            }
        }
        templates.SetType(i, type);
    }

    // Invoke the matchers for each parameter <-> argument pair.
    // If any arguments cannot be matched, then `score` will be increased.
    // If the overload has any template types or numbers then these will be set based on the
    // argument types. Template types may be refined by constraining with later argument types. For
    // example calling `F<T>(T, T)` with the argument types (abstract-int, i32) will first set T to
    // abstract-int when matching the first argument, and then constrained down to i32 when matching
    // the second argument.
    // Note that inferred template types are not tested against their matchers at this point.
    auto num_params = std::min(num_parameters, num_arguments);
    for (size_t p = 0; p < num_params; p++) {
        auto& parameter = context.data[overload.parameters + p];
        auto* matcher_indices = context.data[parameter.matcher_indices];
        if (!context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                 .Type(args[p])) {
            MATCH_FAILURE(kMismatchedParamTypePenalty);
        }
    }

    // Check each of the inferred types and numbers for the implicit templates match their
    // respective matcher.
    for (size_t i = overload.num_explicit_templates; i < overload.num_templates; i++) {
        auto& tmpl = context.data[overload.templates + i];
        auto* matcher_indices = context.data[tmpl.matcher_indices];
        if (!matcher_indices) {
            continue;
        }

        auto matcher = context.Match(templates, overload, matcher_indices, earliest_eval_stage);

        switch (tmpl.kind) {
            case TemplateInfo::Kind::kType: {
                // Check all constrained template types matched their constraint matchers.
                // If the template type *does not* match any of the types in the constraint
                // matcher, then `score` is incremented and the template is assigned an invalid
                // type. If the template type *does* match a type, then the template type is
                // replaced with the first matching type. The order of types in the template matcher
                // is important here, which can be controlled with the [[precedence(N)]] decorations
                // on the types in the def file.
                if (auto* type = templates.Type(i)) {
                    if (auto* ty = matcher.Type(type)) {
                        // Template type matched one of the types in the template type's
                        // matcher. Replace the template type with this type.
                        templates.SetType(i, ty);
                        continue;
                    }
                }
                templates.SetType(i, context.types.invalid());
                MATCH_FAILURE(kMismatchedImplicitTemplateTypePenalty);
                break;
            }

            case TemplateInfo::Kind::kNumber: {
                // Checking that the inferred number matches the constraints on the
                // template. Increments `score` and assigns the template an invalid number if the
                // template numbers do not match their constraint matchers.
                auto number = templates.Num(i);
                if (!number.IsValid() || !matcher.Num(number).IsValid()) {
                    templates.SetNum(i, Number::invalid);
                    MATCH_FAILURE(kMismatchedImplicitTemplateNumberPenalty);
                }
            }
        }
    }

    // Now that all the template types have been finalized, we can construct the parameters.
    Vector<Overload::Parameter, kNumFixedParameters> parameters;
    parameters.Reserve(num_params);
    for (size_t p = 0; p < num_params; p++) {
        auto& parameter = context.data[overload.parameters + p];
        auto* matcher_indices = context.data[parameter.matcher_indices];
        auto* ty =
            context.Match(templates, overload, matcher_indices, earliest_eval_stage).Type(args[p]);
        parameters.Emplace(ty, parameter.usage);
    }

    return Candidate{score, &overload, templates, parameters};
#undef MATCH_FAILURE
}

Result<Candidate, StyledText> ResolveCandidate(Context& context,
                                               Candidates&& candidates,
                                               std::string_view intrinsic_name,
                                               VectorRef<const core::type::Type*> template_args,
                                               VectorRef<const core::type::Type*> args) {
    Vector<uint32_t, kNumFixedParameters> best_ranks;
    best_ranks.Resize(args.Length(), 0xffffffff);
    size_t num_matched = 0;
    Candidate* best = nullptr;
    for (auto& candidate : candidates) {
        if (candidate.score > 0) {
            continue;  // Candidate has already been ruled out.
        }
        bool some_won = false;   // An argument ranked less than the 'best' overload's argument
        bool some_lost = false;  // An argument ranked more than the 'best' overload's argument
        for (size_t i = 0; i < args.Length(); i++) {
            auto rank = core::type::Type::ConversionRank(args[i], candidate.parameters[i].type);
            if (best_ranks[i] > rank) {
                best_ranks[i] = rank;
                some_won = true;
            } else if (best_ranks[i] < rank) {
                some_lost = true;
            }
        }
        // If no arguments of this candidate ranked worse than the previous best candidate, then
        // this candidate becomes the new best candidate.
        // If no arguments of this candidate ranked better than the previous best candidate, then
        // this candidate is removed from the list of matches.
        // If neither of the above apply, then we have two candidates with no clear winner, which
        // results in an ambiguous overload error. In this situation the loop ends with
        // `num_matched > 1`.
        if (some_won) {
            // One or more arguments of this candidate ranked better than the previous best
            // candidate's argument(s).
            num_matched++;
            if (!some_lost) {
                // All arguments were at as-good or better than the previous best.
                if (best) {
                    // Mark the previous best candidate as no longer being in the running, by
                    // setting its score to a non-zero value. We pick 1 as this is the closest to 0
                    // (match) as we can get.
                    best->score = 1;
                    num_matched--;
                }
                // This candidate is the new best.
                best = &candidate;
            }
        } else {
            // No arguments ranked better than the current best.
            // Change the score of this candidate to a non-zero value, so that it's not considered a
            // match.
            candidate.score = 1;
        }
    }

    if (num_matched > 1) {
        // Re-sort the candidates with the most promising first
        SortCandidates(candidates);
        // Raise an error
        return ErrAmbiguousOverload(context, intrinsic_name, template_args, args, candidates);
    }

    return std::move(*best);
}

void PrintCandidates(StyledText& ss,
                     Context& context,
                     VectorRef<Candidate> candidates,
                     std::string_view intrinsic_name,
                     VectorRef<const core::type::Type*> template_args,
                     VectorRef<const core::type::Type*> args) {
    for (auto& candidate : candidates) {
        ss << " • ";
        PrintCandidate(ss, context, candidate, intrinsic_name, template_args, args);
        ss << "\n";
    }
}

StyledText ErrAmbiguousOverload(Context& context,
                                std::string_view intrinsic_name,
                                VectorRef<const core::type::Type*> template_args,
                                VectorRef<const core::type::Type*> args,
                                VectorRef<Candidate> candidates) {
    StyledText err;
    err << "ambiguous overload while attempting to match "
        << CallSignature(intrinsic_name, template_args, args) << "\n";

    for (auto& candidate : candidates) {
        if (candidate.score == 0) {
            err << "  ";
            PrintCandidate(err, context, candidate, intrinsic_name, template_args, args);
            err << "\n";
        }
    }
    TINT_ICE() << err.Plain();
    return err;
}

}  // namespace

void PrintCandidate(StyledText& ss,
                    Context& context,
                    const Candidate& candidate,
                    std::string_view intrinsic_name,
                    VectorRef<const core::type::Type*> template_args,
                    VectorRef<const core::type::Type*> args) {
    // Restore old style before returning.
    auto prev_style = ss.Style();
    TINT_DEFER(ss << prev_style);

    auto& overload = *candidate.overload;

    TemplateState templates = candidate.templates;

    // TODO(crbug.com/tint/1730): Use input evaluation stage to output only relevant overloads.
    auto earliest_eval_stage = EvaluationStage::kConstant;

    ss << style::Code << style::Function(intrinsic_name);

    if (overload.num_explicit_templates > 0) {
        ss << "<";
        for (size_t i = 0; i < overload.num_explicit_templates; i++) {
            const auto& tmpl = context.data[overload.templates + i];

            bool matched = false;
            if (i < template_args.Length()) {
                auto* matcher_indices = context.data[tmpl.matcher_indices];
                matched = !matcher_indices ||
                          context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                              .Type(template_args[i]);
            }

            if (i > 0) {
                ss << ", ";
            }
            ss << style::Type(tmpl.name) << " ";
            if (matched) {
                ss << (style::Code + style::Match)(" ✓ ");
            } else {
                ss << (style::Code + style::Mismatch)(" ✗ ");
            }
        }
        ss << ">";
    }

    bool all_params_match = true;
    ss << "(";
    for (size_t i = 0; i < overload.num_parameters; i++) {
        const auto& parameter = context.data[overload.parameters + i];
        auto* matcher_indices = context.data[parameter.matcher_indices];

        bool matched = false;
        if (i < args.Length()) {
            matched = context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                          .Type(args[i]);
        }
        all_params_match = all_params_match && matched;

        if (i > 0) {
            ss << ", ";
        }

        if (parameter.usage != ParameterUsage::kNone) {
            ss << style::Variable(parameter.usage, ": ");
        }
        context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);

        ss << style::Code << " ";
        if (matched) {
            ss << (style::Code + style::Match)(" ✓ ");
        } else {
            ss << (style::Code + style::Mismatch)(" ✗ ");
        }
    }
    ss << ")";
    if (overload.return_matcher_indices.IsValid()) {
        ss << " -> ";
        auto* matcher_indices = context.data[overload.return_matcher_indices];
        context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);
    }

    bool first = true;
    auto separator = [&] {
        ss << style::Plain(first ? " where:\n     " : "\n     ");
        first = false;
    };

    if (all_params_match && args.Length() > overload.num_parameters) {
        separator();
        ss << style::Mismatch(" ✗ ")
           << style::Plain(" overload expects ", static_cast<int>(overload.num_parameters),
                           " argument", overload.num_parameters != 1 ? "s" : "", ", call passed ",
                           args.Length(), " argument", args.Length() != 1 ? "s" : "");
    }
    if (all_params_match && template_args.Length() > overload.num_explicit_templates) {
        separator();
        ss << style::Mismatch(" ✗ ")
           << style::Plain(" overload expects ", static_cast<int>(overload.num_explicit_templates),
                           " template argument", overload.num_explicit_templates != 1 ? "s" : "",
                           ", call passed ", template_args.Length(), " argument",
                           template_args.Length() != 1 ? "s" : "");
    }

    for (size_t i = 0; i < overload.num_templates; i++) {
        auto& tmpl = context.data[overload.templates + i];
        if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
            separator();
            bool matched = false;
            if (tmpl.kind == TemplateInfo::Kind::kType) {
                if (auto* ty = templates.Type(i)) {
                    matched =
                        context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                            .Type(ty);
                }
            } else {
                matched = context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                              .Num(templates.Num(i))
                              .IsValid();
            }
            if (matched) {
                ss << style::Match(" ✓ ") << style::Plain(" ");
            } else {
                ss << style::Mismatch(" ✗ ") << style::Plain(" ");
            }

            ss << style::Type(tmpl.name) << style::Plain(" is ");
            if (tmpl.kind == TemplateInfo::Kind::kType) {
                context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                    .PrintType(ss);
            } else {
                context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                    .PrintNum(ss);
            }
        }
    }
}

Result<Overload, StyledText> LookupFn(Context& context,
                                      std::string_view intrinsic_name,
                                      size_t function_id,
                                      VectorRef<const core::type::Type*> template_args,
                                      VectorRef<const core::type::Type*> args,
                                      EvaluationStage earliest_eval_stage) {
    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching call to " << CallSignature(intrinsic_name, template_args, args) << "\n";
        if (!candidates.IsEmpty()) {
            err << "\n"
                << candidates.Length() << " candidate function"
                << (candidates.Length() > 1 ? "s:" : ":") << "\n";
            PrintCandidates(err, context, candidates, intrinsic_name, template_args, args);
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, context.data.builtins[function_id], intrinsic_name,
                          template_args, args, earliest_eval_stage, on_no_match);
}

Result<Overload, StyledText> LookupUnary(Context& context,
                                         core::UnaryOp op,
                                         const core::type::Type* arg,
                                         EvaluationStage earliest_eval_stage) {
    const IntrinsicInfo* intrinsic_info = nullptr;
    std::string_view intrinsic_name;
    switch (op) {
        case core::UnaryOp::kComplement:
            intrinsic_info = &context.data.unary_complement;
            intrinsic_name = "operator ~ ";
            break;
        case core::UnaryOp::kNegation:
            intrinsic_info = &context.data.unary_minus;
            intrinsic_name = "operator - ";
            break;
        case core::UnaryOp::kAddressOf:
            intrinsic_info = &context.data.unary_and;
            intrinsic_name = "operator & ";
            break;
        case core::UnaryOp::kIndirection:
            intrinsic_info = &context.data.unary_star;
            intrinsic_name = "operator * ";
            break;
        case core::UnaryOp::kNot:
            intrinsic_info = &context.data.unary_not;
            intrinsic_name = "operator ! ";
            break;
    }

    Vector args{arg};

    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&, name = intrinsic_name](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching overload for " << CallSignature(name, Empty, args) << "\n";
        if (!candidates.IsEmpty()) {
            err << "\n"
                << candidates.Length() << " candidate operator"
                << (candidates.Length() > 1 ? "s:" : ":") << "\n";
            PrintCandidates(err, context, candidates, name, Empty, Vector{arg});
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, *intrinsic_info, intrinsic_name, Empty, args,
                          earliest_eval_stage, on_no_match);
}

Result<Overload, StyledText> LookupBinary(Context& context,
                                          core::BinaryOp op,
                                          const core::type::Type* lhs,
                                          const core::type::Type* rhs,
                                          EvaluationStage earliest_eval_stage,
                                          bool is_compound) {
    const IntrinsicInfo* intrinsic_info = nullptr;
    std::string_view intrinsic_name;
    switch (op) {
        case core::BinaryOp::kAnd:
            intrinsic_info = &context.data.binary_and;
            intrinsic_name = is_compound ? "operator &= " : "operator & ";
            break;
        case core::BinaryOp::kOr:
            intrinsic_info = &context.data.binary_or;
            intrinsic_name = is_compound ? "operator |= " : "operator | ";
            break;
        case core::BinaryOp::kXor:
            intrinsic_info = &context.data.binary_xor;
            intrinsic_name = is_compound ? "operator ^= " : "operator ^ ";
            break;
        case core::BinaryOp::kLogicalAnd:
            intrinsic_info = &context.data.binary_logical_and;
            intrinsic_name = "operator && ";
            break;
        case core::BinaryOp::kLogicalOr:
            intrinsic_info = &context.data.binary_logical_or;
            intrinsic_name = "operator || ";
            break;
        case core::BinaryOp::kEqual:
            intrinsic_info = &context.data.binary_equal;
            intrinsic_name = "operator == ";
            break;
        case core::BinaryOp::kNotEqual:
            intrinsic_info = &context.data.binary_not_equal;
            intrinsic_name = "operator != ";
            break;
        case core::BinaryOp::kLessThan:
            intrinsic_info = &context.data.binary_less_than;
            intrinsic_name = "operator < ";
            break;
        case core::BinaryOp::kGreaterThan:
            intrinsic_info = &context.data.binary_greater_than;
            intrinsic_name = "operator > ";
            break;
        case core::BinaryOp::kLessThanEqual:
            intrinsic_info = &context.data.binary_less_than_equal;
            intrinsic_name = "operator <= ";
            break;
        case core::BinaryOp::kGreaterThanEqual:
            intrinsic_info = &context.data.binary_greater_than_equal;
            intrinsic_name = "operator >= ";
            break;
        case core::BinaryOp::kShiftLeft:
            intrinsic_info = &context.data.binary_shift_left;
            intrinsic_name = is_compound ? "operator <<= " : "operator << ";
            break;
        case core::BinaryOp::kShiftRight:
            intrinsic_info = &context.data.binary_shift_right;
            intrinsic_name = is_compound ? "operator >>= " : "operator >> ";
            break;
        case core::BinaryOp::kAdd:
            intrinsic_info = &context.data.binary_plus;
            intrinsic_name = is_compound ? "operator += " : "operator + ";
            break;
        case core::BinaryOp::kSubtract:
            intrinsic_info = &context.data.binary_minus;
            intrinsic_name = is_compound ? "operator -= " : "operator - ";
            break;
        case core::BinaryOp::kMultiply:
            intrinsic_info = &context.data.binary_star;
            intrinsic_name = is_compound ? "operator *= " : "operator * ";
            break;
        case core::BinaryOp::kDivide:
            intrinsic_info = &context.data.binary_divide;
            intrinsic_name = is_compound ? "operator /= " : "operator / ";
            break;
        case core::BinaryOp::kModulo:
            intrinsic_info = &context.data.binary_modulo;
            intrinsic_name = is_compound ? "operator %= " : "operator % ";
            break;
    }

    Vector args{lhs, rhs};

    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&, name = intrinsic_name](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching overload for " << CallSignature(name, Empty, args) << "\n";
        if (!candidates.IsEmpty()) {
            err << "\n"
                << candidates.Length() << " candidate operator"
                << (candidates.Length() > 1 ? "s:" : ":") << "\n";
            PrintCandidates(err, context, candidates, name, Empty, args);
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, *intrinsic_info, intrinsic_name, Empty, args,
                          earliest_eval_stage, on_no_match);
}

Result<Overload, StyledText> LookupCtorConv(Context& context,
                                            std::string_view type_name,
                                            size_t type_id,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage) {
    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching constructor for " << CallSignature(type_name, template_args, args)
            << "\n";
        Candidates ctor, conv;
        for (auto candidate : candidates) {
            if (candidate.overload->flags.Contains(OverloadFlag::kIsConstructor)) {
                ctor.Push(candidate);
            } else {
                conv.Push(candidate);
            }
        }
        if (!ctor.IsEmpty()) {
            err << "\n"
                << ctor.Length() << " candidate constructor" << (ctor.Length() > 1 ? "s:" : ":")
                << "\n";
            PrintCandidates(err, context, ctor, type_name, template_args, args);
        }
        if (!conv.IsEmpty()) {
            err << "\n"
                << conv.Length() << " candidate conversion" << (conv.Length() > 1 ? "s:" : ":")
                << "\n";
            PrintCandidates(err, context, conv, type_name, template_args, args);
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, context.data.ctor_conv[type_id], type_name, template_args, args,
                          earliest_eval_stage, on_no_match);
}

}  // namespace tint::core::intrinsic

/// TypeInfo for the Any type declared in the anonymous namespace above
TINT_INSTANTIATE_TYPEINFO(tint::core::intrinsic::Any);
