///|
fn is_reflect_metadata_type_annotation(type_name : String) -> Bool {
  type_name == "reflect.Type" ||
  type_name == "reflect.Property" ||
  type_name == "reflect.Method" ||
  type_name == "reflect.Module"
}

///|
fn eval_value_accepts_type_annotation(
  type_name : String,
  value : Value,
) -> Bool {
  let type_name = pkl_strip_default_type_marker(type_name)
  match pkl_constrained_type_base_name(type_name) {
    Some(base_name) =>
      return eval_value_accepts_type_annotation(base_name, value)
    None => ()
  }
  // PKL-148at: top-level union — `Int|String` accepts a value when
  // ANY choice does. The split walker honours angle / paren / bracket
  // nesting so `Map` inside a union doesn't trip on
  // its inner `,`. Single-choice strings fall through to the regular
  // match below.
  let choices = split_top_level_union_choices(type_name)
  if choices.length() > 1 {
    for choice in choices {
      let trimmed = pkl_constraint_trim(choice)
      if eval_value_accepts_type_annotation(trimmed, value) {
        return true
      }
    }
    return false
  }
  if type_name.has_suffix("?") {
    if value is NullValue {
      return true
    }
    let inner_name = String::unsafe_substring(
      type_name,
      start=0,
      end=type_name.length() - 1,
    )
    return eval_value_accepts_type_annotation(inner_name, value)
  }
  // PKL-148at: `Listing` / `Map` / `Set` etc.
  // are shape-preserving cast targets — the outer head determines
  // runtime acceptance; the type parameters are validated lazily
  // when individual elements are read. Strip the `<...>` tail here
  // and recurse on the bare head so `Set(...) as Set>`
  // routes through the generic-free arm match.
  match type_name.find("<") {
    Some(idx) =>
      if type_name.has_suffix(">") {
        let head = String::unsafe_substring(type_name, start=0, end=idx)
        return eval_value_accepts_type_annotation(head, value)
      }
    None => ()
  }
  // PKL-148at: function-type literal (`(Int) -> Int`, `(A, B) -> C`).
  // Apple Pkl's `as` accepts any FunctionValue whose arity matches
  // the parameter count; the parameter / return types are validated
  // lazily at call time. Detect `(...) -> ...` shape and check arity
  // by counting top-level commas in the parameter group.
  if type_name.has_prefix("(") {
    let close_opt = type_name.find(")")
    if close_opt is Some(close) {
      let arrow_ok = close + 2 < type_name.length() &&
        String::unsafe_substring(type_name, start=close + 1, end=close + 3) ==
        "->"
      if arrow_ok {
        let params_text = String::unsafe_substring(
          type_name,
          start=1,
          end=close,
        )
        let trimmed = pkl_constraint_trim(params_text)
        let arity = if trimmed == "" {
          0
        } else {
          let mut commas = 0
          let mut depth = 0
          for i = 0; i < params_text.length(); i = i + 1 {
            let c = params_text[i].to_int().unsafe_to_char()
            if c == '(' || c == '<' || c == '[' {
              depth = depth + 1
            } else if c == ')' || c == '>' || c == ']' {
              depth = depth - 1
            } else if c == ',' && depth == 0 {
              commas = commas + 1
            }
          }
          commas + 1
        }
        return value is FunctionValue(parameters, _, _, _, _) &&
          parameters.length() == arity
      }
    }
  }
  // PKL-148ai: string-literal type annotation (`x: "Pigeon"`,
  // `List`). The Pkl surface lets a quoted
  // string stand in as a singleton type whose only inhabitant is the
  // literal value itself. Match a StringValue against the unquoted
  // payload; non-string runtimes never satisfy it.
  if type_name.length() >= 2 &&
    type_name.has_prefix("\"") &&
    type_name.has_suffix("\"") {
    let literal = String::unsafe_substring(
      type_name,
      start=1,
      end=type_name.length() - 1,
    )
    return value is StringValue(s) && s == literal
  }
  if type_name == "BaseValueRenderer" ||
    type_name == "ValueRenderer" ||
    type_name == "BytesRenderer" {
    return match value {
      ObjectValue(members) =>
        match renderer_format_from_members(members) {
          Some("pklbinary") => type_name != "ValueRenderer"
          Some(_) => type_name != "BytesRenderer"
          None => false
        }
      _ => false
    }
  }
  if renderer_format_for_class_name(type_name) is Some(_) {
    return match value {
      ObjectValue(members) => object_class_tag_matches(members, type_name)
      _ => false
    }
  }
  if type_name == "RenderDirective" {
    return match value {
      ObjectValue(members) =>
        object_class_tag_matches(members, "RenderDirective")
      _ => false
    }
  }
  if is_reflect_metadata_type_annotation(type_name) {
    return value is ObjectValue(_)
  }
  match (type_name, value) {
    // PKL-148e: `Any` is Apple Pkl's top type — it accepts every
    // runtime value, matching `eval_value_accepts_type_annotation`'s
    // top-level surface.
    ("Any", _) => true
    ("Int", IntValue(_)) => true
    ("Float", FloatValue(_)) => true
    // PKL-092: `Number` is the type-system union of Int and Float; both
    // pass the annotation. Float-only contexts use the `Float` name.
    ("Number", IntValue(_)) | ("Number", FloatValue(_)) => true
    ("String", StringValue(_)) => true
    ("Boolean", BoolValue(_)) | ("Bool", BoolValue(_)) => true
    ("Null", NullValue) => true
    ("Object", ObjectValue(_)) => true
    ("Dynamic", ObjectValue(_)) => true
    // PKL-148bh: `module` is the type of the enclosing module — any
    // ObjectValue satisfies it structurally (types/currentModuleType*).
    ("module", ObjectValue(_)) => true
    ("Module", ObjectValue(members)) =>
      object_class_tag_matches(members, "Module")
    ("Class", ObjectValue(members)) => reflect_kind(members) is Some("Class")
    ("TypeAlias", ObjectValue(members)) =>
      reflect_kind(members) is Some("TypeAlias")
    // PKL-148bh: `unknown` is Apple Pkl's wildcard return type;
    // accept every runtime value (basic/newInAmendingModuleMethod).
    ("unknown", _) => true
    ("Listing", ListingValue(_))
    | ("Listing", DefaultedListingValue(_, _, _)) => true
    ("Mapping", MappingValue(_))
    | ("Mapping", DefaultedMappingValue(_, _, _)) => true
    // PKL-148h: `List` accepts the dedicated `ListValue`; the older
    // path accepting `ListingValue` is kept as a transitional aid for
    // codepaths that still produce `ListingValue` for list-shaped input
    // (e.g. `pkl:json.Parser` arrays). Apple Pkl's `Collection` is the
    // join of List + Set, so all three list-shaped variants satisfy it.
    // `Map` accepts both `MapValue` and `MappingValue` for the same
    // reason; the split slice for Mapping is separate.
    ("List", ListValue(_))
    | ("List", ListingValue(_))
    | ("List", DefaultedListingValue(_, _, _)) => true
    ("Collection", ListValue(_))
    | ("Collection", ListingValue(_))
    | ("Collection", DefaultedListingValue(_, _, _))
    | ("Collection", SetValue(_)) => true
    ("Map", MapValue(_))
    | ("Map", MappingValue(_))
    | ("Map", DefaultedMappingValue(_, _, _)) => true
    ("Set", SetValue(_))
    | ("Set", ListingValue(_))
    | ("Set", DefaultedListingValue(_, _, _))
    | ("Set", ListValue(_)) => true
    ("Pair", PairValue(_, _)) => true
    ("IntSeq", IntSeqValue(_, _, _)) => true
    ("Mixin", ObjectValue(members)) =>
      object_class_tag_matches(members, "Mixin") ||
      object_members_are_mixin_body(members)
    ("Function", FunctionValue(_, _, _, _, _)) => true
    ("Duration", DurationValue(_, _)) => true
    ("DataSize", DataSizeValue(_, _)) => true
    ("Regex", RegexValue(_)) => true
    ("Bytes", BytesValue(_)) => true
    _ => false
  }
}

