Skip to content

Commit 70f104a

Browse files
danakjjonmeow
andauthored
Always import canonical instructions except for exceptional Decl cases (#6009)
There are a few instructions that import in multiple phases, which receive the `const_id` and use it to construct multiple constants until building the final constant value. These include `AssociatedConstantDecl`, `FunctionDecl`, and `InterfaceDecl`. Other instructions just construct a constant value in a single attempt, once all their dependencies are imported. For these instruction types, avoid importing the non-canonical instruction. Always get the canonical constant instruction and import that. Since the constant value of an instruction can have a very different structure than its non-canonical value, this ensures import has a consistent structure to work with, by only working with canonical values as much as possible. The `VtableDecl` and `VtablePtr` were set up to pass along `const_id` but do not actually require multiple phases, so they have been changed to stop passing along the unused (and always empty) `const_id`. --------- Co-authored-by: Jon Ross-Perkins <[email protected]>
1 parent cb5e2e1 commit 70f104a

File tree

4 files changed

+117
-87
lines changed

4 files changed

+117
-87
lines changed

toolchain/check/import_ref.cpp

Lines changed: 81 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,9 +2046,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
20462046
}
20472047

20482048
static auto TryResolveTypedInst(ImportRefResolver& resolver,
2049-
SemIR::VtableDecl inst,
2050-
SemIR::ConstantId /*vtable_const_id*/)
2051-
-> ResolveResult {
2049+
SemIR::VtableDecl inst) -> ResolveResult {
20522050
const auto& import_vtable = resolver.import_vtables().Get(inst.vtable_id);
20532051
auto class_const_id =
20542052
GetLocalConstantId(resolver, resolver.import_classes()
@@ -2117,9 +2115,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
21172115
}
21182116

21192117
static auto TryResolveTypedInst(ImportRefResolver& resolver,
2120-
SemIR::VtablePtr inst,
2121-
SemIR::ConstantId /*vtable_const_id*/)
2122-
-> ResolveResult {
2118+
SemIR::VtablePtr inst) -> ResolveResult {
21232119
auto specific_data = GetLocalSpecificData(resolver, inst.specific_id);
21242120

21252121
auto vtable_const_id = GetLocalConstantId(
@@ -2147,6 +2143,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
21472143
auto fn_val_id = GetLocalConstantInstId(
21482144
resolver,
21492145
resolver.import_functions().Get(inst.function_id).first_decl_id());
2146+
21502147
auto specific_data = GetLocalSpecificData(resolver, inst.specific_id);
21512148
if (resolver.HasNewWork()) {
21522149
return ResolveResult::Retry();
@@ -3058,40 +3055,84 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
30583055
SemIR::InstId inst_id,
30593056
SemIR::ConstantId const_id)
30603057
-> ResolveResult {
3061-
if (SemIR::IsSingletonInstId(inst_id)) {
3062-
CARBON_CHECK(!const_id.has_value());
3058+
// These instruction types are imported across multiple phases to arrive at
3059+
// their constant value. We can't just import their constant value instruction
3060+
// directly.
3061+
auto untyped_inst = resolver.import_insts().GetWithAttachedType(inst_id);
3062+
CARBON_KIND_SWITCH(untyped_inst) {
3063+
case CARBON_KIND(SemIR::AssociatedConstantDecl inst): {
3064+
return TryResolveTypedInst(resolver, inst, const_id);
3065+
}
3066+
case CARBON_KIND(SemIR::ClassDecl inst): {
3067+
return TryResolveTypedInst(resolver, inst, const_id);
3068+
}
3069+
case CARBON_KIND(SemIR::FunctionDecl inst): {
3070+
return TryResolveTypedInst(resolver, inst, const_id);
3071+
}
3072+
case CARBON_KIND(SemIR::ImplDecl inst): {
3073+
return TryResolveTypedInst(resolver, inst, const_id);
3074+
}
3075+
case CARBON_KIND(SemIR::InterfaceDecl inst): {
3076+
return TryResolveTypedInst(resolver, inst, const_id);
3077+
}
3078+
default:
3079+
break;
3080+
}
3081+
3082+
// Other instructions are imported in a single phase (once their dependencies
3083+
// are all imported).
3084+
CARBON_CHECK(!const_id.has_value());
3085+
3086+
auto inst_constant_id = resolver.import_constant_values().Get(inst_id);
3087+
if (!inst_constant_id.is_constant()) {
3088+
// TODO: Import of non-constant BindNames happens when importing `let`
3089+
// declarations.
3090+
CARBON_CHECK(resolver.import_insts().Is<SemIR::BindName>(inst_id),
3091+
"TryResolveInst on non-constant instruction {0}", inst_id);
3092+
return ResolveResult::Done(SemIR::ConstantId::NotConstant);
3093+
}
3094+
3095+
// Import the canonical constant value instruction for `inst_id` directly. We
3096+
// don't try to import the non-canonical `inst_id`.
3097+
auto constant_inst_id =
3098+
resolver.import_constant_values().GetInstId(inst_constant_id);
3099+
CARBON_DCHECK(resolver.import_constant_values().GetConstantInstId(
3100+
constant_inst_id) == constant_inst_id,
3101+
"Constant value of constant instruction should refer to "
3102+
"the same instruction");
3103+
3104+
if (SemIR::IsSingletonInstId(constant_inst_id)) {
30633105
// Constants for builtins can be directly copied.
3064-
return ResolveResult::Done(resolver.local_constant_values().Get(inst_id));
3106+
return ResolveResult::Done(
3107+
resolver.local_constant_values().Get(constant_inst_id));
30653108
}
30663109

3067-
auto untyped_inst = resolver.import_insts().GetWithAttachedType(inst_id);
3068-
CARBON_KIND_SWITCH(untyped_inst) {
3110+
auto untyped_constant_inst =
3111+
resolver.import_insts().GetWithAttachedType(constant_inst_id);
3112+
CARBON_KIND_SWITCH(untyped_constant_inst) {
30693113
case CARBON_KIND(SemIR::AdaptDecl inst): {
3070-
return TryResolveTypedInst(resolver, inst, inst_id);
3114+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
30713115
}
30723116
case CARBON_KIND(SemIR::AddrPattern inst): {
3073-
return TryResolveTypedInst(resolver, inst, inst_id);
3117+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
30743118
}
30753119
case CARBON_KIND(SemIR::ArrayType inst): {
30763120
return TryResolveTypedInst(resolver, inst);
30773121
}
3078-
case CARBON_KIND(SemIR::AssociatedConstantDecl inst): {
3079-
return TryResolveTypedInst(resolver, inst, const_id);
3080-
}
30813122
case CARBON_KIND(SemIR::AssociatedEntity inst): {
30823123
return TryResolveTypedInst(resolver, inst);
30833124
}
30843125
case CARBON_KIND(SemIR::AssociatedEntityType inst): {
30853126
return TryResolveTypedInst(resolver, inst);
30863127
}
30873128
case CARBON_KIND(SemIR::BaseDecl inst): {
3088-
return TryResolveTypedInst(resolver, inst, inst_id);
3129+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
30893130
}
30903131
case CARBON_KIND(SemIR::BindAlias inst): {
30913132
return TryResolveTypedInst(resolver, inst);
30923133
}
30933134
case CARBON_KIND(SemIR::BindingPattern inst): {
3094-
return TryResolveTypedInst(resolver, inst, inst_id);
3135+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
30953136
}
30963137
case CARBON_KIND(SemIR::BindSymbolicName inst): {
30973138
return TryResolveTypedInst(resolver, inst);
@@ -3108,9 +3149,6 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31083149
case CARBON_KIND(SemIR::CharLiteralValue inst): {
31093150
return TryResolveTypedInst(resolver, inst);
31103151
}
3111-
case CARBON_KIND(SemIR::ClassDecl inst): {
3112-
return TryResolveTypedInst(resolver, inst, const_id);
3113-
}
31143152
case CARBON_KIND(SemIR::ClassType inst): {
31153153
return TryResolveTypedInst(resolver, inst);
31163154
}
@@ -3133,7 +3171,7 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31333171
return TryResolveTypedInst(resolver, inst);
31343172
}
31353173
case CARBON_KIND(SemIR::FieldDecl inst): {
3136-
return TryResolveTypedInst(resolver, inst, inst_id);
3174+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
31373175
}
31383176
case CARBON_KIND(SemIR::FloatLiteralValue inst): {
31393177
return TryResolveTypedInst(resolver, inst);
@@ -3144,9 +3182,6 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31443182
case CARBON_KIND(SemIR::FloatValue inst): {
31453183
return TryResolveTypedInst(resolver, inst);
31463184
}
3147-
case CARBON_KIND(SemIR::FunctionDecl inst): {
3148-
return TryResolveTypedInst(resolver, inst, const_id);
3149-
}
31503185
case CARBON_KIND(SemIR::FunctionType inst): {
31513186
return TryResolveTypedInst(resolver, inst);
31523187
}
@@ -3159,9 +3194,6 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31593194
case CARBON_KIND(SemIR::GenericInterfaceType inst): {
31603195
return TryResolveTypedInst(resolver, inst);
31613196
}
3162-
case CARBON_KIND(SemIR::ImplDecl inst): {
3163-
return TryResolveTypedInst(resolver, inst, const_id);
3164-
}
31653197
case CARBON_KIND(SemIR::LookupImplWitness inst): {
31663198
return TryResolveTypedInst(resolver, inst);
31673199
}
@@ -3172,13 +3204,10 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31723204
return TryResolveTypedInst(resolver, inst);
31733205
}
31743206
case CARBON_KIND(SemIR::ImplWitnessTable inst): {
3175-
return TryResolveTypedInst(resolver, inst, inst_id);
3207+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
31763208
}
31773209
case CARBON_KIND(SemIR::ImportRefLoaded inst): {
3178-
return TryResolveTypedInst(resolver, inst, inst_id);
3179-
}
3180-
case CARBON_KIND(SemIR::InterfaceDecl inst): {
3181-
return TryResolveTypedInst(resolver, inst, const_id);
3210+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
31823211
}
31833212
case CARBON_KIND(SemIR::IntValue inst): {
31843213
return TryResolveTypedInst(resolver, inst);
@@ -3190,10 +3219,10 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
31903219
return TryResolveTypedInst(resolver, inst);
31913220
}
31923221
case CARBON_KIND(SemIR::Namespace inst): {
3193-
return TryResolveTypedInst(resolver, inst, inst_id);
3222+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
31943223
}
31953224
case CARBON_KIND(SemIR::OutParamPattern inst): {
3196-
return TryResolveTypedInst(resolver, inst, inst_id);
3225+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
31973226
}
31983227
case CARBON_KIND(SemIR::PartialType inst): {
31993228
return TryResolveTypedInst(resolver, inst);
@@ -3205,13 +3234,13 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
32053234
return TryResolveTypedInst(resolver, inst);
32063235
}
32073236
case CARBON_KIND(SemIR::RefParamPattern inst): {
3208-
return TryResolveTypedInst(resolver, inst, inst_id);
3237+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32093238
}
32103239
case CARBON_KIND(SemIR::RequireCompleteType inst): {
32113240
return TryResolveTypedInst(resolver, inst);
32123241
}
32133242
case CARBON_KIND(SemIR::ReturnSlotPattern inst): {
3214-
return TryResolveTypedInst(resolver, inst, inst_id);
3243+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32153244
}
32163245
case CARBON_KIND(SemIR::SpecificFunction inst): {
32173246
return TryResolveTypedInst(resolver, inst);
@@ -3229,13 +3258,13 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
32293258
return TryResolveTypedInst(resolver, inst);
32303259
}
32313260
case CARBON_KIND(SemIR::SymbolicBindingPattern inst): {
3232-
return TryResolveTypedInst(resolver, inst, inst_id);
3261+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32333262
}
32343263
case CARBON_KIND(SemIR::TupleAccess inst): {
32353264
return TryResolveTypedInst(resolver, inst);
32363265
}
32373266
case CARBON_KIND(SemIR::TuplePattern inst): {
3238-
return TryResolveTypedInst(resolver, inst, inst_id);
3267+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32393268
}
32403269
case CARBON_KIND(SemIR::TupleType inst): {
32413270
return TryResolveTypedInst(resolver, inst);
@@ -3247,51 +3276,28 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
32473276
return TryResolveTypedInst(resolver, inst);
32483277
}
32493278
case CARBON_KIND(SemIR::ValueParamPattern inst): {
3250-
return TryResolveTypedInst(resolver, inst, inst_id);
3279+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32513280
}
32523281
case CARBON_KIND(SemIR::VarPattern inst): {
3253-
return TryResolveTypedInst(resolver, inst, inst_id);
3282+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32543283
}
32553284
case CARBON_KIND(SemIR::VarStorage inst): {
3256-
return TryResolveTypedInst(resolver, inst, inst_id);
3285+
return TryResolveTypedInst(resolver, inst, constant_inst_id);
32573286
}
32583287
case CARBON_KIND(SemIR::VtableDecl inst): {
3259-
return TryResolveTypedInst(resolver, inst, const_id);
3288+
return TryResolveTypedInst(resolver, inst);
32603289
}
32613290
case CARBON_KIND(SemIR::VtablePtr inst): {
3262-
return TryResolveTypedInst(resolver, inst, const_id);
3263-
}
3264-
default: {
3265-
auto inst_constant_id = resolver.import_constant_values().Get(inst_id);
3266-
if (!inst_constant_id.is_constant()) {
3267-
// TODO: Import of non-constant BindNames happens when importing `let`
3268-
// declarations.
3269-
CARBON_CHECK(untyped_inst.Is<SemIR::BindName>(),
3270-
"TryResolveInst on non-constant instruction {0}",
3271-
untyped_inst);
3272-
return ResolveResult::Done(SemIR::ConstantId::NotConstant);
3273-
}
3274-
3275-
// This instruction might have a constant value of a different kind.
3276-
auto constant_inst_id =
3277-
resolver.import_constant_values().GetInstId(inst_constant_id);
3278-
if (constant_inst_id == inst_id) {
3279-
// Produce a diagnostic to provide a source location with the CHECK
3280-
// failure.
3281-
resolver.local_context().TODO(
3282-
SemIR::LocId(AddImportIRInst(resolver, inst_id)),
3283-
llvm::formatv("TryResolveInst on {0}", untyped_inst.kind()).str());
3284-
CARBON_FATAL("TryResolveInst on unsupported instruction kind {0}",
3285-
untyped_inst.kind());
3286-
}
3287-
// Try to resolve the constant value instead. Note that this can only
3288-
// retry once.
3289-
CARBON_DCHECK(resolver.import_constant_values().GetConstantInstId(
3290-
constant_inst_id) == constant_inst_id,
3291-
"Constant value of constant instruction should refer to "
3292-
"the same instruction");
3293-
return TryResolveInstCanonical(resolver, constant_inst_id, const_id);
3291+
return TryResolveTypedInst(resolver, inst);
32943292
}
3293+
default:
3294+
// Found a canonical instruction which needs to be resolved, but which is
3295+
// not yet handled.
3296+
//
3297+
// TODO: Could we turn this into a compile-time error?
3298+
CARBON_FATAL(
3299+
"Missing case in TryResolveInstCanonical for instruction kind {0}",
3300+
untyped_constant_inst.kind());
32953301
}
32963302
}
32973303

0 commit comments

Comments
 (0)