Repository: carbon-language/carbon-lang
File: toolchain/check/import_ref.cpp (C++)

Code before:
      }
      case CARBON_KIND(SemIR::PointerType inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::SpecificFunction inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::SymbolicBindingPattern inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::StructType inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::StructValue inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::TupleType inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::TupleValue inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::UnboundElementType inst): {
        return TryResolveTypedInst(inst);
      }
      default: {
        // This instruction might have a constant value of a different kind.
        auto constant_inst_id =
            import_ir_.constant_values().GetConstantInstId(inst_id);
        if (constant_inst_id == inst_id) {
          context_.TODO(
              SemIR::LocId(AddImportIRInst(inst_id)),
              llvm::formatv("TryResolveInst on {0}", untyped_inst.kind())
                  .str());
          return {.const_id = SemIR::ConstantId::Error};
        }
        // Try to resolve the constant value instead. Note that this can only
        // retry once.
        CARBON_DCHECK(import_ir_.constant_values().GetConstantInstId(
                          constant_inst_id) == constant_inst_id);
        return TryResolveInstCanonical(constant_inst_id, const_id);
      }
    }
  }

  // Produces a resolve result that tries resolving this instruction again. If
  // `const_id` is specified, then this is the end of the second phase, and the
  // constant value will be passed to the next resolution attempt. Otherwise,
  // this is the end of the first phase.
  auto Retry(SemIR::ConstantId const_id = SemIR::ConstantId::Invalid)
      -> ResolveResult {

Review comment (suggestion):
This change is necessary to support cases where the instruction that we are importing has a constant value, but is not the instruction that *defines* the constant value. For example, this happens when we have `extend base: B`, where the `B` is a `NameRef` instruction (which we won't directly import).

Code after:
      }
      case CARBON_KIND(SemIR::PointerType inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::SpecificFunction inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::SymbolicBindingPattern inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::StructType inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::StructValue inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::TupleType inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::TupleValue inst): {
        return TryResolveTypedInst(inst);
      }
      case CARBON_KIND(SemIR::UnboundElementType inst): {
        return TryResolveTypedInst(inst);
      }
      default: {
        // This instruction might have a constant value of a different kind.
        auto constant_inst_id =
            import_ir_.constant_values().GetConstantInstId(inst_id);
        if (constant_inst_id == inst_id) {
          context_.TODO(
              SemIR::LocId(AddImportIRInst(inst_id)),
              llvm::formatv("TryResolveInst on {0}", untyped_inst.kind())
                  .str());
          return {.const_id = SemIR::ConstantId::Error};
        }
        // Try to resolve the constant value instead. Note that this can only
        // retry once.
        CARBON_DCHECK(import_ir_.constant_values().GetConstantInstId(
                          constant_inst_id) == constant_inst_id,
                      "Constant value of constant instruction should refer to "
                      "the same instruction");
        return TryResolveInstCanonical(constant_inst_id, const_id);
      }
    }
  }

  // Produces a resolve result that tries resolving this instruction again. If
  // `const_id` is specified, then this is the end of the second phase, and the
  // constant value will be passed to the next resolution attempt. Otherwise,
  // this is the end of the first phase.