///|
fn eval_type_name_is_type_parameter(
  type_name : String,
  declarations : Array[Declaration],
) -> Bool {
  // PKL-089 / PKL-090: a function or class type parameter is an
  // arbitrary user-chosen identifier (T, U, K, V, MyParam) bound at the
  // declaration site. The evaluator treats it as 'accept any value' —
  // call-site inference is deferred, so neither runtime parameter
  // validation nor return-value validation should reject based on the
  // parameter name. Class type parameters check covers methods on a
  // generic class; function parameters cover top-level generic
  // functions.
  for declaration in declarations {
    match declaration {
      FunctionDeclaration(fd) =>
        for parameter in fd.type_parameters {
          if parameter == type_name {
            return true
          }
        }
      ClassDeclaration(cd) =>
        for parameter in cd.type_parameters {
          if parameter == type_name {
            return true
          }
        }
      TypeAliasDeclaration(_) => ()
    }
  }
  false
}

///|
/// PKL-148ag: true iff every choice in the union-resolved form of
/// `type_name` fails to resolve to a stdlib class, user class,
/// typealias, or in-scope type parameter. The check feeds the
/// callable parameter / return rejection paths so an unknown type
/// annotation surfaces `Cannot find type \`\`.` (Apple Pkl's
/// upstream wording) instead of the mismatched-value message that
/// otherwise pretends the annotation is meaningful.
fn eval_type_name_is_unresolvable(
  type_name : String,
  declarations : Array[Declaration],
) -> Bool {
  let aliases = eval_type_alias_bindings(declarations)
  let resolved = eval_resolved_type_alias(type_name, aliases)
  for choice in split_top_level_union_choices(resolved) {
    let trimmed = pkl_constraint_trim(choice)
    let without_constraint = match pkl_constrained_type_base_name(trimmed) {
      Some(base) => base
      None => trimmed
    }
    let head = match without_constraint.find("<") {
      Some(idx) =>
        String::unsafe_substring(without_constraint, start=0, end=idx)
      None => without_constraint
    }
    let head_no_optional = if head.has_suffix("?") {
      String::unsafe_substring(head, start=0, end=head.length() - 1)
    } else {
      head
    }
    if head_no_optional == "" ||
      head_no_optional.has_prefix("\"") ||
      is_stdlib_class_name(head_no_optional) ||
      is_reflect_metadata_type_annotation(head_no_optional) ||
      eval_lookup_class_decl(declarations, head_no_optional) is Some(_) ||
      eval_type_name_is_type_parameter(head_no_optional, declarations) {
      return false
    }
  }
  true
}

