6
6
#include " toolchain/check/context.h"
7
7
#include " toolchain/check/convert.h"
8
8
#include " toolchain/check/decl_name_stack.h"
9
+ #include " toolchain/check/diagnostic_helpers.h"
9
10
#include " toolchain/check/eval.h"
10
11
#include " toolchain/check/generic.h"
11
12
#include " toolchain/check/handle.h"
@@ -387,21 +388,23 @@ auto HandleParseNode(Context& context, Parse::AdaptDeclId node_id) -> bool {
387
388
[&] {
388
389
CARBON_DIAGNOSTIC (IncompleteTypeInAdaptDecl, Error,
389
390
" adapted type {0} is an incomplete type" ,
390
- SemIR::TypeId );
391
+ InstIdAsType );
391
392
return context.emitter ().Build (node_id, IncompleteTypeInAdaptDecl,
392
- adapted_type_id );
393
+ adapted_inst_id );
393
394
},
394
395
[&] {
395
396
CARBON_DIAGNOSTIC (AbstractTypeInAdaptDecl, Error,
396
- " adapted type {0} is an abstract type" ,
397
- SemIR::TypeId);
397
+ " adapted type {0} is an abstract type" , InstIdAsType);
398
398
return context.emitter ().Build (node_id, AbstractTypeInAdaptDecl,
399
- adapted_type_id );
399
+ adapted_inst_id );
400
400
});
401
+ if (adapted_type_id == SemIR::TypeId::Error) {
402
+ adapted_inst_id = SemIR::InstId::BuiltinErrorInst;
403
+ }
401
404
402
405
// Build a SemIR representation for the declaration.
403
406
class_info.adapt_id = context.AddInst <SemIR::AdaptDecl>(
404
- node_id, {.adapted_type_id = adapted_type_id });
407
+ node_id, {.adapted_type_inst_id = adapted_inst_id });
405
408
406
409
// Extend the class scope with the adapted type's scope if requested.
407
410
if (introducer.modifier_set .HasAnyOf (KeywordModifierSet::Extend)) {
@@ -432,9 +435,10 @@ struct BaseInfo {
432
435
SemIR::NameScopeId scope_id;
433
436
SemIR::InstId inst_id;
434
437
};
435
- constexpr BaseInfo BaseInfo::Error = {.type_id = SemIR::TypeId::Error,
436
- .scope_id = SemIR::NameScopeId::Invalid,
437
- .inst_id = SemIR::InstId::Invalid};
438
+ constexpr BaseInfo BaseInfo::Error = {
439
+ .type_id = SemIR::TypeId::Error,
440
+ .scope_id = SemIR::NameScopeId::Invalid,
441
+ .inst_id = SemIR::InstId::BuiltinErrorInst};
438
442
} // namespace
439
443
440
444
// Diagnoses an attempt to derive from a final type.
@@ -531,7 +535,7 @@ auto HandleParseNode(Context& context, Parse::BaseDeclId node_id) -> bool {
531
535
context.GetUnboundElementType (class_info.self_type_id , base_info.type_id );
532
536
class_info.base_id = context.AddInst <SemIR::BaseDecl>(
533
537
node_id, {.type_id = field_type_id,
534
- .base_type_id = base_info.type_id ,
538
+ .base_type_inst_id = base_info.inst_id ,
535
539
.index = SemIR::ElementIndex::Invalid});
536
540
537
541
if (base_info.type_id != SemIR::TypeId::Error) {
@@ -607,27 +611,17 @@ static auto CheckCompleteAdapterClassType(Context& context,
607
611
}
608
612
609
613
// The object representation of the adapter is the object representation
610
- // of the adapted type. This is the adapted type itself unless it's a class
611
- // type.
612
- //
613
- // TODO: The object representation of `const T` should also be the object
614
- // representation of `T`.
615
- auto adapted_type_id = context.insts ()
616
- .GetAs <SemIR::AdaptDecl>(class_info.adapt_id )
617
- .adapted_type_id ;
618
- if (auto adapted_class =
619
- context.types ().TryGetAs <SemIR::ClassType>(adapted_type_id)) {
620
- auto & adapted_class_info = context.classes ().Get (adapted_class->class_id );
621
- if (adapted_class_info.adapt_id .is_valid ()) {
622
- return adapted_class_info.complete_type_witness_id ;
623
- }
624
- }
614
+ // of the adapted type.
615
+ auto adapted_type_id =
616
+ class_info.GetAdaptedType (context.sem_ir (), SemIR::SpecificId::Invalid);
617
+ auto object_repr_id = context.types ().GetObjectRepr (adapted_type_id);
625
618
626
619
return context.AddInst <SemIR::CompleteTypeWitness>(
627
620
node_id,
628
621
{.type_id = context.GetBuiltinType (SemIR::BuiltinInstKind::WitnessType),
629
- .object_repr_id = adapted_type_id });
622
+ .object_repr_id = object_repr_id });
630
623
}
624
+
631
625
static auto AddStructTypeFields (
632
626
Context& context,
633
627
llvm::SmallVector<SemIR::StructTypeField>& struct_type_fields)
@@ -664,11 +658,12 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
664
658
}
665
659
666
660
bool defining_vptr = class_info.is_dynamic ;
667
- if (class_info.base_id .is_valid ()) {
668
- auto base_info = context.insts ().GetAs <SemIR::BaseDecl>(class_info.base_id );
661
+ auto base_type_id =
662
+ class_info.GetBaseType (context.sem_ir (), SemIR::SpecificId::Invalid);
663
+ if (base_type_id.is_valid ()) {
669
664
// TODO: If the base class is template dependent, we will need to decide
670
665
// whether to add a vptr as part of instantiation.
671
- if (auto * base_class_info = TryGetAsClass (context, base_info. base_type_id );
666
+ if (auto * base_class_info = TryGetAsClass (context, base_type_id);
672
667
base_class_info && base_class_info->is_dynamic ) {
673
668
defining_vptr = false ;
674
669
}
@@ -684,16 +679,13 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
684
679
.type_id = context.GetPointerType (
685
680
context.GetBuiltinType (SemIR::BuiltinInstKind::VtableType))});
686
681
}
687
- if (class_info. base_id .is_valid ()) {
682
+ if (base_type_id .is_valid ()) {
688
683
auto base_decl = context.insts ().GetAs <SemIR::BaseDecl>(class_info.base_id );
689
684
base_decl.index =
690
685
SemIR::ElementIndex{static_cast <int >(struct_type_fields.size ())};
691
686
context.ReplaceInstPreservingConstantValue (class_info.base_id , base_decl);
692
687
struct_type_fields.push_back (
693
- {.name_id = SemIR::NameId::Base,
694
- .type_id = context.insts ()
695
- .GetAs <SemIR::BaseDecl>(class_info.base_id )
696
- .base_type_id });
688
+ {.name_id = SemIR::NameId::Base, .type_id = base_type_id});
697
689
}
698
690
699
691
return context.AddInst <SemIR::CompleteTypeWitness>(
0 commit comments