@@ -264,6 +264,9 @@ class ImportContext {
264264 auto import_interfaces () -> const SemIR::InterfaceStore& {
265265 return import_ir ().interfaces ();
266266 }
267+ auto import_named_constraints () -> const SemIR::NamedConstraintStore& {
268+ return import_ir ().named_constraints ();
269+ }
267270 auto import_ints () -> const SharedValueStores::IntStore& {
268271 return import_ir ().ints ();
269272 }
@@ -337,6 +340,9 @@ class ImportContext {
337340 auto local_interfaces () -> SemIR::InterfaceStore& {
338341 return local_ir ().interfaces ();
339342 }
343+ auto local_named_constraints () -> SemIR::NamedConstraintStore& {
344+ return local_ir ().named_constraints ();
345+ }
340346 auto local_ints () -> SharedValueStores::IntStore& {
341347 return local_ir ().ints ();
342348 }
@@ -2521,7 +2527,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
25212527 const auto & import_interface =
25222528 resolver.import_interfaces ().Get (inst.interface_id );
25232529
2524- SemIR::InterfaceId interface_id = SemIR::InterfaceId::None;
2530+ auto interface_id = SemIR::InterfaceId::None;
25252531 if (!interface_const_id.has_value ()) {
25262532 auto import_specific_id = SemIR::SpecificId::None;
25272533 if (auto import_generic_interface_type =
@@ -2598,6 +2604,162 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
25982604 return ResolveResult::Done (interface_const_id, new_interface.first_decl_id ());
25992605}
26002606
2607+ // Make a declaration of a named constraint. This is done as a separate step
2608+ // from importing the constraint definition in order to resolve cycles.
2609+ static auto MakeNamedConstraintDecl (
2610+ ImportContext& context,
2611+ const SemIR::NamedConstraint& import_named_constraint,
2612+ SemIR::SpecificId enclosing_specific_id)
2613+ -> std::pair<SemIR::NamedConstraintId, SemIR::ConstantId> {
2614+ SemIR::NamedConstraintDecl named_constraint_decl = {
2615+ .type_id = SemIR::TypeType::TypeId,
2616+ .named_constraint_id = SemIR::NamedConstraintId::None,
2617+ .decl_block_id = SemIR::InstBlockId::Empty};
2618+ auto named_constraint_decl_id = AddPlaceholderImportedInst (
2619+ context, import_named_constraint.first_owning_decl_id ,
2620+ named_constraint_decl);
2621+
2622+ // Start with an incomplete interface.
2623+ named_constraint_decl.named_constraint_id =
2624+ context.local_named_constraints ().Add (
2625+ {GetIncompleteLocalEntityBase (context, named_constraint_decl_id,
2626+ import_named_constraint),
2627+ {.scope_id = import_named_constraint.is_complete ()
2628+ ? AddPlaceholderNameScope (context)
2629+ : SemIR::NameScopeId::None}});
2630+
2631+ if (import_named_constraint.has_parameters ()) {
2632+ named_constraint_decl.type_id = GetGenericNamedConstraintType (
2633+ context.local_context (), named_constraint_decl.named_constraint_id ,
2634+ enclosing_specific_id);
2635+ }
2636+
2637+ // Write the interface ID into the InterfaceDecl.
2638+ auto interface_const_id = ReplacePlaceholderImportedInst (
2639+ context, named_constraint_decl_id, named_constraint_decl);
2640+ return {named_constraint_decl.named_constraint_id , interface_const_id};
2641+ }
2642+
2643+ // Imports the definition for a named constraint that has been imported as a
2644+ // forward declaration.
2645+ static auto AddNamedConstraintDefinition (
2646+ ImportContext& context,
2647+ const SemIR::NamedConstraint& import_named_constraint,
2648+ SemIR::NamedConstraint& new_named_constraint, SemIR::InstId self_param_id)
2649+ -> void {
2650+ auto & new_scope =
2651+ context.local_name_scopes ().Get (new_named_constraint.scope_id );
2652+ const auto & import_scope =
2653+ context.import_name_scopes ().Get (import_named_constraint.scope_id );
2654+
2655+ // Push a block so that we can add scoped instructions to it.
2656+ context.local_context ().inst_block_stack ().Push ();
2657+ InitializeNameScopeAndImportRefs (context, import_scope, new_scope,
2658+ new_named_constraint.first_owning_decl_id ,
2659+ SemIR::NameId::None,
2660+ new_named_constraint.parent_scope_id );
2661+ new_scope.set_is_interface_definition ();
2662+ new_named_constraint.body_block_id =
2663+ context.local_context ().inst_block_stack ().Pop ();
2664+ new_named_constraint.self_param_id = self_param_id;
2665+
2666+ CARBON_CHECK (import_scope.extended_scopes ().empty (),
2667+ " Interfaces don't currently have extended scopes to support." );
2668+ }
2669+
2670+ static auto TryResolveTypedInst (ImportRefResolver& resolver,
2671+ SemIR::NamedConstraintDecl inst,
2672+ SemIR::ConstantId named_constraint_const_id)
2673+ -> ResolveResult {
2674+ const auto & import_named_constraint =
2675+ resolver.import_named_constraints ().Get (inst.named_constraint_id );
2676+
2677+ auto named_constraint_id = SemIR::NamedConstraintId::None;
2678+ if (!named_constraint_const_id.has_value ()) {
2679+ auto import_specific_id = SemIR::SpecificId::None;
2680+ if (auto import_generic_named_constraint_type =
2681+ resolver.import_types ().TryGetAs <SemIR::GenericNamedConstraintType>(
2682+ inst.type_id )) {
2683+ import_specific_id =
2684+ import_generic_named_constraint_type->enclosing_specific_id ;
2685+ }
2686+ auto specific_data = GetLocalSpecificData (resolver, import_specific_id);
2687+ if (resolver.HasNewWork ()) {
2688+ // This is the end of the first phase. Don't make a new interface yet if
2689+ // we already have new work.
2690+ return ResolveResult::Retry ();
2691+ }
2692+
2693+ // On the second phase, create a forward declaration of the interface.
2694+ auto enclosing_specific_id =
2695+ GetOrAddLocalSpecific (resolver, import_specific_id, specific_data);
2696+ std::tie (named_constraint_id, named_constraint_const_id) =
2697+ MakeNamedConstraintDecl (resolver, import_named_constraint,
2698+ enclosing_specific_id);
2699+ } else {
2700+ // On the third phase, compute the interface ID from the constant value of
2701+ // the declaration.
2702+ auto named_constraint_const_inst = resolver.local_insts ().Get (
2703+ resolver.local_constant_values ().GetInstId (named_constraint_const_id));
2704+ if (auto facet_type =
2705+ named_constraint_const_inst.TryAs <SemIR::FacetType>()) {
2706+ const SemIR::FacetTypeInfo& facet_type_info =
2707+ resolver.local_facet_types ().Get (facet_type->facet_type_id );
2708+ CARBON_CHECK (facet_type_info.extend_named_constraints .size () == 1 );
2709+ CARBON_CHECK (facet_type_info.extend_constraints .empty ());
2710+ CARBON_CHECK (facet_type_info.self_impls_constraints .empty ());
2711+ CARBON_CHECK (facet_type_info.self_impls_named_constraints .empty ());
2712+ named_constraint_id =
2713+ facet_type_info.extend_named_constraints .front ().named_constraint_id ;
2714+ } else {
2715+ auto generic_named_constraint_type =
2716+ resolver.local_types ().GetAs <SemIR::GenericNamedConstraintType>(
2717+ named_constraint_const_inst.type_id ());
2718+ named_constraint_id = generic_named_constraint_type.named_constraint_id ;
2719+ }
2720+ }
2721+
2722+ auto parent_scope_id =
2723+ GetLocalNameScopeId (resolver, import_named_constraint.parent_scope_id );
2724+ auto implicit_param_patterns = GetLocalInstBlockContents (
2725+ resolver, import_named_constraint.implicit_param_patterns_id );
2726+ auto param_patterns = GetLocalInstBlockContents (
2727+ resolver, import_named_constraint.param_patterns_id );
2728+ auto generic_data =
2729+ GetLocalGenericData (resolver, import_named_constraint.generic_id );
2730+
2731+ std::optional<SemIR::InstId> self_param_id;
2732+ if (import_named_constraint.is_complete ()) {
2733+ self_param_id =
2734+ GetLocalConstantInstId (resolver, import_named_constraint.self_param_id );
2735+ }
2736+ auto & new_named_constraint =
2737+ resolver.local_named_constraints ().Get (named_constraint_id);
2738+
2739+ if (resolver.HasNewWork ()) {
2740+ return ResolveResult::Retry (named_constraint_const_id,
2741+ new_named_constraint.first_decl_id ());
2742+ }
2743+
2744+ new_named_constraint.parent_scope_id = parent_scope_id;
2745+ new_named_constraint.implicit_param_patterns_id =
2746+ GetLocalCanonicalInstBlockId (
2747+ resolver, import_named_constraint.implicit_param_patterns_id ,
2748+ implicit_param_patterns);
2749+ new_named_constraint.param_patterns_id = GetLocalCanonicalInstBlockId (
2750+ resolver, import_named_constraint.param_patterns_id , param_patterns);
2751+ SetGenericData (resolver, import_named_constraint.generic_id ,
2752+ import_named_constraint.generic_id , generic_data);
2753+
2754+ if (import_named_constraint.is_complete ()) {
2755+ CARBON_CHECK (self_param_id);
2756+ AddNamedConstraintDefinition (resolver, import_named_constraint,
2757+ new_named_constraint, *self_param_id);
2758+ }
2759+ return ResolveResult::Done (named_constraint_const_id,
2760+ new_named_constraint.first_decl_id ());
2761+ }
2762+
26012763static auto TryResolveTypedInst (ImportRefResolver& resolver,
26022764 SemIR::FacetAccessType inst) -> ResolveResult {
26032765 auto facet_value_inst_id =
@@ -3187,8 +3349,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31873349 case CARBON_KIND (SemIR::InterfaceDecl inst): {
31883350 return TryResolveTypedInst (resolver, inst, const_id);
31893351 }
3190- // TODO: Import NamedConstraintDecl once its FacetType constant value
3191- // contains the NamedConstraintId.
3352+ case CARBON_KIND (SemIR::NamedConstraintDecl inst): {
3353+ return TryResolveTypedInst (resolver, inst, const_id);
3354+ }
31923355 default :
31933356 break ;
31943357 }
0 commit comments