///|
/// PKL-148l: a callable's parameter declared with a basic type
/// annotation (`a: Int`, `b: Number`, `s: String`, etc.) must reject
/// arguments whose runtime type does not satisfy the annotation
/// before the body runs. Apple Pkl emits the bare diagnostic
/// (`Expected value of type \`Int\`, but got type \`Float\`. Value: 1.1`)
/// with no `label argument N` prefix, so this helper mirrors the
/// return-side wording.
fn eval_callable_argument_type_rejection_message(
  type_name : String?,
  value : Value,
  class_env : Array[ClassBinding],
  cache : Array[ValueBinding],
  declarations : Array[Declaration],
) -> String? {
  match type_name {
    Some(source) => {
      if eval_type_name_is_type_parameter(source, declarations) {
        return None
      }
      if reference_value_satisfies_annotation(source, value, declarations) {
        return None
      }
      let aliases = eval_type_alias_bindings(declarations)
      let resolved = eval_resolved_type_alias(source, aliases)
      // PKL-148t: alias resolution may produce a union shape
      // (`Union` → `Int|Boolean`) or a generic head
      // (`Parameterized` → `List`). Walk every choice in the
      // top-level union split, stripping each choice's `(...)`
      // constraint and outermost `<...>` generic head — accept if
      // any choice matches via the builtin acceptance set or the
      // user-class annotation cascade.
      let union_accepted = {
        let mut matched = false
        for choice in split_top_level_union_choices(resolved) {
          let trimmed = pkl_constraint_trim(choice)
          let without_constraint = match
            pkl_constrained_type_base_name(trimmed) {
            Some(base) => base
            None => trimmed
          }
          let head_for_check = match without_constraint.find("<") {
            Some(idx) =>
              String::unsafe_substring(without_constraint, start=0, end=idx)
            None => without_constraint
          }
          if eval_value_accepts_type_annotation(head_for_check, value) ||
            value_satisfies_user_class_annotation(
              head_for_check, value, declarations,
            ) {
            matched = true
            break
          }
        }
        matched
      }
      if union_accepted {
        // PKL-148af: head-level acceptance still needs to walk a
        // `List` / `Listing` / `Set` / `Map` /
        // `Mapping` value's elements against the inner type so
        // `f3(List("foo", 42))` against `x: List` rejects the
        // `42` element with the same `"Expected value of type \`X\`,
        // but got type \`Y\`. Value: "` wording. Strip the outer
        // constraint and recurse into the cascade per element / entry;
        // the first violation surfaces and the rest are silenced
        // (matches Apple Pkl's fail-fast diag ordering).
        let resolved_base = match pkl_constrained_type_base_name(resolved) {
          Some(b) => b
          None => resolved
        }
        let listing_or_list_or_set = match
          generic_argument_text(resolved_base, "Listing") {
          Some(t) => Some(t)
          None =>
            match generic_argument_text(resolved_base, "List") {
              Some(t) => Some(t)
              None => generic_argument_text(resolved_base, "Set")
            }
        }
        match listing_or_list_or_set {
          Some(element_type) =>
            match value {
              ListingValue(elements)
              | DefaultedListingValue(_, elements, _)
              | ListValue(elements)
              | SetValue(elements) =>
                for element in elements {
                  match
                    eval_callable_argument_type_rejection_message(
                      Some(element_type),
                      element,
                      class_env,
                      cache,
                      declarations,
                    ) {
                    Some(message) => return Some(message)
                    None => ()
                  }
                }
              _ => ()
            }
          None => ()
        }
        let mapping_or_map = match
          generic_argument_text(resolved_base, "Mapping") {
          Some(t) => Some(t)
          None => generic_argument_text(resolved_base, "Map")
        }
        match mapping_or_map {
          Some(inner_text) => {
            let parts = split_top_level_generic_arguments(inner_text)
            if parts.length() == 2 {
              let key_type = parts[0]
              let value_type = parts[1]
              match value {
                MappingValue(entries)
                | DefaultedMappingValue(_, entries, _)
                | MapValue(entries) =>
                  for entry in entries {
                    match
                      eval_callable_argument_type_rejection_message(
                        Some(key_type),
                        entry.key,
                        class_env,
                        cache,
                        declarations,
                      ) {
                      Some(message) => return Some(message)
                      None => ()
                    }
                    match
                      eval_callable_argument_type_rejection_message(
                        Some(value_type),
                        entry.value,
                        class_env,
                        cache,
                        declarations,
                      ) {
                      Some(message) => return Some(message)
                      None => ()
                    }
                  }
                _ => ()
              }
            }
          }
          None => ()
        }
        return None
      }
      // PKL-148ag: when the annotation itself doesn't name a known
      // type (no stdlib class, user class, typealias, or in-scope
      // type parameter resolves), Apple Pkl surfaces
      // `Cannot find type \`\`.` — not the mismatched-value
      // wording. Run the resolvability gate before crafting the
      // value-mismatch message.
      if eval_type_name_is_unresolvable(source, declarations) {
        return Some("Cannot find type `\{source}`.")
      }
      // PKL-148u: Apple Pkl quotes the RESOLVED type name in the
      // rejection diagnostic (not the source alias name). Strip a
      // trailing `?` so `Nullable = Duration?` shows as `Duration`.
      let diag_name = qualified_rejection_type_label(resolved, class_env, cache)
      if value is NullValue {
        return Some("Expected value of type `\{diag_name}`, but got `null`.")
      }
      let actual = qualify_value_type_name(
        value,
        class_env,
        module_name_from_cache(cache),
      )
      Some(
        "Expected value of type `\{diag_name}`, but got type `\{actual}`. Value: \{render_pcf_value_inline(value)}",
      )
    }
    None => None
  }
}

