Skip to content

Commit de9b7d2

Browse files
authored
Fix use-after-free printing the name of an interface that might have been invalidated by lazy import. (#4509)
While here, also change the diagnostic emission to pass the interface type rather than the interface name. This prepares us to include the arguments in the diagnostic.
1 parent 4f474fa commit de9b7d2

File tree

4 files changed

+451
-7
lines changed

4 files changed

+451
-7
lines changed

toolchain/check/context.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,12 @@ auto Context::GetGenericInterfaceType(SemIR::InterfaceId interface_id,
12991299
*this, interface_id, enclosing_specific_id);
13001300
}
13011301

1302+
auto Context::GetInterfaceType(SemIR::InterfaceId interface_id,
1303+
SemIR::SpecificId specific_id) -> SemIR::TypeId {
1304+
return GetTypeImpl<SemIR::FacetType>(
1305+
*this, FacetTypeFromInterface(interface_id, specific_id).facet_type_id);
1306+
}
1307+
13021308
auto Context::GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId {
13031309
return GetTypeImpl<SemIR::PointerType>(*this, pointee_type_id);
13041310
}

toolchain/check/context.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,10 @@ class Context {
397397
SemIR::SpecificId enclosing_specific_id)
398398
-> SemIR::TypeId;
399399

400+
// Gets the facet type corresponding to a particular interface.
401+
auto GetInterfaceType(SemIR::InterfaceId interface_id,
402+
SemIR::SpecificId specific_id) -> SemIR::TypeId;
403+
400404
// Returns a pointer type whose pointee type is `pointee_type_id`.
401405
auto GetPointerType(SemIR::TypeId pointee_type_id) -> SemIR::TypeId;
402406

toolchain/check/member_access.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,28 +193,29 @@ static auto PerformImplLookup(
193193
return SemIR::InstId::BuiltinError;
194194
}
195195

196-
auto& interface = context.interfaces().Get(interface_type->interface_id);
197196
auto witness_id =
198197
LookupInterfaceWitness(context, loc_id, type_const_id,
199198
assoc_type.interface_type_id.AsConstantId());
200199
if (!witness_id.is_valid()) {
200+
auto interface_type_id = context.GetInterfaceType(
201+
interface_type->interface_id, interface_type->specific_id);
201202
if (missing_impl_diagnoser) {
202203
// TODO: Pass in the expression whose type we are printing.
203204
CARBON_DIAGNOSTIC(MissingImplInMemberAccessNote, Note,
204-
"type {1} does not implement interface `{0}`",
205-
SemIR::NameId, SemIR::TypeId);
205+
"type {1} does not implement interface {0}",
206+
SemIR::TypeId, SemIR::TypeId);
206207
missing_impl_diagnoser()
207-
.Note(loc_id, MissingImplInMemberAccessNote, interface.name_id,
208+
.Note(loc_id, MissingImplInMemberAccessNote, interface_type_id,
208209
context.GetTypeIdForTypeConstant(type_const_id))
209210
.Emit();
210211
} else {
211212
// TODO: Pass in the expression whose type we are printing.
212213
CARBON_DIAGNOSTIC(MissingImplInMemberAccess, Error,
213-
"cannot access member of interface `{0}` in type {1} "
214+
"cannot access member of interface {0} in type {1} "
214215
"that does not implement that interface",
215-
SemIR::NameId, SemIR::TypeId);
216+
SemIR::TypeId, SemIR::TypeId);
216217
context.emitter().Emit(loc_id, MissingImplInMemberAccess,
217-
interface.name_id,
218+
interface_type_id,
218219
context.GetTypeIdForTypeConstant(type_const_id));
219220
}
220221
return SemIR::InstId::BuiltinError;

0 commit comments

Comments
 (0)