Skip to content

Commit aa92d0d

Browse files
committed
rewrites-complete
1 parent 0e0cd10 commit aa92d0d

File tree

3 files changed

+185
-7
lines changed

3 files changed

+185
-7
lines changed

toolchain/check/facet_type.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,10 @@ static auto IncompleteFacetTypeDiagnosticBuilder(
6262
return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeDefinition,
6363
facet_type_inst_id);
6464
} else {
65-
CARBON_DIAGNOSTIC(
66-
ImplAsIncompleteFacetTypeRewrites, Error,
67-
"declaration of impl as incomplete facet type {0} with rewrites",
68-
InstIdAsType);
69-
return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeRewrites,
70-
facet_type_inst_id);
65+
context.TODO(loc_id,
66+
"declaration of impl as incomplete interface with a rewrite "
67+
"constraint");
68+
return context.emitter().BuildSuppressed();
7169
}
7270
}
7371

@@ -105,6 +103,9 @@ auto InitialFacetTypeImplWitness(
105103
.specific_id = self_specific_id});
106104
}
107105

106+
// The presence of any rewrite constraints requires that we know how many
107+
// entries to allocate in the witness table, which requires the entire facet
108+
// type to be complete, even if this was a declaration.
108109
if (!RequireCompleteType(
109110
context, facet_type_id, SemIR::LocId(facet_type_inst_id), [&] {
110111
return IncompleteFacetTypeDiagnosticBuilder(

toolchain/check/testdata/impl/fail_undefined_interface.carbon

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,58 @@ class C {}
4141
// CHECK:STDERR:
4242
impl C as J {}
4343

44+
// --- fail_class_with_rewrite.carbon
45+
library "[[@TEST_NAME]]";
46+
47+
interface J;
48+
interface K { let X:! type; }
49+
class C {}
50+
51+
// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE+7]]:19: error: member access into object of incomplete type `J` [IncompleteTypeInMemberAccess]
52+
// CHECK:STDERR: impl C as J where .X = ();
53+
// CHECK:STDERR: ^~
54+
// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE-7]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere]
55+
// CHECK:STDERR: interface J;
56+
// CHECK:STDERR: ^~~~~~~~~~~~
57+
// CHECK:STDERR:
58+
impl C as J where .X = ();
59+
60+
// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE+7]]:19: error: member access into object of incomplete type `J` [IncompleteTypeInMemberAccess]
61+
// CHECK:STDERR: impl C as J where .X = () {}
62+
// CHECK:STDERR: ^~
63+
// CHECK:STDERR: fail_class_with_rewrite.carbon:[[@LINE-16]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere]
64+
// CHECK:STDERR: interface J;
65+
// CHECK:STDERR: ^~~~~~~~~~~~
66+
// CHECK:STDERR:
67+
impl C as J where .X = () {}
68+
69+
// --- fail_class_with_qualified_rewrite.carbon
70+
library "[[@TEST_NAME]]";
71+
72+
interface J;
73+
interface K { let X:! type; }
74+
class C {}
75+
76+
// TODO: The failure here should be that J is incomplete, once the rewrite of
77+
// `.(K.X)` works. Since any rewrite in the decl requires us to know the size of
78+
// the witness table which requires all interfaces to be complete.
79+
//
80+
// CHECK:STDERR: fail_class_with_qualified_rewrite.carbon:[[@LINE+8]]:38: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
81+
// CHECK:STDERR: impl C as J where .Self impls K and .(K.X) = ();
82+
// CHECK:STDERR: ^
83+
// CHECK:STDERR:
84+
// CHECK:STDERR: fail_class_with_qualified_rewrite.carbon:[[@LINE+4]]:38: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
85+
// CHECK:STDERR: impl C as J where .Self impls K and .(K.X) = ();
86+
// CHECK:STDERR: ^
87+
// CHECK:STDERR:
88+
impl C as J where .Self impls K and .(K.X) = ();
89+
90+
// CHECK:STDERR: fail_class_with_qualified_rewrite.carbon:[[@LINE+4]]:38: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
91+
// CHECK:STDERR: impl C as J where .Self impls K and .(K.X) = () {}
92+
// CHECK:STDERR: ^
93+
// CHECK:STDERR:
94+
impl C as J where .Self impls K and .(K.X) = () {}
95+
4496
// --- incomplete_where.carbon
4597
library "[[@TEST_NAME]]";
4698

@@ -146,6 +198,132 @@ impl C as I where .Self impls Incomplete {
146198
// CHECK:STDOUT: .Self = constants.%C
147199
// CHECK:STDOUT: }
148200
// CHECK:STDOUT:
201+
// CHECK:STDOUT: --- fail_class_with_rewrite.carbon
202+
// CHECK:STDOUT:
203+
// CHECK:STDOUT: constants {
204+
// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete]
205+
// CHECK:STDOUT: %K.type: type = facet_type <@K> [concrete]
206+
// CHECK:STDOUT: %Self: %K.type = symbolic_binding Self, 0 [symbolic]
207+
// CHECK:STDOUT: %K.assoc_type: type = assoc_entity_type @K [concrete]
208+
// CHECK:STDOUT: %assoc0: %K.assoc_type = assoc_entity element0, @K.%X [concrete]
209+
// CHECK:STDOUT: %C: type = class_type @C [concrete]
210+
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
211+
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
212+
// CHECK:STDOUT: %.Self: %J.type = symbolic_binding .Self [symbolic_self]
213+
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
214+
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
215+
// CHECK:STDOUT: }
216+
// CHECK:STDOUT:
217+
// CHECK:STDOUT: file {
218+
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
219+
// CHECK:STDOUT: .J = %J.decl
220+
// CHECK:STDOUT: .K = %K.decl
221+
// CHECK:STDOUT: .C = %C.decl
222+
// CHECK:STDOUT: }
223+
// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {}
224+
// CHECK:STDOUT: %K.decl: type = interface_decl @K [concrete = constants.%K.type] {} {}
225+
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
226+
// CHECK:STDOUT: impl_decl @C.as.<error>.impl [concrete] {} {
227+
// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, file.%C.decl [concrete = constants.%C]
228+
// CHECK:STDOUT: %J.ref.loc14: type = name_ref J, file.%J.decl [concrete = constants.%J.type]
229+
// CHECK:STDOUT: %.Self.2: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
230+
// CHECK:STDOUT: %.Self.ref.loc14: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self]
231+
// CHECK:STDOUT: %.loc14_25: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
232+
// CHECK:STDOUT: %.loc14_13: type = where_expr %.Self.2 [concrete = <error>] {
233+
// CHECK:STDOUT: requirement_base_facet_type constants.%J.type
234+
// CHECK:STDOUT: requirement_rewrite <error>, <error>
235+
// CHECK:STDOUT: }
236+
// CHECK:STDOUT: }
237+
// CHECK:STDOUT: impl_decl @C.as.<error>.impl [concrete] {} {
238+
// CHECK:STDOUT: %C.ref.loc16: type = name_ref C, file.%C.decl [concrete = constants.%C]
239+
// CHECK:STDOUT: %J.ref.loc16: type = name_ref J, file.%J.decl [concrete = constants.%J.type]
240+
// CHECK:STDOUT: %.Self.1: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
241+
// CHECK:STDOUT: %.Self.ref.loc16: %J.type = name_ref .Self, %.Self.1 [symbolic_self = constants.%.Self]
242+
// CHECK:STDOUT: %.loc16_25: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
243+
// CHECK:STDOUT: %.loc16_13: type = where_expr %.Self.1 [concrete = <error>] {
244+
// CHECK:STDOUT: requirement_base_facet_type constants.%J.type
245+
// CHECK:STDOUT: requirement_rewrite <error>, <error>
246+
// CHECK:STDOUT: }
247+
// CHECK:STDOUT: }
248+
// CHECK:STDOUT: }
249+
// CHECK:STDOUT:
250+
// CHECK:STDOUT: interface @J;
251+
// CHECK:STDOUT:
252+
// CHECK:STDOUT: interface @K {
253+
// CHECK:STDOUT: %Self: %K.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
254+
// CHECK:STDOUT: %X: type = assoc_const_decl @X [concrete] {
255+
// CHECK:STDOUT: %assoc0: %K.assoc_type = assoc_entity element0, @K.%X [concrete = constants.%assoc0]
256+
// CHECK:STDOUT: }
257+
// CHECK:STDOUT:
258+
// CHECK:STDOUT: !members:
259+
// CHECK:STDOUT: .Self = %Self
260+
// CHECK:STDOUT: .X = @X.%assoc0
261+
// CHECK:STDOUT: witness = (%X)
262+
// CHECK:STDOUT:
263+
// CHECK:STDOUT: !requires:
264+
// CHECK:STDOUT: }
265+
// CHECK:STDOUT:
266+
// CHECK:STDOUT: generic assoc_const @X(@K.%Self: %K.type) {
267+
// CHECK:STDOUT: assoc_const X:! type;
268+
// CHECK:STDOUT: }
269+
// CHECK:STDOUT:
270+
// CHECK:STDOUT: impl @C.as.<error>.impl: %C.ref.loc14 as %.loc14_13 {
271+
// CHECK:STDOUT: !members:
272+
// CHECK:STDOUT: witness = <error>
273+
// CHECK:STDOUT: }
274+
// CHECK:STDOUT:
275+
// CHECK:STDOUT: class @C {
276+
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
277+
// CHECK:STDOUT: complete_type_witness = %complete_type
278+
// CHECK:STDOUT:
279+
// CHECK:STDOUT: !members:
280+
// CHECK:STDOUT: .Self = constants.%C
281+
// CHECK:STDOUT: }
282+
// CHECK:STDOUT:
283+
// CHECK:STDOUT: specific @X(constants.%Self) {}
284+
// CHECK:STDOUT:
285+
// CHECK:STDOUT: --- fail_class_with_qualified_rewrite.carbon
286+
// CHECK:STDOUT:
287+
// CHECK:STDOUT: constants {
288+
// CHECK:STDOUT: %K.type: type = facet_type <@K> [concrete]
289+
// CHECK:STDOUT: %Self: %K.type = symbolic_binding Self, 0 [symbolic]
290+
// CHECK:STDOUT: %K.assoc_type: type = assoc_entity_type @K [concrete]
291+
// CHECK:STDOUT: %assoc0: %K.assoc_type = assoc_entity element0, @K.%X [concrete]
292+
// CHECK:STDOUT: %C: type = class_type @C [concrete]
293+
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
294+
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
295+
// CHECK:STDOUT: }
296+
// CHECK:STDOUT:
297+
// CHECK:STDOUT: interface @J;
298+
// CHECK:STDOUT:
299+
// CHECK:STDOUT: interface @K {
300+
// CHECK:STDOUT: %Self: %K.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
301+
// CHECK:STDOUT: %X: type = assoc_const_decl @X [concrete] {
302+
// CHECK:STDOUT: %assoc0: %K.assoc_type = assoc_entity element0, @K.%X [concrete = constants.%assoc0]
303+
// CHECK:STDOUT: }
304+
// CHECK:STDOUT:
305+
// CHECK:STDOUT: !members:
306+
// CHECK:STDOUT: .Self = %Self
307+
// CHECK:STDOUT: .X = @X.%assoc0
308+
// CHECK:STDOUT: witness = (%X)
309+
// CHECK:STDOUT:
310+
// CHECK:STDOUT: !requires:
311+
// CHECK:STDOUT: }
312+
// CHECK:STDOUT:
313+
// CHECK:STDOUT: generic assoc_const @X(@K.%Self: %K.type) {
314+
// CHECK:STDOUT: assoc_const X:! type;
315+
// CHECK:STDOUT: }
316+
// CHECK:STDOUT:
317+
// CHECK:STDOUT: class @C {
318+
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
319+
// CHECK:STDOUT: complete_type_witness = %complete_type
320+
// CHECK:STDOUT:
321+
// CHECK:STDOUT: !members:
322+
// CHECK:STDOUT: .Self = constants.%C
323+
// CHECK:STDOUT: }
324+
// CHECK:STDOUT:
325+
// CHECK:STDOUT: specific @X(constants.%Self) {}
326+
// CHECK:STDOUT:
149327
// CHECK:STDOUT: --- incomplete_where.carbon
150328
// CHECK:STDOUT:
151329
// CHECK:STDOUT: constants {

toolchain/diagnostics/diagnostic_kind.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ CARBON_DIAGNOSTIC_KIND(ExtendImplSelfAs)
329329
CARBON_DIAGNOSTIC_KIND(ExtendImplSelfAsDefault)
330330
CARBON_DIAGNOSTIC_KIND(ImplAccessMemberBeforeSet)
331331
CARBON_DIAGNOSTIC_KIND(ImplAsIncompleteFacetTypeDefinition)
332-
CARBON_DIAGNOSTIC_KIND(ImplAsIncompleteFacetTypeRewrites)
333332
CARBON_DIAGNOSTIC_KIND(ImplAsNonFacetType)
334333
CARBON_DIAGNOSTIC_KIND(ImplAsOutsideClass)
335334
CARBON_DIAGNOSTIC_KIND(ImplAssociatedConstantNeedsValue)

0 commit comments

Comments
 (0)