///|
fn module_name_from_cache(cache : Array[ValueBinding]) -> String? {
  match lookup_value(cache, "@__module_name") {
    Some(StringValue(module_name)) =>
      if module_name.length() == 0 {
        None
      } else {
        Some(module_name)
      }
    _ => None
  }
}

///|
fn push_module_metadata_from_cache(
  call_cache : Array[ValueBinding],
  caller_cache : Array[ValueBinding],
) -> Unit {
  for
    name in [
      "@__module_name", "@__module_path", "@__module_source", "@__module_imports",
      "@__module_is_amend",
    ] {
    if lookup_value(call_cache, name) is None {
      match lookup_value(caller_cache, name) {
        Some(v) => call_cache.push({ name, value: v })
        None => ()
      }
    }
  }
}

///|
fn push_class_default_scope_from_cache(
  call_cache : Array[ValueBinding],
  caller_cache : Array[ValueBinding],
) -> Unit {
  if lookup_value(call_cache, "@__class_default_call_scope") is Some(_) {
    return
  }
  let marker = match lookup_value(caller_cache, "@__class_default_scope") {
    Some(value) => Some(value)
    None => lookup_value(caller_cache, "@__class_default_call_scope")
  }
  match marker {
    Some(value) =>
      call_cache.push({ name: "@__class_default_call_scope", value })
    None => ()
  }
}

///|
fn push_class_default_call_name(
  call_cache : Array[ValueBinding],
  label : String,
) -> Unit {
  if lookup_value(call_cache, "@__class_default_call_scope") is None {
    return
  }
  if lookup_value(call_cache, "@__class_default_call_name") is Some(_) {
    return
  }
  if label.has_prefix("function ") {
    call_cache.push({
      name: "@__class_default_call_name",
      value: StringValue(
        String::unsafe_substring(
          label,
          start="function ".length(),
          end=label.length(),
        ),
      ),
    })
  }
}

///|
fn qualified_rejection_type_label(
  type_name : String,
  class_env : Array[ClassBinding],
  cache : Array[ValueBinding],
) -> String {
  let label = rejection_type_label(type_name)
  match module_name_from_cache(cache) {
    Some(module_name) =>
      if is_stdlib_class_name(label) ||
        lookup_class_binding(class_env, label) is None {
        label
      } else {
        "\{module_name}#\{label}"
      }
    None => label
  }
}

///|
fn eval_callable_argument_rejection_message(
  type_name : String?,
  value : Value,
  declarations : Array[Declaration],
) -> String? {
  // Mirror the return-side alias resolution: a parameter declared
  // `x: Small` with `typealias Small = Int(isBetween(0, 10))` must trigger
  // the same predicate cascade as `x: Int(isBetween(0, 10))`. The
  // `_from_source` predicate variants keep the original alias name in the
  // diagnostic while running the resolved constraint against the value.
  match type_name {
    Some(source) => {
      if eval_type_name_is_type_parameter(source, declarations) {
        return None
      }
      let aliases = eval_type_alias_bindings(declarations)
      let resolved = eval_resolved_type_alias(source, aliases)
      match
        pkl_constrained_type_annotation_value_rejection_message_from_source(
          source, resolved, value,
        ) {
        Some(message) => Some(message)
        None =>
          pkl_user_defined_constrained_type_annotation_value_rejection_message_from_source(
            source, resolved, value, declarations,
          )
      }
    }
    None => None
  }
}

///|
priv enum CallableCollectionAnnotationCast {
  CallableCollectionCastSkipped
  CallableCollectionCastOk(Value)
  CallableCollectionCastErr(String)
}

///|
fn cast_callable_collection_annotation(
  type_name : String?,
  value : Value,
  bindings : Array[Binding],
  env : Array[ValueBinding],
  class_env : Array[ClassBinding],
  cache : Array[ValueBinding],
  stack : Array[String],
  declarations : Array[Declaration],
  resolve_import : (String) -> EvalResult?,
) -> CallableCollectionAnnotationCast {
  let annotation = match type_name {
    Some(name) => name
    None => return CallableCollectionCastSkipped
  }
  if type_annotation_collection_branch_count(annotation, declarations) == 0 {
    return CallableCollectionCastSkipped
  }
  match
    cast_value_to_type_annotation(
      annotation, value, bindings, env, class_env, cache, stack, declarations, resolve_import,
    ) {
    TypeCastOk(casted) =>
      match
        binding_collection_host_constraint_rejection_message(
          Some(annotation),
          casted,
          declarations,
        ) {
        Some(message) => CallableCollectionCastErr(message)
        None => CallableCollectionCastOk(casted)
      }
    TypeCastErr(message) => CallableCollectionCastErr(message)
  }
}

///|

///|
/// PKL-148bh: runtime predicate check for a callable parameter
/// annotation that carries a `()` constraint
/// (e.g. `String(length > n)` where `n` lives in the captured env).
/// Mirrors the eval_runtime_constraint_for_property cascade but uses
/// the function's captured_env as the lexical scope and binds `this`
/// to the actual argument. Returns Apple Pkl's standard violation
/// wording when the predicate evaluates to `false`; returns `None`
/// when the predicate matches or the annotation has no constraint /
/// fails to parse.
fn eval_callable_runtime_constraint_message(
  type_name : String?,
  diagnostic_type_name : String?,
  value : Value,
  bindings : Array[Binding],
  class_env : Array[ClassBinding],
  captured_env : Array[ValueBinding],
  stack : Array[String],
  declarations : Array[Declaration],
  resolve_import : (String) -> EvalResult?,
) -> String? {
  let source = match type_name {
    Some(s) => s
    None => return None
  }
  let text = match pkl_constrained_type_constraint_text(source) {
    Some(t) => t
    None => return None
  }
  let parts = pkl_split_constraint_arguments(text)
  let diagnostic_parts = match diagnostic_type_name {
    Some(display_source) =>
      match pkl_constrained_type_constraint_text(display_source) {
        Some(display_text) => pkl_split_constraint_arguments(display_text)
        None => parts
      }
    None => parts
  }
  for part_index = 0; part_index < parts.length(); part_index = part_index + 1 {
    let part = parts[part_index]
    let expr = match parse_constraint_expression(part) {
      Some(e) => e
      None => continue
    }
    let pred_env : Array[ValueBinding] = []
    for b in captured_env {
      pred_env.push(b)
    }
    pred_env.push({ name: "this", value })
    // Implicit-receiver bareword resolution: when the value is an
    // ObjectValue, hoist its visible members so `length` / `name`
    // etc. resolve directly. Scalar values rely on
    // rewrite_implicit_this_in_expr to fold bare names that miss
    // both env and bindings into `this.` member accesses.
    match value {
      ObjectValue(members) =>
        for m in members {
          if !is_invisible_member_name(m.name) {
            pred_env.push({ name: m.name, value: m.value })
          }
        }
      _ => ()
    }
    let rewritten = rewrite_implicit_this_in_expr(
      expr, bindings, pred_env, captured_env,
    )
    let probe_diags : Array[Diagnostic] = []
    let probe = eval_expr_with_bindings(
      rewritten, bindings, pred_env, class_env, captured_env, stack, declarations,
      probe_diags, resolve_import,
    )
    match probe {
      Some(BoolValue(true)) => continue
      Some(BoolValue(false)) => {
        let nested_violation_value : Value? = match rewritten {
          BinaryExpr(Is, nested_target_expr, Identifier(nested_type)) =>
            match pkl_constrained_type_constraint_text(nested_type) {
              Some(_) => {
                let nested_target_diags : Array[Diagnostic] = []
                let nested_target = eval_expr_with_bindings(
                  nested_target_expr, bindings, pred_env, class_env, captured_env,
                  stack, declarations, nested_target_diags, resolve_import,
                )
                match nested_target {
                  Some(target_value) => {
                    let nested_base = match
                      pkl_constrained_type_base_name(nested_type) {
                      Some(base) => base
                      None => nested_type
                    }
                    if eval_value_matches_type_annotation(
                        nested_base, target_value, class_env, declarations,
                      ) {
                      let nested_env = copy_value_bindings(captured_env)
                      nested_env.push({ name: "this", value: target_value })
                      let nested_diags : Array[Diagnostic] = []
                      eval_expr_with_bindings(
                        nested_target_expr, bindings, nested_env, class_env, captured_env,
                        stack, declarations, nested_diags, resolve_import,
                      )
                    } else {
                      None
                    }
                  }
                  None => None
                }
              }
              None => None
            }
          _ => None
        }
        let hint = match pkl_constrained_type_base_name(source) {
          Some(base) =>
            if base == "Int" ||
              base == "Float" ||
              base == "Number" ||
              base == "Boolean" ||
              base == "String" ||
              base == "Listing" ||
              base == "Mapping" ||
              base == "Set" ||
              base == "Map" ||
              base.has_prefix("Listing<") ||
              base.has_prefix("Mapping<") ||
              base.has_prefix("Set<") ||
              base.has_prefix("Map<") {
              None
            } else {
              Some(base)
            }
          None => None
        }
        let rendered_violation_value = match nested_violation_value {
          Some(nested_value) =>
            render_pcf_value_inline_compact(nested_value, None)
          None => render_pcf_value_inline_compact(value, hint)
        }
        let diagnostic_part = if part_index < diagnostic_parts.length() {
          diagnostic_parts[part_index]
        } else {
          part
        }
        return Some(
          "Type constraint `\{pretty_constraint_text(strip_balanced_outer_type_parens(diagnostic_part))}` violated. Value: \{rendered_violation_value}",
        )
      }
      None if diagnostic_type_name is Some(_) && probe_diags.length() > 0 =>
        return Some(probe_diags[0].message)
      _ => continue
    }
  }
  None
}

///|
/// PKL-148: render a value through the inline PCF form so diagnostic
/// messages can quote the rejected value. The wrapper keeps the call
/// sites concise — the `Value: ` segment is a recurring shape
/// in Apple Pkl's constraint / type-mismatch wording.
fn render_pcf_value_inline(value : Value) -> String {
  let buf = StringBuilder::new()
  match value {
    ObjectValue(members) =>
      // PKL-148bh: every typed ObjectValue now carries the
      // `@hidden$__class` tag (universal tagging in
      // `tag_object_with_class`), so the inline form prints
      // `new  { ... }` for both Dynamic and user classes
      // (lambdas/pipeOperator's diagnostic for `Person`).
      match find_object_class_tag(members) {
        Some(class_name) => render_pcf_class_inline(class_name, members, buf)
        None => render_pcf_inline(value, 0, false, buf)
      }
    _ => render_pcf_inline(value, 0, false, buf)
  }
  buf.to_string()
}

///|
/// Render an ObjectValue with an attached class tag in the inline-quote
/// form Apple Pkl uses inside diagnostic strings — `new Dynamic {}` /
/// `new Dynamic { x = 1 }`. Visible members only; the class tag itself
/// stays hidden.
fn render_pcf_class_inline(
  class_name : String,
  members : Array[ValueMember],
  buf : StringBuilder,
) -> Unit {
  buf.write_string("new ")
  buf.write_string(class_name)
  let visible = visible_members(members)
  if visible.length() == 0 {
    buf.write_string(" {}")
    return
  }
  buf.write_string(" { ")
  for i = 0; i < visible.length(); i = i + 1 {
    if i > 0 {
      buf.write_string("; ")
    }
    buf.write_string(visible[i].name)
    buf.write_string(" = ")
    render_pcf_scalar(visible[i].value, buf)
  }
  buf.write_string(" }")
}

///|
/// PKL-148d: compact single-line render used by constraint diagnostics
/// (`Type constraint \`X\` violated. Value: `). Apple Pkl renders
/// the offending ObjectValue as `new ClassName { x = "..." }` on one
/// line, with the class name pulled from the host constraint target.
/// Listing / Mapping fall back to `new Listing {}` / `new Mapping {}`
/// for empty cases so the existing PKL-148b output stays stable; the
/// non-empty inline form mirrors `render_pcf_inline` but on a single
/// line.
fn render_pcf_value_inline_compact(
  value : Value,
  class_hint : String?,
) -> String {
  let buf = StringBuilder::new()
  match value {
    ObjectValue(members) => {
      buf.write_string("new ")
      match class_hint {
        Some(name) => {
          buf.write_string(name)
          buf.write_char(' ')
        }
        None => ()
      }
      let visible = visible_members(members)
      if visible.length() == 0 {
        buf.write_string("{}")
      } else {
        buf.write_string("{ ")
        for i = 0; i < visible.length(); i = i + 1 {
          if i > 0 {
            buf.write_string("; ")
          }
          buf.write_string(visible[i].name)
          buf.write_string(" = ")
          render_pcf_scalar(visible[i].value, buf)
        }
        buf.write_string(" }")
      }
    }
    _ => render_pcf_inline(value, 0, false, buf)
  }
  buf.to_string()
}

///|
/// PKL-148e: looser check that accepts ObjectValue for any
/// user-declared class name (and the stdlib `Dynamic` / `Typed`
/// supertypes). Apple Pkl's runtime carries the dynamic class along
/// with the instance; pkl-mbt's ObjectValue erases it. Until we
/// recover the class on the value, accept any ObjectValue against a
/// declared class type — the alternative (rejecting every
/// `param: Person` call site) is strictly worse for upstream
/// compatibility.
fn value_satisfies_user_class_annotation(
  type_name : String,
  value : Value,
  declarations : Array[Declaration],
) -> Bool {
  match value {
    ObjectValue(members) => {
      if reflect_kind(members) is Some(_) {
        return false
      }
      // A nullable annotation `T?` carries the same class identity as `T`
      // for a non-null object value (the `null` arm is handled elsewhere /
      // short-circuited before this check). Strip a single trailing `?` so
      // `InlineSnapshot?` unifies with a value tagged `InlineSnapshot` —
      // without this, a `T?`-annotated function parameter / field whose
      // type-check reaches here (post PKL-158 backfill) wrongly rejects a
      // structurally-identical value with "Expected `T?`, got `T`".
      let type_name = if type_name.has_suffix("?") {
        String::unsafe_substring(type_name, start=0, end=type_name.length() - 1)
      } else {
        type_name
      }
      if type_name == "Dynamic" || type_name == "Typed" {
        return true
      }
      let base = match pkl_constrained_type_base_name(type_name) {
        Some(b) => b
        None => type_name
      }
      match find_object_class_tag(members) {
        Some(tag) => {
          // PKL-158b: the value's class tag may be alias-qualified
          // (`s.Task` from `new s.Task {}`) while the annotation names
          // the same underlying class by its simple name (`Task`). When
          // the alias resolves to the module that declares the class,
          // Apple Pkl treats `s.Task` and `Task` as ONE class, so strip a
          // leading `.` qualifier before comparing. Without this the
          // cross-module element type-check (enabled by the PKL-158 type
          // backfill) wrongly rejects a structurally-identical value.
          //
          // KNOWN LIMITATION: this is simple-name matching, not module-path
          // identity. A *different* module's same-named class (`b.Task`
          // where `b` is an unrelated module declaring its own `Task`) is
          // also accepted here, whereas Apple Pkl rejects it (`modA#Task`
          // vs `modB#Task`). This loose acceptance predates PKL-158
          // (`value_satisfies_user_class_annotation` has never carried
          // module identity); strict identity would require threading the
          // resolved declaring-module path through the class tag.
          let tag_simple = match tag.rev_find(".") {
            Some(idx) =>
              String::unsafe_substring(tag, start=idx + 1, end=tag.length())
            None => tag
          }
          // PKL-pkspec: the annotation may itself be alias-qualified
          // (`impl: base.Step`) while the value's tag is the bare class
          // name (`new Step {}`, where `Step` is reachable via the same
          // module's `extends`). Strip a leading `.` from the
          // annotation base too, so `base.Step` and `Step` (same
          // underlying imported class) unify by simple name — mirroring
          // the tag-side stripping above and its KNOWN LIMITATION.
          let base_simple = match base.rev_find(".") {
            Some(idx) =>
              String::unsafe_substring(base, start=idx + 1, end=base.length())
            None => base
          }
          if tag == base ||
            tag_simple == base ||
            tag == base_simple ||
            tag_simple == base_simple {
            return true
          } else {
            let mut current : ClassDecl? = eval_lookup_class_decl(
              declarations, tag,
            )
            if current is None {
              current = eval_lookup_class_decl(declarations, tag_simple)
            }
            while current is Some(decl) {
              match decl.parent_name {
                Some(parent) => {
                  // A parent named via an import alias (`adapter.Adapter`,
                  // `Vitest.Vitest`) is the SAME underlying class as the
                  // simple-name annotation base (`Adapter`). Reduce both to
                  // their bare simple name (strip a `#` / `.`
                  // qualifier) before comparing — without this an
                  // extends-chain that crosses a module boundary
                  // (`WebVitest -> Vitest.Vitest -> adapter.Adapter`) never
                  // unifies with the bare `Adapter` field annotation. Same
                  // simple-name KNOWN LIMITATION as the tag/base comparison
                  // above (no module-path identity).
                  let parent_simple = name_class_simple_name(parent)
                  if parent == base ||
                    parent_simple == base ||
                    parent == base_simple ||
                    parent_simple == base_simple {
                    return true
                  } else {
                    let next = eval_lookup_class_decl(declarations, parent)
                    current = if next is Some(_) {
                      next
                    } else {
                      eval_lookup_class_decl(declarations, parent_simple)
                    }
                  }
                }
                None => current = None
              }
            }
            return false
          }
        }
        None => ()
      }
      eval_lookup_class_decl(declarations, base) is Some(_)
    }
    _ => false
  }
}

///|
fn eval_callable_return_rejection_message(
  label : String,
  return_type_name : String?,
  value : Value,
  class_env : Array[ClassBinding],
  cache : Array[ValueBinding],
  declarations : Array[Declaration],
) -> String? {
  match return_type_name {
    Some(type_name) => {
      if eval_type_name_is_type_parameter(type_name, declarations) {
        return None
      }
      let aliases = eval_type_alias_bindings(declarations)
      let resolved_type_name = eval_resolved_type_alias(type_name, aliases)
      // PKL-148t: alias resolution may produce a generic
      // (`Parameterized` → `List`) or a union
      // (`Union` → `Int|Boolean`); the value-side acceptance only
      // matches on a bare head, so split the resolved name on
      // top-level `|`, strip each choice's `(...)` constraint and
      // outermost `<...>` generic head, and accept if any choice
      // matches. Mirrors PKL-148l's callable-parameter normalisation
      // (which the parameter side already runs via
      // `eval_callable_argument_type_rejection_message`).
      let union_accepted = {
        let mut matched = false
        for choice in split_top_level_union_choices(resolved_type_name) {
          let trimmed = pkl_constraint_trim(choice)
          let without_constraint = match
            pkl_constrained_type_base_name(trimmed) {
            Some(base) => base
            None => trimmed
          }
          let head_for_check = match without_constraint.find("<") {
            Some(idx) =>
              String::unsafe_substring(without_constraint, start=0, end=idx)
            None => without_constraint
          }
          if eval_value_accepts_type_annotation(head_for_check, value) ||
            value_satisfies_user_class_annotation(
              head_for_check, value, declarations,
            ) {
            matched = true
            break
          }
        }
        matched
      }
      if !union_accepted {
        // PKL-148ag: unresolvable annotation → `Cannot find type`
        // rather than the value-mismatch wording. Mirrors the
        // parameter-side gate.
        if eval_type_name_is_unresolvable(type_name, declarations) {
          return Some("Cannot find type `\{type_name}`.")
        }
        // PKL-148: align with Apple Pkl's diagnostic wording so
        // snippetTest fixtures that capture this exact string via
        // `test.catch(...)` match byte-for-byte. The trailing
        // `Value: ` segment mirrors upstream — it renders the
        // failing value with the standard PCF inline form so the
        // user sees what was rejected.
        let diag_name = qualified_rejection_type_label(
          type_name, class_env, cache,
        )
        if value is NullValue {
          return Some("Expected value of type `\{diag_name}`, but got `null`.")
        }
        let actual = qualify_value_type_name(
          value,
          class_env,
          module_name_from_cache(cache),
        )
        Some(
          "Expected value of type `\{diag_name}`, but got type `\{actual}`. Value: \{render_pcf_value_inline(value)}",
        )
      } else {
        // PKL-148ae: Apple Pkl's return-side constraint diagnostic
        // omits the call-site label (`method  return ...`) —
        // it matches the parameter side already dropped by PKL-148o.
        // `label` is preserved at the signature so callers can still
        // carry the call-site identity for non-constraint diagnostics
        // (`